diff options
Diffstat (limited to 'nx-X11/lib/font')
208 files changed, 71582 insertions, 0 deletions
diff --git a/nx-X11/lib/font/FreeType/Imakefile b/nx-X11/lib/font/FreeType/Imakefile new file mode 100644 index 000000000..57361471b --- /dev/null +++ b/nx-X11/lib/font/FreeType/Imakefile @@ -0,0 +1,47 @@ +XCOMM $XFree86: xc/lib/font/FreeType/Imakefile,v 1.30 2003/11/05 16:54:28 tsi Exp $ + +#if BuildServer && DoLoadableServer +#define IHaveSubdirs +#define NoLibSubdirs +#define PassCDebugFlags +SUBDIRS = module +#endif + +#if !HasFreetype2 +EXTRAINCLUDES = -I$(FT2SOURCEDIR)/truetype +INTERNALDEFINES = -DUSE_INTERNAL_FREETYPE +#endif + +DEFINES = ServerExtraDefines StrcasecmpDefines Freetype2BuildDefines \ + -DXFREE86_FT2 $(INTERNALDEFINES) + +FT2SOURCEDIR = $(TOP)/extras/freetype2/src +FT2INCS = $(FREETYPE2INCLUDES) + +INCLUDES = $(FT2INCS) -I. -I$(FONTINCSRC) -I../include -I$(XINCLUDESRC) \ + -I$(SERVERSRC)/include $(EXTRAINCLUDES) \ + -I$(INCLUDESRC) + +SRCS = xttcap.c ftfuncs.c ftenc.c fttools.c +OBJS = xttcap.o ftfuncs.o ftenc.o fttools.o + +#if BuildFontLib +#define DoNormalLib NormalLibFont +#define DoSharedLib SharedLibFont +#define DoDebugLib DebugLibFont +#define DoProfileLib ProfileLibFont +#include <Library.tmpl> +LibraryObjectRule() + +SubdirLibraryRule($(OBJS)) +NormalLintTarget($(SRCS)) + +#endif + +#if BuildServer && DoLoadableServer +MakeSubdirs($(SUBDIRS)) +DependSubdirs($(SUBDIRS)) +#endif + +DependTarget() + diff --git a/nx-X11/lib/font/FreeType/ft.h b/nx-X11/lib/font/FreeType/ft.h new file mode 100644 index 000000000..8ad8403d5 --- /dev/null +++ b/nx-X11/lib/font/FreeType/ft.h @@ -0,0 +1,96 @@ +/* +Copyright (c) 1997 by Mark Leisher +Copyright (c) 1998-2002 by Juliusz Chroboczek + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +/* $XFree86: xc/lib/font/FreeType/ft.h,v 1.22 2003/06/08 15:41:13 herrb Exp $ */ + +#ifndef _FT_H_ +#define _FT_H_ + +#include <X11/Xfuncproto.h> + +#define FREETYPE_VERSION (FREETYPE_MAJOR * 1000000 + FREETYPE_MINOR * 1000 + FREETYPE_PATCH) + +#undef DEBUG_TRUETYPE + +#ifdef DEBUG_TRUETYPE +#define MUMBLE(s) (ErrorF((s))) +#define MUMBLE1(s,x) (ErrorF((s),(x))) +#else +#define MUMBLE(s) +#define MUMBLE1(s,x) +#endif + +#undef MAX +#define MAX(h,i) ((h) > (i) ? (h) : (i)) +#define ADJUSTMAX(m,v) if((v)>(m)) (m)=(v) +#undef MIN +#define MIN(l,o) ((l) < (o) ? (l) : (o)) +#define ADJUSTMIN(m,v) if ((v)<(m)) (m)=(v) + +/* When comparing floating point values, we want to ignore small errors. */ +#define NEGLIGIBLE ((double)0.001) +/* Are x and y significantly different? */ +#define DIFFER(x,y) (fabs((x)-(y))>=NEGLIGIBLE*fabs(x)) +/* Is x significantly different from 0 w.r.t. y? */ +#define DIFFER0(x,y) (fabs(x)>=NEGLIGIBLE*fabs(y)) + +#ifndef ABS +#define ABS(x) ((x) >= 0 ? (x) : -(x)) +#endif + +/* Two to the sixteenth power, as a double. */ +#define TWO_SIXTEENTH ((double)(1<<16)) +#define TWO_SIXTH ((double)(1<<6)) + +/* Data structures used across files */ + +typedef struct _FTMapping +{ + int named; + FT_CharMap cmap; + int base; + struct _FontMap *mapping; /* allow inclusion without fontenc.h */ +} FTMappingRec, *FTMappingPtr; + +/* Prototypes */ + +/* ftfuncs.c */ + +#if 0 +void FreeTypeRegisterFontFileFunctions(void); +#endif + +/* ftenc.c */ + +int FTPickMapping(char*, int, char*, FT_Face, FTMappingPtr); +unsigned FTRemap(FT_Face face, FTMappingPtr, unsigned code); + +/* fttools.c */ + +int FTtoXReturnCode(int); +int FTGetEnglishName(FT_Face, int, char *, int); +int FTcheckForTTCName(char*, char**, int*); + +extern void ErrorF(const char*, ...); + +#endif /* _FT_H_ */ diff --git a/nx-X11/lib/font/FreeType/ftenc.c b/nx-X11/lib/font/FreeType/ftenc.c new file mode 100644 index 000000000..a9d6494ff --- /dev/null +++ b/nx-X11/lib/font/FreeType/ftenc.c @@ -0,0 +1,242 @@ +/* +Copyright (c) 1998-2003 by Juliusz Chroboczek + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ +/* $XFree86: xc/lib/font/FreeType/ftenc.c,v 1.24 2003/10/19 18:53:49 dawes Exp $ */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#ifndef FONTMODULE +#include <string.h> +#else +#include "Xmd.h" +#include "Xdefs.h" +#include "xf86_ansic.h" +#endif + +#include <X11/fonts/fntfilst.h> +#include <X11/fonts/fontutil.h> +#include <X11/fonts/FSproto.h> + +#include <X11/fonts/fontmisc.h> +#include <X11/fonts/fontenc.h> +#include <ft2build.h> +#include FT_FREETYPE_H +#include FT_TRUETYPE_IDS_H +#include FT_TRUETYPE_TABLES_H +#include FT_TYPE1_TABLES_H +#include FT_BDF_H +#include FT_XFREE86_H +#include "ft.h" + +static int find_cmap(int, int, int, FT_Face, FT_CharMap *); + +static int +FTEncFontSpecific(char *encoding) +{ + char *p = encoding; + + if(strcasecmp(encoding, "microsoft-symbol") == 0) + return 1; + + while(*p != '-') { + if(*p == '\0') + return 0; + p++; + } + p++; + return (strcasecmp(p, "fontspecific") == 0); +} + +int +FTPickMapping(char *xlfd, int length, char *filename, FT_Face face, + FTMappingPtr tm) +{ + FontEncPtr encoding; + FontMapPtr mapping; + FT_CharMap cmap; + int ftrc; + int symbol = 0; + const char *enc, *reg; + char *encoding_name = 0; + char buf[20]; + + if(xlfd) + encoding_name = FontEncFromXLFD(xlfd, length); + if(!encoding_name) + encoding_name = "iso8859-1"; + + symbol = FTEncFontSpecific(encoding_name); + + ftrc = FT_Get_BDF_Charset_ID(face, &enc, ®); + if(ftrc == 0) { + /* Disable reencoding for non-Unicode fonts. This will + currently only work for BDFs. */ + if(strlen(enc) + strlen(reg) > 18) + goto native; + strcpy(buf, enc); + strcat(buf, "-"); + strcat(buf, reg); + ErrorF("%s %s\n", buf, encoding_name); + if(strcasecmp(buf, "iso10646-1") != 0) { + if(strcasecmp(buf, encoding_name) == 0) + goto native; + return BadFontFormat; + } + } else if(symbol) { + ftrc = FT_Select_Charmap(face, ft_encoding_adobe_custom); + if(ftrc == 0) + goto native; + } + + encoding = FontEncFind(encoding_name, filename); + if(symbol && encoding == NULL) + encoding = FontEncFind("microsoft-symbol", filename); + if(encoding == NULL) { + ErrorF("FreeType: couldn't find encoding '%s' for '%s'\n", + encoding_name, filename); + return BadFontName; + } + + if(FT_Has_PS_Glyph_Names(face)) { + for(mapping = encoding->mappings; mapping; mapping = mapping->next) { + if(mapping->type == FONT_ENCODING_POSTSCRIPT) { + tm->named = 1; + tm->base = 0; + tm->mapping = mapping; + return Successful; + } + } + } + + for(mapping = encoding->mappings; mapping; mapping = mapping->next) { + if(find_cmap(mapping->type, mapping->pid, mapping->eid, face, + &cmap)) { + tm->named = 0; + tm->cmap = cmap; + if(symbol) { + /* deal with an undocumented ``feature'' of the + Microsft-Symbol cmap */ + TT_OS2 *os2; + os2 = FT_Get_Sfnt_Table(face, ft_sfnt_os2); + if(os2) + tm->base = os2->usFirstCharIndex - 0x20; + else + tm->base = 0; + } else + tm->base = 0; + tm->mapping = mapping; + return Successful; + } + } + + return BadFontFormat; + + native: + tm->named = 0; + tm->cmap = face->charmap; + tm->base = 0; + tm->mapping = NULL; + return Successful; +} + +static int +find_cmap(int type, int pid, int eid, FT_Face face, FT_CharMap *cmap_return) +{ + int i, n; + FT_CharMap cmap = NULL; + + n = face->num_charmaps; + + switch(type) { + case FONT_ENCODING_TRUETYPE: /* specific cmap */ + for(i=0; i<n; i++) { + cmap = face->charmaps[i]; + if(cmap->platform_id == pid && cmap->encoding_id == eid) { + *cmap_return = cmap; + return 1; + } + } + break; + case FONT_ENCODING_UNICODE: /* any Unicode cmap */ + /* prefer Microsoft Unicode */ + for(i=0; i<n; i++) { + cmap = face->charmaps[i]; + if(cmap->platform_id == TT_PLATFORM_MICROSOFT && + cmap->encoding_id == TT_MS_ID_UNICODE_CS) { + *cmap_return = cmap; + return 1; + } + } + break; + /* Try Apple Unicode */ + for(i=0; i<n; i++) { + cmap = face->charmaps[i]; + if(cmap->platform_id == TT_PLATFORM_APPLE_UNICODE) { + *cmap_return = cmap; + return 1; + } + } + /* ISO Unicode? */ + for(i=0; i<n; i++) { + cmap = face->charmaps[i]; + if(cmap->platform_id == TT_PLATFORM_ISO) { + *cmap_return = cmap; + return 1; + } + } + break; + default: + return 0; + } + return 0; +} + +unsigned +FTRemap(FT_Face face, FTMappingPtr tm, unsigned code) +{ + unsigned index; + char *name; + unsigned glyph_index; + + if(tm->mapping) { + if(tm->named) { + name = FontEncName(code, tm->mapping); + if(!name) + return 0; + glyph_index = FT_Get_Name_Index(face, name); + return glyph_index; + } else { + index = FontEncRecode(code, tm->mapping) + tm->base; + FT_Set_Charmap(face, tm->cmap); + glyph_index = FT_Get_Char_Index(face, index); + return glyph_index; + } + } else { + if(code < 0x100) { + index = code; + FT_Set_Charmap(face, tm->cmap); + glyph_index = FT_Get_Char_Index(face, index); + return glyph_index; + } else + return 0; + } +} diff --git a/nx-X11/lib/font/FreeType/ftfuncs.c b/nx-X11/lib/font/FreeType/ftfuncs.c new file mode 100644 index 000000000..d3c9d9eeb --- /dev/null +++ b/nx-X11/lib/font/FreeType/ftfuncs.c @@ -0,0 +1,3851 @@ +/* +Copyright (c) 1997 by Mark Leisher +Copyright (c) 1998-2003 by Juliusz Chroboczek +Copyright (c) 1998 Go Watanabe, All rights reserved. +Copyright (c) 1998 Kazushi (Jam) Marukawa, All rights reserved. +Copyright (c) 1998 Takuya SHIOZAKI, All rights reserved. +Copyright (c) 1998 X-TrueType Server Project, All rights reserved. +Copyright (c) 2003-2004 After X-TT Project, All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ +/* $XdotOrg: xc/lib/font/FreeType/ftfuncs.c,v 1.13 2005/10/23 18:32:05 ajax Exp $ */ + +/* $XFree86: xc/lib/font/FreeType/ftfuncs.c,v 1.43 2004/02/07 04:37:18 dawes Exp $ */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <X11/fonts/fontmisc.h> + +#ifndef FONTMODULE +#include <string.h> +#include <math.h> +#else +#include "Xmd.h" +#include "Xdefs.h" +#include "xf86_ansic.h" +#endif + +#include <X11/fonts/fntfilst.h> +#include <X11/fonts/fontutil.h> +#include <X11/fonts/FSproto.h> +#include <ft2build.h> +#include FT_FREETYPE_H +#include FT_SIZES_H +#include FT_TRUETYPE_IDS_H +#include FT_TRUETYPE_TABLES_H +#include FT_TYPE1_TABLES_H +#include FT_XFREE86_H +#include FT_BBOX_H +#include FT_INTERNAL_TRUETYPE_TYPES_H +#include FT_TRUETYPE_TAGS_H +#include FT_INTERNAL_SFNT_H +#include FT_INTERNAL_STREAM_H +/* + * If you want to use FT_Outline_Get_CBox instead of + * FT_Outline_Get_BBox, define here. + */ +/* #define USE_GET_CBOX */ +#ifdef USE_GET_CBOX +#include FT_OUTLINE_H +#endif + +#include <X11/fonts/fontenc.h> +#include "ft.h" +#include "ftfuncs.h" +#include "xttcap.h" + +/* Work around FreeType bug */ +#define WORK_AROUND_UPM 2048 + +#ifndef True +#define True (-1) +#endif /* True */ +#ifndef False +#define False (0) +#endif /* False */ + +#define FLOOR64(x) ((x) & -64) +#define CEIL64(x) (((x) + 64 - 1) & -64) + +/* + * If you want very lazy method(vl=y) AS DEFAULT when + * handling large charset, define here. + */ +/* #define DEFAULT_VERY_LAZY 1 */ /* Always */ +#define DEFAULT_VERY_LAZY 2 /* Multi-byte only */ +/* #define DEFAULT_VERY_LAZY 256 */ /* Unicode only */ + +/* Does the X accept noSuchChar? */ +#define X_ACCEPTS_NO_SUCH_CHAR +/* Does the XAA accept NULL noSuchChar.bits?(dangerous) */ +/* #define XAA_ACCEPTS_NULL_BITS */ + +#ifdef X_ACCEPTS_NO_SUCH_CHAR +static CharInfoRec noSuchChar = { /* metrics */{0,0,0,0,0,0}, + /* bits */ NULL }; +#endif + +/* The propery names for all the XLFD properties. */ + +static char *xlfd_props[] = { + "FOUNDRY", + "FAMILY_NAME", + "WEIGHT_NAME", + "SLANT", + "SETWIDTH_NAME", + "ADD_STYLE_NAME", + "PIXEL_SIZE", + "POINT_SIZE", + "RESOLUTION_X", + "RESOLUTION_Y", + "SPACING", + "AVERAGE_WIDTH", + "CHARSET_REGISTRY", + "CHARSET_ENCODING", +}; + + +static int ftypeInitP = 0; /* is the engine initialised? */ +FT_Library ftypeLibrary; + +static FTFacePtr faceTable[NUMFACEBUCKETS]; + +static unsigned +hash(char *string) +{ + int i; + unsigned u = 0; + for(i = 0; string[i] != '\0'; i++) + u = (u<<5) + (u >> (NUMFACEBUCKETS - 5)) + (unsigned char)string[i]; + return u; +} + +static int +ifloor(int x, int y) +{ + if(x >= 0) + return x/y; + else + return x/y - 1; +} + +static int +iceil(int x, int y) +{ + return ifloor(x + y - 1, y); +} + +static int +FreeTypeOpenFace(FTFacePtr *facep, char *FTFileName, char *realFileName, int faceNumber) +{ + FT_Error ftrc; + int bucket; + FTFacePtr face, otherFace; + + if (!ftypeInitP) { + ftrc = FT_Init_FreeType(&ftypeLibrary); + if (ftrc != 0) { + ErrorF("FreeType: error initializing ftypeEngine: %d\n", ftrc); + return AllocError; + } + ftypeInitP = 1; + } + + /* Try to find a matching face in the hashtable */ + bucket = hash(FTFileName)%NUMFACEBUCKETS; + otherFace = faceTable[bucket]; + while(otherFace) { + if( strcmp(otherFace->filename, FTFileName) == 0 ) break; + otherFace = otherFace->next; + } + if(otherFace) { + MUMBLE1("Returning cached face: %s\n", otherFace->filename); + *facep = otherFace; + return Successful; + } + + /* No cached match; need to make a new one */ + face = (FTFacePtr)xalloc(sizeof(FTFaceRec)); + if(face == NULL) { + return AllocError; + } + memset(face, 0, sizeof(FTFaceRec)); + + face->filename = (char*)xalloc(strlen(FTFileName)+1); + if(face->filename == NULL) { + xfree(face); + return AllocError; + } + strcpy(face->filename, FTFileName); + + ftrc = FT_New_Face(ftypeLibrary, realFileName, faceNumber, &face->face); + if(ftrc != 0) { + ErrorF("FreeType: couldn't open face %s: %d\n", FTFileName, ftrc); + xfree(face->filename); + xfree(face); + return BadFontName; + } + + face->bitmap = ((face->face->face_flags & FT_FACE_FLAG_SCALABLE) == 0); + if(!face->bitmap) { + TT_MaxProfile *maxp; + maxp = FT_Get_Sfnt_Table(face->face, ft_sfnt_maxp); + if(maxp && maxp->maxContours == 0) + face->bitmap = 1; + } + /* Insert face in hashtable and return it */ + face->next = faceTable[bucket]; + faceTable[bucket] = face; + *facep = face; + return Successful; +} + +static void +FreeTypeFreeFace(FTFacePtr face) +{ + int bucket; + FTFacePtr otherFace; + + if(!face->instances) { + bucket = hash(face->filename) % NUMFACEBUCKETS; + if(faceTable[bucket] == face) + faceTable[bucket] = face->next; + else { + otherFace = faceTable[bucket]; + while(otherFace) { + if(otherFace->next == face) + break; + otherFace = otherFace->next; + } + if(otherFace && otherFace->next) + otherFace->next = otherFace->next->next; + else + ErrorF("FreeType: freeing unknown face\n"); + } + MUMBLE1("Closing face: %s\n", face->filename); + FT_Done_Face(face->face); + xfree(face->filename); + xfree(face); + } +} + +static int +TransEqual(FTNormalisedTransformationPtr t1, FTNormalisedTransformationPtr t2) +{ + if(t1->scale != t2->scale) + return 0; + else if(t1->xres != t2->xres || t1->yres != t2->yres) + return 0; + else if(t1->nonIdentity != t2->nonIdentity) + return 0; + else if(t1->nonIdentity && t2->nonIdentity) { + return + t1->matrix.xx == t2->matrix.xx && + t1->matrix.yx == t2->matrix.yx && + t1->matrix.yy == t2->matrix.yy && + t1->matrix.xy == t2->matrix.xy; + } else + return 1; +} + +static int +BitmapFormatEqual(FontBitmapFormatPtr f1, FontBitmapFormatPtr f2) +{ + return + f1->bit == f2->bit && + f1->byte == f2->byte && + f1->glyph == f2->glyph; +} + +static int +TTCapEqual(struct TTCapInfo *t1, struct TTCapInfo *t2) +{ + return + t1->autoItalic == t2->autoItalic && + t1->scaleWidth == t2->scaleWidth && + t1->scaleBBoxWidth == t2->scaleBBoxWidth && + t1->scaleBBoxHeight == t2->scaleBBoxHeight && + t1->doubleStrikeShift == t2->doubleStrikeShift && + t1->adjustBBoxWidthByPixel == t2->adjustBBoxWidthByPixel && + t1->adjustLeftSideBearingByPixel == t2->adjustLeftSideBearingByPixel && + t1->adjustRightSideBearingByPixel == t2->adjustRightSideBearingByPixel && + t1->flags == t2->flags && + t1->scaleBitmap == t2->scaleBitmap && + /* + If we use forceConstantSpacing, + we *MUST* allocate new instance. + */ + t1->forceConstantSpacingEnd < 0 && + t2->forceConstantSpacingEnd < 0; +} + +static int +FTInstanceMatch(FTInstancePtr instance, + char *FTFileName, FTNormalisedTransformationPtr trans, + int spacing, FontBitmapFormatPtr bmfmt, + struct TTCapInfo *tmp_ttcap, FT_Int32 load_flags) +{ + if(strcmp(instance->face->filename, FTFileName) != 0) { + return 0; + } else if(!TransEqual(&instance->transformation, trans)) { + return 0; + } else if( spacing != instance->spacing ) { + return 0; + } else if( load_flags != instance->load_flags ) { + return 0; + } else if(!BitmapFormatEqual(&instance->bmfmt, bmfmt)) { + return 0; + } else if(!TTCapEqual(&instance->ttcap, tmp_ttcap)) { + return 0; + } else { + return 1; + } +} + +static int +FreeTypeActivateInstance(FTInstancePtr instance) +{ + FT_Error ftrc; + if(instance->face->active_instance == instance) + return Successful; + + ftrc = FT_Activate_Size(instance->size); + if(ftrc != 0) { + instance->face->active_instance = NULL; + ErrorF("FreeType: couldn't activate instance: %d\n", ftrc); + return FTtoXReturnCode(ftrc); + } + FT_Set_Transform(instance->face->face, + instance->transformation.nonIdentity ? + &instance->transformation.matrix : 0, + 0); + + instance->face->active_instance = instance; + return Successful; +} + +static int +FTFindSize(FT_Face face, FTNormalisedTransformationPtr trans, + int *x_return, int *y_return) +{ + int tx, ty, x, y; + int i, j; + int d, dd; + + if(trans->nonIdentity) + return BadFontName; + + tx = (int)(trans->scale * trans->xres / 72.0 + 0.5); + ty = (int)(trans->scale * trans->yres / 72.0 + 0.5); + + d = 100; + j = -1; + for(i = 0; i < face->num_fixed_sizes; i++) { + x = face->available_sizes[i].width; + y = face->available_sizes[i].height; + if(ABS(x - tx) <= 1 && ABS(y - ty) <= 1) { + dd = ABS(x - tx) * ABS(x - tx) + ABS(y - ty) * ABS(y - ty); + if(dd < d) { + j = i; + d = dd; + } + } + } + if(j < 0) + return BadFontName; + + *x_return = face->available_sizes[j].width; + *y_return = face->available_sizes[j].height; + return Successful; +} + +static int +FreeTypeOpenInstance(FTInstancePtr *instance_return, FTFacePtr face, + char *FTFileName, FTNormalisedTransformationPtr trans, + int spacing, FontBitmapFormatPtr bmfmt, + struct TTCapInfo *tmp_ttcap, FT_Int32 load_flags) +{ + FT_Error ftrc; + int xrc; + FTInstancePtr instance, otherInstance; + + /* Search for a matching instance */ + for(otherInstance = face->instances; + otherInstance; + otherInstance = otherInstance->next) { + if(FTInstanceMatch(otherInstance, FTFileName, trans, spacing, bmfmt, + tmp_ttcap, load_flags)) break; + } + if(otherInstance) { + MUMBLE("Returning cached instance\n"); + otherInstance->refcount++; + *instance_return = otherInstance; + return Successful; + } + + /* None matching found */ + instance = (FTInstancePtr)xalloc(sizeof(FTInstanceRec)); + if(instance == NULL) { + return AllocError; + } + + instance->refcount = 1; + instance->face = face; + + instance->load_flags = load_flags; + instance->spacing = spacing; /* Actual spacing */ + instance->pixel_size =0; + instance->pixel_width_unit_x =0; + instance->pixel_width_unit_y =0; + instance->charcellMetrics = NULL; + instance->averageWidth = 0; + instance->rawAverageWidth = 0; + instance->forceConstantMetrics = NULL; + + instance->transformation = *trans; + instance->bmfmt = *bmfmt; + instance->glyphs = NULL; + instance->available = NULL; + + if( 0 <= tmp_ttcap->forceConstantSpacingEnd ) + instance->nglyphs = 2 * instance->face->face->num_glyphs; + else + instance->nglyphs = instance->face->face->num_glyphs; + + /* Store the TTCap info. */ + memcpy((char*)&instance->ttcap, (char*)tmp_ttcap, + sizeof(struct TTCapInfo)); + + ftrc = FT_New_Size(instance->face->face, &instance->size); + if(ftrc != 0) { + ErrorF("FreeType: couldn't create size object: %d\n", ftrc); + xfree(instance); + return FTtoXReturnCode(ftrc); + } + FreeTypeActivateInstance(instance); + if(!face->bitmap) { + ftrc = FT_Set_Char_Size(instance->face->face, + (int)(trans->scale*(1<<6) + 0.5), + (int)(trans->scale*(1<<6) + 0.5), + trans->xres, trans->yres); + } else { + int xsize, ysize; + xrc = FTFindSize(face->face, trans, &xsize, &ysize); + if(xrc != Successful) { + xfree(instance); + return xrc; + } + ftrc = FT_Set_Pixel_Sizes(instance->face->face, xsize, ysize); + } + if(ftrc != 0) { + FT_Done_Size(instance->size); + xfree(instance); + return FTtoXReturnCode(ftrc); + } + + if( FT_IS_SFNT( face->face ) ) { + /* See Set_Char_Sizes() in ttdriver.c */ + FT_Error err; + TT_Face tt_face; + FT_Long tt_dim_x, tt_dim_y; + FT_UShort tt_x_ppem, tt_y_ppem; + FT_F26Dot6 tt_char_width, tt_char_height; + SFNT_Service sfnt; + tt_face=(TT_Face)face->face; + tt_char_width = (int)(trans->scale*(1<<6) + 0.5); + tt_char_height = (int)(trans->scale*(1<<6) + 0.5); + if ( ( tt_face->header.Flags & 8 ) != 0 ) { + tt_dim_x = ( ( tt_char_width * trans->xres + (36+32*72) ) / 72 ) & -64; + tt_dim_y = ( ( tt_char_height * trans->yres + (36+32*72) ) / 72 ) & -64; + } + else{ + tt_dim_x = ( ( tt_char_width * trans->xres + 36 ) / 72 ); + tt_dim_y = ( ( tt_char_height * trans->yres + 36 ) / 72 ); + } + tt_x_ppem = (FT_UShort)( tt_dim_x >> 6 ); + tt_y_ppem = (FT_UShort)( tt_dim_y >> 6 ); + /* See Reset_SBit_Size() in ttobjs.c */ + sfnt = (SFNT_Service)tt_face->sfnt; + err = sfnt->set_sbit_strike(tt_face,tt_x_ppem,tt_y_ppem,&instance->strike_index); + if ( err ) instance->strike_index=0xFFFFU; + } + + /* maintain a linked list of instances */ + instance->next = instance->face->instances; + instance->face->instances = instance; + + *instance_return = instance; + return Successful; +} + +static void +FreeTypeFreeInstance(FTInstancePtr instance) +{ + FTInstancePtr otherInstance; + + if( instance == NULL ) return; + + if(instance->face->active_instance == instance) + instance->face->active_instance = NULL; + instance->refcount--; + if(instance->refcount <= 0) { + int i,j; + + if(instance->face->instances == instance) + instance->face->instances = instance->next; + else { + for(otherInstance = instance->face->instances; + otherInstance; + otherInstance = otherInstance->next) + if(otherInstance->next == instance) { + otherInstance->next = instance->next; + break; + } + } + + FT_Done_Size(instance->size); + FreeTypeFreeFace(instance->face); + + if(instance->charcellMetrics) { + xfree(instance->charcellMetrics); + } + if(instance->forceConstantMetrics) { + xfree(instance->forceConstantMetrics); + } + if(instance->glyphs) { + for(i = 0; i < iceil(instance->nglyphs, FONTSEGMENTSIZE); i++) { + if(instance->glyphs[i]) { + for(j = 0; j < FONTSEGMENTSIZE; j++) { + if(instance->available[i][j] == + FT_AVAILABLE_RASTERISED) + xfree(instance->glyphs[i][j].bits); + } + xfree(instance->glyphs[i]); + } + } + xfree(instance->glyphs); + } + if(instance->available) { + for(i = 0; i < iceil(instance->nglyphs, FONTSEGMENTSIZE); i++) { + if(instance->available[i]) + xfree(instance->available[i]); + } + xfree(instance->available); + } + xfree(instance); + } +} + +static int +FreeTypeInstanceFindGlyph(unsigned idx_in, int flags, FTInstancePtr instance, + CharInfoPtr **glyphs, int ***available, + int *found, int *segmentP, int *offsetP) +{ + int segment, offset; + unsigned idx = idx_in; + + if( 0 <= instance->ttcap.forceConstantSpacingEnd ){ + if( (flags & FT_FORCE_CONSTANT_SPACING) ) + idx += instance->nglyphs / 2 ; + } + + if(idx > instance->nglyphs) { + *found = 0; + return Successful; + } + + if(*available == NULL) { + *available = + (int**)xalloc(sizeof(int*) * iceil(instance->nglyphs, + FONTSEGMENTSIZE)); + if(*available == NULL) + return AllocError; + memset((char*)(*available), 0, + sizeof(int*) * iceil(instance->nglyphs, FONTSEGMENTSIZE)); + } + + segment = ifloor(idx, FONTSEGMENTSIZE); + offset = idx - segment * FONTSEGMENTSIZE; + + if((*available)[segment] == NULL) { + (*available)[segment] = (int*)xalloc(sizeof(int) * FONTSEGMENTSIZE); + if((*available)[segment] == NULL) + return AllocError; + memset((char*)(*available)[segment], 0, sizeof(int) * FONTSEGMENTSIZE); + } + + if(*glyphs == NULL) { + *glyphs = (CharInfoPtr*)xalloc(sizeof(CharInfoPtr)* + iceil(instance->nglyphs, + FONTSEGMENTSIZE)); + if(*glyphs == NULL) + return AllocError; + memset((char*)(*glyphs), 0, + sizeof(CharInfoPtr)*iceil(instance->nglyphs, FONTSEGMENTSIZE)); + } + + if((*glyphs)[segment] == NULL) { + (*glyphs)[segment]= + (CharInfoPtr)xalloc(sizeof(CharInfoRec) * FONTSEGMENTSIZE); + if((*glyphs)[segment] == NULL) + return AllocError; + } + + *found = 1; + *segmentP = segment; + *offsetP = offset; + return Successful; +} + +static int +FreeTypeInstanceGetGlyph(unsigned idx, int flags, CharInfoPtr *g, FTInstancePtr instance) +{ + int found, segment, offset; + int xrc; + int ***available; + CharInfoPtr **glyphs; + + available = &instance->available; + glyphs = &instance->glyphs; + + xrc = FreeTypeInstanceFindGlyph(idx, flags, instance, glyphs, available, + &found, &segment, &offset); + if(xrc != Successful) + return xrc; + + if(!found || (*available)[segment][offset] == FT_AVAILABLE_NO) { + *g = NULL; + return Successful; + } + + if((*available)[segment][offset] == FT_AVAILABLE_RASTERISED) { + *g = &(*glyphs)[segment][offset]; + return Successful; + } + + flags |= FT_GET_GLYPH_BOTH; + + xrc = FreeTypeRasteriseGlyph(idx, flags, + &(*glyphs)[segment][offset], instance, + (*available)[segment][offset] >= FT_AVAILABLE_METRICS); + if(xrc != Successful && (*available)[segment][offset] >= FT_AVAILABLE_METRICS) { + ErrorF("Warning: FreeTypeRasteriseGlyph() returns an error,\n"); + ErrorF("\tso the backend tries to set a white space.\n"); + xrc = FreeTypeRasteriseGlyph(idx, flags | FT_GET_DUMMY, + &(*glyphs)[segment][offset], instance, + (*available)[segment][offset] >= FT_AVAILABLE_METRICS); + } + if(xrc == Successful) { + (*available)[segment][offset] = FT_AVAILABLE_RASTERISED; + /* return the glyph */ + *g = &(*glyphs)[segment][offset]; + } + return xrc; +} + +static int +FreeTypeInstanceGetGlyphMetrics(unsigned idx, int flags, + xCharInfo **metrics, FTInstancePtr instance ) +{ + int xrc; + int found, segment, offset; + + /* Char cell */ + if(instance->spacing == FT_CHARCELL) { + *metrics = instance->charcellMetrics; + return Successful; + } + /* Force constant metrics */ + if( flags & FT_FORCE_CONSTANT_SPACING) { + *metrics = instance->forceConstantMetrics; + return Successful; + } + + /* Not char cell */ + + xrc = FreeTypeInstanceFindGlyph(idx, flags, instance, + &instance->glyphs, &instance->available, + &found, &segment, &offset); + if(xrc != Successful) + return xrc; + if(!found) { + *metrics = NULL; + return Successful; + } + if( instance->available[segment][offset] == FT_AVAILABLE_NO ) { + *metrics = NULL; + return Successful; + } + + if( instance->available[segment][offset] >= FT_AVAILABLE_METRICS ) { + *metrics = &instance->glyphs[segment][offset].metrics; + return Successful; + } + + flags |= FT_GET_GLYPH_METRICS_ONLY; + + xrc = FreeTypeRasteriseGlyph(idx, flags, + &instance->glyphs[segment][offset], + instance, 0); + if(xrc == Successful) { + instance->available[segment][offset] = FT_AVAILABLE_METRICS; + *metrics = &instance->glyphs[segment][offset].metrics; + } + return xrc; +} + +/* + * Pseudo enbolding similar as Microsoft Windows. + * It is useful but poor. + */ +static void +ft_make_up_bold_bitmap( char *raster, int bpr, int ht, int ds_mode) +{ + int x, y; + unsigned char *p = (unsigned char *)raster; + if ( ds_mode & TTCAP_DOUBLE_STRIKE_MKBOLD_EDGE_LEFT ) { + for (y=0; y<ht; y++) { + unsigned char rev_pat=0; + unsigned char lsb = 0; + for (x=0; x<bpr; x++) { + unsigned char tmp = *p<<7; + if ( (rev_pat & 0x01) && (*p & 0x80) ) p[-1] &= 0xfe; + rev_pat = ~(*p); + *p |= (*p>>1) | lsb; + *p &= ~(rev_pat & (*p << 1)); + lsb = tmp; + p++; + } + } + } + else { + for (y=0; y<ht; y++) { + unsigned char lsb = 0; + for (x=0; x<bpr; x++) { + unsigned char tmp = *p<<7; + *p |= (*p>>1) | lsb; + lsb = tmp; + p++; + } + } + } +} + +static void +ft_make_up_italic_bitmap( char *raster, int bpr, int ht, int shift, + int h_total, int h_offset, double a_italic) +{ + int x, y; + unsigned char *p = (unsigned char *)raster; + if ( a_italic < 0 ) shift = -shift; + for (y=0; y<ht; y++) { + unsigned char *tmp_p = p + y*bpr; + int tmp_shift = shift * (h_total -1 -(y+h_offset)) / h_total; + int tmp_byte_shift; + if ( 0 <= tmp_shift ) { + tmp_byte_shift = tmp_shift/8; + tmp_shift %= 8; + if ( tmp_shift ) { + for (x=bpr-1;0<=x;x--) { + if ( x != bpr-1 ) + tmp_p[x+1] |= tmp_p[x]<<(8-tmp_shift); + tmp_p[x]>>=tmp_shift; + } + } + if ( tmp_byte_shift ) { + for (x=bpr-1;0<x;x--) { + tmp_p[x] = tmp_p[x-1]; + } + tmp_p[x]=0; + } + } + else { + tmp_shift = -tmp_shift; + tmp_byte_shift = tmp_shift/8; + tmp_shift %= 8; + if ( tmp_shift ) { + for (x=0;x<bpr;x++) { + if ( x != 0 ) + tmp_p[x-1] |= tmp_p[x]>>(8-tmp_shift); + tmp_p[x]<<=tmp_shift; + } + } + if ( tmp_byte_shift ) { + for (x=0;x<bpr-1;x++) { + tmp_p[x] = tmp_p[x+1]; + } + tmp_p[x]=0; + } + } + } +} + +/* + * The very lazy method, + * parse the htmx field in TrueType font. + */ + +/* from src/truetype/ttgload.c */ +static void +tt_get_metrics( TT_HoriHeader* header, + FT_UInt idx, + FT_Short* bearing, + FT_UShort* advance ) +/* Copyright 1996-2001, 2002 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +{ + TT_LongMetrics longs_m; + FT_UShort k = header->number_Of_HMetrics; + + if ( k == 0 ) { + *bearing = *advance = 0; + return; + } + + if ( idx < (FT_UInt)k ) { + longs_m = (TT_LongMetrics )header->long_metrics + idx; + *bearing = longs_m->bearing; + *advance = longs_m->advance; + } + else { + *bearing = ((TT_ShortMetrics*)header->short_metrics)[idx - k]; + *advance = ((TT_LongMetrics )header->long_metrics)[k - 1].advance; + } +} + +static int +ft_get_very_lazy_bbox( FT_UInt index, + FT_Face face, + FT_Size size, + double slant, + FT_Matrix *matrix, + FT_BBox *bbox, + FT_Long *horiAdvance, + FT_Long *vertAdvance) +{ + if ( FT_IS_SFNT( face ) ) { + TT_Face ttface = (TT_Face)face; + FT_Size_Metrics *smetrics = &size->metrics; + FT_Short leftBearing = 0; + FT_UShort advance = 0; + FT_Vector p0, p1, p2, p3; + + /* horizontal */ + tt_get_metrics(&ttface->horizontal, index, + &leftBearing, &advance); + +#if 0 + fprintf(stderr,"x_scale=%f y_scale=%f\n", + (double)smetrics->x_scale,(double)smetrics->y_scale); +#endif + bbox->xMax = *horiAdvance = + FT_MulFix( advance, smetrics->x_scale ); + bbox->xMin = + FT_MulFix( leftBearing, smetrics->x_scale ); + /* vertical */ + bbox->yMin = FT_MulFix( face->bbox.yMin, + smetrics->y_scale ); + bbox->yMax = FT_MulFix( face->bbox.yMax, + smetrics->y_scale ); + /* slant */ + if( 0 < slant ) { + bbox->xMax += slant * bbox->yMax; + bbox->xMin += slant * bbox->yMin; + } + else if( slant < 0 ) { + bbox->xMax += slant * bbox->yMin; + bbox->xMin += slant * bbox->yMax; + } + + *vertAdvance = -1; /* We don't support */ + + p0.x = p2.x = bbox->xMin; + p1.x = p3.x = bbox->xMax; + p0.y = p1.y = bbox->yMin; + p2.y = p3.y = bbox->yMax; + + FT_Vector_Transform(&p0, matrix); + FT_Vector_Transform(&p1, matrix); + FT_Vector_Transform(&p2, matrix); + FT_Vector_Transform(&p3, matrix); + +#if 0 + fprintf(stderr, + "->(%.1f %.1f) (%.1f %.1f)" + " (%.1f %.1f) (%.1f %.1f)\n", + p0.x / 64.0, p0.y / 64.0, + p1.x / 64.0, p1.y / 64.0, + p2.x / 64.0, p2.y / 64.0, + p3.x / 64.0, p3.y / 64.0); +#endif + bbox->xMin = MIN(p0.x, MIN(p1.x, MIN(p2.x, p3.x))); + bbox->xMax = MAX(p0.x, MAX(p1.x, MAX(p2.x, p3.x))); + bbox->yMin = MIN(p0.y, MIN(p1.y, MIN(p2.y, p3.y))); + bbox->yMax = MAX(p0.y, MAX(p1.y, MAX(p2.y, p3.y))); + return 0; /* Successful */ + } + return -1; +} + +static FT_Error +FT_Do_SBit_Metrics( FT_Face ft_face, FT_Size ft_size, FT_ULong strike_index, + FT_UShort glyph_index, FT_Glyph_Metrics *metrics_return, + int *sbitchk_incomplete_but_exist ) +{ +#if (FREETYPE_VERSION >= 2001008) + SFNT_Service sfnt; + TT_Face face; + FT_Error error; + FT_Stream stream; + TT_SBit_Strike strike; + TT_SBit_Range range; + TT_SBit_MetricsRec elem_metrics; + FT_ULong ebdt_pos; + FT_ULong glyph_offset; + ; + + if ( ! FT_IS_SFNT( ft_face ) ) + { + error=-1; + goto Exit; + } + + face = (TT_Face)ft_face; + sfnt = (SFNT_Service)face->sfnt; + + if (strike_index != 0xFFFFU && sfnt && sfnt->find_sbit_image && + sfnt->load_sbits) { + /* Check whether there is a glyph sbit for the current index */ + error = sfnt->find_sbit_image( face, glyph_index, strike_index, + &range, &strike, &glyph_offset ); + } + else error=-1; + if ( error ) goto Exit; + + if ( metrics_return == NULL ) goto Exit; + + stream = face->root.stream; + + /* now, find the location of the `EBDT' table in */ + /* the font file */ + error = face->goto_table( face, TTAG_EBDT, stream, 0 ); + if ( error ) + error = face->goto_table( face, TTAG_bdat, stream, 0 ); + if (error) + goto Exit; + + ebdt_pos = FT_STREAM_POS(); + + /* place stream at beginning of glyph data and read metrics */ + if ( FT_STREAM_SEEK( ebdt_pos + glyph_offset ) ) + goto Exit; + + error = sfnt->load_sbit_metrics( stream, range, &elem_metrics ); + if ( error ) + goto Exit; + + metrics_return->width = (FT_Pos)elem_metrics.width << 6; + metrics_return->height = (FT_Pos)elem_metrics.height << 6; + + metrics_return->horiBearingX = (FT_Pos)elem_metrics.horiBearingX << 6; + metrics_return->horiBearingY = (FT_Pos)elem_metrics.horiBearingY << 6; + metrics_return->horiAdvance = (FT_Pos)elem_metrics.horiAdvance << 6; + + metrics_return->vertBearingX = (FT_Pos)elem_metrics.vertBearingX << 6; + metrics_return->vertBearingY = (FT_Pos)elem_metrics.vertBearingY << 6; + metrics_return->vertAdvance = (FT_Pos)elem_metrics.vertAdvance << 6; + + Exit: + return error; +#else /* if (FREETYPE_VERSION < 2001008) */ + TT_Face face; + SFNT_Service sfnt; + if ( ! FT_IS_SFNT( ft_face ) ) return -1; + face = (TT_Face)ft_face; + sfnt = (SFNT_Service)face->sfnt; + if ( strike_index != 0xFFFFU && sfnt->load_sbits ) { + if ( sbitchk_incomplete_but_exist ) *sbitchk_incomplete_but_exist=1; + } + return -1; +#endif +} + +int +FreeTypeRasteriseGlyph(unsigned idx, int flags, CharInfoPtr tgp, + FTInstancePtr instance, int hasMetrics) +{ + FTFacePtr face; + FT_BBox bbox; + FT_Long outline_hori_advance, outline_vert_advance; + FT_Glyph_Metrics sbit_metrics; + FT_Glyph_Metrics *bitmap_metrics=NULL, *metrics = NULL; + char *raster; + int wd, ht, bpr; /* width, height, bytes per row */ + int wd_actual, ht_actual; + int ftrc, is_outline, correct, b_shift=0; + int dx, dy; + int leftSideBearing, rightSideBearing, characterWidth, rawCharacterWidth, + ascent, descent; + int sbitchk_incomplete_but_exist; + double bbox_center_raw; + + face = instance->face; + + FreeTypeActivateInstance(instance); + + if(!tgp) return AllocError; + + /* + * PREPARE METRICS + */ + + if(!hasMetrics) { + if( instance->spacing == FT_CHARCELL || flags & FT_GET_DUMMY ){ + memcpy((char*)&tgp->metrics, + (char*)instance->charcellMetrics, + sizeof(xCharInfo)); + } + else if( flags & FT_FORCE_CONSTANT_SPACING ) { + memcpy((char*)&tgp->metrics, + (char*)instance->forceConstantMetrics, + sizeof(xCharInfo)); + } + /* mono or prop. */ + else{ + int new_width; + double ratio; + + sbitchk_incomplete_but_exist=0; + if( ! (instance->load_flags & FT_LOAD_NO_BITMAP) ) { + if( FT_Do_SBit_Metrics(face->face,instance->size,instance->strike_index, + idx,&sbit_metrics,&sbitchk_incomplete_but_exist)==0 ) { + bitmap_metrics = &sbit_metrics; + } + } + if( bitmap_metrics == NULL ) { + if ( sbitchk_incomplete_but_exist==0 && (instance->ttcap.flags & TTCAP_IS_VERY_LAZY) ) { + if( ft_get_very_lazy_bbox( idx, face->face, instance->size, + instance->ttcap.vl_slant, + &instance->transformation.matrix, + &bbox, &outline_hori_advance, + &outline_vert_advance ) == 0 ) { + goto bbox_ok; /* skip exact calculation */ + } + } + ftrc = FT_Load_Glyph(instance->face->face, idx, + instance->load_flags); + if(ftrc != 0) return FTtoXReturnCode(ftrc); + metrics = &face->face->glyph->metrics; + if( face->face->glyph->format == FT_GLYPH_FORMAT_BITMAP ) { + bitmap_metrics = metrics; + } + } + + if( bitmap_metrics ) { + FT_Pos factor; + + leftSideBearing = bitmap_metrics->horiBearingX / 64; + rightSideBearing = (bitmap_metrics->width + bitmap_metrics->horiBearingX) / 64; + bbox_center_raw = (2.0 * bitmap_metrics->horiBearingX + bitmap_metrics->width)/2.0/64.0; + characterWidth = (int)floor(bitmap_metrics->horiAdvance + * instance->ttcap.scaleBBoxWidth / 64.0 + .5); + ascent = bitmap_metrics->horiBearingY / 64; + descent = (bitmap_metrics->height - bitmap_metrics->horiBearingY) / 64 ; + /* */ + new_width = characterWidth; + if( instance->ttcap.flags & TTCAP_DOUBLE_STRIKE_CORRECT_B_BOX_WIDTH ) + new_width += instance->ttcap.doubleStrikeShift; + new_width += instance->ttcap.adjustBBoxWidthByPixel; + ratio = (double)new_width/characterWidth; + characterWidth = new_width; + /* adjustment by pixel unit */ + if( instance->ttcap.flags & TTCAP_DOUBLE_STRIKE ) + rightSideBearing += instance->ttcap.doubleStrikeShift; + rightSideBearing += instance->ttcap.adjustRightSideBearingByPixel; + leftSideBearing += instance->ttcap.adjustLeftSideBearingByPixel; + rightSideBearing += instance->ttcap.rsbShiftOfBitmapAutoItalic; + leftSideBearing += instance->ttcap.lsbShiftOfBitmapAutoItalic; + /* */ + factor = bitmap_metrics->horiAdvance; + rawCharacterWidth = (unsigned short)(short)(floor(1000 * factor + * instance->ttcap.scaleBBoxWidth * ratio / 64. + / instance->pixel_size)); + } + else { + /* Outline */ +#ifdef USE_GET_CBOX + /* Very fast?? */ + FT_Outline_Get_CBox(&face->face->glyph->outline, &bbox); + ftrc=0; /* FT_Outline_Get_CBox returns nothing. */ +#else + /* Calculate exact metrics */ + ftrc=FT_Outline_Get_BBox(&face->face->glyph->outline, &bbox); +#endif + if( ftrc != 0 ) return FTtoXReturnCode(ftrc); + outline_hori_advance = metrics->horiAdvance; + outline_vert_advance = metrics->vertAdvance; + bbox_ok: + descent = CEIL64(-bbox.yMin - 32) / 64; + leftSideBearing = FLOOR64(bbox.xMin + 32) / 64; + ascent = FLOOR64(bbox.yMax + 32) / 64; + rightSideBearing = FLOOR64(bbox.xMax + 32) / 64; + bbox_center_raw = (double)(bbox.xMax + bbox.xMin)/2.0/64.; + if ( instance->pixel_width_unit_x != 0 ) + characterWidth = + (int)floor( outline_hori_advance + * instance->ttcap.scaleBBoxWidth + * instance->pixel_width_unit_x / 64. + .5); + else { + characterWidth = + (int)floor( outline_vert_advance + * instance->ttcap.scaleBBoxHeight + * instance->pixel_width_unit_y / 64. + .5); + if(characterWidth <= 0) + characterWidth = instance->charcellMetrics->characterWidth; + } + /* */ + new_width = characterWidth; + if( instance->ttcap.flags & TTCAP_DOUBLE_STRIKE_CORRECT_B_BOX_WIDTH ) + new_width += instance->ttcap.doubleStrikeShift; + new_width += instance->ttcap.adjustBBoxWidthByPixel; + ratio = (double)new_width/characterWidth; + characterWidth = new_width; + if ( instance->pixel_width_unit_x != 0 ) + rawCharacterWidth = + (unsigned short)(short)(floor(1000 * outline_hori_advance + * instance->ttcap.scaleBBoxWidth * ratio + * instance->pixel_width_unit_x / 64.)); + else { + rawCharacterWidth = + (unsigned short)(short)(floor(1000 * outline_vert_advance + * instance->ttcap.scaleBBoxHeight * ratio + * instance->pixel_width_unit_y / 64.)); + if(rawCharacterWidth <= 0) + rawCharacterWidth = instance->charcellMetrics->attributes; + } + /* adjustment by pixel unit */ + if( instance->ttcap.flags & TTCAP_DOUBLE_STRIKE ) + rightSideBearing += instance->ttcap.doubleStrikeShift; + rightSideBearing += instance->ttcap.adjustRightSideBearingByPixel; + leftSideBearing += instance->ttcap.adjustLeftSideBearingByPixel; + } + + /* Set the glyph metrics. */ + tgp->metrics.attributes = (unsigned short)((short)rawCharacterWidth); + tgp->metrics.leftSideBearing = leftSideBearing; + tgp->metrics.rightSideBearing = rightSideBearing; + tgp->metrics.characterWidth = characterWidth; + tgp->metrics.ascent = ascent; + tgp->metrics.descent = descent; + /* Update the width to match the width of the font */ + if( instance->spacing != FT_PROPORTIONAL ) + tgp->metrics.characterWidth = instance->charcellMetrics->characterWidth; + if(instance->ttcap.flags & TTCAP_MONO_CENTER){ + b_shift = (int)floor((instance->advance/2.0-bbox_center_raw) + .5); + tgp->metrics.leftSideBearing += b_shift; + tgp->metrics.rightSideBearing += b_shift; + } + } + } + + if( flags & FT_GET_GLYPH_METRICS_ONLY ) return Successful; + + /* + * CHECK THE NECESSITY OF BITMAP POSITION'S CORRECTION + */ + + correct=0; + if( instance->spacing == FT_CHARCELL ) correct=1; + else if( flags & FT_FORCE_CONSTANT_SPACING ) correct=1; + else{ + int sbit_available=0; + sbitchk_incomplete_but_exist=0; + if( !(instance->load_flags & FT_LOAD_NO_BITMAP) ) { + if( FT_Do_SBit_Metrics(face->face,instance->size, + instance->strike_index,idx,NULL, + &sbitchk_incomplete_but_exist)==0 ) { + sbit_available=1; + } + } + if( sbit_available == 0 ) { + if ( sbitchk_incomplete_but_exist==0 && (instance->ttcap.flags & TTCAP_IS_VERY_LAZY) ) { + if( FT_IS_SFNT(face->face) ) correct=1; + } + } + } + + /* + * RENDER AND ALLOCATE BUFFER + */ + + if( flags & FT_GET_DUMMY ) is_outline = -1; + else { + if( !metrics ) { + ftrc = FT_Load_Glyph(instance->face->face, idx, + instance->load_flags); + metrics = &face->face->glyph->metrics; + + if(ftrc != 0) return FTtoXReturnCode(ftrc); + } + + if( face->face->glyph->format != FT_GLYPH_FORMAT_BITMAP ) { + ftrc = FT_Render_Glyph(face->face->glyph,FT_RENDER_MODE_MONO); + if( ftrc != 0 ) return FTtoXReturnCode(ftrc); + is_outline = 1; + } + else{ + is_outline=0; + } + } + + /* Spacial case */ + if( (instance->ttcap.flags & TTCAP_MONO_CENTER) && hasMetrics ) { + if( is_outline == 1 ){ + if( correct ){ + if( ft_get_very_lazy_bbox( idx, face->face, instance->size, + instance->ttcap.vl_slant, + &instance->transformation.matrix, + &bbox, &outline_hori_advance, + &outline_vert_advance ) != 0 ){ + is_outline = -1; /* <- error */ + } + } + else { +#ifdef USE_GET_CBOX + FT_Outline_Get_CBox(&face->face->glyph->outline, &bbox); + ftrc=0; +#else + ftrc=FT_Outline_Get_BBox(&face->face->glyph->outline, &bbox); +#endif + if( ftrc != 0 ) return FTtoXReturnCode(ftrc); + } + bbox_center_raw = (double)(bbox.xMax + bbox.xMin)/2.0/64.; + } + else if( is_outline == 0 ) + bbox_center_raw = (2.0 * metrics->horiBearingX + metrics->width)/2.0/64.0; + else + bbox_center_raw = 0; + b_shift = (int)floor((instance->advance/2.0-bbox_center_raw) + .5); + } + + wd_actual = tgp->metrics.rightSideBearing - tgp->metrics.leftSideBearing; + ht_actual = tgp->metrics.ascent + tgp->metrics.descent; + + /* The X convention is to consider a character with an empty + * bounding box as undefined. This convention is broken. */ + + if(wd_actual <= 0) wd = 1; + else wd=wd_actual; + if(ht_actual <= 0) ht = 1; + else ht=ht_actual; + + bpr = (((wd + (instance->bmfmt.glyph<<3) - 1) >> 3) & + -instance->bmfmt.glyph); + raster = (char*)xalloc(ht * bpr); + if(raster == NULL) + return AllocError; + memset(raster, 0, ht * bpr); + + tgp->bits = raster; + + /* If FT_GET_DUMMY is set, we return white space. */ + if ( is_outline == -1 ) return Successful; + + if ( wd_actual <= 0 || ht_actual <= 0 ) return Successful; + + /* + * CALCULATE OFFSET, dx AND dy. + */ + + dx = face->face->glyph->bitmap_left - tgp->metrics.leftSideBearing; + dy = tgp->metrics.ascent - face->face->glyph->bitmap_top; + + if(instance->ttcap.flags & TTCAP_MONO_CENTER) + dx += b_shift; + + /* To prevent chipped bitmap, we correct dx and dy if needed. */ + if( correct && is_outline==1 ){ + int lsb, rsb, asc, des; + int chip_left,chip_right,chip_top,chip_bot; +#ifdef USE_GET_CBOX + FT_Outline_Get_CBox(&face->face->glyph->outline, &bbox); + ftrc=0; +#else + ftrc=FT_Outline_Get_BBox(&face->face->glyph->outline, &bbox); +#endif + if( ftrc != 0 ) return FTtoXReturnCode(ftrc); + des = CEIL64(-bbox.yMin - 32) / 64; + lsb = FLOOR64(bbox.xMin + 32) / 64; + asc = FLOOR64(bbox.yMax + 32) / 64; + rsb = FLOOR64(bbox.xMax + 32) / 64; + rightSideBearing = tgp->metrics.rightSideBearing; + leftSideBearing = tgp->metrics.leftSideBearing; + if( instance->ttcap.flags & TTCAP_DOUBLE_STRIKE ) + rightSideBearing -= instance->ttcap.doubleStrikeShift; + /* special case */ + if(instance->ttcap.flags & TTCAP_MONO_CENTER){ + leftSideBearing -= b_shift; + rightSideBearing -= b_shift; + } + chip_left = lsb - leftSideBearing; + chip_right = rightSideBearing - rsb; + if( flags & FT_FORCE_CONSTANT_SPACING ){ + if( instance->ttcap.force_c_adjust_lsb_by_pixel != 0 || + instance->ttcap.force_c_adjust_rsb_by_pixel != 0 ){ + chip_left=0; + chip_right=0; + } + } + else{ + if( instance->ttcap.adjustRightSideBearingByPixel != 0 || + instance->ttcap.adjustLeftSideBearingByPixel != 0 ){ + chip_left=0; + chip_right=0; + } + } + chip_top = tgp->metrics.ascent - asc; + chip_bot = tgp->metrics.descent - des; + if( chip_left < 0 && 0 < chip_right ) dx++; + else if( chip_right < 0 && 0 < chip_left ) dx--; + if( chip_top < 0 && 0 < chip_bot ) dy++; + else if( chip_bot < 0 && 0 < chip_top ) dy--; + } + + /* + * COPY RASTER + */ + + { + FT_Bitmap *bitmap; + int i, j; + unsigned char *current_raster; + unsigned char *current_buffer; + int mod_dx0,mod_dx1; + int div_dx; + bitmap = &face->face->glyph->bitmap; + if( 0 <= dx ){ + div_dx = dx / 8; + mod_dx0 = dx % 8; + mod_dx1 = 8-mod_dx0; + } + else{ + div_dx = dx / 8 -1; + mod_dx1 = -dx % 8; + mod_dx0 = 8-mod_dx1; + } + for( i = MAX(0, dy) ; i<ht ; i++ ){ + int prev_jj,jj; + if( bitmap->rows <= i-dy ) break; + current_buffer=(unsigned char *)(bitmap->buffer+bitmap->pitch*(i-dy)); + current_raster=(unsigned char *)(raster+i*bpr); + j = MAX(0,div_dx); + jj = j-div_dx; + prev_jj = jj-1; + if( j<bpr ){ + if( 0 <= prev_jj && prev_jj < bitmap->pitch ) + current_raster[j]|=current_buffer[prev_jj]<<mod_dx1; + if( 0 <= jj && jj < bitmap->pitch ){ + current_raster[j]|=current_buffer[jj]>>mod_dx0; + j++; prev_jj++; jj++; + for( ; j<bpr ; j++,prev_jj++,jj++ ){ + current_raster[j]|=current_buffer[prev_jj]<<mod_dx1; + if( bitmap->pitch <= jj ) break; + current_raster[j]|=current_buffer[jj]>>mod_dx0; + } + } + } + } + } + + /* by TTCap */ + if ( instance->ttcap.flags & TTCAP_DOUBLE_STRIKE ) { + int i; + for( i=0 ; i < instance->ttcap.doubleStrikeShift ; i++ ) + ft_make_up_bold_bitmap( raster, bpr, ht, instance->ttcap.flags); + } + if ( is_outline == 0 && + ( instance->ttcap.lsbShiftOfBitmapAutoItalic != 0 || + instance->ttcap.rsbShiftOfBitmapAutoItalic != 0 ) ) { + ft_make_up_italic_bitmap( raster, bpr, ht, + - instance->ttcap.lsbShiftOfBitmapAutoItalic + + instance->ttcap.rsbShiftOfBitmapAutoItalic, + instance->charcellMetrics->ascent + + instance->charcellMetrics->descent, + instance->charcellMetrics->ascent + - tgp->metrics.ascent, + instance->ttcap.autoItalic); + } + + if(instance->bmfmt.bit == LSBFirst) { + BitOrderInvert((unsigned char*)(tgp->bits), ht*bpr); + } + + if(instance->bmfmt.byte != instance->bmfmt.bit) { + switch(instance->bmfmt.scan) { + case 1: + break; + case 2: + TwoByteSwap((unsigned char*)(tgp->bits), ht*bpr); + break; + case 4: + FourByteSwap((unsigned char*)(tgp->bits), ht*bpr); + break; + default: + ; + } + } + + return Successful; +} + +static void +FreeTypeFreeFont(FTFontPtr font) +{ + FreeTypeFreeInstance(font->instance); + if(font->ranges) + xfree(font->ranges); + if(font->dummy_char.bits) + xfree(font->dummy_char.bits); + xfree(font); +} + +/* Free a font. If freeProps is 0, don't free the properties. */ + +static void +FreeTypeFreeXFont(FontPtr pFont, int freeProps) +{ + FTFontPtr tf; + + if(pFont) { + if((tf = (FTFontPtr)pFont->fontPrivate)) { + FreeTypeFreeFont(tf); + } + if(freeProps && pFont->info.nprops>0) { + xfree(pFont->info.isStringProp); + xfree(pFont->info.props); + } + DestroyFontRec(pFont); + } +} + + +/* Unload a font */ + +static void +FreeTypeUnloadXFont(FontPtr pFont) +{ + MUMBLE("Unloading\n"); + FreeTypeFreeXFont(pFont, 1); +} + +/* Add the font properties, including the Font name, the XLFD + properties, some strings from the font, and various typographical + data. We only provide data readily available in the tables in the + font for now, altough FIGURE_WIDTH would be a good idea as it is + used by Xaw. */ + +static int +FreeTypeAddProperties(FTFontPtr font, FontScalablePtr vals, FontInfoPtr info, + char *fontname, int rawAverageWidth, Bool font_properties) +{ + int i, j, maxprops; + char *sp, *ep, val[MAXFONTNAMELEN], *vp; + FTFacePtr face; + FTInstancePtr instance; + FTNormalisedTransformationPtr trans; + int upm; + TT_OS2 *os2; + TT_Postscript *post; + PS_FontInfoRec t1info_rec, *t1info; + int xlfdProps = 0; + int ftrc; + + instance = font->instance; + face = instance->face; + trans = &instance->transformation; + upm = face->face->units_per_EM; + if(upm == 0) { + /* Work around FreeType bug */ + upm = WORK_AROUND_UPM; + } + + os2 = FT_Get_Sfnt_Table(face->face, ft_sfnt_os2); + post = FT_Get_Sfnt_Table(face->face, ft_sfnt_post); + ftrc = FT_Get_PS_Font_Info(face->face, &t1info_rec); + if(ftrc == 0) + t1info = &t1info_rec; + else + t1info = NULL; + + if(t1info) { + os2 = NULL; + post = NULL; + } + + info->nprops = 0; /* in case we abort */ + + strcpy(val, fontname); + if(FontParseXLFDName(val, vals, FONT_XLFD_REPLACE_VALUE)) { + xlfdProps = 1; + } else { + MUMBLE("Couldn't parse XLFD\n"); + xlfdProps = 0; + } + + maxprops= + 1 + /* NAME */ + (xlfdProps ? 14 : 0) + /* from XLFD */ + 5 + + ( !face->bitmap ? 3 : 0 ) + /* raw_av,raw_asc,raw_dec */ + ( font_properties ? 2 : 0 ) + /* asc,dec */ + ( (font_properties && os2) ? 6 : 0 ) + + ( (font_properties && (post || t1info)) ? 3 : 0 ) + + 2; /* type */ + + info->props = (FontPropPtr)xalloc(maxprops * sizeof(FontPropRec)); + if(info->props == NULL) + return AllocError; + + info->isStringProp = (char*)xalloc(maxprops); + if(info->isStringProp == NULL) { + xfree(info->props); + return AllocError; + } + + memset((char *)info->isStringProp, 0, maxprops); + + i = 0; + + info->props[i].name = MakeAtom("FONT", 4, TRUE); + info->props[i].value = MakeAtom(val, strlen(val), TRUE); + info->isStringProp[i] = 1; + i++; + + if(*val && *(sp = val + 1)) { + for (j = 0, sp = val + 1; j < 14; j++) { + if (j == 13) + /* Handle the case of the final field containing a subset + specification. */ + for (ep = sp; *ep && *ep != '['; ep++); + else + for (ep = sp; *ep && *ep != '-'; ep++); + + info->props[i].name = + MakeAtom(xlfd_props[j], strlen(xlfd_props[j]), TRUE); + + switch(j) { + case 6: /* pixel size */ + info->props[i].value = + (int)(fabs(vals->pixel_matrix[3]) + 0.5); + i++; + break; + case 7: /* point size */ + info->props[i].value = + (int)(fabs(vals->point_matrix[3])*10.0 + 0.5); + i++; + break; + case 8: /* resolution x */ + info->props[i].value = vals->x; + i++; + break; + case 9: /* resolution y */ + info->props[i].value = vals->y; + i++; + break; + case 11: /* average width */ + info->props[i].value = vals->width; + i++; + break; + default: /* a string */ + info->props[i].value = MakeAtom(sp, ep - sp, TRUE); + info->isStringProp[i] = 1; + i++; + } + sp = ++ep; + } + } + + info->props[i].name = MakeAtom("RAW_PIXEL_SIZE", 14, TRUE); + info->props[i].value = 1000; + i++; + + info->props[i].name = MakeAtom("RAW_POINT_SIZE", 14, TRUE); + info->props[i].value = (long)(72270.0 / (double)vals->y + .5); + i++; + + if(!face->bitmap) { + info->props[i].name = MakeAtom("RAW_AVERAGE_WIDTH", 17, TRUE); + info->props[i].value = rawAverageWidth; + i++; + } + + if ( font_properties ) { + info->props[i].name = MakeAtom("FONT_ASCENT", 11, TRUE); + info->props[i].value = info->fontAscent; + i++; + } + + if(!face->bitmap) { + info->props[i].name = MakeAtom("RAW_ASCENT", 10, TRUE); + info->props[i].value = + ((double)face->face->ascender/(double)upm*1000.0); + i++; + } + + if ( font_properties ) { + info->props[i].name = MakeAtom("FONT_DESCENT", 12, TRUE); + info->props[i].value = info->fontDescent; + i++; + } + + if(!face->bitmap) { + info->props[i].name = MakeAtom("RAW_DESCENT", 11, TRUE); + info->props[i].value = + -((double)face->face->descender/(double)upm*1000.0); + i++; + } + + j = FTGetEnglishName(face->face, TT_NAME_ID_COPYRIGHT, + val, MAXFONTNAMELEN); + vp = val; + if (j < 0) { + if(t1info && t1info->notice) { + vp = t1info->notice; + j = strlen(vp); + } + } + if(j > 0) { + info->props[i].name = MakeAtom("COPYRIGHT", 9, TRUE); + info->props[i].value = MakeAtom(vp, j, TRUE); + info->isStringProp[i] = 1; + i++; + } + + j = FTGetEnglishName(face->face, TT_NAME_ID_FULL_NAME, + val, MAXFONTNAMELEN); + vp = val; + if (j < 0) { + if(t1info && t1info->full_name) { + vp = t1info->full_name; + j = strlen(vp); + } + } + if(j > 0) { + info->props[i].name = MakeAtom("FACE_NAME", 9, TRUE); + info->props[i].value = MakeAtom(vp, j, TRUE); + info->isStringProp[i] = 1; + i++; + } + + vp = (char *)FT_Get_Postscript_Name(face->face); + if (vp) { + j = strlen(vp); + } else { + j = -1; + } + if (j < 0) { + j = FTGetEnglishName(face->face, TT_NAME_ID_PS_NAME, + val, MAXFONTNAMELEN); + vp = val; + } + if (j < 0) { + if(t1info && t1info->full_name) { + vp = t1info->full_name; + j = strlen(vp); + } + } + if(j > 0) { + info->props[i].name = MakeAtom("_ADOBE_POSTSCRIPT_FONTNAME", 26, TRUE); + info->props[i].value = MakeAtom(vp, j, TRUE); + info->isStringProp[i] = 1; + i++; + } + + /* These macros handle the case of a diagonal matrix. They convert + FUnits into pixels. */ +#define TRANSFORM_FUNITS_X(xval) \ + ((int) \ + floor( ((double)(xval)/(double)upm) * (double)vals->pixel_matrix[0] + 0.5 ) ) + +#define TRANSFORM_FUNITS_Y(yval) \ + ((int) \ + floor( ((double)(yval)/(double)upm) * (double)vals->pixel_matrix[3] + 0.5 ) ) + + /* In what follows, we assume the matrix is diagonal. In the rare + case when it is not, the values will be somewhat wrong. */ + + if( font_properties && os2 ) { + info->props[i].name = MakeAtom("SUBSCRIPT_SIZE",14,TRUE); + info->props[i].value = + TRANSFORM_FUNITS_Y(os2->ySubscriptYSize); + i++; + info->props[i].name = MakeAtom("SUBSCRIPT_X",11,TRUE); + info->props[i].value = + TRANSFORM_FUNITS_X(os2->ySubscriptXOffset); + i++; + info->props[i].name = MakeAtom("SUBSCRIPT_Y",11,TRUE); + info->props[i].value = + TRANSFORM_FUNITS_Y(os2->ySubscriptYOffset); + i++; + info->props[i].name = MakeAtom("SUPERSCRIPT_SIZE",16,TRUE); + info->props[i].value = + TRANSFORM_FUNITS_Y(os2->ySuperscriptYSize); + i++; + info->props[i].name = MakeAtom("SUPERSCRIPT_X",13,TRUE); + info->props[i].value = + TRANSFORM_FUNITS_X(os2->ySuperscriptXOffset); + i++; + info->props[i].name = MakeAtom("SUPERSCRIPT_Y",13,TRUE); + info->props[i].value = + TRANSFORM_FUNITS_Y(os2->ySuperscriptYOffset); + i++; + } + + if( font_properties && (post || t1info) ) { + int underlinePosition, underlineThickness; + + /* Raw underlineposition counts upwards, + but UNDERLINE_POSITION counts downwards. */ + if(post) { + underlinePosition = TRANSFORM_FUNITS_Y(-post->underlinePosition); + underlineThickness = TRANSFORM_FUNITS_Y(post->underlineThickness); + } else { + underlinePosition = + TRANSFORM_FUNITS_Y(-t1info->underline_position); + underlineThickness = + TRANSFORM_FUNITS_Y(t1info->underline_thickness); + } + if(underlineThickness <= 0) + underlineThickness = 1; + + info->props[i].name = MakeAtom("UNDERLINE_THICKNESS",19,TRUE); + info->props[i].value = underlineThickness; + i++; + + info->props[i].name = MakeAtom("UNDERLINE_POSITION",18,TRUE); + + info->props[i].value = underlinePosition; + + i++; + + /* The italic angle is often unreliable for Type 1 fonts */ + if(post && trans->matrix.xx == trans->matrix.yy) { + info->props[i].name = MakeAtom("ITALIC_ANGLE",12,TRUE); + info->props[i].value = + /* Convert from TT_Fixed to + 64th of a degree counterclockwise from 3 o'clock */ + 90*64+(post->italicAngle >> 10); + i++; + } +#undef TRANSFORM_FUNITS_X +#undef TRANSFORM_FUNITS_Y + } + + info->props[i].name = MakeAtom("FONT_TYPE", 9, TRUE); + vp = (char *)FT_Get_X11_Font_Format(face->face); + info->props[i].value = MakeAtom(vp, strlen(vp), TRUE); + info->isStringProp[i] = 1; + i++; + + info->props[i].name = MakeAtom("RASTERIZER_NAME", 15, TRUE); + info->props[i].value = MakeAtom("FreeType", 10, TRUE); + info->isStringProp[i] = 1; + i++; + + info->nprops = i; + return Successful; +} + +static int +ft_get_index(unsigned code, FTFontPtr font, unsigned *idx) +{ + + /* As a special case, we pass 0 even when it is not in the ranges; + this will allow for the default glyph, which should exist in any + TrueType font. */ + + /* This is not required... + if(code > 0 && font->nranges) { + int i; + for(i = 0; i < font->nranges; i++) + if((code >= + font->ranges[i].min_char_low+ + (font->ranges[i].min_char_high<<8)) && + (code <= + font->ranges[i].max_char_low + + (font->ranges[i].max_char_high<<8))) + break; + if(i == font->nranges) { + *idx = font->zero_idx; + return -1; + } + } + */ + if( font->info ) { + if( !( font->info->firstCol <= (code & 0x000ff) && + (code & 0x000ff) <= font->info->lastCol && + font->info->firstRow <= (code >> 8) && + (code >> 8) <= font->info->lastRow ) ) { + *idx = font->zero_idx; + /* Error: The code has not been parsed in ft_compute_bounds()! + We should not return any metrics. */ + return -1; + } + } + + *idx = FTRemap(font->instance->face->face, &font->mapping, code); + + return 0; +} + +static int +FreeTypeFontGetGlyph(unsigned code, int flags, CharInfoPtr *g, FTFontPtr font) +{ + unsigned idx = 0; + int xrc; + +#ifdef X_ACCEPTS_NO_SUCH_CHAR + if( ft_get_index(code,font,&idx) || idx == 0 || idx == font->zero_idx ) { + *g = NULL; + flags &= ~FT_FORCE_CONSTANT_SPACING; + /* if( font->instance->spacing != FT_CHARCELL ) */ + return Successful; + } +#else + if( ft_get_index(code,font,&idx) ) { + /* The code has not been parsed! */ + *g = NULL; + flags &= ~FT_FORCE_CONSTANT_SPACING; + } +#endif + + xrc = FreeTypeInstanceGetGlyph(idx, flags, g, font->instance); + if( xrc == Successful && *g != NULL ) + return Successful; + if( font->zero_idx != idx ) { + xrc = FreeTypeInstanceGetGlyph(font->zero_idx, flags, g, font->instance); + if( xrc == Successful && *g != NULL ) + return Successful; + } + return FreeTypeInstanceGetGlyph(font->zero_idx, flags|FT_GET_DUMMY, g, font->instance); +} + +static int +FreeTypeFontGetGlyphMetrics(unsigned code, int flags, xCharInfo **metrics, FTFontPtr font) +{ + unsigned idx = 0; + int xrc; + +#ifdef X_ACCEPTS_NO_SUCH_CHAR + if ( ft_get_index(code,font,&idx) || idx == 0 || idx == font->zero_idx ) { + *metrics = NULL; + flags &= ~FT_FORCE_CONSTANT_SPACING; + /* if( font->instance->spacing != FT_CHARCELL ) */ + return Successful; + } +#else + if ( ft_get_index(code,font,&idx) || idx == 0 || idx == font->zero_idx ) { + /* The code has not been parsed! */ + *metrics = NULL; + flags &= ~FT_FORCE_CONSTANT_SPACING; + } +#endif + + xrc = FreeTypeInstanceGetGlyphMetrics(idx, flags, metrics, font->instance); + if( xrc == Successful && *metrics != NULL ) + return Successful; + if( font->zero_idx != idx ) { + xrc = FreeTypeInstanceGetGlyphMetrics(font->zero_idx, flags, + metrics, font->instance); + if( xrc == Successful && *metrics != NULL ) + return Successful; + } + return FreeTypeInstanceGetGlyphMetrics(font->zero_idx, flags|FT_GET_DUMMY, metrics, font->instance); +} + +/* + * restrict code range + * + * boolean for the numeric zone: + * results = results & (ranges[0] | ranges[1] | ... ranges[nranges-1]) + */ + +static void +restrict_code_range(unsigned short *refFirstCol, + unsigned short *refFirstRow, + unsigned short *refLastCol, + unsigned short *refLastRow, + fsRange const *ranges, int nRanges) +{ + if (nRanges) { + int minCol = 256, minRow = 256, maxCol = -1, maxRow = -1; + fsRange const *r = ranges; + int i; + + for (i=0; i<nRanges; i++) { + if (r->min_char_high != r->max_char_high) { + minCol = 0x00; + maxCol = 0xff; + } else { + if (minCol > r->min_char_low) + minCol = r->min_char_low; + if (maxCol < r->max_char_low) + maxCol = r->max_char_low; + } + if (minRow > r->min_char_high) + minRow = r->min_char_high; + if (maxRow < r->max_char_high) + maxRow = r->max_char_high; + r++; + } + + if (minCol > *refLastCol) + *refFirstCol = *refLastCol; + else if (minCol > *refFirstCol) + *refFirstCol = minCol; + + if (maxCol < *refFirstCol) + *refLastCol = *refFirstCol; + else if (maxCol < *refLastCol) + *refLastCol = maxCol; + + if (minRow > *refLastRow) { + *refFirstRow = *refLastRow; + *refFirstCol = *refLastCol; + } else if (minRow > *refFirstRow) + *refFirstRow = minRow; + + if (maxRow < *refFirstRow) { + *refLastRow = *refFirstRow; + *refLastCol = *refFirstCol; + } else if (maxRow < *refLastRow) + *refLastRow = maxRow; + } +} + + +static int +restrict_code_range_by_str(int count,unsigned short *refFirstCol, + unsigned short *refFirstRow, + unsigned short *refLastCol, + unsigned short *refLastRow, + char const *str) +{ + int nRanges = 0; + int result = 0; + fsRange *ranges = NULL; + char const *p, *q; + + p = q = str; + for (;;) { + int minpoint=0, maxpoint=65535; + long val; + + /* skip comma and/or space */ + while (',' == *p || isspace(*p)) + p++; + + /* begin point */ + if ('-' != *p) { + val = strtol(p, (char **)&q, 0); + if (p == q) + /* end or illegal */ + break; + if (val<0 || val>65535) { + /* out of zone */ + break; + } + minpoint = val; + p=q; + } + + /* skip space */ + while (isspace(*p)) + p++; + + if (',' != *p && '\0' != *p) { + /* contiune */ + if ('-' == *p) + /* hyphon */ + p++; + else + /* end or illegal */ + break; + + /* skip space */ + while (isspace(*p)) + p++; + + val = strtol(p, (char **)&q, 0); + if (p != q) { + if (val<0 || val>65535) + break; + maxpoint = val; + } else if (',' != *p && '\0' != *p) + /* end or illegal */ + break; + p=q; + } else + /* comma - single code */ + maxpoint = minpoint; + + if ( count <= 0 && minpoint>maxpoint ) { + int tmp; + tmp = minpoint; + minpoint = maxpoint; + maxpoint = tmp; + } + + /* add range */ +#if 0 + fprintf(stderr, "zone: 0x%04X - 0x%04X\n", minpoint, maxpoint); + fflush(stderr); +#endif + nRanges++; + ranges = (fsRange *)xrealloc(ranges, nRanges*sizeof(*ranges)); + if (NULL == ranges) + break; + { + fsRange *r = ranges+nRanges-1; + + r->min_char_low = minpoint & 0xff; + r->max_char_low = maxpoint & 0xff; + r->min_char_high = (minpoint>>8) & 0xff; + r->max_char_high = (maxpoint>>8) & 0xff; + } + } + + if (ranges) { + if ( count <= 0 ) { + restrict_code_range(refFirstCol, refFirstRow, refLastCol, refLastRow, + ranges, nRanges); + } + else { + int i; + fsRange *r; + for ( i=0 ; i<nRanges ; i++ ) { + if ( count <= i ) break; + r = ranges+i; + refFirstCol[i] = r->min_char_low; + refLastCol[i] = r->max_char_low; + refFirstRow[i] = r->min_char_high; + refLastRow[i] = r->max_char_high; + } + result=i; + } + xfree(ranges); + } + return result; +} + +/* *face_number and *spacing are initialized but *load_flags is NOT. */ +static int +FreeTypeSetUpTTCap( char *fileName, FontScalablePtr vals, + char **dynStrRealFileName, char **dynStrFTFileName, + struct TTCapInfo *ret, int *face_number, FT_Int32 *load_flags, + int *spacing, Bool *font_properties, char **dynStrTTCapCodeRange ) +{ + int result = Successful; + SDynPropRecValList listPropRecVal; + SPropRecValContainer contRecValue; + Bool hinting=True; + Bool isEmbeddedBitmap = True; + Bool alwaysEmbeddedBitmap = False; + int pixel = vals->pixel; + + *font_properties=True; + *dynStrRealFileName=NULL; + *dynStrFTFileName=NULL; + *dynStrTTCapCodeRange=NULL; + + if (SPropRecValList_new(&listPropRecVal)) { + return AllocError; + } + + { + int len = strlen(fileName); + char *capHead = NULL; + { + /* font cap */ + char *p1=NULL, *p2=NULL; + + p1=strrchr(fileName, '/'); + if ( p1 == NULL ) p1 = fileName; + else p1++; + if (NULL != (p2=strrchr(p1, ':'))) { + /* colon exist in the right side of slash. */ + int dirLen = p1-fileName; + int baseLen = fileName+len - p2 -1; + + *dynStrRealFileName = (char *)xalloc(dirLen+baseLen+1); + if( *dynStrRealFileName == NULL ) { + result = AllocError; + goto quit; + } + if ( 0 < dirLen ) + memcpy(*dynStrRealFileName, fileName, dirLen); + strcpy(*dynStrRealFileName+dirLen, p2+1); + capHead = p1; + } else { + *dynStrRealFileName = xstrdup(fileName); + if( *dynStrRealFileName == NULL ) { + result = AllocError; + goto quit; + } + } + } + + /* font cap */ + if (capHead) { + if (SPropRecValList_add_by_font_cap(&listPropRecVal, + capHead)) { + result = BadFontPath; + goto quit; + } + } + } + + *face_number=0; + *spacing=0; + ret->autoItalic=0.0; + ret->scaleWidth=1.0; + ret->scaleBBoxWidth = 1.0; + ret->scaleBBoxHeight = 1.0; + ret->doubleStrikeShift = 1; + ret->adjustBBoxWidthByPixel = 0; + ret->adjustLeftSideBearingByPixel = 0; + ret->adjustRightSideBearingByPixel = 0; + ret->flags = 0; + ret->scaleBitmap = 0.0; + ret->forceConstantSpacingBegin = -1; + ret->forceConstantSpacingEnd = -1; + ret->force_c_representative_metrics_char_code = -2; + ret->force_c_scale_b_box_width = 1.0; + ret->force_c_scale_b_box_height = 1.0; + ret->force_c_adjust_width_by_pixel = 0; + ret->force_c_adjust_lsb_by_pixel = 0; + ret->force_c_adjust_rsb_by_pixel = 0; + ret->force_c_scale_lsb = 0.0; + ret->force_c_scale_rsb = 1.0; + /* */ + ret->vl_slant=0; + ret->lsbShiftOfBitmapAutoItalic=0; + ret->rsbShiftOfBitmapAutoItalic=0; + /* face number */ + { + char *beginptr=NULL,*endptr; + if ( SPropRecValList_search_record(&listPropRecVal, + &contRecValue, + "FaceNumber")) { + int lv; + beginptr = SPropContainer_value_str(contRecValue); + lv=strtol(beginptr, &endptr, 10); + if ( *beginptr != '\0' && *endptr == '\0' ) { + if ( 0 < lv ) *face_number = lv; + } + } + if( beginptr && 0 < *face_number ) { + char *slash; + *dynStrFTFileName = /* add -> ':'+strlen0+':'+strlen1+'\0' */ + (char *)xalloc(1+strlen(beginptr)+1+strlen(*dynStrRealFileName)+1); + if( *dynStrFTFileName == NULL ){ + result = AllocError; + goto quit; + } + **dynStrFTFileName = '\0'; + slash = strrchr(*dynStrRealFileName,'/'); + if( slash ) { + char *p; + strcat(*dynStrFTFileName,*dynStrRealFileName); + p = strrchr(*dynStrFTFileName,'/'); + p[1] = '\0'; + strcat(*dynStrFTFileName,":"); + strcat(*dynStrFTFileName,beginptr); + strcat(*dynStrFTFileName,":"); + strcat(*dynStrFTFileName,slash+1); + } + else{ + strcat(*dynStrFTFileName,":"); + strcat(*dynStrFTFileName,beginptr); + strcat(*dynStrFTFileName,":"); + strcat(*dynStrFTFileName,*dynStrRealFileName); + } + } + else{ + *dynStrFTFileName = (char *)xalloc(strlen(*dynStrRealFileName)+1); + if( *dynStrFTFileName == NULL ){ + result = AllocError; + goto quit; + } + **dynStrFTFileName = '\0'; + strcat(*dynStrFTFileName,*dynStrRealFileName); + } + } + /* + fprintf(stderr,"[Filename:%s]\n",fileName); + fprintf(stderr,"[RealFilename:%s]\n",*dynStrRealFileName); + fprintf(stderr,"[FTFilename:%s]\n",*dynStrFTFileName); + */ + /* slant control */ + if (SPropRecValList_search_record(&listPropRecVal, + &contRecValue, + "AutoItalic")) + ret->autoItalic = SPropContainer_value_dbl(contRecValue); + /* hinting control */ + if (SPropRecValList_search_record(&listPropRecVal, + &contRecValue, + "Hinting")) + hinting = SPropContainer_value_bool(contRecValue); + /* scaling */ + if (SPropRecValList_search_record(&listPropRecVal, + &contRecValue, + "ScaleWidth")) { + ret->scaleWidth = SPropContainer_value_dbl(contRecValue); + if (ret->scaleWidth<=0.0) { + fprintf(stderr, "ScaleWitdh needs plus.\n"); + result = BadFontName; + goto quit; + } + } + /* bbox adjustment */ + if (SPropRecValList_search_record(&listPropRecVal, + &contRecValue, + "ScaleBBoxWidth")) { + /* Scaling to Bounding Box Width */ + int lv; + char *endptr,*beginptr; + double v,scaleBBoxWidth=1.0,scaleBBoxHeight=1.0; + beginptr = SPropContainer_value_str(contRecValue); + do { + if ( strlen(beginptr) < 1 ) break; + v=strtod(beginptr, &endptr); + if ( endptr!=beginptr ) { + scaleBBoxWidth = v; + } + if ( *endptr != ';' && *endptr != ',' ) break; + if ( *endptr == ',' ) { + beginptr=endptr+1; + v=strtod(beginptr, &endptr); + if ( endptr!=beginptr ) { + scaleBBoxHeight = v; + } + } + if ( *endptr != ';' && *endptr != ',' ) break; + beginptr=endptr+1; + lv=strtol(beginptr, &endptr, 10); + if ( endptr!=beginptr ) { + ret->adjustBBoxWidthByPixel = lv; + } + if ( *endptr != ',' ) break; + beginptr=endptr+1; + lv=strtol(beginptr, &endptr, 10); + if ( endptr!=beginptr ) { + ret->adjustLeftSideBearingByPixel = lv; + } + if ( *endptr != ',' ) break; + beginptr=endptr+1; + lv=strtol(beginptr, &endptr, 10); + if ( endptr!=beginptr ) { + ret->adjustRightSideBearingByPixel = lv; + } + } while ( 0 ); + if (scaleBBoxWidth<=0.0) { + fprintf(stderr, "ScaleBBoxWitdh needs plus.\n"); + result = BadFontName; + goto quit; + } + if (scaleBBoxHeight<=0.0) { + fprintf(stderr, "ScaleBBoxHeight needs plus.\n"); + result = BadFontName; + goto quit; + } + ret->scaleBBoxWidth = scaleBBoxWidth; + ret->scaleBBoxHeight = scaleBBoxHeight; + } + /* spacing */ + if (SPropRecValList_search_record(&listPropRecVal, + &contRecValue, + "ForceSpacing")) { + char *strSpace = SPropContainer_value_str(contRecValue); + Bool err = False; + if (1 != strlen(strSpace)) + err = True; + else + switch (strSpace[0]) { + case 'M': + ret->flags |= TTCAP_MONO_CENTER; + *spacing = 'm'; + break; + case 'm': + case 'p': + case 'c': + *spacing = strSpace[0]; + break; + default: + err = True; + } + if (err) { + result = BadFontName; + goto quit; + } + } + /* doube striking */ + if (SPropRecValList_search_record(&listPropRecVal, + &contRecValue, + "DoubleStrike")) { + /* Set or Reset Auto Bold Flag */ + char *strDoubleStrike = SPropContainer_value_str(contRecValue); + Bool err = False; + if ( 0 < strlen(strDoubleStrike) ) { + switch (strDoubleStrike[0]) { + case 'm': + case 'M': + case 'l': + case 'L': + ret->flags |= TTCAP_DOUBLE_STRIKE; + ret->flags |= TTCAP_DOUBLE_STRIKE_MKBOLD_EDGE_LEFT; + break; + case 'y': + case 'Y': + ret->flags |= TTCAP_DOUBLE_STRIKE; + break; + case 'n': + case 'N': + ret->flags &= ~TTCAP_DOUBLE_STRIKE; + ret->flags &= ~TTCAP_DOUBLE_STRIKE_MKBOLD_EDGE_LEFT; + ret->flags &= ~TTCAP_DOUBLE_STRIKE_CORRECT_B_BOX_WIDTH; + break; + default: + err = True; + } + if ( err != True ) { + if ( strDoubleStrike[1] ) { + switch (strDoubleStrike[1]) { + case 'b': + case 'B': + case 'p': + case 'P': + case 'y': + case 'Y': + ret->flags |= TTCAP_DOUBLE_STRIKE_CORRECT_B_BOX_WIDTH; + break; + default: + break; + } + } + do { + char *comma_ptr=strchr(strDoubleStrike,';'); + if ( !comma_ptr ) comma_ptr=strchr(strDoubleStrike,','); + if ( !comma_ptr ) break; + if ( comma_ptr[1] ) { + char *endptr; + int mkboldMaxPixel; + mkboldMaxPixel=strtol(comma_ptr+1, &endptr, 10); + if ( endptr != comma_ptr+1 && mkboldMaxPixel <= pixel ) { + ret->flags &= ~TTCAP_DOUBLE_STRIKE_MKBOLD_EDGE_LEFT; + } + } + comma_ptr=strchr(comma_ptr+1,','); + if ( !comma_ptr ) break; + if ( comma_ptr[1] ) { + char *endptr; + int max_pixel; + max_pixel=strtol(comma_ptr+1, &endptr, 10); + if ( endptr != comma_ptr+1 && max_pixel <= pixel ) { + if( ret->flags & TTCAP_DOUBLE_STRIKE ) + ret->doubleStrikeShift += pixel / max_pixel; + } + } + } while(0); + } + } + else + err = True; + if (err) { + result = BadFontName; + goto quit; + } + } + /* very lazy metrics */ + if (SPropRecValList_search_record(&listPropRecVal, + &contRecValue, + "VeryLazyMetrics")){ + Bool isVeryLazy = SPropContainer_value_bool(contRecValue); + ret->flags |= TTCAP_DISABLE_DEFAULT_VERY_LAZY; + if( isVeryLazy == True ) + ret->flags |= TTCAP_IS_VERY_LAZY; + else + ret->flags &= ~TTCAP_IS_VERY_LAZY; + } + /* embedded bitmap */ + if (SPropRecValList_search_record(&listPropRecVal, + &contRecValue, + "EmbeddedBitmap")) { + char *strEmbeddedBitmap = SPropContainer_value_str(contRecValue); + Bool err = False; + if ( 1 == strlen(strEmbeddedBitmap) ) { + switch (strEmbeddedBitmap[0]) { + case 'y': + case 'Y': + isEmbeddedBitmap = True; + alwaysEmbeddedBitmap = True; + break; + case 'u': + case 'U': + isEmbeddedBitmap = True; + alwaysEmbeddedBitmap = False; + break; + case 'n': + case 'N': + isEmbeddedBitmap = False; + break; + default: + err = True; + } + } + else + err = True; + if (err) { + result = BadFontName; + goto quit; + } + } + /* scale bitmap */ + if((ret->flags & TTCAP_IS_VERY_LAZY) && + SPropRecValList_search_record(&listPropRecVal, + &contRecValue, + "VeryLazyBitmapWidthScale")) { + /* Scaling to Bitmap Bounding Box Width */ + double scaleBitmapWidth = SPropContainer_value_dbl(contRecValue); + + fprintf(stderr, "Warning: `bs' option is not required in X-TT version 2.\n"); +#if 0 + if (scaleBitmapWidth<=0.0) { + fprintf(stderr, "ScaleBitmapWitdh needs plus.\n"); + result = BadFontName; + goto quit; + } +#endif + ret->scaleBitmap = scaleBitmapWidth; + } + /* restriction of the code range */ + if (SPropRecValList_search_record(&listPropRecVal, + &contRecValue, + "CodeRange")) { + *dynStrTTCapCodeRange = xstrdup(SPropContainer_value_str(contRecValue)); + if( *dynStrTTCapCodeRange == NULL ) { + result = AllocError; + goto quit; + } + } + /* forceConstantSpacing{Begin,End} */ + if ( 1 /* ft->spacing == 'p' */ ){ + unsigned short first_col=0,last_col=0x00ff; + unsigned short first_row=0,last_row=0x00ff; + if (SPropRecValList_search_record(&listPropRecVal, + &contRecValue, + "ForceConstantSpacingCodeRange")) { + if ( restrict_code_range_by_str(1,&first_col, &first_row, + &last_col, &last_row, + SPropContainer_value_str(contRecValue)) == 1 ) { + ret->forceConstantSpacingBegin = (int)( first_row<<8 | first_col ); + ret->forceConstantSpacingEnd = (int)( last_row<<8 | last_col ); + if ( ret->forceConstantSpacingBegin <= ret->forceConstantSpacingEnd ) + ret->flags &= ~TTCAP_FORCE_C_OUTSIDE; + else ret->flags |= TTCAP_FORCE_C_OUTSIDE; + } + } + } + /* */ + if ( 1 ){ + unsigned short first_col=0, last_col=0x0ff; + unsigned short first_row=0, last_row=0x0ff; + if ( SPropRecValList_search_record(&listPropRecVal, + &contRecValue, + "ForceConstantSpacingMetrics")) { + char *strMetrics; + strMetrics = SPropContainer_value_str(contRecValue); + if ( strMetrics ) { + char *comma_ptr,*period_ptr,*semic_ptr; + semic_ptr=strchr(strMetrics,';'); + comma_ptr=strchr(strMetrics,','); + period_ptr=strchr(strMetrics,'.'); + if ( semic_ptr && comma_ptr ) + if ( semic_ptr < comma_ptr ) comma_ptr=NULL; + if ( semic_ptr && period_ptr ) + if ( semic_ptr < period_ptr ) period_ptr=NULL; + if ( !comma_ptr && !period_ptr && strMetrics != semic_ptr ) { + if ( restrict_code_range_by_str(1,&first_col, &first_row, + &last_col, &last_row, + SPropContainer_value_str(contRecValue)) == 1 ) { + ret->force_c_representative_metrics_char_code = + (int)( first_row<<8 | first_col ); + } + } + else { + double v; + char *endptr,*beginptr=strMetrics; + do { + v=strtod(beginptr, &endptr); + if ( endptr!=beginptr ) { + ret->force_c_scale_b_box_width = v; + } + if ( *endptr != ',' ) break; + beginptr=endptr+1; + v=strtod(beginptr, &endptr); + if ( endptr!=beginptr ) { + ret->force_c_scale_lsb = v; + ret->flags |= TTCAP_FORCE_C_LSB_FLAG; + } + if ( *endptr != ',' ) break; + beginptr=endptr+1; + v=strtod(beginptr, &endptr); + if ( endptr!=beginptr ) { + ret->force_c_scale_rsb = v; + ret->flags |= TTCAP_FORCE_C_RSB_FLAG; + } + if ( *endptr != ',' ) break; + beginptr=endptr+1; + v=strtod(beginptr, &endptr); + if ( endptr!=beginptr ) { + ret->force_c_scale_b_box_height = v; + } + } while (0); + } + if ( semic_ptr ) { + int lv; + char *endptr,*beginptr=semic_ptr+1; + do { + lv=strtol(beginptr, &endptr, 10); + if ( endptr!=beginptr ) { + ret->force_c_adjust_width_by_pixel=lv; + } + if ( *endptr != ',' ) break; + beginptr=endptr+1; + lv=strtol(beginptr, &endptr, 10); + if ( endptr!=beginptr ) { + ret->force_c_adjust_lsb_by_pixel=lv; + } + if ( *endptr != ',' ) break; + beginptr=endptr+1; + lv=strtol(beginptr, &endptr, 10); + if ( endptr!=beginptr ) { + ret->force_c_adjust_rsb_by_pixel=lv; + } + } while (0); + } + } + } + } + + if (SPropRecValList_search_record(&listPropRecVal, + &contRecValue, + "FontProperties")) { + /* Set or Reset the Flag of FontProperties */ + *font_properties=SPropContainer_value_bool(contRecValue); + } + + ret->force_c_scale_b_box_width *= ret->scaleBBoxWidth; + ret->force_c_scale_b_box_height *= ret->scaleBBoxHeight; + + ret->force_c_scale_b_box_width *= ret->scaleWidth; + ret->scaleBBoxWidth *= ret->scaleWidth; + + ret->force_c_adjust_rsb_by_pixel += ret->adjustRightSideBearingByPixel; + ret->force_c_adjust_lsb_by_pixel += ret->adjustLeftSideBearingByPixel; + + /* scaleWidth, scaleBBoxWidth, force_c_scale_b_box_width, force_c_scale_b_box_width */ + + /* by TTCap */ + if( hinting == False ) *load_flags |= FT_LOAD_NO_HINTING; + if( isEmbeddedBitmap == False ) *load_flags |= FT_LOAD_NO_BITMAP; + if( ret->autoItalic != 0 && alwaysEmbeddedBitmap == False ) + *load_flags |= FT_LOAD_NO_BITMAP; + + quit: + return result; +} + +static int +ft_get_trans_from_vals( FontScalablePtr vals, FTNormalisedTransformationPtr trans ) +{ + /* Compute the transformation matrix. We use floating-point + arithmetic for simplicity */ + + trans->xres = vals->x; + trans->yres = vals->y; + + /* This value cannot be 0. */ + trans->scale = hypot(vals->point_matrix[2], vals->point_matrix[3]); + trans->nonIdentity = 0; + + /* Try to round stuff. We want approximate zeros to be exact zeros, + and if the elements on the diagonal are approximately equal, we + want them equal. We do this to avoid breaking hinting. */ + if(DIFFER(vals->point_matrix[0], vals->point_matrix[3])) { + trans->nonIdentity = 1; + trans->matrix.xx = + (int)((vals->point_matrix[0]*(double)TWO_SIXTEENTH)/trans->scale); + trans->matrix.yy = + (int)((vals->point_matrix[3]*(double)TWO_SIXTEENTH)/trans->scale); + } else { + trans->matrix.xx = trans->matrix.yy = + ((vals->point_matrix[0] + vals->point_matrix[3])/2* + (double)TWO_SIXTEENTH)/trans->scale; + } + + if(DIFFER0(vals->point_matrix[1], trans->scale)) { + trans->matrix.yx = + (int)((vals->point_matrix[1]*(double)TWO_SIXTEENTH)/trans->scale); + trans->nonIdentity = 1; + } else + trans->matrix.yx = 0; + + if(DIFFER0(vals->point_matrix[2], trans->scale)) { + trans->matrix.xy = + (int)((vals->point_matrix[2]*(double)TWO_SIXTEENTH)/trans->scale); + trans->nonIdentity = 1; + } else + trans->matrix.xy=0; + return 0; +} + + +static int +is_fixed_width(FT_Face face) +{ + PS_FontInfoRec t1info_rec; + int ftrc; + + if(FT_IS_FIXED_WIDTH(face)) { + return 1; + } + + ftrc = FT_Get_PS_Font_Info(face, &t1info_rec); + if(ftrc == 0 && t1info_rec.is_fixed_pitch) { + return 1; + } + + return 0; +} + +static int +FreeTypeLoadFont(FTFontPtr font, FontInfoPtr info, FTFacePtr face, + char *FTFileName, FontScalablePtr vals, FontEntryPtr entry, + FontBitmapFormatPtr bmfmt, FT_Int32 load_flags, + struct TTCapInfo *tmp_ttcap, char *dynStrTTCapCodeRange, + int ttcap_spacing ) +{ + int xrc; + FTNormalisedTransformationRec trans; + int spacing, actual_spacing, zero_code; + long lastCode, firstCode; + TT_Postscript *post; + + ft_get_trans_from_vals(vals,&trans); + + /* Check for charcell in XLFD */ + spacing = FT_PROPORTIONAL; + if(entry->name.ndashes == 14) { + char *p; + int dashes = 0; + for(p = entry->name.name; + p <= entry->name.name + entry->name.length - 2; + p++) { + if(*p == '-') { + dashes++; + if(dashes == 11) { + if(p[1]=='c' && p[2]=='-') + spacing=FT_CHARCELL; + else if(p[1]=='m' && p[2]=='-') + spacing=FT_MONOSPACED; + break; + } + } + } + } + /* by TTCap */ + if( ttcap_spacing != 0 ) { + if( ttcap_spacing == 'c' ) spacing=FT_CHARCELL; + else if( ttcap_spacing == 'm' ) spacing=FT_MONOSPACED; + else spacing=FT_PROPORTIONAL; + } + + actual_spacing = spacing; + if( spacing == FT_PROPORTIONAL ) { + if( is_fixed_width(face->face) ) + actual_spacing = FT_MONOSPACED; + } + + if(entry->name.ndashes == 14) { + xrc = FTPickMapping(entry->name.name, entry->name.length, FTFileName, + face->face, &font->mapping); + if (xrc != Successful) + return xrc; + } else { + xrc = FTPickMapping(0, 0, FTFileName, + face->face, &font->mapping); + if (xrc != Successful) + return xrc; + } + + font->nranges = vals->nranges; + font->ranges = 0; + if(font->nranges) { + font->ranges = (fsRange*)xalloc(vals->nranges*sizeof(fsRange)); + if(font->ranges == NULL) + return AllocError; + memcpy((char*)font->ranges, (char*)vals->ranges, + vals->nranges*sizeof(fsRange)); + } + + zero_code=-1; + if(info) { + firstCode = 0; + lastCode = 0xFFFFL; + if(!font->mapping.mapping || + font->mapping.mapping->encoding->row_size == 0) { + /* linear indexing */ + lastCode=MIN(lastCode, + font->mapping.mapping ? + font->mapping.mapping->encoding->size-1 : + 0xFF); + if(font->mapping.mapping && font->mapping.mapping->encoding->first) + firstCode = font->mapping.mapping->encoding->first; + info->firstRow = firstCode/0x100; + info->lastRow = lastCode/0x100; + info->firstCol = + (info->firstRow || info->lastRow) ? 0 : (firstCode & 0xFF); + info->lastCol = info->lastRow ? 0xFF : (lastCode & 0xFF); + if ( firstCode == 0 ) zero_code=0; + } else { + /* matrix indexing */ + info->firstRow = font->mapping.mapping->encoding->first; + info->lastRow = MIN(font->mapping.mapping->encoding->size-1, + lastCode/0x100); + info->firstCol = font->mapping.mapping->encoding->first_col; + info->lastCol = MIN(font->mapping.mapping->encoding->row_size-1, + lastCode<0x100?lastCode:0xFF); + if( info->firstRow == 0 && info->firstCol == 0 ) zero_code=0; + } + + /* firstCode and lastCode are not valid in case of a matrix + encoding */ + + if( dynStrTTCapCodeRange ) { + restrict_code_range_by_str(0,&info->firstCol, &info->firstRow, + &info->lastCol, &info->lastRow, + dynStrTTCapCodeRange); + } + restrict_code_range(&info->firstCol, &info->firstRow, + &info->lastCol, &info->lastRow, + font->ranges, font->nranges); + } + font->info = info; + + /* zero code is frequently used. */ + if ( zero_code < 0 ) { + /* The fontenc should have the information of DefaultCh. + But we do not have such a information. + So we cannot but set 0. */ + font->zero_idx = 0; + } + else + font->zero_idx = FTRemap(face->face, + &font->mapping, zero_code); + + post = FT_Get_Sfnt_Table(face->face, ft_sfnt_post); + +#ifdef DEFAULT_VERY_LAZY + if( !( tmp_ttcap->flags & TTCAP_DISABLE_DEFAULT_VERY_LAZY ) ) + if( DEFAULT_VERY_LAZY <= 1 + info->lastRow - info->firstRow ) { + if( post ){ + tmp_ttcap->flags |= TTCAP_IS_VERY_LAZY; + } + } +#endif + /* We should always reset. */ + tmp_ttcap->flags &= ~TTCAP_DISABLE_DEFAULT_VERY_LAZY; + + if ( face->bitmap || actual_spacing == FT_CHARCELL ) + tmp_ttcap->flags &= ~TTCAP_IS_VERY_LAZY; + /* "vl=y" is available when TrueType or OpenType only */ + if ( !face->bitmap && !(FT_IS_SFNT( face->face )) ) + tmp_ttcap->flags &= ~TTCAP_IS_VERY_LAZY; + + if( post ) { + if( post->italicAngle != 0 ) + tmp_ttcap->vl_slant = -sin( (post->italicAngle/1024./5760.)*1.57079632679489661923 ); + /* fprintf(stderr,"angle=%g(%g)\n",tmp_ttcap->vl_slant,(post->italicAngle/1024./5760.)*90); */ + } + + xrc = FreeTypeOpenInstance(&font->instance, face, + FTFileName, &trans, actual_spacing, bmfmt, + tmp_ttcap, load_flags ); + return xrc; +} + +static void +adjust_min_max(xCharInfo *minc, xCharInfo *maxc, xCharInfo *tmp) +{ +#define MINMAX(field,ci) \ + if (minc->field > (ci)->field) \ + minc->field = (ci)->field; \ + if (maxc->field < (ci)->field) \ + maxc->field = (ci)->field; + + MINMAX(ascent, tmp); + MINMAX(descent, tmp); + MINMAX(leftSideBearing, tmp); + MINMAX(rightSideBearing, tmp); + MINMAX(characterWidth, tmp); + + if ((INT16)minc->attributes > (INT16)tmp->attributes) + minc->attributes = tmp->attributes; + if ((INT16)maxc->attributes < (INT16)tmp->attributes) + maxc->attributes = tmp->attributes; +#undef MINMAX +} + +static void +ft_compute_bounds(FTFontPtr font, FontInfoPtr pinfo, FontScalablePtr vals ) +{ + FTInstancePtr instance; + int row, col; + unsigned int c; + xCharInfo minchar, maxchar, *tmpchar = NULL; + int overlap, maxOverlap; + long swidth = 0; + long total_width = 0; + int num_cols, num_chars = 0; + int flags, skip_ok = 0; + int force_c_outside ; + + instance = font->instance; + force_c_outside = instance->ttcap.flags & TTCAP_FORCE_C_OUTSIDE; + + minchar.ascent = minchar.descent = + minchar.leftSideBearing = minchar.rightSideBearing = + minchar.characterWidth = minchar.attributes = 32767; + maxchar.ascent = maxchar.descent = + maxchar.leftSideBearing = maxchar.rightSideBearing = + maxchar.characterWidth = maxchar.attributes = -32767; + maxOverlap = -32767; + + /* Parse all glyphs */ + num_cols = 1 + pinfo->lastCol - pinfo->firstCol; + for (row = pinfo->firstRow; row <= pinfo->lastRow; row++) { + if ( skip_ok && tmpchar ) { + if ( !force_c_outside ) { + if ( instance->ttcap.forceConstantSpacingBegin < row<<8 + && row<<8 < (instance->ttcap.forceConstantSpacingEnd & 0x0ff00) ) { + if (tmpchar->characterWidth) { + num_chars += num_cols; + swidth += ABS(tmpchar->characterWidth)*num_cols; + total_width += tmpchar->characterWidth*num_cols; + continue; + } + } + else skip_ok=0; + } + else { /* for GB18030 proportional */ + if ( instance->ttcap.forceConstantSpacingBegin < row<<8 + || row<<8 < (instance->ttcap.forceConstantSpacingEnd & 0x0ff00) ) { + if (tmpchar->characterWidth) { + num_chars += num_cols; + swidth += ABS(tmpchar->characterWidth)*num_cols; + total_width += tmpchar->characterWidth*num_cols; + continue; + } + } + else skip_ok=0; + } + } + for (col = pinfo->firstCol; col <= pinfo->lastCol; col++) { + c = row<<8|col; + flags=0; + if ( !force_c_outside ) { + if ( c <= instance->ttcap.forceConstantSpacingEnd + && instance->ttcap.forceConstantSpacingBegin <= c ) + flags|=FT_FORCE_CONSTANT_SPACING; + } + else { /* for GB18030 proportional */ + if ( c <= instance->ttcap.forceConstantSpacingEnd + || instance->ttcap.forceConstantSpacingBegin <= c ) + flags|=FT_FORCE_CONSTANT_SPACING; + } +#if 0 + fprintf(stderr, "comp_bounds: %x ->", c); +#endif + if ( skip_ok == 0 || flags == 0 ){ + tmpchar=NULL; +#if 0 + fprintf(stderr, "%x\n", c); +#endif + if( FreeTypeFontGetGlyphMetrics(c, flags, &tmpchar, font) != Successful ) + continue; + } + if ( !tmpchar ) continue; + adjust_min_max(&minchar, &maxchar, tmpchar); + overlap = tmpchar->rightSideBearing - tmpchar->characterWidth; + if (maxOverlap < overlap) + maxOverlap = overlap; + + if (!tmpchar->characterWidth) + continue; + num_chars++; + swidth += ABS(tmpchar->characterWidth); + total_width += tmpchar->characterWidth; + + if ( flags & FT_FORCE_CONSTANT_SPACING ) skip_ok=1; + } + } + +#ifndef X_ACCEPTS_NO_SUCH_CHAR + /* Check code 0 */ + if( FreeTypeInstanceGetGlyphMetrics(font->zero_idx, 0, &tmpchar, font->instance) != Successful || tmpchar == NULL) + if( FreeTypeInstanceGetGlyphMetrics(font->zero_idx, FT_GET_DUMMY, &tmpchar, font->instance) != Successful ) + tmpchar = NULL; + if ( tmpchar ) { + adjust_min_max(&minchar, &maxchar, tmpchar); + overlap = tmpchar->rightSideBearing - tmpchar->characterWidth; + if (maxOverlap < overlap) + maxOverlap = overlap; + } +#endif + + /* AVERAGE_WIDTH ... 1/10 pixel unit */ + if (num_chars > 0) { + swidth = (swidth * 10.0 + num_chars / 2.0) / num_chars; + if (total_width < 0) + swidth = -swidth; + vals->width = swidth; + } else + vals->width = 0; + + /* + if (char_width.pixel) { + maxchar.characterWidth = char_width.pixel; + minchar.characterWidth = char_width.pixel; + } + */ + + pinfo->maxbounds = maxchar; + pinfo->minbounds = minchar; + pinfo->ink_maxbounds = maxchar; + pinfo->ink_minbounds = minchar; + pinfo->maxOverlap = maxOverlap; +} + +static int +compute_new_extents( FontScalablePtr vals, double scale, double lsb, double rsb, double desc, double asc, + int *lsb_result, int *rsb_result, int *desc_result, int *asc_result ) +{ +#define TRANSFORM_POINT(matrix, x, y, dest) \ + ((dest)[0] = (matrix)[0] * (x) + (matrix)[2] * (y), \ + (dest)[1] = (matrix)[1] * (x) + (matrix)[3] * (y)) + +#define CHECK_EXTENT(lsb, rsb, desc, asc, data) \ + ((lsb) > (data)[0] ? (lsb) = (data)[0] : 0 , \ + (rsb) < (data)[0] ? (rsb) = (data)[0] : 0, \ + (-desc) > (data)[1] ? (desc) = -(data)[1] : 0 , \ + (asc) < (data)[1] ? (asc) = (data)[1] : 0) + double newlsb, newrsb, newdesc, newasc; + double point[2]; + + /* Compute new extents for this glyph */ + TRANSFORM_POINT(vals->pixel_matrix, lsb, -desc, point); + newlsb = point[0]; + newrsb = newlsb; + newdesc = -point[1]; + newasc = -newdesc; + TRANSFORM_POINT(vals->pixel_matrix, lsb, asc, point); + CHECK_EXTENT(newlsb, newrsb, newdesc, newasc, point); + TRANSFORM_POINT(vals->pixel_matrix, rsb, -desc, point); + CHECK_EXTENT(newlsb, newrsb, newdesc, newasc, point); + TRANSFORM_POINT(vals->pixel_matrix, rsb, asc, point); + CHECK_EXTENT(newlsb, newrsb, newdesc, newasc, point); + + /* ???: lsb = (int)floor(newlsb * scale); */ + *lsb_result = (int)floor(newlsb * scale + 0.5); + *rsb_result = (int)floor(newrsb * scale + 0.5); + *desc_result = (int)ceil(newdesc * scale - 0.5); + *asc_result = (int)floor(newasc * scale + 0.5); + + return 0; +#undef CHECK_EXTENT +#undef TRANSFORM_POINT +} + +static int +is_matrix_unit(FontScalablePtr vals) +{ + double base_size; + FT_Matrix m; + + base_size = hypot(vals->point_matrix[2], vals->point_matrix[3]); + + m.xx = vals->point_matrix[0] / base_size * 65536; + m.xy = vals->point_matrix[2] / base_size * 65536; + m.yx = vals->point_matrix[1] / base_size * 65536; + m.yy = vals->point_matrix[3] / base_size * 65536; + + return (m.xx == 65536) && (m.yx == 0) && + (m.xy == 0) && (m.yy == 65536); +} + +/* Do all the real work for OpenFont or FontInfo */ +/* xf->info is only accessed through info, and xf might be null */ + +static int +FreeTypeLoadXFont(char *fileName, + FontScalablePtr vals, FontPtr xf, FontInfoPtr info, + FontBitmapFormatPtr bmfmt, FontEntryPtr entry) +{ + FTFontPtr font = NULL; + FTFacePtr face = NULL; + FTInstancePtr instance; + FT_Size_Metrics *smetrics; + int xrc=Successful; + int charcell; + long rawWidth = 0, rawAverageWidth = 0; + int upm, minLsb, maxRsb, ascent, descent, width, averageWidth; + double scale, base_width, base_height; + Bool orig_is_matrix_unit, font_properties; + int face_number, ttcap_spacing; + struct TTCapInfo tmp_ttcap; + struct TTCapInfo *ins_ttcap; + FT_Int32 load_flags = FT_LOAD_DEFAULT; /* orig: FT_LOAD_RENDER | FT_LOAD_MONOCHROME */ + char *dynStrRealFileName = NULL; /* foo.ttc */ + char *dynStrFTFileName = NULL; /* :1:foo.ttc */ + char *dynStrTTCapCodeRange = NULL; + + font = (FTFontPtr)xalloc(sizeof(FTFontRec)); + if(font == NULL) { + xrc = AllocError; + goto quit; + } + memset(font, 0, sizeof(FTFontRec)); + + xrc = FreeTypeSetUpTTCap(fileName, vals, + &dynStrRealFileName, &dynStrFTFileName, + &tmp_ttcap, &face_number, + &load_flags, &ttcap_spacing, + &font_properties, &dynStrTTCapCodeRange); + if ( xrc != Successful ) { + goto quit; + } + + xrc = FreeTypeOpenFace(&face, dynStrFTFileName, dynStrRealFileName, face_number); + if(xrc != Successful) { + goto quit; + } + + if( is_matrix_unit(vals) ) + orig_is_matrix_unit = True; + else { + orig_is_matrix_unit = False; + /* Turn off EmbeddedBitmap when original matrix is not diagonal. */ + load_flags |= FT_LOAD_NO_BITMAP; + } + + if( face->bitmap ) load_flags &= ~FT_LOAD_NO_BITMAP; + + /* Slant control by TTCap */ + if(!face->bitmap) { + vals->pixel_matrix[2] += + vals->pixel_matrix[0] * tmp_ttcap.autoItalic; + vals->point_matrix[2] += + vals->point_matrix[0] * tmp_ttcap.autoItalic; + vals->pixel_matrix[3] += + vals->pixel_matrix[1] * tmp_ttcap.autoItalic; + vals->point_matrix[3] += + vals->point_matrix[1] * tmp_ttcap.autoItalic; + } + + base_width=hypot(vals->pixel_matrix[0], vals->pixel_matrix[1]); + base_height=hypot(vals->pixel_matrix[2], vals->pixel_matrix[3]); + if(MAX(base_width, base_height) < 1.0 ) { + xrc = BadFontName; + goto quit; + } + + xrc = FreeTypeLoadFont(font, info, face, dynStrFTFileName, vals, entry, bmfmt, + load_flags, &tmp_ttcap, dynStrTTCapCodeRange, + ttcap_spacing ); + if(xrc != Successful) { + goto quit; + } + + instance = font->instance; + smetrics = &instance->size->metrics; + ins_ttcap = &instance->ttcap; + + upm = face->face->units_per_EM; + if(upm == 0) { + /* Work around FreeType bug */ + upm = WORK_AROUND_UPM; + } + scale = 1.0 / upm; + + charcell = (instance->spacing == FT_CHARCELL); + + if( instance->charcellMetrics == NULL ) { + + /* New instance */ + + long force_c_rawWidth = 0; + int force_c_lsb,force_c_rsb,force_c_width; + double unit_x=0,unit_y=0,advance; + CharInfoPtr tmpglyph; + + /* + * CALCULATE HEADER'S METRICS + */ + + /* for OUTLINE fonts */ + if(!face->bitmap) { + int new_width; + double ratio,force_c_ratio; + double width_x=0,width_y=0; + double force_c_width_x, force_c_rsb_x, force_c_lsb_x; + double tmp_rsb,tmp_lsb,tmp_asc,tmp_des; + double max_advance_height; + tmp_asc = face->face->bbox.yMax; + tmp_des = -(face->face->bbox.yMin); + if ( tmp_asc < face->face->ascender ) tmp_asc = face->face->ascender; + if ( tmp_des < -(face->face->descender) ) tmp_des = -(face->face->descender); + tmp_lsb = face->face->bbox.xMin; + tmp_rsb = face->face->bbox.xMax; + if ( tmp_rsb < face->face->max_advance_width ) tmp_rsb = face->face->max_advance_width; + /* apply scaleBBoxWidth */ + /* we should not ...??? */ + tmp_lsb *= ins_ttcap->scaleBBoxWidth; + tmp_rsb *= ins_ttcap->scaleBBoxWidth; + /* transform and rescale */ + compute_new_extents( vals, scale, tmp_lsb, tmp_rsb, tmp_des, tmp_asc, + &minLsb, &maxRsb, &descent, &ascent ); + /* */ + /* Consider vertical layouts */ + if( 0 < face->face->max_advance_height ) + max_advance_height = face->face->max_advance_height; + else + max_advance_height = tmp_asc + tmp_des; + if( vals->pixel_matrix[1] == 0 ){ + unit_x = fabs(vals->pixel_matrix[0]); + unit_y = 0; + width_x = face->face->max_advance_width * ins_ttcap->scaleBBoxWidth * unit_x; + } + else if( vals->pixel_matrix[3] == 0 ){ + unit_y = fabs(vals->pixel_matrix[2]); + unit_x = 0; + width_x = max_advance_height * ins_ttcap->scaleBBoxHeight * unit_y; + } + else{ + unit_x = fabs(vals->pixel_matrix[0] - + vals->pixel_matrix[1]*vals->pixel_matrix[2]/vals->pixel_matrix[3]); + unit_y = fabs(vals->pixel_matrix[2] - + vals->pixel_matrix[3]*vals->pixel_matrix[0]/vals->pixel_matrix[1]); + width_x = face->face->max_advance_width * ins_ttcap->scaleBBoxWidth * unit_x; + width_y = max_advance_height * ins_ttcap->scaleBBoxHeight * unit_y; + if( width_y < width_x ){ + width_x = width_y; + unit_x = 0; + } + else{ + unit_y = 0; + } + } + /* calculate correction ratio */ + width = (int)floor( (advance = width_x * scale) + 0.5); + new_width = width; + if( ins_ttcap->flags & TTCAP_DOUBLE_STRIKE_CORRECT_B_BOX_WIDTH ) + new_width += ins_ttcap->doubleStrikeShift; + new_width += ins_ttcap->adjustBBoxWidthByPixel; + ratio = (double)new_width/width; + width = new_width; + /* force constant */ + if( unit_x != 0 ) { + force_c_width_x = face->face->max_advance_width + * ins_ttcap->force_c_scale_b_box_width * unit_x; + force_c_lsb_x = face->face->max_advance_width + * ins_ttcap->force_c_scale_lsb * unit_x; + force_c_rsb_x = face->face->max_advance_width + * ins_ttcap->force_c_scale_rsb * unit_x; + } + else { + force_c_width_x = max_advance_height + * ins_ttcap->force_c_scale_b_box_height * unit_y; + force_c_lsb_x = max_advance_height + * ins_ttcap->force_c_scale_lsb * unit_y; + force_c_rsb_x = max_advance_height + * ins_ttcap->force_c_scale_rsb * unit_y; + } + /* calculate correction ratio */ + force_c_width = (int)floor(force_c_width_x * scale + 0.5); + new_width = force_c_width; + if( ins_ttcap->flags & TTCAP_DOUBLE_STRIKE_CORRECT_B_BOX_WIDTH ) + force_c_width += ins_ttcap->doubleStrikeShift; + new_width += ins_ttcap->force_c_adjust_width_by_pixel; + force_c_ratio = (double)new_width/force_c_width; + force_c_width = new_width; + /* force_c_lsb, force_c_rsb */ + if( ins_ttcap->flags & TTCAP_FORCE_C_LSB_FLAG ) + force_c_lsb = (int)floor( force_c_lsb_x * scale + 0.5 ); + else + force_c_lsb = minLsb; + if( ins_ttcap->flags & TTCAP_FORCE_C_RSB_FLAG ) + force_c_rsb = (int)floor( force_c_rsb_x * scale + 0.5 ); + else + force_c_rsb = maxRsb; + /* calculate shift of BitmapAutoItalic + (when diagonal matrix only) */ + if( orig_is_matrix_unit == True ) { + if( ins_ttcap->autoItalic != 0 ) { + double ai; + int ai_lsb,ai_rsb,ai_total; + if( 0 < ins_ttcap->autoItalic ) ai=ins_ttcap->autoItalic; + else ai = -ins_ttcap->autoItalic; + ai_total = (int)( (ascent+descent) * ai + 0.5); + ai_rsb = (int)((double)ai_total * ascent / ( ascent + descent ) + 0.5 ); + ai_lsb = -(ai_total - ai_rsb); + if( 0 < ins_ttcap->autoItalic ) { + ins_ttcap->lsbShiftOfBitmapAutoItalic = ai_lsb; + ins_ttcap->rsbShiftOfBitmapAutoItalic = ai_rsb; + } + else { + ins_ttcap->lsbShiftOfBitmapAutoItalic = -ai_rsb; + ins_ttcap->rsbShiftOfBitmapAutoItalic = -ai_lsb; + } + } + } + /* integer adjustment by TTCap */ + if( ins_ttcap->flags & TTCAP_DOUBLE_STRIKE ) + maxRsb += ins_ttcap->doubleStrikeShift; + maxRsb += ins_ttcap->adjustRightSideBearingByPixel; + minLsb += ins_ttcap->adjustLeftSideBearingByPixel; + /* */ + if( ins_ttcap->flags & TTCAP_DOUBLE_STRIKE ) + force_c_rsb += ins_ttcap->doubleStrikeShift; + force_c_rsb += ins_ttcap->force_c_adjust_rsb_by_pixel; + force_c_lsb += ins_ttcap->force_c_adjust_lsb_by_pixel; + /* apply to rawWidth */ + averageWidth = (int)floor(10 * width_x * scale + * ratio + 0.5); + rawWidth = floor(width_x * scale + * ratio * 1000. / base_height + 0.5); + rawAverageWidth = floor(width_x * scale * ratio * 10. + * 1000. / base_height + 0.5); + force_c_rawWidth = floor(force_c_width_x * scale + * force_c_ratio * 1000. / base_height + 0.5); + /* */ + } + /* for BITMAP fonts [if(face->bitmap)] */ + else { + /* These values differ from actual when outline, + so we must use them ONLY FOR BITMAP. */ + width = (int)floor(smetrics->max_advance * ins_ttcap->scaleBBoxWidth / 64.0 + .5); + descent = -smetrics->descender / 64; + ascent = smetrics->ascender / 64; + /* force constant */ + force_c_width = (int)floor(smetrics->max_advance + * ins_ttcap->force_c_scale_b_box_width / 64.0 + .5); + /* Preserve average width for bitmap fonts */ + if(vals->width != 0) + averageWidth = (int)floor(vals->width * ins_ttcap->scaleBBoxWidth +.5); + else + averageWidth = (int)floor(10.0 * smetrics->max_advance + * ins_ttcap->scaleBBoxWidth / 64.0 + .5); + rawWidth = 0; + rawAverageWidth = 0; + force_c_rawWidth = 0; + /* We don't consider vertical layouts */ + advance = (int)floor(smetrics->max_advance / 64.0 +.5); + unit_x = vals->pixel_matrix[0]; + unit_y = 0; + /* We can use 'width' only when bitmap. + This should not be set when outline. */ + minLsb = 0; + maxRsb = width; + /* force constant */ + if( ins_ttcap->flags & TTCAP_FORCE_C_LSB_FLAG ) + force_c_lsb = (int)floor(smetrics->max_advance + * ins_ttcap->force_c_scale_lsb / 64.0 + .5); + else + force_c_lsb = minLsb; + if( ins_ttcap->flags & TTCAP_FORCE_C_RSB_FLAG ) + force_c_rsb = (int)floor(smetrics->max_advance + * ins_ttcap->force_c_scale_rsb / 64.0 + .5); + else + force_c_rsb = maxRsb; + /* calculate shift of BitmapAutoItalic */ + if( ins_ttcap->autoItalic != 0 ) { + double ai; + int ai_lsb,ai_rsb,ai_total; + if( 0 < ins_ttcap->autoItalic ) ai=ins_ttcap->autoItalic; + else ai = -ins_ttcap->autoItalic; + ai_total = (int)( (ascent+descent) * ai + 0.5); + ai_rsb = (int)((double)ai_total * ascent / ( ascent + descent ) + 0.5 ); + ai_lsb = -(ai_total - ai_rsb); + if( 0 < ins_ttcap->autoItalic ) { + ins_ttcap->lsbShiftOfBitmapAutoItalic = ai_lsb; + ins_ttcap->rsbShiftOfBitmapAutoItalic = ai_rsb; + } + else { + ins_ttcap->lsbShiftOfBitmapAutoItalic = -ai_rsb; + ins_ttcap->rsbShiftOfBitmapAutoItalic = -ai_lsb; + } + } + /* integer adjustment by TTCap */ + if( ins_ttcap->flags & TTCAP_DOUBLE_STRIKE_CORRECT_B_BOX_WIDTH ) + width += ins_ttcap->doubleStrikeShift; + if( ins_ttcap->flags & TTCAP_DOUBLE_STRIKE ) + maxRsb += ins_ttcap->doubleStrikeShift; + maxRsb += ins_ttcap->adjustRightSideBearingByPixel; + minLsb += ins_ttcap->adjustLeftSideBearingByPixel; + /* We have not carried out matrix calculation, so this is done. */ + maxRsb += ins_ttcap->rsbShiftOfBitmapAutoItalic; + minLsb += ins_ttcap->lsbShiftOfBitmapAutoItalic; + /* force constant */ + if( ins_ttcap->flags & TTCAP_DOUBLE_STRIKE ) + force_c_rsb += ins_ttcap->doubleStrikeShift; + force_c_rsb += ins_ttcap->force_c_adjust_rsb_by_pixel; + force_c_lsb += ins_ttcap->force_c_adjust_lsb_by_pixel; + force_c_rsb += ins_ttcap->rsbShiftOfBitmapAutoItalic; + force_c_lsb += ins_ttcap->lsbShiftOfBitmapAutoItalic; + } + + /* SET CALCULATED VALUES TO INSTANCE */ + + /* Set actual height and cosine */ + instance->pixel_size = base_height; + instance->advance = advance; + if ( unit_x != 0 ){ + instance->pixel_width_unit_x = unit_x/base_height; + instance->pixel_width_unit_y = 0; + } + else{ + instance->pixel_width_unit_x = 0; + instance->pixel_width_unit_y = unit_y/base_height; + } + + /* header's metrics */ + instance->charcellMetrics = (xCharInfo*)xalloc(sizeof(xCharInfo)); + if(instance->charcellMetrics == NULL) { + xrc = AllocError; + goto quit; + } + instance->charcellMetrics->ascent = ascent; + instance->charcellMetrics->descent = descent; + instance->charcellMetrics->attributes = rawWidth; + instance->charcellMetrics->rightSideBearing = maxRsb; + instance->charcellMetrics->leftSideBearing = minLsb; + instance->charcellMetrics->characterWidth = width; + instance->averageWidth = averageWidth; + instance->rawAverageWidth = rawAverageWidth; + + /* Check code 0 */ + if( FreeTypeInstanceGetGlyph(font->zero_idx, 0, &tmpglyph, font->instance) != Successful + || tmpglyph == NULL) + if( FreeTypeInstanceGetGlyph(font->zero_idx, FT_GET_DUMMY, &tmpglyph, font->instance) + != Successful ) + tmpglyph = NULL; + if ( !tmpglyph ) { + xrc = AllocError; + goto quit; + } + + /* FORCE CONSTANT METRICS */ + if( 0 <= ins_ttcap->forceConstantSpacingEnd ) { + xCharInfo *tmpchar = NULL; + int c = ins_ttcap->force_c_representative_metrics_char_code; + /* header's metrics */ + if( instance->forceConstantMetrics == NULL ){ + instance->forceConstantMetrics = (xCharInfo*)xalloc(sizeof(xCharInfo)); + if(instance->forceConstantMetrics == NULL) { + xrc = AllocError; + goto quit; + } + } + /* Get Representative Metrics */ + if ( 0 <= c ) { + if( FreeTypeFontGetGlyphMetrics(c, 0, &tmpchar, font) != Successful ) + tmpchar = NULL; + } + if ( tmpchar && 0 < tmpchar->characterWidth ) { + instance->forceConstantMetrics->leftSideBearing = tmpchar->leftSideBearing; + instance->forceConstantMetrics->rightSideBearing = tmpchar->rightSideBearing; + instance->forceConstantMetrics->characterWidth = tmpchar->characterWidth; + instance->forceConstantMetrics->ascent = tmpchar->ascent; + instance->forceConstantMetrics->descent = tmpchar->descent; + instance->forceConstantMetrics->attributes = tmpchar->attributes; + } + else { + instance->forceConstantMetrics->leftSideBearing = force_c_lsb; + instance->forceConstantMetrics->rightSideBearing = force_c_rsb; + instance->forceConstantMetrics->characterWidth = force_c_width; + instance->forceConstantMetrics->ascent = ascent; + instance->forceConstantMetrics->descent = descent; + instance->forceConstantMetrics->attributes = force_c_rawWidth; + } + /* Check code 0 */ + if( FreeTypeInstanceGetGlyph(font->zero_idx, FT_FORCE_CONSTANT_SPACING, + &tmpglyph, font->instance) != Successful + || tmpglyph == NULL) + if( FreeTypeInstanceGetGlyph(font->zero_idx, FT_FORCE_CONSTANT_SPACING | FT_GET_DUMMY, + &tmpglyph, font->instance) + != Successful ) + tmpglyph = NULL; + if ( !tmpglyph ) { + xrc = AllocError; + goto quit; + } + } + } + else{ + + /* + * CACHED VALUES + */ + + width = instance->charcellMetrics->characterWidth; + ascent = instance->charcellMetrics->ascent; + descent = instance->charcellMetrics->descent; + rawWidth = instance->charcellMetrics->attributes; + maxRsb = instance->charcellMetrics->rightSideBearing; + minLsb = instance->charcellMetrics->leftSideBearing; + averageWidth = instance->averageWidth; + rawAverageWidth = instance->rawAverageWidth; + + } + + /* + * SET maxbounds, minbounds ... + */ + + if( !charcell ) { /* NOT CHARCELL */ + if( info ){ + /* + Calculate all glyphs' metrics. + maxbounds.ascent and maxbounds.descent are quite important values + for XAA. If ascent/descent of each glyph exceeds + maxbounds.ascent/maxbounds.descent, XAA causes SERVER CRASH. + Therefore, THIS MUST BE DONE. + */ + ft_compute_bounds(font,info,vals); + } + } + else{ /* CHARCELL */ + + /* + * SET CALCULATED OR CACHED VARIABLES + */ + + vals->width = averageWidth; + + if( info ){ + + info->maxbounds.leftSideBearing = minLsb; + info->maxbounds.rightSideBearing = maxRsb; + info->maxbounds.characterWidth = width; + info->maxbounds.ascent = ascent; + info->maxbounds.descent = descent; + info->maxbounds.attributes = + (unsigned short)(short)rawWidth; + + info->minbounds = info->maxbounds; + } + } + + /* set info */ + + if( info ){ + /* + info->fontAscent = ascent; + info->fontDescent = descent; + */ + info->fontAscent = info->maxbounds.ascent; + info->fontDescent = info->maxbounds.descent; + /* Glyph metrics are accurate */ + info->inkMetrics=1; + + memcpy((char *)&info->ink_maxbounds, + (char *)&info->maxbounds, sizeof(xCharInfo)); + memcpy((char *)&info->ink_minbounds, + (char *)&info->minbounds, sizeof(xCharInfo)); + + /* XXX - hack */ + info->defaultCh=0; + + /* Set the pInfo flags */ + /* Properties set by FontComputeInfoAccelerators: + pInfo->noOverlap; + pInfo->terminalFont; + pInfo->constantMetrics; + pInfo->constantWidth; + pInfo->inkInside; + */ + /* from lib/font/util/fontaccel.c */ + FontComputeInfoAccelerators(info); + } + + if(xf) + xf->fontPrivate = (void*)font; + + if(info) { + xrc = FreeTypeAddProperties(font, vals, info, entry->name.name, + rawAverageWidth, font_properties); + if (xrc != Successful) { + goto quit; + } + } + + quit: + if ( dynStrTTCapCodeRange ) xfree(dynStrTTCapCodeRange); + if ( dynStrFTFileName ) xfree(dynStrFTFileName); + if ( dynStrRealFileName ) xfree(dynStrRealFileName); + if ( xrc != Successful ) { + if( font ){ + if( face && font->instance == NULL ) FreeTypeFreeFace(face); + FreeTypeFreeFont(font); + } + } + return xrc; +} + +/* Routines used by X11 to get info and glyphs from the font. */ + +static int +FreeTypeGetMetrics(FontPtr pFont, unsigned long count, unsigned char *chars, + FontEncoding charEncoding, unsigned long *metricCount, + xCharInfo **metrics) +{ + unsigned int code = 0; + int flags = 0; + FTFontPtr tf; + struct TTCapInfo *ttcap; + xCharInfo **mp, *m; + + /* MUMBLE1("Get metrics for %ld characters\n", count);*/ + + tf = (FTFontPtr)pFont->fontPrivate; + ttcap = &tf->instance->ttcap; + mp = metrics; + + while (count-- > 0) { + switch (charEncoding) { + case Linear8Bit: + case TwoD8Bit: + code = *chars++; + break; + case Linear16Bit: + case TwoD16Bit: + code = (*chars++ << 8); + code |= *chars++; + /* */ + if ( !(ttcap->flags & TTCAP_FORCE_C_OUTSIDE) ) { + if ( (int)code <= ttcap->forceConstantSpacingEnd + && ttcap->forceConstantSpacingBegin <= (int)code ) + flags|=FT_FORCE_CONSTANT_SPACING; + else flags=0; + } + else { /* for GB18030 proportional */ + if ( (int)code <= ttcap->forceConstantSpacingEnd + || ttcap->forceConstantSpacingBegin <= (int)code ) + flags|=FT_FORCE_CONSTANT_SPACING; + else flags=0; + } + break; + } + + if(FreeTypeFontGetGlyphMetrics(code, flags, &m, tf) == Successful && m!=NULL) { + *mp++ = m; + } +#ifdef X_ACCEPTS_NO_SUCH_CHAR + else *mp++ = &noSuchChar.metrics; +#endif + } + + *metricCount = mp - metrics; + return Successful; +} + +static int +FreeTypeGetGlyphs(FontPtr pFont, unsigned long count, unsigned char *chars, + FontEncoding charEncoding, unsigned long *glyphCount, + CharInfoPtr *glyphs) +{ + unsigned int code = 0; + int flags = 0; + FTFontPtr tf; + CharInfoPtr *gp; + CharInfoPtr g; + struct TTCapInfo *ttcap; + + tf = (FTFontPtr)pFont->fontPrivate; + ttcap = &tf->instance->ttcap; + gp = glyphs; + + while (count-- > 0) { + switch (charEncoding) { + case Linear8Bit: case TwoD8Bit: + code = *chars++; + break; + case Linear16Bit: case TwoD16Bit: + code = *chars++ << 8; + code |= *chars++; + /* */ + if ( !(ttcap->flags & TTCAP_FORCE_C_OUTSIDE) ) { + if ( (int)code <= ttcap->forceConstantSpacingEnd + && ttcap->forceConstantSpacingBegin <= (int)code ) + flags|=FT_FORCE_CONSTANT_SPACING; + else flags=0; + } + else { /* for GB18030 proportional */ + if ( (int)code <= ttcap->forceConstantSpacingEnd + || ttcap->forceConstantSpacingBegin <= (int)code ) + flags|=FT_FORCE_CONSTANT_SPACING; + else flags=0; + } + break; + } + + if(FreeTypeFontGetGlyph(code, flags, &g, tf) == Successful && g!=NULL) { + *gp++ = g; + } +#ifdef X_ACCEPTS_NO_SUCH_CHAR + else { +#ifdef XAA_ACCEPTS_NULL_BITS + *gp++ = &noSuchChar; +#else + if ( tf->dummy_char.bits ) { + *gp++ = &tf->dummy_char; + } + else { + char *raster = NULL; + int wd_actual, ht_actual, wd, ht, bpr; + wd_actual = tf->info->maxbounds.rightSideBearing - tf->info->maxbounds.leftSideBearing; + ht_actual = tf->info->maxbounds.ascent + tf->info->maxbounds.descent; + if(wd_actual <= 0) wd = 1; + else wd=wd_actual; + if(ht_actual <= 0) ht = 1; + else ht=ht_actual; + bpr = (((wd + (tf->instance->bmfmt.glyph<<3) - 1) >> 3) & + -tf->instance->bmfmt.glyph); + raster = (char*)xalloc(ht * bpr); + if(raster) { + memset(raster, 0, ht * bpr); + tf->dummy_char.bits = raster; + *gp++ = &tf->dummy_char; + } + } +#endif + } +#endif + } + + *glyphCount = gp - glyphs; + return Successful; +} + +static int +FreeTypeSetUpFont(FontPathElementPtr fpe, FontPtr xf, FontInfoPtr info, + fsBitmapFormat format, fsBitmapFormatMask fmask, + FontBitmapFormatPtr bmfmt) +{ + int xrc; + int image; + + /* Get the default bitmap format information for this X installation. + Also update it for the client if running in the font server. */ + FontDefaultFormat(&bmfmt->bit, &bmfmt->byte, &bmfmt->glyph, &bmfmt->scan); + if ((xrc = CheckFSFormat(format, fmask, &bmfmt->bit, &bmfmt->byte, + &bmfmt->scan, &bmfmt->glyph, + &image)) != Successful) { + MUMBLE1("Aborting after checking FS format: %d\n", xrc); + return xrc; + } + + if(xf) { + xf->refcnt = 0; + xf->bit = bmfmt->bit; + xf->byte = bmfmt->byte; + xf->glyph = bmfmt->glyph; + xf->scan = bmfmt->scan; + xf->format = format; + xf->get_glyphs = FreeTypeGetGlyphs; + xf->get_metrics = FreeTypeGetMetrics; + xf->unload_font = FreeTypeUnloadXFont; + xf->unload_glyphs = 0; + xf->fpe = fpe; + xf->svrPrivate = 0; + xf->fontPrivate = 0; /* we'll set it later */ + xf->fpePrivate = 0; + } + + info->defaultCh = 0; + info->noOverlap = 0; /* not updated */ + info->terminalFont = 0; /* not updated */ + info->constantMetrics = 0; /* we'll set it later */ + info->constantWidth = 0; /* we'll set it later */ + info->inkInside = 1; + info->inkMetrics = 1; + info->allExist=0; /* not updated */ + info->drawDirection = LeftToRight; /* we'll set it later */ + info->cachable = 1; /* we don't do licensing */ + info->anamorphic = 0; /* can hinting lead to anamorphic scaling? */ + info->maxOverlap = 0; /* we'll set it later. */ + info->pad = 0; /* ??? */ + return Successful; +} + +/* Functions exported by the backend */ + +static int +FreeTypeOpenScalable(FontPathElementPtr fpe, FontPtr *ppFont, int flags, + FontEntryPtr entry, char *fileName, FontScalablePtr vals, + fsBitmapFormat format, fsBitmapFormatMask fmask, + FontPtr non_cachable_font) +{ + int xrc; + FontPtr xf; + FontBitmapFormatRec bmfmt; + + MUMBLE1("Open Scalable %s, XLFD=",fileName); +#ifdef DEBUG_TRUETYPE + fwrite(entry->name.name, entry->name.length, 1, stdout); +#endif + MUMBLE("\n"); + + xf = CreateFontRec(); + if (xf == NULL) + return AllocError; + + xrc = FreeTypeSetUpFont(fpe, xf, &xf->info, format, fmask, &bmfmt); + if(xrc != Successful) { + DestroyFontRec(xf); + return xrc; + } + xrc = FreeTypeLoadXFont(fileName, vals, xf, &xf->info, &bmfmt, entry); + if(xrc != Successful) { + MUMBLE1("Error during load: %d\n",xrc); + DestroyFontRec(xf); + return xrc; + } + + *ppFont = xf; + + return xrc; +} + +/* Routine to get requested font info. */ + +static int +FreeTypeGetInfoScalable(FontPathElementPtr fpe, FontInfoPtr info, + FontEntryPtr entry, FontNamePtr fontName, + char *fileName, FontScalablePtr vals) +{ + int xrc; + FontBitmapFormatRec bmfmt; + + MUMBLE("Get info, XLFD= "); +#ifdef DEBUG_TRUETYPE + fwrite(entry->name.name, entry->name.length, 1, stdout); +#endif + MUMBLE("\n"); + + xrc = FreeTypeSetUpFont(fpe, 0, info, 0, 0, &bmfmt); + if(xrc != Successful) { + return xrc; + } + + bmfmt.glyph <<= 3; + + xrc = FreeTypeLoadXFont(fileName, vals, 0, info, &bmfmt, entry); + if(xrc != Successful) { + MUMBLE1("Error during load: %d\n", xrc); + return xrc; + } + + return Successful; +} + +/* Renderer registration. */ + +/* Set the capabilities of this renderer. */ +#define CAPABILITIES (CAP_CHARSUBSETTING | CAP_MATRIX) + +/* Set it up so file names with either upper or lower case can be + loaded. We don't support compressed fonts. */ +static FontRendererRec renderers[] = { + {".ttf", 4, 0, FreeTypeOpenScalable, 0, + FreeTypeGetInfoScalable, 0, CAPABILITIES}, + {".TTF", 4, 0, FreeTypeOpenScalable, 0, + FreeTypeGetInfoScalable, 0, CAPABILITIES}, + {".ttc", 4, 0, FreeTypeOpenScalable, 0, + FreeTypeGetInfoScalable, 0, CAPABILITIES}, + {".TTC", 4, 0, FreeTypeOpenScalable, 0, + FreeTypeGetInfoScalable, 0, CAPABILITIES}, + {".otf", 4, 0, FreeTypeOpenScalable, 0, + FreeTypeGetInfoScalable, 0, CAPABILITIES}, + {".OTF", 4, 0, FreeTypeOpenScalable, 0, + FreeTypeGetInfoScalable, 0, CAPABILITIES}, + {".otc", 4, 0, FreeTypeOpenScalable, 0, + FreeTypeGetInfoScalable, 0, CAPABILITIES}, + {".OTC", 4, 0, FreeTypeOpenScalable, 0, + FreeTypeGetInfoScalable, 0, CAPABILITIES}, + {".pfa", 4, 0, FreeTypeOpenScalable, 0, + FreeTypeGetInfoScalable, 0, CAPABILITIES}, + {".PFA", 4, 0, FreeTypeOpenScalable, 0, + FreeTypeGetInfoScalable, 0, CAPABILITIES}, + {".pfb", 4, 0, FreeTypeOpenScalable, 0, + FreeTypeGetInfoScalable, 0, CAPABILITIES}, + {".PFB", 4, 0, FreeTypeOpenScalable, 0, + FreeTypeGetInfoScalable, 0, CAPABILITIES}, +}; +static int num_renderers = sizeof(renderers) / sizeof(renderers[0]); + +static FontRendererRec alt_renderers[] = { + {".bdf", 4, 0, FreeTypeOpenScalable, 0, + FreeTypeGetInfoScalable, 0, CAPABILITIES}, + {".BDF", 4, 0, FreeTypeOpenScalable, 0, + FreeTypeGetInfoScalable, 0, CAPABILITIES}, + {".pcf", 4, 0, FreeTypeOpenScalable, 0, + FreeTypeGetInfoScalable, 0, CAPABILITIES}, + {".PCF", 4, 0, FreeTypeOpenScalable, 0, + FreeTypeGetInfoScalable, 0, CAPABILITIES}, +}; + +static int num_alt_renderers = +sizeof(alt_renderers) / sizeof(alt_renderers[0]); + + +void +FreeTypeRegisterFontFileFunctions(void) +{ + int i; + + for (i = 0; i < num_renderers; i++) + FontFileRegisterRenderer(&renderers[i]); + + for (i = 0; i < num_alt_renderers; i++) + FontFilePriorityRegisterRenderer(&alt_renderers[i], -10); +} diff --git a/nx-X11/lib/font/FreeType/ftfuncs.h b/nx-X11/lib/font/FreeType/ftfuncs.h new file mode 100644 index 000000000..f115a8b77 --- /dev/null +++ b/nx-X11/lib/font/FreeType/ftfuncs.h @@ -0,0 +1,189 @@ +/* +Copyright (c) 1998-2002 by Juliusz Chroboczek +Copyright (c) 2003 After X-TT Project, All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ +/* $XFree86: xc/lib/font/FreeType/ftfuncs.h,v 1.17 2003/12/21 04:02:07 dawes Exp $ */ + +/* Number of buckets in the hashtable holding faces */ +#define NUMFACEBUCKETS 32 + +/* Glyphs are held in segments of this size */ +#define FONTSEGMENTSIZE 16 + +/* A structure that holds bitmap order and padding info. */ + +typedef struct { + int bit; /* bit order */ + int byte; /* byte order */ + int glyph; /* glyph pad size */ + int scan; /* machine word size */ +} FontBitmapFormatRec, *FontBitmapFormatPtr; + +struct FTSize_s; + +/* At the lowest level, there is face; FTFaces are in one-to-one + correspondence with TrueType faces. Multiple instance may share + the same face. */ + +typedef struct _FTFace { + char *filename; + FT_Face face; + int bitmap; + struct _FTInstance *instances; + struct _FTInstance *active_instance; + struct _FTFace *next; /* link to next face in bucket */ +} FTFaceRec, *FTFacePtr; + +/* A transformation matrix with resolution information */ +typedef struct _FTNormalisedTransformation { + double scale; + int nonIdentity; /* if 0, matrix is the identity */ + FT_Matrix matrix; + int xres, yres; +} FTNormalisedTransformationRec, *FTNormalisedTransformationPtr; + +#define FT_PROPORTIONAL 0 +#define FT_MONOSPACED 1 +#define FT_CHARCELL 2 + +#define FT_AVAILABLE_UNKNOWN 0 +#define FT_AVAILABLE_NO 1 +#define FT_AVAILABLE_METRICS 2 +#define FT_AVAILABLE_RASTERISED 3 + +#define FT_GET_GLYPH_BOTH 0x01 +#define FT_GET_GLYPH_METRICS_ONLY 0x02 +#define FT_GET_DUMMY 0x04 +#define FT_FORCE_CONSTANT_SPACING 0x08 + +#define TTCAP_DOUBLE_STRIKE 0x0001 +#define TTCAP_DOUBLE_STRIKE_MKBOLD_EDGE_LEFT 0x0002 +#define TTCAP_DOUBLE_STRIKE_CORRECT_B_BOX_WIDTH 0x0008 +#define TTCAP_IS_VERY_LAZY 0x0010 +#define TTCAP_DISABLE_DEFAULT_VERY_LAZY 0x0020 +#define TTCAP_FORCE_C_LSB_FLAG 0x0100 +#define TTCAP_FORCE_C_RSB_FLAG 0x0200 +#define TTCAP_FORCE_C_OUTSIDE 0x0400 +#define TTCAP_MONO_CENTER 0x0800 + +/* TTCap */ +struct TTCapInfo { + long flags; + double autoItalic; + double scaleWidth; + double scaleBBoxWidth; + double scaleBBoxHeight; + int doubleStrikeShift; + int adjustBBoxWidthByPixel; + int adjustLeftSideBearingByPixel; + int adjustRightSideBearingByPixel; + double scaleBitmap; + int forceConstantSpacingBegin; + int forceConstantSpacingEnd; + /* We don't compare */ + int force_c_adjust_width_by_pixel; + int force_c_adjust_lsb_by_pixel; + int force_c_adjust_rsb_by_pixel; + int force_c_representative_metrics_char_code; + double force_c_scale_b_box_width; + double force_c_scale_b_box_height; + double force_c_scale_lsb; + double force_c_scale_rsb; + double vl_slant; + int lsbShiftOfBitmapAutoItalic; + int rsbShiftOfBitmapAutoItalic; +}; + +/* An instance builds on a face by specifying the transformation + matrix. Multiple fonts may share the same instance. */ + +/* This structure caches bitmap data */ +typedef struct _FTInstance { + FTFacePtr face; /* the associated face */ + FT_Size size; + FTNormalisedTransformationRec transformation; + FT_Int32 load_flags; + FT_ULong strike_index; + int spacing; /* actual spacing */ + double pixel_size; /* to calc attributes (actual height) */ + double pixel_width_unit_x; /* to calc horiz. width (cosine) */ + double pixel_width_unit_y; /* to calc vert. width (cosine) */ + xCharInfo *charcellMetrics; /* the header's metrics */ + int averageWidth; /* the header's metrics */ + long rawAverageWidth; /* the header's metrics */ + double advance; /* the header's metrics */ + xCharInfo *forceConstantMetrics; + FontBitmapFormatRec bmfmt; + unsigned nglyphs; + CharInfoPtr *glyphs; /* glyphs and available are used in parallel */ + int **available; + struct TTCapInfo ttcap; + int refcount; + struct _FTInstance *next; /* link to next instance */ +} FTInstanceRec, *FTInstancePtr; + +/* A font is an instance with coding information; fonts are in + one-to-one correspondence with X fonts */ +typedef struct _FTFont{ + FTInstancePtr instance; + FTMappingRec mapping; + unsigned zero_idx; + FontInfoPtr info; + int nranges; + CharInfoRec dummy_char; + fsRange *ranges; +} FTFontRec, *FTFontPtr; + +#ifndef NOT_IN_FTFUNCS + +/* Prototypes for some local functions */ + +static int FreeTypeOpenFace(FTFacePtr *facep, char *FTFileName, char *realFileName, int faceNumber); +static void FreeTypeFreeFace(FTFacePtr face); +static int +FreeTypeOpenInstance(FTInstancePtr *instancep, FTFacePtr face, + char *FTFileName, FTNormalisedTransformationPtr trans, + int spacing, FontBitmapFormatPtr bmfmt, + struct TTCapInfo *tmp_ttcap, FT_Int32 load_flags); +static void FreeTypeFreeInstance(FTInstancePtr instance); +static int +FreeTypeInstanceGetGlyph(unsigned idx, int flags, CharInfoPtr *g, FTInstancePtr instance); +static int +FreeTypeInstanceGetGlyphMetrics(unsigned idx, int flags, + xCharInfo **metrics, FTInstancePtr instance ); +static int +FreeTypeRasteriseGlyph(unsigned idx, int flags, CharInfoPtr tgp, + FTInstancePtr instance, int hasMetrics ); +static void FreeTypeFreeFont(FTFontPtr font); +static void FreeTypeFreeXFont(FontPtr pFont, int freeProps); +static void FreeTypeUnloadXFont(FontPtr pFont); +static int +FreeTypeAddProperties(FTFontPtr font, FontScalablePtr vals, FontInfoPtr info, + char *fontname, int rawAverageWidth, Bool font_properties); +static int FreeTypeFontGetGlyph(unsigned code, int flags, CharInfoPtr *g, FTFontPtr font); +static int +FreeTypeLoadFont(FTFontPtr font, FontInfoPtr info, FTFacePtr face, + char *FTFileName, FontScalablePtr vals, FontEntryPtr entry, + FontBitmapFormatPtr bmfmt, FT_Int32 load_flags, + struct TTCapInfo *tmp_ttcap, char *dynStrTTCapCodeRange, + int ttcap_spacing ); + +#endif /* NOT_IN_FTFUNCS */ diff --git a/nx-X11/lib/font/FreeType/ftsystem.c b/nx-X11/lib/font/FreeType/ftsystem.c new file mode 100644 index 000000000..90c51c1bf --- /dev/null +++ b/nx-X11/lib/font/FreeType/ftsystem.c @@ -0,0 +1,332 @@ +/***************************************************************************/ +/* */ +/* ftsystem.c */ +/* */ +/* ANSI-specific FreeType low-level system interface (body). */ +/* */ +/* Copyright 1996-2001, 2002 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* Modified for XFree86. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + +/* Modified for XFree86 */ +/* $XFree86$ */ + + /*************************************************************************/ + /* */ + /* This file contains the default interface used by FreeType to access */ + /* low-level, i.e. memory management, i/o access as well as thread */ + /* synchronisation. It can be replaced by user-specific routines if */ + /* necessary. */ + /* */ + /*************************************************************************/ + + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <ft2build.h> +#include FT_CONFIG_CONFIG_H +#include FT_INTERNAL_DEBUG_H +#include FT_SYSTEM_H +#include FT_ERRORS_H +#include FT_TYPES_H + +#ifndef FONTMODULE +#include <stdio.h> +#include <stdlib.h> +#else +#include "Xmd.h" +#define _XTYPEDEF_BOOL +#include "Xdefs.h" +#define DONT_DEFINE_WRAPPERS +#include "xf86_ansic.h" +#undef DONT_DEFINE_WRAPPERS +#define malloc(x) xf86malloc(x) +#define realloc(x, y) xf86realloc(x, y) +#define free(x) xf86free(x) +#define FILE XF86FILE +#define fopen(x, y) xf86fopen(x, y) +#define fclose(x) xf86fclose(x) +#define fseek(x, y, z) xf86fseek(x, y, z) +#define ftell(x) xf86ftell(x) +#define SEEK_SET XF86_SEEK_SET +#define SEEK_END XF86_SEEK_END +#define fread(x, y, z, t) xf86fread(x, y, z, t) +#endif + + + /*************************************************************************/ + /* */ + /* MEMORY MANAGEMENT INTERFACE */ + /* */ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* It is not necessary to do any error checking for the */ + /* allocation-related functions. This will be done by the higher level */ + /* routines like FT_Alloc() or FT_Realloc(). */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* ft_alloc */ + /* */ + /* <Description> */ + /* The memory allocation function. */ + /* */ + /* <Input> */ + /* memory :: A pointer to the memory object. */ + /* */ + /* size :: The requested size in bytes. */ + /* */ + /* <Return> */ + /* The address of newly allocated block. */ + /* */ + FT_CALLBACK_DEF( void* ) + ft_alloc( FT_Memory memory, + long size ) + { + FT_UNUSED( memory ); + + return malloc( size ); + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* ft_realloc */ + /* */ + /* <Description> */ + /* The memory reallocation function. */ + /* */ + /* <Input> */ + /* memory :: A pointer to the memory object. */ + /* */ + /* cur_size :: The current size of the allocated memory block. */ + /* */ + /* new_size :: The newly requested size in bytes. */ + /* */ + /* block :: The current address of the block in memory. */ + /* */ + /* <Return> */ + /* The address of the reallocated memory block. */ + /* */ + FT_CALLBACK_DEF( void* ) + ft_realloc( FT_Memory memory, + long cur_size, + long new_size, + void* block ) + { + FT_UNUSED( memory ); + FT_UNUSED( cur_size ); + + return realloc( block, new_size ); + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* ft_free */ + /* */ + /* <Description> */ + /* The memory release function. */ + /* */ + /* <Input> */ + /* memory :: A pointer to the memory object. */ + /* */ + /* block :: The address of block in memory to be freed. */ + /* */ + FT_CALLBACK_DEF( void ) + ft_free( FT_Memory memory, + void* block ) + { + FT_UNUSED( memory ); + + free( block ); + } + + + /*************************************************************************/ + /* */ + /* RESOURCE MANAGEMENT INTERFACE */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ + /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ + /* messages during execution. */ + /* */ +#undef FT_COMPONENT +#define FT_COMPONENT trace_io + + /* We use the macro STREAM_FILE for convenience to extract the */ + /* system-specific stream handle from a given FreeType stream object */ +#define STREAM_FILE( stream ) ( (FILE*)stream->descriptor.pointer ) + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* ft_ansi_stream_close */ + /* */ + /* <Description> */ + /* The function to close a stream. */ + /* */ + /* <Input> */ + /* stream :: A pointer to the stream object. */ + /* */ + FT_CALLBACK_DEF( void ) + ft_ansi_stream_close( FT_Stream stream ) + { + fclose( STREAM_FILE( stream ) ); + + stream->descriptor.pointer = NULL; + stream->size = 0; + stream->base = 0; + } + + + /*************************************************************************/ + /* */ + /* <Function> */ + /* ft_ansi_stream_io */ + /* */ + /* <Description> */ + /* The function to open a stream. */ + /* */ + /* <Input> */ + /* stream :: A pointer to the stream object. */ + /* */ + /* offset :: The position in the data stream to start reading. */ + /* */ + /* buffer :: The address of buffer to store the read data. */ + /* */ + /* count :: The number of bytes to read from the stream. */ + /* */ + /* <Return> */ + /* The number of bytes actually read. */ + /* */ + FT_CALLBACK_DEF( unsigned long ) + ft_ansi_stream_io( FT_Stream stream, + unsigned long offset, + unsigned char* buffer, + unsigned long count ) + { + FILE* file; + + + file = STREAM_FILE( stream ); + + fseek( file, offset, SEEK_SET ); + + return (unsigned long)fread( buffer, 1, count, file ); + } + + + /* documentation is in ftobjs.h */ + + FT_EXPORT_DEF( FT_Error ) + FT_Stream_Open( FT_Stream stream, + const char* filepathname ) + { + FILE* file; + + + if ( !stream ) + return FT_Err_Invalid_Stream_Handle; + + file = fopen( filepathname, "rb" ); + if ( !file ) + { + FT_ERROR(( "FT_Stream_Open:" )); + FT_ERROR(( " could not open `%s'\n", filepathname )); + + return FT_Err_Cannot_Open_Resource; + } + + fseek( file, 0, SEEK_END ); + stream->size = ftell( file ); + fseek( file, 0, SEEK_SET ); + + stream->descriptor.pointer = file; + stream->pathname.pointer = (char*)filepathname; + stream->pos = 0; + + stream->read = ft_ansi_stream_io; + stream->close = ft_ansi_stream_close; + + FT_TRACE1(( "FT_Stream_Open:" )); + FT_TRACE1(( " opened `%s' (%d bytes) successfully\n", + filepathname, stream->size )); + + return FT_Err_Ok; + } + + +#ifdef FT_DEBUG_MEMORY + + extern FT_Int + ft_mem_debug_init( FT_Memory memory ); + + extern void + ft_mem_debug_done( FT_Memory memory ); + +#endif + + + /* documentation is in ftobjs.h */ + + FT_EXPORT_DEF( FT_Memory ) + FT_New_Memory( void ) + { + FT_Memory memory; + + + memory = (FT_Memory)malloc( sizeof ( *memory ) ); + if ( memory ) + { + memory->user = 0; + memory->alloc = ft_alloc; + memory->realloc = ft_realloc; + memory->free = ft_free; +#ifdef FT_DEBUG_MEMORY + ft_mem_debug_init( memory ); +#endif + } + + return memory; + } + + + /* documentation is in ftobjs.h */ + + FT_EXPORT_DEF( void ) + FT_Done_Memory( FT_Memory memory ) + { +#ifdef FT_DEBUG_MEMORY + ft_mem_debug_done( memory ); +#endif +#undef free + memory->free( memory, memory ); + } + + +/* END */ diff --git a/nx-X11/lib/font/FreeType/fttools.c b/nx-X11/lib/font/FreeType/fttools.c new file mode 100644 index 000000000..9251838a9 --- /dev/null +++ b/nx-X11/lib/font/FreeType/fttools.c @@ -0,0 +1,201 @@ +/* + Copyright (c) 1997 by Mark Leisher + Copyright (c) 1998-2002 by Juliusz Chroboczek + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +/* $XFree86: xc/lib/font/FreeType/fttools.c,v 1.6 2003/06/08 15:41:13 herrb Exp $ */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <X11/fonts/fontmisc.h> +#ifndef FONTMODULE +#include <ctype.h> +#include <string.h> +#else +#include "Xmd.h" +#include "Xdefs.h" +#include "xf86_ansic.h" +#endif + +#include <X11/fonts/font.h> +#include <ft2build.h> +#include FT_FREETYPE_H +#include FT_SFNT_NAMES_H +#include FT_TRUETYPE_IDS_H +#include "ft.h" + +/* backward compatibility hack */ +#if (FREETYPE_VERSION < 2001008) +# ifndef ft_isdigit +# define ft_isdigit isdigit +# endif +#endif + +#ifndef LSBFirst +#define LSBFirst 0 +#define MSBFirst 1 +#endif + +#define LOBYTE(s,byte) ((byte)==LSBFirst?*(char*)(s):*((char*)(s)+1)) +#define HIBYTE(s,byte) ((byte)==LSBFirst?*((char*)(s)+1):*(char*)(s)) + +int FTtoXReturnCode(int rc) +{ + if(rc == 0x40) + return AllocError; + /* Anything else stops the font matching mechanism */ + else return BadFontName; + +} + +/* Convert slen bytes from UCS-2 to ISO 8859-1. Byte specifies the + endianness of the string, max the maximum number of bytes written into + to. */ +static int +FTu2a(int slen, FT_Byte *from, char *to, int byte, int max) +{ + int i, n; + + n = 0; + for (i = 0; i < slen; i += 2) { + if(n >= max) + break; + if(HIBYTE(from+i, byte)!=0) + *to++='?'; + else + *to++ = LOBYTE(from+i,byte); + n++; + } + *to = 0; + return n; +} + +static int +FTGetName(FT_Face face, int nid, int pid, int eid, FT_SfntName *name_return) +{ + FT_SfntName name; + int n, i; + + n = FT_Get_Sfnt_Name_Count(face); + if(n <= 0) + return 0; + + for(i = 0; i < n; i++) { + if(FT_Get_Sfnt_Name(face, i, &name)) + continue; + if(name.name_id == nid && + name.platform_id == pid && + (eid < 0 || name.encoding_id == eid)) { + switch(name.platform_id) { + case TT_PLATFORM_APPLE_UNICODE: + case TT_PLATFORM_MACINTOSH: + if(name.language_id != TT_MAC_LANGID_ENGLISH) + continue; + break; + case TT_PLATFORM_MICROSOFT: + if(name.language_id != TT_MS_LANGID_ENGLISH_UNITED_STATES && + name.language_id != TT_MS_LANGID_ENGLISH_UNITED_KINGDOM) + break; + continue; + break; + default: + break; + } + *name_return = name; + return 1; + } + } + return 0; +} + +int +FTGetEnglishName(FT_Face face, int nid, char *name_return, int name_len) +{ + FT_SfntName name; + int len; + + if(FTGetName(face, nid, + TT_PLATFORM_MICROSOFT, TT_MS_ID_UNICODE_CS, &name) || + FTGetName(face, nid, + TT_PLATFORM_APPLE_UNICODE, -1, &name)) + return FTu2a(name.string_len, name.string, name_return, + MSBFirst, name_len); + + /* Pretend that Apple Roman is ISO 8859-1. */ + if(FTGetName(face, nid, TT_PLATFORM_MACINTOSH, TT_MAC_ID_ROMAN, &name)) { + len = name.string_len; + if(len > name_len) + len = name_len; + memcpy(name_return, name.string, len); + return len; + } + + /* Must be some font that can only be named in Polish or something. */ + return -1; +} + +int +FTcheckForTTCName(char *fileName, char **realFileName, int *faceNumber) +{ + int length; + int fn; + int i, j; + char *start, *realName; + + length = strlen(fileName); + if(length < 4) + return 0; + + if(strcasecmp(fileName + (length-4), ".ttc") != 0 && + strcasecmp(fileName + (length-4), ".otc") != 0) + return 0; + + realName = xalloc(length + 1); + if(realName == NULL) + return 0; + + strcpy(realName, fileName); + *realFileName=realName; + start = strchr(realName, ':'); + if(start) { + fn=0; + i=1; + while(ft_isdigit(start[i])) { + fn *= 10; + fn += start[i]-'0'; + i++; + } + if(start[i]==':') { + *faceNumber = fn; + i++; + j = 0; + while(start[i]) { + start[j++] = start[i++]; + } + start[j] = '\0'; + return 1; + } + } + + *faceNumber = 0; + return 1; +} diff --git a/nx-X11/lib/font/FreeType/module/Imakefile b/nx-X11/lib/font/FreeType/module/Imakefile new file mode 100644 index 000000000..855220b1e --- /dev/null +++ b/nx-X11/lib/font/FreeType/module/Imakefile @@ -0,0 +1,111 @@ +XCOMM $XFree86: xc/lib/font/FreeType/module/Imakefile,v 1.16 2003/11/05 16:58:35 tsi Exp $ + +FT2INCDIR = $(TOP)/extras/freetype2/include +FT2SOURCEDIR = $(TOP)/extras/freetype2/src + +/*#define BuildFreetypeDlModule NO*/ + +#if !defined(BuildFreetypeDlModule) +# define BuildFreetypeDlModule (HasFreetype2 && HasDlopen) +#endif + +#if !BuildFreetypeDlModule +EXTRADEFINES = Freetype2BuildDefines -DFONTMODULE +# else +# undef MakeDllModules +# define MakeDllModules YES +#endif + + + +DEFINES = $(EXTRADEFINES) -DXFREE86_FT2 $(INTERNALDEFINES) +#define IHaveModules +#include <Server.tmpl> + + +#if BuildFreetypeDlModule + +FT2INCLUDES = $(FREETYPE2INCLUDES) +EXTLIB = $(FREETYPE2LIB) + +# if !HasFreetype2 +LINKFT2LIB = -L$(BUILDLIBDIR) +# endif +#else + +FT2INCLUDES = -I$(FT2INCDIR) \ + -I$(FT2SOURCEDIR)/base \ + -I$(FT2SOURCEDIR)/gzip \ + -I$(FT2SOURCEDIR)/raster \ + -I$(FT2SOURCEDIR)/sfnt \ + -I$(FT2SOURCEDIR)/truetype \ + -I$(FT2SOURCEDIR)/cff \ + -I$(FT2SOURCEDIR)/type1 \ + -I$(FT2SOURCEDIR)/psaux \ + -I$(FT2SOURCEDIR)/psnames \ + -I$(FT2SOURCEDIR)/pshinter \ + -I$(FT2SOURCEDIR)/autohint \ + -I$(FT2SOURCEDIR)/bdf \ + -I$(FT2SOURCEDIR)/pcf \ + -I$(FT2SOURCEDIR)/lzw + +FT2SRCS = ftbase.c ftinit.c ftglyph.c ftbbox.c ftsystem.c fttype1.c ftxf86.c \ + ftgzip.c raster.c sfnt.c truetype.c cff.c type1.c \ + psaux.c psnames.c pshinter.c autohint.c ftlzw.c \ + ftbdf.c bdf.c pcf.c +FT2OBJS = ftbase.o ftinit.o ftglyph.o ftbbox.o ftsystem.o fttype1.o ftxf86.o \ + ftgzip.o raster.o sfnt.o truetype.o cff.o type1.o \ + psaux.o psnames.o pshinter.o autohint.o ftlzw.o \ + ftbdf.o bdf.o pcf.o +#endif + +INCLUDES = -I. -I.. -I$(FONTINCSRC) -I../../include -I$(XINCLUDESRC) \ + -I$(SERVERSRC)/include $(FT2INCLUDES) -I$(INCLUDESRC) + +SRCS = xttcap.c ftfuncs.c ftenc.c fttools.c $(FT2SRCS) ftmodule.c +OBJS = xttcap.o ftfuncs.o ftenc.o fttools.o $(FT2OBJS) ftmodule.o + +LinkSourceFile(ftenc.c,..) +LinkSourceFile(ftfuncs.c,..) +LinkSourceFile(fttools.c,..) +LinkSourceFile(xttcap.c,..) + +#if !BuildFreetypeDlModule +LinkSourceFile(ftbase.c,$(FT2SOURCEDIR)/base) +LinkSourceFile(ftinit.c,$(FT2SOURCEDIR)/base) +LinkSourceFile(ftglyph.c,$(FT2SOURCEDIR)/base) +LinkSourceFile(ftbbox.c,$(FT2SOURCEDIR)/base) +LinkSourceFile(ftsystem.c,..) +LinkSourceFile(ftutil.c,$(FT2SOURCEDIR)/base) +LinkSourceFile(fttype1.c,$(FT2SOURCEDIR)/base) +LinkSourceFile(ftxf86.c,$(FT2SOURCEDIR)/base) +LinkSourceFile(ftgzip.c,$(FT2SOURCEDIR)/gzip) +LinkSourceFile(raster.c,$(FT2SOURCEDIR)/raster) +LinkSourceFile(sfnt.c,$(FT2SOURCEDIR)/sfnt) +LinkSourceFile(truetype.c,$(FT2SOURCEDIR)/truetype) +LinkSourceFile(cff.c,$(FT2SOURCEDIR)/cff) +LinkSourceFile(type1.c,$(FT2SOURCEDIR)/type1) +LinkSourceFile(psaux.c,$(FT2SOURCEDIR)/psaux) +LinkSourceFile(psnames.c,$(FT2SOURCEDIR)/psnames) +LinkSourceFile(pshinter.c,$(FT2SOURCEDIR)/pshinter) +LinkSourceFile(autohint.c,$(FT2SOURCEDIR)/autohint) +LinkSourceFile(ftbdf.c,$(FT2SOURCEDIR)/base) +LinkSourceFile(bdf.c,$(FT2SOURCEDIR)/bdf) +LinkSourceFile(pcf.c,$(FT2SOURCEDIR)/pcf) +LinkSourceFile(ftlzw.c,$(FT2SOURCEDIR)/lzw) +#endif + +ModuleObjectRule() + +#if !BuildFreetypeDlModule +LibraryModuleTarget(freetype,$(OBJS)) +InstallLibraryModule(freetype,$(MODULEDIR),fonts) +InstallDriverSDKLibraryModule(freetype,$(DRIVERSDKMODULEDIR),fonts) +#else +DepDynamicModuleTarget(Concat3(lib,freetype,.so), $(OBJS), $(LINKFT2LIB) $(OBJS) $(EXTLIB)) +InstallDynamicModule(Concat3(lib,freetype,.so),$(MODULEDIR),fonts) +InstallDriverSDKDynamicModule(Concat3(lib,freetype,.so),$(DRIVERSDKMODULEDIR),fonts) +#endif + +DependTarget() + diff --git a/nx-X11/lib/font/FreeType/module/ft2build.h b/nx-X11/lib/font/FreeType/module/ft2build.h new file mode 100644 index 000000000..83b9d4802 --- /dev/null +++ b/nx-X11/lib/font/FreeType/module/ft2build.h @@ -0,0 +1,45 @@ +/***************************************************************************/ +/* */ +/* ft2build.h */ +/* */ +/* FreeType 2 build and setup macros. */ +/* */ +/* Copyright 1996-2001 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* Modified for XFree86. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + +/* $XFree86: xc/lib/font/FreeType/ft2build.h,v 1.3 2002/10/01 00:02:10 alanh Exp $ */ + +/* $XdotOrg: xc/lib/font/FreeType/module/ft2build.h,v 1.3 2005/07/03 07:00:58 daniels Exp $ */ + /*************************************************************************/ + /* */ + /* This file corresponds to the default "ft2build.h" file for */ + /* FreeType 2. It uses the "freetype" include root. */ + /* */ + /* Note that specific platforms might use a different configuration. */ + /* See builds/unix/ft2unix.h for an example. */ + /* */ + /*************************************************************************/ + +#ifndef __FT2_BUILD_GENERIC_H__ +#define __FT2_BUILD_GENERIC_H__ + +# if defined (FONTMODULE) +# include "ftheader.h" +# else +#include <freetype/config/ftheader.h> +# endif + +#endif /* __FT2_BUILD_GENERIC_H__ */ + + +/* END */ diff --git a/nx-X11/lib/font/FreeType/module/ftheader.h b/nx-X11/lib/font/FreeType/module/ftheader.h new file mode 100644 index 000000000..ec1671c41 --- /dev/null +++ b/nx-X11/lib/font/FreeType/module/ftheader.h @@ -0,0 +1,550 @@ +/***************************************************************************/ +/* */ +/* ftheader.h */ +/* */ +/* Build macros of the FreeType 2 library. */ +/* */ +/* Copyright 1996-2001, 2002 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ +/* $XFree86: xc/lib/font/FreeType/ftheader.h,v 1.4 2003/05/29 03:05:08 dawes Exp $ */ + +#ifndef __FT_HEADER_H__ +#define __FT_HEADER_H__ + + /*@***********************************************************************/ + /* */ + /* <Macro> */ + /* FT_BEGIN_HEADER */ + /* */ + /* <Description> */ + /* This macro is used in association with @FT_END_HEADER in header */ + /* files to ensure that the declarations within are properly */ + /* encapsulated in an `extern "C" { .. }' block when included from a */ + /* C++ compiler. */ + /* */ +#ifdef __cplusplus +#define FT_BEGIN_HEADER extern "C" { +#else +#define FT_BEGIN_HEADER /* nothing */ +#endif + + + /*@***********************************************************************/ + /* */ + /* <Macro> */ + /* FT_END_HEADER */ + /* */ + /* <Description> */ + /* This macro is used in association with @FT_BEGIN_HEADER in header */ + /* files to ensure that the declarations within are properly */ + /* encapsulated in an `extern "C" { .. }' block when included from a */ + /* C++ compiler. */ + /* */ +#ifdef __cplusplus +#define FT_END_HEADER } +#else +#define FT_END_HEADER /* nothing */ +#endif + + + /*************************************************************************/ + /* */ + /* Aliases for the FreeType 2 public and configuration files. */ + /* */ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* <Section> */ + /* header_file_macros */ + /* */ + /* <Title> */ + /* Header File Macros */ + /* */ + /* <Abstract> */ + /* Macro definitions used to #include specific header files. */ + /* */ + /* <Description> */ + /* The following macros are defined to the name of specific */ + /* FreeType 2 header files. They can be used directly in #include */ + /* statements as in: */ + /* */ + /* { */ + /* #include FT_FREETYPE_H */ + /* #include FT_MULTIPLE_MASTERS_H */ + /* #include FT_GLYPH_H */ + /* } */ + /* */ + /* There are several reasons why we are now using macros to name */ + /* public header files. The first one is that such macros are not */ + /* limited to the infamous 8.3 naming rule required by DOS (and */ + /* `FT_MULTIPLE_MASTERS_H' is a lot more meaningful than `ftmm.h'). */ + /* */ + /* The second reason is that is allows for more flexibility in the */ + /* way FreeType 2 is installed on a given system. */ + /* */ + /*************************************************************************/ + + /* configuration files */ + + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_CONFIG_CONFIG_H */ + /* */ + /* @description: */ + /* A macro used in #include statements to name the file containing */ + /* FreeType 2 configuration data. */ + /* */ +#ifndef FT_CONFIG_CONFIG_H +#define FT_CONFIG_CONFIG_H <freetype/config/ftconfig.h> +#endif + + + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_CONFIG_STANDARD_LIBRARY_H */ + /* */ + /* @description: */ + /* A macro used in #include statements to name the file containing */ + /* FreeType 2 configuration data. */ + /* */ +#ifndef FT_CONFIG_STANDARD_LIBRARY_H +#define FT_CONFIG_STANDARD_LIBRARY_H <myftstdlib.h> +#endif + + + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_CONFIG_OPTIONS_H */ + /* */ + /* @description: */ + /* A macro used in #include statements to name the file containing */ + /* FreeType 2 project-specific configuration options. */ + /* */ +#ifndef FT_CONFIG_OPTIONS_H +#define FT_CONFIG_OPTIONS_H <ftoption.h> +#endif + + + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_CONFIG_MODULES_H */ + /* */ + /* @description: */ + /* A macro used in #include statements to name the file containing */ + /* the list of FreeType 2 modules that are statically linked to new */ + /* library instances in @FT_Init_FreeType. */ + /* */ +#ifndef FT_CONFIG_MODULES_H +#define FT_CONFIG_MODULES_H <ftmodule.h> +#endif + + /* public headers */ + + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_FREETYPE_H */ + /* */ + /* @description: */ + /* A macro used in #include statements to name the file containing */ + /* the base FreeType 2 API. */ + /* */ +#define FT_FREETYPE_H <freetype/freetype.h> + + + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_ERRORS_H */ + /* */ + /* @description: */ + /* A macro used in #include statements to name the file containing */ + /* the list of FreeType 2 error codes (and messages). */ + /* */ + /* It is included by @FT_FREETYPE_H. */ + /* */ +#define FT_ERRORS_H <freetype/fterrors.h> + + + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_MODULE_ERRORS_H */ + /* */ + /* @description: */ + /* A macro used in #include statements to name the file containing */ + /* the list of FreeType 2 module error offsets (and messages). */ + /* */ +#define FT_MODULE_ERRORS_H <freetype/ftmoderr.h> + + + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_SYSTEM_H */ + /* */ + /* @description: */ + /* A macro used in #include statements to name the file containing */ + /* the FreeType 2 interface to low-level operations (i.e. memory */ + /* management and stream i/o). */ + /* */ + /* It is included by @FT_FREETYPE_H. */ + /* */ +#define FT_SYSTEM_H <freetype/ftsystem.h> + + + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_IMAGE_H */ + /* */ + /* @description: */ + /* A macro used in #include statements to name the file containing */ + /* types definitions related to glyph images (i.e. bitmaps, outlines, */ + /* scan-converter parameters). */ + /* */ + /* It is included by @FT_FREETYPE_H. */ + /* */ +#define FT_IMAGE_H <freetype/ftimage.h> + + + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_TYPES_H */ + /* */ + /* @description: */ + /* A macro used in #include statements to name the file containing */ + /* the basic data types defined by FreeType 2. */ + /* */ + /* It is included by @FT_FREETYPE_H. */ + /* */ +#define FT_TYPES_H <fttypes.h> + + + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_LIST_H */ + /* */ + /* @description: */ + /* A macro used in #include statements to name the file containing */ + /* the list management API of FreeType 2. */ + /* */ + /* (Most applications will never need to include this file.) */ + /* */ +#define FT_LIST_H <freetype/ftlist.h> + + + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_OUTLINE_H */ + /* */ + /* @description: */ + /* A macro used in #include statements to name the file containing */ + /* the scalable outline management API of FreeType 2. */ + /* */ +#define FT_OUTLINE_H <freetype/ftoutln.h> + + + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_SIZES_H */ + /* */ + /* @description: */ + /* A macro used in #include statements to name the file containing */ + /* the API used to manage multiple @FT_Size objects per face. */ + /* */ +#define FT_SIZES_H <freetype/ftsizes.h> + + + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_MODULE_H */ + /* */ + /* @description: */ + /* A macro used in #include statements to name the file containing */ + /* the module management API of FreeType 2. */ + /* */ +#define FT_MODULE_H <freetype/ftmodapi.h> + + + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_RENDER_H */ + /* */ + /* @description: */ + /* A macro used in #include statements to name the file containing */ + /* the renderer module management API of FreeType 2. */ + /* */ +#define FT_RENDER_H <freetype/ftrender.h> + + + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_TYPE1_TABLES_H */ + /* */ + /* @description: */ + /* A macro used in #include statements to name the file containing */ + /* the types and API specific to the Type 1 format. */ + /* */ +#define FT_TYPE1_TABLES_H <freetype/t1tables.h> + + + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_TRUETYPE_IDS_H */ + /* */ + /* @description: */ + /* A macro used in #include statements to name the file containing */ + /* the enumeration values used to identify name strings, languages, */ + /* encodings, etc. This file really contains a _large_ set of */ + /* constant macro definitions, taken from the TrueType and OpenType */ + /* specifications. */ + /* */ +#define FT_TRUETYPE_IDS_H <freetype/ttnameid.h> + + + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_TRUETYPE_TABLES_H */ + /* */ + /* @description: */ + /* A macro used in #include statements to name the file containing */ + /* the types and API specific to the TrueType (as well as OpenType) */ + /* format. */ + /* */ +#define FT_TRUETYPE_TABLES_H <freetype/tttables.h> + + + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_TRUETYPE_TAGS_H */ + /* */ + /* @description: */ + /* A macro used in #include statements to name the file containing */ + /* the definitions of TrueType 4-byte `tags' used to identify blocks */ + /* in SFNT-based font formats (i.e. TrueType and OpenType). */ + /* */ +#define FT_TRUETYPE_TAGS_H <freetype/tttags.h> + + + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_BDF_H */ + /* */ + /* @description: */ + /* A macro used in #include statements to name the file containing */ + /* the definitions of an API to access BDF-specific strings from a */ + /* face. */ + /* */ +#define FT_BDF_H <freetype/ftbdf.h> + + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_GZIP_H */ + /* */ + /* @description: */ + /* A macro used in #include statements to name the file containing */ + /* the definitions of an API to support for gzip-compressed files. */ + /* */ +#define FT_GZIP_H <freetype/ftgzip.h> + + + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_LZW_H */ + /* */ + /* @description: */ + /* A macro used in #include statements to name the file containing */ + /* the definitions of an API to support for LZW-compressed files. */ + /* */ +#define FT_LZW_H <freetype/ftlzw.h> + + + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_WINFONTS_H */ + /* */ + /* @description: */ + /* A macro used in #include statements to name the file containing */ + /* the definitions of an API to support Windows .FNT files */ + /* */ +#define FT_WINFONTS_H <freetype/ftwinfnt.h> + + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_GLYPH_H */ + /* */ + /* @description: */ + /* A macro used in #include statements to name the file containing */ + /* the API of the optional glyph management component. */ + /* */ +#define FT_GLYPH_H <freetype/ftglyph.h> + + + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_BBOX_H */ + /* */ + /* @description: */ + /* A macro used in #include statements to name the file containing */ + /* the API of the optional exact bounding box computation routines. */ + /* */ +#define FT_BBOX_H <freetype/ftbbox.h> + + + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_CACHE_H */ + /* */ + /* @description: */ + /* A macro used in #include statements to name the file containing */ + /* the API of the optional FreeType 2 cache sub-system. */ + /* */ +#define FT_CACHE_H <freetype/ftcache.h> + + + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_CACHE_IMAGE_H */ + /* */ + /* @description: */ + /* A macro used in #include statements to name the file containing */ + /* the `glyph image' API of the FreeType 2 cache sub-system. */ + /* */ + /* It is used to define a cache for @FT_Glyph elements. You can also */ + /* see the API defined in @FT_CACHE_SMALL_BITMAPS_H if you only need */ + /* to store small glyph bitmaps, as it will use less memory. */ + /* */ +#define FT_CACHE_IMAGE_H <freetype/cache/ftcimage.h> + + + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_CACHE_SMALL_BITMAPS_H */ + /* */ + /* @description: */ + /* A macro used in #include statements to name the file containing */ + /* the `small bitmaps' API of the FreeType 2 cache sub-system. */ + /* */ + /* It is used to define a cache for small glyph bitmaps in a */ + /* relatively memory-efficient way. You can also use the API defined */ + /* in @FT_CACHE_IMAGE_H if you want to cache arbitrary glyph images, */ + /* including scalable outlines. */ + /* */ +#define FT_CACHE_SMALL_BITMAPS_H <freetype/cache/ftcsbits.h> + + + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_CACHE_CHARMAP_H */ + /* */ + /* @description: */ + /* A macro used in #include statements to name the file containing */ + /* the `charmap' API of the FreeType 2 cache sub-system. */ + /* */ +#define FT_CACHE_CHARMAP_H <freetype/cache/ftccmap.h> + + + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_MAC_H */ + /* */ + /* @description: */ + /* A macro used in #include statements to name the file containing */ + /* the Macintosh-specific FreeType 2 API. The latter is used to */ + /* access fonts embedded in resource forks. */ + /* */ + /* This header file must be explicitly included by client */ + /* applications compiled on the Mac (note that the base API still */ + /* works though). */ + /* */ +#define FT_MAC_H <freetype/ftmac.h> + + + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_MULTIPLE_MASTERS_H */ + /* */ + /* @description: */ + /* A macro used in #include statements to name the file containing */ + /* the optional multiple-masters management API of FreeType 2. */ + /* */ +#define FT_MULTIPLE_MASTERS_H <freetype/ftmm.h> + + + /*************************************************************************/ + /* */ + /* @macro: */ + /* FT_SFNT_NAMES_H */ + /* */ + /* @description: */ + /* A macro used in #include statements to name the file containing */ + /* the optional FreeType 2 API used to access embedded `name' strings */ + /* in SFNT-based font formats (i.e. TrueType and OpenType). */ + /* */ +#define FT_SFNT_NAMES_H <freetype/ftsnames.h> + + /* */ + +#define FT_TRIGONOMETRY_H <freetype/fttrigon.h> +#define FT_STROKER_H <freetype/ftstroke.h> +#define FT_SYNTHESIS_H <freetype/ftsynth.h> +#define FT_ERROR_DEFINITIONS_H <freetype/fterrdef.h> + +#define FT_CACHE_MANAGER_H <freetype/cache/ftcmanag.h> + +#define FT_CACHE_INTERNAL_LRU_H <freetype/cache/ftlru.h> +#define FT_CACHE_INTERNAL_GLYPH_H <freetype/cache/ftcglyph.h> +#define FT_CACHE_INTERNAL_CACHE_H <freetype/cache/ftccache.h> + +#define FT_XFREE86_H <freetype/ftxf86.h> + +#define FT_INCREMENTAL_H <freetype/ftincrem.h> + +#define FT_TRUETYPE_UNPATENTED_H <freetype/ttunpat.h> + + /* now include internal headers definitions from <freetype/internal/...> */ + +#define FT_INTERNAL_INTERNAL_H <freetype/internal/internal.h> +#include FT_INTERNAL_INTERNAL_H + + +#endif /* __FT2_BUILD_H__ */ + + +/* END */ diff --git a/nx-X11/lib/font/FreeType/module/ftmodule.c b/nx-X11/lib/font/FreeType/module/ftmodule.c new file mode 100644 index 000000000..c2fe79089 --- /dev/null +++ b/nx-X11/lib/font/FreeType/module/ftmodule.c @@ -0,0 +1,76 @@ +/* + * Copyright (C) 1998-2002 The XFree86 Project, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of the XFree86 Project shall + * not be used in advertising or otherwise to promote the sale, use or other + * dealings in this Software without prior written authorization from the + * XFree86 Project. + */ +/* $XFree86: xc/lib/font/FreeType/module/ftmodule.c,v 1.18 2003/11/02 04:30:57 dawes Exp $ */ + +#include "misc.h" + +#include <X11/fonts/fontmod.h> +#include "xf86Module.h" + +#ifdef HAVE_XORG_CONFIG_H +#include <xorg-config.h> +#endif + +static MODULESETUPPROTO(freetypeSetup); + + /* + * This is the module data function that is accessed when loading + * libfreetype as a module. + */ + +static XF86ModuleVersionInfo VersRec = +{ + "freetype", + MODULEVENDORSTRING " & the After X-TT Project", + MODINFOSTRING1, + MODINFOSTRING2, + XORG_VERSION_CURRENT, + 2, 1, 0, + ABI_CLASS_FONT, /* Font module */ + ABI_FONT_VERSION, + MOD_CLASS_FONT, + {0,0,0,0} /* signature, to be patched into the file by a tool */ +}; + +XF86ModuleData freetypeModuleData = { &VersRec, freetypeSetup, NULL }; + +extern void FreeTypeRegisterFontFileFunctions(void); + +FontModule freetypeModule = { + FreeTypeRegisterFontFileFunctions, + "FreeType", + NULL +}; + +static pointer +freetypeSetup(pointer module, pointer opts, int *errmaj, int *errmin) +{ + freetypeModule.module = module; + LoadFont(&freetypeModule); + + /* Need a non-NULL return */ + return (pointer)1; +} diff --git a/nx-X11/lib/font/FreeType/module/ftmodule.h b/nx-X11/lib/font/FreeType/module/ftmodule.h new file mode 100644 index 000000000..443c97c29 --- /dev/null +++ b/nx-X11/lib/font/FreeType/module/ftmodule.h @@ -0,0 +1,21 @@ +/* $XFree86: xc/lib/font/FreeType/ftmodule.h,v 1.5 2003/10/24 16:33:08 tsi Exp $ */ + +FT_USE_MODULE(autohint_module_class) +FT_USE_MODULE(cff_driver_class) +/* FT_USE_MODULE(t1cid_driver_class) */ +FT_USE_MODULE(pcf_driver_class) +FT_USE_MODULE(bdf_driver_class) +FT_USE_MODULE(psaux_module_class) +FT_USE_MODULE(psnames_module_class) +FT_USE_MODULE(pshinter_module_class) +FT_USE_MODULE(ft_raster1_renderer_class) +FT_USE_MODULE(sfnt_module_class) +/* FT_USE_MODULE(ft_smooth_renderer_class) */ +/* FT_USE_MODULE(ft_smooth_lcd_renderer_class) */ +/* FT_USE_MODULE(ft_smooth_lcdv_renderer_class) */ +FT_USE_MODULE(tt_driver_class) +FT_USE_MODULE(t1_driver_class) +/* FT_USE_MODULE(t42_driver_class) */ +/* FT_USE_MODULE(pfr_driver_class) */ +/* FT_USE_MODULE(winfnt_driver_class) */ + diff --git a/nx-X11/lib/font/FreeType/module/ftoption.h b/nx-X11/lib/font/FreeType/module/ftoption.h new file mode 100644 index 000000000..a527ec12d --- /dev/null +++ b/nx-X11/lib/font/FreeType/module/ftoption.h @@ -0,0 +1,567 @@ +/***************************************************************************/ +/* */ +/* ftoption.h */ +/* */ +/* User-selectable configuration macros (specification only). */ +/* */ +/* Copyright 1996-2001, 2002, 2003, 2004 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ + + +#ifndef __FTOPTION_H__ +#define __FTOPTION_H__ + + +#include <ft2build.h> + + +FT_BEGIN_HEADER + + /*************************************************************************/ + /* */ + /* USER-SELECTABLE CONFIGURATION MACROS */ + /* */ + /* This file contains the default configuration macro definitions for */ + /* a standard build of the FreeType library. There are three ways to */ + /* use this file to build project-specific versions of the library: */ + /* */ + /* - You can modify this file by hand, but this is not recommended in */ + /* cases where you would like to build several versions of the */ + /* library from a single source directory. */ + /* */ + /* - You can put a copy of this file in your build directory, more */ + /* precisely in "$BUILD/freetype/config/ftoption.h", where "$BUILD" */ + /* is the name of a directory that is included _before_ the FreeType */ + /* include path during compilation. */ + /* */ + /* The default FreeType Makefiles and Jamfiles use the build */ + /* directory "builds/<system>" by default, but you can easily change */ + /* that for your own projects. */ + /* */ + /* - Copy the file <ft2build.h> to "$BUILD/ft2build.h" and modify it */ + /* slightly to pre-define the macro FT_CONFIG_OPTIONS_H used to */ + /* locate this file during the build. For example, */ + /* */ + /* #define FT_CONFIG_OPTIONS_H <myftoptions.h> */ + /* #include <freetype/config/ftheader.h> */ + /* */ + /* will use "$BUILD/myftoptions.h" instead of this file for macro */ + /* definitions. */ + /* */ + /* Note also that you can similarly pre-define the macro */ + /* FT_CONFIG_MODULES_H used to locate the file listing of the modules */ + /* that are statically linked to the library at compile time. By */ + /* default, this file is <freetype/config/ftmodule.h>. */ + /* */ + /* We highly recommend using the third method whenever possible. */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** G E N E R A L F R E E T Y P E 2 C O N F I G U R A T I O N ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* Many compilers provide a non-ANSI 64-bit data type that can be used */ + /* by FreeType to speed up some computations. However, this will create */ + /* some problems when compiling the library in strict ANSI mode. */ + /* */ + /* For this reason, the use of 64-bit integers is normally disabled when */ + /* the __STDC__ macro is defined. You can however disable this by */ + /* defining the macro FT_CONFIG_OPTION_FORCE_INT64 here. */ + /* */ + /* For most compilers, this will only create compilation warnings when */ + /* building the library. */ + /* */ + /* ObNote: The compiler-specific 64-bit integers are detected in the */ + /* file "ftconfig.h" either statically or through the */ + /* `configure' script on supported platforms. */ + /* */ +#undef FT_CONFIG_OPTION_FORCE_INT64 + + + /*************************************************************************/ + /* */ + /* LZW-compressed file support. */ + /* */ + /* FreeType now handles font files that have been compressed with the */ + /* 'compress' program. This is mostly used to parse many of the PCF */ + /* files that come with various X11 distributions. The implementation */ + /* uses NetBSD's `zopen' to partially uncompress the file on the fly */ + /* (see src/lzw/ftgzip.c). */ + /* */ + /* Define this macro if you want to enable this `feature'. */ + /* */ +#define FT_CONFIG_OPTION_USE_LZW + + + /*************************************************************************/ + /* */ + /* Gzip-compressed file support. */ + /* */ + /* FreeType now handles font files that have been compressed with the */ + /* 'gzip' program. This is mostly used to parse many of the PCF files */ + /* that come with XFree86. The implementation uses `zlib' to */ + /* partially uncompress the file on the fly (see src/gzip/ftgzip.c). */ + /* */ + /* Define this macro if you want to enable this `feature'. See also */ + /* the macro FT_CONFIG_OPTION_SYSTEM_ZLIB below. */ + /* */ +#define FT_CONFIG_OPTION_USE_ZLIB + + + /*************************************************************************/ + /* */ + /* ZLib library selection */ + /* */ + /* This macro is only used when FT_CONFIG_OPTION_USE_ZLIB is defined. */ + /* It allows FreeType's `ftgzip' component to link to the system's */ + /* installation of the ZLib library. This is useful on systems like */ + /* Unix or VMS where it generally is already available. */ + /* */ + /* If you let it undefined, the component will use its own copy */ + /* of the zlib sources instead. These have been modified to be */ + /* included directly within the component and *not* export external */ + /* function names. This allows you to link any program with FreeType */ + /* _and_ ZLib without linking conflicts. */ + /* */ + /* Do not #undef this macro here since the build system might define */ + /* it for certain configurations only. */ + /* */ +/* #define FT_CONFIG_OPTION_SYSTEM_ZLIB */ + + + /*************************************************************************/ + /* */ + /* DLL export compilation */ + /* */ + /* When compiling FreeType as a DLL, some systems/compilers need a */ + /* special keyword in front OR after the return type of function */ + /* declarations. */ + /* */ + /* Two macros are used within the FreeType source code to define */ + /* exported library functions: FT_EXPORT and FT_EXPORT_DEF. */ + /* */ + /* FT_EXPORT( return_type ) */ + /* */ + /* is used in a function declaration, as in */ + /* */ + /* FT_EXPORT( FT_Error ) */ + /* FT_Init_FreeType( FT_Library* alibrary ); */ + /* */ + /* */ + /* FT_EXPORT_DEF( return_type ) */ + /* */ + /* is used in a function definition, as in */ + /* */ + /* FT_EXPORT_DEF( FT_Error ) */ + /* FT_Init_FreeType( FT_Library* alibrary ) */ + /* { */ + /* ... some code ... */ + /* return FT_Err_Ok; */ + /* } */ + /* */ + /* You can provide your own implementation of FT_EXPORT and */ + /* FT_EXPORT_DEF here if you want. If you leave them undefined, they */ + /* will be later automatically defined as `extern return_type' to */ + /* allow normal compilation. */ + /* */ + /* Do not #undef these macros here since the build system might define */ + /* them for certain configurations only. */ + /* */ +/* #define FT_EXPORT(x) extern x */ +/* #define FT_EXPORT_DEF(x) x */ + + + /*************************************************************************/ + /* */ + /* Glyph Postscript Names handling */ + /* */ + /* By default, FreeType 2 is compiled with the `PSNames' module. This */ + /* module is in charge of converting a glyph name string into a */ + /* Unicode value, or return a Macintosh standard glyph name for the */ + /* use with the TrueType `post' table. */ + /* */ + /* Undefine this macro if you do not want `PSNames' compiled in your */ + /* build of FreeType. This has the following effects: */ + /* */ + /* - The TrueType driver will provide its own set of glyph names, */ + /* if you build it to support postscript names in the TrueType */ + /* `post' table. */ + /* */ + /* - The Type 1 driver will not be able to synthetize a Unicode */ + /* charmap out of the glyphs found in the fonts. */ + /* */ + /* You would normally undefine this configuration macro when building */ + /* a version of FreeType that doesn't contain a Type 1 or CFF driver. */ + /* */ +#define FT_CONFIG_OPTION_POSTSCRIPT_NAMES + + + /*************************************************************************/ + /* */ + /* Postscript Names to Unicode Values support */ + /* */ + /* By default, FreeType 2 is built with the `PSNames' module compiled */ + /* in. Among other things, the module is used to convert a glyph name */ + /* into a Unicode value. This is especially useful in order to */ + /* synthetize on the fly a Unicode charmap from the CFF/Type 1 driver */ + /* through a big table named the `Adobe Glyph List' (AGL). */ + /* */ + /* Undefine this macro if you do not want the Adobe Glyph List */ + /* compiled in your `PSNames' module. The Type 1 driver will not be */ + /* able to synthetize a Unicode charmap out of the glyphs found in the */ + /* fonts. */ + /* */ +#define FT_CONFIG_OPTION_ADOBE_GLYPH_LIST + + + /*************************************************************************/ + /* */ + /* Support for Mac fonts */ + /* */ + /* Define this macro if you want support for outline fonts in Mac */ + /* format (mac dfont, mac resource, macbinary containing a mac */ + /* resource) on non-Mac platforms. */ + /* */ + /* Note that the `FOND' resource isn't checked. */ + /* */ +#define FT_CONFIG_OPTION_MAC_FONTS + + + /*************************************************************************/ + /* */ + /* Guessing methods to access embedded resource forks */ + /* */ + /* Enable extra Mac fonts support on non-Mac platforms (e.g. */ + /* GNU/Linux). */ + /* */ + /* Resource forks which include fonts data are stored sometimes in */ + /* locations which users or developers don't expected. In some cases, */ + /* resource forks start with some offset from the head of a file. In */ + /* other cases, the actual resource fork is stored in file different */ + /* from what the user specifies. If this option is activated, */ + /* FreeType tries to guess whether such offsets or different file */ + /* names must be used. */ + /* */ + /* Note that normal, direct access of resource forks is controlled via */ + /* the FT_CONFIG_OPTION_MAC_FONTS option. */ + /* */ +#ifdef FT_CONFIG_OPTION_MAC_FONTS +#define FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK +#endif + + + /*************************************************************************/ + /* */ + /* Allow the use of FT_Incremental_Interface to load typefaces that */ + /* contain no glyph data, but supply it via a callback function. */ + /* This allows FreeType to be used with the PostScript language, using */ + /* the GhostScript interpreter. */ + /* */ +/* #define FT_CONFIG_OPTION_INCREMENTAL */ + + + /*************************************************************************/ + /* */ + /* The size in bytes of the render pool used by the scan-line converter */ + /* to do all of its work. */ + /* */ + /* This must be greater than 4KByte. */ + /* */ +#define FT_RENDER_POOL_SIZE 16384L + + + /*************************************************************************/ + /* */ + /* FT_MAX_MODULES */ + /* */ + /* The maximum number of modules that can be registered in a single */ + /* FreeType library object. 32 is the default. */ + /* */ +#define FT_MAX_MODULES 32 + + + /*************************************************************************/ + /* */ + /* Debug level */ + /* */ + /* FreeType can be compiled in debug or trace mode. In debug mode, */ + /* errors are reported through the `ftdebug' component. In trace */ + /* mode, additional messages are sent to the standard output during */ + /* execution. */ + /* */ + /* Define FT_DEBUG_LEVEL_ERROR to build the library in debug mode. */ + /* Define FT_DEBUG_LEVEL_TRACE to build it in trace mode. */ + /* */ + /* Don't define any of these macros to compile in `release' mode! */ + /* */ + /* Do not #undef these macros here since the build system might define */ + /* them for certain configurations only. */ + /* */ +/* #define FT_DEBUG_LEVEL_ERROR */ +/* #define FT_DEBUG_LEVEL_TRACE */ + + + /*************************************************************************/ + /* */ + /* Memory Debugging */ + /* */ + /* FreeType now comes with an integrated memory debugger that is */ + /* capable of detecting simple errors like memory leaks or double */ + /* deletes. To compile it within your build of the library, you */ + /* should define FT_DEBUG_MEMORY here. */ + /* */ + /* Note that the memory debugger is only activated at runtime when */ + /* when the _environment_ variable "FT2_DEBUG_MEMORY" is defined also! */ + /* */ + /* Do not #undef this macro here since the build system might define */ + /* it for certain configurations only. */ + /* */ +/* #define FT_DEBUG_MEMORY */ + + + /*************************************************************************/ + /* */ + /* Module errors */ + /* */ + /* If this macro is set (which is _not_ the default), the higher byte */ + /* of an error code gives the module in which the error has occurred, */ + /* while the lower byte is the real error code. */ + /* */ + /* Setting this macro makes sense for debugging purposes only, since */ + /* it would break source compatibility of certain programs that use */ + /* FreeType 2. */ + /* */ + /* More details can be found in the files ftmoderr.h and fterrors.h. */ + /* */ +#undef FT_CONFIG_OPTION_USE_MODULE_ERRORS + + + + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** S F N T D R I V E R C O N F I G U R A T I O N ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* Define TT_CONFIG_OPTION_EMBEDDED_BITMAPS if you want to support */ + /* embedded bitmaps in all formats using the SFNT module (namely */ + /* TrueType & OpenType). */ + /* */ +#define TT_CONFIG_OPTION_EMBEDDED_BITMAPS + + + /*************************************************************************/ + /* */ + /* Define TT_CONFIG_OPTION_POSTSCRIPT_NAMES if you want to be able to */ + /* load and enumerate the glyph Postscript names in a TrueType or */ + /* OpenType file. */ + /* */ + /* Note that when you do not compile the `PSNames' module by undefining */ + /* the above FT_CONFIG_OPTION_POSTSCRIPT_NAMES, the `sfnt' module will */ + /* contain additional code used to read the PS Names table from a font. */ + /* */ + /* (By default, the module uses `PSNames' to extract glyph names.) */ + /* */ +#define TT_CONFIG_OPTION_POSTSCRIPT_NAMES + + + /*************************************************************************/ + /* */ + /* Define TT_CONFIG_OPTION_SFNT_NAMES if your applications need to */ + /* access the internal name table in a SFNT-based format like TrueType */ + /* or OpenType. The name table contains various strings used to */ + /* describe the font, like family name, copyright, version, etc. It */ + /* does not contain any glyph name though. */ + /* */ + /* Accessing SFNT names is done through the functions declared in */ + /* `freetype/ftnames.h'. */ + /* */ +#define TT_CONFIG_OPTION_SFNT_NAMES + + + /*************************************************************************/ + /* */ + /* TrueType CMap support */ + /* */ + /* Here you can fine-tune which TrueType CMap table format shall be */ + /* supported. */ +#define TT_CONFIG_CMAP_FORMAT_0 +#define TT_CONFIG_CMAP_FORMAT_2 +#define TT_CONFIG_CMAP_FORMAT_4 +#define TT_CONFIG_CMAP_FORMAT_6 +#define TT_CONFIG_CMAP_FORMAT_8 +#define TT_CONFIG_CMAP_FORMAT_10 +#define TT_CONFIG_CMAP_FORMAT_12 + + + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** T R U E T Y P E D R I V E R C O N F I G U R A T I O N ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + + /*************************************************************************/ + /* */ + /* Define TT_CONFIG_OPTION_BYTECODE_INTERPRETER if you want to compile */ + /* a bytecode interpreter in the TrueType driver. Note that there are */ + /* important patent issues related to the use of the interpreter. */ + /* */ + /* By undefining this, you will only compile the code necessary to load */ + /* TrueType glyphs without hinting. */ + /* */ + /* Do not #undef this macro here, since the build system might */ + /* define it for certain configurations only. */ + /* */ +/* #define TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ + + + /*************************************************************************/ + /* */ + /* Define TT_CONFIG_OPTION_UNPATENTED_HINTING (in addition to */ + /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER) to compile the unpatented */ + /* work-around hinting system. Note that for the moment, the algorithm */ + /* is only used when selected at runtime through the parameter tag */ + /* FT_PARAM_TAG_UNPATENTED_HINTING; or when the debug hook */ + /* FT_DEBUG_HOOK_UNPATENTED_HINTING is globally actived */ + /* */ +#define TT_CONFIG_OPTION_UNPATENTED_HINTING + + + /*************************************************************************/ + /* */ + /* Define TT_CONFIG_OPTION_INTERPRETER_SWITCH to compile the TrueType */ + /* bytecode interpreter with a huge switch statement, rather than a call */ + /* table. This results in smaller and faster code for a number of */ + /* architectures. */ + /* */ + /* Note however that on some compiler/processor combinations, undefining */ + /* this macro will generate faster, though larger, code. */ + /* */ +#define TT_CONFIG_OPTION_INTERPRETER_SWITCH + + + /*************************************************************************/ + /* */ + /* Define TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED to compile the */ + /* TrueType glyph loader to use Apple's definition of how to handle */ + /* component offsets in composite glyphs. */ + /* */ + /* Apple and MS disagree on the default behavior of component offsets */ + /* in composites. Apple says that they should be scaled by the scale */ + /* factors in the transformation matrix (roughly, it's more complex) */ + /* while MS says they should not. OpenType defines two bits in the */ + /* composite flags array which can be used to disambiguate, but old */ + /* fonts will not have them. */ + /* */ + /* http://partners.adobe.com/asn/developer/opentype/glyf.html */ + /* http://fonts.apple.com/TTRefMan/RM06/Chap6glyf.html */ + /* */ +#undef TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED + + + /*************************************************************************/ + /*************************************************************************/ + /**** ****/ + /**** T Y P E 1 D R I V E R C O N F I G U R A T I O N ****/ + /**** ****/ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* T1_MAX_DICT_DEPTH is the maximal depth of nest dictionaries and */ + /* arrays in the Type 1 stream (see t1load.c). A minimum of 4 is */ + /* required. */ + /* */ +#define T1_MAX_DICT_DEPTH 5 + + + /*************************************************************************/ + /* */ + /* T1_MAX_SUBRS_CALLS details the maximum number of nested sub-routine */ + /* calls during glyph loading. */ + /* */ +#define T1_MAX_SUBRS_CALLS 16 + + + /*************************************************************************/ + /* */ + /* T1_MAX_CHARSTRING_OPERANDS is the charstring stack's capacity. A */ + /* minimum of 16 is required. */ + /* */ + /* The Chinese font MingTiEG-Medium (CNS 11643 character set) needs 256. */ + /* */ +#define T1_MAX_CHARSTRINGS_OPERANDS 256 + + + /*************************************************************************/ + /* */ + /* Define this configuration macro if you want to prevent the */ + /* compilation of `t1afm', which is in charge of reading Type 1 AFM */ + /* files into an existing face. Note that if set, the T1 driver will be */ + /* unable to produce kerning distances. */ + /* */ +#undef T1_CONFIG_OPTION_NO_AFM + + + /*************************************************************************/ + /* */ + /* Define this configuration macro if you want to prevent the */ + /* compilation of the Multiple Masters font support in the Type 1 */ + /* driver. */ + /* */ +#undef T1_CONFIG_OPTION_NO_MM_SUPPORT + + /* */ + +/* + * The FT_CONFIG_OPTION_CHESTER_XXXX macros are used to toggle some recent + * improvements to the auto-hinter contributed by David Chester. They will + * most likely disappear completely in the next release. For now, you + * should always keep them defined. + * + */ +#define FT_CONFIG_OPTION_CHESTER_HINTS + +#ifdef FT_CONFIG_OPTION_CHESTER_HINTS + +#define FT_CONFIG_CHESTER_SMALL_F +#define FT_CONFIG_CHESTER_ASCENDER +#define FT_CONFIG_CHESTER_SERIF +#define FT_CONFIG_CHESTER_STEM +#define FT_CONFIG_CHESTER_BLUE_SCALE + +#endif /* FT_CONFIG_OPTION_CHESTER_HINTS */ + +FT_END_HEADER + + +#endif /* __FTOPTION_H__ */ + + +/* END */ diff --git a/nx-X11/lib/font/FreeType/module/ftstdlib.h b/nx-X11/lib/font/FreeType/module/ftstdlib.h new file mode 100644 index 000000000..3d5b7fc76 --- /dev/null +++ b/nx-X11/lib/font/FreeType/module/ftstdlib.h @@ -0,0 +1,113 @@ +/* ftstdlib.h -- modified for XFree86. */ +/* $XFree86: xc/lib/font/FreeType/ftstdlib.h,v 1.5 2003/02/22 06:00:36 dawes Exp $ */ + +#ifndef __FTSTDLIB_H__ +#define __FTSTDLIB_H__ + +#ifndef FONTMODULE + +#include <limits.h> + +#define FT_UINT_MAX UINT_MAX +#define FT_ULONG_MAX ULONG_MAX + +#include <ctype.h> + +#define ft_isalnum isalnum +#define ft_isupper isupper +#define ft_islower islower +#define ft_isdigit isdigit +#define ft_isxdigit isxdigit + + +#include <string.h> + +#define ft_strlen strlen +#define ft_strcat strcat +#define ft_strcmp strcmp +#define ft_strncmp strncmp +#define ft_memcpy memcpy +#define ft_strcpy strcpy +#define ft_strncpy strncpy +#define ft_memset memset +#define ft_memmove memmove +#define ft_memcmp memcmp + +#include <stdio.h> + +#define ft_sprintf sprintf + +#include <stdlib.h> + +#define ft_qsort qsort +#define ft_exit exit + +#define ft_atoi atoi + +#include <setjmp.h> + +#define ft_jmp_buf jmp_buf /* note: this cannot be a typedef since */ + /* jmp_buf is defined as a macro */ + /* on certain platforms */ + +#define ft_setjmp setjmp /* same thing here */ +#define ft_longjmp longjmp /* " */ + + +#else + +#include "Xmd.h" +#define _XTYPEDEF_BOOL +#include "Xdefs.h" +#define DONT_DEFINE_WRAPPERS +#define DEFINE_SETJMP_WRAPPERS +#include "xf86_ansic.h" +#undef DONT_DEFINE_WRAPPERS + +#ifndef offsetof +#define offsetof(TYPE, MEMBER) ((xf86size_t)&((TYPE*)0)->MEMBER) +#endif + +#define FT_UINT_MAX 4294967295U +#ifdef LONG64 +#define FT_ULONG_MAX 18446744073709551615UL +#else +#define FT_ULONG_MAX 4294967295UL +#endif + +#define ft_isalnum xf86isalnum +#define ft_isupper xf86isupper +#define ft_islower xf86islower +#define ft_xdigit xf86isxdigit + +#define ft_strlen xf86strlen +#define ft_strcmp xf86strcmp +#define ft_strncmp xf86strncmp +#define ft_memcpy xf86memcpy +#define ft_strcpy xf86strcpy +#define ft_strncpy xf86strncpy +#define ft_memset xf86memset +#define ft_memmove xf86memmove +#define ft_memcmp xf86memcmp + +#define ft_sprintf xf86sprintf + +#define ft_qsort xf86qsort +#define ft_exit xf86exit + +#define ft_atoi xf86atoi + +#define ft_jmp_buf jmp_buf +#define ft_setjmp setjmp +#define ft_longjmp longjmp + +#endif /* FONTMODULE */ + + +#include <stdarg.h> + + +#endif /* __FTSTDLIB_H__ */ + + +/* END */ diff --git a/nx-X11/lib/font/FreeType/module/fttypes.h b/nx-X11/lib/font/FreeType/module/fttypes.h new file mode 100644 index 000000000..82bb273e4 --- /dev/null +++ b/nx-X11/lib/font/FreeType/module/fttypes.h @@ -0,0 +1,571 @@ +/***************************************************************************/ +/* */ +/* fttypes.h */ +/* */ +/* FreeType simple types definitions (specification only). */ +/* */ +/* Copyright 1996-2001 by */ +/* David Turner, Robert Wilhelm, and Werner Lemberg. */ +/* */ +/* Modified for XFree86. */ +/* */ +/* This file is part of the FreeType project, and may only be used, */ +/* modified, and distributed under the terms of the FreeType project */ +/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ +/* this file you indicate that you have read the license and */ +/* understand and accept it fully. */ +/* */ +/***************************************************************************/ +/* $XFree86: xc/lib/font/FreeType/fttypes.h,v 1.4 2003/05/29 03:05:08 dawes Exp $ */ + +#ifndef __FTTYPES_H__ +#define __FTTYPES_H__ + + +#include <ft2build.h> +#include FT_CONFIG_CONFIG_H +#include FT_SYSTEM_H +#include FT_IMAGE_H + +#ifndef FONTMODULE +#include <stddef.h> +#else +#include "Xmd.h" +#define _XTYPEDEF_BOOL +#include "Xdefs.h" +#include "xf86_ansic.h" +#ifndef size_t +#define DONT_DEFINE_WRAPPERS +#define size_t xf86size_t +#undef DONT_DEFINE_WRAPPERS +#endif +#endif + +FT_BEGIN_HEADER + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* basic_types */ + /* */ + /* <Title> */ + /* Basic Data Types */ + /* */ + /* <Abstract> */ + /* The basic data types defined by the library. */ + /* */ + /* <Description> */ + /* This section contains the basic data types defined by FreeType 2, */ + /* ranging from simple scalar types to bitmap descriptors. More */ + /* font-specific structures are defined in a different section. */ + /* */ + /* <Order> */ + /* FT_Byte */ + /* FT_Char */ + /* FT_Int */ + /* FT_UInt */ + /* FT_Short */ + /* FT_UShort */ + /* FT_Long */ + /* FT_ULong */ + /* FT_Bool */ + /* FT_Offset */ + /* FT_PtrDist */ + /* FT_String */ + /* FT_Error */ + /* FT_Fixed */ + /* FT_Pointer */ + /* FT_Pos */ + /* FT_Vector */ + /* FT_BBox */ + /* FT_Matrix */ + /* FT_FWord */ + /* FT_UFWord */ + /* FT_F2Dot14 */ + /* FT_UnitVector */ + /* FT_F26Dot6 */ + /* */ + /* */ + /* FT_Generic */ + /* FT_Generic_Finalizer */ + /* */ + /* FT_Bitmap */ + /* FT_Pixel_Mode */ + /* FT_Palette_Mode */ + /* FT_Glyph_Format */ + /* FT_IMAGE_TAG */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Bool */ + /* */ + /* <Description> */ + /* A typedef of unsigned char, used for simple booleans. */ + /* */ + typedef unsigned char FT_Bool; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_FWord */ + /* */ + /* <Description> */ + /* A signed 16-bit integer used to store a distance in original font */ + /* units. */ + /* */ + typedef signed short FT_FWord; /* distance in FUnits */ + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_UFWord */ + /* */ + /* <Description> */ + /* An unsigned 16-bit integer used to store a distance in original */ + /* font units. */ + /* */ + typedef unsigned short FT_UFWord; /* unsigned distance */ + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Char */ + /* */ + /* <Description> */ + /* A simple typedef for the _signed_ char type. */ + /* */ + typedef signed char FT_Char; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Byte */ + /* */ + /* <Description> */ + /* A simple typedef for the _unsigned_ char type. */ + /* */ + typedef unsigned char FT_Byte; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_String */ + /* */ + /* <Description> */ + /* A simple typedef for the char type, usually used for strings. */ + /* */ + typedef char FT_String; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Short */ + /* */ + /* <Description> */ + /* A typedef for signed short. */ + /* */ + typedef signed short FT_Short; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_UShort */ + /* */ + /* <Description> */ + /* A typedef for unsigned short. */ + /* */ + typedef unsigned short FT_UShort; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Int */ + /* */ + /* <Description> */ + /* A typedef for the int type. */ + /* */ + typedef int FT_Int; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_UInt */ + /* */ + /* <Description> */ + /* A typedef for the unsigned int type. */ + /* */ + typedef unsigned int FT_UInt; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Long */ + /* */ + /* <Description> */ + /* A typedef for signed long. */ + /* */ + typedef signed long FT_Long; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_ULong */ + /* */ + /* <Description> */ + /* A typedef for unsigned long. */ + /* */ + typedef unsigned long FT_ULong; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_F2Dot14 */ + /* */ + /* <Description> */ + /* A signed 2.14 fixed float type used for unit vectors. */ + /* */ + typedef signed short FT_F2Dot14; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_F26Dot6 */ + /* */ + /* <Description> */ + /* A signed 26.6 fixed float type used for vectorial pixel */ + /* coordinates. */ + /* */ + typedef signed long FT_F26Dot6; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Fixed */ + /* */ + /* <Description> */ + /* This type is used to store 16.16 fixed float values, like scales */ + /* or matrix coefficients. */ + /* */ + typedef signed long FT_Fixed; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Error */ + /* */ + /* <Description> */ + /* The FreeType error code type. A value of 0 is always interpreted */ + /* as a successful operation. */ + /* */ + typedef int FT_Error; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Pointer */ + /* */ + /* <Description> */ + /* A simple typedef for a typeless pointer. */ + /* */ + typedef void* FT_Pointer; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_Offset */ + /* */ + /* <Description> */ + /* This is equivalent to the ANSI C `size_t' type, i.e. the largest */ + /* _unsigned_ integer type used to express a file size or position, */ + /* or a memory block size. */ + /* */ + typedef size_t FT_Offset; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_PtrDist */ + /* */ + /* <Description> */ + /* This is equivalent to the ANSI C `ptrdiff_t' type, i.e. the */ + /* largest _signed_ integer type used to express the distance */ + /* between two pointers. */ + /* */ + typedef size_t FT_PtrDist; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_UnitVector */ + /* */ + /* <Description> */ + /* A simple structure used to store a 2D vector unit vector. Uses */ + /* FT_F2Dot14 types. */ + /* */ + /* <Fields> */ + /* x :: Horizontal coordinate. */ + /* */ + /* y :: Vertical coordinate. */ + /* */ + typedef struct FT_UnitVector_ + { + FT_F2Dot14 x; + FT_F2Dot14 y; + + } FT_UnitVector; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Matrix */ + /* */ + /* <Description> */ + /* A simple structure used to store a 2x2 matrix. Coefficients are */ + /* in 16.16 fixed float format. The computation performed is: */ + /* */ + /* { */ + /* x' = x*xx + y*xy */ + /* y' = x*yx + y*yy */ + /* } */ + /* */ + /* <Fields> */ + /* xx :: Matrix coefficient. */ + /* */ + /* xy :: Matrix coefficient. */ + /* */ + /* yx :: Matrix coefficient. */ + /* */ + /* yy :: Matrix coefficient. */ + /* */ + typedef struct FT_Matrix_ + { + FT_Fixed xx, xy; + FT_Fixed yx, yy; + + } FT_Matrix; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Data */ + /* */ + /* <Description> */ + /* Read-only binary data represented as a pointer and a length. */ + /* */ + /* <Fields> */ + /* pointer :: The data. */ + /* */ + /* length :: The length of the data in bytes. */ + /* */ + typedef struct FT_Data_ + { + const FT_Byte* pointer; + FT_Int length; + + } FT_Data; + + + /*************************************************************************/ + /* */ + /* <FuncType> */ + /* FT_Generic_Finalizer */ + /* */ + /* <Description> */ + /* Describes a function used to destroy the `client' data of any */ + /* FreeType object. See the description of the FT_Generic type for */ + /* details of usage. */ + /* */ + /* <Input> */ + /* The address of the FreeType object which is under finalization. */ + /* Its client data is accessed through its `generic' field. */ + /* */ + typedef void (*FT_Generic_Finalizer)(void* object); + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_Generic */ + /* */ + /* <Description> */ + /* Client applications often need to associate their own data to a */ + /* variety of FreeType core objects. For example, a text layout API */ + /* might want to associate a glyph cache to a given size object. */ + /* */ + /* Most FreeType object contains a `generic' field, of type */ + /* FT_Generic, which usage is left to client applications and font */ + /* servers. */ + /* */ + /* It can be used to store a pointer to client-specific data, as well */ + /* as the address of a `finalizer' function, which will be called by */ + /* FreeType when the object is destroyed (for example, the previous */ + /* client example would put the address of the glyph cache destructor */ + /* in the `finalizer' field). */ + /* */ + /* <Fields> */ + /* data :: A typeless pointer to any client-specified data. This */ + /* field is completely ignored by the FreeType library. */ + /* */ + /* finalizer :: A pointer to a `generic finalizer' function, which */ + /* will be called when the object is destroyed. If this */ + /* field is set to NULL, no code will be called. */ + /* */ + typedef struct FT_Generic_ + { + void* data; + FT_Generic_Finalizer finalizer; + + } FT_Generic; + + + /*************************************************************************/ + /* */ + /* <Macro> */ + /* FT_MAKE_TAG */ + /* */ + /* <Description> */ + /* This macro converts four letter tags which are used to label */ + /* TrueType tables into an unsigned long to be used within FreeType. */ + /* */ + /* <Note> */ + /* The produced values *must* be 32bit integers. Don't redefine this */ + /* macro. */ + /* */ +#define FT_MAKE_TAG( _x1, _x2, _x3, _x4 ) \ + ( ( (FT_ULong)_x1 << 24 ) | \ + ( (FT_ULong)_x2 << 16 ) | \ + ( (FT_ULong)_x3 << 8 ) | \ + (FT_ULong)_x4 ) + + + /*************************************************************************/ + /*************************************************************************/ + /* */ + /* L I S T M A N A G E M E N T */ + /* */ + /*************************************************************************/ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Section> */ + /* list_processing */ + /* */ + /*************************************************************************/ + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_ListNode */ + /* */ + /* <Description> */ + /* Many elements and objects in FreeType are listed through a */ + /* FT_List record (see FT_ListRec). As its name suggests, a */ + /* FT_ListNode is a handle to a single list element. */ + /* */ + typedef struct FT_ListNodeRec_* FT_ListNode; + + + /*************************************************************************/ + /* */ + /* <Type> */ + /* FT_List */ + /* */ + /* <Description> */ + /* A handle to a list record (see FT_ListRec). */ + /* */ + typedef struct FT_ListRec_* FT_List; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_ListNodeRec */ + /* */ + /* <Description> */ + /* A structure used to hold a single list element. */ + /* */ + /* <Fields> */ + /* prev :: The previous element in the list. NULL if first. */ + /* */ + /* next :: The next element in the list. NULL if last. */ + /* */ + /* data :: A typeless pointer to the listed object. */ + /* */ + typedef struct FT_ListNodeRec_ + { + FT_ListNode prev; + FT_ListNode next; + void* data; + + } FT_ListNodeRec; + + + /*************************************************************************/ + /* */ + /* <Struct> */ + /* FT_ListRec */ + /* */ + /* <Description> */ + /* A structure used to hold a simple doubly-linked list. These are */ + /* used in many parts of FreeType. */ + /* */ + /* <Fields> */ + /* head :: The head (first element) of doubly-linked list. */ + /* */ + /* tail :: The tail (last element) of doubly-linked list. */ + /* */ + typedef struct FT_ListRec_ + { + FT_ListNode head; + FT_ListNode tail; + + } FT_ListRec; + + + /* */ + +#define FT_IS_EMPTY( list ) ( (list).head == 0 ) + + /* return base error code (without module-specific prefix) */ +#define FT_ERROR_BASE( x ) ( (x) & 0xFF ) + + /* return module error code */ +#define FT_ERROR_MODULE( x ) ( (x) & 0xFF00U ) + +#define FT_BOOL( x ) ( (FT_Bool)( x ) ) + +FT_END_HEADER + +#endif /* __FTTYPES_H__ */ + + +/* END */ diff --git a/nx-X11/lib/font/FreeType/module/myftstdlib.h b/nx-X11/lib/font/FreeType/module/myftstdlib.h new file mode 100644 index 000000000..dc9f8658f --- /dev/null +++ b/nx-X11/lib/font/FreeType/module/myftstdlib.h @@ -0,0 +1,82 @@ +/* ftstdlib.h -- modified for XFree86. */ +/* $XFree86: xc/lib/font/FreeType/ftstdlib.h,v 1.5 2003/02/22 06:00:36 dawes Exp $ */ +#ifndef __MYFTSTDLIB_H__ +#define __MYFTSTDLIB_H__ + + +#ifndef FONTMODULE + +# include <ftstdlib.h> +# ifndef ft_isdigit +# define ft_isdigit isdigit +# endif + +#else + +#ifndef __FTSTDLIB_H__ +#define __FTSTDLIB_H__ +/* we don't include limits.h */ +#define CHAR_BIT 8 + +#include "Xmd.h" +#define _XTYPEDEF_BOOL +#include "Xdefs.h" +#define DONT_DEFINE_WRAPPERS +#define DEFINE_SETJMP_WRAPPERS +#include "xf86_ansic.h" +#undef DONT_DEFINE_WRAPPERS + +#ifndef offsetof +#define offsetof(TYPE, MEMBER) ((xf86size_t)&((TYPE*)0)->MEMBER) +#endif + +#define FT_UINT_MAX 4294967295U +#ifdef LONG64 +#define FT_ULONG_MAX 18446744073709551615UL +#else +#define FT_ULONG_MAX 4294967295UL +#endif + +#define ft_isalnum xf86isalnum +#define ft_isupper xf86isupper +#define ft_islower xf86islower +#define ft_isxdigit xf86isxdigit +/* works around a bug in freetype 2.1.8 */ +#ifndef isdigit +#define isdigit xf86isdigit +#endif +#define ft_isdigit xf86isdigit + +#define ft_strlen xf86strlen +#define ft_strcat xf86strcat +#define ft_strrchr xf86strrchr +#define ft_strcmp xf86strcmp +#define ft_strncmp xf86strncmp +#define ft_memcpy xf86memcpy +#define ft_strcpy xf86strcpy +#define ft_strncpy xf86strncpy +#define ft_memset xf86memset +#define ft_memmove xf86memmove +#define ft_memcmp xf86memcmp + +#define ft_sprintf xf86sprintf + +#define ft_qsort xf86qsort +#define ft_exit xf86exit + +#define ft_atoi xf86atoi + +#define ft_jmp_buf jmp_buf +#define ft_setjmp setjmp +#define ft_longjmp longjmp + +#endif /* __FTSTDLIB_H__ */ +#endif /* FONTMODULE */ + + +#include <stdarg.h> + +#endif /* __MYFTSTDLIB_H__ */ + + +/* END */ diff --git a/nx-X11/lib/font/FreeType/xttcap.c b/nx-X11/lib/font/FreeType/xttcap.c new file mode 100644 index 000000000..2040c1612 --- /dev/null +++ b/nx-X11/lib/font/FreeType/xttcap.c @@ -0,0 +1,809 @@ +/* ===EmacsMode: -*- Mode: C; tab-width:4; c-basic-offset: 4; -*- === */ +/* ===FileName: === + Copyright (c) 1998 Takuya SHIOZAKI, All Rights reserved. + Copyright (c) 1998 X-TrueType Server Project, All rights reserved. + Copyright (c) 2003 After X-TT Project, All rights reserved. + +===Notice + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + + Major Release ID: X-TrueType Server Version 1.4 [Charles's Wain Release 0] + +Notice=== + */ +/* $XFree86: xc/lib/font/FreeType/xttcap.c,v 1.1 2003/10/19 18:53:50 dawes Exp $ */ + +/* +#include "xttversion.h" + +static char const * const releaseID = + _XTT_RELEASE_NAME; +*/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <X11/fonts/fontmisc.h> +#ifndef FONTMODULE +#include <string.h> +#include <ctype.h> +#include <math.h> +#else +#include "Xmd.h" +#include "Xdefs.h" +#include "xf86_ansic.h" +#endif +/* +#include <X11/X.h> +#include <X11/Xmd.h> +#include <X11/Xfuncproto.h> +#include "xf86Module.h" +#include "xf86_ansic.h" +*/ + +#ifndef True +#define True (-1) +#endif /* True */ +#ifndef False +#define False (0) +#endif /* False */ + +#include "xttcap.h" + +#if 0 +/* + Prototypes for obsoleted OS (e.g. SunOS4) + */ + +#if (defined(sun) && !(defined(SVR4) || defined(__SVR4))) +double strtod(char *str, char **ptr); +double strtol(char *str, char **ptr, int base); +#endif +#endif + + +/************************************************************************** + Private Data Types + */ + +/* Property Record List */ +/* List Node */ +typedef struct TagSPropRecValListNodeP +{ + SPropRecValContainerEntityP containerE; + struct TagSPropRecValListNodeP *nextNode; +} SPropRecValListNodeP; + + +/************************************************************************** + Tables + */ + +/* valid record field */ +static SPropertyRecord const validRecords[] = +{ + { "FontFile", eRecTypeString }, + { "FaceNumber", eRecTypeString }, + { "AutoItalic", eRecTypeDouble }, + { "DoubleStrike", eRecTypeString }, + { "FontProperties", eRecTypeBool }, + { "ForceSpacing", eRecTypeString }, + { "ScaleBBoxWidth", eRecTypeString }, + { "ScaleWidth", eRecTypeDouble }, + { "EncodingOptions", eRecTypeString }, + { "Hinting", eRecTypeBool }, + { "VeryLazyMetrics", eRecTypeBool }, + { "CodeRange", eRecTypeString }, + { "EmbeddedBitmap", eRecTypeString }, + { "VeryLazyBitmapWidthScale", eRecTypeDouble }, + { "ForceConstantSpacingCodeRange", eRecTypeString }, + { "ForceConstantSpacingMetrics", eRecTypeString }, + { "Dummy", eRecTypeVoid } +}; +static int const +numOfValidRecords = sizeof(validRecords)/sizeof(validRecords[0]); + +/* correspondence between record name and cap variable name */ +static struct { + char const * capVariable; + char const * recordName; +} const correspondRelations[] = { + { "fn", "FaceNumber" }, + { "ai", "AutoItalic" }, + { "ds", "DoubleStrike" }, + { "fp", "FontProperties" }, + { "fs", "ForceSpacing" }, + { "bw", "ScaleBBoxWidth" }, + { "sw", "ScaleWidth" }, + { "eo", "EncodingOptions" }, + { "vl", "VeryLazyMetrics" }, + { "bs", "VeryLazyBitmapWidthScale" }, + { "cr", "CodeRange" }, + { "eb", "EmbeddedBitmap" }, + { "hi", "Hinting" }, + { "fc", "ForceConstantSpacingCodeRange" }, + { "fm", "ForceConstantSpacingMetrics" } +}; +static int const +numOfCorrespondRelations += sizeof(correspondRelations)/sizeof(correspondRelations[0]); + +/************************************************************************** + Functions + */ + +#ifdef USE_TTP_FILE + +#ifndef LEN_LINEBUF +#define LEN_LINEBUF 2048 +#endif /* !def LEN_LINEBUF */ + +/* get one line */ +static Bool /* True == Error, False == Success */ +get_one_line(FILE *is, char *buf) +{ + Bool result = False; + int count = 0; + Bool flHead = True; + Bool flSpace = False; + Bool flInSingleQuote = False; + Bool flInDoubleQuote = False; + Bool flBackSlash = False; + Bool flFirstElement = True; + + *buf = '\0'; + for (;;) { + int c = fgetc(is); + + if (ferror(is)) { + fprintf(stderr, "truetype font property file : read error.\n"); + result = True; + break; + } + + if (EOF == c) { + if (flInSingleQuote || flInDoubleQuote) { + fprintf(stderr, + "truetype font property file : unmatched quote.\n"); + result = True; + } + break; + } + if (flInSingleQuote) { + if ('\'' == c) { + /* end of single quoted string */ + flInSingleQuote = False; + c = -1; /* NOT extract to buffer. */ + } else + /* others, extract all character to buffer unconditionally. */ + ; + goto trans; + } + if (flBackSlash) { + /* escape --- when just before character is backslash, + next character is escaped. */ + flBackSlash = False; + if ('n' == c) + /* newline */ + c = '\n'; + if ('\n' == c) + /* ignore newline */ + c = -1; + else + /* others, extract all character to buffer unconditionally. */ + ; + goto trans; + } + if ('\\' == c) { + /* set flag to escape next character. */ + flBackSlash = True; + c = -1; /* NOT extract to buffer. */ + goto trans; + } + if (flInDoubleQuote) { + if ('"' == c) { + /* end of double quoted string */ + flInDoubleQuote = False; + c = -1; /* NOT extract to buffer. */ + } else + /* others, extract all character to buffer unconditionally. */ + ; + goto trans; + } + if ('#' == c) { + /* skip comment till end of line. */ + while ('\n' != c) { + c = fgetc(is); + if (ferror(is)) { + fprintf(stderr, + "truetype font property file : read error.\n"); + result = True; + break; + } + if (EOF == c) { + break; + } + } + break; + } + if ('\'' == c) { + /* into single quoted string */ + flInSingleQuote = True; + c = -1; /* NOT extract to buffer. */ + goto trans; + } + if ('"' == c) { + /* into double quoted string */ + flInDoubleQuote = True; + c = -1; /* NOT extract to buffer. */ + goto trans; + } + if ('\n' == c) + /* End of Line */ + break; + if (isspace(c)) { + /* convine multiple spaces */ + if (!flHead) + /* except space at the head of line */ + flSpace = True; + continue; + } + trans: + /* set flHead to False, since current character is not white space + when reaches here. */ + flHead = False; + do { + if (count>=LEN_LINEBUF-1) { + /* overflow */ + fprintf(stderr, + "truetype font property file : too long line.\n"); + result = True; + goto quit; + } + if (flSpace) { + /* just before characters is white space, but + current character is not WS. */ + if (flFirstElement) { + /* this spaces is the first cell(?) of white spaces. */ + flFirstElement = False; + /* separate record name and record value */ + *buf = (char)0xff; + } else + *buf = ' '; + flSpace = False; + } else + if (-1 != c) { + *buf = c; + c = -1; /* invalidate */ + } else + /* skip */ + buf--; + buf++; + } while (-1 != c); /* when 'c' is not -1, it means + that 'c' contains an untreated character. */ + } + *buf = '\0'; + + quit: + return result; +} + +/* parse one line */ +static Bool /* True == Error, False == Success */ +parse_one_line(SDynPropRecValList *pThisList, FILE *is) +{ + Bool result = False; + char *buf = NULL; + char *recordHead, *valueHead = NULL; + + if (NULL == (buf = xalloc(LEN_LINEBUF))) { + fprintf(stderr, + "truetype font property file : cannot allocate memory.\n"); + result = True; + goto abort; + } + { + recordHead = buf; +/* refRecordValue->refRecordType = NULL;*/ + do { + if (get_one_line(is, buf)) { + result = True; + goto quit; + } + if (feof(is)) { + if ('\0' == *buf) + goto quit; + break; + } + } while ('\0' == *buf); + + if (NULL != (valueHead = strchr(buf, 0xff))) { + *valueHead = '\0'; + valueHead++; + } else + valueHead = buf+strlen(buf); +#if 0 + fprintf(stderr, + "truetype font property file : \n" + "recName:\"%s\"\nvalue:\"%s\"\n", + recordHead, valueHead); +#endif + result = SPropRecValList_add_record(pThisList, recordHead, valueHead); + } + quit: + xfree(buf); + abort: + return result; +} + +/* Read Property File */ +Bool /* True == Error, False == Success */ +SPropRecValList_read_prop_file(SDynPropRecValList *pThisList, + char const * const strFileName) +{ + Bool result = False; + FILE *is; + +#if 1 + if (!strcmp(strFileName, "-")) + is = stdin; + else +#endif + is = fopen(strFileName, "r"); + if (NULL == is) { + fprintf(stderr, "truetype font property : cannot open file %s.\n", + strFileName); + result = True; + goto abort; + } + { + for (;;) { + if (False != (result = parse_one_line(pThisList, is))) + goto quit; + if (feof(is)) + break; + } + } + quit: +#if 1 + if (strcmp(strFileName, "-")) +#endif + fclose(is); + abort: + return result; +} +#endif /* USE_TTP_FILE */ + +/* get property record type by record name */ +static Bool /* True == Found, False == Not Found */ +get_record_type_by_name(SPropertyRecord const ** const refRefRecord, /*result*/ + char const *strName) +{ + Bool result = False; + int i; + + *refRefRecord = NULL; + for (i=0; i<numOfValidRecords; i++) { + if (!mystrcasecmp(validRecords[i].strRecordName, strName)) { + result = True; + *refRefRecord = &validRecords[i]; + break; + } + } + + return result; +} + +/* Constructor for Container Node */ +Bool /* True == Error, False == Success */ +SPropRecValList_new(SDynPropRecValList *pThisList) +{ + Bool result = False; + + pThisList->headNode = NULL; + + return result; +} + +/* Destructor for Container List */ +Bool /* True == Error, False == Success */ +SPropRecValList_delete(SDynPropRecValList *pThisList) +{ + Bool result = False; + SPropRecValListNodeP *p, *np; + + for (p=pThisList->headNode; NULL!=p; p=np) { + np = p->nextNode; + switch (p->containerE.refRecordType->recordType) { + case eRecTypeInteger: + break; + case eRecTypeDouble: + break; + case eRecTypeBool: + break; + case eRecTypeString: + if (SPropContainer_value_str(&p->containerE)) + xfree((void*)SPropContainer_value_str(&p->containerE)); + break; + case eRecTypeVoid: + break; + } + xfree(p); + } + + pThisList->headNode = NULL; + + return result; +} + +#ifdef DUMP +void +SPropRecValList_dump(SRefPropRecValList *pThisList) +{ + SPropRecValListNodeP *p; + for (p=pThisList->headNode; NULL!=p; p=p->nextNode) { + switch (p->containerE.refRecordType->recordType) { + case eRecTypeInteger: + fprintf(stderr, "%s = %d\n", + p->containerE.refRecordType->strRecordName, + p->containerE.uValue.integerValue); + break; + case eRecTypeDouble: + fprintf(stderr, "%s = %f\n", + p->containerE.refRecordType->strRecordName, + p->containerE.uValue.doubleValue); + break; + case eRecTypeBool: + fprintf(stderr, "%s = %s\n", + p->containerE.refRecordType->strRecordName, + p->containerE.uValue.boolValue + ? "True":"False"); + break; + case eRecTypeString: + fprintf(stderr, "%s = \"%s\"\n", + p->containerE.refRecordType->strRecordName, + p->containerE.uValue.dynStringValue); + break; + case eRecTypeVoid: + fprintf(stderr, "%s = void\n", + p->containerE.refRecordType->strRecordName); + break; + } + } +} +#endif + +/* Add Property Record Value */ +extern Bool /* True == Error, False == Success */ +SPropRecValList_add_record(SDynPropRecValList *pThisList, + char const * const recordName, + char const * const strValue) +{ + Bool result = False; + SPropRecValContainerEntityP tmpContainerE; + + if (get_record_type_by_name(&tmpContainerE.refRecordType, recordName)) { + switch (tmpContainerE.refRecordType->recordType) { + case eRecTypeInteger: + { + int val; + char *endPtr; + + val = strtol(strValue, &endPtr, 0); + if ('\0' != *endPtr) { + fprintf(stderr, + "truetype font property : " + "%s record needs integer value.\n", + recordName); + result = True; + goto quit; + } + SPropContainer_value_int(&tmpContainerE) = val; + } + break; + case eRecTypeDouble: + { + double val; + char *endPtr; + + val = strtod(strValue, &endPtr); + if ('\0' != *endPtr) { + fprintf(stderr, + "truetype font property : " + "%s record needs floating point value.\n", + recordName); + result = True; + goto quit; + } + SPropContainer_value_dbl(&tmpContainerE) = val; + } + break; + case eRecTypeBool: + { + Bool val; + + if (!mystrcasecmp(strValue, "yes")) + val = True; + else if (!mystrcasecmp(strValue, "y")) + val = True; + else if (!mystrcasecmp(strValue, "on")) + val = True; + else if (!mystrcasecmp(strValue, "true")) + val = True; + else if (!mystrcasecmp(strValue, "t")) + val = True; + else if (!mystrcasecmp(strValue, "ok")) + val = True; + else if (!mystrcasecmp(strValue, "no")) + val = False; + else if (!mystrcasecmp(strValue, "n")) + val = False; + else if (!mystrcasecmp(strValue, "off")) + val = False; + else if (!mystrcasecmp(strValue, "false")) + val = False; + else if (!mystrcasecmp(strValue, "f")) + val = False; + else if (!mystrcasecmp(strValue, "bad")) + val = False; + else { + fprintf(stderr, + "truetype font property : " + "%s record needs boolean value.\n", + recordName); + result = True; + goto quit; + } + SPropContainer_value_bool(&tmpContainerE) = val; + } + break; + case eRecTypeString: + { + char *p; + + if (NULL == (p = (char *)xalloc(strlen(strValue)+1))) { + fprintf(stderr, + "truetype font property : " + "cannot allocate memory.\n"); + result = True; + goto quit; + } + strcpy(p, strValue); + SPropContainer_value_str(&tmpContainerE) = p; + } + break; + case eRecTypeVoid: + if ('\0' != *strValue) { + fprintf(stderr, + "truetype font property : " + "%s record needs void.\n", recordName); + result = True; + } + break; + } + { + /* add to list */ + SPropRecValListNodeP *newNode; + + if (NULL == (newNode = + (SPropRecValListNodeP *)xalloc(sizeof(*newNode)))) { + fprintf(stderr, + "truetype font property : " + "cannot allocate memory.\n"); + result = True; + goto quit; + } + newNode->nextNode = pThisList->headNode; + newNode->containerE = tmpContainerE; + tmpContainerE.refRecordType = NULL; /* invalidate -- + disown value handle. */ + pThisList->headNode = newNode; + } + } else { + /* invalid record name */ + fprintf(stderr, + "truetype font : " + "invalid record name \"%s.\"\n", recordName); + result = True; + } + + quit: + return result; +} + + +/* Search Property Record */ +Bool /* True == Hit, False == Miss */ +SPropRecValList_search_record(SRefPropRecValList *pThisList, + SPropRecValContainer *refRecValue, + char const * const recordName) +{ + Bool result = False; + SPropRecValListNodeP *p; + + *refRecValue = NULL; + for (p=pThisList->headNode; NULL!=p; p=p->nextNode) { + if (!mystrcasecmp(p->containerE.refRecordType->strRecordName, + recordName)) { + *refRecValue = &p->containerE; + result = True; + break; + } + } + + return result; +} + + +/* Parse TTCap */ +Bool /* True == Error, False == Success */ +SPropRecValList_add_by_font_cap(SDynPropRecValList *pThisList, + char const *strCapHead) +{ + Bool result = False; + /* SPropertyRecord const *refRecordType; */ + char const *term; + + if (NULL == (term = strrchr(strCapHead, ':'))) + goto abort; + + { + /* for xfsft compatible */ + char const *p; + for (p=term-1; p>=strCapHead; p--) { + if ( ':'==*p ) { + /* + * :num:filename + * ^p ^term + */ + if ( p!=term ) { + int len = term-p-1; + char *value; + + len = term-p-1; + value=(char *)xalloc(len+1); + memcpy(value, p+1, len); + value[len]='\0'; + SPropRecValList_add_record(pThisList, + "FaceNumber", + value); + xfree(value); + term=p; + } + break; + } + if ( !isdigit(*p) ) + break; + } + } + + while (strCapHead<term) { + int i; + char const *nextColon = strchr(strCapHead, ':'); + if (0<nextColon-strCapHead) { + char *duplicated = (char *)xalloc((nextColon-strCapHead)+1); + { + char *value; + + memcpy(duplicated, strCapHead, nextColon-strCapHead); + duplicated[nextColon-strCapHead] = '\0'; + if (NULL != (value=strchr(duplicated, '='))) { + *value = '\0'; + value++; + } else + value = &duplicated[nextColon-strCapHead]; + + for (i=0; i<numOfCorrespondRelations; i++) { + if (!mystrcasecmp(correspondRelations[i].capVariable, + duplicated)) { + if (SPropRecValList_add_record(pThisList, + correspondRelations[i] + .recordName, + value)) + break; + goto next; + } + } + fprintf(stderr, "truetype font : Illegal Font Cap.\n"); + result = True; + break; + next: + ; + } + xfree(duplicated); + } + strCapHead = nextColon+1; + } + + /* quit: */ + abort: + return result; +} + + +/************************************************************************** + Functions (xttmisc) + */ + +/* compare strings, ignoring case */ +Bool /* False == equal, True == not equal */ +mystrcasecmp(char const *s1, char const *s2) +{ + Bool result = True; + +#if (defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) ||\ + defined(__bsdi__)) && !defined(FONTMODULE) + /* 4.4BSD has strcasecmp function. */ + result = strcasecmp(s1, s2) != 0; +#else + { + unsigned int len1 = strlen(s1); + + if (len1 == strlen(s2)) { + int i; + for (i=0; i<len1; i++) { + if (toupper(*s1++) != toupper(*s2++)) + goto quit; + } + result = False; + } else + /* len1 != len2 -> not equal*/ + ; + } + quit: + ; +#endif + + return result; +} + + +/* strdup clone with using the allocator of X server */ +char * +XttXstrdup(char const *str) +{ + char *result; + + result = (char *)xalloc(strlen(str)+1); + + if (result) + strcpy(result, str); + + return result; +} + + +#if 0 +int main() +{ + SDynPropRecValList list; + + SPropRecValList_new(&list); + SPropRecValList_read_prop_file(&list, "-"); + SPropRecValList_dump(&list); + SPropRecValList_delete(&list); + + return 0; +} +#endif + +/* end of file */ diff --git a/nx-X11/lib/font/FreeType/xttcap.h b/nx-X11/lib/font/FreeType/xttcap.h new file mode 100644 index 000000000..33c224f90 --- /dev/null +++ b/nx-X11/lib/font/FreeType/xttcap.h @@ -0,0 +1,140 @@ +/* ===EmacsMode: -*- Mode: C; tab-width:4; c-basic-offset: 4; -*- === */ +/* ===FileName: === + Copyright (c) 1998 Takuya SHIOZAKI, All Rights reserved. + Copyright (c) 1998 X-TrueType Server Project, All rights reserved. + Copyright (c) 2003 After X-TT Project, All rights reserved. + +===Notice + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. + + Major Release ID: X-TrueType Server Version 1.3 [Aoi MATSUBARA Release 3] + +Notice=== + */ +/* $XFree86: xc/extras/X-TrueType/xttcap.h,v 1.2 2001/08/01 00:44:33 tsi Exp $ */ + +#ifndef _XTTCAP_H_ +#define _XTTCAP_H_ (1) + +#include <X11/Xdefs.h> + +/******************************************************************* + Data Types + */ + +/* Record Type */ +typedef enum +{ + eRecTypeInteger, + eRecTypeDouble, + eRecTypeBool, + eRecTypeString, + eRecTypeVoid=-1 +} ERecType; + +/* Record Name vs Record Type */ +typedef struct +{ + char const *strRecordName; + ERecType const recordType; +} SPropertyRecord; + +/* Record Value Container */ +typedef struct +{ + SPropertyRecord const *refRecordType; + union { + int integerValue; + double doubleValue; + Bool boolValue; + char *dynStringValue; + } uValue; +} SPropRecValContainerEntityP, *SPropRecValContainer; + +/* Record Value List */ +typedef struct TagSPropRecValListNodeP SPropRecValListNode; +typedef struct +{ + SPropRecValListNode *headNode; +} SDynPropRecValList; +typedef SDynPropRecValList const SRefPropRecValList; + + +/******************************************************************* + Functions + */ + +/* Constructor for Rec Val List */ +extern Bool /* True == Error, False == Success */ +SPropRecValList_new(SDynPropRecValList *pThisList); +/* Destructor for Rec Val List */ +extern Bool /* True == Error, False == Success */ +SPropRecValList_delete(SDynPropRecValList *pThisList); +/* Read Property File */ +extern Bool /* True == Error, False == Success */ +SPropRecValList_read_prop_file(SDynPropRecValList *pThisList, + char const * const strFileName); +/* Add Property Record Value */ +extern Bool /* True == Error, False == Success */ +SPropRecValList_add_record(SDynPropRecValList *pThisList, + char const * const recordName, + char const * const strValue); +/* Search Property Record */ +extern Bool /* True == Hit, False == Miss */ +SPropRecValList_search_record(SRefPropRecValList *pThisList, + SPropRecValContainer *refContRecVal, + char const * const recordName); +/* Add by Font Cap */ +extern Bool /* True == Error, False == Success */ +SPropRecValList_add_by_font_cap(SDynPropRecValList *pThisList, + char const *strCapHead); + +#ifdef DUMP +void +SPropRecValList_dump(SRefPropRecValList *refList); +#endif + +#define SPropContainer_value_int(contRecVal)\ + ((contRecVal)->uValue.integerValue) +#define SPropContainer_value_dbl(contRecVal)\ + ((contRecVal)->uValue.doubleValue) +#define SPropContainer_value_bool(contRecVal)\ + ((contRecVal)->uValue.boolValue) +#define SPropContainer_value_str(contRecVal)\ + ((contRecVal)->uValue.dynStringValue) + +/****************************************************** + Prototypes (xttmisc) + */ + +/* compare strings with ignoring case */ + /* False == equal, True == not equal */ +Bool mystrcasecmp(char const *s1, char const *s2); + +/* strdup clone */ +char * XttXstrdup(char const *str); +#undef xstrdup +#define xstrdup(s) XttXstrdup((char const*)s) + +#endif /* !def _XTTCAP_H_ */ + +/* end of file */ diff --git a/nx-X11/lib/font/Imakefile b/nx-X11/lib/font/Imakefile new file mode 100644 index 000000000..02ddd8eaa --- /dev/null +++ b/nx-X11/lib/font/Imakefile @@ -0,0 +1,178 @@ +XCOMM $Xorg: Imakefile,v 1.3 2000/08/17 19:46:24 cpqbld Exp $ + + + + +XCOMM $XFree86: xc/lib/font/Imakefile,v 3.37 2003/10/24 16:21:12 tsi Exp $ + +#include <Server.tmpl> + +#define IHaveSubdirs + +#define DoNormalLib NormalLibFont +#define DoSharedLib SharedLibFont +#define DoExtraLib SharedLibFont +#define DoDebugLib DebugLibFont +#define DoProfileLib ProfileLibFont + +#if !BuildFontLib +#define LibCreate NO +#else +#define LibCreate YES +#endif + +#if BuildLibraries +#define LibInstall YES +#else +#define LibInstall NO +#endif + +#if BuildLibraries +STUBDIRS = stubs +#endif + +LIBNAME = Xfont +SOREV = $(SOFONTREV) + +#ifndef SeparateSharedCompile +#define SeparateSharedCompile YES +#endif +#if NormalLibFont && SharedLibFont && SeparateSharedCompile +STATIC_OBJSDIR = unshared/ +#endif + +#ifdef SharedXfontReqs +REQUIREDLIBS = SharedXfontReqs +#endif + +#if BuildSpeedo + SPEEDODIRS = Speedo + SPEEDOSHAREDOBJS = Speedo/?*.o + SPEEDOSTATICOBJS = Speedo/$(STATIC_OBJSDIR)?*.o + SPEEDODEBUGOBJS = Speedo/debugger/?*.o + SPEEDOPROFILEOBJS = Speedo/profiled/?*.o + SPEEDODONES = Speedo/DONE +#endif +#if BuildType1 || BuildCID + TYPE1DIRS = Type1 + TYPE1SHAREDOBJS = Type1/?*.o + TYPE1STATICOBJS = Type1/$(STATIC_OBJSDIR)?*.o + TYPE1DEBUGOBJS = Type1/debugger/?*.o + TYPE1PROFILEOBJS = Type1/profiled/?*.o + TYPE1DONES = Type1/DONE +#endif +#if BuildFreeType || BuildFreetype2Library + FREETYPEDIRS = FreeType + FREETYPESHAREDOBJS = FreeType/?*.o + FREETYPESTATICOBJS = FreeType/$(STATIC_OBJSDIR)?*.o + FREETYPEDEBUGOBJS = FreeType/debugger/?*.o +FREETYPEPROFILEOBJS = FreeType/profiled/?*.o + FREETYPEDONES = FreeType/DONE +#endif +#if BuildBuiltinFonts + BUILTINDIRS = builtins + BUILTINSHAREDOBJS = builtins/?*.o + BUILTINSTATICOBJS = builtins/$(STATIC_OBJSDIR)?*.o + BUILTINDEBUGOBJS = builtins/debugger/?*.o + BUILTINPROFILEOBJS = builtins/profiled/?*.o + BUILTINDONES = builtins/DONE +#endif +#if BuildFontCache + FONTCACHEDIRS = fontcache +FONTCACHESHAREDOBJS = fontcache/?*.o +FONTCACHESTATICOBJS = fontcache/$(STATIC_OBJSDIR)?*.o + FONTCACHEDEBUGOBJS = fontcache/debugger/?*.o +FONTCACHEPROFILEOBJS = fontcache/profiled/?*.o + FONTCACHEDONES = fontcache/DONE +#endif + + SUBDIRS = bitmap fontfile fc $(FONTCACHEDIRS) \ + $(SPEEDODIRS) $(TYPE1DIRS) \ + $(FREETYPEDIRS) $(BUILTINDIRS) \ + util $(STUBDIRS) include + SHARED_OBJS = bitmap/?*.o fontfile/?*.o fc/?*.o $(FONTCACHESHAREDOBJS) \ + $(SPEEDOSHAREDOBJS) $(TYPE1SHAREDOBJS) \ + $(FREETYPESHAREDOBJS) \ + $(BUILTINSHAREDOBJS) util/?*.o + STATIC_OBJS = bitmap/$(STATIC_OBJSDIR)?*.o fontfile/$(STATIC_OBJSDIR)?*.o \ + fc/$(STATIC_OBJSDIR)?*.o $(FONTCACHESTATICOBJS) \ + $(SPEEDOSTATICOBJS) $(TYPE1STATICOBJS) \ + $(FREETYPESTATICOBJS) \ + $(BUILTINSTATICOBJS) util/$(STATIC_OBJSDIR)?*.o + DEBUG_OBJS = bitmap/debugger/?*.o fontfile/debugger/?*.o fc/debugger/?*.o \ + $(FONTCACHEDEBUGOBJS) \ + $(SPEEDODEBUGOBJS) $(TYPE1DEBUGOBJS) \ + $(FREETYPEDEBUGOBJS) \ + $(BUILTINDEBUGOBJS) util/debugger/?*.o + PROFILE_OBJS = bitmap/profiled/?*.o fontfile/profiled/?*.o fc/profiled/?*.o \ + $(FONTCACHEPROFILEOBJS) \ + $(SPEEDOPROFILEOBJS) $(TYPE1PROFILEOBJS) \ + $(FREETYPEPROFILEOBJS) \ + $(BUILTINPROFILEOBJS) util/profiled/?*.o + DONES = bitmap/DONE fontfile/DONE fc/DONE $(FONTCACHEDONES) \ + $(SPEEDODONES) $(TYPE1DONES) \ + $(FREETYPEDONES) \ + $(BUILTINDONES) util/DONE + +#if BuildServer && DoLoadableServer + BASEDIRS = fontfile fc util $(FONTCACHEDIRS) + BASELIBOBJS = fontfile/$(STATIC_OBJSDIR)?*.o fc/$(STATIC_OBJSDIR)?*.o \ + util/$(STATIC_OBJSDIR)?*.o $(FONTCACHESTATICOBJS) + BASEOBJS = fontfile/module/ffcheck.o fontfile/module/register.o \ + util/private.o + BASEDONES = fontfile/DONE fontfile/module/DONE fc/DONE util/DONE \ + $(FONTCACHEDONES) +#endif + +#if HasParallelMake +MakeMutex($(SUBDIRS) $(DONES)) +#endif + +#if HasGnuMake || HasBsdMake +$(DONES): $(SUBDIRS) +#endif + +#include <Library.tmpl> + +#undef _LinkBuildLibrary +#define _LinkBuildLibrary(lib) LinkBuildLibrary(lib) + +#if LibCreate +#if NormalLibFont +NormalDepLibraryTarget($(LIBNAME),$(SUBDIRS) $(DONES),$(STATIC_OBJS)) +#if LibInstall +InstallLibrary($(LIBNAME),$(USRLIBDIR)) +#endif /* LibInstall */ +#endif /* NormalLibFont */ + +#if SharedLibFont +SharedDepLibraryTarget($(LIBNAME),$(SOREV),$(SUBDIRS) $(DONES),$(SHARED_OBJS),.,.) +#if LibInstall +InstallSharedLibrary($(LIBNAME),$(SOREV),$(SHLIBDIR)) +#endif /* LibInstall */ +#endif /* SharedLibFont */ + +#if DebugLibFont +DebuggedDepLibraryTarget($(LIBNAME),$(SUBDIRS) $(DONES),$(DEBUG_OBJS)) +#if LibInstall +InstallLibrary($(LIBNAME)_d,$(USRLIBDIR)) +#endif /* LibInstall */ +#endif /* DebugLibFont */ + +#if ProfileLibFont +ProfiledDepLibraryTarget($(LIBNAME),$(SUBDIRS) $(DONES),$(PROFILE_OBJS)) +#if LibInstall +InstallLibrary($(LIBNAME)_p,$(USRLIBDIR)) +#endif /* LibInstall */ +#endif /* ProfileLibFont */ +#endif /* LibCreate */ + +#if BuildServer && DoLoadableServer +NormalDepLibraryTarget(fontbase,$(BASEDIRS) $(BASEDONES),$(BASELIBOBJS)) +NormalDepRelocatableTarget(fontbase,$(BASEDIRS) $(BASEDONES),$(BASEOBJS)) +#endif + + +ForceSubdirs($(SUBDIRS)) + +DependSubdirs($(SUBDIRS)) diff --git a/nx-X11/lib/font/Speedo/Imakefile b/nx-X11/lib/font/Speedo/Imakefile new file mode 100644 index 000000000..e2d9dcdeb --- /dev/null +++ b/nx-X11/lib/font/Speedo/Imakefile @@ -0,0 +1,46 @@ +XCOMM $Xorg: Imakefile,v 1.3 2000/08/17 19:46:24 cpqbld Exp $ + + + + +XCOMM $XFree86: xc/lib/font/Speedo/Imakefile,v 1.10 2001/01/19 08:13:29 dawes Exp $ + +#if BuildServer && DoLoadableServer +#define IHaveSubdirs +#define NoLibSubdirs +#define PassCDebugFlags +SUBDIRS = module +#endif + + INCLUDES = -I$(FONTINCSRC) -I../include -I$(SERVERSRC)/include + HEADERS = + SPEEDOSRCS = do_char.c do_trns.c out_bl2d.c out_blk.c \ + out_scrn.c out_util.c reset.c set_spcs.c set_trns.c + SPEEDOOBJS = do_char.o do_trns.o out_bl2d.o out_blk.o \ + out_scrn.o out_util.o reset.o set_spcs.o set_trns.o + + SRCS = spfuncs.c spfile.c spinfo.c sperr.c spfont.c spglyph.c \ + spencode.c bics-unicode.c \ + $(SPEEDOSRCS) + OBJS = spfuncs.o spfile.o spinfo.o sperr.o spfont.o spglyph.o \ + spencode.o bics-unicode.o \ + $(SPEEDOOBJS) + +#if BuildFontLib +#define DoNormalLib NormalLibFont +#define DoSharedLib SharedLibFont +#define DoDebugLib DebugLibFont +#define DoProfileLib ProfileLibFont +#include <Library.tmpl> +LibraryObjectRule() + +SubdirLibraryRule($(OBJS)) +NormalLintTarget($(SRCS)) +#endif + +#if BuildServer && DoLoadableServer +MakeSubdirs($(SUBDIRS)) +DependSubdirs($(SUBDIRS)) +#endif + +DependTarget() diff --git a/nx-X11/lib/font/Speedo/adobe-iso.h b/nx-X11/lib/font/Speedo/adobe-iso.h new file mode 100644 index 000000000..e1eeef1c5 --- /dev/null +++ b/nx-X11/lib/font/Speedo/adobe-iso.h @@ -0,0 +1,200 @@ +/* $Xorg: adobe-iso.h,v 1.3 2000/08/17 19:46:24 cpqbld Exp $ */ + +/* + * Latin 1 format from masterset format 11 (ps) + * 0 implies no valid mapping + */ + +int adobe_map[] = { + 32, 32, + 33, 33, + 34, 34, + 35, 35, + 36, 36, + 37, 37, + 38, 38, + 39, 169, + 40, 40, + 41, 41, + 42, 42, + 43, 43, + 44, 44, + 45, 45, + 46, 46, + 47, 47, + 48, 48, + 49, 49, + 50, 50, + 51, 51, + 52, 52, + 53, 53, + 54, 54, + 55, 55, + 56, 56, + 57, 57, + 58, 58, + 59, 59, + 60, 60, + 61, 61, + 62, 62, + 63, 63, + 64, 64, + 65, 65, + 66, 66, + 67, 67, + 68, 68, + 69, 69, + 70, 70, + 71, 71, + 72, 72, + 73, 73, + 74, 74, + 75, 75, + 76, 76, + 77, 77, + 78, 78, + 79, 79, + 80, 80, + 81, 81, + 82, 82, + 83, 83, + 84, 84, + 85, 85, + 86, 86, + 87, 87, + 88, 88, + 89, 89, + 90, 90, + 91, 91, + 92, 92, + 93, 93, + 94, 195, + 95, 95, + 96, 193, + 97, 97, + 98, 98, + 99, 99, + 100, 100, + 101, 101, + 102, 102, + 103, 103, + 104, 104, + 105, 105, + 106, 106, + 107, 107, + 108, 108, + 109, 109, + 110, 110, + 111, 111, + 112, 112, + 113, 113, + 114, 114, + 115, 115, + 116, 116, + 117, 117, + 118, 118, + 119, 119, + 120, 120, + 121, 121, + 122, 122, + 123, 123, + 124, 124, + 125, 125, + 126, 196, /* lc tilde */ + 127, 0, /* */ + 161, 161, /* invert exclamation */ + 162, 162, /* cent */ + 163, 163, /* pound sterling */ + 164, 168, /* intl currency */ + 165, 165, /* yen */ + 166, 320, /* split vert bar */ + 167, 167, /* section mark */ + 168, 200, /* dierisis */ + 169, 0, /* superior copyright */ + 170, 0, /* feminine ordinal */ + 171, 171, /* dbl left guillemot */ + 172, 314, /* math not */ + 173, 0, /* hyphen ? */ + 174, 0, /* superior registered */ + 175, 0, /* overscore */ + 176, 321, /* degree */ + 177, 329, /* math +- */ + 178, 333, /* superior 2 */ + 179, 332, /* superior 3 */ + 180, 194, /* lc acute */ + 181, 324, /* greek lc mu */ + 182, 182, /* Paragraph */ + 183, 180, /* center dot */ + 184, 203, /* cedilla lc */ + 185, 328, /* superior 1 */ + 186, 0, /* masculine ordinal(using superior o) */ + 187, 187, /* right dbl guillemot */ + 188, 327, /* 1/4 */ + 189, 326, /* 1/2 */ + 190, 331, /* 3/4 */ + 191, 191, /* invert question */ + 192, 259, /* A grave */ + 193, 256, /* A acute */ + 194, 257, /* A circumflex */ + 195, 261, /* A tilde */ + 196, 258, /* A dierisis */ + 197, 260, /* A angstrom */ + 198, 225, /* AE ligature */ + 199, 262, /* C cedilla */ + 200, 266, /* E grave */ + 201, 263, /* E acute */ + 202, 264, /* E circumflex */ + 203, 265, /* E dierisis */ + 204, 270, /* I grave */ + 205, 267, /* I acute */ + 206, 268, /* I circumflex */ + 207, 269, /* I dierisis */ + 208, 317, /* D bar */ + 209, 271, /* N tilde */ + 210, 275, /* O grave */ + 211, 272, /* O acute */ + 212, 273, /* O circumflex */ + 213, 276, /* O tilde */ + 214, 274, /* O dierisis */ + 215, 325, /* math multiply */ + 216, 233, /* O bar */ + 217, 281, /* U grave */ + 218, 278, /* U acute */ + 219, 279, /* U circumflex */ + 220, 280, /* U dierisis */ + 221, 319, /* Y acute */ + 222, 318, /* icelandic thorn lc */ + 223, 251, /* German dbl s */ + 224, 287, /* a grave */ + 225, 284, /* a acute */ + 226, 285, /* a circumflex */ + 227, 289, /* a tilde */ + 228, 286, /* a dierisis */ + 229, 288, /* a angstrom */ + 230, 241, /* ae ligature */ + 231, 290, /* c cedilla */ + 232, 294, /* e grave */ + 233, 291, /* e acute */ + 234, 292, /* e circumflex */ + 235, 293, /* e dierisis */ + 236, 298, /* i grave */ + 237, 295, /* i acute */ + 238, 296, /* i circumflex */ + 239, 297, /* i dierisis */ + 240, 323, /* icelandic eth lc */ + 241, 299, /* n tilde */ + 242, 303, /* o grave */ + 243, 300, /* o acute */ + 244, 301, /* o circumflex */ + 245, 304, /* o tilde */ + 246, 302, /* o dierisis */ + 247, 322, /* math divide */ + 248, 249, /* o bar */ + 249, 309, /* u grave */ + 250, 306, /* u acute */ + 251, 307, /* u circumflex */ + 252, 308, /* u dierisis */ + 253, 334, /* y acute */ + 254, 330, /* icelandic thorn uc */ + 255, 310, /* y dierisis */ +}; diff --git a/nx-X11/lib/font/Speedo/bics-iso.h b/nx-X11/lib/font/Speedo/bics-iso.h new file mode 100644 index 000000000..4964fa34e --- /dev/null +++ b/nx-X11/lib/font/Speedo/bics-iso.h @@ -0,0 +1,224 @@ +/* $Xorg: bics-iso.h,v 1.4 2001/02/09 02:04:00 xorgcvs Exp $ */ +/* + +Copyright 1993, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + +*/ +/* $XFree86: xc/lib/font/Speedo/bics-iso.h,v 1.6 2001/01/17 19:43:17 dawes Exp $ */ + +int sp_bics_map[] = { + 32, 0, + 33, 1, + 34, 2, + 35, 3, + 36, 4, + 37, 5, + 38, 6, + 39, 264, + 40, 8, + 41, 9, + 42, 10, + 43, 11, + 44, 12, + 45, 13, + 46, 14, + 47, 15, + 48, 16, + 49, 17, + 50, 18, + 51, 19, + 52, 20, + 53, 21, + 54, 22, + 55, 23, + 56, 24, + 57, 25, + 58, 26, + 59, 27, + 60, 28, + 61, 29, + 62, 30, + 63, 31, + 64, 32, + 65, 33, + 66, 34, + 67, 35, + 68, 36, + 69, 37, + 70, 38, + 71, 39, + 72, 40, + 73, 41, + 74, 42, + 75, 43, + 76, 44, + 77, 45, + 78, 46, + 79, 47, + 80, 48, + 81, 49, + 82, 50, + 83, 51, + 84, 52, + 85, 53, + 86, 54, + 87, 55, + 88, 56, + 89, 57, + 90, 58, + 91, 59, + 92, 60, + 93, 61, + 94, 133, + 95, 63, + 96, 131, + 97, 65, + 98, 66, + 99, 67, + 100, 68, + 101, 69, + 102, 70, + 103, 71, + 104, 72, + 105, 73, + 106, 74, + 107, 75, + 108, 76, + 109, 77, + 110, 78, + 111, 79, + 112, 80, + 113, 81, + 114, 82, + 115, 83, + 116, 84, + 117, 85, + 118, 86, + 119, 87, + 120, 88, + 121, 89, + 122, 90, + 123, 91, + 124, 92, + 125, 93, + 126, 137, + 127, 358, + 161, 128, + 162, 98, + 163, 97, + 164, 278, + 165, 274, + 166, 277, + 167, 110, + 168, 135, + 169, 503, + 170, 538, + 171, 125, + 172, 309, + 173, 191, + 174, 504, + 175, 230, + 176, 339, + 177, 286, + 178, 160, + 179, 161, + 180, 129, + 181, 325, + 182, 279, + 183, 102, + 184, 141, + 185, 159, + 186, 544, + 187, 126, + 188, 151, + 189, 153, + 190, 155, + 191, 127, + 192, 259, + 193, 261, + 194, 257, + 195, 253, + 196, 255, + 197, 113, + 198, 114, + 199, 148, + 200, 249, + 201, 251, + 202, 247, + 203, 245, + 204, 239, + 205, 241, + 206, 237, + 207, 235, + 208, 169, + 209, 196, + 210, 202, + 211, 200, + 212, 204, + 213, 208, + 214, 206, + 215, 284, + 216, 115, + 217, 212, + 218, 210, + 219, 214, + 220, 216, + 221, 224, + 222, 271, + 223, 121, + 224, 260, + 225, 262, + 226, 258, + 227, 254, + 228, 256, + 229, 117, + 230, 118, + 231, 149, + 232, 250, + 233, 252, + 234, 248, + 235, 246, + 236, 240, + 237, 242, + 238, 238, + 239, 236, + 240, 273, + 241, 195, + 242, 201, + 243, 199, + 244, 203, + 245, 207, + 246, 205, + 247, 285, + 248, 119, + 249, 211, + 250, 209, + 251, 213, + 252, 215, + 253, 223, + 254, 272, + 255, 221, +}; + diff --git a/nx-X11/lib/font/Speedo/bics-unicode.c b/nx-X11/lib/font/Speedo/bics-unicode.c new file mode 100644 index 000000000..735508268 --- /dev/null +++ b/nx-X11/lib/font/Speedo/bics-unicode.c @@ -0,0 +1,138 @@ +/* +Copyright (c) 1998 by Juliusz Chroboczek + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +/* $XFree86$ */ + +/* These data are very dodgy. */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include "bics-unicode.h" + +static short table_160[]= +{0, 128, 98, 97, 278, 274, 277, 110, 135, 503, 538, 125, 309, 191, 504, + 230, 339, 286, 160, 161, 129, 325, 279, 102, 141, 159, 544, 126, 151, + 153, 155, 127, 259, 261, 257, 253, 255, 113, 114, 148, 249, 251, 247, + 245, 239, 241, 237, 235, 169, 196, 202, 200, 204, 208, 206, 284, 115, + 212, 210, 214, 216, 224, 271, 121, 260, 262, 258, 254, 256, 117, 118, + 149, 250, 252, 248, 246, 240, 242, 238, 236, 273, 195, 201, 199, 203, + 207, 205, 285, 119, 211, 209, 213, 215, 223, 272, 221, 477, 476, 374, + 373, 171, 177, 376, 375, -1, -1, -1, -1, 378, 377, 379, -1, 169, 173, + 383, 382, -1, -1, -1, -1, 172, 178, 243, 244, -1, -1, -1, -1, -1, -1, + 385, -1, -1, -1, -1, -1, 233, 234, 387, 386, -1, -1, 391, 390, 389, + 122, 276, 275, -1, -1, 393, 392, -1, 395, 394, 399, 398, -1, -1, -1, + -1, 170, 174, 194, 193, 402, 401, 198, 197, 263, -1, -1, -1, -1, -1, + -1, 404, 403, 116, 120, -1, -1, 408, 407, 406, 405, 410, 409, -1, -1, + 486, 485, 412, 411, 419, 418, 364, 363, -1, -1, 218, 217, 421, 420, -1, + -1, 220, 219, 423, 422, -1, 268, 425, 424, -1, -1, 222, 368, 367, 372, + 371, 370, 369}; + +static short table_728[]={144, 181, 146, 731, 137, 183}; + +static short table_915[]= +{313, 314, -1, -1, -1, 315, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 316, -1, -1, 317, -1, -1, 318, -1, -1, -1, -1, -1, -1, -1, 319, 320, + -1, 321, 322, -1, 323, 324, -1, -1, -1, 325, -1, -1, -1, 326, -1, -1, + 327, 328, -1, 329}; + +static short table_8211[]= +{111, 112, -1, -1, -1, -1, -1, 106, -1, 103, 105, 107, 104, 108, 109, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 100, -1, -1, + -1, -1, -1, -1, -1, -1, 123, 124, -1, 265}; + +static short table_8319[]= +{543, 475, 466, 467, 468, 469, 470, 471, 472, 473, 474, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 491, -1, -1, -1, 266}; + +static short table_8592[]={293, 295, 294, 292, 297, 296}; + +static short table_8712[]= +{298, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 492, -1, -1, -1, -1, -1, + -1, 302, -1, -1, -1, 303, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 299, + -1, -1, -1, -1, 428}; + + +static short table_8800[]={288, -1, -1, -1, 291, 290}; + +static short table_9600[]= +{304, -1, -1, -1, 305, -1, -1, -1, 308, -1, -1, -1, 306, -1, -1, -1, + 307, 357, 358, 359, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 335, 336, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 348, -1, -1, -1, 345, -1, -1, -1, -1, -1, 347, -1, -1, -1, 346, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 339, -1, -1, -1, 342, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 344}; + +static short table_9784[]={360, -1, 361, 362, -1, -1, -1, -1, 350, -1, 349}; + +static short table_9824[]= +{354, -1, -1, 352, -1, 351, 353, -1, -1, -1, 330, 331}; + +static short table_64256[]={282, 95, 96, 281}; + +int +unicode_to_bics(unsigned code) +{ + if(code<32) return -1; + else if(code<127) return code-32; + else if(code<160) return -1; + else if(code<383) return table_160[code-160]; + else if(code==402) return 99; + else if(code==486) return 480; + else if(code==487) return 379; + else if(code==501) return 384; + else if(code==711) return 139; + else if(code<728) return -1; + else if(code<734) return table_728[code-728]; + else if(code<915) return -1; + else if(code<967) return table_915[code-915]; + else if(code<8211) return -1; + else if(code<8253) return table_8211[code-8211]; + else if(code<8319) return -1; + else if(code<8360) return table_8319[code-8319]; + else if(code<8592) return -1; + else if(code<8598) return table_8592[code-8592]; + else if(code==8616) return 340; + else if(code<8712) return -1; + else if(code<8751) return table_8712[code-8712]; + else if(code<8800) return -1; + else if(code<8806) return table_8800[code-8800]; + else if(code==8976) return 310; + else if(code==8992) return 300; + else if(code==8993) return 301; + else if(code==9400) return 332; + else if(code==9415) return 333; + else if(code==9473) return 355; + else if(code==9475) return 356; + else if(code<9600) return -1; + else if(code<9690) return table_9600[code-9600]; + else if(code==9711) return 343; + else if(code<9784) return -1; + else if(code<9795) return table_9784[code-9784]; + else if(code<9824) return -1; + else if(code<9836) return table_9824[code-9824]; + else if(code<64256) return -1; + else if(code<64261) return table_64256[code-64256]; + else return -1; +} + diff --git a/nx-X11/lib/font/Speedo/bics-unicode.h b/nx-X11/lib/font/Speedo/bics-unicode.h new file mode 100644 index 000000000..90fa1885b --- /dev/null +++ b/nx-X11/lib/font/Speedo/bics-unicode.h @@ -0,0 +1,3 @@ +/* $XFree86$ */ + +int unicode_to_bics(unsigned); diff --git a/nx-X11/lib/font/Speedo/do_char.c b/nx-X11/lib/font/Speedo/do_char.c new file mode 100644 index 000000000..410d6339a --- /dev/null +++ b/nx-X11/lib/font/Speedo/do_char.c @@ -0,0 +1,1016 @@ +/* $Xorg: do_char.c,v 1.3 2000/08/17 19:46:24 cpqbld Exp $ */ + +/* + +Copyright 1989-1991, Bitstream Inc., Cambridge, MA. +You are hereby granted permission under all Bitstream propriety rights to +use, copy, modify, sublicense, sell, and redistribute the Bitstream Speedo +software and the Bitstream Charter outline font for any purpose and without +restrictions; provided, that this notice is left intact on all copies of such +software or font and that Bitstream's trademark is acknowledged as shown below +on all unmodified copies of such font. + +BITSTREAM CHARTER is a registered trademark of Bitstream Inc. + + +BITSTREAM INC. DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING +WITHOUT LIMITATION THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE. BITSTREAM SHALL NOT BE LIABLE FOR ANY DIRECT OR INDIRECT +DAMAGES, INCLUDING BUT NOT LIMITED TO LOST PROFITS, LOST DATA, OR ANY OTHER +INCIDENTAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF OR IN ANY WAY CONNECTED +WITH THE SPEEDO SOFTWARE OR THE BITSTREAM CHARTER OUTLINE FONT. + +*/ +/* $XFree86: xc/lib/font/Speedo/do_char.c,v 1.3 2001/01/17 19:43:17 dawes Exp $ */ + +/***************************** D O - C H A R . C ***************************** + * * + * This is the top level module for processing one simple or composite * + * character. + * * + ****************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include "spdo_prv.h" /* General definitions for Speedo */ + +#define DEBUG 0 + +#if DEBUG +#include <stdio.h> +#define SHOW(X) printf("X = %d\n", X) +#else +#define SHOW(X) +#endif + +/***** GLOBAL VARIABLES *****/ + +/***** GLOBAL FUNCTIONS *****/ + +/***** EXTERNAL VARIABLES *****/ + +/***** EXTERNAL FUNCTIONS *****/ + +/***** STATIC VARIABLES *****/ + +/***** STATIC FUNCTIONS *****/ + +static boolean sp_make_simp_char(PROTO_DECL2 ufix8 FONTFAR *pointer,ufix8 format); +static boolean sp_make_comp_char(PROTO_DECL2 ufix8 FONTFAR *pointer); +static ufix8 FONTFAR *sp_get_char_org(PROTO_DECL2 ufix16 char_index,boolean top_level); +static fix15 sp_get_posn_arg(PROTO_DECL2 ufix8 FONTFAR *STACKFAR *ppointer,ufix8 format); +static fix15 sp_get_scale_arg(PROTO_DECL2 ufix8 FONTFAR *STACKFAR *ppointer,ufix8 format); + + +FUNCTION ufix16 get_char_id( +GDECL +ufix16 char_index) /* Index to character in char directory */ +/* + * Returns character id for specified character index in currently + * selected font. + * Reports Error 10 and returns 0 if no font selected. + * Reports Error 12 and returns 0 if character data not available. + */ +{ +ufix8 FONTFAR *pointer; /* Pointer to character data */ + +if (!sp_globals.specs_valid) /* Font specs not defined? */ + { + report_error(10); /* Report font not specified */ + return (ufix16)0; /* Return zero character id */ + } + +pointer = sp_get_char_org(char_index, TRUE); /* Get pointer to character data */ +if (pointer == NULL) /* Character data not available? */ + { + report_error(12); /* Report character data not avail */ + return (ufix16)0; /* Return zero character id */ + } + +return 0xffff & NEXT_WORD(pointer); /* Return character id */ +} + + +#if INCL_METRICS +FUNCTION fix31 get_char_width( +GDECL +ufix16 char_index) /* Index to character in char directory */ +/* + * Returns character set width for specified character index in currently + * selected font in units of 1/65536 em. + * Reports Error 10 and returns 0 if no font selected. + * Reports Error 12 and returns 0 if character data not available. + */ +{ +ufix8 FONTFAR *pointer; /* Pointer to character data */ +fix31 set_width; /* Set width of character */ + +if (!sp_globals.specs_valid) /* Font specs not defined? */ + { + report_error(10); /* Report font not specified */ + return (fix31)0; /* Return zero character width */ + } + +pointer = sp_get_char_org(char_index, TRUE); /* Get pointer to character data */ +if (pointer == NULL) /* Character data not available? */ + { + report_error(12); /* Report character data not avail */ + return (fix31)0; /* Return zero character width */ + } + +pointer += 2; /* Skip over character id */ +set_width = (fix31)NEXT_WORD(pointer); /* Read set width and Convert units */ +set_width = ((set_width << 16) + (sp_globals.metric_resolution >> 1)) / sp_globals.metric_resolution; +return set_width; /* Return in 1/65536 em units */ +} +#endif + +#if INCL_METRICS +FUNCTION fix15 get_track_kern( +GDECL +fix15 track, /* Track required (0 - 3) */ +fix15 point_size) /* Point size (units of whole points) */ +/* + * Returns inter-character spacing adjustment in units of 1/256 + * points for the specified kerning track and point size. + * If the specified point size is larger than the maximum point + * size for the specified track, the adjustment for the maximum + * point size is used. + * If the specified point size is smaller than the minimum point + * size for the specified track, the adjustment for the minimum + * point size is used. + * If the specified point size is between the minimum point size + * and the maximum point size for the specified track, the + * adjustment is interpolated linearly between the minimum and + * maximum adjustments. + * Reports Error 10 and returns 0 if no font selected. + * Reports Error 13 and returns 0 if track kerning data not in font. + */ +{ +ufix8 FONTFAR *pointer; /* Pointer to character data */ +fix15 no_tracks; /* Number of kerning tracks in font */ +ufix8 format; /* Track kerning format byte */ +fix15 i; /* Track counter */ +fix15 min_pt_size = 0; /* Minimum point size for track */ +fix15 max_pt_size = 0; /* Maximum point size for track */ +fix15 min_adj = 0; /* Adjustment for min point size */ +fix15 max_adj = 0; /* Adjustment for max point size */ +fix31 delta_pt_size; /* Max point size - min point size */ +fix31 delta_adj; /* Min adjustment - max adjustment */ +fix15 adj = 0; /* Interpolated adjustment */ + +if (track == 0) /* Track zero selected? */ + { + return adj; /* Return zero track kerning adjustment */ + } + +if (!sp_globals.specs_valid) /* Font specs not defined? */ + { + report_error(10); /* Report font not specified */ + return adj; /* Return zero track kerning adjustment */ + } + +no_tracks = sp_globals.kern.no_tracks; /* Number of kerning tracks */ +if (track > no_tracks) /* Required track not available? */ + { + report_error(13); /* Report track kerning data not avail */ + return adj; /* Return zero track kerning adjustment */ + } + +pointer = sp_globals.kern.tkorg; /* Point to start of track kern data */ +for (i = 0; i < track; i++) /* Read until track required is read */ + { + format = NEXT_BYTE(pointer); /* Read track kerning format byte */ + min_pt_size = (format & BIT0)? + NEXT_WORD(pointer): + (fix15)NEXT_BYTE(pointer); + min_adj = (format & BIT1)? + NEXT_WORD(pointer): + (fix15)NEXT_BYTE(pointer); + max_pt_size = (format & BIT2)? + NEXT_WORD(pointer): + (fix15)NEXT_BYTE(pointer); + max_adj = (format & BIT3)? + NEXT_WORD(pointer): + (fix15)NEXT_BYTE(pointer); + } + +if (point_size <= min_pt_size) /* Smaller than minimum point size? */ + { + return min_adj; /* Return minimum adjustment (1/256 points) */ + } + +if (point_size >= max_pt_size) /* Larger than maximum point size? */ + { + return max_adj; /* Return maximum adjustment (1/256 points) */ + } + +delta_pt_size = (fix31)(max_pt_size - min_pt_size); +delta_adj = (fix31)(min_adj - max_adj); +adj = (fix15)(min_adj - + (((fix31)(point_size - min_pt_size) * delta_adj + + (delta_pt_size >> 1)) / delta_pt_size)); +return adj; /* Return interpolated adjustment (1/256 points) */ +} +#endif + +#if INCL_METRICS +FUNCTION fix31 get_pair_kern( +GDECL +ufix16 char_index1, /* Index to first character in char directory */ +ufix16 char_index2) /* Index to second character in char directory */ +/* + * Returns inter-character spacing adjustment in units of 1/65536 em + * for the specified pair of characters. + * Reports Error 10 and returns 0 if no font selected. + * Reports Error 14 and returns 0 if pair kerning data not in font. + */ +{ +ufix8 FONTFAR *origin; /* Pointer to first kerning pair record */ +ufix8 FONTFAR *pointer; /* Pointer to character data */ +ufix16 tmpufix16; /* Temporary workspace */ +fix15 no_pairs; /* Number of kerning pairs in font */ +ufix8 format; /* Track kerning format byte */ +boolean long_id; /* TRUE if 2-byte character ids */ +fix15 rec_size; /* Number of bytes in kern pair record */ +fix15 n; /* Number of remaining kern pairs */ +fix15 nn; /* Number of kern pairs in first partition */ +fix15 base; /* Index to first record in rem kern pairs */ +fix15 i; /* Index to kern pair being tested */ +fix31 adj = 0; /* Returned value of adjustment */ +fix15 adj_base = 0; /* Adjustment base for relative adjustments */ + +if (!sp_globals.specs_valid) /* Font specs not defined? */ + { + report_error(10); /* Report font not specified */ + return adj; /* Return zero pair kerning adjustment */ + } + +no_pairs = sp_globals.kern.no_pairs; /* Number of kerning pairs */ +if (no_pairs == 0) /* Pair kerning data not available? */ + { + report_error(14); /* Report pair kerning data not avail */ + return adj; /* Return zero pair kerning adjustment */ + } + +pointer = sp_globals.kern.pkorg; /* Point to start of pair kern data */ +format = NEXT_BYTE(pointer); /* Read pair kerning format byte */ +if (!(format & BIT0)) /* One-byte adjustment values? */ + adj_base = NEXT_WORD(pointer); /* Read base adjustment */ +origin = pointer; /* First byte of kerning pair data */ +rec_size = format + 3; /* Compute kerning pair record size */ +long_id = format & BIT1; /* Set flag for 2-byte char index */ + +n = no_pairs; /* Consider all kerning pairs */ +base = 0; /* Set base at first kern pair record */ +while (n != 0) /* While 1 or more kern pairs remain ... */ + { + nn = n >> 1; /* Size of first partition */ + i = base + nn; /* Index to record to be tested */ + pointer = origin + (i * rec_size); + tmpufix16 = NEXT_CHNDX(pointer, long_id); + if (char_index1 < tmpufix16) + { + n = nn; /* Number remaining in first partition */ + continue; + } + if (char_index1 > tmpufix16) + { + n -= nn + 1; /* Number remaining in second partition */ + base = i + 1; /* Base index for second partition */ + continue; + } + tmpufix16 = NEXT_CHNDX(pointer, long_id); + if (char_index2 < tmpufix16) + { + n = nn; /* Number remaining in first partition */ + continue; + } + if (char_index2 > tmpufix16) + { + n -= nn + 1; /* Number remaining in second partition */ + base = i + 1; /* Base index for second partition */ + continue; + } + adj = (format & BIT0)? + (fix31)NEXT_WORD(pointer): + (fix31)(adj_base + (fix15)NEXT_BYTE(pointer)); + adj = ((adj << 16) + (sp_globals.orus_per_em >> 1)) / sp_globals.orus_per_em; /* Convert units */ + n = 0; /* No more to consider */ + } +return adj; /* Return pair kerning adjustment */ +} +#endif + + +#if INCL_METRICS +#ifdef old +FUNCTION boolean get_char_bbox( +GDECL +ufix16 char_index, +bbox_t *bbox) +{ +/* + * returns true if character exists, false if it doesn't + * provides transformed character bounding box in 1/65536 pixels + * in the provided bbox_t structure. Bounding box may be + * conservative in the event that the transformation is not + * normal or the character is compound. + */ + +ufix8 FONTFAR *pointer; +fix15 tmp; +point_t Pmin, Pmax; + +#if REENTRANT_ALLOC +plaid_t plaid; +sp_globals.plaid = &plaid; +#endif + +if (!sp_globals.specs_valid) /* Font specs not defined? */ + { + report_error(10); /* Report font not specified */ + return FALSE; /* Error return */ + } + +init_tcb(); /* Initialize transformation control block */ + +pointer = sp_get_char_org(char_index, TRUE); /* Point to start of character data */ +if (pointer == NULL) /* Character data not available? */ + { + report_error(12); /* Report character data not avail */ + return FALSE; /* Error return */ + } + +pointer += 2; /* Skip over character id */ +tmp = NEXT_WORD(pointer); /* Read set width */ + +tmp = NEXT_BYTE(pointer); +if (tmp & BIT1) /* Optional data in header? */ + { + tmp = (ufix8)NEXT_BYTE(pointer); /* Read size of optional data */ + pointer += tmp; /* Skip optional data */ + } + +pointer = plaid_tcb(pointer, tmp); /* Process plaid data */ +pointer = read_bbox(pointer, &Pmin, &Pmax,(boolean)FALSE); /* Read bounding box */ +bbox->xmin = (fix31)Pmin.x << sp_globals.poshift; +bbox->xmax = (fix31)Pmax.x << sp_globals.poshift; +bbox->ymin = (fix31)Pmin.y << sp_globals.poshift; +bbox->ymax = (fix31)Pmax.y << sp_globals.poshift; +return TRUE; +} + +#else /* new code, 4/25/91 */ + +FUNCTION boolean get_char_bbox( +GDECL +ufix16 char_index, +bbox_t *bbox) +{ +/* + * returns true if character exists, false if it doesn't + * provides transformed character bounding box in 1/65536 pixels + * in the provided bbox_t structure. Bounding box may be + * conservative in the event that the transformation is not + * normal or the character is compound. + */ + +ufix8 FONTFAR *pointer; +fix15 tmp; +fix15 format; +ufix16 pix_adj; +point_t Pmin, Pmax; + +#if REENTRANT_ALLOC +plaid_t plaid; +sp_globals.plaid = &plaid; +#endif + +if (!sp_globals.specs_valid) /* Font specs not defined? */ + { + report_error(10); /* Report font not specified */ + return FALSE; /* Error return */ + } + +init_tcb(); /* Initialize transformation control block */ + +pointer = sp_get_char_org(char_index, TRUE); /* Point to start of character data */ +if (pointer == NULL) /* Character data not available? */ + { + report_error(12); /* Report character data not avail */ + return FALSE; /* Error return */ + } + +pointer += 2; /* Skip over character id */ +tmp = NEXT_WORD(pointer); /* Read set width */ + +format = NEXT_BYTE(pointer); +if (format & BIT1) /* Optional data in header? */ + { + tmp = (ufix8)NEXT_BYTE(pointer); /* Read size of optional data */ + pointer += tmp; /* Skip optional data */ + } + +if (format & BIT0) + { + pix_adj = sp_globals.onepix << 1; /* Allow 2 pixel expansion ... */ + } +else + { + pix_adj = 0; + } + +pointer = plaid_tcb(pointer, format); /* Process plaid data */ +pointer = read_bbox(pointer, &Pmin, &Pmax,(boolean)FALSE); /* Read bounding box */ + +Pmin.x -= pix_adj; /* ... of components of ... */ +Pmin.y -= pix_adj; /* ... compound ... */ +Pmax.x += pix_adj; /* ... character ... */ +Pmax.y += pix_adj; /* ... bounding box. */ + + +bbox->xmin = (fix31)Pmin.x << sp_globals.poshift; +bbox->xmax = (fix31)Pmax.x << sp_globals.poshift; +bbox->ymin = (fix31)Pmin.y << sp_globals.poshift; +bbox->ymax = (fix31)Pmax.y << sp_globals.poshift; +return TRUE; +} +#endif /* new code */ + +#endif + + +#if INCL_ISW +FUNCTION boolean make_char_isw( +GDECL +ufix16 char_index, +ufix32 imported_setwidth) +{ +fix15 xmin; /* Minimum X ORU value in font */ +fix15 xmax; /* Maximum X ORU value in font */ +fix15 ymin; /* Minimum Y ORU value in font */ +fix15 ymax; /* Maximum Y ORU value in font */ +ufix16 return_value; + +sp_globals.import_setwidth_act = TRUE; +/* convert imported width to orus */ +sp_globals.imported_width = (sp_globals.metric_resolution * + imported_setwidth) >> 16; +return_value = do_make_char(char_index); + +if (sp_globals.isw_modified_constants) + { + /* reset fixed point constants */ + xmin = read_word_u(sp_globals.font_org + FH_FXMIN); + ymin = read_word_u(sp_globals.font_org + FH_FYMIN); + ymax = read_word_u(sp_globals.font_org + FH_FYMAX); + sp_globals.constr.data_valid = FALSE; + xmax = read_word_u(sp_globals.font_org + FH_FXMAX); + if (!setup_consts(xmin,xmax,ymin,ymax)) + { + report_error(3); /* Requested specs out of range */ + return FALSE; + } + } +return (return_value); +} + +FUNCTION boolean make_char( +GDECL +ufix16 char_index) /* Index to character in char directory */ +{ +sp_globals.import_setwidth_act = FALSE; +return (do_make_char(char_index)); +} + +FUNCTION static boolean do_make_char(GDECL ufix16 char_index) +#else +FUNCTION boolean make_char(GDECL ufix16 char_index) +#endif +/* + * Outputs specified character using the currently selected font and + * scaling and output specifications. + * Reports Error 10 and returns FALSE if no font specifications + * previously set. + * Reports Error 12 and returns FALSE if character data not available. + */ +{ +ufix8 FONTFAR *pointer; /* Pointer to character data */ +fix15 x_orus; +fix15 tmpfix15; +ufix8 format; + +#if INCL_ISW +sp_globals.isw_modified_constants = FALSE; +#endif + +#if REENTRANT_ALLOC + +plaid_t plaid; + +#if INCL_BLACK || INCL_SCREEN || INCL_2D +intercepts_t intercepts; +sp_globals.intercepts = &intercepts; +#endif + +sp_globals.plaid = &plaid; +#endif + +if (!sp_globals.specs_valid) /* Font specs not defined? */ + { + report_error(10); /* Report font not specified */ + return FALSE; /* Error return */ + } + +#if INCL_MULTIDEV +#if INCL_OUTLINE +if (sp_globals.output_mode == MODE_OUTLINE && !sp_globals.outline_device_set) + { + report_error(2); + return FALSE; + } +else +#endif + if (!sp_globals.bitmap_device_set) + { + report_error(2); + return FALSE; + } +#endif + + +init_tcb(); /* Initialize transformation control block */ + +pointer = sp_get_char_org(char_index, TRUE); /* Point to start of character data */ +SHOW(pointer); +if (pointer == NULL) /* Character data not available? */ + { + report_error(12); /* Report character data not avail */ + return FALSE; /* Error return */ + } + +pointer += 2; /* Skip over character id */ +x_orus = NEXT_WORD(pointer); /* Read set width */ +#if INCL_SQUEEZING || INCL_ISW +sp_globals.setwidth_orus = x_orus; +#endif + +#if INCL_ISW +if (sp_globals.import_setwidth_act) + x_orus = sp_globals.imported_width; +#endif +sp_globals.Psw.x = (fix15)((fix31) + (((fix31)x_orus * (sp_globals.specs.xxmult>>16) + + ( ((fix31)x_orus * (sp_globals.specs.xxmult&0xffffL) )>>16) + ) << sp_globals.pixshift) / sp_globals.metric_resolution); + +sp_globals.Psw.y = (fix15)( + (fix31)( + ((fix31)x_orus * (sp_globals.specs.yxmult>>16) + + ( ((fix31)x_orus * (sp_globals.specs.yxmult&0xffffL) )>>16) + ) << sp_globals.pixshift) / sp_globals.metric_resolution); + +format = NEXT_BYTE(pointer); +if (format & BIT1) /* Optional data in header? */ + { + tmpfix15 = (ufix8)NEXT_BYTE(pointer); /* Read size of optional data */ + pointer += tmpfix15; /* Skip optional data */ + } +if (format & BIT0) + { + return sp_make_comp_char(pointer); /* Output compound character */ + } +else + { + return sp_make_simp_char(pointer, format); /* Output simple character */ + } +} + +FUNCTION static boolean sp_make_simp_char( +GDECL +ufix8 FONTFAR *pointer, /* Pointer to first byte of position argument */ +ufix8 format) /* Character format byte */ +/* + * Called by sp_make_char() to output a simple (non-compound) character. + * Returns TRUE on completion. + */ +{ +point_t Pmin, Pmax; /* Transformed corners of bounding box */ +#if INCL_SQUEEZING || INCL_ISW +ufix8 FONTFAR *save_pointer; +#endif +#if INCL_ISW +fix31 char_width; +fix31 isw_scale; +#endif + +#if INCL_SQUEEZING +sp_globals.squeezing_compound = FALSE; +if ((sp_globals.pspecs->flags & SQUEEZE_LEFT) || + (sp_globals.pspecs->flags & SQUEEZE_RIGHT) || + (sp_globals.pspecs->flags & SQUEEZE_TOP) || + (sp_globals.pspecs->flags & SQUEEZE_BOTTOM) ) + { + /* get the bounding box data before processing the character */ + save_pointer = pointer; + preview_bounding_box (pointer, format); + pointer = save_pointer; + } +#endif +#if (INCL_ISW) +if (sp_globals.import_setwidth_act) + { + save_pointer = pointer; + preview_bounding_box (pointer, format); + pointer = save_pointer; + /* make sure I'm not going to get fixed point overflow */ + isw_scale = compute_isw_scale(); + if (sp_globals.bbox_xmin_orus < 0) + char_width = SQUEEZE_MULT((sp_globals.bbox_xmax_orus - sp_globals.bbox_xmin_orus), isw_scale); + else + char_width = SQUEEZE_MULT(sp_globals.bbox_xmax_orus, isw_scale); + if (char_width >= sp_globals.isw_xmax) + if (!reset_xmax(char_width)) + return FALSE; + } +#endif +pointer = plaid_tcb(pointer, format); /* Process plaid data */ +pointer = read_bbox(pointer, &Pmin, &Pmax, FALSE); /* Read bounding box */ +if (fn_begin_char(sp_globals.Psw, Pmin, Pmax)) /* Signal start of character output */ + { + do + { + proc_outl_data(pointer); /* Process outline data */ + } + while (!fn_end_char()); /* Repeat if not done */ + } +return TRUE; +} + +FUNCTION static boolean sp_make_comp_char( +GDECL +ufix8 FONTFAR *pointer) /* Pointer to first byte of position argument */ +/* + * Called by sp_make_char() to output a compound character. + * Returns FALSE if data for any sub-character is not available. + * Returns TRUE if output completed with no error. + */ +{ +point_t Pmin, Pmax; /* Transformed corners of bounding box */ +point_t Pssw; /* Transformed escapement vector */ +ufix8 FONTFAR *pointer_sav; /* Saved pointer to compound character data */ +ufix8 FONTFAR *sub_pointer; /* Pointer to sub-character data */ +ufix8 format; /* Format of DOCH instruction */ +ufix16 sub_char_index; /* Index to sub-character in character directory */ +fix15 x_posn; /* X position of sub-character (outline res units) */ +fix15 y_posn; /* Y position of sub-character (outline res units) */ +fix15 x_scale; /* X scale factor of sub-character (scale units) */ +fix15 y_scale; /* Y scale factor of sub-character (scale units) */ +fix15 tmpfix15; /* Temporary workspace */ +fix15 x_orus; /* Set width in outline resolution units */ +fix15 pix_adj; /* Pixel adjustment to compound char bounding box */ +#if INCL_SQUEEZING +fix31 x_factor, x_offset, top_scale, bottom_scale; +boolean squeezed_x, squeezed_y; +#endif +#if INCL_SQUEEZING || INCL_ISW +fix15 x_offset_pix; +#endif +#if INCL_ISW +fix31 char_width; +fix31 isw_scale; +#endif + + +#if INCL_SQUEEZING +sp_globals.squeezing_compound = TRUE; +#endif +pointer = read_bbox(pointer, &Pmin, &Pmax, TRUE); /* Read bounding box data */ +pix_adj = sp_globals.onepix << 1; /* Allow 2 pixel expansion ... */ +Pmin.x -= pix_adj; /* ... of components of ... */ +Pmin.y -= pix_adj; /* ... compound ... */ +Pmax.x += pix_adj; /* ... character ... */ +Pmax.y += pix_adj; /* ... bounding box. */ + +#if INCL_SQUEEZING +/* scale the bounding box if necessary before calling begin_char */ +squeezed_x = calculate_x_scale(&x_factor, &x_offset, 0); +squeezed_y = calculate_y_scale(&top_scale, &bottom_scale,0,0); + +if (squeezed_x) + { /* scale the x coordinates of the bbox */ + x_offset_pix = (fix15)(((x_offset >> 16) * sp_globals.tcb0.xppo) + >> sp_globals.mpshift); + if ((x_offset_pix >0) && (x_offset_pix < sp_globals.onepix)) + x_offset_pix = sp_globals.onepix; + Pmin.x = SQUEEZE_MULT (x_factor, Pmin.x) + x_offset_pix - pix_adj; + Pmax.x = SQUEEZE_MULT (x_factor, Pmax.x) + x_offset_pix + pix_adj; + } +if (squeezed_y) + { /* scale the y coordinates of the bbox */ + if ((Pmin.y) < 0) + Pmin.y = SQUEEZE_MULT (bottom_scale, Pmin.y) - pix_adj; + else + Pmin.y = SQUEEZE_MULT (top_scale, Pmin.y) - pix_adj; + if ((Pmax.y) < 0) + Pmax.y = SQUEEZE_MULT (bottom_scale, Pmax.y) + pix_adj; + else + Pmax.y = SQUEEZE_MULT (top_scale, Pmax.y) + pix_adj; + } +#endif +#if (INCL_ISW) +if (sp_globals.import_setwidth_act) + { + /* make sure I'm not going to get fixed point overflow */ + isw_scale = ((fix31)sp_globals.imported_width << 16)/ + (fix31)sp_globals.setwidth_orus; + char_width = SQUEEZE_MULT((sp_globals.bbox_xmax_orus - + sp_globals.bbox_xmin_orus), +isw_scale); + if (char_width >= sp_globals.isw_xmax) + if (!reset_xmax(char_width)) + return FALSE; + } +#endif + +if (fn_begin_char(sp_globals.Psw, Pmin, Pmax)) /* Signal start of character data */ + { + pointer_sav = pointer; + do + { + pointer = pointer_sav; /* Point to next DOCH or END instruction */ + while ((format = NEXT_BYTE(pointer))) /* DOCH instruction? */ + { + init_tcb(); /* Initialize transformation control block */ + x_posn = sp_get_posn_arg(&pointer, format); + y_posn = sp_get_posn_arg(&pointer, (ufix8)(format >> 2)); + x_scale = sp_get_scale_arg(&pointer, (ufix8)(format & BIT4)); + y_scale = sp_get_scale_arg(&pointer, (ufix8)(format & BIT5)); + scale_tcb(&sp_globals.tcb, x_posn, y_posn, x_scale, y_scale); /* Scale for sub-char */ + sub_char_index = (format & BIT6)? /* Read sub-char index */ + 0xffff & NEXT_WORD(pointer): + 0xffff & NEXT_BYTE(pointer); + sub_pointer = sp_get_char_org(sub_char_index, FALSE); /* Point to start of sub-char */ + if (sub_pointer == NULL) /* Character data not available? */ + { + return FALSE; /* Abort character output */ + } + sub_pointer += 2; /* Skip over character id */ + x_orus = NEXT_WORD(sub_pointer); /* Read set_width of sub-character */ + + Pssw.x = (fix15)( + (fix31)( + ((fix31)x_orus * (sp_globals.specs.xxmult>>16) + + ( ((fix31)x_orus * (sp_globals.specs.xxmult&0xffffL) )>>16) + ) << sp_globals.pixshift) / sp_globals.metric_resolution); + Pssw.y = (fix15)( + (fix31)( + ((fix31)x_orus * (sp_globals.specs.yxmult>>16) + + ( ((fix31)x_orus * (sp_globals.specs.yxmult&0xffffL) )>>16) + ) << sp_globals.pixshift) / sp_globals.metric_resolution); + + format = NEXT_BYTE(sub_pointer); /* Read sub-character format */ + if (format & BIT1) /* Optional data in header? */ + { + tmpfix15 = (ufix8)NEXT_BYTE(sub_pointer); /* Read size of optional data */ + sub_pointer += tmpfix15; /* Skip optional data */ + } + sub_pointer = plaid_tcb(sub_pointer, format); /* Process sub-character plaid data */ + sub_pointer = read_bbox(sub_pointer, &Pmin, &Pmax, FALSE); /* Read bounding box */ + fn_begin_sub_char(Pssw, Pmin, Pmax); /* Signal start of sub-character data */ + proc_outl_data(sub_pointer); /* Process sub-character data */ + fn_end_sub_char(); /* Signal end of sub-character data */ + } + } + while (!fn_end_char()); /* Signal end of character; repeat if required */ + } +return TRUE; +} + +#if INCL_LCD /* Dynamic load character data supported? */ +FUNCTION static ufix8 FONTFAR *sp_get_char_org( +GDECL +ufix16 char_index, /* Index of character to be accessed */ +boolean top_level) /* Not a compound character element */ +/* + * Called by sp_get_char_id(), sp_get_char_width(), sp_make_char() and + * sp_make_comp_char() to get a pointer to the start of the character data + * for the specified character index. + * Version for configuration supporting dynamic character data loading. + * Calls load_char_data() to load character data if not already loaded + * as part of the original font buffer. + * Returns NULL if character data not available + */ +{ +buff_t *pchar_data; /* Buffer descriptor requested */ +ufix8 FONTFAR *pointer; /* Pointer into character directory */ +ufix8 format; /* Character directory format byte */ +fix31 char_offset; /* Offset of char data from start of font file */ +fix31 next_char_offset; /* Offset of char data from start of font file */ +fix15 no_bytes; /* Number of bytes required for char data */ + +if (top_level) /* Not element of compound char? */ + { + if (char_index < sp_globals.first_char_idx) /* Before start of character set? */ + return NULL; + char_index -= sp_globals.first_char_idx; + if (char_index >= sp_globals.no_chars_avail) /* Beyond end of character set? */ + return NULL; + sp_globals.cb_offset = 0; /* Reset char buffer offset */ + } + +pointer = sp_globals.pchar_dir; +format = NEXT_BYTE(pointer); /* Read character directory format byte */ +pointer += char_index << 1; /* Point to indexed character entry */ +if (format) /* 3-byte entries in char directory? */ + { + pointer += char_index; /* Adjust for 3-byte entries */ + char_offset = read_long(pointer); /* Read file offset to char data */ + next_char_offset = read_long(pointer + 3); /* Read offset to next char */ + } +else + { + char_offset = (fix31)(0xffff & NEXT_WORD(pointer)); /* Read file offset to char data */ + next_char_offset = (fix31)(0xffff & NEXT_WORD(pointer)); /* Read offset to next char */ + } + +no_bytes = next_char_offset - char_offset; +if (no_bytes == 0) /* Character not in directory? */ + return NULL; + +if (next_char_offset <= sp_globals.font_buff_size)/* Character data already in font buffer? */ + return sp_globals.pfont->org + char_offset; /* Return pointer into font buffer */ + +pchar_data = load_char_data(char_offset, no_bytes, sp_globals.cb_offset); /* Request char data load */ +if (pchar_data->no_bytes < no_bytes) /* Correct number of bytes loaded? */ + return NULL; + +if (top_level) /* Not element of compound char? */ + { + sp_globals.cb_offset = no_bytes; + } + +return pchar_data->org; /* Return pointer into character data buffer */ +} +#endif + +#if INCL_LCD +#else /* Dynamic load character data not supported? */ +FUNCTION static ufix8 FONTFAR *sp_get_char_org( +GDECL +ufix16 char_index, /* Index of character to be accessed */ +boolean top_level) /* Not a compound character element */ +/* + * Called by sp_get_char_id(), sp_get_char_width(), sp_make_char() and + * sp_make_comp_char() to get a pointer to the start of the character data + * for the specified character index. + * Version for configuration not supporting dynamic character data loading. + * Returns NULL if character data not available + */ +{ +ufix8 FONTFAR *pointer; /* Pointer into character directory */ +ufix8 format; /* Character directory format byte */ +fix31 char_offset; /* Offset of char data from start of font file */ +fix31 next_char_offset; /* Offset of char data from start of font file */ +fix15 no_bytes; /* Number of bytes required for char data */ + +if (top_level) /* Not element of compound char? */ + { + if (char_index < sp_globals.first_char_idx) /* Before start of character set? */ + return NULL; + char_index -= sp_globals.first_char_idx; + if (char_index >= sp_globals.no_chars_avail) /* Beyond end of character set? */ + return NULL; + } + +pointer = sp_globals.pchar_dir; +format = NEXT_BYTE(pointer); /* Read character directory format byte */ +pointer += char_index << 1; /* Point to indexed character entry */ +if (format) /* 3-byte entries in char directory? */ + { + pointer += char_index; /* Adjust for 3-byte entries */ + char_offset = read_long(pointer); /* Read file offset to char data */ + next_char_offset = read_long(pointer + 3); /* Read offset to next char */ + } +else + { + char_offset = (fix31)(0xffff & NEXT_WORD(pointer)); /* Read file offset to char data */ + next_char_offset = (fix31)(0xffff & NEXT_WORD(pointer)); /* Read offset to next char */ + } + +no_bytes = next_char_offset - char_offset; +if (no_bytes == 0) /* Character not in directory? */ + return NULL; + +return sp_globals.pfont->org + char_offset; /* Return pointer into font buffer */ +} +#endif + + +FUNCTION static fix15 sp_get_posn_arg( +GDECL +ufix8 FONTFAR * STACKFAR *ppointer, /* Pointer to first byte of position argument */ +ufix8 format) /* Format of DOCH arguments */ +/* + * Called by sp_make_comp_char() to read a position argument from the + * specified point in the font/char buffer. + * Updates pointer to byte following position argument. + * Returns value of position argument in outline resolution units + */ +{ +switch (format & 0x03) + { +case 1: + return NEXT_WORD(*ppointer); + +case 2: + return (fix15)((fix7)NEXT_BYTE(*ppointer)); + +default: + return (fix15)0; + } +} + +FUNCTION static fix15 sp_get_scale_arg( +GDECL +ufix8 FONTFAR *STACKFAR *ppointer, /* Pointer to first byte of position argument */ +ufix8 format) /* Format of DOCH arguments */ +/* + * Called by sp_make_comp_char() to read a scale argument from the + * specified point in the font/char buffer. + * Updates pointer to byte following scale argument. + * Returns value of scale argument in scale units (normally 1/4096) + */ +{ +if (format) + return NEXT_WORD(*ppointer); +else + return (fix15)ONE_SCALE; +} +#if INCL_ISW || INCL_SQUEEZING +FUNCTION static void preview_bounding_box( +GDECL +ufix8 FONTFAR *pointer, /* Pointer to first byte of position argument */ +ufix8 format) /* Character format byte */ +{ +point_t Pmin, Pmax; /* Transformed corners of bounding box */ + + sp_globals.no_X_orus = (format & BIT2)? + (fix15)NEXT_BYTE(pointer): + 0; + sp_globals.no_Y_orus = (format & BIT3)? + (fix15)NEXT_BYTE(pointer): + 0; + pointer = read_oru_table(pointer); + + /* Skip over control zone table */ + pointer = skip_control_zone(pointer,format); + + /* Skip over interpolation table */ + pointer = skip_interpolation_table(pointer,format); + /* get_args has a pathological need for this value to be set */ + sp_globals.Y_edge_org = sp_globals.no_X_orus; + pointer = read_bbox(pointer, &Pmin, &Pmax, TRUE); /* Read bounding bo +x */ + +} +#endif +#if INCL_ISW +FUNCTION static boolean reset_xmax( +GDECL +fix31 xmax) + +{ +fix15 xmin; /* Minimum X ORU value in font */ +fix15 ymin; /* Minimum Y ORU value in font */ +fix15 ymax; /* Maximum Y ORU value in font */ + + +sp_globals.isw_modified_constants = TRUE; +xmin = read_word_u(sp_globals.font_org + FH_FXMIN); +ymin = read_word_u(sp_globals.font_org + FH_FYMIN); +ymax = read_word_u(sp_globals.font_org + FH_FYMAX); + +if (!setup_consts(xmin,xmax,ymin,ymax)) + { + report_error(3); /* Requested specs out of range */ + return FALSE; + } +sp_globals.constr.data_valid = FALSE; +/* recompute setwidth */ +sp_globals.Psw.x = (fix15)((fix31)( + ((fix31)sp_globals.imported_width * (sp_globals.specs.xxmult>>16) + + ( ((fix31)sp_globals.imported_width * + (sp_globals.specs.xxmult&0xffffL) )>>16) + ) << sp_globals.pixshift) / sp_globals.metric_resolution); +sp_globals.Psw.y = (fix15)( + (fix31)( + ((fix31)sp_globals.imported_width * (sp_globals.specs.yxmult>>16) + + ( ((fix31)sp_globals.imported_width * (sp_globals.specs.yxmult&0xffffL) )>>16) + ) << sp_globals.pixshift) / sp_globals.metric_resolution); + +return TRUE; +} +#endif diff --git a/nx-X11/lib/font/Speedo/do_trns.c b/nx-X11/lib/font/Speedo/do_trns.c new file mode 100644 index 000000000..2e0f1dbed --- /dev/null +++ b/nx-X11/lib/font/Speedo/do_trns.c @@ -0,0 +1,512 @@ +/* $Xorg: do_trns.c,v 1.3 2000/08/17 19:46:25 cpqbld Exp $ */ + +/* + +Copyright 1989-1991, Bitstream Inc., Cambridge, MA. +You are hereby granted permission under all Bitstream propriety rights to +use, copy, modify, sublicense, sell, and redistribute the Bitstream Speedo +software and the Bitstream Charter outline font for any purpose and without +restrictions; provided, that this notice is left intact on all copies of such +software or font and that Bitstream's trademark is acknowledged as shown below +on all unmodified copies of such font. + +BITSTREAM CHARTER is a registered trademark of Bitstream Inc. + + +BITSTREAM INC. DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING +WITHOUT LIMITATION THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE. BITSTREAM SHALL NOT BE LIABLE FOR ANY DIRECT OR INDIRECT +DAMAGES, INCLUDING BUT NOT LIMITED TO LOST PROFITS, LOST DATA, OR ANY OTHER +INCIDENTAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF OR IN ANY WAY CONNECTED +WITH THE SPEEDO SOFTWARE OR THE BITSTREAM CHARTER OUTLINE FONT. + +*/ +/* $XFree86: xc/lib/font/Speedo/do_trns.c,v 1.3 2001/01/17 19:43:17 dawes Exp $ */ + +/**************************** D O _ T R N S . C ****************************** + * * + * This module is responsible for executing all intelligent transformation * + * for bounding box and outline data * + * * + ****************************************************************************/ + + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include "spdo_prv.h" /* General definitions for Speedo */ + +#define DEBUG 0 + +#if DEBUG +#include <stdio.h> +#define SHOW(X) printf("X = %d\n", X) +#else +#define SHOW(X) +#endif + +/***** GLOBAL VARIABLES *****/ + +/***** GLOBAL FUNCTIONS *****/ + +/***** EXTERNAL VARIABLES *****/ + +/***** EXTERNAL FUNCTIONS *****/ + +/***** STATIC VARIABLES *****/ + +/***** STATIC FUNCTIONS *****/ + +static void sp_split_curve(PROTO_DECL2 point_t P1,point_t P2,point_t P3,fix15 depth); +static ufix8 FONTFAR *sp_get_args(PROTO_DECL2 ufix8 FONTFAR *pointer,ufix8 format,point_t STACKFAR *pP); + + +FUNCTION ufix8 FONTFAR *read_bbox( +GDECL +ufix8 FONTFAR *pointer, /* Pointer to next byte in char data */ +point_t STACKFAR *pPmin, /* Lower left corner of bounding box */ +point_t STACKFAR *pPmax, /* Upper right corner of bounding box */ +boolean set_flag) /* flag to indicate whether global oru bbox should be saved */ +/* + * Called by make_simp_char() and make_comp_char() to read the + * bounding box data from the font. + * Sets Pmin and Pmax to the bottom left and top right corners + * of the bounding box after transformation into device space. + * The units of Pmin and Pmax are sub-pixels. + * Updates *ppointer to point to the byte following the + * bounding box data. + */ +{ +ufix8 format1; +ufix8 format = 0; +fix15 i; +point_t P; + +sp_globals.x_int = 0; +sp_globals.y_int = sp_globals.Y_int_org; +sp_globals.x_orus = sp_globals.y_orus = 0; +format1 = NEXT_BYTE(pointer); +pointer = sp_get_args(pointer, format1, pPmin); +#if INCL_SQUEEZING || INCL_ISW +if (set_flag) + { + sp_globals.bbox_xmin_orus = sp_globals.x_orus; + sp_globals.bbox_ymin_orus = sp_globals.y_orus; + } +#endif +*pPmax = *pPmin; +for (i = 1; i < 4; i++) + { + switch(i) + { + case 1: + if (format1 & BIT6) /* Xmax requires X int zone 1? */ + sp_globals.x_int++; + format = (format1 >> 4) | 0x0c; + break; + + case 2: + if (format1 & BIT7) /* Ymax requires Y int zone 1? */ + sp_globals.y_int++; + format = NEXT_BYTE(pointer); + break; + + case 3: + sp_globals.x_int = 0; + format >>= 4; + break; + + default: + break; + } + + pointer = sp_get_args(pointer, format, &P); +#if INCL_SQUEEZING || INCL_ISW + if (set_flag && (i==2)) + { + sp_globals.bbox_xmax_orus = sp_globals.x_orus; + sp_globals.bbox_ymax_orus = sp_globals.y_orus; + } +#endif + if ((i == 2) || (!sp_globals.normal)) + { + if (P.x < pPmin->x) + pPmin->x = P.x; + if (P.y < pPmin->y) + pPmin->y = P.y; + if (P.x > pPmax->x) + pPmax->x = P.x; + if (P.y > pPmax->y) + pPmax->y = P.y; + } + } + +#if DEBUG +printf("BBOX %6.1f(Xint 0), %6.1f(Yint 0), %6.1f(Xint %d), %6.1f(Yint %d)\n", + (real)pPmin->x / (real)sp_globals.onepix, + (real)pPmin->y / (real)sp_globals.onepix, + (real)pPmax->x / (real)sp_globals.onepix, + (format1 >> 6) & 0x01, + (real)pPmax->y / (real)sp_globals.onepix, + (format1 >> 7) & 0x01); + +#endif +return pointer; +} + +FUNCTION void proc_outl_data( +GDECL +ufix8 FONTFAR *pointer) /* Pointer to next byte in char data */ +/* + * Called by make_simp_char() and make_comp_char() to read the + * outline data from the font. + * The outline data is parsed, transformed into device coordinates + * and passed to an output module for further processing. + * Note that pointer is not updated to facilitate repeated + * processing of the outline data when banding mode is in effect. + */ +{ +ufix8 format1, format2; +point_t P0, P1, P2, P3; +fix15 depth; +fix15 curve_count; + +sp_globals.x_int = 0; +sp_globals.y_int = sp_globals.Y_int_org; +#if INCL_PLAID_OUT /* Plaid data monitoring included? */ +record_xint((fix15)sp_globals.x_int); /* Record xint data */ +record_yint((fix15)(sp_globals.y_int - sp_globals.Y_int_org)); /* Record yint data */ +#endif + +sp_globals.x_orus = sp_globals.y_orus = 0; +curve_count = 0; +while(TRUE) + { + format1 = NEXT_BYTE(pointer); + switch(format1 >> 4) + { + case 0: /* LINE */ + pointer = sp_get_args(pointer, format1, &P1); +#if DEBUG + printf("LINE %6.1f, %6.1f\n", + (real)P1.x / (real)sp_globals.onepix, (real)P1.y / (real)sp_globals.onepix); +#endif + fn_line(P1); + sp_globals.P0 = P1; + continue; + + case 1: /* Short XINT */ + sp_globals.x_int = format1 & 0x0f; +#if DEBUG + printf("XINT %d\n", sp_globals.x_int); +#endif +#if INCL_PLAID_OUT /* Plaid data monitoring included? */ +record_xint((fix15)sp_globals.x_int); /* Record xint data */ +#endif + continue; + + case 2: /* Short YINT */ + sp_globals.y_int = sp_globals.Y_int_org + (format1 & 0x0f); +#if DEBUG + printf("YINT %d\n", sp_globals.y_int - sp_globals.Y_int_org); +#endif +#if INCL_PLAID_OUT /* Plaid data monitoring included? */ +record_yint((fix15)(sp_globals.y_int - sp_globals.Y_int_org)); /* Record yint data */ +#endif + continue; + + case 3: /* Miscellaneous */ + switch(format1 & 0x0f) + { + case 0: /* END */ + if (curve_count) + { + fn_end_contour(); + } + return; + + case 1: /* Long XINT */ + sp_globals.x_int = NEXT_BYTE(pointer); +#if DEBUG + printf("XINT %d\n", sp_globals.x_int); +#endif +#if INCL_PLAID_OUT /* Plaid data monitoring included? */ +record_xint((fix15)sp_globals.x_int); /* Record xint data */ +#endif + continue; + + case 2: /* Long YINT */ + sp_globals.y_int = sp_globals.Y_int_org + NEXT_BYTE(pointer); +#if DEBUG + printf("YINT %d\n", sp_globals.y_int - sp_globals.Y_int_org); +#endif +#if INCL_PLAID_OUT /* Plaid data monitoring included? */ +record_yint((fix15)(sp_globals.y_int - sp_globals.Y_int_org)); /* Record yint data */ +#endif + continue; + + default: /* Not used */ + continue; + } + + case 4: /* MOVE Inside */ + case 5: /* MOVE Outside */ + if (curve_count++) + { + fn_end_contour(); + } + + pointer = sp_get_args(pointer, format1, &P0); + sp_globals.P0 = P0; +#if DEBUG + printf("MOVE %6.1f, %6.1f\n", + (real)sp_globals.P0.x / (real)sp_globals.onepix, (real)sp_globals.P0.y / (real)sp_globals.onepix); +#endif + fn_begin_contour(sp_globals.P0, (boolean)(format1 & BIT4)); + continue; + + case 6: /* Undefined */ +#if DEBUG + printf("*** Undefined instruction (Hex %4x)\n", format1); +#endif + continue; + + case 7: /* Undefined */ +#if DEBUG + printf("*** Undefined instruction (Hex %4x)\n", format1); +#endif + continue; + + default: /* CRVE */ + format2 = NEXT_BYTE(pointer); + pointer = sp_get_args(pointer, format1, &P1); + pointer = sp_get_args(pointer, format2, &P2); + pointer = sp_get_args(pointer, (ufix8)(format2 >> 4), &P3); + depth = (format1 >> 4) & 0x07; +#if DEBUG + printf("CRVE %6.1f, %6.1f, %6.1f, %6.1f, %6.1f, %6.1f, %d\n", + (real)P1.x / (real)sp_globals.onepix, (real)P1.y / (real)sp_globals.onepix, + (real)P2.x / (real)sp_globals.onepix, (real)P2.y / (real)sp_globals.onepix, + (real)P3.x / (real)sp_globals.onepix, (real)P3.y / (real)sp_globals.onepix, + depth); +#endif + depth += sp_globals.depth_adj; + if (sp_globals.curves_out) + { + fn_curve(P1, P2, P3, depth); + sp_globals.P0 = P3; + continue; + } + if (depth <= 0) + { + fn_line(P3); + sp_globals.P0 = P3; + continue; + } + sp_split_curve(P1, P2, P3, depth); + continue; + } + } +} + +FUNCTION static void sp_split_curve( +GDECL +point_t P1, /* First control point of Bezier curve */ +point_t P2, /* Second control point of Bezier curve */ +point_t P3, /* End point of Bezier curve */ +fix15 depth) /* Levels of recursive subdivision required */ +/* + * Called by proc_outl_data() to subdivide Bezier curves into an + * appropriate number of vectors, whenever curves are not enabled + * for output to the currently selected output module. + * sp_split_curve() calls itself recursively to the depth specified + * at which point it calls line() to deliver each vector resulting + * from the spliting process. + */ +{ +fix31 X0 = (fix31)sp_globals.P0.x; +fix31 Y0 = (fix31)sp_globals.P0.y; +fix31 X1 = (fix31)P1.x; +fix31 Y1 = (fix31)P1.y; +fix31 X2 = (fix31)P2.x; +fix31 Y2 = (fix31)P2.y; +fix31 X3 = (fix31)P3.x; +fix31 Y3 = (fix31)P3.y; +point_t Pmid; +point_t Pctrl1; +point_t Pctrl2; + +#if DEBUG +printf("CRVE(%3.1f, %3.1f, %3.1f, %3.1f, %3.1f, %3.1f)\n", + (real)P1.x / (real)sp_globals.onepix, (real)P1.y / (real)sp_globals.onepix, + (real)P2.x / (real)sp_globals.onepix, (real)P2.y / (real)sp_globals.onepix, + (real)P3.x / (real)sp_globals.onepix, (real)P3.y / (real)sp_globals.onepix); +#endif + + +Pmid.x = (X0 + (X1 + X2) * 3 + X3 + 4) >> 3; +Pmid.y = (Y0 + (Y1 + Y2) * 3 + Y3 + 4) >> 3; +if ((--depth) <= 0) + { + fn_line(Pmid); + sp_globals.P0 = Pmid; + fn_line(P3); + sp_globals.P0 = P3; + } +else + { + Pctrl1.x = (X0 + X1 + 1) >> 1; + Pctrl1.y = (Y0 + Y1 + 1) >> 1; + Pctrl2.x = (X0 + (X1 << 1) + X2 + 2) >> 2; + Pctrl2.y = (Y0 + (Y1 << 1) + Y2 + 2) >> 2; + sp_split_curve(Pctrl1, Pctrl2, Pmid, depth); + Pctrl1.x = (X1 + (X2 << 1) + X3 + 2) >> 2; + Pctrl1.y = (Y1 + (Y2 << 1) + Y3 + 2) >> 2; + Pctrl2.x = (X2 + X3 + 1) >> 1; + Pctrl2.y = (Y2 + Y3 + 1) >> 1; + sp_split_curve(Pctrl1, Pctrl2, P3, depth); + } +} + +FUNCTION static ufix8 FONTFAR *sp_get_args( +GDECL +ufix8 FONTFAR *pointer, /* Pointer to next byte in char data */ +ufix8 format, /* Format specifiaction of argument pair */ +point_t STACKFAR *pP) /* Resulting transformed point */ +/* + * Called by read_bbox() and proc_outl_data() to read an X Y argument + * pair from the font. + * The format is specified as follows: + * Bits 0-1: Type of X argument. + * Bits 2-3: Type of Y argument. + * where the 4 possible argument types are: + * Type 0: Controlled coordinate represented by one byte + * index into the X or Y controlled coordinate table. + * Type 1: Interpolated coordinate represented by a two-byte + * signed integer. + * Type 2: Interpolated coordinate represented by a one-byte + * signed increment/decrement relative to the + * proceding X or Y coordinate. + * Type 3: Repeat of preceding X or Y argument value and type. + * The units of P are sub-pixels. + * Updates *ppointer to point to the byte following the + * argument pair. + */ +{ +ufix8 edge; + +/* Read X argument */ +switch(format & 0x03) + { +case 0: /* Index to controlled oru */ + edge = NEXT_BYTE(pointer); + sp_globals.x_orus = sp_plaid.orus[edge]; +#if INCL_RULES + sp_globals.x_pix = sp_plaid.pix[edge]; +#endif + break; + +case 1: /* 2 byte interpolated oru value */ + sp_globals.x_orus = NEXT_WORD(pointer); + goto L1; + +case 2: /* 1 byte signed oru increment */ + sp_globals.x_orus += (fix15)((fix7)NEXT_BYTE(pointer)); +L1: +#if INCL_RULES + sp_globals.x_pix = TRANS(sp_globals.x_orus, sp_plaid.mult[sp_globals.x_int], sp_plaid.offset[sp_globals.x_int], sp_globals.mpshift); +#endif + break; + +default: /* No change in X value */ + break; + } + +/* Read Y argument */ +switch((format >> 2) & 0x03) + { +case 0: /* Index to controlled oru */ + edge = sp_globals.Y_edge_org + NEXT_BYTE(pointer); + sp_globals.y_orus = sp_plaid.orus[edge]; +#if INCL_RULES + sp_globals.y_pix = sp_plaid.pix[edge]; +#endif + break; + +case 1: /* 2 byte interpolated oru value */ + sp_globals.y_orus = NEXT_WORD(pointer); + goto L2; + +case 2: /* 1 byte signed oru increment */ + sp_globals.y_orus += (fix15)((fix7)NEXT_BYTE(pointer)); +L2: +#if INCL_RULES + sp_globals.y_pix = TRANS(sp_globals.y_orus, sp_plaid.mult[sp_globals.y_int], sp_plaid.offset[sp_globals.y_int], sp_globals.mpshift); +#endif + break; + +default: /* No change in X value */ + break; + } + +#if INCL_RULES +switch(sp_globals.tcb.xmode) + { +case 0: /* X mode 0 */ + pP->x = sp_globals.x_pix; + break; + +case 1: /* X mode 1 */ + pP->x = -sp_globals.x_pix; + break; + +case 2: /* X mode 2 */ + pP->x = sp_globals.y_pix; + break; + +case 3: /* X mode 3 */ + pP->x = -sp_globals.y_pix; + break; + +default: /* X mode 4 */ +#endif + pP->x = (MULT16(sp_globals.x_orus, sp_globals.tcb.xxmult) + + MULT16(sp_globals.y_orus, sp_globals.tcb.xymult) + + sp_globals.tcb.xoffset) >> sp_globals.mpshift; +#if INCL_RULES + break; + } + +switch(sp_globals.tcb.ymode) + { +case 0: /* Y mode 0 */ + pP->y = sp_globals.y_pix; + break; + +case 1: /* Y mode 1 */ + pP->y = -sp_globals.y_pix; + break; + +case 2: /* Y mode 2 */ + pP->y = sp_globals.x_pix; + break; + +case 3: /* Y mode 3 */ + pP->y = -sp_globals.x_pix; + break; + +default: /* Y mode 4 */ +#endif + pP->y = (MULT16(sp_globals.x_orus, sp_globals.tcb.yxmult) + + MULT16(sp_globals.y_orus, sp_globals.tcb.yymult) + + sp_globals.tcb.yoffset) >> sp_globals.mpshift; +#if INCL_RULES + break; + } +#endif + +return pointer; +} + + + diff --git a/nx-X11/lib/font/Speedo/htest.c b/nx-X11/lib/font/Speedo/htest.c new file mode 100644 index 000000000..235b76560 --- /dev/null +++ b/nx-X11/lib/font/Speedo/htest.c @@ -0,0 +1,361 @@ +/* $Xorg: htest.c,v 1.3 2000/08/17 19:46:25 cpqbld Exp $ */ + +/* + +Copyright 1989-1991, Bitstream Inc., Cambridge, MA. +You are hereby granted permission under all Bitstream propriety rights to +use, copy, modify, sublicense, sell, and redistribute the Bitstream Speedo +software and the Bitstream Charter outline font for any purpose and without +restrictions; provided, that this notice is left intact on all copies of such +software or font and that Bitstream's trademark is acknowledged as shown below +on all unmodified copies of such font. + +BITSTREAM CHARTER is a registered trademark of Bitstream Inc. + + +BITSTREAM INC. DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING +WITHOUT LIMITATION THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE. BITSTREAM SHALL NOT BE LIABLE FOR ANY DIRECT OR INDIRECT +DAMAGES, INCLUDING BUT NOT LIMITED TO LOST PROFITS, LOST DATA, OR ANY OTHER +INCIDENTAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF OR IN ANY WAY CONNECTED +WITH THE SPEEDO SOFTWARE OR THE BITSTREAM CHARTER OUTLINE FONT. + +*/ + +/****************************** H T E S T . C ******************************** + * * + * SPEEDO FONT HEADER TEST MODULE * + * * + ****************************************************************************/ + + +#include "speedo.h" /* General definition for make_bmap */ +#include <stdio.h> + +#define DEBUG 0 + +#if DEBUG +#define SHOW(X) printf("X = %d\n", X) +#else +#define SHOW(X) +#endif + +#define FONT_BUFFER_SIZE 1000 + +/***** EXTERNAL FUNCTIONS *****/ + +/***** STATIC VARIABLES *****/ +static char pathname[100]; /* Name of font file to be output */ +static ufix8 font_buffer[FONT_BUFFER_SIZE]; /* Font buffer */ +static FILE *fdescr; /* Speedo outline file descriptor */ + + + +FUNCTION main(argc,argv) +int argc; +char *argv[]; +{ +int bytes_read; /* Number of bytes read from font file */ +ufix8 tmpufix8; /* Temporary workspace */ +fix15 tmpfix15; /* Temporary workspace */ +ufix16 tmpufix16; /* Temporary workspace */ +ufix32 tmpufix32; /* Temporary workspace */ +ufix8 *pvt_header_org; /* Origin of provate header data */ + +ufix8 read_1b(); /* Read 1 byte field from font header */ +fix15 read_2b(); /* Read 2 byte field from font header */ +fix31 read_4b(); /* Read 4 byte field from font header */ + +if (argc != 2) + { + fprintf(stderr,"Usage: htest {fontfile}\n\n"); + exit (1); + } + +sprintf(pathname, argv[1]); + +/* Initialization */ +printf("\n SPEEDO FONT FILE HEADER DATA\n"); +printf(" -------------------------\n\n"); +/* Load Speedo outline file */ +fdescr = fopen (pathname, "rb"); +if (fdescr == NULL) + { + printf("****** Cannot open file %s\n", pathname); + return; + } + +bytes_read = fread(font_buffer, sizeof(ufix8), sizeof(font_buffer), fdescr); +if (bytes_read == 0) + { + printf("****** Error on reading %s: %x\n", pathname, bytes_read); + fclose(fdescr); + return; + } + +printf("Format Identifier ...................... %.4s\n", font_buffer + FH_FMVER); + +tmpufix32 = (ufix32)read_4b(font_buffer + FH_FMVER + 4); +printf("CR-LF-NULL-NULL data ............... %8.8lx %s\n", tmpufix32, (tmpufix32 != 0x0d0a0000)? "(incorrect)": " "); + +printf("Font Size .............................. %4ld\n", (ufix32)read_4b(font_buffer + FH_FNTSZ)); + +printf("Minimum Font Buffer Size ............... %4ld\n", (ufix32)read_4b(font_buffer + FH_FBFSZ)); + +printf("Minimum Character Buffer Size .......... %4d\n", (ufix16)read_2b(font_buffer + FH_CBFSZ)); + +printf("Header Size ............................ %4d\n", (ufix16)read_2b(font_buffer + FH_HEDSZ)); + +printf("Font ID ................................ %4.4d\n", (ufix16)read_2b(font_buffer + FH_FNTID)); + +printf("Font Version Number .................... %4d\n", (ufix16)read_1b(font_buffer + FH_SFVNR)); + +printf("Font Full Name:\n %.70s\n", font_buffer + FH_FNTNM); + +printf("Manufacturing Date ................ %10.10s\n", font_buffer + FH_MDATE); + +printf("Character Set Name:\n %s\n", font_buffer + FH_LAYNM); + +printf("Character Set ID: ...................... %.4s\n", font_buffer + FH_LAYNM + 66); + +printf("Copyright Notice:\n %.70s\n", font_buffer + FH_CPYRT); + +printf("Number of Char. Indexes in Char. Set ... %4d\n", (ufix16)read_2b(font_buffer + FH_NCHRL)); + +printf("Total number of Char. Indexes in Font .. %4d\n", (ufix16)read_2b(font_buffer + FH_NCHRF)); + +printf("Index of First Character ............... %4d\n", (ufix16)read_2b(font_buffer + FH_FCHRF)); + +printf("Number of Kerning Tracks ............... %4d\n", (ufix16)read_2b(font_buffer + FH_NKTKS)); + +printf("Number of Kerning Pairs ................ %4d\n", (ufix16)read_2b(font_buffer + FH_NKPRS)); + +printf("Font Flags:\n"); +tmpufix8 = read_1b(font_buffer + FH_FLAGS); +printf(" Extended font ...................... %s\n", (tmpufix8 & BIT0)? " Yes": " No"); + +printf("Classification Flags:\n"); +tmpufix8 = read_1b(font_buffer + FH_CLFGS); +printf(" Italic ............................. %s\n", (tmpufix8 & BIT0)? " Yes": " No"); +printf(" Monospace .......................... %s\n", (tmpufix8 & BIT1)? " Yes": " No"); +printf(" Serif .............................. %s\n", (tmpufix8 & BIT2)? " Yes": " No"); +printf(" Display ............................ %s\n", (tmpufix8 & BIT3)? " Yes": " No"); + +tmpufix8 = read_1b(font_buffer + FH_FAMCL); +printf("Family Classification .................. %4d ", tmpufix8); +switch (tmpufix8) + { +case 0: + printf("(Don't care)\n"); + break; +case 1: + printf("(Serif)\n"); + break; +case 2: + printf("(Sans serif)\n"); + break; +case 3: + printf("(Monospace)\n"); + break; +case 4: + printf("(Script or calligraphic)\n"); + break; +case 5: + printf("(Decorative)\n"); + break; +default: + printf("\n"); + break; + } + +printf("Font Form Classification:\n"); +tmpufix8 = read_1b(font_buffer + FH_FRMCL); +printf(" Width Type ......................... %4d ", (tmpufix8 & 0x0f)); +switch (tmpufix8 & 0x0f) + { +case 4: + printf("(Condensed)\n"); + break; +case 6: + printf("(Semi-condensed)\n"); + break; +case 8: + printf("(Normal)\n"); + break; +case 10: + printf("(Semi-expanded)\n"); + break; +case 12: + printf("(Expanded)\n"); + break; +default: + printf("\n"); + break; + } +printf(" Weight ............................. %4d ", (tmpufix8 >> 4)); +switch (tmpufix8 >> 4) + { +case 1: + printf("(Thin)\n"); + break; +case 2: + printf("(Ultralight)\n"); + break; +case 3: + printf("(Extra light)\n"); + break; +case 4: + printf("(Light)\n"); + break; +case 5: + printf("(Book)\n"); + break; +case 6: + printf("(Normal)\n"); + break; +case 7: + printf("(Medium)\n"); + break; +case 8: + printf("(Semibold)\n"); + break; +case 9: + printf("(Demibold)\n"); + break; +case 10: + printf("(Bold)\n"); + break; +case 11: + printf("(Extrabold)\n"); + break; +case 12: + printf("(Ultrabold)\n"); + break; +case 13: + printf("(Heavy)\n"); + break; +case 14: + printf("(Black)\n"); + break; +default: + printf("\n"); + break; + } + +printf("Short Font Name ........................ %.16s\n", font_buffer + FH_SFNTN); + +printf("Short Face Name ........................ %.16s\n", font_buffer + FH_SFACN); + +printf("Font Form .............................. %.14s\n", font_buffer + FH_FNTFM); + +printf("Italic Angle ........................... %7.2f\n", ((real)read_2b(font_buffer + FH_ITANG) / 256.0)); + +printf("ORUs per Em ............................ %4d\n", (ufix16)read_2b(font_buffer + FH_ORUPM)); + +printf("Width of Word Space .................... %4d\n", (ufix16)read_2b(font_buffer + FH_WDWTH)); + +printf("Width of Em Space ...................... %4d\n", (ufix16)read_2b(font_buffer + FH_EMWTH)); + +printf("Width of En Space ...................... %4d\n", (ufix16)read_2b(font_buffer + FH_ENWTH)); + +printf("Width of Thin Space .................... %4d\n", (ufix16)read_2b(font_buffer + FH_TNWTH)); + +printf("Width of Figure Space .................. %4d\n", (ufix16)read_2b(font_buffer + FH_FGWTH)); + +printf("Min X coordinate in font ............... %4d\n", (fix15)read_2b(font_buffer + FH_FXMIN)); + +printf("Min Y coordinate in font ............... %4d\n", (fix15)read_2b(font_buffer + FH_FYMIN)); + +printf("Max X coordinate in font ............... %4d\n", (fix15)read_2b(font_buffer + FH_FXMAX)); + +printf("Max Y coordinate in font ............... %4d\n", (fix15)read_2b(font_buffer + FH_FYMAX)); + +printf("Underline Position ..................... %4d\n", (fix15)read_2b(font_buffer + FH_ULPOS)); + +printf("Underline Thickness .................... %4d\n", (fix15)read_2b(font_buffer + FH_ULTHK)); + +printf("Small Caps Y position .................. %4d\n", (fix15)read_2b(font_buffer + FH_SMCTR)); +printf("Small Caps X scale ..................... %7.2f\n", ((real)read_2b(font_buffer + FH_SMCTR + 2) / 4096.0)); +printf("Small Caps Y scale ..................... %7.2f\n", ((real)(fix15)read_2b(font_buffer + FH_SMCTR + 4) / 4096.0)); + +printf("Display Superiors Y position ........... %4d\n", (fix15)read_2b(font_buffer + FH_SMCTR)); +printf("Display Superiors X scale .............. %7.2f\n", ((real)read_2b(font_buffer + FH_SMCTR + 2) / 4096.0)); +printf("Display Superiors Y scale .............. %7.2f\n", ((real)read_2b(font_buffer + FH_SMCTR + 4) / 4096.0)); + +printf("Footnote Superiors Y position .......... %4d\n", (fix15)read_2b(font_buffer + FH_FNSTR)); +printf("Footnote Superiors X scale ............. %7.2f\n", ((real)read_2b(font_buffer + FH_FNSTR + 2) / 4096.0)); +printf("Footnote Superiors Y scale ............. %7.2f\n", ((real)read_2b(font_buffer + FH_FNSTR + 4) / 4096.0)); + +printf("Alpha Superiors Y position ............. %4d\n", (fix15)read_2b(font_buffer + FH_ALSTR)); +printf("Alpha Superiors X scale ................ %7.2f\n", ((real)read_2b(font_buffer + FH_ALSTR + 2) / 4096.0)); +printf("Alpha Superiors Y scale ................ %7.2f\n", ((real)read_2b(font_buffer + FH_ALSTR + 4) / 4096.0)); + +printf("Chemical Inferiors Y position .......... %4d\n", (fix15)read_2b(font_buffer + FH_CMITR)); +printf("Chemical Inferiors X scale ............. %7.2f\n", ((real)read_2b(font_buffer + FH_CMITR + 2) / 4096.0)); +printf("Chemical Inferiors Y scale ............. %7.2f\n", ((real)read_2b(font_buffer + FH_CMITR + 4) / 4096.0)); + +printf("Small Numerators Y position ............ %4d\n", (fix15)read_2b(font_buffer + FH_SNMTR)); +printf("Small Numerators X scale ............... %7.2f\n", ((real)read_2b(font_buffer + FH_SNMTR + 2) / 4096.0)); +printf("Small Numerators Y scale ............... %7.2f\n", ((real)read_2b(font_buffer + FH_SNMTR + 4) / 4096.0)); + +printf("Small Denominators Y position .......... %4d\n", (fix15)read_2b(font_buffer + FH_SDNTR)); +printf("Small Denominators X scale ............. %7.2f\n", ((real)read_2b(font_buffer + FH_SDNTR + 2) / 4096.0)); +printf("Small Denominators Y scale ............. %7.2f\n", ((real)read_2b(font_buffer + FH_SDNTR + 4) / 4096.0)); + +printf("Medium Numerators Y position ........... %4d\n", (fix15)read_2b(font_buffer + FH_MNMTR)); +printf("Medium Numerators X scale .............. %7.2f\n", ((real)read_2b(font_buffer + FH_MNMTR + 2) / 4096.0)); +printf("Medium Numerators Y scale .............. %7.2f\n", ((real)read_2b(font_buffer + FH_MNMTR + 4) / 4096.0)); + +printf("Medium Denominators Y position ......... %4d\n", (fix15)read_2b(font_buffer + FH_MDNTR)); +printf("Medium Denominators X scale ............ %7.2f\n", ((real)read_2b(font_buffer + FH_MDNTR + 2) / 4096.0)); +printf("Medium Denominators Y scale ............ %7.2f\n", ((real)read_2b(font_buffer + FH_MDNTR + 4) / 4096.0)); + +printf("Large Numerators Y position ............ %4d\n", (fix15)read_2b(font_buffer + FH_LNMTR)); +printf("Large Numerators X scale ............... %7.2f\n", ((real)read_2b(font_buffer + FH_LNMTR + 2) / 4096.0)); +printf("Large Numerators Y scale ............... %7.2f\n", ((real)read_2b(font_buffer + FH_LNMTR + 4) / 4096.0)); + +printf("Large Denominators Y position .......... %4d\n", (fix15)read_2b(font_buffer + FH_LDNTR)); +printf("Large Denominators X scale ............. %7.2f\n", ((real)read_2b(font_buffer + FH_LDNTR + 2) / 4096.0)); +printf("Large Denominators Y scale ............. %7.2f\n", ((real)read_2b(font_buffer + FH_LDNTR + 4) / 4096.0)); + +fclose(fdescr); +} + + +FUNCTION ufix8 read_1b(pointer) +ufix8 *pointer; +/* + * Reads 1-byte field from font buffer + */ +{ +return *pointer; +} + +FUNCTION fix15 read_2b(pointer) +ufix8 *pointer; +/* + * Reads 2-byte field from font buffer + */ +{ +fix31 temp; + +temp = *pointer++; +temp = (temp << 8) + *(pointer); +return temp; +} + +FUNCTION fix31 read_4b(pointer) +ufix8 *pointer; +/* + * Reads 4-byte field from font buffer + */ +{ +fix31 temp; + +temp = *pointer++; +temp = (temp << 8) + *(pointer++); +temp = (temp << 8) + *(pointer++); +temp = (temp << 8) + *(pointer); +return temp; +} + diff --git a/nx-X11/lib/font/Speedo/iface.c b/nx-X11/lib/font/Speedo/iface.c new file mode 100644 index 000000000..1dad5ae48 --- /dev/null +++ b/nx-X11/lib/font/Speedo/iface.c @@ -0,0 +1,650 @@ +/* $Xorg: iface.c,v 1.3 2000/08/17 19:46:25 cpqbld Exp $ */ + +/* + +Copyright 1989-1991, Bitstream Inc., Cambridge, MA. +You are hereby granted permission under all Bitstream propriety rights to +use, copy, modify, sublicense, sell, and redistribute the Bitstream Speedo +software and the Bitstream Charter outline font for any purpose and without +restrictions; provided, that this notice is left intact on all copies of such +software or font and that Bitstream's trademark is acknowledged as shown below +on all unmodified copies of such font. + +BITSTREAM CHARTER is a registered trademark of Bitstream Inc. + + +BITSTREAM INC. DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING +WITHOUT LIMITATION THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE. BITSTREAM SHALL NOT BE LIABLE FOR ANY DIRECT OR INDIRECT +DAMAGES, INCLUDING BUT NOT LIMITED TO LOST PROFITS, LOST DATA, OR ANY OTHER +INCIDENTAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF OR IN ANY WAY CONNECTED +WITH THE SPEEDO SOFTWARE OR THE BITSTREAM CHARTER OUTLINE FONT. + +*/ +/* $XFree86: xc/lib/font/Speedo/iface.c,v 1.2 1998/07/25 06:56:53 dawes Exp $ */ + +/***************************** I F A C E . C ********************************* + * * + * This module provides a layer to make Speedo function calls to and * + * from it compatible with Fontware 2.X function calls. * + * * + ****************************************************************************/ + +#include "speedo.h" /* General definitions for Speedo */ +#ifndef FONTMODULE +#include <math.h> +#else +#include "xf86_ansic.h" +#endif + +#define DEBUG 0 + +#if DEBUG +#include <stdio.h> +#define SHOW(X) printf("X = %d\n", X) +#else +#define SHOW(X) +#endif + +#define PI 3.1415926536 /* pi */ +#define PTPERINCH 72.2892 /* nbr points per inch, exactly! */ + +#define BIT8 0x0100 +#define BIT9 0x0200 +#define BIT10 0x0400 +#define BIT11 0x0800 +#define BIT12 0x1000 +#define BIT13 0x2000 +#define BIT14 0x4000 +#define BIT15 0x8000 + +#define READ 0 + +typedef short bool16; +typedef int bool; + +typedef +struct + { + bool16 left; + bool16 right; + bool16 top; + bool16 bottom; + } lrtb; + + +typedef +struct + { + buff_t *pfont; /* Pointer to font data */ + ufix16 mode; /* what mode is the font generator in */ + real point_size_x; /* Point size in X dimension */ + real point_size_y; /* Point size in Y dimension */ + real res_hor; /* Horizontal resolution of output device */ + real res_ver; /* Vertical resolution of output device */ + real rot_angle; /* Rotation angle in degrees (clockwise) */ + real obl_angle; /* Obliquing angle in degrees (clockwise) */ + bool16 whitewrite; /* if T, generate bitmaps for whitewriters */ + fix15 thresh; /* Scan conversion threshold * + * Thickens characters on each edge by * + * <thresh> sub-pixels */ + bool16 import_widths; /* Use imported width table */ + lrtb clip; /* Clip to standard character cell */ + lrtb squeeze; /* Squeeze to standard character cell */ + bool16 bogus_mode; /* if T, ignore plaid data */ + } comp_char_desc; /* character attributes for scan conv */ + +/***** GLOBAL VARIABLES *****/ + +/***** GLOBAL FUNCTIONS *****/ + fw_reset(); /* Fontware 2.X reset call */ + fw_set_specs(); /* Fontware 2.X set specs call */ +bool fw_make_char(); /* Fontware 2.X make character call */ + +/***** EXTERNAL VARIABLES *****/ + +/***** EXTERNAL FUNCTIONS *****/ +void _open_bitmap(); +void _close_bitmap(); +void _set_bitmap_bits(); +void _open_outline(); +void _open_outline(); +void _start_new_char(); +void _start_curve(); +void _line_to(); +void _close_curve(); +void _close_outline(); + +/***** STATIC VARIABLES *****/ +static specs_t *pspecs; +static buff_t *pfont; +static buff_t char_data; +static fix15 set_width_x; +static specs_t specsarg; + +/***** STATIC FUNCTIONS *****/ +static fix31 make_mult(); + + +FUNCTION fw_reset() +{ +sp_reset(); +} + +FUNCTION fw_set_specs(pspecs) +comp_char_desc *pspecs; /* Pointer to scan conversion parameters structure */ + +/* Fontware 2.X character generator call to set font specifications + * compc -- pointer to structure containing scan conversion parameters. + * ->compf -- compressed font data structure + * ->point_size_x -- x pointsize + * ->point_size_y -- y pointsize + * ->res_hor -- horizontal pixels per inch + * ->res_ver -- vertical pixels per inch + * ->rot_angle -- rotation angle in degrees (clockwise) + * ->obl_angle -- obliquing angle in degrees (clockwise) + * ->whitewrite -- if true, generate bitmaps for whitewriters + * ->thresh -- scan-conversion threshold + * ->import_widths -- if true, use external width table + * ->clip.left -- clips min x at left of emsquare + * ->clip.right -- clips max x at right of emsquare + * ->clip.bottom -- clips min x at bottom of emsquare + * ->clip.top -- clips max x at top of emsquare + * ->squeeze.left -- squeezes min x at left of emsquare + * ->squeeze.right, .top, .bottom &c + * ->sw_fixed -- if TRUE, match pixel widths to scaled outline widths + * ->bogus_mode -- ignore plaid data if TRUE + */ + +{ +fix15 irot; +fix15 iobl; +fix15 x_trans_type; +fix15 y_trans_type; +fix31 xx_mult; +fix31 xy_mult; +fix31 yx_mult; +fix31 yy_mult; +real sinrot, cosrot, tanobl; +real x_distortion; +real pixperem_h; +real pixperem_v; +real point_size_x; +real point_size_y; +real res_hor; +real res_ver; +fix15 mode; + +specsarg.pfont = pspecs->pfont; + +irot = floor(pspecs->rot_angle + 0.5); +iobl = floor(pspecs->obl_angle + 0.5); +if (iobl > 85) + iobl = 85; +if (iobl < -85) + iobl = -85; +if ((irot % 90) == 0) + { + x_trans_type = y_trans_type = irot / 90 & 0x0003; + if (iobl != 0) + { + if (x_trans_type & 0x01) + y_trans_type = 4; + else + x_trans_type = 4; + } + } +else if (((irot + iobl) % 90) == 0) + { + x_trans_type = y_trans_type = (irot + iobl) / 90 & 0x0003; + if (iobl != 0) + { + if (x_trans_type & 0x01) + x_trans_type = 4; + else + y_trans_type = 4; + } + } +else + { + x_trans_type = y_trans_type = 4; + } + +point_size_x = pspecs->point_size_x; +point_size_y = pspecs->point_size_y; +res_hor = pspecs->res_hor; +res_ver = pspecs->res_ver; + +switch (x_trans_type) + { +case 0: + xx_mult = make_mult(point_size_x, res_hor); + xy_mult = 0; + break; + +case 1: + xx_mult = 0; + xy_mult = make_mult(point_size_y, res_hor); + break; + +case 2: + xx_mult = -make_mult(point_size_x, res_hor); + xy_mult = 0; + break; + +case 3: + xx_mult = 0; + xy_mult = -make_mult(point_size_y, res_hor); + break; + +default: + sinrot = sin((real)irot * PI / 180.); + cosrot = cos((real)irot * PI / 180.); + tanobl = tan((real)iobl * PI / 180.); + x_distortion = point_size_x / point_size_y; + pixperem_h = point_size_y * res_hor / (real)PTPERINCH; /* this is NOT a bug */ + xx_mult = floor(cosrot * x_distortion * pixperem_h * 65536.0 + 0.5); + xy_mult = floor((sinrot + cosrot * tanobl) * pixperem_h * 65536.0 + 0.5); + break; + } + +switch (y_trans_type) + { +case 0: + yx_mult = 0; + yy_mult = make_mult(point_size_y, res_ver); + break; + +case 1: + yx_mult = -make_mult(point_size_x, res_hor); + yy_mult = 0; + break; + +case 2: + yx_mult = 0; + yy_mult = -make_mult(point_size_y, res_ver); + break; + +case 3: + yx_mult = make_mult(point_size_x, res_ver); + yy_mult = 0; + break; + +default: + sinrot = sin((real)irot * PI / 180.); + cosrot = cos((real)irot * PI / 180.); + tanobl = tan((real)iobl * PI / 180.); + x_distortion = point_size_x / point_size_y; + pixperem_v = point_size_y * res_ver / (real)PTPERINCH; + yx_mult = floor(-sinrot * x_distortion * pixperem_v * 65536.0 + 0.5); + yy_mult = floor((cosrot - sinrot * tanobl) * pixperem_v * 65536.0 + 0.5); + break; + } + +specsarg.xxmult = xx_mult; +specsarg.xymult = xy_mult; +specsarg.xoffset = 0; +specsarg.yxmult = yx_mult; +specsarg.yymult = yy_mult; +specsarg.yoffset = 0; +specsarg.out_info = 0; + +/* Select processing mode */ +switch (pspecs->mode) + { +case 1: + if (pspecs->whitewrite) /* White-write requested? */ + { + mode = 1; + } + else + { + mode = 0; + } + break; + +case 2: + mode = 2; + break; + +default: + mode = pspecs->mode; + break; + } + +if (pspecs->bogus_mode) /* Linear transformation requested? */ + { + mode |= BIT4; /* Set linear tranformation flag */ + } + +if (pspecs->import_widths) /* Imported widths requested? */ + { + mode |= BIT6; /* Set imported width flag */ + } + +if (pspecs->clip.left) /* Clip left requested? */ + { + mode |= BIT8; /* Set clip left flag */ + } + +if (pspecs->clip.right) /* Clip right requested? */ + { + mode |= BIT9; /* Set clip right flag */ + } + +if (pspecs->clip.top) /* Clip top requested? */ + { + mode |= BIT10; /* Set clip top flag */ + } + +if (pspecs->clip.bottom) /* Clip bottom requested? */ + { + mode |= BIT11; /* Set clip bottom flag */ + } + +if (pspecs->squeeze.left) /* Squeeze left requested? */ + { + mode |= BIT12; /* Set squeeze left flag */ + } + +if (pspecs->squeeze.right) /* Squeeze right requested? */ + { + mode |= BIT13; /* Set squeeze right flag */ + } + +if (pspecs->squeeze.top) /* Squeeze top requested? */ + { + mode |= BIT14; /* Set squeeze top flag */ + } + +if (pspecs->squeeze.bottom) /* Squeeze bottom requested? */ + { + mode |= BIT15; /* Set squeeze bottom flag */ + } + +specsarg.flags = mode; + +sp_set_specs(&specsarg); +} + +FUNCTION static fix31 make_mult(point_size, resolution) +real point_size; +real resolution; +{ +real ms_factor; + +return (fix31)floor((point_size * resolution * 65536.0) / (real)PTPERINCH + 0.5); +} + +FUNCTION bool fw_make_char(char_index) +ufix16 char_index; +{ +return sp_make_char(char_index); +} + +FUNCTION buff_t *sp_load_char_data(file_offset, no_bytes, cb_offset) +fix31 file_offset; +fix15 no_bytes; +fix15 cb_offset; +/* + * Called by Speedo character generator to request that character + * data be loaded from the font file. + * This is a dummy function that assumes that the entire font has + * been loaded. + */ +{ +#if DEBUG +printf("load_char_data(%d, %d, %d)\n", file_offset, no_bytes, char_offset); +#endif +char_data.org = pfont->org + file_offset; +char_data.no_bytes = no_bytes; +return &char_data; +} + +FUNCTION void sp_report_error(n) +fix15 n; /* Error identification number */ +/* + * Called by Speedo character generator to report an error. + */ +{ +switch(n) + { +case 1: + printf("Insufficient font data loaded\n"); + break; + +case 3: + printf("Transformation matrix out of range\n"); + break; + +case 4: + printf("Font format error\n"); + break; + +case 5: + printf("Requested specs not compatible with output module\n"); + break; + +case 7: + printf("Intelligent transformation requested but not supported\n"); + break; + +case 8: + printf("Unsupported output mode requested\n"); + break; + +case 9: + printf("Extended font loaded but only compact fonts supported\n"); + break; + +case 10: + printf("Font specs not set prior to use of font\n"); + break; + +case 12: + printf("Character data not available()\n"); + break; + +case 13: + printf("Track kerning data not available()\n"); + break; + +case 14: + printf("Pair kerning data not available()\n"); + break; + +default: + printf("report_error(%d)\n", n); + break; + } +} + + + +FUNCTION void sp_open_bitmap(sw_x, sw_y, xorg, yorg, xsize, ysize) +fix31 sw_x; /* X component of escapement vector */ +fix31 sw_y; /* Y component of escapement vector */ +fix31 xorg; /* X origin */ +fix31 yorg; /* Y origin */ +fix15 xsize; /* width of bitmap */ +fix15 ysize; /* height of bitmap */ +/* + * Called by Speedo character generator to initialize a buffer prior + * to receiving bitmap data. + */ +{ + +fix15 xmin,xmax,ymin,ymax; + +#if DEBUG +printf("sp_open_bitmap:\n"); +printf(" X component of set width vector = %3.1f\n", (real)sw_x / 65536.0); +printf(" Y component of set width vector = %3.1f\n", (real)sw_y / 65536.0); +printf(" Bounding box is (%d, %d, %d, %d)\n", xmin, ymin, xmax, ymax); +#endif + +xmin = xorg >> 16; +ymin = yorg >> 16; +xmax = xmin + xsize; +ymax = ymin + ysize; + +set_width_x = ((sw_x >> 15) + 1) >> 1; +open_bitmap(set_width_x, xmin, xmax, ymin, ymax); +} + +FUNCTION void sp_set_bitmap_bits(y, x1, x2) +fix15 y, x1, x2; +/* + * Called by Speedo character generator to write one row of pixels + * into the generated bitmap character. + */ +{ +#if DEBUG +printf("set_bitmap_bits(%d, %d, %d)\n", y, x1, x2); +#endif + +set_bitmap_bits(y, x1, x2); +} + +FUNCTION void sp_close_bitmap() +/* + * Called by Speedo character generator to indicate all bitmap data + * has been generated. + */ +{ +#if DEBUG +printf("close_bitmap()\n"); +#endif + +close_bitmap(); +} + +FUNCTION void sp_open_outline(sw_x, sw_y, xmin, xmax, ymin, ymax) +fix31 sw_x; /* X component of escapement vector */ +fix31 sw_y; /* Y component of escapement vector */ +fix31 xmin; /* Minimum X value in outline */ +fix31 xmax; /* Maximum X value in outline */ +fix31 ymin; /* Minimum Y value in outline */ +fix31 ymax; /* Maximum Y value in outline */ +/* + * Called by Speedo character generator to initialize prior to + * outputting scaled outline data. + */ +{ +#if DEBUG +printf("open_outline(%3.1f, %3.1f, %3.1f, %3.1f, %3.1f, %3.1f)\n", + (real)sw_x / 65536.0, (real)sw_y / 65536.0, + (real)xmin / 65536.0, (real)xmax / 65536.0, (real)ymin / 65536.0, (real)ymax / 65536.0); +#endif + +set_width_x = ((sw_x >> 15) + 1) >> 1; +open_outline(set_width_x); +} + +FUNCTION void sp_start_new_char() +/* + * Called by Speedo character generator to initialize prior to + * outputting scaled outline data for a sub-character in a compound + * character. + */ +{ +#if DEBUG +printf("start_new_char()\n"); +#endif + +start_new_char(); +} + +FUNCTION void sp_start_contour(x, y, outside) +fix31 x; /* X coordinate of start point in 1/65536 pixels */ +fix31 y; /* Y coordinate of start point in 1/65536 pixels */ +boolean outside; /* TRUE if curve encloses ink (Counter-clockwise) */ +/* + * Called by Speedo character generator at the start of each contour + * in the outline data of the character. + */ +{ +real realx, realy; + +realx = (real)x / 65536.0; +realy = (real)y / 65536.0; + +#if DEBUG +printf("start_curve(%3.1f, %3.1f, %s)\n", + realx, realy, + outside? "outside": "inside"); +#endif + +start_curve(realx, realy, outside); +} + +FUNCTION void sp_curve_to(x1, y1, x2, y2, x3, y3) +fix31 x1; /* X coordinate of first control point in 1/65536 pixels */ +fix31 y1; /* Y coordinate of first control point in 1/65536 pixels */ +fix31 x2; /* X coordinate of second control point in 1/65536 pixels */ +fix31 y2; /* Y coordinate of second control point in 1/65536 pixels */ +fix31 x3; /* X coordinate of curve end point in 1/65536 pixels */ +fix31 y3; /* Y coordinate of curve end point in 1/65536 pixels */ +/* + * Called by Speedo character generator once for each curve in the + * scaled outline data of the character. This function is only called if curve + * output is enabled in the set_specs() call. + */ +{ +#if DEBUG +printf("curve_to(%3.1f, %3.1f, %3.1f, %3.1f, %3.1f, %3.1f)\n", + (real)x1 / 65536.0, (real)y1 / 65536.0, + (real)x2 / 65536.0, (real)y2 / 65536.0, + (real)x3 / 65536.0, (real)y3 / 65536.0); +#endif +} + +FUNCTION void sp_line_to(x, y) +fix31 x; /* X coordinate of vector end point in 1/65536 pixels */ +fix31 y; /* Y coordinate of vector end point in 1/65536 pixels */ +/* + * Called by Speedo character generator onece for each vector in the + * scaled outline data for the character. This include curve data that has + * been sub-divided into vectors if curve output has not been enabled + * in the set_specs() call. + */ +{ +real realx, realy; + +realx = (real)x / 65536.0; +realy = (real)y / 65536.0; + +#if DEBUG +printf("line_to(%3.1f, %3.1f)\n", + realx, realy); +#endif + +line_to(realx, realy); +} + +FUNCTION void sp_close_contour() +/* + * Called by Speedo character generator at the end of each contour + * in the outline data of the character. + */ +{ +#if DEBUG +printf("close_curve()\n"); +#endif + +close_curve(); +} + +FUNCTION void sp_close_outline() +/* + * Called by Speedo character generator at the end of output of the + * scaled outline of the character. + */ +{ +#if DEBUG +printf("close_outline()\n"); +#endif + +close_outline(set_width_x); +} + diff --git a/nx-X11/lib/font/Speedo/keys.h b/nx-X11/lib/font/Speedo/keys.h new file mode 100644 index 000000000..dd9d0bff7 --- /dev/null +++ b/nx-X11/lib/font/Speedo/keys.h @@ -0,0 +1,56 @@ +/* $Xorg: keys.h,v 1.3 2000/08/17 19:46:25 cpqbld Exp $ */ + +/* + +Copyright 1989-1991, Bitstream Inc., Cambridge, MA. +You are hereby granted permission under all Bitstream propriety rights to +use, copy, modify, sublicense, sell, and redistribute the Bitstream Speedo +software and the Bitstream Charter outline font for any purpose and without +restrictions; provided, that this notice is left intact on all copies of such +software or font and that Bitstream's trademark is acknowledged as shown below +on all unmodified copies of such font. + +BITSTREAM CHARTER is a registered trademark of Bitstream Inc. + + +BITSTREAM INC. DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING +WITHOUT LIMITATION THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE. BITSTREAM SHALL NOT BE LIABLE FOR ANY DIRECT OR INDIRECT +DAMAGES, INCLUDING BUT NOT LIMITED TO LOST PROFITS, LOST DATA, OR ANY OTHER +INCIDENTAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF OR IN ANY WAY CONNECTED +WITH THE SPEEDO SOFTWARE OR THE BITSTREAM CHARTER OUTLINE FONT. + +*/ + + +/***** DECRYPTION KEY CONSTANTS (PC Platform) *****/ + +#define CUS0 432 /* Customer number */ + +#define KEY0 0 /* Decryption key 0 */ +#define KEY1 72 /* Decryption key 1 */ +#define KEY2 123 /* Decryption key 2 */ +#define KEY3 1 /* Decryption key 3 */ +#define KEY4 222 /* Decryption key 4 */ +#define KEY5 194 /* Decryption key 5 */ +#define KEY6 113 /* Decryption key 6 */ +#define KEY7 119 /* Decryption key 7 */ +#define KEY8 52 /* Decryption key 8 */ + +/***** DECRYPTION KEY CONSTANTS (Sample) *****/ + +#define XSAMPLEFONTS + +#define XCUS0 0 /* Customer number */ + +#define XKEY0 0 /* Decryption key 0 */ +#define XKEY1 0 /* Decryption key 1 */ +#define XKEY2 0 /* Decryption key 2 */ +#define XKEY3 0 /* Decryption key 3 */ +#define XKEY4 0 /* Decryption key 4 */ +#define XKEY5 0 /* Decryption key 5 */ +#define XKEY6 0 /* Decryption key 6 */ +#define XKEY7 0 /* Decryption key 7 */ +#define XKEY8 0 /* Decryption key 8 */ + + diff --git a/nx-X11/lib/font/Speedo/module/Imakefile b/nx-X11/lib/font/Speedo/module/Imakefile new file mode 100644 index 000000000..e517707c5 --- /dev/null +++ b/nx-X11/lib/font/Speedo/module/Imakefile @@ -0,0 +1,47 @@ +XCOMM $XFree86: xc/lib/font/Speedo/module/Imakefile,v 1.5 1999/08/14 10:49:18 dawes Exp $ + +#define IHaveModules +#include <Server.tmpl> + + INCLUDES = -I$(FONTINCSRC) -I../../include -I$(SERVERSRC)/include \ + -I$(XINCLUDESRC) -I../ + HEADERS = + DEFINES = -DFONTMODULE + + SPEEDOSRCS = do_char.c do_trns.c out_bl2d.c out_blk.c speedomod.c \ + out_scrn.c out_util.c reset.c set_spcs.c set_trns.c + SPEEDOOBJS = do_char.o do_trns.o out_bl2d.o out_blk.o speedomod.o \ + out_scrn.o out_util.o reset.o set_spcs.o set_trns.o + + SRCS = spfuncs.c spfile.c spinfo.c sperr.c spfont.c spglyph.c \ + spencode.c bics-unicode.c \ + $(SPEEDOSRCS) + OBJS = spfuncs.o spfile.o spinfo.o sperr.o spfont.o spglyph.o \ + spencode.o bics-unicode.o \ + $(SPEEDOOBJS) + +LinkSourceFile(bics-unicode.c,..) +LinkSourceFile(do_char.c,..) +LinkSourceFile(do_trns.c,..) +LinkSourceFile(out_bl2d.c,..) +LinkSourceFile(out_blk.c,..) +LinkSourceFile(out_scrn.c,..) +LinkSourceFile(out_util.c,..) +LinkSourceFile(reset.c,..) +LinkSourceFile(set_spcs.c,..) +LinkSourceFile(set_trns.c,..) +LinkSourceFile(spfuncs.c,..) +LinkSourceFile(spfile.c,..) +LinkSourceFile(spinfo.c,..) +LinkSourceFile(sperr.c,..) +LinkSourceFile(spfont.c,..) +LinkSourceFile(spglyph.c,..) +LinkSourceFile(spencode.c,..) + +ModuleObjectRule() +LibraryModuleTarget(speedo,$(OBJS)) +InstallLibraryModule(speedo,$(MODULEDIR),fonts) + +DependTarget() + +InstallDriverSDKLibraryModule(speedo,$(DRIVERSDKMODULEDIR),fonts) diff --git a/nx-X11/lib/font/Speedo/module/speedomod.c b/nx-X11/lib/font/Speedo/module/speedomod.c new file mode 100644 index 000000000..94820fe44 --- /dev/null +++ b/nx-X11/lib/font/Speedo/module/speedomod.c @@ -0,0 +1,72 @@ +/* + * Copyright (C) 1998 The XFree86 Project, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of the XFree86 Project shall + * not be used in advertising or otherwise to promote the sale, use or other + * dealings in this Software without prior written authorization from the + * XFree86 Project. + */ +/* $XFree86: xc/lib/font/Speedo/module/speedomod.c,v 1.8 2001/09/04 13:49:16 dawes Exp $ */ + +#include "misc.h" + +#include <X11/fonts/fontmod.h> +#include "xf86Module.h" + +static MODULESETUPPROTO(speedoSetup); + + /* + * This is the module data function that is accessed when loading + * libspeedo as a module. + */ + +static XF86ModuleVersionInfo VersRec = +{ + "speedo", + MODULEVENDORSTRING, + MODINFOSTRING1, + MODINFOSTRING2, + XORG_VERSION_CURRENT, + 1, 0, 1, + ABI_CLASS_FONT, /* A font module */ + ABI_FONT_VERSION, + MOD_CLASS_FONT, + {0,0,0,0} /* signature, to be patched into the file by a tool */ +}; + +XF86ModuleData speedoModuleData = { &VersRec, speedoSetup, NULL }; + +extern void SpeedoRegisterFontFileFunctions(void); + +FontModule speedoModule = { + SpeedoRegisterFontFileFunctions, + "Speedo", + NULL +}; + +static pointer +speedoSetup(pointer module, pointer opts, int *errmaj, int *errmin) +{ + speedoModule.module = module; + LoadFont(&speedoModule); + + /* Need a non-NULL return */ + return (pointer)1; +} diff --git a/nx-X11/lib/font/Speedo/nsample.c b/nx-X11/lib/font/Speedo/nsample.c new file mode 100644 index 000000000..a90367f0a --- /dev/null +++ b/nx-X11/lib/font/Speedo/nsample.c @@ -0,0 +1,745 @@ +/* $Xorg: nsample.c,v 1.3 2000/08/17 19:46:26 cpqbld Exp $ */ + +/* + +Copyright 1989-1991, Bitstream Inc., Cambridge, MA. +You are hereby granted permission under all Bitstream propriety rights to +use, copy, modify, sublicense, sell, and redistribute the Bitstream Speedo +software and the Bitstream Charter outline font for any purpose and without +restrictions; provided, that this notice is left intact on all copies of such +software or font and that Bitstream's trademark is acknowledged as shown below +on all unmodified copies of such font. + +BITSTREAM CHARTER is a registered trademark of Bitstream Inc. + + +BITSTREAM INC. DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING +WITHOUT LIMITATION THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE. BITSTREAM SHALL NOT BE LIABLE FOR ANY DIRECT OR INDIRECT +DAMAGES, INCLUDING BUT NOT LIMITED TO LOST PROFITS, LOST DATA, OR ANY OTHER +INCIDENTAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF OR IN ANY WAY CONNECTED +WITH THE SPEEDO SOFTWARE OR THE BITSTREAM CHARTER OUTLINE FONT. + +*/ + + +/*************************** N S A M P L E . C ******************************* + * * + * SPEEDO CHARACTER GENERATOR TEST MODULE * + * * + * This is an illustration of what external resources are required to * + * load a Speedo outline and use the Speedo character generator to generate * + * bitmaps or scaled outlines according to the desired specification. * * + * * + * This program loads a Speedo outline, defines a set of character * + * generation specifications, generates bitmap (or outline) data for each * + * character in the font and prints them on the standard output. * + * * + * If the font buffer is too small to hold the entire font, the first * + * part of the font is loaded. Character data is then loaded dynamically * + * as required. * + * * + ****************************************************************************/ + +#include <stdio.h> +#if PROTOS_AVAIL +#include <stddef.h> +#include <malloc.h> +#include <stdlib.h> +void main(int argc,char *argv[]); +#else +void* malloc(); +#endif + +#include "speedo.h" /* General definition for make_bmap */ +#include "keys.h" /* Font decryption keys */ + +#define DEBUG 0 + +#if DEBUG +#define SHOW(X) printf("X = %d\n", X) +#else +#define SHOW(X) +#endif + +#define MAX_BITS 256 /* Max line length of generated bitmap */ + +/***** GLOBAL FUNCTIONS *****/ + +/***** EXTERNAL FUNCTIONS *****/ + +/***** STATIC FUNCTIONS *****/ + +#if PROTOS_AVAIL +fix31 read_4b(ufix8 FONTFAR *ptr); +fix15 read_2b(ufix8 FONTFAR *ptr); +#else +fix31 read_4b(); +fix15 read_2b(); +#endif +/***** STATIC VARIABLES *****/ +static char pathname[100]; /* Name of font file to be output */ +static ufix8 FONTFAR *font_buffer; /* Pointer to allocated Font buffer */ +static ufix8 FONTFAR *char_buffer; /* Pointer to allocate Character buffer */ +static buff_t font; /* Buffer descriptor for font data */ +#if INCL_LCD +static buff_t char_data; /* Buffer descriptor for character data */ +#endif +static FILE *fdescr; /* Speedo outline file descriptor */ +static ufix16 char_index; /* Index of character to be generated */ +static ufix16 char_id; /* Character ID */ +static ufix16 minchrsz; /* minimum character buffer size */ + +static ufix8 key[] = + { + KEY0, + KEY1, + KEY2, + KEY3, + KEY4, + KEY5, + KEY6, + KEY7, + KEY8 + }; /* Font decryption key */ + +static fix15 raswid; /* raster width */ +static fix15 rashgt; /* raster height */ +static fix15 offhor; /* horizontal offset from left edge of emsquare */ +static fix15 offver; /* vertical offset from baseline */ +static fix15 set_width; /* character set width */ +static fix15 y_cur; /* Current y value being generated and printed */ +static char line_of_bits[2 * MAX_BITS + 1]; /* Buffer for row of generated bits */ + +#if INCL_MULTIDEV +#if INCL_BLACK || INCL_SCREEN || INCL_2D +bitmap_t bfuncs = { sp_open_bitmap, sp_set_bitmap_bits, sp_close_bitmap }; +#endif +#if INCL_OUTLINE +outline_t ofuncs = { sp_open_outline, sp_start_new_char, sp_start_contour, sp_curve_to, + sp_line_to, sp_close_contour, sp_close_outline }; +#endif +#endif + + +ufix8 temp[16]; /* temp buffer for first 16 bytes of font */ + + +FUNCTION void main(argc,argv) +int argc; +char *argv[]; +{ +ufix16 bytes_read; /* Number of bytes read from font file */ +specs_t specs; /* Bundle of character generation specs */ +int first_char_index; /* Index of first character in font */ +int no_layout_chars; /* number of characters in layout */ +ufix32 i; +ufix32 minbufsz; /* minimum font buffer size to allocate */ +ufix16 cust_no; +ufix8 FONTFAR *byte_ptr; + +#if REENTRANT_ALLOC +SPEEDO_GLOBALS* sp_global_ptr; +#endif + + +if (argc != 2) + { + fprintf(stderr,"Usage: nsample {fontfile}\n\n"); + exit (1); + } + +sprintf(pathname, argv[1]); + +/* Load Speedo outline file */ +fdescr = fopen (pathname, "rb"); +if (fdescr == NULL) + { + printf("****** Cannot open file %s\n", pathname); + return; + } + +/* get minimum font buffer size - read first 16 bytes to get the minimum + size field from the header, then allocate buffer dynamically */ + +bytes_read = fread(temp, sizeof(ufix8), 16, fdescr); + +if (bytes_read != 16) + { + printf("****** Error on reading %s: %x\n", pathname, bytes_read); + fclose(fdescr); + return; + } +#if INCL_LCD +minbufsz = (ufix32)read_4b(temp+FH_FBFSZ); +#else +minbufsz = (ufix32)read_4b(temp+FH_FNTSZ); +if (minbufsz >= 0x10000) + { + printf("****** Cannot process fonts greater than 64K - use dynamic character loading configuration option\n"); + fclose(fdescr); + return; + } +#endif + +#if (defined(M_I86SM) || defined(M_I86MM)) +font_buffer = (ufix8 FONTFAR *)_fmalloc((ufix16)minbufsz); +#else +font_buffer = (ufix8 *)malloc((ufix16)minbufsz); +#endif + +if (font_buffer == NULL) + { + printf("****** Unable to allocate memory for font buffer\n"); + fclose(fdescr); + return; + } + +#if DEBUG +printf("Loading font file %s\n", pathname); +#endif + +fseek(fdescr, (ufix32)0, 0); +#if (defined(M_I86SM) || (defined(M_I86MM))) +byte_ptr = font_buffer; +for (i=0; i< minbufsz; i++){ + int ch; + ch = getc(fdescr); + if (ch == EOF) + {printf ("Premature EOF in reading font buffer, %ld bytes read\n",i); + exit(2);} + *byte_ptr=(ufix8)ch; + byte_ptr++; + } +bytes_read = i; +#else +bytes_read = fread((ufix8 *)font_buffer, sizeof(ufix8), (ufix16)minbufsz, fdescr); +if (bytes_read == 0) + { + printf("****** Error on reading %s: %x\n", pathname, bytes_read); + fclose(fdescr); + return; + } +#endif + +#if INCL_LCD +/* now allocate minimum character buffer */ + +minchrsz = read_2b(font_buffer+FH_CBFSZ); +#if (defined(M_I86SM) || (defined(M_I86MM))) +char_buffer = (ufix8 FONTFAR *)_fmalloc(minchrsz); +#else +char_buffer = (ufix8*)malloc(minchrsz); +#endif + +if (char_buffer == NULL) + { + printf("****** Unable to allocate memory for character buffer\n"); + fclose(fdescr); + return; + } +#endif + +#if DYNAMIC_ALLOC || REENTRANT_ALLOC + sp_global_ptr = (SPEEDO_GLOBALS *)malloc(sizeof(SPEEDO_GLOBALS)); + memset(sp_global_ptr,(ufix8)0,sizeof(SPEEDO_GLOBALS)); +#endif + + +/* Initialization */ +#if REENTRANT_ALLOC +sp_reset(sp_global_ptr); /* Reset Speedo character generator */ +#else +sp_reset(); /* Reset Speedo character generator */ +#endif + +font.org = font_buffer; +font.no_bytes = bytes_read; + +#if REENTRANT_ALLOC +if ((cust_no=sp_get_cust_no(sp_global_ptr,font)) != CUS0 && /* NOT STANDARD ENCRYPTION */ +#else +if ((cust_no=sp_get_cust_no(font)) != CUS0 && /* NOT STANDARD ENCRYPTION */ +#endif + cust_no != 0) + { +#if REENTRANT_ALLOC + printf("Unable to use fonts for customer number %d\n", + sp_get_cust_no(sp_global_ptr(font))); +#else + printf("Unable to use fonts for customer number %d\n", + sp_get_cust_no(font)); +#endif + fclose(fdescr); + return; + } + +#if INCL_KEYS +#if REENTRANT_ALLOC +sp_set_key(sp_global_ptr,key); /* Set decryption key */ +#else +sp_set_key(key); /* Set decryption key */ +#endif +#endif + +#if INCL_MULTIDEV +#if INCL_BLACK || INCL_SCREEN || INCL_2D +#if REENTRANT_ALLOC +sp_set_bitmap_device(sp_global_ptr,&bfuncs,sizeof(bfuncs)); /* Set decryption key */ +#else +sp_set_bitmap_device(&bfuncs,sizeof(bfuncs)); /* Set decryption key */ +#endif +#endif +#if INCL_OUTLINE +#if REENTRANT_ALLOC +sp_set_outline_device(sp_global_ptr,&ofuncs,sizeof(ofuncs)); /* Set decryption key */ +#else +sp_set_outline_device(&ofuncs,sizeof(ofuncs)); /* Set decryption key */ +#endif +#endif +#endif + +first_char_index = read_2b(font_buffer + FH_FCHRF); +no_layout_chars = read_2b(font_buffer + FH_NCHRL); + +/* Set specifications for character to be generated */ +specs.pfont = &font; /* Pointer to Speedo outline structure */ +specs.xxmult = 25L << 16; /* Coeff of X to calculate X pixels */ +specs.xymult = 0L << 16; /* Coeff of Y to calculate X pixels */ +specs.xoffset = 0L << 16; /* Position of X origin */ +specs.yxmult = 0L << 16; /* Coeff of X to calculate Y pixels */ +specs.yymult = 25L << 16; /* Coeff of Y to calculate Y pixels */ +specs.yoffset = 0L << 16; /* Position of Y origin */ +specs.flags = 0; /* Mode flags */ +specs.out_info = NULL; + + +#if REENTRANT_ALLOC +if (!sp_set_specs(sp_global_ptr,&specs)) /* Set character generation specifications */ +#else +if (!sp_set_specs(&specs)) /* Set character generation specifications */ +#endif + { + printf("****** Cannot set requested specs\n"); + } +else + { + for (i = 0; i < no_layout_chars; i++) /* For each character in font */ + { + char_index = i + first_char_index; +#if REENTRANT_ALLOC + char_id = sp_get_char_id(sp_global_ptr,char_index); +#else + char_id = sp_get_char_id(char_index); +#endif + if (char_id != 0) + { +#if REENTRANT_ALLOC + if (!sp_make_char(sp_global_ptr,char_index)) +#else + if (!sp_make_char(char_index)) +#endif + { + printf("****** Cannot generate character %d\n", char_index); + } + } + } + } + +fclose(fdescr); +} + +#if INCL_LCD +#if REENTRANT_ALLOC +FUNCTION buff_t *sp_load_char_data(sp_global_ptr, file_offset, no_bytes, cb_offset) +SPEEDO_GLOBALS *sp_global_ptr; +#else +FUNCTION buff_t *sp_load_char_data(file_offset, no_bytes, cb_offset) +#endif +fix31 file_offset; /* Offset in bytes from the start of the font file */ +fix15 no_bytes; /* Number of bytes to be loaded */ +fix15 cb_offset; /* Offset in bytes from start of char buffer */ +/* + * Called by Speedo character generator to request that character + * data be loaded from the font file into a character data buffer. + * The character buffer offset is zero for all characters except elements + * of compound characters. If a single buffer is allocated for character + * data, cb_offset ensures that sub-character data is loaded after the + * top-level compound character. + * Returns a pointer to a buffer descriptor. + */ +{ +int bytes_read; + +#if DEBUG +printf("\nCharacter data(%d, %d, %d) requested\n", file_offset, no_bytes, cb_offset); +#endif +if (fseek(fdescr, (long)file_offset, (int)0) != 0) + { + printf("****** Error in seeking character\n"); + fclose(fdescr); + exit(1); + } + +if ((no_bytes + cb_offset) > minchrsz) + { + printf("****** Character buffer overflow\n"); + fclose(fdescr); + exit(3); + } + +bytes_read = fread((char_buffer + cb_offset), sizeof(ufix8), no_bytes, fdescr); +if (bytes_read != no_bytes) + { + printf("****** Error on reading character data\n"); + fclose(fdescr); + exit(2); + } + +#if DEBUG +printf("Character data loaded\n"); +#endif + +char_data.org = (ufix8 FONTFAR *)char_buffer + cb_offset; +char_data.no_bytes = no_bytes; +return &char_data; +} +#endif + + +#if REENTRANT_ALLOC +FUNCTION void sp_report_error(sp_global_ptr,n) +SPEEDO_GLOBALS *sp_global_ptr; +#else +FUNCTION void sp_report_error(n) +#endif +fix15 n; /* Error identification number */ +/* + * Called by Speedo character generator to report an error. + * + * Since character data not available is one of those errors + * that happens many times, don't report it to user + */ +{ + +switch(n) + { +case 1: + printf("Insufficient font data loaded\n"); + break; + +case 3: + printf("Transformation matrix out of range\n"); + break; + +case 4: + printf("Font format error\n"); + break; + +case 5: + printf("Requested specs not compatible with output module\n"); + break; + +case 7: + printf("Intelligent transformation requested but not supported\n"); + break; + +case 8: + printf("Unsupported output mode requested\n"); + break; + +case 9: + printf("Extended font loaded but only compact fonts supported\n"); + break; + +case 10: + printf("Font specs not set prior to use of font\n"); + break; + +case 12: + break; + +case 13: + printf("Track kerning data not available()\n"); + break; + +case 14: + printf("Pair kerning data not available()\n"); + break; + +default: + printf("report_error(%d)\n", n); + break; + } +} + +#if REENTRANT_ALLOC +FUNCTION void sp_open_bitmap(sp_global_ptr, x_set_width, y_set_width, xorg, yorg, xsize, ysize) +SPEEDO_GLOBALS *sp_global_ptr; +#else +FUNCTION void sp_open_bitmap(x_set_width, y_set_width, xorg, yorg, xsize, ysize) +#endif +fix31 x_set_width; +fix31 y_set_width; /* Set width vector */ +fix31 xorg; /* Pixel boundary at left extent of bitmap character */ +fix31 yorg; /* Pixel boundary at right extent of bitmap character */ +fix15 xsize; /* Pixel boundary of bottom extent of bitmap character */ +fix15 ysize; /* Pixel boundary of top extent of bitmap character */ +/* + * Called by Speedo character generator to initialize a buffer prior + * to receiving bitmap data. + */ +{ +fix15 i; + +#if DEBUG +printf("open_bitmap(%3.1f, %3.1f, %3.1f, %3.1f, %d, %d)\n", + (real)x_set_width / 65536.0, (real)y_set_width / 65536.0, + (real)xorg / 65536.0, (real)yorg / 65536.0, (int)xsize, (int)ysize); +#endif +raswid = xsize; +rashgt = ysize; +offhor = (fix15)(xorg >> 16); +offver = (fix15)(yorg >> 16); + +if (raswid > MAX_BITS) + raswid = MAX_BITS; + +printf("\nCharacter index = %d, ID = %d\n", char_index, char_id); +printf("set width = %3.1f, %3.1f\n", (real)x_set_width / 65536.0, (real)y_set_width / 65536.0); +printf("X offset = %d\n", offhor); +printf("Y offset = %d\n\n", offver); +for (i = 0; i < raswid; i++) + { + line_of_bits[i << 1] = '.'; + line_of_bits[(i << 1) + 1] = ' '; + } +line_of_bits[raswid << 1] = '\0'; +y_cur = 0; +} + +#if REENTRANT_ALLOC +FUNCTION void sp_set_bitmap_bits (sp_global_ptr, y, xbit1, xbit2) +SPEEDO_GLOBALS *sp_global_ptr; +#else +FUNCTION void sp_set_bitmap_bits (y, xbit1, xbit2) +#endif + fix15 y; /* Scan line (0 = first row above baseline) */ + fix15 xbit1; /* Pixel boundary where run starts */ + fix15 xbit2; /* Pixel boundary where run ends */ + +/* + * Called by Speedo character generator to write one row of pixels + * into the generated bitmap character. + */ + +{ +fix15 i; + +#if DEBUG +printf("set_bitmap_bits(%d, %d, %d)\n", (int)y, (int)xbit1, (int)xbit2); +#endif +/* Clip runs beyond end of buffer */ +if (xbit1 > MAX_BITS) + xbit1 = MAX_BITS; + +if (xbit2 > MAX_BITS) + xbit2 = MAX_BITS; + +/* Output backlog lines if any */ +while (y_cur != y) + { + printf(" %s\n", line_of_bits); + for (i = 0; i < raswid; i++) + { + line_of_bits[i << 1] = '.'; + } + y_cur++; + } + +/* Add bits to current line */ +for (i = xbit1; i < xbit2; i++) + { + line_of_bits[i << 1] = 'X'; + } +} + +#if REENTRANT_ALLOC +FUNCTION void sp_close_bitmap(sp_global_ptr) +SPEEDO_GLOBALS *sp_global_ptr; +#else +FUNCTION void sp_close_bitmap() +#endif +/* + * Called by Speedo character generator to indicate all bitmap data + * has been generated. + */ +{ +#if DEBUG +printf("close_bitmap()\n"); +#endif +printf(" %s\n", line_of_bits); +} + +#if INCL_OUTLINE +#if REENTRANT_ALLOC +FUNCTION void sp_open_outline(sp_global_ptr, x_set_width, y_set_width, xmin, xmax, ymin, ymax) +SPEEDO_GLOBALS *sp_global_ptr; +#else +FUNCTION void sp_open_outline(x_set_width, y_set_width, xmin, xmax, ymin, ymax) +#endif +fix31 x_set_width; +fix31 y_set_width; /* Transformed escapement vector */ +fix31 xmin; /* Minimum X value in outline */ +fix31 xmax; /* Maximum X value in outline */ +fix31 ymin; /* Minimum Y value in outline */ +fix31 ymax; /* Maximum Y value in outline */ +/* + * Called by Speedo character generator to initialize prior to + * outputting scaled outline data. + */ +{ +printf("\nopen_outline(%3.1f, %3.1f, %3.1f, %3.1f, %3.1f, %3.1f)\n", + (real)x_set_width / 65536.0, (real)y_set_width / 65536.0, + (real)xmin / 65536.0, (real)xmax / 65536.0, (real)ymin / 65536.0, (real)ymax / 65536.0); +} + + +#if REENTRANT_ALLOC +FUNCTION void sp_start_new_char(sp_global_ptr) +SPEEDO_GLOBALS *sp_global_ptr; +#else +FUNCTION void sp_start_new_char() +#endif +/* + * Called by Speedo character generator to initialize prior to + * outputting scaled outline data for a sub-character in a compound + * character. + */ +{ +printf("start_new_char()\n"); +} + +#if REENTRANT_ALLOC +FUNCTION void sp_start_contour(sp_global_ptr, x, y, outside) +SPEEDO_GLOBALS *sp_global_ptr; +#else +FUNCTION void sp_start_contour(x, y, outside) +#endif +fix31 x; /* X coordinate of start point in 1/65536 pixels */ +fix31 y; /* Y coordinate of start point in 1/65536 pixels */ +boolean outside; /* TRUE if curve encloses ink (Counter-clockwise) */ +/* + * Called by Speedo character generator at the start of each contour + * in the outline data of the character. + */ +{ +printf("start_contour(%3.1f, %3.1f, %s)\n", + (real)x / 65536.0, (real)y / 65536.0, + outside? "outside": "inside"); +} + +#if REENTRANT_ALLOC +FUNCTION void sp_curve_to(sp_global_ptr, x1, y1, x2, y2, x3, y3) +SPEEDO_GLOBALS *sp_global_ptr; +#else +FUNCTION void sp_curve_to(x1, y1, x2, y2, x3, y3) +#endif +fix31 x1; /* X coordinate of first control point in 1/65536 pixels */ +fix31 y1; /* Y coordinate of first control point in 1/65536 pixels */ +fix31 x2; /* X coordinate of second control point in 1/65536 pixels */ +fix31 y2; /* Y coordinate of second control point in 1/65536 pixels */ +fix31 x3; /* X coordinate of curve end point in 1/65536 pixels */ +fix31 y3; /* Y coordinate of curve end point in 1/65536 pixels */ +/* + * Called by Speedo character generator onece for each curve in the + * scaled outline data of the character. This function is only called if curve + * output is enabled in the set_specs() call. + */ +{ +printf("curve_to(%3.1f, %3.1f, %3.1f, %3.1f, %3.1f, %3.1f)\n", + (real)x1 / 65536.0, (real)y1 / 65536.0, + (real)x2 / 65536.0, (real)y2 / 65536.0, + (real)x3 / 65536.0, (real)y3 / 65536.0); +} + +#if REENTRANT_ALLOC +FUNCTION void sp_line_to(sp_global_ptr, x, y) +SPEEDO_GLOBALS *sp_global_ptr; +#else +FUNCTION void sp_line_to(x, y) +#endif +fix31 x; /* X coordinate of vector end point in 1/65536 pixels */ +fix31 y; /* Y coordinate of vector end point in 1/65536 pixels */ +/* + * Called by Speedo character generator onece for each vector in the + * scaled outline data for the character. This include curve data that has + * been sub-divided into vectors if curve output has not been enabled + * in the set_specs() call. + */ +{ +printf("line_to(%3.1f, %3.1f)\n", + (real)x / 65536.0, (real)y / 65536.0); +} + + +#if REENTRANT_ALLOC +FUNCTION void sp_close_contour(sp_global_ptr) +SPEEDO_GLOBALS *sp_global_ptr; +#else +FUNCTION void sp_close_contour() +#endif +/* + * Called by Speedo character generator at the end of each contour + * in the outline data of the character. + */ +{ +printf("close_contour()\n"); +} + +#if REENTRANT_ALLOC +FUNCTION void sp_close_outline(sp_global_ptr) +SPEEDO_GLOBALS *sp_global_ptr; +#else +FUNCTION void sp_close_outline() +#endif +/* + * Called by Speedo character generator at the end of output of the + * scaled outline of the character. + */ +{ +printf("close_outline()\n"); +} + +#endif + +FUNCTION fix15 read_2b(pointer) +ufix8 FONTFAR *pointer; +/* + * Reads 2-byte field from font buffer + */ +{ +fix15 temp; + +temp = *pointer++; +temp = (temp << 8) + *(pointer); +return temp; +} + + +FUNCTION fix31 read_4b(pointer) +ufix8 FONTFAR *pointer; +/* + * Reads 4-byte field from font buffer + */ +{ +fix31 temp; + +temp = *pointer++; +temp = (temp << 8) + *(pointer++); +temp = (temp << 8) + *(pointer++); +temp = (temp << 8) + *(pointer); +return temp; +} + + diff --git a/nx-X11/lib/font/Speedo/out_bl2d.c b/nx-X11/lib/font/Speedo/out_bl2d.c new file mode 100644 index 000000000..6c38cb30d --- /dev/null +++ b/nx-X11/lib/font/Speedo/out_bl2d.c @@ -0,0 +1,772 @@ +/* $Xorg: out_bl2d.c,v 1.3 2000/08/17 19:46:26 cpqbld Exp $ */ + +/* + +Copyright 1989-1991, Bitstream Inc., Cambridge, MA. +You are hereby granted permission under all Bitstream propriety rights to +use, copy, modify, sublicense, sell, and redistribute the Bitstream Speedo +software and the Bitstream Charter outline font for any purpose and without +restrictions; provided, that this notice is left intact on all copies of such +software or font and that Bitstream's trademark is acknowledged as shown below +on all unmodified copies of such font. + +BITSTREAM CHARTER is a registered trademark of Bitstream Inc. + + +BITSTREAM INC. DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING +WITHOUT LIMITATION THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE. BITSTREAM SHALL NOT BE LIABLE FOR ANY DIRECT OR INDIRECT +DAMAGES, INCLUDING BUT NOT LIMITED TO LOST PROFITS, LOST DATA, OR ANY OTHER +INCIDENTAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF OR IN ANY WAY CONNECTED +WITH THE SPEEDO SOFTWARE OR THE BITSTREAM CHARTER OUTLINE FONT. + +*/ +/* $XFree86: xc/lib/font/Speedo/out_bl2d.c,v 1.3 1999/02/07 11:47:14 dawes Exp $ */ + +/*************************** O U T _ B L 2 D . C ***************************** + * * + * This is an output module for screen writer using two dimensional scanning * + ****************************************************************************/ + + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include "spdo_prv.h" /* General definitions for speedo */ + +#define CLOCKWISE 1 +#define DEBUG 0 +#define ABS(X) ( (X < 0) ? -X : X) + +#if DEBUG +#include <stdio.h> +#define SHOW(X) printf("X = %d\n", X) +#else +#define SHOW(X) +#endif + +/***** GLOBAL VARIABLES *****/ + +/***** GLOBAL FUNCTIONS *****/ + +/***** EXTERNAL VARIABLES *****/ + +/***** EXTERNAL FUNCTIONS *****/ + +/***** STATIC VARIABLES *****/ + +/***** STATIC FUNCTIONS *****/ + +#if INCL_2D +static void sp_draw_vector_to_2d(PROTO_DECL2 fix15 x0,fix15 y0,fix15 x1,fix15 y1,band_t GLOBALFAR *band); +static void sp_add_intercept_2d(PROTO_DECL2 fix15 y,fix15 x); +static void sp_proc_intercepts_2d(PROTO_DECL1); +#endif + +#if INCL_2D +FUNCTION boolean init_2d( +GDECL +specs_t GLOBALFAR *specsarg) +/* + * init_out_2d() is called by sp_set_specs() to initialize the output module. + * Returns TRUE if output module can accept requested specifications. + * Returns FALSE otherwise. + */ +{ + +if (specsarg->flags & CURVES_OUT) + return FALSE; /* Curves out, clipping not supported */ + +#if DEBUG +printf("INIT_OUT__2d()\n"); +#endif +return TRUE; +} +#endif + +#if INCL_2D +FUNCTION boolean begin_char_2d( +GDECL +point_t Psw, +point_t Pmin, +point_t Pmax) +/* Called once at the start of the character generation process + * Initializes intercept table, either calculates pixel maxima or + * decides that they need to be collected + */ +{ +#if DEBUG +printf("BEGIN_CHAR__2d(%3.1f, %3.1f, %3.1f, %3.1f, %3.1f, %3.1f\n", + (real)Psw.x / (real)sp_globals.onepix, (real)Psw.y / (real)sp_globals.onepix, + (real)Pmin.x / (real)sp_globals.onepix, (real)Pmin.y / (real)sp_globals.onepix, + (real)Pmax.x / (real)sp_globals.onepix, (real)Pmax.y / (real)sp_globals.onepix); +#endif +/* Convert PIX.FRAC to 16.16 form */ +sp_globals.x_scan_active = TRUE; /* Assume x-scanning from the start */ + +init_char_out(Psw,Pmin,Pmax); +return TRUE; +} +#endif + + +#if INCL_2D +FUNCTION void begin_contour_2d( +GDECL +point_t P1, +boolean outside) +/* Called at the start of each contour + */ +{ + +#if DEBUG +printf("BEGIN_CONTOUR__2d(%3.4f, %3.4f, %s)\n", + (real)P1.x / (real)sp_globals.onepix, + (real)P1.y / (real)sp_globals.onepix, + outside? "outside": "inside"); +#endif +sp_globals.x0_spxl = P1.x; +sp_globals.y0_spxl = P1.y; +} +#endif + +#if INCL_2D +FUNCTION void line_2d( +GDECL +point_t P1) +/* + * Called for each vector in the transformed character + * "draws" vector into intercept table + */ +{ + +#if DEBUG +printf("LINE_0(%3.4f, %3.4f)\n", + (real)P1.x / (real)sp_globals.onepix, + (real)P1.y / (real)sp_globals.onepix); +#endif + +if (sp_globals.extents_running) + { + if (sp_globals.x0_spxl > sp_globals.bmap_xmax) + sp_globals.bmap_xmax = sp_globals.x0_spxl; + if (sp_globals.x0_spxl < sp_globals.bmap_xmin) + sp_globals.bmap_xmin = sp_globals.x0_spxl; + if (sp_globals.y0_spxl > sp_globals.bmap_ymax) + sp_globals.bmap_ymax = sp_globals.y0_spxl; + if (sp_globals.y0_spxl < sp_globals.bmap_ymin) + sp_globals.bmap_ymin = sp_globals.y0_spxl; + } + +if (!sp_globals.intercept_oflo) + { + sp_draw_vector_to_2d(sp_globals.x0_spxl, + sp_globals.y0_spxl, + P1.x, + P1.y, + &sp_globals.y_band); /* y-scan */ + + if (sp_globals.x_scan_active) + sp_draw_vector_to_2d(sp_globals.y0_spxl, + sp_globals.x0_spxl, + P1.y, + P1.x, + &sp_globals.x_band); /* x-scan if selected */ + } + +sp_globals.x0_spxl = P1.x; +sp_globals.y0_spxl = P1.y; /* update endpoint */ +} + +FUNCTION static void sp_draw_vector_to_2d( +GDECL +fix15 x0, /* X coordinate */ +fix15 y0, /* Y coordinate */ +fix15 x1, +fix15 y1, +band_t GLOBALFAR *band) +{ +register fix15 how_many_y; /* # of intercepts at y = n + 1/2 */ +register fix15 yc; /* Current scan-line */ + fix15 temp1; /* various uses */ + fix15 temp2; /* various uses */ +register fix31 dx_dy; /* slope of line in 16.16 form */ +register fix31 xc; /* high-precision (16.16) x coordinate */ + fix15 y_pxl; + +yc = (y0 + sp_globals.pixrnd) >> sp_globals.pixshift; /* current scan line = end of last line */ +y_pxl = (y1 + sp_globals.pixrnd) >> sp_globals.pixshift; /* calculate new end-scan line */ + +if ((how_many_y = y_pxl - yc) == 0) return; /* Don't draw a null line */ + +if (how_many_y < 0) yc--; /* Predecrment downward lines */ + +if (yc > band->band_max) /* Is start point above band? */ + { + if (y_pxl > band->band_max) return; /* line has to go down! */ + how_many_y = y_pxl - (yc = band->band_max) - 1; /* Yes, limit it */ + } + +if (yc < band->band_min) /* Is start point below band? */ + { + if (y_pxl < band->band_min) return; /* line has to go up! */ + how_many_y = y_pxl - (yc = band->band_min); /* Yes, limit it */ + } + +xc = (fix31)(x0 + sp_globals.pixrnd) << 16; /* Original x coordinate with built in */ + /* rounding. int.16 + pixshift form */ + +if ( (temp1 = (x1 - x0)) == 0) /* check for vertical line */ + { + dx_dy = 0L; /* Zero slope, leave xc alone */ + goto skip_calc; + } + +/* calculate dx_dy at 16.16 fixed point */ + +dx_dy = ( (fix31)temp1 << 16 )/(fix31)(y1 - y0); + +/* We have to check for a @#$%@# possible multiply overflow */ +/* by doing another @#$*& multiply. In assembly language, */ +/* the program could just check the OVerflow flag or whatever*/ +/* works on the particular processor. This C code is meant */ +/* to be processor independent. */ + +temp1 = (yc << sp_globals.pixshift) - y0 + sp_globals.pixrnd; +/* This sees if the sign bits start at bit 15 */ +/* if they do, no overflow has occurred */ + +temp2 = (fix15)(MULT16(temp1,(fix15)(dx_dy >> 16)) >> 15); + +if ( (temp2 != (fix15)0xFFFF) && + (temp2 != 0x0000) ) + { /* Overflow. Pick point closest to yc + .5 */ + if (ABS(temp1) < ABS((yc << sp_globals.pixshift) - y1 + sp_globals.pixrnd)) + { /* use x1 instead of x0 */ + xc = (fix31)(x1 + sp_globals.pixrnd) << (16 - sp_globals.pixshift); + } + goto skip_calc; + } +/* calculate new xc at the center of the *current* scan line */ +/* due to banding, yc may be several lines away from y0 */ +/* xc += (yc + .5 - y0) * dx_dy */ +/* This multiply generates a subpixel delta. */ +/* So we leave it as an int.pixshift + 16 delta */ + +xc += (fix31)temp1 * dx_dy; +dx_dy <<= sp_globals.pixshift; +skip_calc: + +yc -= band->band_array_offset; /* yc is now an offset relative to the band */ + +if (how_many_y < 0) + { /* Vector down */ + if ((how_many_y += yc + 1) < band->band_floor) + how_many_y = band->band_floor; /* can't go below floor */ + while(yc >= how_many_y) + { + temp1 = (fix15)(xc >> 16); + sp_add_intercept_2d(yc--,temp1); + xc -= dx_dy; + } + } + else + { /* Vector up */ + /* check to see that line doesn't extend beyond top of band */ + if ((how_many_y += yc) > band->band_ceiling) + how_many_y = band->band_ceiling; + while(yc < how_many_y) + { + temp1 = (fix15)(xc >> 16); + sp_add_intercept_2d(yc++,temp1); + xc += dx_dy; + } + } +} + +#endif + +#if INCL_2D +FUNCTION boolean end_char_2d() +/* Called when all character data has been output + * Return TRUE if output process is complete + * Return FALSE to repeat output of the transformed data beginning + * with the first contour + */ +{ + +fix31 xorg; +fix31 yorg; +#if INCL_CLIPPING +fix31 em_max, em_min, bmap_max, bmap_min; +#endif + +#if DEBUG +printf("END_CHAR__2d()\n"); +#endif + +if (sp_globals.first_pass) + { + if (sp_globals.bmap_xmax >= sp_globals.bmap_xmin) + { + sp_globals.xmin = (sp_globals.bmap_xmin + sp_globals.pixrnd + 1) >> sp_globals.pixshift; + sp_globals.xmax = (sp_globals.bmap_xmax + sp_globals.pixrnd) >> sp_globals.pixshift; + } + else + { + sp_globals.xmin = sp_globals.xmax = 0; + } + if (sp_globals.bmap_ymax >= sp_globals.bmap_ymin) + { + +#if INCL_CLIPPING + switch(sp_globals.tcb0.xtype) + { + case 1: /* 180 degree rotation */ + if (sp_globals.specs.flags & CLIP_TOP) + { + sp_globals.clip_ymin = (fix31)((fix31)EM_TOP * sp_globals.tcb0.yppo + ((1<<sp_globals.multshift)/2)); + sp_globals.clip_ymin = sp_globals.clip_ymin >> sp_globals.multshift; + bmap_min = (sp_globals.bmap_ymin + sp_globals.pixrnd + 1) >> sp_globals.pixshift; + sp_globals.clip_ymin = -1 * sp_globals.clip_ymin; + if (bmap_min < sp_globals.clip_ymin) + sp_globals.ymin = sp_globals.clip_ymin; + else + sp_globals.ymin = bmap_min; + } + if (sp_globals.specs.flags & CLIP_BOTTOM) + { + sp_globals.clip_ymax = (fix31)((fix31)(-1 * EM_BOT) * sp_globals.tcb0.yppo + ((1<<sp_globals.multshift)/2)); + sp_globals.clip_ymax = sp_globals.clip_ymax >> sp_globals.multshift; + bmap_max = (sp_globals.bmap_ymax + sp_globals.pixrnd) >> sp_globals.pixshift; + if (bmap_max < sp_globals.clip_ymax) + sp_globals.ymax = bmap_max; + else + sp_globals.ymax = sp_globals.clip_ymax; + } + sp_globals.clip_xmax = -sp_globals.xmin; + sp_globals.clip_xmin = ((sp_globals.set_width.x+32768L) >> 16) - + sp_globals.xmin; + break; + case 2: /* 90 degree rotation */ + if (sp_globals.specs.flags & CLIP_TOP) + { + sp_globals.clip_xmin = (fix31)((fix31)(-1 * EM_BOT) * sp_globals.tcb0.yppo + ((1<<sp_globals.multshift)/2)); + sp_globals.clip_xmin = sp_globals.clip_xmin >> sp_globals.multshift; + sp_globals.clip_xmin = -1 * sp_globals.clip_xmin; + bmap_min = (sp_globals.bmap_xmin + sp_globals.pixrnd + 1) >> sp_globals.pixshift; + if (bmap_min > sp_globals.clip_xmin) + sp_globals.clip_xmin = bmap_min; + + /* normalize to x origin */ + sp_globals.clip_xmin -= sp_globals.xmin; + } + if (sp_globals.specs.flags & CLIP_BOTTOM) + { + sp_globals.clip_xmax = (fix31)((fix31)EM_TOP * sp_globals.tcb0.yppo + ((1<<sp_globals.multshift)/2)); + sp_globals.clip_xmax = sp_globals.clip_xmax >> sp_globals.multshift; + bmap_max = (sp_globals.bmap_xmax + sp_globals.pixrnd) >> sp_globals.pixshift; + if (bmap_max < sp_globals.clip_xmax) + sp_globals.xmax = bmap_max; + else + sp_globals.xmax = sp_globals.clip_xmax; + sp_globals.clip_ymax = 0; + if ((sp_globals.specs.flags & CLIP_TOP) && + (sp_globals.ymax > sp_globals.clip_ymax)) + sp_globals.ymax = sp_globals.clip_ymax; + sp_globals.clip_ymin = ((sp_globals.set_width.y+32768L) >> 16); + if ((sp_globals.specs.flags & CLIP_BOTTOM) && + (sp_globals.ymin < sp_globals.clip_ymin)) + sp_globals.ymin = sp_globals.clip_ymin; + /* normalize to x origin */ + sp_globals.clip_xmax -= sp_globals.xmin; + } + break; + case 3: /* 270 degree rotation */ + if (sp_globals.specs.flags & CLIP_TOP) + { + sp_globals.clip_xmin = (fix31)((fix31)EM_TOP * sp_globals.tcb0.yppo + ((1<<sp_globals.multshift)/2)); + sp_globals.clip_xmin = sp_globals.clip_xmin >> sp_globals.multshift; + sp_globals.clip_xmin = -1 * sp_globals.clip_xmin; + bmap_min = (sp_globals.bmap_xmin + sp_globals.pixrnd + 1) >> sp_globals.pixshift; + + /* let the minimum be the larger of these two values */ + if (bmap_min > sp_globals.clip_xmin) + sp_globals.clip_xmin = bmap_min; + + /* normalize the x value to new xorgin */ + sp_globals.clip_xmin -= sp_globals.xmin; + } + if (sp_globals.specs.flags & CLIP_BOTTOM) + { + sp_globals.clip_xmax = (fix31)((fix31)(-1 * EM_BOT) * sp_globals.tcb0.yppo + ((1<<sp_globals.multshift)/2)); + sp_globals.clip_xmax = sp_globals.clip_xmax >> sp_globals.multshift; + bmap_max = (sp_globals.bmap_xmax + sp_globals.pixrnd) >> sp_globals.pixshift; + + /* let the max be the lesser of these two values */ + if (bmap_max < sp_globals.clip_xmax) + { + sp_globals.xmax = bmap_max; + sp_globals.clip_xmax = bmap_max; + } + else + sp_globals.xmax = sp_globals.clip_xmax; + + /* normalize the x value to new x origin */ + sp_globals.clip_xmax -= sp_globals.xmin; + } + /* compute y clip values */ + sp_globals.clip_ymax = ((sp_globals.set_width.y+32768L) >> 16); + if ((sp_globals.specs.flags & CLIP_TOP) && + (sp_globals.ymax > sp_globals.clip_ymax)) + sp_globals.ymax = sp_globals.clip_ymax; + sp_globals.clip_ymin = 0; + if ((sp_globals.specs.flags & CLIP_BOTTOM) && + (sp_globals.ymin < sp_globals.clip_ymin)) + sp_globals.ymin = sp_globals.clip_ymin; + break; + default: /* this is for zero degree rotation and arbitrary rotation */ + if (sp_globals.specs.flags & CLIP_TOP) + { + sp_globals.clip_ymax = (fix31)((fix31)EM_TOP * sp_globals.tcb0.yppo + ((1<<sp_globals.multshift)/2)); + sp_globals.clip_ymax = sp_globals.clip_ymax >> sp_globals.multshift; + bmap_max = (sp_globals.bmap_ymax + sp_globals.pixrnd) >> sp_globals.pixshift; + if (bmap_max > sp_globals.clip_ymax) + sp_globals.ymax = bmap_max; + else + sp_globals.ymax = sp_globals.clip_ymax; + } + if (sp_globals.specs.flags & CLIP_BOTTOM) + { + sp_globals.clip_ymin = (fix31)((fix31)(-1 * EM_BOT) * sp_globals.tcb0.yppo + ((1<<sp_globals.multshift)/2)); + sp_globals.clip_ymin = sp_globals.clip_ymin >> sp_globals.multshift; + sp_globals.clip_ymin = - sp_globals.clip_ymin; + bmap_min = (sp_globals.bmap_ymin + sp_globals.pixrnd + 1) >> sp_globals.pixshift; + if (bmap_min < sp_globals.clip_ymin) + sp_globals.ymin = sp_globals.clip_ymin; + else + sp_globals.ymin = bmap_min; + } + sp_globals.clip_xmin = -sp_globals.xmin; + sp_globals.clip_xmax = ((sp_globals.set_width.x+32768L) >> 16) - + sp_globals.xmin; + break; + } +if ( !(sp_globals.specs.flags & CLIP_TOP)) +#endif + sp_globals.ymax = (sp_globals.bmap_ymax + sp_globals.pixrnd) >> sp_globals.pixshift; + +#if INCL_CLIPPING +if ( !(sp_globals.specs.flags & CLIP_BOTTOM)) +#endif + sp_globals.ymin = (sp_globals.bmap_ymin + sp_globals.pixrnd + 1) >> sp_globals.pixshift; + } + else + { + sp_globals.ymin = sp_globals.ymax = 0; + } + + /* add in the rounded out part (from xform.) of the left edge */ + if (sp_globals.tcb.xmode == 0) /* for X pix is function of X orus only add the round */ + xorg = (((fix31)sp_globals.xmin << 16) + (sp_globals.rnd_xmin << sp_globals.poshift)); + else + if (sp_globals.tcb.xmode == 1) /* for X pix is function of -X orus only, subtr. round */ + xorg = (((fix31)sp_globals.xmin << 16) - (sp_globals.rnd_xmin << sp_globals.poshift)) ; + else + xorg = (fix31)sp_globals.xmin << 16; /* for other cases don't use round on x */ + + if (sp_globals.tcb.ymode == 2) /* for Y pix is function of X orus only, add round error */ + yorg = (((fix31)sp_globals.ymin << 16) + (sp_globals.rnd_xmin << sp_globals.poshift)); + else + if (sp_globals.tcb.ymode == 3) /* for Y pix is function of -X orus only, sub round */ + yorg = (((fix31)sp_globals.ymin << 16) - (sp_globals.rnd_xmin << sp_globals.poshift)); + else /* all other cases have no round error on yorg */ + yorg = (fix31)sp_globals.ymin << 16; + + open_bitmap(sp_globals.set_width.x, sp_globals.set_width.y, xorg, yorg, + sp_globals.xmax - sp_globals.xmin, sp_globals.ymax - sp_globals.ymin); + if (sp_globals.intercept_oflo) + { + sp_globals.y_band.band_min = sp_globals.ymin; + sp_globals.y_band.band_max = sp_globals.ymax; + sp_globals.x_scan_active = FALSE; + sp_globals.no_x_lists = 0; + init_intercepts_out(); + sp_globals.first_pass = FALSE; + sp_globals.extents_running = FALSE; + return FALSE; + } + else + { + sp_proc_intercepts_2d(); + close_bitmap(); + return TRUE; + } + } +else + { + if (sp_globals.intercept_oflo) + { + reduce_band_size_out(); + init_intercepts_out(); + return FALSE; + } + else + { + sp_proc_intercepts_2d(); + if (next_band_out()) + { + init_intercepts_out(); + return FALSE; + } + close_bitmap(); + return TRUE; + } + } +} +#endif + +#if INCL_2D +FUNCTION static void sp_add_intercept_2d( +GDECL +fix15 y, /* Y coordinate in relative pixel units */ + /* (0 is lowest sample in band) */ +fix15 x) /* X coordinate of intercept in subpixel units */ + +/* Called by line() to add an intercept to the intercept list structure + */ + +{ +register fix15 from; /* Insertion pointers for the linked list sort */ +register fix15 to; + +#if DEBUG +/* Bounds checking IS done in debug mode */ +if ((y >= MAX_INTERCEPTS) || (y < 0)) + { + printf("Intercept out of table!!!!! (%d)\n",y); + return; + } + +if (y >= sp_globals.no_y_lists) + { + printf(" Add x intercept(%2d, %f)\n", + y + sp_globals.x_band.band_min - sp_globals.no_y_lists, + (real)x/(real)sp_globals.onepix); + if (y > (sp_globals.no_x_lists + sp_globals.no_y_lists)) + { + printf(" Intercept too big for band!!!!!\007\n"); + return; + } + } + else + { + printf(" Add y intercept(%2d, %f)\n", y + sp_globals.y_band.band_min,(real)x/(real)sp_globals.onepix); + } + +if (y < 0) /* Y value below bottom of current band? */ + { + printf(" Intecerpt less than 0!!!\007\n"); + return; + } +#endif + +/* Store new values */ + +sp_intercepts.car[sp_globals.next_offset] = x; + +/* Find slot to insert new element (between from and to) */ + +from = y; /* Start at list head */ + +while( (to = sp_intercepts.cdr[from]) >= sp_globals.first_offset) /* Until to == end of list */ + { + if (x <= sp_intercepts.car[to]) /* If next item is larger than or same as this one... */ + goto insert_element; /* ... drop out and insert here */ + from = to; /* move forward in list */ + } + +insert_element: /* insert element "next_offset" between elements "from" */ + /* and "to" */ + +sp_intercepts.cdr[from] = sp_globals.next_offset; +sp_intercepts.cdr[sp_globals.next_offset] = to; + +if (++sp_globals.next_offset >= MAX_INTERCEPTS) /* Intercept buffer full? */ + { + sp_globals.intercept_oflo = TRUE; +/* There may be a few more calls to "add_intercept" from the current line */ +/* To avoid problems, we set next_offset to a safe value. We don't care */ +/* if the intercept table gets trashed at this point */ + sp_globals.next_offset = sp_globals.first_offset; + } +} + +#endif + +#if INCL_2D +FUNCTION static void sp_proc_intercepts_2d() +/* Called by sp_make_char to output accumulated intercept lists + * Clips output to xmin, xmax, sp_globals.ymin, ymax boundaries + */ +{ +register fix15 i; +register fix15 from, to; /* Start and end of run in pixel units + relative to left extent of character */ +register fix15 y; +register fix15 scan_line; + fix15 local_bmap_xmin; + fix15 local_bmap_xmax; + fix15 first_y, last_y; + fix15 j,k; + +#if INCL_CLIPPING +if ((sp_globals.specs.flags & CLIP_LEFT) != 0) + clipleft = TRUE; +else + clipleft = FALSE; +if ((sp_globals.specs.flags & CLIP_RIGHT) != 0) + clipright = TRUE; +else + clipright = FALSE; +if (clipleft || clipright) + { + xmax = sp_globals.clip_xmax << sp_globals.pixshift; + xmin = sp_globals.clip_xmin << sp_globals.pixshift; + } +if (!clipright) + xmax = ((sp_globals.set_width.x+32768L) >> 16); +#endif + +if (sp_globals.x_scan_active) /* If xscanning, we need to make sure we don't miss any important pixels */ + { + first_y = sp_globals.x_band.band_floor; /* start of x lists */ + last_y = sp_globals.x_band.band_ceiling; /* end of x lists */ + for (y = first_y; y != last_y; y++) /* scan all xlists */ + { + i = sp_intercepts.cdr[y]; /* Index head of intercept list */ + while (i != 0) /* Link to next intercept if present */ + { + from = sp_intercepts.car[i]; + j = i; + i = sp_intercepts.cdr[i]; /* Link to next intercept */ + if (i == 0) /* End of list? */ + { +#if DEBUG + printf("****** proc_intercepts: odd number of intercepts in x list\n"); +#endif + break; + } + to = sp_intercepts.car[i]; + k = sp_intercepts.cdr[i]; + if (((to >> sp_globals.pixshift) >= (from >> sp_globals.pixshift)) && + ((to - from) < (sp_globals.onepix + 1))) + { + from = ((fix31)to + (fix31)from - (fix31)sp_globals.onepix) >> (sp_globals.pixshift + 1); + if (from > sp_globals.y_band.band_max) + from = sp_globals.y_band.band_max; + if ((from -= sp_globals.y_band.band_min) < 0) + from = 0; + to = ((y - sp_globals.x_band.band_floor + sp_globals.x_band.band_min) + << sp_globals.pixshift) + + sp_globals.pixrnd; + sp_intercepts.car[j] = to; + sp_intercepts.car[i] = to + sp_globals.onepix; + sp_intercepts.cdr[i] = sp_intercepts.cdr[from]; + sp_intercepts.cdr[from] = j; + } + i = k; + } + } + } +#if DEBUG +printf("\nIntercept lists:\n"); +#endif + +if ((first_y = sp_globals.y_band.band_max) >= sp_globals.ymax) + first_y = sp_globals.ymax - 1; /* Clip to ymax boundary */ + +if ((last_y = sp_globals.y_band.band_min) < sp_globals.ymin) + last_y = sp_globals.ymin; /* Clip to sp_globals.ymin boundary */ + +last_y -= sp_globals.y_band.band_array_offset; + +local_bmap_xmin = sp_globals.xmin << sp_globals.pixshift; +local_bmap_xmax = (sp_globals.xmax << sp_globals.pixshift) + sp_globals.pixrnd; + +#if DEBUG +/* Print out all of the intercept info */ +scan_line = sp_globals.ymax - first_y - 1; + +for (y = first_y - sp_globals.y_band.band_min; y >= last_y; y--, scan_line++) + { + i = y; /* Index head of intercept list */ + while ((i = sp_intercepts.cdr[i]) != 0) /* Link to next intercept if present */ + { + if ((from = sp_intercepts.car[i] - local_bmap_xmin) < 0) + from = 0; /* Clip to xmin boundary */ + i = sp_intercepts.cdr[i]; /* Link to next intercept */ + if (i == 0) /* End of list? */ + { + printf("****** proc_intercepts: odd number of intercepts\n"); + break; + } + if ((to = sp_intercepts.car[i]) > sp_globals.bmap_xmax) + to = sp_globals.bmap_xmax - local_bmap_xmin; /* Clip to xmax boundary */ + else + to -= local_bmap_xmin; + printf(" Y = %2d (scanline %2d): %3.4f %3.4f:\n", + y + sp_globals.y_band.band_min, + scan_line, + (real)from / (real)sp_globals.onepix, + (real)to / (real)sp_globals.onepix); + } + } +#endif + +/* Draw the image */ +scan_line = sp_globals.ymax - first_y - 1; + +for (y = first_y - sp_globals.y_band.band_min; y >= last_y; y--, scan_line++) + { + i = y; /* Index head of intercept list */ + while ((i = sp_intercepts.cdr[i]) != 0) /* Link to next intercept if present */ + { + if ((from = sp_intercepts.car[i] - local_bmap_xmin) < 0) + from = 0; /* Clip to xmin boundary */ + i = sp_intercepts.cdr[i]; /* Link to next intercept */ + + if ((to = sp_intercepts.car[i]) > local_bmap_xmax) + to = sp_globals.bmap_xmax - local_bmap_xmin; /* Clip to xmax boundary */ + else + to -= local_bmap_xmin; +#if INCL_CLIPPING + if (clipleft) + { + if (to <= xmin) + continue; + if (from < xmin) + from = xmin; + } + if (clipright) + { + if (from >= xmax) + continue; + if (to > xmax) + to = xmax; + } +#endif + if ( (to - from) <= sp_globals.onepix) + { + from = (to + from - sp_globals.onepix) >> (sp_globals.pixshift + 1); + set_bitmap_bits(scan_line, from, from + 1); + } + else + { + set_bitmap_bits(scan_line, from >> sp_globals.pixshift, to >> sp_globals.pixshift); + } + } + } +} + +#endif diff --git a/nx-X11/lib/font/Speedo/out_blk.c b/nx-X11/lib/font/Speedo/out_blk.c new file mode 100644 index 000000000..a5b669b2a --- /dev/null +++ b/nx-X11/lib/font/Speedo/out_blk.c @@ -0,0 +1,706 @@ +/* $Xorg: out_blk.c,v 1.3 2000/08/17 19:46:26 cpqbld Exp $ */ + +/* + +Copyright 1989-1991, Bitstream Inc., Cambridge, MA. +You are hereby granted permission under all Bitstream propriety rights to +use, copy, modify, sublicense, sell, and redistribute the Bitstream Speedo +software and the Bitstream Charter outline font for any purpose and without +restrictions; provided, that this notice is left intact on all copies of such +software or font and that Bitstream's trademark is acknowledged as shown below +on all unmodified copies of such font. + +BITSTREAM CHARTER is a registered trademark of Bitstream Inc. + + +BITSTREAM INC. DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING +WITHOUT LIMITATION THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE. BITSTREAM SHALL NOT BE LIABLE FOR ANY DIRECT OR INDIRECT +DAMAGES, INCLUDING BUT NOT LIMITED TO LOST PROFITS, LOST DATA, OR ANY OTHER +INCIDENTAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF OR IN ANY WAY CONNECTED +WITH THE SPEEDO SOFTWARE OR THE BITSTREAM CHARTER OUTLINE FONT. + +*/ +/* $XFree86: xc/lib/font/Speedo/out_blk.c,v 1.2 1999/02/07 06:18:16 dawes Exp $ */ + + +/*************************** O U T _ B L K . C ********************************* + * * + * This is an output module for black-writer mode. * + * * + *****************************************************************************/ + + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include "spdo_prv.h" /* General definitions for Speedo */ + +#define DEBUG 0 +#define LOCAL static +#define ABS(X) ( (X < 0) ? -X : X) + +#if DEBUG +#include <stdio.h> +#define SHOW(X) printf("X = %d\n", X) +#else +#define SHOW(X) +#endif + + +/***** GLOBAL VARIABLES *****/ + +/***** GLOBAL FUNCTIONS *****/ + +/***** EXTERNAL VARIABLES *****/ + +/***** EXTERNAL FUNCTIONS *****/ + +/***** STATIC VARIABLES *****/ + +/***** STATIC FUNCTIONS *****/ + +#if INCL_BLACK +static void sp_add_intercept_black(PROTO_DECL2 fix15 y, fix15 x); +static void sp_proc_intercepts_black(PROTO_DECL1); +#endif + + +#if INCL_BLACK +FUNCTION boolean init_black( +GDECL +specs_t GLOBALFAR *specsarg) +/* + * init_out0() is called by sp_set_specs() to initialize the output module. + * Returns TRUE if output module can accept requested specifications. + * Returns FALSE otherwise. + */ +{ +#if DEBUG +printf("INIT_BLK()\n"); +#endif +if (specsarg->flags & CURVES_OUT) + return FALSE; /* Curves out not supported */ +return (TRUE); +} +#endif + + +#if INCL_BLACK +FUNCTION boolean begin_char_black( +GDECL +point_t Psw, +point_t Pmin, +point_t Pmax) +/* Called once at the start of the character generation process + */ +{ +#if DEBUG +printf("BEGIN_CHAR_BLACK(%3.1f, %3.1f, %3.1f, %3.1f, %3.1f, %3.1f\n", + (real)Psw.x / (real)sp_globals.onepix, (real)Psw.y / (real)sp_globals.onepix, + (real)Pmin.x / (real)sp_globals.onepix, (real)Pmin.y / (real)sp_globals.onepix, + (real)Pmax.x / (real)sp_globals.onepix, (real)Pmax.y / (real)sp_globals.onepix); +#endif +init_char_out(Psw,Pmin,Pmax); +return TRUE; +} +#endif + + +#if INCL_BLACK +FUNCTION void begin_contour_black( +GDECL +point_t P1, +boolean outside) +/* Called at the start of each contour + */ +{ + +#if DEBUG +printf("BEGIN_CONTOUR_BLACK(%3.1f, %3.1f, %s)\n", + (real)P1.x / (real)sp_globals.onepix, (real)P1.y / (real)sp_globals.onepix, outside? "outside": "inside"); +#endif +sp_globals.x0_spxl = P1.x; +sp_globals.y0_spxl = P1.y; +sp_globals.y_pxl = (sp_globals.y0_spxl + sp_globals.pixrnd) >> sp_globals.pixshift; +} +#endif + +#if INCL_BLACK +FUNCTION void line_black( +GDECL +point_t P1) +/* Called for each vector in the transformed character + */ +{ +register fix15 how_many_y; /* # of intercepts at y = n + 1/2 */ +register fix15 yc, i; /* Current scan-line */ + fix15 temp1; /* various uses */ + fix15 temp2; /* various uses */ +register fix31 dx_dy; /* slope of line in 16.16 form */ +register fix31 xc; /* high-precision (16.16) x coordinate */ + fix15 x0,y0,x1,y1; /* PIX.FRAC start and endpoints */ + +x0 = sp_globals.x0_spxl; /* get start of line (== current point) */ +y0 = sp_globals.y0_spxl; +sp_globals.x0_spxl = x1 = P1.x; /* end of line */ +sp_globals.y0_spxl = y1 = P1.y; /* (also update current point to end of line) */ + +yc = sp_globals.y_pxl; /* current scan line = end of last line */ +sp_globals.y_pxl = (y1 + sp_globals.pixrnd) >> sp_globals.pixshift; /* calculate new end-scan sp_globals.line */ + + +#if DEBUG +printf("LINE_BLACK(%3.4f, %3.4f)\n", + (real)P1.x/(real)sp_globals.onepix, + (real)P1.y/(real)sp_globals.onepix); +#endif + +if (sp_globals.extents_running) + { + if (sp_globals.x0_spxl > sp_globals.bmap_xmax) + sp_globals.bmap_xmax = sp_globals.x0_spxl; + if (sp_globals.x0_spxl < sp_globals.bmap_xmin) + sp_globals.bmap_xmin = sp_globals.x0_spxl; + if (sp_globals.y0_spxl > sp_globals.bmap_ymax) + sp_globals.bmap_ymax = sp_globals.y0_spxl; + if (sp_globals.y0_spxl < sp_globals.bmap_ymin) + sp_globals.bmap_ymin = sp_globals.y0_spxl; + } + +if (sp_globals.intercept_oflo) return; + +if ((how_many_y = sp_globals.y_pxl - yc) == 0) return; /* Don't draw a null line */ + +if (how_many_y < 0) yc--; /* Predecrment downward lines */ + +if (yc > sp_globals.y_band.band_max) /* Is start point above band? */ + { + if (sp_globals.y_pxl > sp_globals.y_band.band_max) return; /* line has to go down! */ + how_many_y = sp_globals.y_pxl - (yc = sp_globals.y_band.band_max) - 1; /* Yes, limit it */ + } + +if (yc < sp_globals.y_band.band_min) /* Is start point below band? */ + { + if (sp_globals.y_pxl < sp_globals.y_band.band_min) return; /* line has to go up! */ + how_many_y = sp_globals.y_pxl - (yc = sp_globals.y_band.band_min); /* Yes, limit it */ + } + +xc = (fix31)(x0 + sp_globals.pixrnd) << (16 - sp_globals.pixshift); /* Original x coordinate with built in */ + /* rounding. 16.16 form */ + + +if ( (temp1 = (x1 - x0)) == 0) /* check for vertical line */ + { + yc -= sp_globals.y_band.band_min; /* yc is now an offset relative to the band */ + temp1 = (fix15)(xc >> 16); + if (how_many_y < 0) + { /* Vector down */ + if ((how_many_y += yc + 1) < 0) how_many_y = 0; /* can't go below 0 */ + for (i = yc; i >= how_many_y; i--) + sp_add_intercept_black(i,temp1); + } + else + { /* Vector up */ + /* check to see that line doesn't extend beyond top of band */ + if ((how_many_y += yc) > sp_globals.no_y_lists) how_many_y = sp_globals.no_y_lists; + for (i = yc; i != how_many_y; i++) + sp_add_intercept_black(i,temp1); + } + return; + } + +/* calculate dx_dy at 16.16 fixed point */ + +dx_dy = ( (fix31)temp1 << 16 )/(fix31)(y1 - y0); + +/* We have to check for a @#$%@# possible multiply overflow */ +/* by doing another @#$*& multiply. In assembly language, */ +/* the program could just check the OVerflow flag or whatever*/ +/* works on the particular processor. This C code is meant */ +/* to be processor independant. */ + +temp1 = (yc << sp_globals.pixshift) - y0 + sp_globals.pixrnd; +/* This sees if the sign bits start at bit 15 */ +/* if they do, no overflow has occurred */ + +temp2 = (fix15)(MULT16(temp1,(fix15)(dx_dy >> 16)) >> 15); + +if ( (temp2 != (fix15)0xFFFF) && + (temp2 != 0x0000) && + /* Overflow. Pick point closest to yc + .5 */ + (ABS(temp1) < ABS((yc << sp_globals.pixshift) - y1 + sp_globals.pixrnd)) ) + { /* use x1 instead of x0 */ + xc = (fix31)(x1 + sp_globals.pixrnd) << (16 - sp_globals.pixshift); + } +else + { +/* calculate new xc at the center of the *current* scan line */ +/* due to banding, yc may be several lines away from y0 */ +/* xc += (yc + .5 - y0) * dx_dy */ +/* This multiply generates a subpixel delta. */ +/* So we shift it to be a 16.16 delta */ + + xc += ((fix31)temp1 * dx_dy) >> sp_globals.pixshift; + } + +yc -= sp_globals.y_band.band_min; /* yc is now an offset relative to the band */ + +if (how_many_y < 0) + { /* Vector down */ + if (how_many_y == -1) + sp_add_intercept_black(yc, (fix15) (xc >> 16)); + else + { + if ((how_many_y += yc + 1) < 0) how_many_y = 0; /* can't go below 0 */ + for (i = yc; i >= how_many_y; i--) + { + temp1 = (fix15)(xc >> 16); + sp_add_intercept_black(i,temp1); + xc -= dx_dy; + } + } + } + else + { /* Vector up */ + /* check to see that line doesn't extend beyond top of band */ + if (how_many_y == 1) + sp_add_intercept_black(yc, (fix15) (xc >> 16)); + else + { + if ((how_many_y += yc) > sp_globals.no_y_lists) how_many_y = sp_globals.no_y_lists; + for (i = yc; i != how_many_y; i++) + { + temp1 = (fix15)(xc >> 16); + sp_add_intercept_black(i,temp1); + xc += dx_dy; + } + } + } +} +#endif +#if INCL_BLACK +FUNCTION boolean end_char_black() +GDECL +/* Called when all character data has been output + * Return TRUE if output process is complete + * Return FALSE to repeat output of the transformed data beginning + * with the first contour + */ +{ + +fix31 xorg; +fix31 yorg; +#if INCL_CLIPPING +fix31 bmap_max, bmap_min; +#endif + +#if DEBUG +printf("END_CHAR_BLACK()\n"); +#endif + +if (sp_globals.first_pass) + { + if (sp_globals.bmap_xmax >= sp_globals.bmap_xmin) + { + sp_globals.xmin = (sp_globals.bmap_xmin + sp_globals.pixrnd + 1) >> sp_globals.pixshift; + sp_globals.xmax = (sp_globals.bmap_xmax + sp_globals.pixrnd) >> sp_globals.pixshift; + } + else + { + sp_globals.xmin = sp_globals.xmax = 0; + } + if (sp_globals.bmap_ymax >= sp_globals.bmap_ymin) + { + +#if INCL_CLIPPING + switch(sp_globals.tcb0.xtype) + { + case 1: /* 180 degree rotation */ + if (sp_globals.specs.flags & CLIP_TOP) + { + sp_globals.clip_ymin = (fix31)((fix31)EM_TOP * sp_globals.tcb0.yppo + ((1<<sp_globals.multshift)/2)); + sp_globals.clip_ymin = sp_globals.clip_ymin >> sp_globals.multshift; + bmap_min = (sp_globals.bmap_ymin + sp_globals.pixrnd + 1) >> sp_globals.pixshift; + sp_globals.clip_ymin = -1 * sp_globals.clip_ymin; + if (bmap_min < sp_globals.clip_ymin) + sp_globals.ymin = sp_globals.clip_ymin; + else + sp_globals.ymin = bmap_min; + } + if (sp_globals.specs.flags & CLIP_BOTTOM) + { + sp_globals.clip_ymax = (fix31)((fix31)(-1 * EM_BOT) * sp_globals.tcb0.yppo + ((1<<sp_globals.multshift)/2)); + sp_globals.clip_ymax = sp_globals.clip_ymax >> sp_globals.multshift; + bmap_max = (sp_globals.bmap_ymax + sp_globals.pixrnd) >> sp_globals.pixshift; + if (bmap_max < sp_globals.clip_ymax) + sp_globals.ymax = bmap_max; + else + sp_globals.ymax = sp_globals.clip_ymax; + } + sp_globals.clip_xmax = -sp_globals.xmin; + sp_globals.clip_xmin = ((sp_globals.set_width.x+32768L) >> 16) - + sp_globals.xmin; + break; + case 2: /* 90 degree rotation */ + if (sp_globals.specs.flags & CLIP_TOP) + { + sp_globals.clip_xmin = (fix31)((fix31)(-1 * EM_BOT) * sp_globals.tcb0.yppo + ((1<<sp_globals.multshift)/2)); + sp_globals.clip_xmin = sp_globals.clip_xmin >> sp_globals.multshift; + sp_globals.clip_xmin = -1 * sp_globals.clip_xmin; + bmap_min = (sp_globals.bmap_xmin + sp_globals.pixrnd + 1) >> sp_globals.pixshift; + if (bmap_min > sp_globals.clip_xmin) + sp_globals.clip_xmin = bmap_min; + + /* normalize to x origin */ + sp_globals.clip_xmin -= sp_globals.xmin; + } + if (sp_globals.specs.flags & CLIP_BOTTOM) + { + sp_globals.clip_xmax = (fix31)((fix31)EM_TOP * sp_globals.tcb0.yppo + ((1<<sp_globals.multshift)/2)); + sp_globals.clip_xmax = sp_globals.clip_xmax >> sp_globals.multshift; + bmap_max = (sp_globals.bmap_xmax + sp_globals.pixrnd) >> sp_globals.pixshift; + if (bmap_max < sp_globals.clip_xmax) + sp_globals.xmax = bmap_max; + else + sp_globals.xmax = sp_globals.clip_xmax; + sp_globals.clip_ymax = 0; + if ((sp_globals.specs.flags & CLIP_TOP) && + (sp_globals.ymax > sp_globals.clip_ymax)) + sp_globals.ymax = sp_globals.clip_ymax; + sp_globals.clip_ymin = ((sp_globals.set_width.y+32768L) >> 16); + if ((sp_globals.specs.flags & CLIP_BOTTOM) && + (sp_globals.ymin < sp_globals.clip_ymin)) + sp_globals.ymin = sp_globals.clip_ymin; + /* normalize to x origin */ + sp_globals.clip_xmax -= sp_globals.xmin; + } + break; + case 3: /* 270 degree rotation */ + if (sp_globals.specs.flags & CLIP_TOP) + { + sp_globals.clip_xmin = (fix31)((fix31)EM_TOP * sp_globals.tcb0.yppo + ((1<<sp_globals.multshift)/2)); + sp_globals.clip_xmin = sp_globals.clip_xmin >> sp_globals.multshift; + sp_globals.clip_xmin = -1 * sp_globals.clip_xmin; + bmap_min = (sp_globals.bmap_xmin + sp_globals.pixrnd + 1) >> sp_globals.pixshift; + + /* let the minimum be the larger of these two values */ + if (bmap_min > sp_globals.clip_xmin) + sp_globals.clip_xmin = bmap_min; + + /* normalize the x value to new xorgin */ + sp_globals.clip_xmin -= sp_globals.xmin; + } + if (sp_globals.specs.flags & CLIP_BOTTOM) + { + sp_globals.clip_xmax = (fix31)((fix31)(-1 * EM_BOT) * sp_globals.tcb0.yppo + ((1<<sp_globals.multshift)/2)); + sp_globals.clip_xmax = sp_globals.clip_xmax >> sp_globals.multshift; + bmap_max = (sp_globals.bmap_xmax + sp_globals.pixrnd) >> sp_globals.pixshift; + + /* let the max be the lesser of these two values */ + if (bmap_max < sp_globals.clip_xmax) + { + sp_globals.xmax = bmap_max; + sp_globals.clip_xmax = bmap_max; + } + else + sp_globals.xmax = sp_globals.clip_xmax; + + /* normalize the x value to new x origin */ + sp_globals.clip_xmax -= sp_globals.xmin; + } + /* compute y clip values */ + sp_globals.clip_ymax = ((sp_globals.set_width.y+32768L) >> 16); + if ((sp_globals.specs.flags & CLIP_TOP) && + (sp_globals.ymax > sp_globals.clip_ymax)) + sp_globals.ymax = sp_globals.clip_ymax; + sp_globals.clip_ymin = 0; + if ((sp_globals.specs.flags & CLIP_BOTTOM) && + (sp_globals.ymin < sp_globals.clip_ymin)) + sp_globals.ymin = sp_globals.clip_ymin; + break; + default: /* this is for zero degree rotation and arbitrary rotation */ + if (sp_globals.specs.flags & CLIP_TOP) + { + sp_globals.clip_ymax = (fix31)((fix31)EM_TOP * sp_globals.tcb0.yppo + ((1<<sp_globals.multshift)/2)); + sp_globals.clip_ymax = sp_globals.clip_ymax >> sp_globals.multshift; + bmap_max = (sp_globals.bmap_ymax + sp_globals.pixrnd) >> sp_globals.pixshift; + if (bmap_max > sp_globals.clip_ymax) + sp_globals.ymax = bmap_max; + else + sp_globals.ymax = sp_globals.clip_ymax; + } + if (sp_globals.specs.flags & CLIP_BOTTOM) + { + sp_globals.clip_ymin = (fix31)((fix31)(-1 * EM_BOT) * sp_globals.tcb0.yppo + ((1<<sp_globals.multshift)/2)); + sp_globals.clip_ymin = sp_globals.clip_ymin >> sp_globals.multshift; + sp_globals.clip_ymin = - sp_globals.clip_ymin; + bmap_min = (sp_globals.bmap_ymin + sp_globals.pixrnd + 1) >> sp_globals.pixshift; + if (bmap_min < sp_globals.clip_ymin) + sp_globals.ymin = sp_globals.clip_ymin; + else + sp_globals.ymin = bmap_min; + } + sp_globals.clip_xmin = -sp_globals.xmin; + sp_globals.clip_xmax = ((sp_globals.set_width.x+32768L) >> 16) - + sp_globals.xmin; + break; + } +if ( !(sp_globals.specs.flags & CLIP_TOP)) +#endif + sp_globals.ymax = (sp_globals.bmap_ymax + sp_globals.pixrnd) >> sp_globals.pixshift; + +#if INCL_CLIPPING +if ( !(sp_globals.specs.flags & CLIP_BOTTOM)) +#endif + + sp_globals.ymin = (sp_globals.bmap_ymin + sp_globals.pixrnd + 1) >> sp_globals.pixshift; + } + else + { + sp_globals.ymin = sp_globals.ymax = 0; + } + + /* add in the rounded out part (from xform.) of the left edge */ + if (sp_globals.tcb.xmode == 0) /* for X pix is function of X orus only add the round */ + xorg = (((fix31)sp_globals.xmin << 16) + (sp_globals.rnd_xmin << sp_globals.poshift)); + else + if (sp_globals.tcb.xmode == 1) /* for X pix is function of -X orus only, subtr. round */ + xorg = (((fix31)sp_globals.xmin << 16) - (sp_globals.rnd_xmin << sp_globals.poshift)) ; + else + xorg = (fix31)sp_globals.xmin << 16; /* for other cases don't use round on x */ + + if (sp_globals.tcb.ymode == 2) /* for Y pix is function of X orus only, add round error */ + yorg = (((fix31)sp_globals.ymin << 16) + (sp_globals.rnd_xmin << sp_globals.poshift)); + else + if (sp_globals.tcb.ymode == 3) /* for Y pix is function of -X orus only, sub round */ + yorg = (((fix31)sp_globals.ymin << 16) - (sp_globals.rnd_xmin << sp_globals.poshift)); + else /* all other cases have no round error on yorg */ + yorg = (fix31)sp_globals.ymin << 16; + + open_bitmap(sp_globals.set_width.x, sp_globals.set_width.y, xorg, yorg, + sp_globals.xmax - sp_globals.xmin, sp_globals.ymax - sp_globals.ymin); + if (sp_globals.intercept_oflo) + { + sp_globals.y_band.band_min = sp_globals.ymin; + sp_globals.y_band.band_max = sp_globals.ymax; + init_intercepts_out(); + sp_globals.first_pass = FALSE; + sp_globals.extents_running = FALSE; + return FALSE; + } + else + { + sp_proc_intercepts_black(); + close_bitmap(); + return TRUE; + } + } +else + { + if (sp_globals.intercept_oflo) + { + reduce_band_size_out(); + init_intercepts_out(); + return FALSE; + } + else + { + sp_proc_intercepts_black(); + if (next_band_out()) + { + init_intercepts_out(); + return FALSE; + } + close_bitmap(); + return TRUE; + } + } +} +#endif + +#if INCL_BLACK +FUNCTION LOCAL void sp_add_intercept_black( +GDECL +fix15 y, /* Y coordinate in relative pixel units */ + /* (0 is lowest sample in band) */ +fix15 x) /* X coordinate of intercept in subpixel units */ + +/* Called by line() to add an intercept to the intercept list structure + */ + +{ +register fix15 from; /* Insertion pointers for the linked list sort */ +register fix15 to; + +#if DEBUG +printf(" Add intercept(%2d, %d)\n", y + sp_globals.y_band.band_min,x); + +/* Bounds checking IS done in debug mode */ +if (y < 0) /* Y value below bottom of current band? */ + { + printf(" Intecerpt less than 0!!!\007\n"); + return; + } + +if (y > (sp_globals.no_y_lists - 1)) /* Y value above top of current band? */ + { + printf(" Intercept too big for band!!!!!\007\n"); + return; + } +#endif + +/* Store new values */ + +sp_intercepts.car[sp_globals.next_offset] = x; + +/* Find slot to insert new element (between from and to) */ + +from = y; /* Start at list head */ + +while( (to = sp_intercepts.cdr[from]) >= sp_globals.first_offset) /* Until to == end of list */ + { + if (x <= sp_intercepts.car[to]) /* If next item is larger than or same as this one... */ + goto insert_element; /* ... drop out and insert here */ + from = to; /* move forward in list */ + } + +insert_element: /* insert element "sp_globals.next_offset" between elements "from" */ + /* and "to" */ + +sp_intercepts.cdr[from] = sp_globals.next_offset; +sp_intercepts.cdr[sp_globals.next_offset] = to; + +if (++sp_globals.next_offset >= MAX_INTERCEPTS) /* Intercept buffer full? */ + { + sp_globals.intercept_oflo = TRUE; +/* There may be a few more calls to "add_intercept" from the current line */ +/* To avoid problems, we set next_offset to a safe value. We don't care */ +/* if the intercept table gets trashed at this point */ + sp_globals.next_offset = sp_globals.first_offset; + } +} + +#endif + +#if INCL_BLACK +FUNCTION LOCAL void sp_proc_intercepts_black() +GDECL + +/* Called by sp_make_char to output accumulated intercept lists + * Clips output to sp_globals.xmin, sp_globals.xmax, sp_globals.ymin, sp_globals.ymax boundaries + */ +{ +register fix15 i; +register fix15 from, to; /* Start and end of run in pixel units + relative to left extent of character */ +register fix15 y; +register fix15 scan_line; + fix15 first_y, last_y; + +#if DEBUG +printf("\nIntercept lists:\n"); +#endif + +#if INCL_CLIPPING +if ((sp_globals.specs.flags & CLIP_LEFT) != 0) + clipleft = TRUE; +else + clipleft = FALSE; +if ((sp_globals.specs.flags & CLIP_RIGHT) != 0) + clipright = TRUE; +else + clipright = FALSE; +if (clipleft || clipright) + { + xmax = sp_globals.clip_xmax; + xmin = sp_globals.clip_xmin; + } +if (!clipright) + xmax = ((sp_globals.set_width.x+32768L) >> 16); +#endif + +if ((first_y = sp_globals.y_band.band_max) >= sp_globals.ymax) + first_y = sp_globals.ymax - 1; /* Clip to sp_globals.ymax boundary */ + +if ((last_y = sp_globals.y_band.band_min) < sp_globals.ymin) + last_y = sp_globals.ymin; /* Clip to sp_globals.ymin boundary */ + +last_y -= sp_globals.y_band.band_min; +#if DEBUG +/* Print out all of the intercept info */ +scan_line = sp_globals.ymax - first_y - 1; + +for (y = first_y - sp_globals.y_band.band_min; y >= last_y; y--, scan_line++) + { + i = y; /* Index head of intercept list */ + while ((i = sp_intercepts.cdr[i]) != 0) /* Link to next intercept if present */ + { + if ((from = sp_intercepts.car[i] - sp_globals.xmin) < 0) + from = 0; /* Clip to sp_globals.xmin boundary */ + i = sp_intercepts.cdr[i]; /* Link to next intercept */ + if (i == 0) /* End of list? */ + { + printf("****** proc_intercepts: odd number of intercepts\n"); + break; + } + if ((to = sp_intercepts.car[i]) > sp_globals.xmax) + to = sp_globals.xmax - sp_globals.xmin; /* Clip to sp_globals.xmax boundary */ + else + to -= sp_globals.xmin; + printf(" Y = %2d (scanline %2d): %d %d:\n", + y + sp_globals.y_band.band_min, scan_line, from, to); + } + } +#endif + +/* Draw the image */ +scan_line = sp_globals.ymax - first_y - 1; + +for (y = first_y - sp_globals.y_band.band_min; y >= last_y; y--, scan_line++) + { + i = y; /* Index head of intercept list */ + while ((i = sp_intercepts.cdr[i]) != 0) /* Link to next intercept if present */ + { + if ((from = sp_intercepts.car[i] - sp_globals.xmin) < 0) + from = 0; /* Clip to sp_globals.xmin boundary */ + i = sp_intercepts.cdr[i]; /* Link to next intercept */ + + if ((to = sp_intercepts.car[i]) > sp_globals.xmax) + to = sp_globals.xmax - sp_globals.xmin; /* Clip to sp_globals.xmax boundary */ + else + to -= sp_globals.xmin; + if (from >= to) + { + if (from >= sp_globals.xmax - sp_globals.xmin) + { + --from ; + } + to = from+1; + } +#if INCL_CLIPPING + if (clipleft) + { + if (to <= xmin) + continue; + if (from < xmin) + from = xmin; + } + if (clipright) + { + if (from >= xmax) + continue; + if (to > xmax) + to = xmax; + } +#endif + set_bitmap_bits(scan_line, from, to); + } + } +} + +#endif + + + + diff --git a/nx-X11/lib/font/Speedo/out_outl.c b/nx-X11/lib/font/Speedo/out_outl.c new file mode 100644 index 000000000..013901092 --- /dev/null +++ b/nx-X11/lib/font/Speedo/out_outl.c @@ -0,0 +1,290 @@ +/* $Xorg: out_outl.c,v 1.3 2000/08/17 19:46:26 cpqbld Exp $ */ + +/* + +Copyright 1989-1991, Bitstream Inc., Cambridge, MA. +You are hereby granted permission under all Bitstream propriety rights to +use, copy, modify, sublicense, sell, and redistribute the Bitstream Speedo +software and the Bitstream Charter outline font for any purpose and without +restrictions; provided, that this notice is left intact on all copies of such +software or font and that Bitstream's trademark is acknowledged as shown below +on all unmodified copies of such font. + +BITSTREAM CHARTER is a registered trademark of Bitstream Inc. + + +BITSTREAM INC. DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING +WITHOUT LIMITATION THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE. BITSTREAM SHALL NOT BE LIABLE FOR ANY DIRECT OR INDIRECT +DAMAGES, INCLUDING BUT NOT LIMITED TO LOST PROFITS, LOST DATA, OR ANY OTHER +INCIDENTAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF OR IN ANY WAY CONNECTED +WITH THE SPEEDO SOFTWARE OR THE BITSTREAM CHARTER OUTLINE FONT. + +*/ + + +/**************************** O U T _ 2 _ 1 . C ****************************** + * * + * This is the standard output module for vector output mode. * + * * + ****************************************************************************/ + + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include "spdo_prv.h" /* General definitions for Speedo */ + + +#define DEBUG 0 + +#if DEBUG +#include <stdio.h> +#define SHOW(X) printf("X = %d\n", X) +#else +#define SHOW(X) +#endif + +/* the following macro is used to limit points on the outline to the bounding box */ + +#define RANGECHECK(value,min,max) (((value) >= (min) ? (value) : (min)) < (max) ? (value) : (max)) +/***** GLOBAL VARIABLES *****/ + +/***** GLOBAL FUNCTIONS *****/ + +/***** EXTERNAL VARIABLES *****/ + +/***** EXTERNAL FUNCTIONS *****/ + +/***** STATIC VARIABLES *****/ + +/***** STATIC FUNCTIONS *****/ + + +#if INCL_OUTLINE +FUNCTION boolean init_outline(specsarg) +GDECL +specs_t GLOBALFAR *specsarg; +/* + * init_out2() is called by sp_set_specs() to initialize the output module. + * Returns TRUE if output module can accept requested specifications. + * Returns FALSE otherwise. + */ +{ +#if DEBUG +printf("INIT_OUT_2()\n"); +#endif +if (specsarg->flags & (CLIP_LEFT + CLIP_RIGHT + CLIP_TOP + CLIP_BOTTOM)) + return FALSE; /* Clipping not supported */ +return (TRUE); +} +#endif + +#if INCL_OUTLINE +FUNCTION boolean begin_char_outline(Psw, Pmin, Pmax) +GDECL +point_t Psw; /* End of escapement vector (sub-pixels) */ +point_t Pmin; /* Bottom left corner of bounding box */ +point_t Pmax; /* Top right corner of bounding box */ +/* + * If two or more output modules are included in the configuration, begin_char2() + * is called by begin_char() to signal the start of character output data. + * If only one output module is included in the configuration, begin_char() is + * called by make_simp_char() and make_comp_char(). + */ +{ +fix31 set_width_x; +fix31 set_width_y; +fix31 xmin; +fix31 xmax; +fix31 ymin; +fix31 ymax; + +#if DEBUG +printf("BEGIN_CHAR_2(%3.1f, %3.1f, %3.1f, %3.1f, %3.1f, %3.1f\n", + (real)Psw.x / (real)onepix, (real)Psw.y / (real)onepix, + (real)Pmin.x / (real)onepix, (real)Pmin.y / (real)onepix, + (real)Pmax.x / (real)onepix, (real)Pmax.y / (real)onepix); +#endif +sp_globals.poshift = 16 - sp_globals.pixshift; +set_width_x = (fix31)Psw.x << sp_globals.poshift; +set_width_y = (fix31)Psw.y << sp_globals.poshift; +xmin = (fix31)Pmin.x << sp_globals.poshift; +xmax = (fix31)Pmax.x << sp_globals.poshift; +ymin = (fix31)Pmin.y << sp_globals.poshift; +ymax = (fix31)Pmax.y << sp_globals.poshift; +sp_globals.xmin = Pmin.x; +sp_globals.xmax = Pmax.x; +sp_globals.ymin = Pmin.y; +sp_globals.ymax = Pmax.y; +open_outline(set_width_x, set_width_y, xmin, xmax, ymin, ymax); +return TRUE; +} +#endif + +#if INCL_OUTLINE +FUNCTION void begin_sub_char_outline(Psw, Pmin, Pmax) +GDECL +point_t Psw; /* End of sub-char escapement vector */ +point_t Pmin; /* Bottom left corner of sub-char bounding box */ +point_t Pmax; /* Top right corner of sub-char bounding box */ +/* + * If two or more output modules are included in the configuration, begin_sub_char2() + * is called by begin_sub_char() to signal the start of sub-character output data. + * If only one output module is included in the configuration, begin_sub_char() is + * called by make_comp_char(). + */ +{ +#if DEBUG +printf("BEGIN_SUB_CHAR_2(%3.1f, %3.1f, %3.1f, %3.1f, %3.1f, %3.1f\n", + (real)Psw.x / (real)onepix, (real)Psw.y / (real)onepix, + (real)Pmin.x / (real)onepix, (real)Pmin.y / (real)onepix, + (real)Pmax.x / (real)onepix, (real)Pmax.y / (real)onepix); +#endif +start_new_char(); +} +#endif + + +#if INCL_OUTLINE +FUNCTION void begin_contour_outline(P1, outside) +GDECL +point_t P1; /* Start point of contour */ +boolean outside; /* TRUE if outside (counter-clockwise) contour */ +/* + * If two or more output modules are included in the configuration, begin_contour2() + * is called by begin_contour() to define the start point of a new contour + * and to indicate whether it is an outside (counter-clockwise) contour + * or an inside (clockwise) contour. + * If only one output module is included in the configuration, begin_sub_char() is + * called by proc_outl_data(). + */ +{ +fix15 x,y; +#if DEBUG +printf("BEGIN_CONTOUR_2(%3.1f, %3.1f, %s)\n", + (real)P1.x / (real)onepix, (real)P1.y / (real)onepix, outside? "outside": "inside"); +#endif +x = RANGECHECK(P1.x,sp_globals.xmin,sp_globals.xmax); +y = RANGECHECK(P1.y,sp_globals.ymin,sp_globals.ymax); + +start_contour((fix31)x << sp_globals.poshift, (fix31)y << sp_globals.poshift, outside); +} +#endif + +#if INCL_OUTLINE +FUNCTION void curve_outline(P1, P2, P3,depth) +GDECL +point_t P1; /* First control point of Bezier curve */ +point_t P2; /* Second control point of Bezier curve */ +point_t P3; /* End point of Bezier curve */ +fix15 depth; +/* + * If two or more output modules are included in the configuration, curve2() + * is called by curve() to output one curve segment. + * If only one output module is included in the configuration, curve() is + * called by proc_outl_data(). + * This function is only called when curve output is enabled. + */ +{ +fix15 x1,y1,x2,y2,x3,y3; +#if DEBUG +printf("CURVE_2(%3.1f, %3.1f, %3.1f, %3.1f, %3.1f, %3.1f)\n", + (real)P1.x / (real)onepix, (real)P1.y / (real)onepix, + (real)P2.x / (real)onepix, (real)P2.y / (real)onepix, + (real)P3.x / (real)onepix, (real)P3.y / (real)onepix); +#endif +x1= RANGECHECK(P1.x,sp_globals.xmin,sp_globals.xmax); +y1= RANGECHECK(P1.y,sp_globals.ymin,sp_globals.ymax); + +x2= RANGECHECK(P2.x,sp_globals.xmin,sp_globals.xmax); +y2= RANGECHECK(P2.y,sp_globals.ymin,sp_globals.ymax); + +x3= RANGECHECK(P3.x,sp_globals.xmin,sp_globals.xmax); +y3= RANGECHECK(P3.y,sp_globals.ymin,sp_globals.ymax); + +curve_to((fix31)x1 << sp_globals.poshift, (fix31)y1 << sp_globals.poshift, + (fix31)x2<< sp_globals.poshift, (fix31)y2 << sp_globals.poshift, + (fix31)x3 << sp_globals.poshift, (fix31)y3 << sp_globals.poshift); +} +#endif + +#if INCL_OUTLINE +FUNCTION void line_outline(P1) +GDECL +point_t P1; /* End point of vector */ +/* + * If two or more output modules are included in the configuration, line2() + * is called by line() to output one vector. + * If only one output module is included in the configuration, line() is + * called by proc_outl_data(). If curve output is enabled, line() is also + * called by split_curve(). + */ +{ +fix15 x1,y1; +#if DEBUG +printf("LINE_2(%3.1f, %3.1f)\n", (real)P1.x / (real)onepix, (real)P1.y / (real)onepix); +#endif +x1= RANGECHECK(P1.x,sp_globals.xmin,sp_globals.xmax); +y1= RANGECHECK(P1.y,sp_globals.ymin,sp_globals.ymax); + +line_to((fix31)x1 << sp_globals.poshift, (fix31)y1 << sp_globals.poshift); +} +#endif + +#if INCL_OUTLINE +FUNCTION void end_contour_outline() +GDECL +/* + * If two or more output modules are included in the configuration, end_contour2() + * is called by end_contour() to signal the end of a contour. + * If only one output module is included in the configuration, end_contour() is + * called by proc_outl_data(). + */ +{ +#if DEBUG +printf("END_CONTOUR_2()\n"); +#endif +close_contour(); +} +#endif + + +#if INCL_OUTLINE +FUNCTION void end_sub_char_outline() +GDECL +/* + * If two or more output modules are included in the configuration, end_sub_char2() + * is called by end_sub_char() to signal the end of sub-character data. + * If only one output module is included in the configuration, end_sub_char() is + * called by make_comp_char(). + */ +{ +#if DEBUG +printf("END_SUB_CHAR_2()\n"); +#endif +} +#endif + + +#if INCL_OUTLINE +FUNCTION boolean end_char_outline() +GDECL +/* + * If two or more output modules are included in the configuration, end_char2() + * is called by end_char() to signal the end of the character data. + * If only one output module is included in the configuration, end_char() is + * called by make_simp_char() and make_comp_char(). + * Returns TRUE if output process is complete + * Returns FALSE to repeat output of the transformed data beginning + * with the first contour (of the first sub-char if compound). + */ +{ +#if DEBUG +printf("END_CHAR_2()\n"); +#endif +close_outline(); +return TRUE; +} +#endif + diff --git a/nx-X11/lib/font/Speedo/out_scrn.c b/nx-X11/lib/font/Speedo/out_scrn.c new file mode 100644 index 000000000..0ea3b1976 --- /dev/null +++ b/nx-X11/lib/font/Speedo/out_scrn.c @@ -0,0 +1,1090 @@ +/* $Xorg: out_scrn.c,v 1.3 2000/08/17 19:46:26 cpqbld Exp $ */ + +/* + +Copyright 1989-1991, Bitstream Inc., Cambridge, MA. +You are hereby granted permission under all Bitstream propriety rights to +use, copy, modify, sublicense, sell, and redistribute the Bitstream Speedo +software and the Bitstream Charter outline font for any purpose and without +restrictions; provided, that this notice is left intact on all copies of such +software or font and that Bitstream's trademark is acknowledged as shown below +on all unmodified copies of such font. + +BITSTREAM CHARTER is a registered trademark of Bitstream Inc. + + +BITSTREAM INC. DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING +WITHOUT LIMITATION THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE. BITSTREAM SHALL NOT BE LIABLE FOR ANY DIRECT OR INDIRECT +DAMAGES, INCLUDING BUT NOT LIMITED TO LOST PROFITS, LOST DATA, OR ANY OTHER +INCIDENTAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF OR IN ANY WAY CONNECTED +WITH THE SPEEDO SOFTWARE OR THE BITSTREAM CHARTER OUTLINE FONT. + +*/ +/* $XFree86: xc/lib/font/Speedo/out_scrn.c,v 1.4 1999/12/27 00:39:25 robin Exp $ */ + + +/*************************** O U T _ S C R N . C ***************************** + * * + * This is an output module for screen-writer mode. * + * * + *****************************************************************************/ + + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include "spdo_prv.h" /* General definitions for Speedo */ + +#define DEBUG 0 +#define LOCAL static +#define ABS(X) ( (X < 0) ? -X : X) + +#if DEBUG +#include <stdio.h> +#define SHOW(X) printf("X = %d\n", X) +#else +#define SHOW(X) +#endif + + +/***** GLOBAL VARIABLES *****/ + +/***** GLOBAL FUNCTIONS *****/ + +/***** EXTERNAL VARIABLES *****/ + +/***** EXTERNAL FUNCTIONS *****/ + +/***** STATIC VARIABLES *****/ + +/***** STATIC FUNCTIONS *****/ + +static void sp_add_intercept_screen(PROTO_DECL2 fix15 y,fix31 x); +static void sp_proc_intercepts_screen(PROTO_DECL1); + + +#if INCL_SCREEN +FUNCTION boolean init_screen( +GDECL +specs_t FONTFAR *specsarg) +/* + * init_out0() is called by sp_set_specs() to initialize the output module. + * Returns TRUE if output module can accept requested specifications. + * Returns FALSE otherwise. + */ +{ +#if DEBUG +printf("INIT_SCREEN()\n"); +#endif +return (TRUE); +} +#endif + + +#if INCL_SCREEN +FUNCTION boolean begin_char_screen( +GDECL +point_t Psw, +point_t Pmin, +point_t Pmax) +/* Called once at the start of the character generation process + */ +{ +#if DEBUG +printf("BEGIN_CHAR_SCREEN(%3.1f, %3.1f, %3.1f, %3.1f, %3.1f, %3.1f\n", + (real)Psw.x / (real)sp_globals.onepix, (real)Psw.y / (real)sp_globals.onepix, + (real)Pmin.x / (real)sp_globals.onepix, (real)Pmin.y / (real)sp_globals.onepix, + (real)Pmax.x / (real)sp_globals.onepix, (real)Pmax.y / (real)sp_globals.onepix); +#endif +if (sp_globals.pixshift > 8) + sp_intercepts.fracpix = sp_globals.onepix << (8 - sp_globals.pixshift); +else + sp_intercepts.fracpix = sp_globals.onepix >> (sp_globals.pixshift - 8); + +init_char_out(Psw,Pmin,Pmax); + +return TRUE; +} +#endif + + +#if INCL_SCREEN +FUNCTION void begin_contour_screen( +GDECL +point_t P1, +boolean outside) +/* Called at the start of each contour + */ +{ + +#if DEBUG +printf("BEGIN_CONTOUR_SCREEN(%3.1f, %3.1f, %s)\n", + (real)P1.x / (real)sp_globals.onepix, (real)P1.y / (real)sp_globals.onepix, outside? "outside": "inside"); +#endif +sp_globals.x0_spxl = P1.x; +sp_globals.y0_spxl = P1.y; +sp_globals.y_pxl = (sp_globals.y0_spxl + sp_globals.pixrnd) >> sp_globals.pixshift; +} +#endif + +#if INCL_SCREEN +FUNCTION void curve_screen( +GDECL +point_t P1, point_t P2, point_t P3, +fix15 depth) +{ +fix31 X0; +fix31 Y0; +fix31 X1; +fix31 Y1; +fix31 X2; +fix31 Y2; +fix31 X3; +fix31 Y3; +#if DEBUG +printf("CURVE_SCREEN(%6.4f, %6.4f, %6.4f, %6.4f, %6.4f, %6.4f)\n", + (real)P1.x / (real)sp_globals.onepix, (real)P1.y / (real)sp_globals.onepix, + (real)P2.x / (real)sp_globals.onepix, (real)P2.y / (real)sp_globals.onepix, + (real)P3.x / (real)sp_globals.onepix, (real)P3.y / (real)sp_globals.onepix); +#endif + + +if (sp_globals.extents_running) /* Accumulate actual character extents if required */ + { + if (P3.x > sp_globals.bmap_xmax) + sp_globals.bmap_xmax = P3.x; + if (P3.x < sp_globals.bmap_xmin) + sp_globals.bmap_xmin = P3.x; + if (P3.y > sp_globals.bmap_ymax) + sp_globals.bmap_ymax = P3.y; + if (P3.y < sp_globals.bmap_ymin) + sp_globals.bmap_ymin = P3.y; + } + +X0 = ((fix31)sp_globals.x0_spxl << sp_globals.poshift) + (fix31)32768; +Y0 = ((fix31)sp_globals.y0_spxl << sp_globals.poshift) + (fix31)32768; +X1 = ((fix31)P1.x << sp_globals.poshift) + (fix31)32768; +Y1 = ((fix31)P1.y << sp_globals.poshift) + (fix31)32768; +X2 = ((fix31)P2.x << sp_globals.poshift) + (fix31)32768; +Y2 = ((fix31)P2.y << sp_globals.poshift) + (fix31)32768; +X3 = ((fix31)P3.x << sp_globals.poshift) + (fix31)32768; +Y3 = ((fix31)P3.y << sp_globals.poshift) + (fix31)32768; + +if (((Y0 - Y3) * sp_globals.tcb.mirror) > 0) + { + sp_intercepts.leftedge = LEFT_INT; + } +else + { + sp_intercepts.leftedge = 0; + } + +scan_curve_screen(X0,Y0,X1,Y1,X2,Y2,X3,Y3); +sp_globals.x0_spxl = P3.x; +sp_globals.y0_spxl = P3.y; +sp_globals.y_pxl = (P3.y + sp_globals.pixrnd) >> sp_globals.pixshift; /* calculate new end-scan sp_globals.line */ +} + +FUNCTION void scan_curve_screen( +GDECL +fix31 X0, fix31 Y0, fix31 X1, fix31 Y1, fix31 X2, fix31 Y2, fix31 X3, fix31 Y3) +/* Called for each curve in the transformed character if curves out enabled + */ +{ +fix31 Pmidx; +fix31 Pmidy; +fix31 Pctrl1x; +fix31 Pctrl1y; +fix31 Pctrl2x; +fix31 Pctrl2y; + +#ifdef DBGCRV +printf("SCAN_CURVE_SCREEN(%6.4f, %6.4f, %6.4f, %6.4f, %6.4f, %6.4f, %6.4f, %6.4f)\n", + (real)(X0-32768) / 65536.0, (real)(Y0-32768) / 65536.0, + (real)(X1-32768) / 65536.0, (real)(Y1-32768) / 65536.0, + (real)(X2-32768) / 65536.0, (real)(Y2-32768) / 65536.0, + (real)(X3-32768) / 65536.0, (real)(Y3-32768) / 65536.0); +#endif + +if (((Y3 >> 16)) == (Y0 >> 16) || (Y3+1) == Y0 || Y3 == (Y0+1)) + { + return; + } +if ((X3 >> 16) == (X0 >> 16)) + { + vert_line_screen(X3,(fix15)(Y0>>16),(fix15)(Y3>>16)); + return; + } +Pmidx = (X0 + (X1 + X2) * 3 + X3 + 4 ) >> 3; +Pmidy = (Y0 + (Y1 + Y2) * 3 + Y3 + 4 ) >> 3; + +Pctrl1x = (X0 + X1 + 1 ) >> 1; +Pctrl1y = (Y0 + Y1 + 1) >> 1; +Pctrl2x = (X0 + (X1 << 1) + X2 + 2 ) >> 2; +Pctrl2y = (Y0 + (Y1 << 1) + Y2 + 2 ) >> 2; +scan_curve_screen(X0,Y0, Pctrl1x, Pctrl1y, Pctrl2x,Pctrl2y, Pmidx,Pmidy); + +Pctrl1x = (X1 + (X2 << 1) + X3 + 2 ) >> 2; +Pctrl1y = (Y1 + (Y2 << 1) + Y3 + 2 ) >> 2; +Pctrl2x = (X2 + X3 + 1 ) >> 1; +Pctrl2y = (Y2 + Y3 + 1 ) >> 1; +scan_curve_screen(Pmidx,Pmidy, Pctrl1x,Pctrl1y, Pctrl2x,Pctrl2y, X3,Y3); +} + +FUNCTION void vert_line_screen( +GDECL +fix31 x, +fix15 y1, fix15 y2) +{ + +#ifdef DBGCRV +printf("VERT_LINE_SCREEN(%6.4f, %6.4f, %6.4f)\n", + (real)(x - 32768) / 65536.0, + (real)(y1 - 32768) / 65536.0, + (real)(y2 - 32768) / 65536.0); +#endif + +if (sp_globals.intercept_oflo) + return; + +if (y1 > y2) /* Line goes downwards ? */ + { + if (y1 > (sp_globals.y_band.band_max + 1)) /* Start point above top of band? */ + y1 = sp_globals.y_band.band_max + 1; /* Adjust start point to top of band */ + if (y2 < sp_globals.y_band.band_min) /* End point below bottom of band? */ + y2 = sp_globals.y_band.band_min; /* Adjust end point bottom of band */ + + y1 -= sp_globals.y_band.band_min; /* Translate start point to band origin */ + y2 -= sp_globals.y_band.band_min; /* Translate end point to band origin */ + + while (y2 < y1) /* At least one intercept left? */ + { + sp_add_intercept_screen(--y1, x); /* Add intercept */ + } + } +else if (y2 > y1) /* Line goes upwards ? */ + { + if (y1 < sp_globals.y_band.band_min) /* Start point below bottom of band? */ + y1 = sp_globals.y_band.band_min; /* Adjust start point to bottom of band */ + if (y2 > (sp_globals.y_band.band_max + 1)) /* End point above top of band? */ + y2 = sp_globals.y_band.band_max + 1; /* Adjust end point to top of band */ + + y1 -= sp_globals.y_band.band_min; /* Translate start point to band origin */ + y2 -= sp_globals.y_band.band_min; /* Translate end point to band origin */ + + while (y1 < y2) /* At least one intercept left? */ + { + sp_add_intercept_screen(y1++, x); /* Add intercept */ + } + } + + +} + +#endif + + +#if INCL_SCREEN +FUNCTION void line_screen( +GDECL +point_t P1) +/* Called for each vector in the transformed character + */ +{ +register fix15 how_many_y; /* # of intercepts at y = n + 1/2 */ +register fix15 yc; /* Current scan-line */ + fix15 temp1; /* various uses */ + fix15 temp2; /* various uses */ +register fix31 dx_dy; /* slope of line in 16.16 form */ +register fix31 xc; /* high-precision (16.16) x coordinate */ + fix15 x0,y0,x1,y1; /* PIX.FRAC start and endpoints */ + +x0 = sp_globals.x0_spxl; /* get start of line (== current point) */ +y0 = sp_globals.y0_spxl; +sp_globals.x0_spxl = x1 = P1.x; /* end of line */ +sp_globals.y0_spxl = y1 = P1.y; /* (also update current point to end of line) */ + +yc = sp_globals.y_pxl; /* current scan line = end of last line */ +sp_globals.y_pxl = (y1 + sp_globals.pixrnd) >> sp_globals.pixshift; /* calculate new end-scan sp_globals.line */ + + +#if DEBUG +printf("LINE_SCREEN(%3.4f, %3.4f)\n", + (real)P1.x/(real)sp_globals.onepix, + (real)P1.y/(real)sp_globals.onepix); +#endif + +if (sp_globals.extents_running) + { + if (sp_globals.x0_spxl > sp_globals.bmap_xmax) + sp_globals.bmap_xmax = sp_globals.x0_spxl; + if (sp_globals.x0_spxl < sp_globals.bmap_xmin) + sp_globals.bmap_xmin = sp_globals.x0_spxl; + if (sp_globals.y0_spxl > sp_globals.bmap_ymax) + sp_globals.bmap_ymax = sp_globals.y0_spxl; + if (sp_globals.y0_spxl < sp_globals.bmap_ymin) + sp_globals.bmap_ymin = sp_globals.y0_spxl; + } + +if (sp_globals.intercept_oflo) return; + +if ((how_many_y = sp_globals.y_pxl - yc) == 0) return; /* Don't draw a null line */ + +xc = (fix31)(x0 + sp_globals.pixrnd) << (16 - sp_globals.pixshift); /* Original x coordinate with built in */ + /* rounding. 16.16 form */ + +if (how_many_y < 0) + { + yc--; /* Predecrment downward lines */ + } + +if ((how_many_y * sp_globals.tcb.mirror) < 0) + { + sp_intercepts.leftedge = LEFT_INT; + } +else + { + sp_intercepts.leftedge = 0; + } + +if (yc > sp_globals.y_band.band_max) /* Is start point above band? */ + { + if (sp_globals.y_pxl > sp_globals.y_band.band_max) return; /* line has to go down! */ + how_many_y = sp_globals.y_pxl - (yc = sp_globals.y_band.band_max) - 1; /* Yes, limit it */ + } + +if (yc < sp_globals.y_band.band_min) /* Is start point below band? */ + { + if (sp_globals.y_pxl < sp_globals.y_band.band_min) return; /* line has to go up! */ + how_many_y = sp_globals.y_pxl - (yc = sp_globals.y_band.band_min); /* Yes, limit it */ + } + +if ( (temp1 = (x1 - x0)) == 0) /* check for vertical line */ + { + dx_dy = 0L; /* Zero slope, leave xc alone */ + goto skip_calc; + } + +/* calculate dx_dy at 16.16 fixed point */ + +dx_dy = ( (fix31)temp1 << 16 )/(fix31)(y1 - y0); + +/* We have to check for a @#$%@# possible multiply overflow */ +/* by doing another @#$*& multiply. In assembly language, */ +/* the program could just check the OVerflow flag or whatever*/ +/* works on the particular processor. This C code is meant */ +/* to be processor independant. */ + +temp1 = (yc << sp_globals.pixshift) - y0 + sp_globals.pixrnd; +/* This sees if the sign bits start at bit 15 */ +/* if they do, no overflow has occurred */ + +temp2 = (fix15)(MULT16(temp1,(fix15)(dx_dy >> 16)) >> 15); + +if ( (temp2 != (fix15)-1) && + (temp2 != 0x0000) ) + { /* Overflow. Pick point closest to yc + .5 */ + if (ABS(temp1) < ABS((yc << sp_globals.pixshift) - y1 + sp_globals.pixrnd)) + { /* use x1 instead of x0 */ + xc = (fix31)(x1 + sp_globals.pixrnd) << (16 - sp_globals.pixshift); + } + goto skip_calc; + } +/* calculate new xc at the center of the *current* scan line */ +/* due to banding, yc may be several lines away from y0 */ +/* xc += (yc + .5 - y0) * dx_dy */ +/* This multiply generates a subpixel delta. */ +/* So we shift it to be a 16.16 delta */ + +xc += ((fix31)temp1 * dx_dy) >> sp_globals.pixshift; + +skip_calc: + +yc -= sp_globals.y_band.band_min; /* yc is now an offset relative to the band */ + +if (how_many_y < 0) + { /* Vector down */ + if ((how_many_y += yc + 1) < 0) how_many_y = 0; /* can't go below 0 */ + while(yc >= how_many_y) + { + sp_add_intercept_screen(yc--,xc); + xc -= dx_dy; + } + } + else + { /* Vector up */ + /* check to see that line doesn't extend beyond top of band */ + if ((how_many_y += yc) > sp_globals.no_y_lists) how_many_y = sp_globals.no_y_lists; + while(yc != how_many_y) + { + sp_add_intercept_screen(yc++,xc); + xc += dx_dy; + } + } +} +#endif + +#if INCL_SCREEN +FUNCTION void end_contour_screen() +GDECL +/* Called after the last vector in each contour + */ +{ +#if DEBUG +printf("END_CONTOUR_SCREEN()\n"); +#endif +sp_intercepts.inttype[sp_globals.next_offset-1] |= END_INT; +} +#endif + + + +#if INCL_SCREEN +FUNCTION boolean end_char_screen() +GDECL +/* Called when all character data has been output + * Return TRUE if output process is complete + * Return FALSE to repeat output of the transformed data beginning + * with the first contour + */ +{ + +fix31 xorg; +fix31 yorg; + +#if INCL_CLIPPING +fix31 em_max, em_min, bmap_max, bmap_min; +#endif + +#if DEBUG +printf("END_CHAR_SCREEN()\n"); +#endif + +if (sp_globals.first_pass) + { + if (sp_globals.bmap_xmax >= sp_globals.bmap_xmin) + { + sp_globals.xmin = (sp_globals.bmap_xmin + sp_globals.pixrnd + 1) >> sp_globals.pixshift; + sp_globals.xmax = (sp_globals.bmap_xmax + sp_globals.pixrnd) >> sp_globals.pixshift; + } + else + { + sp_globals.xmin = sp_globals.xmax = 0; + } + if (sp_globals.bmap_ymax >= sp_globals.bmap_ymin) + { + +#if INCL_CLIPPING + switch(sp_globals.tcb0.xtype) + { + case 1: /* 180 degree rotation */ + if (sp_globals.specs.flags & CLIP_TOP) + { + sp_globals.clip_ymin = (fix31)((fix31)EM_TOP * sp_globals.tcb0.yppo + ((1<<sp_globals.multshift)/2)); + sp_globals.clip_ymin = sp_globals.clip_ymin >> sp_globals.multshift; + bmap_min = (sp_globals.bmap_ymin + sp_globals.pixrnd + 1) >> sp_globals.pixshift; + sp_globals.clip_ymin = -1 * sp_globals.clip_ymin; + if (bmap_min < sp_globals.clip_ymin) + sp_globals.ymin = sp_globals.clip_ymin; + else + sp_globals.ymin = bmap_min; + } + if (sp_globals.specs.flags & CLIP_BOTTOM) + { + sp_globals.clip_ymax = (fix31)((fix31)(-1 * EM_BOT) * sp_globals.tcb0.yppo + ((1<<sp_globals.multshift)/2)); + sp_globals.clip_ymax = sp_globals.clip_ymax >> sp_globals.multshift; + bmap_max = (sp_globals.bmap_ymax + sp_globals.pixrnd) >> sp_globals.pixshift; + if (bmap_max < sp_globals.clip_ymax) + sp_globals.ymax = bmap_max; + else + sp_globals.ymax = sp_globals.clip_ymax; + } + sp_globals.clip_xmax = -sp_globals.xmin; + sp_globals.clip_xmin = ((sp_globals.set_width.x+32768L) >> 16) - + sp_globals.xmin; + break; + case 2: /* 90 degree rotation */ + if (sp_globals.specs.flags & CLIP_TOP) + { + sp_globals.clip_xmin = (fix31)((fix31)(-1 * EM_BOT) * sp_globals.tcb0.yppo + ((1<<sp_globals.multshift)/2)); + sp_globals.clip_xmin = sp_globals.clip_xmin >> sp_globals.multshift; + sp_globals.clip_xmin = -1 * sp_globals.clip_xmin; + bmap_min = (sp_globals.bmap_xmin + sp_globals.pixrnd + 1) >> sp_globals.pixshift; + if (bmap_min > sp_globals.clip_xmin) + sp_globals.clip_xmin = bmap_min; + + /* normalize to x origin */ + sp_globals.clip_xmin -= sp_globals.xmin; + } + if (sp_globals.specs.flags & CLIP_BOTTOM) + { + sp_globals.clip_xmax = (fix31)((fix31)EM_TOP * sp_globals.tcb0.yppo + ((1<<sp_globals.multshift)/2)); + sp_globals.clip_xmax = sp_globals.clip_xmax >> sp_globals.multshift; + bmap_max = (sp_globals.bmap_xmax + sp_globals.pixrnd) >> sp_globals.pixshift; + if (bmap_max < sp_globals.clip_xmax) + sp_globals.xmax = bmap_max; + else + sp_globals.xmax = sp_globals.clip_xmax; + sp_globals.clip_ymax = 0; + if ((sp_globals.specs.flags & CLIP_TOP) && + (sp_globals.ymax > sp_globals.clip_ymax)) + sp_globals.ymax = sp_globals.clip_ymax; + sp_globals.clip_ymin = ((sp_globals.set_width.y+32768L) >> 16); + if ((sp_globals.specs.flags & CLIP_BOTTOM) && + (sp_globals.ymin < sp_globals.clip_ymin)) + sp_globals.ymin = sp_globals.clip_ymin; + /* normalize to x origin */ + sp_globals.clip_xmax -= sp_globals.xmin; + } + break; + case 3: /* 270 degree rotation */ + if (sp_globals.specs.flags & CLIP_TOP) + { + sp_globals.clip_xmin = (fix31)((fix31)EM_TOP * sp_globals.tcb0.yppo + ((1<<sp_globals.multshift)/2)); + sp_globals.clip_xmin = sp_globals.clip_xmin >> sp_globals.multshift; + sp_globals.clip_xmin = -1 * sp_globals.clip_xmin; + bmap_min = (sp_globals.bmap_xmin + sp_globals.pixrnd + 1) >> sp_globals.pixshift; + + /* let the minimum be the larger of these two values */ + if (bmap_min > sp_globals.clip_xmin) + sp_globals.clip_xmin = bmap_min; + + /* normalize the x value to new xorgin */ + sp_globals.clip_xmin -= sp_globals.xmin; + } + if (sp_globals.specs.flags & CLIP_BOTTOM) + { + sp_globals.clip_xmax = (fix31)((fix31)(-1 * EM_BOT) * sp_globals.tcb0.yppo + ((1<<sp_globals.multshift)/2)); + sp_globals.clip_xmax = sp_globals.clip_xmax >> sp_globals.multshift; + bmap_max = (sp_globals.bmap_xmax + sp_globals.pixrnd) >> sp_globals.pixshift; + + /* let the max be the lesser of these two values */ + if (bmap_max < sp_globals.clip_xmax) + { + sp_globals.xmax = bmap_max; + sp_globals.clip_xmax = bmap_max; + } + else + sp_globals.xmax = sp_globals.clip_xmax; + + /* normalize the x value to new x origin */ + sp_globals.clip_xmax -= sp_globals.xmin; + } + /* compute y clip values */ + sp_globals.clip_ymax = ((sp_globals.set_width.y+32768L) >> 16); + if ((sp_globals.specs.flags & CLIP_TOP) && + (sp_globals.ymax > sp_globals.clip_ymax)) + sp_globals.ymax = sp_globals.clip_ymax; + sp_globals.clip_ymin = 0; + if ((sp_globals.specs.flags & CLIP_BOTTOM) && + (sp_globals.ymin < sp_globals.clip_ymin)) + sp_globals.ymin = sp_globals.clip_ymin; + break; + default: /* this is for zero degree rotation and arbitrary rotation */ + if (sp_globals.specs.flags & CLIP_TOP) + { + sp_globals.clip_ymax = (fix31)((fix31)EM_TOP * sp_globals.tcb0.yppo + ((1<<sp_globals.multshift)/2)); + sp_globals.clip_ymax = sp_globals.clip_ymax >> sp_globals.multshift; + bmap_max = (sp_globals.bmap_ymax + sp_globals.pixrnd) >> sp_globals.pixshift; + if (bmap_max > sp_globals.clip_ymax) + sp_globals.ymax = bmap_max; + else + sp_globals.ymax = sp_globals.clip_ymax; + } + if (sp_globals.specs.flags & CLIP_BOTTOM) + { + sp_globals.clip_ymin = (fix31)((fix31)(-1 * EM_BOT) * sp_globals.tcb0.yppo + ((1<<sp_globals.multshift)/2)); + sp_globals.clip_ymin = sp_globals.clip_ymin >> sp_globals.multshift; + sp_globals.clip_ymin = - sp_globals.clip_ymin; + bmap_min = (sp_globals.bmap_ymin + sp_globals.pixrnd + 1) >> sp_globals.pixshift; + if (bmap_min < sp_globals.clip_ymin) + sp_globals.ymin = sp_globals.clip_ymin; + else + sp_globals.ymin = bmap_min; + } + sp_globals.clip_xmin = -sp_globals.xmin; + sp_globals.clip_xmax = ((sp_globals.set_width.x+32768L) >> 16) - + sp_globals.xmin; + break; + } +if ( !(sp_globals.specs.flags & CLIP_TOP)) +#endif + sp_globals.ymax = (sp_globals.bmap_ymax + sp_globals.pixrnd) >> sp_globals.pixshift; + +#if INCL_CLIPPING +if ( !(sp_globals.specs.flags & CLIP_BOTTOM)) +#endif + + sp_globals.ymin = (sp_globals.bmap_ymin + sp_globals.pixrnd + 1) >> sp_globals.pixshift; + } + else + { + sp_globals.ymin = sp_globals.ymax = 0; + } + + /* add in the rounded out part (from xform.) of the left edge */ + if (sp_globals.tcb.xmode == 0) /* for X pix is function of X orus only add the round */ + xorg = (((fix31)sp_globals.xmin << 16) + (sp_globals.rnd_xmin << sp_globals.poshift)); + else + if (sp_globals.tcb.xmode == 1) /* for X pix is function of -X orus only, subtr. round */ + xorg = (((fix31)sp_globals.xmin << 16) - (sp_globals.rnd_xmin << sp_globals.poshift)) ; + else + xorg = (fix31)sp_globals.xmin << 16; /* for other cases don't use round on x */ + + if (sp_globals.tcb.ymode == 2) /* for Y pix is function of X orus only, add round error */ + yorg = (((fix31)sp_globals.ymin << 16) + (sp_globals.rnd_xmin << sp_globals.poshift)); + else + if (sp_globals.tcb.ymode == 3) /* for Y pix is function of -X orus only, sub round */ + yorg = (((fix31)sp_globals.ymin << 16) - (sp_globals.rnd_xmin << sp_globals.poshift)); + else /* all other cases have no round error on yorg */ + yorg = (fix31)sp_globals.ymin << 16; + + open_bitmap(sp_globals.set_width.x, sp_globals.set_width.y, xorg, yorg, + sp_globals.xmax - sp_globals.xmin, sp_globals.ymax - sp_globals.ymin); + if (sp_globals.intercept_oflo) + { + sp_globals.y_band.band_min = sp_globals.ymin; + sp_globals.y_band.band_max = sp_globals.ymax; + init_intercepts_out(); + sp_globals.first_pass = FALSE; + sp_globals.extents_running = FALSE; + return FALSE; + } + else + { + sp_proc_intercepts_screen(); + close_bitmap(); + return TRUE; + } + } +else + { + if (sp_globals.intercept_oflo) + { + reduce_band_size_out(); + init_intercepts_out(); + return FALSE; + } + else + { + sp_proc_intercepts_screen(); + if (next_band_out()) + { + init_intercepts_out(); + return FALSE; + } + close_bitmap(); + return TRUE; + } + } +} +#endif + +#if INCL_SCREEN +FUNCTION LOCAL void sp_add_intercept_screen( +GDECL +fix15 y, /* Y coordinate in relative pixel units */ + /* (0 is lowest sample in band) */ +fix31 x) /* X coordinate of intercept in subpixel units */ + +/* Called by line() to add an intercept to the intercept list structure + */ + +{ +register fix15 from; /* Insertion pointers for the linked list sort */ +register fix15 to; +register fix15 xloc; +register fix15 xfrac; + +#if DEBUG +printf(" Add intercept(%2d, %x)\n", y + sp_globals.y_band.band_min, x); + +/* Bounds checking IS done in debug mode */ +if (y < 0) /* Y value below bottom of current band? */ + { + printf(" Intecerpt less than 0!!!\007\n"); + return; + } + +if (y > (sp_globals.no_y_lists - 1)) /* Y value above top of current band? */ + { + printf(" Intercept too big for band!!!!!\007\n"); + return; + } +#endif + +/* Store new values */ + +sp_intercepts.car[sp_globals.next_offset] = xloc = (fix15)(x >> 16); +sp_intercepts.inttype[sp_globals.next_offset] = sp_intercepts.leftedge | (xfrac = ((x >> 8) & FRACTION)); + +/* Find slot to insert new element (between from and to) */ + +from = y; /* Start at list head */ + +while( (to = sp_intercepts.cdr[from]) != 0) /* Until to == end of list */ + { + if (xloc < sp_intercepts.car[to]) /* If next item is larger than or same as this one... */ + goto insert_element; /* ... drop out and insert here */ + else if (xloc == sp_intercepts.car[to] && xfrac < (sp_intercepts.inttype[to] & FRACTION)) + goto insert_element; /* ... drop out and insert here */ + from = to; /* move forward in list */ + } + +insert_element: /* insert element "sp_globals.next_offset" between elements "from" */ + /* and "to" */ + +sp_intercepts.cdr[from] = sp_globals.next_offset; +sp_intercepts.cdr[sp_globals.next_offset] = to; + +if (++sp_globals.next_offset >= MAX_INTERCEPTS) /* Intercept buffer full? */ + { + sp_globals.intercept_oflo = TRUE; +/* There may be a few more calls to "add_intercept" from the current line */ +/* To avoid problems, we set next_offset to a safe value. We don't care */ +/* if the intercept table gets trashed at this point */ + sp_globals.next_offset = sp_globals.first_offset; + } +} + +#endif + +#if INCL_SCREEN +FUNCTION LOCAL void sp_proc_intercepts_screen() +GDECL + +/* Called by sp_make_char to output accumulated intercept lists + * Clips output to sp_globals.xmin, sp_globals.xmax, sp_globals.ymin, sp_globals.ymax boundaries + */ +{ +register fix15 i,j, jplus1, iminus1; +fix15 k,nextk, previ; +register fix15 from, to; /* Start and end of run in pixel units + relative to left extent of character */ +register fix15 y; +register fix15 scan_line; + fix15 first_y, last_y; + fix15 xsave; + + +fix15 diff; + +#if DEBUG +printf("\nPROC_INTERCEPTS_SCREEN: Intercept lists before:\n"); +#endif + +#if INCL_CLIPPING +if ((sp_globals.specs.flags & CLIP_LEFT) != 0) + clipleft = TRUE; +else + clipleft = FALSE; +if ((sp_globals.specs.flags & CLIP_RIGHT) != 0) + clipright = TRUE; +else + clipright = FALSE; +if (clipleft || clipright) + { + xmax = sp_globals.clip_xmax + sp_globals.xmin; + xmin = sp_globals.clip_xmin + sp_globals.xmin; + } +if (!clipright) + xmax = ((sp_globals.set_width.x+32768L) >> 16); +#endif + +if ((first_y = sp_globals.y_band.band_max) >= sp_globals.ymax) + first_y = sp_globals.ymax - 1; /* Clip to sp_globals.ymax boundary */ + +if ((last_y = sp_globals.y_band.band_min) < sp_globals.ymin) + last_y = sp_globals.ymin; /* Clip to sp_globals.ymin boundary */ + +last_y -= sp_globals.y_band.band_min; + +#if DEBUG +/* Print out all of the intercept info */ +scan_line = sp_globals.ymax - first_y - 1; + +for (y = first_y - sp_globals.y_band.band_min; y >= last_y; y--, scan_line++) + { + i = y; /* Index head of intercept list */ + while ((i = sp_intercepts.cdr[i]) != 0) /* Link to next intercept if present */ + { + if ((from = sp_intercepts.car[i] - sp_globals.xmin) < 0) + from = 0; /* Clip to sp_globals.xmin boundary */ + i = sp_intercepts.cdr[i]; /* Link to next intercept */ + if (i == 0) /* End of list? */ + { + printf("****** proc_intercepts: odd number of intercepts\n"); + break; + } + if ((to = sp_intercepts.car[i]) > sp_globals.xmax) + to = sp_globals.xmax - sp_globals.xmin; /* Clip to sp_globals.xmax boundary */ + else + to -= sp_globals.xmin; + printf(" Y = %2d (scanline %2d): %d %d:\n", + y + sp_globals.y_band.band_min, scan_line, from, to); + } + } +#endif + +/* CHECK INTERCEPT LIST FOR DROPOUT AND WINDING, FIX IF NECESSARY */ + +for (y = first_y - sp_globals.y_band.band_min; y >= last_y; y--) + { + previ = y; + i = sp_intercepts.cdr[y]; /* Index head of intercept list */ + while (i != 0) /* Link to next intercept if present */ + { + j = i; + i = sp_intercepts.cdr[i]; /* Link to next intercept */ + if (sp_intercepts.inttype[i] & LEFT_INT) + { + if (sp_intercepts.inttype[j] & LEFT_INT) + { + do { i = sp_intercepts.cdr[i]; } while (sp_intercepts.inttype[i] & LEFT_INT); + do { i = sp_intercepts.cdr[i]; } while (sp_intercepts.cdr[i] && !(sp_intercepts.inttype[sp_intercepts.cdr[i]] & LEFT_INT)); + sp_intercepts.cdr[j] = i; + } + else + { + xsave = sp_intercepts.car[j]; + sp_intercepts.car[j] = sp_intercepts.car[i]; + sp_intercepts.car[i] = xsave; + + xsave = sp_intercepts.inttype[j]; + sp_intercepts.inttype[j] = sp_intercepts.inttype[i] & FRACTION; + sp_intercepts.inttype[i] = xsave | LEFT_INT; + + sp_intercepts.cdr[previ] = i; + sp_intercepts.cdr[j] = sp_intercepts.cdr[i]; + sp_intercepts.cdr[i] = j; + i = j; + j = sp_intercepts.cdr[previ]; + } + } + + if (sp_intercepts.car[j] < sp_globals.xmin) + sp_intercepts.car[j] = sp_globals.xmin; /* Clip to sp_globals.xmin boundary */ + + if (sp_intercepts.car[i] > sp_globals.xmax) + sp_intercepts.car[i] = sp_globals.xmax; + + if (sp_intercepts.car[j] >= sp_intercepts.car[i]) + { + if ((ufix16)(sp_intercepts.inttype[j] & FRACTION) + (ufix16)(sp_intercepts.inttype[i] & FRACTION) > sp_intercepts.fracpix) + ++sp_intercepts.car[i]; + else + --sp_intercepts.car[j]; + } + if (sp_globals.first_pass) + { + if (sp_intercepts.inttype[i-1] & END_INT) + { + for (iminus1 = i+1; !(sp_intercepts.inttype[iminus1] & END_INT); iminus1++) + ; + } + else + iminus1 = i-1; + + if (sp_intercepts.inttype[j] & END_INT) + { + for (jplus1 = j-1; !(sp_intercepts.inttype[jplus1] & END_INT); jplus1--) + ; + jplus1++; + } + else + jplus1 = j+1; + + if ((sp_intercepts.inttype[iminus1] & LEFT_INT)) + { + if ( sp_intercepts.car[jplus1] > sp_intercepts.car[i]) + { + diff = sp_intercepts.car[jplus1] - sp_intercepts.car[i]; + sp_intercepts.car[i] += diff/2; + sp_intercepts.car[jplus1] -= diff/2; + if (diff & 1) + { + if ((ufix16)(sp_intercepts.inttype[i] & FRACTION) + (ufix16)(sp_intercepts.inttype[jplus1] & FRACTION) > sp_intercepts.fracpix) + sp_intercepts.car[i] ++; + else + sp_intercepts.car[jplus1]--; + } + } + } + else if (!(sp_intercepts.inttype[jplus1] & LEFT_INT)) + { + if (sp_intercepts.car[iminus1] < sp_intercepts.car[j]) + { + diff = sp_intercepts.car[j] - sp_intercepts.car[iminus1]; + sp_intercepts.car[j] -= diff/2; + sp_intercepts.car[iminus1] += diff/2; + if (diff & 1) + { + if ((ufix16)(sp_intercepts.inttype[j] & FRACTION) + + (ufix16)(sp_intercepts.inttype[iminus1] & FRACTION) > sp_intercepts.fracpix) + sp_intercepts.car[iminus1]++; + else + sp_intercepts.car[j]--; + } + } + } + if (sp_globals.tcb.mirror == -1) + { + if (sp_intercepts.inttype[j-1] & END_INT) + { + for (jplus1 = j+1; !(sp_intercepts.inttype[jplus1] & END_INT); jplus1++) + ; + } + else + { + jplus1 = j-1; + } + } + + if (!(sp_intercepts.inttype[jplus1] & LEFT_INT) && + sp_intercepts.car[j] > sp_intercepts.car[jplus1]) + { + k = sp_intercepts.cdr[y - 1]; + while (k > 0) + { + nextk = sp_intercepts.cdr[k]; + if (!(sp_intercepts.inttype[k] & LEFT_INT) && + (sp_intercepts.inttype[nextk] & LEFT_INT) && + sp_intercepts.car[nextk] > sp_intercepts.car[jplus1]) + { + if ((diff=sp_intercepts.car[j] - sp_intercepts.car[k]) > 0) + { + if (diff <= (sp_intercepts.car[nextk] - sp_intercepts.car[jplus1])) + { + sp_intercepts.car[j] -= diff/2; + sp_intercepts.car[k] += diff/2; + if (diff & 1) + { + if ((ufix16)(sp_intercepts.inttype[j] & FRACTION) + + (ufix16)(sp_intercepts.inttype[k] & FRACTION) > sp_intercepts.fracpix) + sp_intercepts.car[j]--; + else + sp_intercepts.car[k]++; + } + } + else + { + diff = sp_intercepts.car[nextk] - sp_intercepts.car[jplus1]; + sp_intercepts.car[nextk] -= diff/2; + sp_intercepts.car[jplus1] += diff/2; + if (diff & 1) + { + if ((ufix16)(sp_intercepts.inttype[jplus1] & FRACTION) + + (ufix16)(sp_intercepts.inttype[nextk] & FRACTION) > sp_intercepts.fracpix) + sp_intercepts.car[nextk]--; + else + sp_intercepts.car[jplus1]++; + } + } + } + break; + } + k = nextk; + } + } + if (j > 0 && sp_intercepts.car[j-1] > sp_intercepts.car[i] && !(sp_intercepts.inttype[j-1] & END_INT)) + { + diff = sp_intercepts.car[j-1] - sp_intercepts.car[i]; + sp_intercepts.car[i] += diff/2; + sp_intercepts.car[j-1] -= diff/2; + if (diff & 1) + { + if ((ufix16)(sp_intercepts.inttype[i] & FRACTION) + (ufix16)(sp_intercepts.inttype[j-1] & FRACTION) > sp_intercepts.fracpix) + sp_intercepts.car[i]++; + else + sp_intercepts.car[j-1]--; + } + } + if (sp_intercepts.car[i+1] < sp_intercepts.car[j] && !(sp_intercepts.inttype[i] & END_INT)) + { + diff = sp_intercepts.car[j] - sp_intercepts.car[i+1]; + sp_intercepts.car[j] -= diff/2; + sp_intercepts.car[i+1] += diff/2; + if (diff & 1) + { + if ((ufix16)(sp_intercepts.inttype[j] & FRACTION) + (ufix16)(sp_intercepts.inttype[i+1] & FRACTION) > sp_intercepts.fracpix) + sp_intercepts.car[i+1]++; + else + sp_intercepts.car[j]--; + } + + } + previ = i; + } + i = sp_intercepts.cdr[i]; + } + } + +#if DEBUG +printf("\nPROC_INTERCEPTS_SCREEN: Intercept lists after:\n"); +/* Print out all of the intercept info */ +scan_line = sp_globals.ymax - first_y - 1; + +for (y = first_y - sp_globals.y_band.band_min; y >= last_y; y--, scan_line++) + { + i = y; /* Index head of intercept list */ + while ((i = sp_intercepts.cdr[i]) != 0) /* Link to next intercept if present */ + { + if ((from = sp_intercepts.car[i] - sp_globals.xmin) < 0) + from = 0; /* Clip to sp_globals.xmin boundary */ + i = sp_intercepts.cdr[i]; /* Link to next intercept */ + if (i == 0) /* End of list? */ + { + printf("****** proc_intercepts: odd number of intercepts\n"); + break; + } + if ((to = sp_intercepts.car[i]) > sp_globals.xmax) + to = sp_globals.xmax - sp_globals.xmin; /* Clip to sp_globals.xmax boundary */ + else + to -= sp_globals.xmin; + printf(" Y = %2d (scanline %2d): %d %d:\n", + y + sp_globals.y_band.band_min, scan_line, from, to); + } + } +#endif + +/* INTERCEPTS ALL PATCHED, NOW DRAW THE IMAGE */ +scan_line = sp_globals.ymax - first_y - 1; + +for (y = first_y - sp_globals.y_band.band_min; y >= last_y; y--, scan_line++) + { + i = sp_intercepts.cdr[y]; /* Index head of intercept list */ + while (i != 0) /* Link to next intercept if present */ + { + from = sp_intercepts.car[i]; + i = sp_intercepts.cdr[i]; /* Link to next intercept */ + to = sp_intercepts.car[i]; +#if INCL_CLIPPING + if (clipleft) + { + if (to <= xmin) + { + i = sp_intercepts.cdr[i]; + continue; + } + if (from < xmin) + from = xmin; + } + if (clipright) + { + if (from >= xmax) + { + i = sp_intercepts.cdr[i]; + continue; + } + if (to > xmax) + to = xmax; + } +#endif + set_bitmap_bits(scan_line, from-sp_globals.xmin, to-sp_globals.xmin); + i = sp_intercepts.cdr[i]; + } + } +} + +#endif diff --git a/nx-X11/lib/font/Speedo/out_util.c b/nx-X11/lib/font/Speedo/out_util.c new file mode 100644 index 000000000..171241030 --- /dev/null +++ b/nx-X11/lib/font/Speedo/out_util.c @@ -0,0 +1,341 @@ +/* $Xorg: out_util.c,v 1.3 2000/08/17 19:46:26 cpqbld Exp $ */ + +/* + +Copyright 1989-1991, Bitstream Inc., Cambridge, MA. +You are hereby granted permission under all Bitstream propriety rights to +use, copy, modify, sublicense, sell, and redistribute the Bitstream Speedo +software and the Bitstream Charter outline font for any purpose and without +restrictions; provided, that this notice is left intact on all copies of such +software or font and that Bitstream's trademark is acknowledged as shown below +on all unmodified copies of such font. + +BITSTREAM CHARTER is a registered trademark of Bitstream Inc. + + +BITSTREAM INC. DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING +WITHOUT LIMITATION THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE. BITSTREAM SHALL NOT BE LIABLE FOR ANY DIRECT OR INDIRECT +DAMAGES, INCLUDING BUT NOT LIMITED TO LOST PROFITS, LOST DATA, OR ANY OTHER +INCIDENTAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF OR IN ANY WAY CONNECTED +WITH THE SPEEDO SOFTWARE OR THE BITSTREAM CHARTER OUTLINE FONT. + +*/ +/* $XFree86: xc/lib/font/Speedo/out_util.c,v 1.2 1999/02/07 06:18:17 dawes Exp $ */ + + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#define DEBUG 0 + +/*************************** O U T _ U T I L . C ***************************** + * * + * This is a utility module share by all bitmap output modules * + * * + *****************************************************************************/ + + +#include "spdo_prv.h" /* General definitions for Speedo */ +/* absolute value function */ +#define ABS(X) ( (X < 0) ? -X : X) +#if INCL_BLACK || INCL_2D || INCL_SCREEN + +FUNCTION void init_char_out( +GDECL +point_t Psw, point_t Pmin, point_t Pmax) +{ +sp_globals.set_width.x = (fix31)Psw.x << sp_globals.poshift; +sp_globals.set_width.y = (fix31)Psw.y << sp_globals.poshift; +set_first_band_out(Pmin, Pmax); +init_intercepts_out(); +if (sp_globals.normal) + { + sp_globals.bmap_xmin = Pmin.x; + sp_globals.bmap_xmax = Pmax.x; + sp_globals.bmap_ymin = Pmin.y; + sp_globals.bmap_ymax = Pmax.y; + sp_globals.extents_running = FALSE; + } +else + { + sp_globals.bmap_xmin = 32000; + sp_globals.bmap_xmax = -32000; + sp_globals.bmap_ymin = 32000; + sp_globals.bmap_ymax = -32000; + sp_globals.extents_running = TRUE; + } +sp_globals.first_pass = TRUE; +} + +FUNCTION void begin_sub_char_out( +GDECL +point_t Psw, +point_t Pmin, +point_t Pmax) +/* Called at the start of each sub-character in a composite character + */ +{ +#if DEBUG +printf("BEGIN_SUB_CHAR_out(%3.1f, %3.1f, %3.1f, %3.1f, %3.1f, %3.1f\n", + (real)Psw.x / (real)sp_globals.onepix, (real)Psw.y / (real)sp_globals.onepix, + (real)Pmin.x / (real)sp_globals.onepix, (real)Pmin.y / (real)sp_globals.onepix, + (real)Pmax.x / (real)sp_globals.onepix, (real)Pmax.y / (real)sp_globals.onepix); +#endif +restart_intercepts_out(); +if (!sp_globals.extents_running) + { + sp_globals.bmap_xmin = 32000; + sp_globals.bmap_xmax = -32000; + sp_globals.bmap_ymin = 32000; + sp_globals.bmap_ymax = -32000; + sp_globals.extents_running = TRUE; + } +} + +FUNCTION void curve_out( +GDECL +point_t P1, point_t P2, point_t P3, +fix15 depth) +/* Called for each curve in the transformed character if curves out enabled + */ +{ +#if DEBUG +printf("CURVE_OUT(%3.1f, %3.1f, %3.1f, %3.1f, %3.1f, %3.1f)\n", + (real)P1.x / (real)sp_globals.onepix, (real)P1.y / (real)sp_globals.onepix, + (real)P2.x / (real)sp_globals.onepix, (real)P2.y / (real)sp_globals.onepix, + (real)P3.x / (real)sp_globals.onepix, (real)P3.y / (real)sp_globals.onepix); +#endif +} + + + +FUNCTION void end_contour_out() +GDECL +/* Called after the last vector in each contour + */ +{ +#if DEBUG +printf("END_CONTOUR_OUT()\n"); +#endif +} + + +FUNCTION void end_sub_char_out() +GDECL +/* Called after the last contour in each sub-character in a compound character + */ +{ +#if DEBUG +printf("END_SUB_CHAR_OUT()\n"); +#endif +} + + +FUNCTION void init_intercepts_out() +GDECL +/* Called to initialize intercept storage data structure + */ + +{ +fix15 i; +fix15 no_lists; + +#if DEBUG +printf(" Init intercepts (Y band from %d to %d)\n", sp_globals.y_band.band_min, sp_globals.y_band.band_max); +if (sp_globals.x_scan_active) + printf(" (X band from %d to %d)\n", sp_globals.x_band.band_min, sp_globals.x_band.band_max); +#endif + +sp_globals.intercept_oflo = FALSE; + +sp_globals.no_y_lists = sp_globals.y_band.band_max - sp_globals.y_band.band_min + 1; +#if INCL_2D +if (sp_globals.output_mode == MODE_2D) + { + sp_globals.no_x_lists = sp_globals.x_scan_active ? + sp_globals.x_band.band_max - sp_globals.x_band.band_min + 1 : 0; + no_lists = sp_globals.no_y_lists + sp_globals.no_x_lists; + } +else +#endif + no_lists = sp_globals.no_y_lists; + +#if INCL_2D +sp_globals.y_band.band_floor = 0; +sp_globals.y_band.band_ceiling = sp_globals.no_y_lists; +#endif + +if (no_lists >= MAX_INTERCEPTS) /* Not enough room for list table? */ + { + no_lists = sp_globals.no_y_lists = MAX_INTERCEPTS; + sp_globals.intercept_oflo = TRUE; + sp_globals.y_band.band_min = sp_globals.y_band.band_max - sp_globals.no_y_lists + 1; +#if INCL_2D + sp_globals.y_band.band_array_offset = sp_globals.y_band.band_min; + sp_globals.y_band.band_ceiling = sp_globals.no_y_lists; + sp_globals.no_x_lists = 0; + sp_globals.x_scan_active = FALSE; +#endif + } + +for (i = 0; i < no_lists; i++) /* For each active value... */ + { +#if INCL_SCREEN + if (sp_globals.output_mode == MODE_SCREEN) + sp_intercepts.inttype[i]=0; +#endif + sp_intercepts.cdr[i] = 0; /* Mark each intercept list empty */ + } + +sp_globals.first_offset = sp_globals.next_offset = no_lists; + +#if INCL_2D +sp_globals.y_band.band_array_offset = sp_globals.y_band.band_min; +sp_globals.x_band.band_array_offset = sp_globals.x_band.band_min - sp_globals.no_y_lists; +sp_globals.x_band.band_floor = sp_globals.no_y_lists; +sp_globals.x_band.band_ceiling = no_lists; +#endif +#if INCL_SCREEN +sp_intercepts.inttype[sp_globals.no_y_lists-1] = END_INT; +#endif + +} + + +FUNCTION void restart_intercepts_out() +GDECL + +/* Called by sp_make_char when a new sub character is started + * Freezes current sorted lists + */ + +{ + +#if DEBUG +printf(" Restart intercepts:\n"); +#endif +sp_globals.first_offset = sp_globals.next_offset; +} + + + +FUNCTION void set_first_band_out( +GDECL +point_t Pmin, +point_t Pmax) +{ + +sp_globals.ymin = Pmin.y; +sp_globals.ymax = Pmax.y; + +sp_globals.ymin = (sp_globals.ymin - sp_globals.onepix + 1) >> sp_globals.pixshift; +sp_globals.ymax = (sp_globals.ymax + sp_globals.onepix - 1) >> sp_globals.pixshift; + +#if INCL_CLIPPING + switch(sp_globals.tcb0.xtype) + { + case 1: /* 180 degree rotation */ + if (sp_globals.specs.flags & CLIP_TOP) + { + sp_globals.clip_ymin = (fix31)((fix31)EM_TOP * sp_globals.tcb0.yppo + ((1<<sp_globals.multshift)/2)); + sp_globals.clip_ymin = sp_globals.clip_ymin >> sp_globals.multshift; + sp_globals.clip_ymin = -1* sp_globals.clip_ymin; + if (sp_globals.ymin < sp_globals.clip_ymin) + sp_globals.ymin = sp_globals.clip_ymin; + } + if (sp_globals.specs.flags & CLIP_BOTTOM) + { + sp_globals.clip_ymax = (fix31)((fix31)(-1 * EM_BOT) * sp_globals.tcb0.yppo + ((1<<sp_globals.multshift)/2)); + sp_globals.clip_ymax = sp_globals.clip_ymax >> sp_globals.multshift; + if (sp_globals.ymax > sp_globals.clip_ymax) + sp_globals.ymax = sp_globals.clip_ymax; + } + break; + case 2: /* 90 degree rotation */ + sp_globals.clip_ymax = 0; + if ((sp_globals.specs.flags & CLIP_TOP) && + (sp_globals.ymax > sp_globals.clip_ymax)) + sp_globals.ymax = sp_globals.clip_ymax; + sp_globals.clip_ymin = ((sp_globals.set_width.y+32768L) >> 16); + if ((sp_globals.specs.flags & CLIP_BOTTOM) && + (sp_globals.ymin < sp_globals.clip_ymin)) + sp_globals.ymin = sp_globals.clip_ymin; + break; + case 3: /* 270 degree rotation */ + sp_globals.clip_ymax = ((sp_globals.set_width.y+32768L) >> 16); + if ((sp_globals.specs.flags & CLIP_TOP) && + (sp_globals.ymax > sp_globals.clip_ymax)) + sp_globals.ymax = sp_globals.clip_ymax; + sp_globals.clip_ymin = 0; + if ((sp_globals.specs.flags & CLIP_BOTTOM) && + (sp_globals.ymin < sp_globals.clip_ymin)) + sp_globals.ymin = sp_globals.clip_ymin; + break; + default: /* this is for zero degree rotation and arbitrary rotation */ + if (sp_globals.specs.flags & CLIP_TOP) + { + sp_globals.clip_ymax = (fix31)((fix31)EM_TOP * sp_globals.tcb0.yppo + ((1<<sp_globals.multshift)/2)); + sp_globals.clip_ymax = sp_globals.clip_ymax >> sp_globals.multshift; + if (sp_globals.ymax > sp_globals.clip_ymax) + sp_globals.ymax = sp_globals.clip_ymax; + } + if (sp_globals.specs.flags & CLIP_BOTTOM) + { + sp_globals.clip_ymin = (fix31)((fix31)(-1 * EM_BOT) * sp_globals.tcb0.yppo + ((1<<sp_globals.multshift)/2)); + sp_globals.clip_ymin = sp_globals.clip_ymin >> sp_globals.multshift; + sp_globals.clip_ymin = - sp_globals.clip_ymin; + if (sp_globals.ymin < sp_globals.clip_ymin) + sp_globals.ymin = sp_globals.clip_ymin; + } + break; + } +#endif +sp_globals.y_band.band_min = sp_globals.ymin; +sp_globals.y_band.band_max = sp_globals.ymax - 1; + +sp_globals.xmin = (Pmin.x + sp_globals.pixrnd) >> sp_globals.pixshift; +sp_globals.xmax = (Pmax.x + sp_globals.pixrnd) >> sp_globals.pixshift; + + +#if INCL_2D +sp_globals.x_band.band_min = sp_globals.xmin - 1; /* subtract one pixel of "safety margin" */ +sp_globals.x_band.band_max = sp_globals.xmax /* - 1 + 1 */; /* Add one pixel of "safety margin" */ +#endif +} + + + + + + + +FUNCTION void reduce_band_size_out() +GDECL +{ +sp_globals.y_band.band_min = sp_globals.y_band.band_max - ((sp_globals.y_band.band_max - sp_globals.y_band.band_min) >> 1); +#if INCL_2D +sp_globals.y_band.band_array_offset = sp_globals.y_band.band_min; +#endif +} + + +FUNCTION boolean next_band_out() +GDECL +{ +fix15 tmpfix15; + +if (sp_globals.y_band.band_min <= sp_globals.ymin) + return FALSE; +tmpfix15 = sp_globals.y_band.band_max - sp_globals.y_band.band_min; +sp_globals.y_band.band_max = sp_globals.y_band.band_min - 1; +sp_globals.y_band.band_min = sp_globals.y_band.band_max - tmpfix15; +if (sp_globals.y_band.band_min < sp_globals.ymin) + sp_globals.y_band.band_min = sp_globals.ymin; +#if INCL_2D +sp_globals.y_band.band_array_offset = sp_globals.y_band.band_min; +#endif +return TRUE; +} +#endif + diff --git a/nx-X11/lib/font/Speedo/reset.c b/nx-X11/lib/font/Speedo/reset.c new file mode 100644 index 000000000..4cb9f7de0 --- /dev/null +++ b/nx-X11/lib/font/Speedo/reset.c @@ -0,0 +1,131 @@ +/* $Xorg: reset.c,v 1.3 2000/08/17 19:46:26 cpqbld Exp $ */ + +/* + +Copyright 1989-1991, Bitstream Inc., Cambridge, MA. +You are hereby granted permission under all Bitstream propriety rights to +use, copy, modify, sublicense, sell, and redistribute the Bitstream Speedo +software and the Bitstream Charter outline font for any purpose and without +restrictions; provided, that this notice is left intact on all copies of such +software or font and that Bitstream's trademark is acknowledged as shown below +on all unmodified copies of such font. + +BITSTREAM CHARTER is a registered trademark of Bitstream Inc. + + +BITSTREAM INC. DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING +WITHOUT LIMITATION THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE. BITSTREAM SHALL NOT BE LIABLE FOR ANY DIRECT OR INDIRECT +DAMAGES, INCLUDING BUT NOT LIMITED TO LOST PROFITS, LOST DATA, OR ANY OTHER +INCIDENTAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF OR IN ANY WAY CONNECTED +WITH THE SPEEDO SOFTWARE OR THE BITSTREAM CHARTER OUTLINE FONT. + +*/ +/* $XFree86: xc/lib/font/Speedo/reset.c,v 1.2 1999/02/07 06:18:17 dawes Exp $ */ + + + +/******************************* R E S E T . C ******************************* + * * + * This module provides initialization functions. * + * * + ****************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include "spdo_prv.h" /* General definitions for Speedo */ +#include "keys.h" /* Font decryption keys */ + +#define DEBUG 0 + +#if DEBUG +#include <stdio.h> +#define SHOW(X) printf("X = %d\n", X) +#else +#define SHOW(X) +#endif + +/***** GLOBAL VARIABLES *****/ + +/***** GLOBAL FUNCTIONS *****/ + +/***** EXTERNAL VARIABLES *****/ + +/***** EXTERNAL FUNCTIONS *****/ + +/***** STATIC VARIABLES *****/ + +/***** STATIC FUNCTIONS *****/ + + +FUNCTION void reset() +GDECL +/* + * Called by the host software to intialize the Speedo mechanism + */ +{ +sp_globals.specs_valid = FALSE; /* Flag specs not valid */ + +/* Reset decryption key */ +sp_globals.key32 = (KEY3 << 8) | KEY2; +sp_globals.key4 = KEY4; +sp_globals.key6 = KEY6; +sp_globals.key7 = KEY7; +sp_globals.key8 = KEY8; + +#if INCL_RULES +sp_globals.constr.font_id_valid = FALSE; +#endif + +#if INCL_MULTIDEV +#if INCL_BLACK || INCL_SCREEN || INCL_2D +sp_globals.bitmap_device_set = FALSE; +#endif +#if INCL_OUTLINE +sp_globals.outline_device_set = FALSE; +#endif +#endif +} + +#if INCL_KEYS +FUNCTION void set_key( +GDECL +ufix8 key[]) /* Specified decryption key */ +/* + * Dynamically sets font decryption key. + */ +{ +sp_globals.key32 = ((ufix16)key[3] << 8) | key[2]; +sp_globals.key4 = key[4]; +sp_globals.key6 = key[6]; +sp_globals.key7 = key[7]; +sp_globals.key8 = key[8]; +} +#endif + + + +FUNCTION ufix16 get_cust_no( +GDECL +buff_t font_buff) +/* + returns customer number from font +*/ +{ +ufix8 FONTFAR *hdr2_org; +ufix16 private_off; + +private_off = read_word_u(font_buff.org + FH_HEDSZ); +if (private_off + FH_CUSNR > font_buff.no_bytes) + { + report_error(1); /* Insufficient font data loaded */ + return FALSE; + } + +hdr2_org = font_buff.org + private_off; + +return (read_word_u(hdr2_org + FH_CUSNR)); +} + + diff --git a/nx-X11/lib/font/Speedo/set_spcs.c b/nx-X11/lib/font/Speedo/set_spcs.c new file mode 100644 index 000000000..b69b13f34 --- /dev/null +++ b/nx-X11/lib/font/Speedo/set_spcs.c @@ -0,0 +1,773 @@ +/* $Xorg: set_spcs.c,v 1.3 2000/08/17 19:46:26 cpqbld Exp $ */ + +/* + +Copyright 1989-1991, Bitstream Inc., Cambridge, MA. +You are hereby granted permission under all Bitstream propriety rights to +use, copy, modify, sublicense, sell, and redistribute the Bitstream Speedo +software and the Bitstream Charter outline font for any purpose and without +restrictions; provided, that this notice is left intact on all copies of such +software or font and that Bitstream's trademark is acknowledged as shown below +on all unmodified copies of such font. + +BITSTREAM CHARTER is a registered trademark of Bitstream Inc. + + +BITSTREAM INC. DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING +WITHOUT LIMITATION THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE. BITSTREAM SHALL NOT BE LIABLE FOR ANY DIRECT OR INDIRECT +DAMAGES, INCLUDING BUT NOT LIMITED TO LOST PROFITS, LOST DATA, OR ANY OTHER +INCIDENTAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF OR IN ANY WAY CONNECTED +WITH THE SPEEDO SOFTWARE OR THE BITSTREAM CHARTER OUTLINE FONT. + +*/ +/* $XFree86: xc/lib/font/Speedo/set_spcs.c,v 1.3 2001/01/17 19:43:17 dawes Exp $ */ + + +/*************************** S E T _ S P C S . C ***************************** + * * + * This module implements all sp_set_specs() functionality. * + * * + ****************************************************************************/ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#define SET_SPCS +#include "spdo_prv.h" /* General definitions for Speedo */ +#include "keys.h" + +#define DEBUG 0 + +#if DEBUG +#include <stdio.h> +#define SHOW(X) printf("X = %d\n", X) +#else +#define SHOW(X) +#endif + +/***** GLOBAL VARIABLES *****/ + +/***** GLOBAL FUNCTIONS *****/ + +/****** EXTERNAL VARIABLES *****/ + +/***** STATIC VARIABLES *****/ + + +/****** STATIC FUNCTIONS *****/ + +static boolean sp_setup_consts(PROTO_DECL2 fix15 xmin, fix15 xmax, + fix15 ymin, fix15 ymax); +static void sp_setup_tcb(PROTO_DECL2 tcb_t GLOBALFAR *ptcb); +static fix15 sp_setup_mult(PROTO_DECL2 fix31 input_mult); +static fix31 sp_setup_offset(PROTO_DECL2 fix31 input_offset); + + + +FUNCTION boolean set_specs( +GDECL +specs_t STACKFAR *specsarg) /* Bundle of conversion specifications */ +/* + * Called by host software to set character generation specifications + */ +{ +fix31 offcd; /* Offset to start of character directory */ +fix31 ofcns; /* Offset to start of constraint data */ +fix31 cd_size; /* Size of character directory */ +fix31 no_bytes_min; /* Min number of bytes in font buffer */ +ufix16 font_id; /* Font ID */ +ufix16 private_off; /* offset to private header */ +fix15 xmin; /* Minimum X ORU value in font */ +fix15 xmax; /* Maximum X ORU value in font */ +fix15 ymin; /* Minimum Y ORU value in font */ +fix15 ymax; /* Maximum Y ORU value in font */ + +sp_globals.specs_valid = FALSE; /* Flag specs not valid */ + +sp_globals.specs = *specsarg; /* copy specs structure into sp_globals */ +sp_globals.pspecs = &sp_globals.specs; +sp_globals.font = *sp_globals.pspecs->pfont; +sp_globals.pfont = &sp_globals.font; +sp_globals.font_org = sp_globals.font.org; + +if (read_word_u(sp_globals.font_org + FH_FMVER + 4) != 0x0d0a) + { + report_error(4); /* Font format error */ + return FALSE; + } +if (read_word_u(sp_globals.font_org + FH_FMVER + 6) != 0x0000) + { + report_error(4); /* Font format error */ + return FALSE; + } + +if (get_cust_no(*specsarg->pfont) == 0) + { + sp_globals.key32 = 0; + sp_globals.key4 = 0; + sp_globals.key6 = 0; + sp_globals.key7 = 0; + sp_globals.key8 = 0; + } +else + { + sp_globals.key32 = (KEY3 << 8) | KEY2; + sp_globals.key4 = KEY4; + sp_globals.key6 = KEY6; + sp_globals.key7 = KEY7; + sp_globals.key8 = KEY8; + } + + +sp_globals.no_chars_avail = read_word_u(sp_globals.font_org + FH_NCHRF); + +/* Read sp_globals.orus per em from font header */ +sp_globals.orus_per_em = read_word_u(sp_globals.font_org + FH_ORUPM); + +/* compute address of private header */ +private_off = read_word_u(sp_globals.font_org + FH_HEDSZ); +sp_globals.hdr2_org = sp_globals.font_org + private_off; + +/* set metric resolution if specified, default to outline res otherwise */ +if (private_off > EXP_FH_METRES) + { + sp_globals.metric_resolution = read_word_u(sp_globals.font_org + EXP_FH_METRES); + } +else + { + sp_globals.metric_resolution = sp_globals.orus_per_em; + } + +#if INCL_METRICS +sp_globals.kern.tkorg = sp_globals.font_org + read_long(sp_globals.hdr2_org + FH_OFFTK); +sp_globals.kern.pkorg = sp_globals.font_org + read_long(sp_globals.hdr2_org + FH_OFFPK); +sp_globals.kern.no_tracks = read_word_u(sp_globals.font_org + FH_NKTKS); +sp_globals.kern.no_pairs = read_word_u(sp_globals.font_org + FH_NKPRS); +#endif + +offcd = read_long(sp_globals.hdr2_org + FH_OFFCD); /* Read offset to character directory */ +ofcns = read_long(sp_globals.hdr2_org + FH_OFCNS); /* Read offset to constraint data */ +cd_size = ofcns - offcd; +if ((((sp_globals.no_chars_avail << 1) + 3) != cd_size) && + (((sp_globals.no_chars_avail * 3) + 4) != cd_size)) + { + report_error(4); /* Font format error */ + return FALSE; + } + +#if INCL_LCD /* Dynamic character data load suppoorted? */ +#if INCL_METRICS +no_bytes_min = read_long(sp_globals.hdr2_org + FH_OCHRD); /* Offset to character data */ +#else /* Dynamic character data load not supported? */ +no_bytes_min = read_long(sp_globals.hdr2_org + FH_OFFTK); /* Offset to track kerning data */ +#endif +#else /* Dynamic character data load not supported? */ +no_bytes_min = read_long(sp_globals.hdr2_org + FH_NBYTE); /* Offset to EOF + 1 */ +#endif + +sp_globals.font_buff_size = sp_globals.pfont->no_bytes; +if (sp_globals.font_buff_size < no_bytes_min) /* Minimum data not loaded? */ + { + report_error(1); /* Insufficient font data loaded */ + return FALSE; + } + +sp_globals.pchar_dir = sp_globals.font_org + offcd; +sp_globals.first_char_idx = read_word_u(sp_globals.font_org + FH_FCHRF); + +/* Register font name with sp_globals.constraint mechanism */ +#if INCL_RULES +font_id = read_word_u(sp_globals.font_org + FH_FNTID); +if (!(sp_globals.constr.font_id_valid) || (sp_globals.constr.font_id != font_id)) + { + sp_globals.constr.font_id = font_id; + sp_globals.constr.font_id_valid = TRUE; + sp_globals.constr.data_valid = FALSE; + } +sp_globals.constr.org = sp_globals.font_org + ofcns; +sp_globals.constr.active = ((sp_globals.pspecs->flags & CONSTR_OFF) == 0); +#endif + +/* Set up sliding point constants */ +/* Set pixel shift to accomodate largest transformed pixel value */ +xmin = read_word_u(sp_globals.font_org + FH_FXMIN); +xmax = read_word_u(sp_globals.font_org + FH_FXMAX); +ymin = read_word_u(sp_globals.font_org + FH_FYMIN); +ymax = read_word_u(sp_globals.font_org + FH_FYMAX); + +if (!sp_setup_consts(xmin,xmax,ymin,ymax)) + { + report_error(3); /* Requested specs out of range */ + return FALSE; + } +#if INCL_ISW +/* save the value of the max x oru that the fixed point constants are based on*/ +sp_globals.isw_xmax = xmax; +#endif + +/* Setup transformation control block */ +sp_setup_tcb(&sp_globals.tcb0); + + +/* Select output module */ +sp_globals.output_mode = sp_globals.pspecs->flags & 0x0007; + +#if INCL_USEROUT +if (!init_userout(sp_globals.pspecs)) +#endif + +switch (sp_globals.output_mode) + { +#if INCL_BLACK +case MODE_BLACK: /* Output mode 0 (Black writer) */ + sp_globals.init_out = sp_init_black; + sp_globals.begin_char = sp_begin_char_black; + sp_globals.begin_sub_char = sp_begin_sub_char_out; + sp_globals.begin_contour = sp_begin_contour_black; + sp_globals.curve = sp_curve_out; + sp_globals.line = sp_line_black; + sp_globals.end_contour = sp_end_contour_out; + sp_globals.end_sub_char = sp_end_sub_char_out; + sp_globals.end_char = sp_end_char_black; + break; +#endif + +#if INCL_SCREEN +case MODE_SCREEN: /* Output mode 1 (Screen writer) */ + sp_globals.init_out = sp_init_screen; + sp_globals.begin_char = sp_begin_char_screen; + sp_globals.begin_sub_char = sp_begin_sub_char_out; + sp_globals.begin_contour = sp_begin_contour_screen; + sp_globals.curve = sp_curve_screen; + sp_globals.line = sp_line_screen; + sp_globals.end_contour = sp_end_contour_screen; + sp_globals.end_sub_char = sp_end_sub_char_out; + sp_globals.end_char = sp_end_char_screen; + break; +#endif + +#if INCL_OUTLINE +case MODE_OUTLINE: /* Output mode 2 (Vector) */ + sp_globals.init_out = sp_init_outline; + sp_globals.begin_char = sp_begin_char_outline; + sp_globals.begin_sub_char = sp_begin_sub_char_outline; + sp_globals.begin_contour = sp_begin_contour_outline; + sp_globals.curve = sp_curve_outline; + sp_globals.line = sp_line_outline; + sp_globals.end_contour = sp_end_contour_outline; + sp_globals.end_sub_char = sp_end_sub_char_outline; + sp_globals.end_char = sp_end_char_outline; + break; +#endif + +#if INCL_2D +case MODE_2D: /* Output mode 3 */ + sp_globals.init_out = sp_init_2d; + sp_globals.begin_char = sp_begin_char_2d; + sp_globals.begin_sub_char = sp_begin_sub_char_out; + sp_globals.begin_contour = sp_begin_contour_2d; + sp_globals.curve = sp_curve_out; + sp_globals.line = sp_line_2d; + sp_globals.end_contour = sp_end_contour_out; + sp_globals.end_sub_char = sp_end_sub_char_out; + sp_globals.end_char = sp_end_char_2d; + break; +#endif + +default: + report_error(8); /* Unsupported mode requested */ + return FALSE; + } + + if (!fn_init_out(sp_globals.pspecs)) + { + report_error(5); + return FALSE; + } + + +sp_globals.curves_out = sp_globals.pspecs->flags & CURVES_OUT; + +if (sp_globals.pspecs->flags & BOGUS_MODE) /* Linear transformation requested? */ + { + sp_globals.tcb0.xtype = sp_globals.tcb0.ytype = 4; + } +else /* Intelligent transformation requested? */ + { +#if INCL_RULES +#else + report_error(7); /* Rules requested; not supported */ + return FALSE; +#endif + } + +if ((sp_globals.pspecs->flags & SQUEEZE_LEFT) || + (sp_globals.pspecs->flags & SQUEEZE_RIGHT) || + (sp_globals.pspecs->flags & SQUEEZE_TOP) || + (sp_globals.pspecs->flags & SQUEEZE_BOTTOM) ) + { +#if (INCL_SQUEEZING) +#else + report_error(11); + return FALSE; +#endif + } + +if ((sp_globals.pspecs->flags & CLIP_LEFT) || + (sp_globals.pspecs->flags & CLIP_RIGHT) || + (sp_globals.pspecs->flags & CLIP_TOP) || + (sp_globals.pspecs->flags & CLIP_BOTTOM) ) + { +#if (INCL_CLIPPING) +#else + report_error(11); + return FALSE; +#endif + } + +sp_globals.specs_valid = TRUE; +return TRUE; +} + + + +#if INCL_MULTIDEV +#if INCL_BLACK || INCL_SCREEN || INCL_2D +FUNCTION boolean set_bitmap_device( +GDECL +bitmap_t *bfuncs, +ufix16 size) +{ + +if (size != sizeof(sp_globals.bitmap_device)) + return FALSE; + +sp_globals.bitmap_device = *bfuncs; +sp_globals.bitmap_device_set = TRUE; +} +#endif + +#if INCL_OUTLINE +FUNCTION boolean set_outline_device( +GDECL +outline_t *ofuncs, +ufix16 size) +{ + +if (size != sizeof(sp_globals.outline_device)) + return FALSE; + +sp_globals.outline_device = *ofuncs; +sp_globals.outline_device_set = TRUE; +} +#endif +#endif + + +#ifdef old +FUNCTION boolean sp_setup_consts( +GDECL +fix15 xmin, /* Minimum X ORU value in font */ +fix15 xmax, /* Maximum X ORU value in font */ +fix15 ymin, /* Minimum Y ORU value in font */ +fix15 ymax) /* Maximum Y ORU value in font */ +#else +static FUNCTION boolean sp_setup_consts( +GDECL +fix15 xmin, /* Minimum X ORU value in font */ +fix15 xmax, /* Maximum X ORU value in font */ +fix15 ymin, /* Minimum Y ORU value in font */ +fix15 ymax) /* Maximum Y ORU value in font */ +#endif +/* + * Sets the following constants used for fixed point arithmetic: + * sp_globals.multshift multipliers and products; range is 14 to 8 + * sp_globals.pixshift pixels: range is 0 to 8 + * sp_globals.mpshift shift from product to sub-pixels (sp_globals.multshift - sp_globals.pixshift) + * sp_globals.multrnd rounding for products + * sp_globals.pixrnd rounding for pixels + * sp_globals.mprnd rounding for sub-pixels + * sp_globals.onepix 1 pixel in shifted pixel units + * sp_globals.pixfix mask to eliminate fractional bits of shifted pixels + * sp_globals.depth_adj curve splitting depth adjustment + * Returns FALSE if specs are out of range + */ +{ +fix31 mult; /* Successive multiplier values */ +ufix32 num; /* Numerator of largest multiplier value */ +ufix32 numcopy; /* Copy of numerator */ +ufix32 denom; /* Denominator of largest multiplier value */ +ufix32 denomcopy; /* Copy of denominator */ +ufix32 pix_max; /* Maximum pixel rounding error */ +fix31 xmult; /* Coefficient of X oru value in transformation */ +fix31 ymult; /* Coefficient of Y oru value in transformation */ +fix31 offset; /* Constant in transformation */ +fix15 i; /* Loop counter */ +fix15 x, y; /* Successive corners of bounding box in ORUs */ +fix31 pixval; /* Successive pixel values multiplied by orus per em */ +fix15 xx = 0, yy = 0;/* Bounding box corner that produces max pixel value */ + +/* Determine numerator and denominator of largest multiplier value */ +mult = sp_globals.pspecs->xxmult >> 16; +if (mult < 0) + mult = -mult; +num = mult; + +mult = sp_globals.pspecs->xymult >> 16; +if (mult < 0) + mult = -mult; +if (mult > num) + num = mult; + +mult = sp_globals.pspecs->yxmult >> 16; +if (mult < 0) + mult = -mult; +if (mult > num) + num = mult; + +mult = sp_globals.pspecs->yymult >> 16; +if (mult < 0) + mult = -mult; +if (mult > num) + num = mult; +num++; /* Max absolute pixels per em (rounded up) */ +denom = (ufix32)sp_globals.orus_per_em; + +/* Set curve splitting depth adjustment to accomodate largest multiplier value */ +sp_globals.depth_adj = 0; /* 0 = 0.5 pel, 1 = 0.13 pel, 2 = 0.04 pel accuracy */ +denomcopy = denom; +/* The following two occurances of a strange method of shifting twice by 1 + are intentional and should not be changed to a single shift by 2. + It prevents MicroSoft C 5.1 from generating functions calls to do the shift. + Worse, using the REENTRANT_ALLOC option in conjunction with the /AC compiler + option, the function appears to be called incorrectly, causing depth_adj to always + be set to -7, causing very angular characters. */ + +while ((num > denomcopy) && (sp_globals.depth_adj < 5)) /* > 1, 4, 16, ... pixels per oru? */ + { + denomcopy <<= 1; + denomcopy <<= 1; + sp_globals.depth_adj++; /* Add 1, 2, 3, ... to depth adjustment */ + } +numcopy = num << 2; +while ((numcopy <= denom) && (sp_globals.depth_adj > -4)) /* <= 1/4, 1/16, 1/64 pix per oru? */ + { + numcopy <<= 1; + numcopy <<= 1; + sp_globals.depth_adj--; /* Subtract 1, 2, 3, ... from depth adjustment */ + } +SHOW(sp_globals.depth_adj); + +/* Set multiplier shift to accomodate largest multiplier value */ +sp_globals.multshift = 14; +numcopy = num; +while (numcopy >= denom) /* More than 1, 2, 4, ... pix per oru? */ + { + numcopy >>= 1; + sp_globals.multshift--; /* sp_globals.multshift is 13, 12, 11, ... */ + } + +sp_globals.multrnd = ((fix31)1 << sp_globals.multshift) >> 1; +SHOW(sp_globals.multshift); + + +pix_max = (ufix32)( 0xffff & read_word_u(sp_globals.hdr2_org + FH_PIXMX)); + +num = 0; +xmult = ((sp_globals.pspecs->xxmult >> 16) + 1) >> 1; +ymult = ((sp_globals.pspecs->xymult >> 16) + 1) >> 1; +offset = ((sp_globals.pspecs->xoffset >> 16) + 1) >> 1; +for (i = 0; i < 8; i++) + { + if (i == 4) + { + xmult = ((sp_globals.pspecs->yxmult >> 16) + 1) >> 1; + ymult = ((sp_globals.pspecs->yymult >> 16) + 1) >> 1; + offset = ((sp_globals.pspecs->yoffset >> 16) + 1) >> 1; + } + x = (i & BIT1)? xmin: xmax; + y = (i & BIT0)? ymin: ymax; + pixval = (fix31)x * xmult + (fix31)y * ymult + offset * denom; + if (pixval < 0) + pixval = -pixval; + if (pixval > num) + { + num = pixval; + xx = x; + yy = y; + } + } +if (xx < 0) + xx = -xx; +if (yy < 0) + yy = -yy; +num += xx + yy + ((pix_max + 2) * denom); + /* Allow (with 2:1 safety margin) for 1 pixel rounding errors in */ + /* xmult, ymult and offset values, pix_max pixel expansion */ + /* due to intelligent scaling, and */ + /* 1 pixel rounding of overall character position */ +denom = denom << 14; /* Note num is in units of half pixels times orus per em */ + +sp_globals.pixshift = -1; +while ((num <= denom) && (sp_globals.pixshift < 8)) /* Max pixels <= 32768, 16384, 8192, ... pixels? */ + { + num <<= 1; + sp_globals.pixshift++; /* sp_globals.pixshift = 0, 1, 2, ... */ + } +if (sp_globals.pixshift < 0) + return FALSE; + +SHOW(sp_globals.pixshift); +sp_globals.poshift = 16 - sp_globals.pixshift; + +sp_globals.onepix = (fix15)1 << sp_globals.pixshift; +sp_globals.pixrnd = sp_globals.onepix >> 1; +sp_globals.pixfix = ~0 << sp_globals.pixshift; + +sp_globals.mpshift = sp_globals.multshift - sp_globals.pixshift; +if (sp_globals.mpshift < 0) + return FALSE; +sp_globals.mprnd = ((fix31)1 << sp_globals.mpshift) >> 1; + +return TRUE; +} + +#ifdef old +FUNCTION void sp_setup_tcb( +GDECL +tcb_t GLOBALFAR *ptcb) /* Pointer to transformation control bloxk */ +#else +static FUNCTION void sp_setup_tcb( +GDECL +tcb_t GLOBALFAR *ptcb) /* Pointer to transformation control bloxk */ +#endif +/* + * Convert transformation coeffs to internal form + */ +{ + +ptcb->xxmult = sp_setup_mult(sp_globals.pspecs->xxmult); +ptcb->xymult = sp_setup_mult(sp_globals.pspecs->xymult); +ptcb->xoffset = sp_setup_offset(sp_globals.pspecs->xoffset); +ptcb->yxmult = sp_setup_mult(sp_globals.pspecs->yxmult); +ptcb->yymult = sp_setup_mult(sp_globals.pspecs->yymult); +ptcb->yoffset = sp_setup_offset(sp_globals.pspecs->yoffset); + +SHOW(ptcb->xxmult); +SHOW(ptcb->xymult); +SHOW(ptcb->xoffset); +SHOW(ptcb->yxmult); +SHOW(ptcb->yymult); +SHOW(ptcb->yoffset); + +type_tcb(ptcb); /* Classify transformation type */ +} + +FUNCTION static fix15 sp_setup_mult( +GDECL +fix31 input_mult) /* Multiplier in input format */ +/* + * Called by sp_setup_tcb() to convert multiplier in transformation + * matrix from external to internal form. + */ +{ +fix15 imshift; /* Right shift to internal format */ +fix31 imdenom; /* Divisor to internal format */ +fix31 imrnd; /* Rounding for division operation */ + +imshift = 15 - sp_globals.multshift; +imdenom = (fix31)sp_globals.orus_per_em << imshift; +imrnd = imdenom >> 1; + +input_mult >>= 1; +if (input_mult >= 0) + return (fix15)((input_mult + imrnd) / imdenom); +else + return -(fix15)((-input_mult + imrnd) / imdenom); +} + +FUNCTION static fix31 sp_setup_offset( +GDECL +fix31 input_offset) /* Multiplier in input format */ +/* + * Called by sp_setup_tcb() to convert offset in transformation + * matrix from external to internal form. + */ +{ +fix15 imshift; /* Right shift to internal format */ +fix31 imrnd; /* Rounding for right shift operation */ + +imshift = 15 - sp_globals.multshift; +imrnd = ((fix31)1 << imshift) >> 1; + +return (((input_offset >> 1) + imrnd) >> imshift) + sp_globals.mprnd; +} + +FUNCTION void type_tcb( +GDECL +tcb_t GLOBALFAR *ptcb) /* Pointer to transformation control bloxk */ +{ +fix15 x_trans_type; +fix15 y_trans_type; +fix15 xx_mult; +fix15 xy_mult; +fix15 yx_mult; +fix15 yy_mult; +fix15 h_pos; +fix15 v_pos; +fix15 x_ppo; +fix15 y_ppo; +fix15 x_pos; +fix15 y_pos; + +/* check for mirror image transformations */ +xx_mult = ptcb->xxmult; +xy_mult = ptcb->xymult; +yx_mult = ptcb->yxmult; +yy_mult = ptcb->yymult; + +ptcb->mirror = ((((fix31)xx_mult*(fix31)yy_mult)- + ((fix31)xy_mult*(fix31)yx_mult)) < 0) ? -1 : 1; + +if (sp_globals.pspecs->flags & BOGUS_MODE) /* Linear transformation requested? */ + { + ptcb->xtype = 4; + ptcb->ytype = 4; + + ptcb->xppo = 0; + ptcb->yppo = 0; + ptcb->xpos = 0; + ptcb->ypos = 0; + } +else /* Intelligent tranformation requested? */ + { + h_pos = ((ptcb->xoffset >> sp_globals.mpshift) + sp_globals.pixrnd) & sp_globals.pixfix; + v_pos = ((ptcb->yoffset >> sp_globals.mpshift) + sp_globals.pixrnd) & sp_globals.pixfix; + + x_trans_type = 4; + x_ppo = 0; + x_pos = 0; + + y_trans_type = 4; + y_ppo = 0; + y_pos = 0; + + if (xy_mult == 0) + { + if (xx_mult >= 0) + { + x_trans_type = 0; /* X pix is function of X orus only */ + x_ppo = xx_mult; + x_pos = h_pos; + } + else + { + x_trans_type = 1; /* X pix is function of -X orus only */ + x_ppo = -xx_mult; + x_pos = -h_pos; + } + } + + else if (xx_mult == 0) + { + if (xy_mult >= 0) + { + x_trans_type = 2; /* X pix is function of Y orus only */ + y_ppo = xy_mult; + y_pos = h_pos; + } + else + { + x_trans_type = 3; /* X pix is function of -Y orus only */ + y_ppo = -xy_mult; + y_pos = -h_pos; + } + } + + if (yx_mult == 0) + { + if (yy_mult >= 0) + { + y_trans_type = 0; /* Y pix is function of Y orus only */ + y_ppo = yy_mult; + y_pos = v_pos; + } + else + { + y_trans_type = 1; /* Y pix is function of -Y orus only */ + y_ppo = -yy_mult; + y_pos = -v_pos; + } + } + else if (yy_mult == 0) + { + if (yx_mult >= 0) + { + y_trans_type = 2; /* Y pix is function of X orus only */ + x_ppo = yx_mult; + x_pos = v_pos; + } + else + { + y_trans_type = 3; /* Y pix is function of -X orus only */ + x_ppo = -yx_mult; + x_pos = -v_pos; + } + } + + ptcb->xtype = x_trans_type; + ptcb->ytype = y_trans_type; + + ptcb->xppo = x_ppo; + ptcb->yppo = y_ppo; + ptcb->xpos = x_pos; + ptcb->ypos = y_pos; + } + +sp_globals.normal = (ptcb->xtype != 4) && (ptcb->ytype != 4); + +ptcb->xmode = 4; +ptcb->ymode = 4; + +SHOW(ptcb->xtype); +SHOW(ptcb->ytype); +SHOW(ptcb->xppo); +SHOW(ptcb->yppo); +SHOW(ptcb->xpos); +SHOW(ptcb->ypos); +} + +FUNCTION fix31 read_long( +GDECL +ufix8 FONTFAR *pointer) /* Pointer to first byte of encrypted 3-byte integer */ +/* + * Reads a 3-byte encrypted integer from the byte string starting at + * the specified point. + * Returns the decrypted value read as a signed integer. + */ +{ +fix31 tmpfix31; + +tmpfix31 = (fix31)((*pointer++) ^ sp_globals.key4) << 8; /* Read middle byte */ +tmpfix31 += (fix31)(*pointer++) << 16; /* Read most significant byte */ +tmpfix31 += (fix31)((*pointer) ^ sp_globals.key6); /* Read least significant byte */ +return tmpfix31; +} + +FUNCTION fix15 read_word_u( +GDECL +ufix8 FONTFAR *pointer) /* Pointer to first byte of unencrypted 2-byte integer */ +/* + * Reads a 2-byte unencrypted integer from the byte string starting at + * the specified point. + * Returns the decrypted value read as a signed integer. + */ +{ +fix15 tmpfix15; + +tmpfix15 = (fix15)(*pointer++) << 8; /* Read most significant byte */ +tmpfix15 += (fix15)(*pointer); /* Add least significant byte */ +return tmpfix15; +} + + diff --git a/nx-X11/lib/font/Speedo/set_trns.c b/nx-X11/lib/font/Speedo/set_trns.c new file mode 100644 index 000000000..3b8f60378 --- /dev/null +++ b/nx-X11/lib/font/Speedo/set_trns.c @@ -0,0 +1,1324 @@ +/* $Xorg: set_trns.c,v 1.3 2000/08/17 19:46:27 cpqbld Exp $ */ + +/* + +Copyright 1989-1991, Bitstream Inc., Cambridge, MA. +You are hereby granted permission under all Bitstream propriety rights to +use, copy, modify, sublicense, sell, and redistribute the Bitstream Speedo +software and the Bitstream Charter outline font for any purpose and without +restrictions; provided, that this notice is left intact on all copies of such +software or font and that Bitstream's trademark is acknowledged as shown below +on all unmodified copies of such font. + +BITSTREAM CHARTER is a registered trademark of Bitstream Inc. + + +BITSTREAM INC. DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING +WITHOUT LIMITATION THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE. BITSTREAM SHALL NOT BE LIABLE FOR ANY DIRECT OR INDIRECT +DAMAGES, INCLUDING BUT NOT LIMITED TO LOST PROFITS, LOST DATA, OR ANY OTHER +INCIDENTAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF OR IN ANY WAY CONNECTED +WITH THE SPEEDO SOFTWARE OR THE BITSTREAM CHARTER OUTLINE FONT. + +*/ +/* $XFree86: xc/lib/font/Speedo/set_trns.c,v 1.5tsi Exp $ */ + + + +/*************************** S E T _ T R N S . C ***************************** + * * + * This module is called from do_char.c to set up the intelligent * + * transformation for one character (or sub-character of a composite * + * character. + * * + ****************************************************************************/ + + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include "spdo_prv.h" /* General definitions for Speedo */ + +#define DEBUG 0 + +#if DEBUG +#include <stdio.h> +#define SHOW(X) printf("X = %d\n", X) +#else +#define SHOW(X) +#endif +/***** LOCAL MACROS *****/ + +#define SQUEEZE_X_ORU(A,B,C) ((((fix31)A * (fix31)B) + C) >> 16) +#define ABS(A) ((A < 0)? -A:A) /* absolute value */ +#define IMPORT_FACTOR \ + shift = 16;\ + while (*x_factor > (0x7fffffffL / (isw_scale >> (16 - shift))))\ + shift--;\ + *x_factor = (*x_factor * (isw_scale>>(16-shift))) >> shift; + +/***** GLOBAL VARIABLES *****/ + +/***** GLOBAL FUNCTIONS *****/ + +/***** EXTERNAL VARIABLES *****/ + +/***** EXTERNAL FUNCTIONS *****/ + +/***** STATIC VARIABLES *****/ + +/***** STATIC FUNCTIONS *****/ + +static void sp_constr_update(PROTO_DECL1); +static ufix8 FONTFAR *sp_setup_pix_table(PROTO_DECL2 ufix8 FONTFAR *pointer,boolean short_form,fix15 no_X_ctrl_zones,fix15 no_Y_ctrl_zones); +static ufix8 FONTFAR *sp_setup_int_table(PROTO_DECL2 ufix8 FONTFAR *pointer,fix15 no_X_int_zones,fix15 no_Y_int_zones); + + +FUNCTION void init_tcb() +GDECL +/* + * Called by sp_make_char() and make_comp_char() to initialize the current + * transformation control block to the top level transformation. + */ +{ +sp_globals.tcb = sp_globals.tcb0; +} + +FUNCTION void scale_tcb( +GDECL +tcb_t GLOBALFAR *ptcb, /* Transformation control block */ +fix15 x_pos, /* X position (outline res units) */ +fix15 y_pos, /* Y position (outline res units) */ +fix15 x_scale, /* X scale factor * ONE_SCALE */ +fix15 y_scale) /* Y scale factor * ONE_SCALE */ +/* + * Called by make_comp_char() to apply position and scale for each of the + * components of a compound character. + */ +{ +fix15 xx_mult = ptcb->xxmult; +fix15 xy_mult = ptcb->xymult; +fix31 x_offset = ptcb->xoffset; +fix15 yx_mult = ptcb->yxmult; +fix15 yy_mult = ptcb->yymult; +fix31 y_offset = ptcb->yoffset; + +ptcb->xxmult = TRANS(xx_mult, x_scale, (fix31)SCALE_RND, SCALE_SHIFT); +ptcb->xymult = TRANS(xy_mult, y_scale, (fix31)SCALE_RND, SCALE_SHIFT); +ptcb->xoffset = MULT16(xx_mult, x_pos) + MULT16(xy_mult, y_pos) + x_offset; +ptcb->yxmult = TRANS(yx_mult, x_scale, (fix31)SCALE_RND, SCALE_SHIFT); +ptcb->yymult = TRANS(yy_mult, y_scale, (fix31)SCALE_RND, SCALE_SHIFT); +ptcb->yoffset = MULT16(yx_mult, x_pos) + MULT16(yy_mult, y_pos) + y_offset; + +type_tcb(ptcb); /* Reclassify transformation types */ +} + +FUNCTION ufix8 FONTFAR *skip_interpolation_table( +GDECL +ufix8 FONTFAR *pointer, /* Pointer to next byte in char data */ +ufix8 format) /* Character format byte */ +{ +fix15 i,n; +ufix8 intsize[9]; + +intsize[0] = 1; +intsize[1] = 2; +intsize[2] = 3; +intsize[3] = 1; +intsize[4] = 2; +intsize[5] = 1; +intsize[6] = 2; +intsize[7] = 0; +intsize[8] = 0; + +n = ((format & BIT6)? (fix15)NEXT_BYTE(pointer): 0); +n += ((format & BIT7)? (fix15)NEXT_BYTE(pointer): 0); +for (i = 0; i < n; i++) /* For each entry in int table ... */ + { + format = NEXT_BYTE(pointer); /* Read format byte */ + if (format & BIT7) /* Short Start/End point spec? */ + { + pointer++; /* Skip Start/End point byte */ + } + else + { + pointer += intsize[format & 0x7]; /* Skip Start point spec */ + pointer += intsize[(format >> 3) & 0x7]; /* Skip End point spec */ + } + } +return pointer; +} +FUNCTION ufix8 FONTFAR *skip_control_zone( +GDECL +ufix8 FONTFAR *pointer, /* Pointer to next byte in char data */ +ufix8 format) /* Character format byte */ +{ +fix15 i,n; +ufix16 tmpufix16; + +n = sp_globals.no_X_orus + sp_globals.no_Y_orus - 2; +for (i = 0; i < n; i++) /* For each entry in control table ... */ + { + if (format & BIT4) + pointer++; /* Skip short form From/To fields */ + else + pointer += 2; /* Skip FROM and TO fields */ + /* skip constraints field */ + NEXT_BYTES (pointer, tmpufix16); + + } +return pointer; +} + +#if INCL_RULES +#else +FUNCTION ufix8 FONTFAR *plaid_tcb( +GDECL +ufix8 FONTFAR *pointer, /* Pointer to next byte in char data */ +ufix8 format) /* Character format byte */ +/* + * Called by make_simp_char() and make_comp_char() to set up the controlled + * coordinate table and skip all other intelligent scaling rules embedded + * in the character data. + * Updates pointer to first byte after plaid data. + * This is used only if intelligent scaling is not supported in the + * configuration definitions. + */ +{ +fix15 i, n; + + + +sp_globals.no_X_orus = (format & BIT2)? + (fix15)NEXT_BYTE(pointer): + 0; +sp_globals.no_Y_orus = (format & BIT3)? + (fix15)NEXT_BYTE(pointer): + 0; +pointer = read_oru_table(pointer); /* Updates no_X/Y/orus */ +sp_globals.Y_edge_org = sp_globals.no_X_orus; + +/* Skip over control zone table */ +pointer = skip_control_zone(pointer,format); + +/* Skip over interpolation table */ +pointer = skip_interpolation_table(pointer,format); +return pointer; +} +#endif + +#if INCL_RULES +FUNCTION ufix8 FONTFAR *plaid_tcb( +GDECL +ufix8 FONTFAR *pointer, /* Pointer to next byte in char data */ +ufix8 format) /* Character format byte */ +/* + * Called by make_simp_char() and make_comp_char() to set up the controlled + * coordinate table and process all intelligent scaling rules embedded + * in the character data. + * Updates pointer to first byte after plaid data. + * This is used only if intelligent scaling is enabled in the + * configuration definitions. + */ +{ +fix15 no_X_ctrl_zones; +fix15 no_Y_ctrl_zones; +fix15 no_X_int_zones; +fix15 no_Y_int_zones; + +#if INCL_PLAID_OUT /* Plaid data monitoring included? */ +begin_plaid_data(); +#endif + +sp_constr_update(); /* Update constraint table if required */ + +sp_globals.no_X_orus = (format & BIT2)? + (fix15)NEXT_BYTE(pointer): + 0; +sp_globals.no_Y_orus = (format & BIT3)? + (fix15)NEXT_BYTE(pointer): + 0; +pointer = read_oru_table(pointer); /* Updates no_X/Y/orus to include zero values */ +sp_globals.Y_edge_org = sp_globals.no_X_orus; +if (sp_globals.no_X_orus > 1) /* 2 or more controlled X coordinates? */ + sp_globals.tcb.xmode = sp_globals.tcb.xtype; /* Enable intelligent scaling in X */ + +if (sp_globals.no_Y_orus > 1) /* 2 or more controlled Y coordinates? */ + sp_globals.tcb.ymode = sp_globals.tcb.ytype; /* Enable intelligent scaling in Y */ + +no_X_ctrl_zones = sp_globals.no_X_orus - 1; +no_Y_ctrl_zones = sp_globals.no_Y_orus - 1; +pointer = sp_setup_pix_table(pointer, (boolean)(format & BIT4), + no_X_ctrl_zones, no_Y_ctrl_zones); + +no_X_int_zones = (format & BIT6)? + (fix15)NEXT_BYTE(pointer): + 0; +no_Y_int_zones = (format & BIT7)? + (fix15)NEXT_BYTE(pointer): + 0; +sp_globals.Y_int_org = no_X_int_zones; +pointer = sp_setup_int_table(pointer, no_X_int_zones, no_Y_int_zones); + +#if INCL_PLAID_OUT /* Plaid data monitoring included? */ +end_plaid_data(); +#endif + +return pointer; +} +#endif + +#if INCL_RULES +FUNCTION static void sp_constr_update() +GDECL +/* + * Called by plaid_tcb() to update the constraint table for the current + * transformation. + * This is always carried out whenever a character is generated following + * a change of font or scale factor or after initialization. + */ +{ +fix31 ppo; +fix15 xppo; +fix15 yppo; +ufix8 FONTFAR *pointer; +fix15 no_X_constr; +fix15 no_Y_constr; +fix15 i, j, k, l, n; +fix15 ppm; +ufix8 format; +ufix8 format1; +fix15 limit; +ufix16 constr_org; +fix15 constr_nr; +fix15 size; +fix31 off; +fix15 min; +fix15 orus; +fix15 pix; +ufix16 tmpufix16; /* in extended mode, macro uses secnd term */ + +if (sp_globals.constr.data_valid && /* Constr table already done and ... */ + (sp_globals.tcb.xppo == sp_globals.constr.xppo) && /* ... X pix per oru unchanged and ... */ + (sp_globals.tcb.yppo == sp_globals.constr.yppo)) /* ... Y pix per oru unchanged? */ + { + return; /* No need to update constraint table */ + } + +sp_globals.constr.xppo = xppo = sp_globals.tcb.xppo; /* Update X pixels per oru indicator */ +sp_globals.constr.yppo = yppo = sp_globals.tcb.yppo; /* Update Y pixels per oru indicator */ +sp_globals.constr.data_valid = TRUE; /* Mark constraint table valid */ + +pointer = sp_globals.constr.org; /* Point to first byte of constraint data */ +no_X_constr = NEXT_BYTES(pointer, tmpufix16); /* Read nmbr of X constraints */ +no_Y_constr = NEXT_BYTES(pointer, tmpufix16); /* Read nmbr of Y constraints */ + +i = 0; +constr_org = 0; +n = no_X_constr; +ppo = xppo; +for (j = 0; ; j++) + { + sp_globals.c_act[i] = FALSE; /* Flag constraint 0 not active */ + sp_globals.c_pix[i++] = 0; /* Constraint 0 implies no minimum */ + sp_globals.c_act[i] = FALSE; /* Flag constraint 1 not active */ + sp_globals.c_pix[i++] = sp_globals.onepix; /* Constraint 1 implies min 1 pixel*/ + ppm = (ppo * (fix31)sp_globals.orus_per_em) >> sp_globals.multshift; + for (k = 0; k < n; k++) + { + format = NEXT_BYTE(pointer); /* Read format byte */ + limit = (fix15)NEXT_BYTE(pointer); /* Read limit field */ + sp_globals.c_act[i] = + ((ppm < limit) || (limit == 255)) && + sp_globals.constr.active; + if (sp_globals.c_act[i]) /* Constraint active? */ + { + if ((format & BIT1) && /* Constraint specified and ... */ + (constr_nr = constr_org + + ((format & BIT0)? /* Read unsigned constraint value */ + NEXT_WORD(pointer): + (fix15)NEXT_BYTE(pointer)), + sp_globals.c_act[constr_nr])) /* ... and specified constraint active? */ + { + pix = sp_globals.c_pix[constr_nr]; /* Use constrained pixel value */ + format1 = format; + for (l = 2; l > 0; l--) /* Skip 2 arguments */ + { + format1 >>= 2; + if ((size = format1 & 0x03)) + pointer += size - 1; + } + } + else /* Constraint absent or inactive? */ + { + orus = (format & BIT2)? /* Read unsigned oru value */ + NEXT_WORD(pointer): + (fix15)NEXT_BYTE(pointer); + + if (format & BIT5) /* Specified offset value? */ + { + off = (fix31)((format & BIT4)? /* Read offset value */ + NEXT_WORD(pointer): + (fix7)NEXT_BYTE(pointer)); + off = (off << (sp_globals.multshift - 6)) + sp_globals.multrnd; + } + else /* Unspecified (zero) offset value? */ + { + off = sp_globals.multrnd; + } + + pix = (fix15)(((fix31)orus * ppo + off) / (1 << sp_globals.mpshift)) & sp_globals.pixfix; + } + } + else /* Constraint inactive? */ + { + format1 = format; + for (l = 3; l > 0; l--) /* Skip over 3 arguments */ + { + if ((size = format1 & 0x03)) + pointer += size - 1; + format1 >>= 2; + } + pix = 0; + } + + if (format & 0xc0) /* Specified minimum value? */ + { + min = (format & BIT7)? /* Read unsigned minimum value */ + (fix15)NEXT_BYTE(pointer) << sp_globals.pixshift: + sp_globals.onepix; + } + else /* Unspecified (zero) minimum value? */ + { + min = 0; + } + + sp_globals.c_pix[i] = (pix < min)? min: pix; + i++; + } + if (j) break; /* Finished if second time around loop */ + constr_org = sp_globals.Y_constr_org = i; + n = no_Y_constr; + ppo = yppo; + } + +#if DEBUG +printf("\nCONSTRAINT TABLE\n"); +n = no_X_constr + 2; +for (i = 0; i < n; i++) + { + printf("%3d ", i); + if (sp_globals.c_act[i]) + { + printf("T "); + } + else + { + printf("F "); + } + printf("%5.1f\n", ((real)sp_globals.c_pix[i] / (real)sp_globals.onepix)); + } +printf("--------------\n"); +n = no_Y_constr + 2; +for (i = 0; i < n; i++) + { + j = i + sp_globals.Y_constr_org; + printf("%3d ", i); + if (sp_globals.c_act[j]) + { + printf("T "); + } + else + { + printf("F "); + } + printf("%5.1f\n", ((real)sp_globals.c_pix[j] / (real)sp_globals.onepix)); + } +#endif + +} +#endif + +FUNCTION ufix8 FONTFAR *read_oru_table( +GDECL +ufix8 FONTFAR *pointer) /* Pointer to first byte in controlled coord table */ +/* + * Called by plaid_tcb() to read the controlled coordinate table from the + * character data in the font. + * Updates the pointer to the byte following the controlled coordinate + * data. + */ +{ +fix15 i, j, k, n; +boolean zero_not_in; +boolean zero_added; +fix15 oru; + +#if INCL_RULES +fix15 pos; +#endif + +i = 0; +n = sp_globals.no_X_orus; +#if INCL_RULES +pos = sp_globals.tcb.xpos; +#endif +for (j = 0; ; j++) + { + zero_not_in = TRUE; + zero_added = FALSE; + for (k = 0; k < n; k++) + { + oru = NEXT_WORD(pointer); + if (zero_not_in && (oru >= 0)) /* First positive oru value? */ + { +#if INCL_RULES + sp_plaid.pix[i] = pos; /* Insert position in pix array */ +#endif + if (oru != 0) /* Zero oru value omitted? */ + { + sp_plaid.orus[i++] = 0; /* Insert zero value in oru array */ + zero_added = TRUE; /* Remember to increment size of array */ + } + zero_not_in = FALSE; /* Inhibit further testing for zero ins */ + } + sp_plaid.orus[i++] = oru; /* Add specified oru value to array */ + } + if (zero_not_in) /* All specified oru values negative? */ + { +#if INCL_RULES + sp_plaid.pix[i] = pos; /* Insert position in pix array */ +#endif + sp_plaid.orus[i++] = 0; /* Add zero oru value */ + zero_added = TRUE; /* Remember to increment size of array */ + } + if (j) /* Both X and Y orus read? */ + break; + if (zero_added) + sp_globals.no_X_orus++; /* Increment X array size */ + n = sp_globals.no_Y_orus; /* Prepare to read Y oru values */ +#if INCL_RULES + pos = sp_globals.tcb.ypos; +#endif + } +if (zero_added) /* Zero Y oru value added to array? */ + sp_globals.no_Y_orus++; /* Increment Y array size */ + +#if DEBUG +printf("\nX ORUS\n"); +n = sp_globals.no_X_orus; +for (i = 0; i < n; i++) + { + printf("%2d %4d\n", i, sp_plaid.orus[i]); + } +printf("\nY ORUS\n"); +n = sp_globals.no_Y_orus; +for (i = 0; i < n; i++) + { + printf("%2d %4d\n", i, sp_plaid.orus[i + sp_globals.no_X_orus]); + } +#endif + +return pointer; /* Update pointer */ +} +#if INCL_SQUEEZING || INCL_ISW +FUNCTION static void calculate_x_pix( +GDECL +ufix8 start_edge, ufix8 end_edge, +ufix16 constr_nr, +fix31 x_scale, +fix31 x_offset, +fix31 ppo, +fix15 setwidth_pix) +/* + * Called by sp_setup_pix_table() when X squeezing is necessary + * to insert the correct edge in the global pix array + */ +{ +fix15 zone_pix; +fix15 start_oru, end_oru; + +/* compute scaled oru coordinates */ +start_oru= (fix15)(SQUEEZE_X_ORU(sp_plaid.orus[start_edge], x_scale, x_offset)); +end_oru = (fix15)(SQUEEZE_X_ORU(sp_plaid.orus[end_edge], x_scale, x_offset)); + +if (!sp_globals.c_act[constr_nr]) /* constraint inactive */ + { + /* calculate zone width */ + zone_pix = (fix15)(((((fix31)end_oru - (fix31)start_oru) * ppo) / + (1<<sp_globals.mpshift)) + sp_globals.pixrnd) & sp_globals.pixfix; + /* check for overflow */ + if (((end_oru-start_oru) > 0) && (zone_pix < 0)) + zone_pix = 0x7ffff; + /* check for minimum */ + if ((ABS(zone_pix)) >= sp_globals.c_pix[constr_nr]) + goto Lx; + } +/* use the zone size from the constr table - scale it */ +zone_pix = (fix15)(((SQUEEZE_MULT(x_scale,sp_globals.c_pix[constr_nr])) + + sp_globals.pixrnd) & sp_globals.pixfix); + +/* look for overflow */ +if ((sp_globals.c_pix[constr_nr] > 0) && (zone_pix < 0)) + zone_pix = 0x7fff; + +if (start_edge > end_edge) + { + zone_pix = -zone_pix; + } +Lx: +/* assign pixel value to global pix array */ +sp_plaid.pix[end_edge]=sp_plaid.pix[start_edge] + zone_pix; + +/* check for overflow */ +if (((sp_plaid.pix[start_edge] >0) && (zone_pix >0)) && + (sp_plaid.pix[end_edge] < 0)) + sp_plaid.pix[end_edge] = 0x7fff; /* set it to the max */ + +/* be sure to be in the setwidth !*/ +#if INCL_ISW +if (!sp_globals.import_setwidth_act) /* only check left edge if not isw only */ +#endif +if ((sp_globals.pspecs->flags & SQUEEZE_LEFT) && (sp_plaid.pix[end_edge] < 0)) + sp_plaid.pix[end_edge] = 0; +if ((sp_globals.pspecs->flags & SQUEEZE_RIGHT) && + (sp_plaid.pix[end_edge] > setwidth_pix)) + sp_plaid.pix[end_edge] = setwidth_pix; + +} +#endif + +#if INCL_SQUEEZING +FUNCTION static void calculate_y_pix( +GDECL +ufix8 start_edge, ufix8 end_edge, +ufix16 constr_nr, +fix31 top_scale, fix31 bottom_scale, +fix31 ppo, +fix15 em_top_pix, fix15 em_bot_pix) + +/* + * Called by sp_setup_pix_table() when Y squeezing is necessary + * to insert the correct edge in the global pix array + */ +{ +fix15 zone_pix; +fix15 start_oru, end_oru; +fix31 zone_width, above_base, below_base; + +/* check whether edge is above or below the baseline */ +/* and apply appropriate scale factor to get scaled oru coordinates */ +if (sp_plaid.orus[start_edge] < 0) + start_oru =(fix15)(SQUEEZE_MULT(sp_plaid.orus[start_edge], bottom_scale)); +else + start_oru =(fix15)(SQUEEZE_MULT(sp_plaid.orus[start_edge], top_scale)); + +if (sp_plaid.orus[end_edge] < 0) + end_oru =(fix15)(SQUEEZE_MULT(sp_plaid.orus[end_edge], bottom_scale)); +else + end_oru =(fix15)(SQUEEZE_MULT(sp_plaid.orus[end_edge], top_scale)); + +if (!sp_globals.c_act[constr_nr]) /* Constraint inactive? */ + { + /* calculate zone width */ + zone_pix = (fix15)(((((fix31)end_oru - (fix31)start_oru) * ppo) + >> sp_globals.mpshift)+ sp_globals.pixrnd) & sp_globals.pixfix; + /* check minimum */ + if ((ABS(zone_pix)) >= sp_globals.c_pix[constr_nr]) + goto Ly; + } + +/* Use zone size from constr table */ +if ((end_oru >= 0) && (start_oru >=0)) + /* all above baseline */ + zone_pix = (fix15)(SQUEEZE_MULT(top_scale, sp_globals.c_pix[constr_nr])); +else if ((end_oru <= 0) && (start_oru <=0)) + /* all below baseline */ + zone_pix = (fix15)(SQUEEZE_MULT(bottom_scale, sp_globals.c_pix[constr_nr])); +else + { + /* mixture */ + if (start_oru > 0) + { + zone_width = start_oru - end_oru; + /* get % above baseline in 16.16 fixed point */ + above_base = (((fix31)start_oru) << 16) / + ((fix31)zone_width) ; + /* get % below baseline in 16.16 fixed point */ + below_base = (((fix31)-end_oru) << 16) / + ((fix31)zone_width) ; + } + else + { + zone_width = end_oru - start_oru; + /* get % above baseline in 16.16 fixed point */ + above_base = (((fix31)-start_oru) << 16) / + ((fix31)zone_width) ; + /* get % below baseline in 16.16 fixed point */ + below_base = (((fix31)end_oru) << 16) / + ((fix31)zone_width) ; + } + /* % above baseline * total zone * top_scale + */ + /* % below baseline * total zone * bottom_scale */ + zone_pix = ((((above_base * (fix31)sp_globals.c_pix[constr_nr]) >> 16) * + top_scale) + + (((below_base * (fix31)sp_globals.c_pix[constr_nr]) >> 16) * + bottom_scale)) >> 16; + } + +/* make this zone pix fall on a pixel boundary */ +zone_pix = (zone_pix + sp_globals.pixrnd) & sp_globals.pixfix; + +/* if minimum is in effect make the zone one pixel */ +if ((sp_globals.c_pix[constr_nr] != 0) && (zone_pix < sp_globals.onepix)) + zone_pix = sp_globals.onepix; + +if (start_edge > end_edge) + { + zone_pix = -zone_pix; /* Use negatve zone size */ + } +Ly: +/* assign global pix value */ +sp_plaid.pix[end_edge] = sp_plaid.pix[start_edge] + zone_pix; /* Insert end pixels */ + +/* make sure it is in the EM !*/ +if ((sp_globals.pspecs->flags & SQUEEZE_TOP) && + (sp_plaid.pix[end_edge] > em_top_pix)) + sp_plaid.pix[end_edge] = em_top_pix; +if ((sp_globals.pspecs->flags & SQUEEZE_BOTTOM) && + (sp_plaid.pix[end_edge] < em_bot_pix)) + sp_plaid.pix[end_edge] = em_bot_pix; +} + +FUNCTION boolean calculate_x_scale(x_factor, x_offset, no_X_ctrl_zones) +GDECL +fix31 *x_factor, +fix31 *x_offset, +fix15 no_X_ctrl_zones) /* Number of X control zones */ +/* + * Called by sp_setup_pix_table() when squeezing is included + * to determine whether X scaling is necessary. If it is, the + * scale factor and offset are computed. This function returns + * a boolean value TRUE = X squeezind is necessary, FALSE = no + * X squeezing is necessary. + */ +{ +boolean squeeze_left, squeeze_right; +boolean out_on_right, out_on_left; +fix15 bbox_width,set_width; +fix15 bbox_xmin, bbox_xmax; +fix15 x_offset_pix; +fix15 i; +#if INCL_ISW +fix31 isw_scale; +fix15 shift; +#endif + + +/* set up some flags and common calculations */ +squeeze_left = (sp_globals.pspecs->flags & SQUEEZE_LEFT)? TRUE:FALSE; +squeeze_right = (sp_globals.pspecs->flags & SQUEEZE_RIGHT)? TRUE:FALSE; +bbox_xmin = sp_globals.bbox_xmin_orus; +bbox_xmax = sp_globals.bbox_xmax_orus; +set_width = sp_globals.setwidth_orus; + +if (bbox_xmax > set_width) + out_on_right = TRUE; +else + out_on_right = FALSE; +if (bbox_xmin < 0) + out_on_left = TRUE; +else + out_on_left = FALSE; +bbox_width =bbox_xmax - bbox_xmin; + +/* + * don't need X squeezing if: + * - X squeezing not enabled + * - bbox doesn't violate on left or right + * - left squeezing only is enabled and char isn't out on left + * - right squeezing only is enabled and char isn't out on right + */ + +if ((!squeeze_left && !squeeze_right) || + (!out_on_right && !out_on_left) || + (squeeze_left && !squeeze_right && !out_on_left) || + (squeeze_right && !squeeze_left && !out_on_right)) + return FALSE; + +#if INCL_ISW +if (sp_globals.import_setwidth_act) + { + /* if both isw and squeezing is going on - let the imported */ + /* setwidth factor be factored in with the squeeze */ + isw_scale = compute_isw_scale(); + /*sp_globals.setwidth_orus = sp_globals.imported_width;*/ + } +else + isw_scale = 0x10000L; /* 1 in 16.16 notation */ +#endif + +/* squeezing on left and right ? */ +if (squeeze_left && squeeze_right) + { + /* calculate scale factor */ + if (bbox_width < set_width) + *x_factor = 0x10000L; /* 1 in 16.16 notation */ + else + *x_factor = ((fix31)set_width<<16)/(fix31)bbox_width; +#if INCL_ISW + IMPORT_FACTOR +#endif + /* calculate offset */ + if (out_on_left) /* fall out on left ? */ + *x_offset = -(fix31)*x_factor * (fix31)bbox_xmin; + /* fall out on right and I am shifting only ? */ + else if (out_on_right && (*x_factor == 0x10000L)) + *x_offset = -(fix31)*x_factor * (fix31)(bbox_xmax - set_width); + else + *x_offset = 0x0L; /* 0 in 16.16 notation */ + } +/* squeezing on left only and violates left */ +else if (squeeze_left) + { + if (bbox_width < set_width) /* will it fit if I shift it ? */ + *x_factor = 0x10000L; /* 1 in 16.16 notation */ + else if (out_on_right) + *x_factor = ((fix31)set_width<<16)/(fix31)bbox_width; + else + *x_factor = ((fix31)set_width<<16)/ + (fix31)(bbox_width - (bbox_xmax-set_width)); +#if INCL_ISW + IMPORT_FACTOR +#endif + *x_offset = (fix31)-*x_factor * (fix31)bbox_xmin; + } + +/* I must be squeezing on right, and violates right */ +else + { + if (bbox_width < set_width) /* will it fit if I shift it ? */ + { /* just shift it left - it will fit in the bbox */ + *x_factor = 0x10000L; /* 1 in 16.16 notation */ +#if INCL_ISW + IMPORT_FACTOR +#endif + *x_offset = (fix31)-*x_factor * (fix31)bbox_xmin; + } + else if (out_on_left) + { + *x_factor = ((fix31)set_width<<16)/(fix31)bbox_width; +#if INCL_ISW + IMPORT_FACTOR +#endif + *x_offset = 0x0L; /* 0 in 16.16 notation */ + } + else + { + *x_factor = ((fix31)set_width<<16)/(fix31)bbox_xmax; +#if INCL_ISW + IMPORT_FACTOR +#endif + *x_offset = 0x0L; /* 0 in 16.16 notation */ + } + } + +x_offset_pix = (fix15)(((*x_offset >> 16) * sp_globals.tcb0.xppo) + / (1<<sp_globals.mpshift)); + +if ((x_offset_pix >0) && (x_offset_pix < sp_globals.onepix)) + x_offset_pix = sp_globals.onepix; + +/* look for the first non-negative oru value, scale and add the offset */ +/* to the corresponding pixel value - note that the pixel value */ +/* is set in read_oru_table. */ + +/* look at all the X edges */ +for (i=0; i < (no_X_ctrl_zones+1); i++) + if (sp_plaid.orus[i] >= 0) + { + sp_plaid.pix[i] = (SQUEEZE_MULT(sp_plaid.pix[i], *x_factor) + +sp_globals.pixrnd + x_offset_pix) & sp_globals.pixfix; + break; + } + +return TRUE; +} + +FUNCTION boolean calculate_y_scale( +GDECL +fix31 *top_scale, fix31 *bottom_scale, +fix15 first_Y_zone, +fix15 no_Y_ctrl_zones) +/* + * Called by sp_setup_pix_table() when squeezing is included + * to determine whether Y scaling is necessary. If it is, + * two scale factors are computed, one for above the baseline, + * and one for below the basline. + * This function returns a boolean value TRUE = Y squeezind is necessary, + * FALSE = no Y squeezing is necessary. + */ +{ +boolean squeeze_top, squeeze_bottom; +boolean out_on_top, out_on_bottom; +fix15 bbox_top, bbox_bottom; +fix15 bbox_height; +fix15 i; + +/* set up some flags and common calculations */ +squeeze_top = (sp_globals.pspecs->flags & SQUEEZE_TOP)? TRUE:FALSE; +squeeze_bottom = (sp_globals.pspecs->flags & SQUEEZE_BOTTOM)? TRUE:FALSE; +bbox_top = sp_globals.bbox_ymax_orus; +bbox_bottom = sp_globals.bbox_ymin_orus; +bbox_height = bbox_top - bbox_bottom; + +if (bbox_top > EM_TOP) + out_on_top = TRUE; +else + out_on_top = FALSE; + +if (bbox_bottom < EM_BOT) + out_on_bottom = TRUE; +else + out_on_bottom = FALSE; + +/* + * don't need Y squeezing if: + * - Y squeezing not enabled + * - bbox doesn't violate on top or bottom + * - top squeezing only is enabled and char isn't out on top + * - bottom squeezing only is enabled and char isn't out on bottom + */ +if ((!squeeze_top && !squeeze_bottom) || + (!out_on_top && !out_on_bottom) || + (squeeze_top && !squeeze_bottom && !out_on_top) || + (squeeze_bottom && !squeeze_top && !out_on_bottom)) + return FALSE; + +if (squeeze_top && (bbox_top > EM_TOP)) + *top_scale = ((fix31)EM_TOP << 16)/(fix31)(bbox_top); +else + *top_scale = 0x10000L; /* 1 in 16.16 fixed point */ + +if (squeeze_bottom && (bbox_bottom < EM_BOT)) + *bottom_scale = ((fix31)-(EM_BOT) << 16)/(fix31)-bbox_bottom; +else + *bottom_scale = 0x10000L; + +if (sp_globals.squeezing_compound) + { + for (i=first_Y_zone; i < (first_Y_zone + no_Y_ctrl_zones + 1); i++) + { + if (sp_plaid.orus[i] >= 0) + sp_plaid.pix[i] = (SQUEEZE_MULT(sp_plaid.pix[i], *top_scale) + +sp_globals.pixrnd) & sp_globals.pixfix; + else + sp_plaid.pix[i] = (SQUEEZE_MULT(sp_plaid.pix[i], *bottom_scale) + +sp_globals.pixrnd) & sp_globals.pixfix; + } + } +return TRUE; +} +#endif + +#if INCL_RULES +FUNCTION static ufix8 FONTFAR *sp_setup_pix_table( +GDECL +ufix8 FONTFAR *pointer, /* Pointer to first byte in control zone table */ +boolean short_form, /* TRUE if 1 byte from/to specification */ +fix15 no_X_ctrl_zones, /* Number of X control zones */ +fix15 no_Y_ctrl_zones) /* Number of Y control zones */ +/* + * Called by plaid_tcb() to read the control zone table from the + * character data in the font. + * Sets up a table of pixel values for all controlled coordinates. + * Updates the pointer to the byte following the control zone + * data. + */ +{ +fix15 i, j, n; +fix31 ppo; +#if INCL_SQUEEZING || INCL_ISW +fix31 xppo0; /* top level pixels per oru */ +fix31 yppo0; /* top level pixels per oru */ +#endif +ufix8 edge_org; +ufix8 edge; +ufix8 start_edge; +ufix8 end_edge; +ufix16 constr_org; +fix15 constr_nr; +fix15 zone_pix; +fix31 whole_zone; /* non-transformed value of the first X zone */ +ufix16 tmpufix16; /* in extended mode, macro uses secnd term */ +#if INCL_SQUEEZING +fix31 x_scale; +fix31 y_top_scale, y_bottom_scale; +fix31 x_offset; +boolean squeezed_y; +fix15 setwidth_pix, em_top_pix, em_bot_pix; +#endif + +#if INCL_ISW +boolean imported_width; +fix31 isw_scale; +fix15 isw_setwidth_pix; +#endif + +#if INCL_ISW || INCL_SQUEEZING +boolean squeezed_x; +#endif + +#if INCL_PLAID_OUT /* Plaid data monitoring included? */ +begin_ctrl_zones(no_X_ctrl_zones, no_Y_ctrl_zones); +#endif + + +edge_org = 0; +constr_org = 0; +sp_globals.rnd_xmin = 0; /* initialize the error for chars with no zone */ +n = no_X_ctrl_zones; +ppo = sp_globals.tcb.xppo; +#if INCL_SQUEEZING || INCL_ISW +xppo0 = sp_globals.tcb0.xppo; +yppo0 = sp_globals.tcb0.yppo; +squeezed_x = FALSE; +#endif + +#if INCL_SQUEEZING +squeezed_x = calculate_x_scale (&x_scale, &x_offset, no_X_ctrl_zones); +squeezed_y = calculate_y_scale(&y_top_scale,&y_bottom_scale,(n+1), + no_Y_ctrl_zones); +#if INCL_ISW +if (sp_globals.import_setwidth_act == TRUE) +setwidth_pix = ((fix15)(((fix31)sp_globals.imported_width * xppo0) >> + sp_globals.mpshift) + sp_globals.pixrnd) & sp_globals.pixfix; + +else +#endif +setwidth_pix = ((fix15)(((fix31)sp_globals.setwidth_orus * xppo0) >> + sp_globals.mpshift) + sp_globals.pixrnd) & sp_globals.pixfix; +/* check for overflow */ +if (setwidth_pix < 0) + setwidth_pix = 0x7fff; /* set to maximum */ +em_bot_pix = ((fix15)(((fix31)EM_BOT * yppo0) >> + sp_globals.mpshift) + sp_globals.pixrnd) & sp_globals.pixfix; +em_top_pix = ((fix15)(((fix31)EM_TOP * yppo0) >> + sp_globals.mpshift) + sp_globals.pixrnd) & sp_globals.pixfix; +#endif + +#if INCL_ISW +/* convert to pixels */ +isw_setwidth_pix = ((fix15)(((fix31)sp_globals.imported_width * xppo0) >> + sp_globals.mpshift) + sp_globals.pixrnd) & sp_globals.pixfix; +/* check for overflow */ +if (isw_setwidth_pix < 0) + isw_setwidth_pix = 0x7fff; /* set to maximum */ +if (!squeezed_x && ((imported_width = sp_globals.import_setwidth_act) == TRUE)) + { + isw_scale = compute_isw_scale(); + + /* look for the first non-negative oru value, scale and add the offset */ + /* to the corresponding pixel value - note that the pixel value */ + /* is set in read_oru_table. */ + + /* look at all the X edges */ + for (i=0; i < (no_X_ctrl_zones+1); i++) + if (sp_plaid.orus[i] >= 0) + { + sp_plaid.pix[i] = (SQUEEZE_MULT(sp_plaid.pix[i], isw_scale) + +sp_globals.pixrnd) & sp_globals.pixfix; + break; + } + + } +#endif + +for (i = 0; ; i++) /* For X and Y control zones... */ + { + for (j = 0; j < n; j++) /* For each zone in X or Y... */ + { + if (short_form) /* 1 byte from/to specification? */ + { + edge = NEXT_BYTE(pointer); /* Read packed from/to spec */ + start_edge = edge_org + (edge & 0x0f); /* Extract start edge */ + end_edge = edge_org + (edge >> 4); /* Extract end edge */ + } + else /* 2 byte from/to specification? */ + { + start_edge = edge_org + NEXT_BYTE(pointer); /* Read start edge */ + end_edge = edge_org + NEXT_BYTE(pointer); /* read end edge */ + } + constr_nr = constr_org + + NEXT_BYTES(pointer, tmpufix16); /* Read constraint number */ +#if INCL_SQUEEZING + if (i == 0 && squeezed_x) + calculate_x_pix(start_edge, end_edge, constr_nr, + x_scale, x_offset, ppo, setwidth_pix); + else if (i == 1 && squeezed_y) + calculate_y_pix(start_edge, end_edge,constr_nr, + y_top_scale, y_bottom_scale, ppo, em_top_pix, em_bot_pix); + else + { +#endif +#if INCL_ISW + if (i==0 && imported_width) + calculate_x_pix(start_edge, end_edge, constr_nr, + isw_scale, 0, ppo, isw_setwidth_pix); + else + { +#endif + if (!sp_globals.c_act[constr_nr]) /* Constraint inactive? */ + { + zone_pix = ((fix15)((((fix31)sp_plaid.orus[end_edge] - + (fix31)sp_plaid.orus[start_edge]) * ppo) / + (1<<sp_globals.mpshift)) + sp_globals.pixrnd) & + sp_globals.pixfix; + if ((ABS(zone_pix)) >= sp_globals.c_pix[constr_nr]) + goto L1; + } + zone_pix = sp_globals.c_pix[constr_nr]; /* Use zone size from constr table */ + if (start_edge > end_edge) /* sp_plaid.orus[start_edge] > sp_plaid.orus[end_edge]? */ + { + zone_pix = -zone_pix; /* Use negatve zone size */ + } + L1: + /* inter-character spacing fix */ + if ((j == 0) && (i == 0)) /* if this is the 1st X zone, save rounding error */ + { /* get the non-xformed - xformed zone, in right direction */ + whole_zone = (((fix31)sp_plaid.orus[end_edge] - + (fix31)sp_plaid.orus[start_edge]) * + ppo) / (1<<sp_globals.mpshift); + sp_globals.rnd_xmin = whole_zone - zone_pix; + } + sp_plaid.pix[end_edge] = sp_plaid.pix[start_edge] + zone_pix; /* Insert end pixels */ +#if INCL_SQUEEZING + if (i == 0) /* in the x direction */ + { /* brute force squeeze */ + if ((sp_globals.pspecs->flags & SQUEEZE_LEFT) && + (sp_plaid.pix[end_edge] < 0)) + sp_plaid.pix[end_edge] = 0; + if ((sp_globals.pspecs->flags & SQUEEZE_RIGHT) && + (sp_plaid.pix[end_edge] > setwidth_pix)) + sp_plaid.pix[end_edge] = setwidth_pix; + } + if (i == 1) /* in the y direction */ + { /* brute force squeeze */ + if ((sp_globals.pspecs->flags & SQUEEZE_TOP) && + (sp_plaid.pix[end_edge] > em_top_pix)) + sp_plaid.pix[end_edge] = em_top_pix; + if ((sp_globals.pspecs->flags & SQUEEZE_BOTTOM) && + (sp_plaid.pix[end_edge] < em_bot_pix)) + sp_plaid.pix[end_edge] = em_bot_pix; + } +#endif +#if INCL_SQUEEZING + } +#endif +#if INCL_ISW + } +#endif +#if INCL_PLAID_OUT /* Plaid data monitoring included? */ + record_ctrl_zone( + (fix31)sp_plaid.pix[start_edge] << (16 - sp_globals.pixshift), + (fix31)sp_plaid.pix[end_edge] << (16 - sp_globals.pixshift), + (fix15)(constr_nr - constr_org)); +#endif + } + if (i) /* Y pixels done? */ + break; + edge_org = sp_globals.Y_edge_org; /* Prepare to process Y ctrl zones */ + constr_org = sp_globals.Y_constr_org; + n = no_Y_ctrl_zones; + ppo = sp_globals.tcb.yppo; + } + +#if DEBUG +printf("\nX PIX TABLE\n"); +n = no_X_ctrl_zones + 1; +for (i = 0; i < n; i++) + printf("%2d %6.1f\n", i, (real)sp_plaid.pix[i] / (real)sp_globals.onepix); +printf("\nY PIX TABLE\n"); +n = no_Y_ctrl_zones + 1; +for (i = 0; i < n; i++) + { + j = i + no_X_ctrl_zones + 1; + printf("%2d %6.1f\n", i, (real)sp_plaid.pix[j] / (real)sp_globals.onepix); + } +#endif + +return pointer; +} +#endif + + +#if INCL_RULES +FUNCTION static ufix8 FONTFAR *sp_setup_int_table( +GDECL +ufix8 FONTFAR *pointer, /* Pointer to first byte in interpolation zone table */ +fix15 no_X_int_zones, /* Number of X interpolation zones */ +fix15 no_Y_int_zones) /* Number of X interpolation zones */ +/* + * Called by plaid_tcb() to read the interpolation zone table from the + * character data in the font. + * Sets up a table of interpolation coefficients with one entry for + * every X or Y interpolation zone. + * Updates the pointer to the byte following the interpolation zone + * data. + */ +{ +fix15 i, j, k, l, n; +ufix8 format; +ufix8 format_copy; +ufix8 tmpufix8; +fix15 start_orus = 0; +ufix8 edge_org; +ufix8 edge; +ufix16 adj_factor; +fix15 adj_orus; +fix15 end_orus = 0; +fix31 zone_orus; +fix15 start_pix = 0; +fix15 end_pix = 0; + + +#if INCL_PLAID_OUT /* Plaid data monitoring included? */ +begin_int_zones(no_X_int_zones, no_Y_int_zones); +#endif + +i = 0; +edge_org = 0; +n = no_X_int_zones; +for (j = 0; ; j++) + { + for (k = 0; k < n; k++) + { + format = NEXT_BYTE(pointer); + if (format & BIT7) /* Short start/end point spec? */ + { + tmpufix8 = NEXT_BYTE(pointer); + edge = edge_org + (tmpufix8 & 0xf); + start_orus = sp_plaid.orus[edge]; + start_pix = sp_plaid.pix[edge]; + edge = edge_org + (tmpufix8 >> 4); + end_orus = sp_plaid.orus[edge]; + end_pix = sp_plaid.pix[edge]; + } + else /* Standard start and end point spec? */ + { + format_copy = format; + for (l = 0; ; l++) /* Loop for start and end point */ + { + switch (format_copy & 0x7) /* Decode start/end point format */ + { + + case 0: /* Index to control edge */ + edge = edge_org + NEXT_BYTE(pointer); + end_orus = sp_plaid.orus[edge]; + end_pix = sp_plaid.pix[edge]; + break; + + case 1: /* 1 byte fractional distance to next edge */ + adj_factor = 0xffff & NEXT_BYTE(pointer) << 8; + goto L1; + + + case 2: /* 2 byte fractional distance to next edge */ + adj_factor = 0xffff & NEXT_WORD(pointer); + L1: edge = edge_org + NEXT_BYTE(pointer); + end_orus = sp_plaid.orus[edge] + + ((((fix31)sp_plaid.orus[edge + 1] - (fix31)sp_plaid.orus[edge]) * + (ufix32)adj_factor + (fix31)32768) >> 16); + end_pix = sp_plaid.pix[edge] + + ((((fix31)sp_plaid.pix[edge + 1] - (fix31)sp_plaid.pix[edge]) * + (ufix32)adj_factor + (fix31)32768) >> 16); + break; + + case 3: /* 1 byte delta orus before first edge */ + adj_orus = -(fix15)NEXT_BYTE(pointer); + goto L2; + + case 4: /* 2 byte delta orus before first edge */ + adj_orus = -NEXT_WORD(pointer); + L2: edge = edge_org; + goto L4; + + case 5: /* 1 byte delta orus after last edge */ + adj_orus = (fix15)NEXT_BYTE(pointer); + goto L3; + + case 6: /* 2 byte delta orus after last edge */ + adj_orus = NEXT_WORD(pointer); + L3: edge = j? sp_globals.Y_edge_org + sp_globals.no_Y_orus - 1: sp_globals.no_X_orus - 1; + L4: end_orus = sp_plaid.orus[edge] + adj_orus; + end_pix = sp_plaid.pix[edge] + + (((fix31)adj_orus * (fix31)(j? sp_globals.tcb.yppo: sp_globals.tcb.xppo) + + sp_globals.mprnd) / (1<<sp_globals.mpshift)); + break; + + } + + if (l) /* Second time round loop? */ + break; + format_copy >>= 3; /* Adj format to decode end point format */ + start_orus = end_orus; /* Save start point oru value */ + start_pix = end_pix; /* Save start point pixel value */ + } + } +#if INCL_PLAID_OUT /* Plaid data monitoring included? */ + record_int_zone( + (fix31)start_pix << (16 - sp_globals.pixshift), + (fix31)end_pix << (16 - sp_globals.pixshift)); +#endif + zone_orus = (fix31)end_orus - (fix31)start_orus; + sp_plaid.mult[i] = ((((fix31)end_pix - (fix31)start_pix) << sp_globals.mpshift) + + (zone_orus / 2)) / zone_orus; + sp_plaid.offset[i] = + (((((fix31)start_pix + (fix31)end_pix) << sp_globals.mpshift) - + ((fix31)sp_plaid.mult[i] * ((fix31)start_orus + (fix31)end_orus))) / 2) + + sp_globals.mprnd; + i++; + } + if (j) /* Finished? */ + break; + edge_org = sp_globals.Y_edge_org; /* Prepare to process Y ctrl zones */ + n = no_Y_int_zones; + } + +#if DEBUG +printf("\nX INT TABLE\n"); +n = no_X_int_zones; +for (i = 0; i < n; i++) + { + printf("%2d %7.4f %7.4f\n", i, + (real)sp_plaid.mult[i] / (real)(1 << sp_globals.multshift), + (real)sp_plaid.offset[i] / (real)(1 << sp_globals.multshift)); + } +printf("\nY INT TABLE\n"); +n = no_Y_int_zones; +for (i = 0; i < n; i++) + { + j = i + no_X_int_zones; + printf("%2d %7.4f %7.4f\n", i, + (real)sp_plaid.mult[j] / (real)(1 << sp_globals.multshift), + (real)sp_plaid.offset[j] / (real)(1 << sp_globals.multshift)); + } +#endif + +return pointer; +} +#endif +#if INCL_ISW +FUNCTION fix31 compute_isw_scale() +GDECL +{ +fix31 isw_scale; + +if (sp_globals.setwidth_orus == 0) + isw_scale = 0x00010000; +else + isw_scale = ((fix31)sp_globals.imported_width << 16)/ + (fix31)sp_globals.setwidth_orus; +return isw_scale; +} +#endif diff --git a/nx-X11/lib/font/Speedo/spdo_prv.h b/nx-X11/lib/font/Speedo/spdo_prv.h new file mode 100644 index 000000000..162c0fddd --- /dev/null +++ b/nx-X11/lib/font/Speedo/spdo_prv.h @@ -0,0 +1,421 @@ +/* $Xorg: spdo_prv.h,v 1.3 2000/08/17 19:46:27 cpqbld Exp $ */ + +/* + +Copyright 1989-1991, Bitstream Inc., Cambridge, MA. +You are hereby granted permission under all Bitstream propriety rights to +use, copy, modify, sublicense, sell, and redistribute the Bitstream Speedo +software and the Bitstream Charter outline font for any purpose and without +restrictions; provided, that this notice is left intact on all copies of such +software or font and that Bitstream's trademark is acknowledged as shown below +on all unmodified copies of such font. + +BITSTREAM CHARTER is a registered trademark of Bitstream Inc. + + +BITSTREAM INC. DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING +WITHOUT LIMITATION THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE. BITSTREAM SHALL NOT BE LIABLE FOR ANY DIRECT OR INDIRECT +DAMAGES, INCLUDING BUT NOT LIMITED TO LOST PROFITS, LOST DATA, OR ANY OTHER +INCIDENTAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF OR IN ANY WAY CONNECTED +WITH THE SPEEDO SOFTWARE OR THE BITSTREAM CHARTER OUTLINE FONT. + +*/ +/* $XFree86: xc/lib/font/Speedo/spdo_prv.h,v 1.4 1999/03/14 03:21:17 dawes Exp $ */ + + + +/***************************** S P D O _ P R V . H *******************************/ + +#include "speedo.h" /* include public definitions */ + +/***** CONFIGURATION DEFINITIONS *****/ + + +/***** PRIVATE FONT HEADER OFFSET CONSTANTS *****/ +#define FH_ORUMX 0 /* U Max ORU value 2 bytes */ +#define FH_PIXMX 2 /* U Max Pixel value 2 bytes */ +#define FH_CUSNR 4 /* U Customer Number 2 bytes */ +#define FH_OFFCD 6 /* E Offset to Char Directory 3 bytes */ +#define FH_OFCNS 9 /* E Offset to Constraint Data 3 bytes */ +#define FH_OFFTK 12 /* E Offset to Track Kerning 3 bytes */ +#define FH_OFFPK 15 /* E Offset to Pair Kerning 3 bytes */ +#define FH_OCHRD 18 /* E Offset to Character Data 3 bytes */ +#define FH_NBYTE 21 /* E Number of Bytes in File 3 bytes */ + + +/***** MODE FLAGS CONSTANTS *****/ +#define CURVES_OUT 0X0008 /* Output module accepts curves */ +#define BOGUS_MODE 0X0010 /* Linear scaling mode */ +#define CONSTR_OFF 0X0020 /* Inhibit constraint table */ +#define IMPORT_WIDTHS 0X0040 /* Imported width mode */ +#define SQUEEZE_LEFT 0X0100 /* Squeeze left mode */ +#define SQUEEZE_RIGHT 0X0200 /* Squeeze right mode */ +#define SQUEEZE_TOP 0X0400 /* Squeeze top mode */ +#define SQUEEZE_BOTTOM 0X0800 /* Squeeze bottom mode */ +#define CLIP_LEFT 0X1000 /* Clip left mode */ +#define CLIP_RIGHT 0X2000 /* Clip right mode */ +#define CLIP_TOP 0X4000 /* Clip top mode */ +#define CLIP_BOTTOM 0X8000 /* Clip bottom mode */ + + +/***** MACRO DEFINITIONS *****/ + +#define SQUEEZE_MULT(A,B) (((fix31)A * (fix31)B) / (1 << 16)) + +#define NEXT_BYTE(A) (*(A)++) + +#define NEXT_WORD(A) \ + ((fix15)(sp_globals.key32 ^ ((A) += 2, \ + ((fix15)((A)[-1]) << 8) | (fix15)((A)[-2]) | \ + ((A)[-1] & 0x80? ~0xFFFF : 0)))) + +#if INCL_EXT /* Extended fonts supported? */ + +#define NEXT_BYTES(A, B) \ + (((B = (ufix16)(*(A)++) ^ sp_globals.key7) >= 248)? \ + ((ufix16)(B & 0x07) << 8) + ((*(A)++) ^ sp_globals.key8) + 248: \ + B) + +#else /* Compact fonts only supported? */ + +#define NEXT_BYTES(A, B) ((*(A)++) ^ sp_globals.key7) + +#endif + + +#define NEXT_BYTE_U(A) (*(A)++) + +#define NEXT_WORD_U(A, B) \ + (fix15)(B = (*(A)++) << 8, (fix15)(*(A)++) + B) + +#define NEXT_CHNDX(A, B) \ + ((B)? (ufix16)NEXT_WORD(A): (ufix16)NEXT_BYTE(A)) + +/* Multiply (fix15)X by (fix15)Y to produce (fix31)product */ +#define MULT16(X, Y) \ + ((fix31)X * (fix31)Y) + +/* Multiply (fix15)X by (fix15)MULT, add (fix31)OFFSET, + * shift right SHIFT bits to produce (fix15)result */ +#define TRANS(X, MULT, OFFSET, SHIFT) \ + ((fix15)((((fix31)X * (fix31)MULT) + OFFSET) / (1 << SHIFT))) + +/****************************************************************************** + * + * the following block of definitions redefines every function + * reference to be prefixed with an "sp_". In addition, if this + * is a reentrant version, the parameter sp_globals will be added + * as the first parameter. + * + *****************************************************************************/ + +#if STATIC_ALLOC || DYNAMIC_ALLOC + +#define GDECL + +#define get_char_id(char_index) sp_get_char_id(char_index) +#define get_char_width(char_index) sp_get_char_width(char_index) +#define get_track_kern(track,point_size) sp_get_track_kern(track,point_size) +#define get_pair_kern(char_index1,char_index2) sp_get_pair_kern(char_index1,char_index2) +#define get_char_bbox(char_index,bbox) sp_get_char_bbox(char_index,bbox) +#define make_char(char_index) sp_make_char(char_index) +#if INCL_ISW +#define compute_isw_scale() sp_compute_isw_scale() +#define do_make_char(char_index) sp_do_make_char(char_index) +#define make_char_isw(char_index,imported_width) sp_make_char_isw(char_index,imported_width) +#define reset_xmax(xmax) sp_reset_xmax(xmax) +#endif +#if INCL_ISW || INCL_SQUEEZING +#define preview_bounding_box(pointer,format) sp_preview_bounding_box(pointer,format) +#endif +#define make_simp_char(pointer,format) sp_make_simp_char(pointer,format) +#define make_comp_char(pointer) sp_make_comp_char(pointer) +#define get_char_org(char_index,top_level) sp_get_char_org(char_index,top_level) +#define get_posn_arg(ppointer,format) sp_get_posn_arg(ppointer,format) +#define get_scale_arg(ppointer,format) sp_get_scale_arg(ppointer,format) +#define read_bbox(ppointer,pPmin,pPmax,set_flag) sp_read_bbox(ppointer,pPmin,pPmax,set_flag) +#define proc_outl_data(pointer) sp_proc_outl_data(pointer) +#define split_curve(P1,P2,P3,depth) sp_split_curve(P1,P2,P3,depth) +#define get_args(ppointer,format,pP) sp_get_args(ppointer,format,pP) + +#define init_black(specsarg) sp_init_black(specsarg) +#define begin_char_black(Psw,Pmin,Pmax) sp_begin_char_black(Psw,Pmin,Pmax) +#define begin_contour_black(P1,outside) sp_begin_contour_black(P1,outside) +#define line_black(P1) sp_line_black(P1) +#define end_char_black() sp_end_char_black() +#define add_intercept_black(y,x) sp_add_intercept_black(y,x) +#define proc_intercepts_black() sp_proc_intercepts_black() + +#define init_screen(specsarg) sp_init_screen(specsarg) +#define begin_char_screen(Psw,Pmin,Pmax) sp_begin_char_screen(Psw,Pmin,Pmax) +#define begin_contour_screen(P1,outside) sp_begin_contour_screen(P1,outside) +#define curve_screen(P1,P2,P3,depth) sp_curve_screen(P1,P2,P3,depth) +#define scan_curve_screen(X0,Y0,X1,Y1,X2,Y2,X3,Y3) sp_scan_curve_screen(X0,Y0,X1,Y1,X2,Y2,X3,Y3) +#define vert_line_screen(x,y1,y2) sp_vert_line_screen(x,y1,y2) +#define line_screen(P1) sp_line_screen(P1) +#define end_contour_screen() sp_end_contour_screen() +#define end_char_screen() sp_end_char_screen() +#define add_intercept_screen(y,x) sp_add_intercept_screen(y,x) +#define proc_intercepts_screen() sp_proc_intercepts_screen() + +#define init_outline(specsarg) sp_init_outline(specsarg) +#define begin_char_outline(Psw,Pmin,Pmax) sp_begin_char_outline(Psw,Pmin,Pmax) +#define begin_sub_char_outline(Psw,Pmin,Pmax) sp_begin_sub_char_outline(Psw,Pmin,Pmax) +#define begin_contour_outline(P1,outside) sp_begin_contour_outline(P1,outside) +#define curve_outline(P1,P2,P3,depth) sp_curve_outline(P1,P2,P3,depth) +#define line_outline(P1) sp_line_outline(P1) +#define end_contour_outline() sp_end_contour_outline() +#define end_sub_char_outline() sp_end_sub_char_outline() +#define end_char_outline() sp_end_char_outline() + +#define init_2d(specsarg) sp_init_2d(specsarg) +#define begin_char_2d(Psw, Pmin, Pmax) sp_begin_char_2d(Psw, Pmin, Pmax) +#define begin_contour_2d(P1, outside) sp_begin_contour_2d(P1, outside) +#define line_2d(P1) sp_line_2d(P1) +#define end_char_2d() sp_end_char_2d() +#define add_intercept_2d(y, x) sp_add_intercept_2d(y, x) +#define proc_intercepts_2d() sp_proc_intercepts_2d() +#define draw_vector_to_2d(x0, y0, x1, y1, band) sp_draw_vector_to_2d(x0, y0, x1, y1, band) + +#define init_char_out(Psw,Pmin,Pmax) sp_init_char_out(Psw,Pmin,Pmax) +#define begin_sub_char_out(Psw,Pmin,Pmax) sp_begin_sub_char_out(Psw,Pmin,Pmax) +#define curve_out(P1,P2,P3,depth) sp_curve_out(P1,P2,P3,depth) +#define end_contour_out() sp_end_contour_out() +#define end_sub_char_out() sp_end_sub_char_out() +#define init_intercepts_out() sp_init_intercepts_out() +#define restart_intercepts_out() sp_restart_intercepts_out() +#define set_first_band_out(Pmin,Pmax) sp_set_first_band_out(Pmin,Pmax) +#define reduce_band_size_out() sp_reduce_band_size_out() +#define next_band_out() sp_next_band_out() + +#define init_userout(specsarg) sp_init_userout(specsarg) + +#define reset() sp_reset() +#define set_key(key) sp_set_key(key) +#define get_cust_no(font_buff) sp_get_cust_no(font_buff) +#define set_specs(specsarg) sp_set_specs(specsarg) +#define setup_consts(xmin,xmax,ymin,ymax) sp_setup_consts(xmin,xmax,ymin,ymax) +#define setup_tcb(ptcb) sp_setup_tcb(ptcb) +#define setup_mult(input_mult) sp_setup_mult(input_mult) +#define setup_offset(input_offset) sp_setup_offset(input_offset) +#define type_tcb(ptcb) sp_type_tcb(ptcb) +#define read_long(pointer) sp_read_long(pointer) +#define read_word_u(pointer) sp_read_word_u(pointer) +#define init_tcb() sp_init_tcb() +#define scale_tcb(ptcb,x_pos,y_pos,x_scale,y_scale) sp_scale_tcb(ptcb,x_pos,y_pos,x_scale,y_scale) +#define plaid_tcb(ppointer,format) sp_plaid_tcb(ppointer,format) +#define skip_orus(ppointer,short_form,no_ctrl_zones) sp_skip_orus(ppointer,short_form,no_ctrl_zones) +#define skip_interpolation_table(ppointer,format) sp_skip_interpolation_table(ppointer,format) +#define skip_control_zone(ppointer,format) sp_skip_control_zone(ppointer,format) +#define constr_update() sp_constr_update() +#define read_oru_table(ppointer) sp_read_oru_table(ppointer) +#define calculate_x_pix(start_edge,end_edge,constr_nr,x_scale,x_offset,ppo,setwidth_pix) sp_calculate_x_pix(start_edge,end_edge,constr_nr,x_scale,x_offset,ppo,setwidth_pix) +#define calculate_y_pix(start_edge,end_edge,constr_nr,top_scale,bottom_scale,ppo,emtop_pix,embot_pix) sp_calculate_y_pix(start_edge,end_edge,constr_nr,top_scale,bottom_scale,ppo,emtop_pix,embot_pix) +#define calculate_x_scale(x_factor,x_offset,no_x_ctrl_zones) sp_calculate_x_scale(x_factor,x_offset,no_x_ctrl_zones) +#define calculate_y_scale(top_scale,bottom_scale,first_y_zone,no_Y_ctrl_zones) sp_calculate_y_scale(top_scale,bottom_scale,first_y_zone,no_Y_ctrl_zones) +#define setup_pix_table(ppointer,short_form,no_X_ctrl_zones,no_Y_ctrl_zones) sp_setup_pix_table(ppointer,short_form,no_X_ctrl_zones,no_Y_ctrl_zones) +#define setup_int_table(ppointer,no_X_int_zones, no_Y_int_zones) sp_setup_int_table(ppointer,no_X_int_zones, no_Y_int_zones) + +#define fn_init_out(specsarg) (*sp_globals.init_out)(specsarg) +#define fn_begin_char(Psw,Pmin,Pmax) (*sp_globals.begin_char)(Psw,Pmin,Pmax) +#define fn_begin_sub_char(Psw,Pmin,Pmax) (*sp_globals.begin_sub_char)(Psw,Pmin,Pmax) +#define fn_end_sub_char() (*sp_globals.end_sub_char)() +#define fn_end_char() (*sp_globals.end_char)() +#define fn_line(P1) (*sp_globals.line)(P1) +#define fn_end_contour() (*sp_globals.end_contour)() +#define fn_begin_contour(P0,fmt) (*sp_globals.begin_contour)(P0,fmt) +#define fn_curve(P1,P2,P3,depth) (*sp_globals.curve)(P1,P2,P3,depth) + +#define load_char_data(offset, no_bytes, buff_off) sp_load_char_data(offset, no_bytes, buff_off) +#define report_error(n) sp_report_error(n) + +#if INCL_MULTIDEV + +#define set_bitmap_device(bfuncs,size) sp_set_bitmap_device(bfuncs,size) +#define set_outline_device(ofuncs,size) sp_set_outline_device(ofuncs,size) + +#define open_bitmap(x_set_width, y_set_width, xmin, xmax, ymin, ymax) (*sp_globals.bitmap_device.p_open_bitmap)(x_set_width, y_set_width, xmin, xmax, ymin, ymax) +#define set_bitmap_bits(y, xbit1, xbit2) (*sp_globals.bitmap_device.p_set_bits)(y, xbit1, xbit2) +#define close_bitmap() (*sp_globals.bitmap_device.p_close_bitmap)() + +#define open_outline(x_set_width, y_set_width, xmin, xmax, ymin, ymax) (*sp_globals.outline_device.p_open_outline)(x_set_width, y_set_width, xmin, xmax, ymin, ymax) +#define start_new_char() (*sp_globals.outline_device.p_start_char)() +#define start_contour(x,y,outside) (*sp_globals.outline_device.p_start_contour)(x,y,outside) +#define curve_to(x1,y1,x2,y2,x3,y3) (*sp_globals.outline_device.p_curve)(x1,y1,x2,y2,x3,y3) +#define line_to(x,y) (*sp_globals.outline_device.p_line)(x,y) +#define close_contour() (*sp_globals.outline_device.p_close_contour)() +#define close_outline() (*sp_globals.outline_device.p_close_outline)() + +#else + +#define open_bitmap(x_set_width, y_set_width, xmin, xmax, ymin, ymax) sp_open_bitmap(x_set_width, y_set_width, xmin, xmax, ymin, ymax) +#define set_bitmap_bits(y, xbit1, xbit2) sp_set_bitmap_bits(y, xbit1, xbit2) +#define close_bitmap() sp_close_bitmap() + +#define open_outline(x_set_width, y_set_width, xmin, xmax, ymin, ymax) sp_open_outline(x_set_width, y_set_width, xmin, xmax, ymin, ymax) +#define start_new_char() sp_start_new_char() +#define start_contour(x,y,outside) sp_start_contour(x,y,outside) +#define curve_to(x1,y1,x2,y2,x3,y3) sp_curve_to(x1,y1,x2,y2,x3,y3) +#define line_to(x,y) sp_line_to(x,y) +#define close_contour() sp_close_contour() +#define close_outline() sp_close_outline() + +#endif + +#else + +#define GDECL SPEEDO_GLOBALS* sp_global_ptr, + +#define get_char_id(char_index) sp_get_char_id(sp_global_ptr,char_index) +#define get_char_width(char_index) sp_get_char_width(sp_global_ptr,char_index) +#define get_track_kern(track,point_size) sp_get_track_kern(sp_global_ptr,track,point_size) +#define get_pair_kern(char_index1,char_index2) sp_get_pair_kern(sp_global_ptr,char_index1,char_index2) +#define get_char_bbox(char_index,bbox) sp_get_char_bbox(sp_global_ptr,char_index,bbox) +#define make_char(char_index) sp_make_char(sp_global_ptr,char_index) +#if INCL_ISW +#define compute_isw_scale() sp_compute_isw_scale(sp_global_ptr) +#define do_make_char(char_index) sp_do_make_char(sp_global_ptr,char_index) +#define make_char_isw(char_index,imported_width) sp_make_char_isw(sp_global_ptr,char_index,imported_width) +#define reset_xmax(xmax) sp_reset_xmax(sp_global_ptr,xmax) +#endif +#if INCL_ISW || INCL_SQUEEZING +#define preview_bounding_box(pointer,format) sp_preview_bounding_box(sp_global_ptr,pointer,format) +#endif +#define make_simp_char(pointer,format) sp_make_simp_char(sp_global_ptr,pointer,format) +#define make_comp_char(pointer) sp_make_comp_char(sp_global_ptr,pointer) +#define get_char_org(char_index,top_level) sp_get_char_org(sp_global_ptr,char_index,top_level) +#define get_posn_arg(ppointer,format) sp_get_posn_arg(sp_global_ptr,ppointer,format) +#define get_scale_arg(ppointer,format) sp_get_scale_arg(sp_global_ptr,ppointer,format) +#define read_bbox(ppointer,pPmin,pPmax,set_flag) sp_read_bbox(sp_global_ptr,ppointer,pPmin,pPmax,set_flag) +#define proc_outl_data(pointer) sp_proc_outl_data(sp_global_ptr,pointer) +#define split_curve(P1,P2,P3,depth) sp_split_curve(sp_global_ptr,P1,P2,P3,depth) +#define get_args(ppointer,format,pP) sp_get_args(sp_global_ptr,ppointer,format,pP) + +#define init_black(specsarg) sp_init_black(sp_global_ptr,specsarg) +#define begin_char_black(Psw,Pmin,Pmax) sp_begin_char_black(sp_global_ptr,Psw,Pmin,Pmax) +#define begin_contour_black(P1,outside) sp_begin_contour_black(sp_global_ptr,P1,outside) +#define line_black(P1) sp_line_black(sp_global_ptr,P1) +#define end_char_black() sp_end_char_black(sp_global_ptr) +#define add_intercept_black(y,x) sp_add_intercept_black(sp_global_ptr,y,x) +#define proc_intercepts_black() sp_proc_intercepts_black(sp_global_ptr) + +#define init_screen(specsarg) sp_init_screen(sp_global_ptr,specsarg) +#define begin_char_screen(Psw,Pmin,Pmax) sp_begin_char_screen(sp_global_ptr,Psw,Pmin,Pmax) +#define begin_contour_screen(P1,outside) sp_begin_contour_screen(sp_global_ptr,P1,outside) +#define curve_screen(P1,P2,P3,depth) sp_curve_screen(sp_global_ptr,P1,P2,P3,depth) +#define scan_curve_screen(X0,Y0,X1,Y1,X2,Y2,X3,Y3) sp_scan_curve_screen(sp_global_ptr,X0,Y0,X1,Y1,X2,Y2,X3,Y3) +#define vert_line_screen(x,y1,y2) sp_vert_line_screen(sp_global_ptr,x,y1,y2) +#define line_screen(P1) sp_line_screen(sp_global_ptr,P1) +#define end_char_screen() sp_end_char_screen(sp_global_ptr) +#define end_contour_screen() sp_end_contour_screen(sp_global_ptr) +#define add_intercept_screen(y,x) sp_add_intercept_screen(sp_global_ptr,y,x) +#define proc_intercepts_screen() sp_proc_intercepts_screen(sp_global_ptr) + +#define init_outline(specsarg) sp_init_outline(sp_global_ptr,specsarg) +#define begin_char_outline(Psw,Pmin,Pmax) sp_begin_char_outline(sp_global_ptr,Psw,Pmin,Pmax) +#define begin_sub_char_outline(Psw,Pmin,Pmax) sp_begin_sub_char_outline(sp_global_ptr,Psw,Pmin,Pmax) +#define begin_contour_outline(P1,outside) sp_begin_contour_outline(sp_global_ptr,P1,outside) +#define curve_outline(P1,P2,P3,depth) sp_curve_outline(sp_global_ptr,P1,P2,P3,depth) +#define line_outline(P1) sp_line_outline(sp_global_ptr,P1) +#define end_contour_outline() sp_end_contour_outline(sp_global_ptr) +#define end_sub_char_outline() sp_end_sub_char_outline(sp_global_ptr) +#define end_char_outline() sp_end_char_outline(sp_global_ptr) + +#define init_2d(specsarg) sp_init_2d(sp_global_ptr,specsarg) +#define begin_char_2d(Psw, Pmin, Pmax) sp_begin_char_2d(sp_global_ptr,Psw, Pmin, Pmax) +#define begin_contour_2d(P1, outside) sp_begin_contour_2d(sp_global_ptr,P1, outside) +#define line_2d(P1) sp_line_2d(sp_global_ptr,P1) +#define end_char_2d() sp_end_char_2d(sp_global_ptr) +#define add_intercept_2d(y, x) sp_add_intercept_2d(sp_global_ptr,y, x) +#define proc_intercepts_2d() sp_proc_intercepts_2d(sp_global_ptr) +#define draw_vector_to_2d(x0, y0, x1, y1, band) sp_draw_vector_to_2d(sp_global_ptr,x0, y0, x1, y1, band) + +#define init_char_out(Psw,Pmin,Pmax) sp_init_char_out(sp_global_ptr,Psw,Pmin,Pmax) +#define begin_sub_char_out(Psw,Pmin,Pmax) sp_begin_sub_char_out(sp_global_ptr,Psw,Pmin,Pmax) +#define curve_out(P1,P2,P3,depth) sp_curve_out(sp_global_ptr,P1,P2,P3,depth) +#define end_contour_out() sp_end_contour_out(sp_global_ptr) +#define end_sub_char_out() sp_end_sub_char_out(sp_global_ptr) +#define init_intercepts_out() sp_init_intercepts_out(sp_global_ptr) +#define restart_intercepts_out() sp_restart_intercepts_out(sp_global_ptr) +#define set_first_band_out(Pmin,Pmax) sp_set_first_band_out(sp_global_ptr,Pmin,Pmax) +#define reduce_band_size_out() sp_reduce_band_size_out(sp_global_ptr) +#define next_band_out() sp_next_band_out(sp_global_ptr) + +#define init_userout(specsarg) sp_init_userout(sp_global_ptr,specsarg) + +#define reset() sp_reset(sp_global_ptr) +#define set_key(key) sp_set_key(sp_global_ptr,key) +#define get_cust_no(font_buff) sp_get_cust_no(sp_global_ptr,font_buff) +#define set_specs(specsarg) sp_set_specs(sp_global_ptr,specsarg) +#define setup_consts(xmin,xmax,ymin,ymax) sp_setup_consts(sp_global_ptr,xmin,xmax,ymin,ymax) +#define setup_tcb(ptcb) sp_setup_tcb(sp_global_ptr,ptcb) +#define setup_mult(input_mult) sp_setup_mult(sp_global_ptr,input_mult) +#define setup_offset(input_offset) sp_setup_offset(sp_global_ptr,input_offset) +#define type_tcb(ptcb) sp_type_tcb(sp_global_ptr,ptcb) +#define read_long(pointer) sp_read_long(sp_global_ptr,pointer) +#define read_word_u(pointer) sp_read_word_u(sp_global_ptr,pointer) +#define init_tcb() sp_init_tcb(sp_global_ptr) +#define scale_tcb(ptcb,x_pos,y_pos,x_scale,y_scale) sp_scale_tcb(sp_global_ptr,ptcb,x_pos,y_pos,x_scale,y_scale) +#define plaid_tcb(ppointer,format) sp_plaid_tcb(sp_global_ptr,ppointer,format) +#define skip_orus(ppointer,short_form,no_ctrl_zones) sp_skip_orus(sp_global_ptr,ppointer,short_form,no_ctrl_zones) +#define skip_interpolation_table(ppointer,format) sp_skip_interpolation_table(sp_global_ptr,ppointer,format) +#define skip_control_zone(ppointer,format) sp_skip_control_zone(sp_global_ptr,ppointer,format) +#define constr_update() sp_constr_update(sp_global_ptr) +#define read_oru_table(ppointer) sp_read_oru_table(sp_global_ptr,ppointer) +#define calculate_x_pix(start_edge,end_edge,constr_nr,x_scale,x_offset,ppo,setwidth_pix) sp_calculate_x_pix(sp_global_ptr,start_edge,end_edge,constr_nr,x_scale,x_offset,ppo,setwidth_pix) +#define calculate_y_pix(start_edge,end_edge,constr_nr,top_scale,bottom_scale,ppo,emtop_pix,embot_pix) sp_calculate_y_pix(sp_global_ptr,start_edge,end_edge,constr_nr,top_scale,bottom_scale,ppo,emtop_pix,embot_pix) +#define calculate_x_scale(x_factor,x_offset,no_x_ctrl_zones) sp_calculate_x_scale(sp_global_ptr,x_factor,x_offset,no_x_ctrl_zones) +#define calculate_y_scale(top_scale,bottom_scale,first_y_zone,no_Y_ctrl_zones) sp_calculate_y_scale(sp_global_ptr,top_scale,bottom_scale,first_y_zone,no_Y_ctrl_zones) +#define setup_pix_table(ppointer,short_form,no_X_ctrl_zones,no_Y_ctrl_zones) sp_setup_pix_table(sp_global_ptr,ppointer,short_form,no_X_ctrl_zones,no_Y_ctrl_zones) +#define setup_int_table(ppointer,no_X_int_zones, no_Y_int_zones) sp_setup_int_table(sp_global_ptr,ppointer,no_X_int_zones, no_Y_int_zones) + +#define fn_init_out(specsarg) (*sp_globals.init_out)(sp_global_ptr,specsarg) +#define fn_begin_char(Psw,Pmin,Pmax) (*sp_globals.begin_char)(sp_global_ptr,Psw,Pmin,Pmax) +#define fn_begin_sub_char(Psw,Pmin,Pmax) (*sp_globals.begin_sub_char)(sp_global_ptr,Psw,Pmin,Pmax) +#define fn_end_sub_char() (*sp_globals.end_sub_char)(sp_global_ptr) +#define fn_end_char() (*sp_globals.end_char)(sp_global_ptr) +#define fn_line(P1) (*sp_globals.line)(sp_global_ptr,P1) +#define fn_end_contour() (*sp_globals.end_contour)(sp_global_ptr) +#define fn_begin_contour(P0,fmt) (*sp_globals.begin_contour)(sp_global_ptr,P0,fmt) +#define fn_curve(P1,P2,P3,depth) (*sp_globals.curve)(sp_global_ptr,P1,P2,P3,depth) + + +#define load_char_data(offset, no_bytes, buff_off) sp_load_char_data(sp_global_ptr, offset, no_bytes, buff_off) +#define report_error(n) sp_report_error(sp_global_ptr, n) + +#if INCL_MULTIDEV + +#define set_bitmap_device(bfuncs,size) sp_set_bitmap_device(sp_global_ptr,bfuncs,size) +#define set_outline_device(ofuncs,size) sp_set_outline_device(sp_global_ptr,ofuncs,size) + +#define open_bitmap(x_set_width, y_set_width, xmin, xmax, ymin, ymax)(*sp_globals.bitmap_device.p_open_bitmap)(sp_global_ptr,x_set_width, y_set_width, xmin, xmax, ymin, ymax) +#define set_bitmap_bits(y, xbit1, xbit2)(*sp_globals.bitmap_device.p_set_bits)(sp_global_ptr,y, xbit1, xbit2) +#define close_bitmap()(*sp_globals.bitmap_device.p_close_bitmap)(sp_global_ptr) + +#define open_outline(x_set_width, y_set_width, xmin, xmax, ymin, ymax)(*sp_globals.outline_device.p_open_outline)(sp_global_ptr,x_set_width, y_set_width, xmin, xmax, ymin, ymax) +#define start_new_char()(*sp_globals.outline_device.p_start_char)(sp_global_ptr) +#define start_contour(x,y,outside)(*sp_globals.outline_device.p_start_contour)(sp_global_ptr,x,y,outside) +#define curve_to(x1,y1,x2,y2,x3,y3)(*sp_globals.outline_device.p_curve)(sp_global_ptr,x1,y1,x2,y2,x3,y3) +#define line_to(x,y)(*sp_globals.outline_device.p_line)(sp_global_ptr,x,y) +#define close_contour()(*sp_globals.outline_device.p_close_contour)(sp_global_ptr) +#define close_outline()(*sp_globals.outline_device.p_close_outline)(sp_global_ptr) + +#else + +#define open_bitmap(x_set_width, y_set_width, xmin, xmax, ymin, ymax) sp_open_bitmap(sp_global_ptr, x_set_width, y_set_width, xmin, xmax, ymin, ymax) +#define set_bitmap_bits(y, xbit1, xbit2) sp_set_bitmap_bits(sp_global_ptr, y, xbit1, xbit2) +#define close_bitmap() sp_close_bitmap(sp_global_ptr) + +#define open_outline(x_set_width, y_set_width, xmin, xmax, ymin, ymax) sp_open_outline(sp_global_ptr, x_set_width, y_set_width, xmin, xmax, ymin, ymax) +#define start_new_char() sp_start_new_char(sp_global_ptr ) +#define start_contour(x,y,outside) sp_start_contour(sp_global_ptr, x,y,outside) +#define curve_to(x1,y1,x2,y2,x3,y3) sp_curve_to(sp_global_ptr, x1,y1,x2,y2,x3,y3) +#define line_to(x,y) sp_line_to(sp_global_ptr, x,y) +#define close_contour() sp_close_contour(sp_global_ptr) +#define close_outline() sp_close_outline(sp_global_ptr) + +#endif +#endif + + diff --git a/nx-X11/lib/font/Speedo/speedo.h b/nx-X11/lib/font/Speedo/speedo.h new file mode 100644 index 000000000..5eb516c1c --- /dev/null +++ b/nx-X11/lib/font/Speedo/speedo.h @@ -0,0 +1,890 @@ +/* $Xorg: speedo.h,v 1.3 2000/08/17 19:46:27 cpqbld Exp $ */ + +/* + +Copyright 1989-1991, Bitstream Inc., Cambridge, MA. +You are hereby granted permission under all Bitstream propriety rights to +use, copy, modify, sublicense, sell, and redistribute the Bitstream Speedo +software and the Bitstream Charter outline font for any purpose and without +restrictions; provided, that this notice is left intact on all copies of such +software or font and that Bitstream's trademark is acknowledged as shown below +on all unmodified copies of such font. + +BITSTREAM CHARTER is a registered trademark of Bitstream Inc. + + +BITSTREAM INC. DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING +WITHOUT LIMITATION THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE. BITSTREAM SHALL NOT BE LIABLE FOR ANY DIRECT OR INDIRECT +DAMAGES, INCLUDING BUT NOT LIMITED TO LOST PROFITS, LOST DATA, OR ANY OTHER +INCIDENTAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF OR IN ANY WAY CONNECTED +WITH THE SPEEDO SOFTWARE OR THE BITSTREAM CHARTER OUTLINE FONT. + +*/ +/* $XFree86: xc/lib/font/Speedo/speedo.h,v 3.5 2001/01/17 19:43:18 dawes Exp $ */ + +#ifndef _SPEEDO_H_ +#define _SPEEDO_H_ + +#include <X11/Xmd.h> + +/***************************** S P E E D O . H ******************************* + ****************************************************************************/ + +/***** USER OPTIONS OVERRIDE DEFAULTS ******/ +#include "useropt.h" + +/***** CONFIGURATION DEFINITIONS *****/ + +#ifndef INCL_CLIPPING +#define INCL_CLIPPING 0 /* 0 indicates CLIPPING code is not compiled in*/ +#endif + +#ifndef INCL_SQUEEZING +#define INCL_SQUEEZING 0 /* 0 indicates SQUEEZE code is not compiled in*/ +#endif + +#ifndef INCL_EXT +#define INCL_EXT 1 /* 1 to include extended font support */ +#endif /* 0 to omit extended font support */ + +#ifndef INCL_RULES +#define INCL_RULES 1 /* 1 to include intelligent scaling support */ +#endif /* 0 to omit intelligent scaling support */ + +#ifndef INCL_BLACK +#define INCL_BLACK 1 /* 1 to include blackwriter output support */ +#endif /* 0 to omit output mode 0 support */ + +#ifndef INCL_SCREEN +#define INCL_SCREEN 0 /* 1 to include screen writeroutput support */ +#endif /* 0 to omit support */ + +#ifndef INCL_OUTLINE +#define INCL_OUTLINE 0 /* 1 to include outline output support */ +#endif /* 0 to omit output mode 2 support */ + +#ifndef INCL_2D +#define INCL_2D 0 /* 1 to include 2d blackwriter output support */ +#endif /* 0 to omit output mode 3 support */ + +#ifndef INCL_USEROUT +#define INCL_USEROUT 0 /* 1 to include user defined output module support */ +#endif /* 0 to omit user defined output module support */ + +#ifndef INCL_LCD +#define INCL_LCD 1 /* 1 to include load char data support*/ +#endif /* 0 to omit load char data support */ +#ifndef INCL_ISW +#define INCL_ISW 0 /* 1 to include imported width support */ +#endif /* 0 to omit imported width support */ + +#ifndef INCL_METRICS +#define INCL_METRICS 1 /* 1 to include metrics support */ +#endif /* 0 to omit metrics support */ + +#ifndef INCL_KEYS +#define INCL_KEYS 0 /* 1 to include multi key support */ +#endif /* 0 to omit multi key support */ + +#ifndef INCL_MULTIDEV +#define INCL_MULTIDEV 0 /* 1 to include multiple output device support */ +#endif /* 0 to omit multi device support */ + +#ifndef SHORT_LISTS +#define SHORT_LISTS 1 /* 1 to allocate small intercept lists */ +#endif + +#ifndef INCL_PLAID_OUT +#define INCL_PLAID_OUT 0 /* 1 to include plaid data monitoring */ +#endif /* 0 to omit plaid data monitoring */ + +#ifndef FONTFAR /* if Intel mixed memory model implementation */ +#define FONTFAR /* pointer type modifier for font buffer */ +#endif + +#ifndef STACKFAR /* if Intel mixed memory model implementation */ +#define STACKFAR /* pointer type modifier for font buffer */ +#endif + +#ifndef GLOBALFAR +#define GLOBALFAR +#endif + +#define MODE_BLACK 0 +#define MODE_SCREEN MODE_BLACK + INCL_BLACK +#define MODE_OUTLINE MODE_SCREEN + INCL_SCREEN +#define MODE_2D MODE_OUTLINE + INCL_OUTLINE + +#ifdef DYNAMIC_ALLOC +#if DYNAMIC_ALLOC +#define STATIC_ALLOC 0 +#endif +#endif + +#ifdef REENTRANT_ALLOC +#if REENTRANT_ALLOC +#define STATIC_ALLOC 0 +#endif +#endif + +#ifndef STATIC_ALLOC +#define STATIC_ALLOC 1 +#endif + +#ifndef DYNAMIC_ALLOC +#define DYNAMIC_ALLOC 0 +#endif + +#ifndef REENTRANT_ALLOC +#define REENTRANT_ALLOC 0 +#endif + +/***** TYPE DEFINITIONS *****/ + +#ifndef STDEF +#ifndef SPD_BMAP + +typedef INT8 fix7; + +typedef double real; + +typedef CARD8 ufix8; +#ifndef VFONT +typedef CARD8 boolean; +#endif +#endif + +typedef INT16 fix15; + +typedef CARD16 ufix16; + +typedef INT32 fix31; + +typedef CARD32 ufix32; +#endif + +/***** GENERAL CONSTANTS *****/ + +#ifndef FALSE +#define FALSE 0 +#define TRUE 1 +#endif + +#ifndef NULL +#include <stddef.h> +#endif + +#define FUNCTION + +#define BIT0 0x01 +#define BIT1 0x02 +#define BIT2 0x04 +#define BIT3 0x08 +#define BIT4 0x10 +#define BIT5 0x20 +#define BIT6 0x40 +#define BIT7 0x80 + +#if INCL_EXT /* Extended fonts supported? */ + +#define MAX_CONSTR 750 /* Max constraints (incl 4 dummies) */ +#define MAX_CTRL_ZONES 256 /* Max number of controlled orus */ +#define MAX_INT_ZONES 256 /* Max number of interpolation zones */ + +#else /* Compact fonts only supported */ + +#define MAX_CONSTR 512 /* Max constraints (incl 4 dummies) */ +#define MAX_CTRL_ZONES 64 /* Max number of controlled orus */ +#define MAX_INT_ZONES 64 /* Max number of interpolation zones */ + +#endif + +#define SCALE_SHIFT 12 /* Binary point positiion for scale values */ +#define SCALE_RND 2048 /* Rounding bit for scaling transformation */ +#define ONE_SCALE 4096 /* Unity scale value */ + +#ifdef INCL_SCREEN /* constants used by Screenwriter module */ +#define LEFT_INT 1 /* left intercept */ +#define END_INT 2 /* last intercept */ +#define FRACTION 0xFC /* fractional portion of intercept type list */ +#endif + +#if INCL_SQUEEZING || INCL_CLIPPING /* constants used by SQUEEZEing code */ +#define EM_TOP 764 +#define EM_BOT -236 +#endif + +/***** STRUCTURE DEFINITIONS *****/ +#if REENTRANT_ALLOC +#define PROTO_DECL1 struct speedo_global_data GLOBALFAR *sp_global_ptr +#define PROTO_DECL2 PROTO_DECL1 , +#else +#define PROTO_DECL1 void +#define PROTO_DECL2 +#endif + +typedef +struct buff_tag + { + ufix8 FONTFAR *org; /* Pointer to start of buffer */ + ufix32 no_bytes; /* Size of buffer in bytes */ + } +buff_t; /* Buffer descriptor */ + +typedef struct constr_tag + { + ufix8 FONTFAR *org; /* Pointer to first byte in constr data */ + ufix16 font_id; /* Font id for calculated data */ + fix15 xppo; /* X pixels per oru for calculated data */ + fix15 yppo; /* Y pixels per oru for calculated data */ + boolean font_id_valid; /* TRUE if font id valid */ + boolean data_valid; /* TRUE if calculated data valid */ + boolean active; /* TRUE if constraints enabled */ + } +constr_t; /* Constraint data state */ + +typedef struct kern_tag + { + ufix8 FONTFAR *tkorg; /* First byte of track kerning data */ + ufix8 FONTFAR *pkorg; /* First byte of pair kerning data */ + fix15 no_tracks; /* Number of kerning tracks */ + fix15 no_pairs; /* Number of kerning pairs */ + } +kern_t; /* Kerning control block */ + +typedef struct specs_tag + { + buff_t STACKFAR *pfont; /* Pointer to font data */ + fix31 xxmult; /* Coeff of X orus to compute X pix */ + fix31 xymult; /* Coeff of Y orus to compute X pix */ + fix31 xoffset; /* Constant to compute X pix */ + fix31 yxmult; /* Coeff of X orus to compute Y pix */ + fix31 yymult; /* Coeff of Y orus to compute Y pix */ + fix31 yoffset; /* Constant to compute Y pix */ + ufix32 flags; /* Mode flags: */ + /* Bit 0 - 2: Output module selector: */ + /* Bit 3: Send curves to output module*/ + /* Bit 4: Use linear scaling if set */ + /* Bit 5: Inhibit constraint table */ + /* Bit 6: Import set width if set */ + /* Bit 7: not used */ + /* Bit 8: Squeeze left if set */ + /* Bit 9: Squeeze right if set */ + /* Bit 10: Squeeze top if set */ + /* Bit 11: Squeeze bottom if set */ + /* Bit 12: Clip left if set */ + /* Bit 13: Clip right if set */ + /* Bit 14: Clip top if set */ + /* Bit 15: Clip bottom if set */ + /* Bits 16-31 not used */ + void *out_info; /* information for output module */ + } +specs_t; /* Specs structure for fw_set_specs */ + +typedef struct tcb_tag + { + fix15 xxmult; /* Linear coeff of Xorus to compute Xpix */ + fix15 xymult; /* Linear coeff of Yorus to compute Xpix */ + fix31 xoffset; /* Linear constant to compute Xpix */ + fix15 yxmult; /* Linear coeff of Xorus to compute Ypix */ + fix15 yymult; /* Linear coeff of Yorus to compute Ypix */ + fix31 yoffset; /* Linear constant to compute Ypix */ + fix15 xppo; /* Pixels per oru in X dimension of char */ + fix15 yppo; /* Pixels per oru in Y dimension of char */ + fix15 xpos; /* Origin in X dimension of character */ + fix15 ypos; /* Origin in Y dimension of character */ + ufix16 xtype; /* Transformation type for X oru coords */ + ufix16 ytype; /* Transformation type for Y oru coords */ + ufix16 xmode; /* Transformation mode for X oru coords */ + ufix16 ymode; /* Transformation mode for Y oru coords */ + fix15 mirror; /* Transformation creates mirror image */ + } +tcb_t; /* Transformation control block */ + +typedef struct point_tag + { + fix15 x; /* X coord of point (shifted pixels) */ + fix15 y; /* Y coord of point (shifted pixels) */ + } +point_t; /* Point in device space */ + +typedef struct band_tag + { + fix15 band_max; + fix15 band_min; + fix15 band_array_offset; + fix15 band_floor; + fix15 band_ceiling; + } band_t; + +typedef struct bbox_tag + { + fix31 xmin; + fix31 xmax; + fix31 ymin; + fix31 ymax; + } bbox_t; + +#if SHORT_LISTS +#define MAX_INTERCEPTS 256 /* Max storage for intercepts */ +typedef ufix8 cdr_t; /* 8 bit links in intercept chains */ +#else +#define MAX_INTERCEPTS 1000 /* Max storage for intercepts */ +typedef ufix16 cdr_t; /* 16 bit links in intercept chains */ +#endif + +#if REENTRANT_ALLOC + +typedef struct intercepts_tag + { + fix15 car[MAX_INTERCEPTS]; + fix15 cdr[MAX_INTERCEPTS]; +#if INCL_SCREEN + ufix8 inttype[MAX_INTERCEPTS]; + ufix8 leftedge; + ufix16 fracpix; +#endif + } intercepts_t; + +typedef struct plaid_tag + { + fix15 orus[MAX_CTRL_ZONES]; /* Controlled coordinate table (orus) */ +#if INCL_RULES + fix15 pix[MAX_CTRL_ZONES]; /* Controlled coordinate table (sub-pixels) */ + fix15 mult[MAX_INT_ZONES]; /* Interpolation multiplier table */ + fix31 offset[MAX_INT_ZONES]; /* Interpolation offset table */ +#endif + } plaid_t; +#endif + +#if INCL_MULTIDEV +typedef struct bitmap_tag + { + void (*p_open_bitmap)(PROTO_DECL2 fix31 x_set_width, fix31 y_set_width, fix31 xorg, fix31 yorg, fix15 xsize,fix15 ysize); + void (*p_set_bits)(PROTO_DECL2 fix15 y, fix15 xbit1, fix15 xbit2); + void (*p_close_bitmap)(PROTO_DECL1); + } bitmap_t; + +typedef struct outline_tag + { + void (*p_open_outline)(PROTO_DECL2 fix31 x_set_width, fix31 y_set_width, fix31 xmin, fix31 xmax, fix31 ymin,fix31 ymax); + void (*p_start_char)(PROTO_DECL1); + void (*p_start_contour)(PROTO_DECL2 fix31 x,fix31 y,boolean outside); + void (*p_curve)(PROTO_DECL2 fix31 x1, fix31 y1, fix31 x2, fix31 y2, fix31 x3, fix31 y3); + void (*p_line)(PROTO_DECL2 fix31 x, fix31 y); + void (*p_close_contour)(PROTO_DECL1); + void (*p_close_outline)(PROTO_DECL1); + } outline_t; +#endif + +/* ---------------------------------------------------*/ +/**** MAIN GLOBAL DATA STRUCTURE, SPEEDO_GLOBALS *****/ + +typedef struct speedo_global_data + { +/* do_char.c data definitions */ +#if INCL_METRICS /* Metrics functions supported? */ + kern_t kern; /* Kerning control block */ +#endif /* endif incl_metrics */ + point_t Psw; /* End of escapement vector (1/65536 pixel units) */ + +#if INCL_LCD /* Dynamic load character data supported? */ + fix15 cb_offset; /* Offset to sub-char data in char buffer */ +#endif /* endif incl_lcd */ + +/* do_trns.c data definitions */ + point_t P0; /* Current point (sub-pixels) */ + fix15 x_orus; /* Current X argument (orus) */ + fix15 y_orus; /* Current Y argument (orus) */ + fix15 x_pix; /* Current X argument (sub-pixels) */ + fix15 y_pix; /* Current Y argument (sub-pixels) */ + ufix8 x_int; /* Current X interpolation zone */ + ufix8 y_int; /* Current Y interpolation zone */ + +#if INCL_MULTIDEV && INCL_OUTLINE + outline_t outline_device; + boolean outline_device_set; +#endif + +#if INCL_BLACK || INCL_SCREEN || INCL_2D +#if INCL_MULTIDEV + bitmap_t bitmap_device; + boolean bitmap_device_set; +#endif + band_t y_band; /* Y current band(whole pixels) */ + + struct set_width_tag + { + fix31 x; + fix31 y; + } set_width; /* Character escapement vector */ + + boolean first_pass; /* TRUE during first pass thru outline data */ + boolean extents_running; /* T if extent accumulation for each vector */ + fix15 x0_spxl; /* X coord of current point (sub pixels) */ + fix15 y0_spxl; /* Y coord of current point (sub pixels) */ + fix15 y_pxl; /* Y coord of current point (whole pixels) */ +#if REENTRANT_ALLOC + intercepts_t STACKFAR *intercepts; +#else /* else if not reentrant */ + fix15 car[MAX_INTERCEPTS]; /* Data field of intercept storage */ + cdr_t cdr[MAX_INTERCEPTS]; /* Link field of intercept storage */ +#if INCL_SCREEN + ufix8 inttype[MAX_INTERCEPTS]; + ufix8 leftedge; + ufix16 fracpix; +#endif /* endif incl_screen */ +#endif /* endif reentrant */ + fix15 bmap_xmin; /* Min X value (sub-pixel units) */ + fix15 bmap_xmax; /* Max X value (sub-pixel units) */ + fix15 bmap_ymin; /* Min Y value (sub-pixel units) */ + fix15 bmap_ymax; /* Max Y value (sub-pixel units) */ + fix15 no_y_lists; /* Number of active intercept lists */ + fix15 first_offset; /* Index of first active list cell */ + fix15 next_offset; /* Index of next free list cell */ + boolean intercept_oflo; /* TRUE if intercepts data lost */ +#endif /* endif incl_black, incl_screen, incl_2d */ + +/* bounding box now used by all output modules, including outline */ + fix15 xmin; /* Min X value in whole character */ + fix15 xmax; /* Max X value in whole character */ + fix15 ymin; /* Min Y value in whole character */ + fix15 ymax; /* Max Y value in whole character */ + +#if INCL_2D + fix15 no_x_lists; /* Number of active x intercept lists */ + band_t x_band; /* X current band(whole pixels) */ + boolean x_scan_active; /* X scan flag during scan conversion */ +#endif + +/* reset.c data definitions */ + ufix16 key32; /* Decryption keys 3,2 combined */ + ufix8 key4; /* Decryption key 4 */ + ufix8 key6; /* Decryption key 6 */ + ufix8 key7; /* Decryption key 7 */ + ufix8 key8; /* Decryption key 8 */ + +/* set_spcs.c data definitions */ + buff_t font; + buff_t GLOBALFAR *pfont; /* Pointer to font buffer structure */ + fix31 font_buff_size; /* Number of bytes loaded in font buffer */ + ufix8 FONTFAR *pchar_dir; /* Pointer to character directory */ + fix15 first_char_idx; /* Index to first character in font */ + fix15 no_chars_avail; /* Total characters in font layout */ + fix15 orus_per_em; /* Outline resolution */ + fix15 metric_resolution; /* metric resolution for setwidths, kerning pairs + (defaults to orus_per_em) */ + tcb_t tcb0; /* Top level transformation control block */ + + boolean specs_valid; /* TRUE if fw_set_specs() successful */ + + fix15 depth_adj; /* Curve splitting depth adjustment */ + boolean curves_out; /* Allow curves to output module */ + fix15 output_mode; /* Output module selector */ + fix15 thresh; /* Scan conversion threshold (sub-pixels) */ + boolean normal; /* TRUE if 0 obl and mult of 90 deg rot */ + + fix15 multshift; /* Fixed point shift for multipliers */ + fix15 pixshift; /* Fixed point shift for sub-pixels */ + fix15 poshift; /* Left shift from pixel to output format */ + fix15 mpshift; /* Fixed point shift for mult to sub-pixels */ + fix31 multrnd; /* 0.5 in multiplier units */ + fix15 pixrnd; /* 0.5 in sub-pixel units */ + fix31 mprnd; /* 0.5 sub-pixels in multiplier units */ + fix15 pixfix; /* Mask to remove fractional pixels */ + fix15 onepix; /* 1.0 pixels in sub-pixel units */ + + boolean (*init_out)(PROTO_DECL2 specs_t GLOBALFAR *specsarg); + boolean (*begin_char)(PROTO_DECL2 point_t Psw,point_t Pmin,point_t Pmax); + void (*begin_sub_char)(PROTO_DECL2 point_t Psw,point_t Pmin,point_t Pmax); + void (*begin_contour)(PROTO_DECL2 point_t P1,boolean outside); + void (*curve)(PROTO_DECL2 point_t P1, point_t P2, point_t P3, fix15 depth); + void (*line)(PROTO_DECL2 point_t P1); + void (*end_contour)(PROTO_DECL1); + void (*end_sub_char)(PROTO_DECL1); + boolean (*end_char)(PROTO_DECL1); + specs_t GLOBALFAR *pspecs; /* Pointer to specifications bundle */ + specs_t specs; /* copy specs onto stack */ + ufix8 FONTFAR *font_org; /* Pointer to start of font data */ + ufix8 FONTFAR *hdr2_org; /* Pointer to start of private header data */ + +/* set_trns.c data definitions */ + tcb_t tcb; /* Current transformation control block */ + ufix8 Y_edge_org; /* Index to first Y controlled coordinate */ + ufix8 Y_int_org; /* Index to first Y interpolation zone */ + fix31 rnd_xmin; /* rounded out value of xmin for int-char spac. fix */ + +#if REENTRANT_ALLOC + plaid_t STACKFAR *plaid; +#else /* if not reentrant */ + fix15 orus[MAX_CTRL_ZONES]; /* Controlled coordinate table (orus) */ +#if INCL_RULES + fix15 pix[MAX_CTRL_ZONES]; /* Controlled coordinate table (sub-pixels) */ + fix15 mult[MAX_INT_ZONES]; /* Interpolation multiplier table */ + fix31 offset[MAX_INT_ZONES]; /* Interpolation offset table */ +#endif /* endif incl_rules */ +#endif /* endif not reentrant */ + + fix15 no_X_orus; /* Number of X controlled coordinates */ + fix15 no_Y_orus; /* Number of Y controlled coordinates */ + ufix16 Y_constr_org; /* Origin of constraint table in font data */ + +#if INCL_RULES + constr_t constr; /* Constraint data state */ + boolean c_act[MAX_CONSTR]; /* TRUE if constraint currently active */ + fix15 c_pix[MAX_CONSTR]; /* Size of constrained zone if active */ +#endif +#if INCL_ISW + boolean import_setwidth_act; /* boolean to indicate imported setwidth */ + boolean isw_modified_constants; + ufix32 imported_width; /* value of imported setwidth */ + fix15 isw_xmax; /* maximum oru value for constants*/ +#endif +#if INCL_SQUEEZING || INCL_ISW + fix15 setwidth_orus; /* setwidth value in orus */ + /* bounding box in orus for squeezing */ + fix15 bbox_xmin_orus; /* X minimum in orus */ + fix15 bbox_xmax_orus; /* X maximum in orus */ + fix15 bbox_ymin_orus; /* Y minimum in orus */ + fix15 bbox_ymax_orus; /* Y maximum in orus */ +#endif +#ifdef INCL_SQUEEZING + boolean squeezing_compound; /* flag to indicate a compound character*/ +#endif +#ifdef INCL_CLIPPING + fix31 clip_xmax; + fix31 clip_ymax; + fix31 clip_xmin; + fix31 clip_ymin; +#endif + } SPEEDO_GLOBALS; + +/*********************************************************************************** + * + * Speedo global data structure allocation + * + ***********************************************************************************/ + +#ifdef SET_SPCS +#define EXTERN +#else +#define EXTERN extern +#endif +#if STATIC_ALLOC +EXTERN SPEEDO_GLOBALS GLOBALFAR sp_globals; +#define sp_intercepts sp_globals +#define sp_plaid sp_globals +#else +#if DYNAMIC_ALLOC +EXTERN SPEEDO_GLOBALS GLOBALFAR *sp_global_ptr; +#define sp_globals (*sp_global_ptr) +#define sp_intercepts (*sp_global_ptr) +#define sp_plaid (*sp_global_ptr) +#else +#if REENTRANT_ALLOC +#define sp_globals (*sp_global_ptr) +#define sp_intercepts (*(*sp_global_ptr).intercepts) +#define sp_plaid (*(*sp_global_ptr).plaid) +#endif +#endif +#endif +#ifdef EXTERN +#undef EXTERN +#endif + + +/***** PUBLIC FONT HEADER OFFSET CONSTANTS *****/ +#define FH_FMVER 0 /* U D4.0 CR LF NULL NULL 8 bytes */ +#define FH_FNTSZ 8 /* U Font size (bytes) 4 bytes */ +#define FH_FBFSZ 12 /* U Min font buffer size (bytes) 4 bytes */ +#define FH_CBFSZ 16 /* U Min char buffer size (bytes) 2 bytes */ +#define FH_HEDSZ 18 /* U Header size (bytes) 2 bytes */ +#define FH_FNTID 20 /* U Source Font ID 2 bytes */ +#define FH_SFVNR 22 /* U Source Font Version Number 2 bytes */ +#define FH_FNTNM 24 /* U Source Font Name 70 bytes */ +#define FH_MDATE 94 /* U Manufacturing Date 10 bytes */ +#define FH_LAYNM 104 /* U Layout Name 70 bytes */ +#define FH_CPYRT 174 /* U Copyright Notice 78 bytes */ +#define FH_NCHRL 252 /* U Number of Chars in Layout 2 bytes */ +#define FH_NCHRF 254 /* U Total Number of Chars in Font 2 bytes */ +#define FH_FCHRF 256 /* U Index of first char in Font 2 bytes */ +#define FH_NKTKS 258 /* U Number of kerning tracks in font 2 bytes */ +#define FH_NKPRS 260 /* U Number of kerning pairs in font 2 bytes */ +#define FH_FLAGS 262 /* U Font flags 1 byte: */ + /* Bit 0: Extended font */ + /* Bit 1: not used */ + /* Bit 2: not used */ + /* Bit 3: not used */ + /* Bit 4: not used */ + /* Bit 5: not used */ + /* Bit 6: not used */ + /* Bit 7: not used */ +#define FH_CLFGS 263 /* U Classification flags 1 byte: */ + /* Bit 0: Italic */ + /* Bit 1: Monospace */ + /* Bit 2: Serif */ + /* Bit 3: Display */ + /* Bit 4: not used */ + /* Bit 5: not used */ + /* Bit 6: not used */ + /* Bit 7: not used */ +#define FH_FAMCL 264 /* U Family Classification 1 byte: */ + /* 0: Don't care */ + /* 1: Serif */ + /* 2: Sans serif */ + /* 3: Monospace */ + /* 4: Script or calligraphic */ + /* 5: Decorative */ + /* 6-255: not used */ +#define FH_FRMCL 265 /* U Font form Classification 1 byte: */ + /* Bits 0-3 (width type): */ + /* 0-3: not used */ + /* 4: Condensed */ + /* 5: not used */ + /* 6: Semi-condensed */ + /* 7: not used */ + /* 8: Normal */ + /* 9: not used */ + /* 10: Semi-expanded */ + /* 11: not used */ + /* 12: Expanded */ + /* 13-15: not used */ + /* Bits 4-7 (Weight): */ + /* 0: not used */ + /* 1: Thin */ + /* 2: Ultralight */ + /* 3: Extralight */ + /* 4: Light */ + /* 5: Book */ + /* 6: Normal */ + /* 7: Medium */ + /* 8: Semibold */ + /* 9: Demibold */ + /* 10: Bold */ + /* 11: Extrabold */ + /* 12: Ultrabold */ + /* 13: Heavy */ + /* 14: Black */ + /* 15-16: not used */ +#define FH_SFNTN 266 /* U Short Font Name 32 bytes */ +#define FH_SFACN 298 /* U Short Face Name 16 bytes */ +#define FH_FNTFM 314 /* U Font form 14 bytes */ +#define FH_ITANG 328 /* U Italic angle 2 bytes (1/256th deg) */ +#define FH_ORUPM 330 /* U Number of ORUs per em 2 bytes */ +#define FH_WDWTH 332 /* U Width of Wordspace 2 bytes */ +#define FH_EMWTH 334 /* U Width of Emspace 2 bytes */ +#define FH_ENWTH 336 /* U Width of Enspace 2 bytes */ +#define FH_TNWTH 338 /* U Width of Thinspace 2 bytes */ +#define FH_FGWTH 340 /* U Width of Figspace 2 bytes */ +#define FH_FXMIN 342 /* U Font-wide min X value 2 bytes */ +#define FH_FYMIN 344 /* U Font-wide min Y value 2 bytes */ +#define FH_FXMAX 346 /* U Font-wide max X value 2 bytes */ +#define FH_FYMAX 348 /* U Font-wide max Y value 2 bytes */ +#define FH_ULPOS 350 /* U Underline position 2 bytes */ +#define FH_ULTHK 352 /* U Underline thickness 2 bytes */ +#define FH_SMCTR 354 /* U Small caps transformation 6 bytes */ +#define FH_DPSTR 360 /* U Display sups transformation 6 bytes */ +#define FH_FNSTR 366 /* U Footnote sups transformation 6 bytes */ +#define FH_ALSTR 372 /* U Alpha sups transformation 6 bytes */ +#define FH_CMITR 378 /* U Chemical infs transformation 6 bytes */ +#define FH_SNMTR 384 /* U Small nums transformation 6 bytes */ +#define FH_SDNTR 390 /* U Small denoms transformation 6 bytes */ +#define FH_MNMTR 396 /* U Medium nums transformation 6 bytes */ +#define FH_MDNTR 402 /* U Medium denoms transformation 6 bytes */ +#define FH_LNMTR 408 /* U Large nums transformation 6 bytes */ +#define FH_LDNTR 414 /* U Large denoms transformation 6 bytes */ + /* Transformation data format: */ + /* Y position 2 bytes */ + /* X scale 2 bytes (1/4096ths) */ + /* Y scale 2 bytes (1/4096ths) */ +#define SIZE_FW FH_LDNTR + 6 /* size of nominal font header */ +#define EXP_FH_METRES SIZE_FW /* offset to expansion field metric resolution (optional) */ + + + +/***** MODE FLAGS CONSTANTS *****/ +#define CURVES_OUT 0X0008 /* Output module accepts curves */ +#define BOGUS_MODE 0X0010 /* Linear scaling mode */ +#define CONSTR_OFF 0X0020 /* Inhibit constraint table */ +#define IMPORT_WIDTHS 0X0040 /* Imported width mode */ +#define SQUEEZE_LEFT 0X0100 /* Squeeze left mode */ +#define SQUEEZE_RIGHT 0X0200 /* Squeeze right mode */ +#define SQUEEZE_TOP 0X0400 /* Squeeze top mode */ +#define SQUEEZE_BOTTOM 0X0800 /* Squeeze bottom mode */ +#define CLIP_LEFT 0X1000 /* Clip left mode */ +#define CLIP_RIGHT 0X2000 /* Clip right mode */ +#define CLIP_TOP 0X4000 /* Clip top mode */ +#define CLIP_BOTTOM 0X8000 /* Clip bottom mode */ + +/*********************************************************************************** + * + * Speedo function declarations - use prototypes if available + * + ***********************************************************************************/ + +/* do_char.c functions */ +ufix16 sp_get_char_id(PROTO_DECL2 ufix16 char_index); +boolean sp_make_char(PROTO_DECL2 ufix16 char_index); +#if INCL_ISW +fix31 sp_compute_isw_scale(PROTO_DECL2); +static boolean sp_do_make_char(PROTO_DECL2 ufix16 char_index); +boolean sp_make_char_isw(PROTO_DECL2 ufix16 char_index, ufix32 imported_width); +static boolean sp_reset_xmax(PROTO_DECL2 fix31 xmax); +#endif +#if INCL_ISW || INCL_SQUEEZING +static void sp_preview_bounding_box(PROTO_DECL2 ufix8 FONTFAR *pointer,ufix8 format); +#endif + +#if INCL_METRICS /* Metrics functions supported? */ +fix31 sp_get_char_width(PROTO_DECL2 ufix16 char_index); +fix15 sp_get_track_kern(PROTO_DECL2 fix15 track,fix15 point_size); +fix31 sp_get_pair_kern(PROTO_DECL2 ufix16 char_index1,ufix16 char_index2); +boolean sp_get_char_bbox(PROTO_DECL2 ufix16 char_index, bbox_t *bbox); +#endif + +/* do_trns.c functions */ +ufix8 FONTFAR *sp_read_bbox(PROTO_DECL2 ufix8 FONTFAR *pointer,point_t STACKFAR *pPmin,point_t STACKFAR *pPmax,boolean set_flag); +void sp_proc_outl_data(PROTO_DECL2 ufix8 FONTFAR *pointer); + +/* out_blk.c functions */ +#if INCL_BLACK +boolean sp_init_black(PROTO_DECL2 specs_t GLOBALFAR *specsarg); +boolean sp_begin_char_black(PROTO_DECL2 point_t Psw,point_t Pmin,point_t Pmax); +void sp_begin_contour_black(PROTO_DECL2 point_t P1,boolean outside); +void sp_line_black(PROTO_DECL2 point_t P1); +boolean sp_end_char_black(PROTO_DECL1); +#endif + +/* out_scrn.c functions */ +#if INCL_SCREEN +boolean sp_init_screen(PROTO_DECL2 specs_t GLOBALFAR *specsarg); +boolean sp_begin_char_screen(PROTO_DECL2 point_t Psw,point_t Pmin,point_t Pmax); +void sp_begin_contour_screen(PROTO_DECL2 point_t P1,boolean outside); +void sp_curve_screen(PROTO_DECL2 point_t P1,point_t P2,point_t P3, fix15 depth); +void sp_scan_curve_screen(PROTO_DECL2 fix31 X0,fix31 Y0,fix31 X1,fix31 Y1,fix31 X2,fix31 Y2,fix31 X3,fix31 Y3); +void sp_vert_line_screen(PROTO_DECL2 fix31 x, fix15 y1, fix15 y2); +void sp_line_screen(PROTO_DECL2 point_t P1); +void sp_end_contour_screen(PROTO_DECL1); +boolean sp_end_char_screen(PROTO_DECL1); +#endif + +/* out_outl.c functions */ +#if INCL_OUTLINE +#if INCL_MULTIDEV +boolean sp_set_outline_device(PROTO_DECL2 outline_t *ofuncs, ufix16 size); +#endif + + +boolean sp_init_outline(PROTO_DECL2 specs_t GLOBALFAR *specsarg); +boolean sp_begin_char_outline(PROTO_DECL2 point_t Psw,point_t Pmin,point_t Pmax); +void sp_begin_sub_char_outline(PROTO_DECL2 point_t Psw,point_t Pmin,point_t Pmax); +void sp_begin_contour_outline(PROTO_DECL2 point_t P1,boolean outside); +void sp_curve_outline(PROTO_DECL2 point_t P1,point_t P2,point_t P3, fix15 depth); +void sp_line_outline(PROTO_DECL2 point_t P1); +void sp_end_contour_outline(PROTO_DECL1); +void sp_end_sub_char_outline(PROTO_DECL1); +boolean sp_end_char_outline(PROTO_DECL1); +#endif + +/* out_bl2d.c functions */ +#if INCL_2D +boolean sp_init_2d(PROTO_DECL2 specs_t GLOBALFAR *specsarg); +boolean sp_begin_char_2d(PROTO_DECL2 point_t Psw,point_t Pmin,point_t Pmax); +void sp_begin_contour_2d(PROTO_DECL2 point_t P1,boolean outside); +void sp_line_2d(PROTO_DECL2 point_t P1); +boolean sp_end_char_2d(PROTO_DECL1); +#endif + +/* out_util.c functions */ +#if INCL_BLACK || INCL_SCREEN || INCL_2D + +#if INCL_MULTIDEV +boolean sp_set_bitmap_device(PROTO_DECL2 bitmap_t *bfuncs, ufix16 size); +#endif + +void sp_init_char_out(PROTO_DECL2 point_t Psw, point_t Pmin, point_t Pmax); +void sp_begin_sub_char_out(PROTO_DECL2 point_t Psw, point_t Pmin, point_t Pmax); +void sp_curve_out(PROTO_DECL2 point_t P1, point_t P2, point_t P3, fix15 depth); +void sp_end_contour_out(PROTO_DECL1); +void sp_end_sub_char_out(PROTO_DECL1); +void sp_init_intercepts_out(PROTO_DECL1); +void sp_restart_intercepts_out(PROTO_DECL1); +void sp_set_first_band_out(PROTO_DECL2 point_t Pmin, point_t Pmax); +void sp_reduce_band_size_out(PROTO_DECL1); +boolean sp_next_band_out(PROTO_DECL1); +#endif + +#if INCL_USEROUT +boolean sp_init_userout(specs_t *specsarg); +#endif + + +/* reset.c functions */ +void sp_reset(PROTO_DECL1); +#if INCL_KEYS +void sp_set_key(PROTO_DECL2 ufix8 key[]); +#endif +ufix16 sp_get_cust_no(PROTO_DECL2 buff_t font_buff); + +/* set_spcs.c functions */ +boolean sp_set_specs(PROTO_DECL2 specs_t STACKFAR *specsarg); +void sp_type_tcb(PROTO_DECL2 tcb_t GLOBALFAR *ptcb); + +fix31 sp_read_long(PROTO_DECL2 ufix8 FONTFAR *pointer); +fix15 sp_read_word_u(PROTO_DECL2 ufix8 FONTFAR *pointer); + +/* set_trns.c functions */ +void sp_init_tcb(PROTO_DECL1); +void sp_scale_tcb(PROTO_DECL2 tcb_t GLOBALFAR *ptcb,fix15 x_pos,fix15 y_pos,fix15 x_scale,fix15 y_scale); +ufix8 FONTFAR *sp_plaid_tcb(PROTO_DECL2 ufix8 FONTFAR *pointer,ufix8 format); +ufix8 FONTFAR *sp_skip_interpolation_table(PROTO_DECL2 ufix8 FONTFAR *pointer, ufix8 format); +ufix8 FONTFAR *sp_skip_control_zone(PROTO_DECL2 ufix8 FONTFAR *pointer, ufix8 format); + +ufix8 FONTFAR *sp_read_oru_table(PROTO_DECL2 ufix8 FONTFAR *pointer); +#if INCL_SQUEEZING || INCL_ISW +static void sp_calculate_x_pix(PROTO_DECL2 ufix8 start_edge,ufix8 end_edge,ufix16 constr_nr,fix31 x_scale,fix31 x_offset,fix31 ppo,fix15 setwidth_pix); +#endif +#if INCL_SQUEEZING +static void sp_calculate_y_pix(PROTO_DECL2 ufix8 start_edge,ufix8 end_edge,ufix16 constr_nr,fix31 top_scale,fix31 bottom_scale,fix31 ppo,fix15 emtop_pix,fix15 embot_pix); +boolean sp_calculate_x_scale(PROTO_DECL2 fix31 *x_factor,fix31 *x_offset,fix15 no_x_ctrl_zones); +boolean sp_calculate_y_scale(PROTO_DECL2 fix31 *top_scale,fix31 *bottom_scale,fix15 first_y_zone, fix15 no_Y_ctrl_zones); +#endif + + +/* user defined functions */ + +void sp_report_error(PROTO_DECL2 fix15 n); + +#if INCL_BLACK || INCL_SCREEN || INCL_2D +void sp_open_bitmap(PROTO_DECL2 fix31 x_set_width, fix31 y_set_width, fix31 xorg, fix31 yorg, fix15 xsize,fix15 ysize); +void sp_set_bitmap_bits(PROTO_DECL2 fix15 y, fix15 xbit1, fix15 xbit2); +void sp_close_bitmap(PROTO_DECL1); +#endif + +#if INCL_OUTLINE +void sp_open_outline(PROTO_DECL2 fix31 x_set_width, fix31 y_set_width, fix31 xmin, fix31 xmax, fix31 ymin,fix31 ymax); +void sp_start_new_char(PROTO_DECL1); +void sp_start_contour(PROTO_DECL2 fix31 x,fix31 y,boolean outside); +void sp_curve_to(PROTO_DECL2 fix31 x1, fix31 y1, fix31 x2, fix31 y2, fix31 x3, fix31 y3); +void sp_line_to(PROTO_DECL2 fix31 x, fix31 y); +void sp_close_contour(PROTO_DECL1); +void sp_close_outline(PROTO_DECL1); +#endif + +#if INCL_LCD /* Dynamic load character data supported? */ +buff_t *sp_load_char_data(PROTO_DECL2 fix31 file_offset,fix15 no_bytes,fix15 cb_offset); /* Load character data from font file */ +#endif + +#if INCL_PLAID_OUT /* Plaid data monitoring included? */ +void sp_record_xint(PROTO_DECL2 fix15 int_num); /* Record xint data */ +void sp_record_yint(PROTO_DECL2 fix15 int_num); /* Record yint data */ +void sp_begin_plaid_data(PROTO_DECL1); /* Signal start of plaid data */ +void sp_begin_ctrl_zones(PROTO_DECL2 fix15, no_X_zones, fix15 no_Y_zones); /* Signal start of control zones */ +void sp_record_ctrl_zone(PROTO_DECL2 fix31 start, fix31 end, fix15 constr); /* Record control zone data */ +void sp_begin_int_zones(PROTO_DECL2 fix15 no_X_int_zones, fix15 no_Y_int_zones); /* Signal start of interpolation zones */ +void sp_record_int_zone(PROTO_DECL2 fix31 start, fix31 end); /* Record interpolation zone data */ +void sp_end_plaid_data(PROTO_DECL1); /* Signal end of plaid data */ +#endif + +#endif /* _SPEEDO_H_ */ diff --git a/nx-X11/lib/font/Speedo/spencode.c b/nx-X11/lib/font/Speedo/spencode.c new file mode 100644 index 000000000..96a13504a --- /dev/null +++ b/nx-X11/lib/font/Speedo/spencode.c @@ -0,0 +1,67 @@ +/* $Xorg: spencode.c,v 1.4 2001/02/09 02:04:00 xorgcvs Exp $ */ +/* + * Copyright 1990, 1991 Network Computing Devices; + * Portions Copyright 1987 by Digital Equipment Corporation + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the names of Network Computing Devices or Digital + * not be used in advertising or publicity pertaining to distribution of + * the software without specific, written prior permission. + * + * NETWORK COMPUTING DEVICES AND DIGITAL DISCLAIM ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES OR DIGITAL BE + * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + +Copyright 1987, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + +*/ +/* $XFree86: xc/lib/font/Speedo/spencode.c,v 1.6 2001/01/17 19:43:18 dawes Exp $ */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include "spint.h" + +/* No longer needed with new encoding code */ +/* #include "bics-iso.h" + +int sp_bics_map_size = (sizeof(sp_bics_map) / (sizeof(int) * 2));*/ + +#ifdef EXTRAFONTS +#include "adobe-iso.h" + +int adobe_map_size = (sizeof(adobe_map) / (sizeof(int) * 2)); + +#endif /* EXTRAFONTS */ diff --git a/nx-X11/lib/font/Speedo/sperr.c b/nx-X11/lib/font/Speedo/sperr.c new file mode 100644 index 000000000..36ce51125 --- /dev/null +++ b/nx-X11/lib/font/Speedo/sperr.c @@ -0,0 +1,127 @@ +/* $Xorg: sperr.c,v 1.4 2001/02/09 02:04:00 xorgcvs Exp $ */ +/* + * Copyright 1990, 1991 Network Computing Devices; + * Portions Copyright 1987 by Digital Equipment Corporation + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the names of M.I.T., Network Computing Devices, + * or Digital not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. M.I.T. Network Computing Devices, or Digital + * make no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * NETWORK COMPUTING DEVICES, DIGITAL AND MIT DISCLAIM ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES, DIGITAL OR MIT BE + * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +/* + +Copyright 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + +*/ +/* $XFree86: xc/lib/font/Speedo/sperr.c,v 1.6 2001/12/14 19:56:41 dawes Exp $ */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include "spint.h" + +#ifndef FONTMODULE +#include <stdarg.h> +#endif + +extern void ErrorF(const char* f, ...); + +void +SpeedoErr(char *str, ...) +{ + va_list v; + int a1; + + va_start(v, str); + ErrorF("Speedo: "); + a1 = va_arg(v, int); + ErrorF(str, a1); + va_end(v); +} + +/* + * Called by Speedo character generator to report an error. + * + * Since character data not available is one of those errors + * that happens many times, don't report it to user + */ +void +sp_report_error(fix15 n) +{ + switch (n) { + case 1: + SpeedoErr("Insufficient font data loaded\n"); + break; + case 3: + SpeedoErr("Transformation matrix out of range\n"); + break; + case 4: + SpeedoErr("Font format error\n"); + break; + case 5: + SpeedoErr("Requested specs not compatible with output module\n"); + break; + case 7: + SpeedoErr("Intelligent transformation requested but not supported\n"); + break; + case 8: + SpeedoErr("Unsupported output mode requested\n"); + break; + case 9: + SpeedoErr("Extended font loaded but only compact fonts supported\n"); + break; + case 10: + SpeedoErr("Font specs not set prior to use of font\n"); + break; + case 12: + break; + case 13: + SpeedoErr("Track kerning data not available()\n"); + break; + case 14: + SpeedoErr("Pair kerning data not available()\n"); + break; + default: + SpeedoErr("report_error(%d)\n", n); + break; + } +} diff --git a/nx-X11/lib/font/Speedo/spfile.c b/nx-X11/lib/font/Speedo/spfile.c new file mode 100644 index 000000000..c58c0e471 --- /dev/null +++ b/nx-X11/lib/font/Speedo/spfile.c @@ -0,0 +1,460 @@ +/* $Xorg: spfile.c,v 1.4 2001/02/09 02:04:00 xorgcvs Exp $ */ +/* + * Copyright 1990, 1991 Network Computing Devices; + * Portions Copyright 1987 by Digital Equipment Corporation + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the names of Network Computing Devices or Digital + * not be used in advertising or publicity pertaining to distribution of + * the software without specific, written prior permission. + * + * NETWORK COMPUTING DEVICES AND DIGITAL DISCLAIM ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES OR DIGITAL + * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Dave Lemke, Network Computing Devices Inc + */ + +/* + +Copyright 1987, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + +*/ +/* $XFree86: xc/lib/font/Speedo/spfile.c,v 1.13 2001/08/13 21:46:47 dawes Exp $ */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <X11/fonts/fntfilst.h> +#include <X11/fonts/fontenc.h> +#ifndef FONTMODULE +#include <stdio.h> +#else +#include "xf86_ansic.h" +#endif + +#include "spint.h" +#include "bics-unicode.h" + +SpeedoFontPtr sp_fp_cur = (SpeedoFontPtr) 0; + +#ifdef EXTRAFONTS +#include "ncdkeys.h" +#endif + +#include "keys.h" + +#ifdef EXTRAFONTS +static ufix8 skey[] = +{ + SKEY0, + SKEY1, + SKEY2, + SKEY3, + SKEY4, + SKEY5, + SKEY6, + SKEY7, + SKEY8 +}; /* Sample Font decryption key */ + +static ufix8 rkey[] = +{ + RKEY0, + RKEY1, + RKEY2, + RKEY3, + RKEY4, + RKEY5, + RKEY6, + RKEY7, + RKEY8 +}; /* Retail Font decryption key */ + +#endif /* EXTRAFONTS */ + +#ifdef XSAMPLEFONTS +static ufix8 xkey[] = +{ + XKEY0, + XKEY1, + XKEY2, + XKEY3, + XKEY4, + XKEY5, + XKEY6, + XKEY7, + XKEY8 +}; /* Sample Font decryption key */ +#endif + +static ufix8 mkey[] = +{ + KEY0, + KEY1, + KEY2, + KEY3, + KEY4, + KEY5, + KEY6, + KEY7, + KEY8 +}; /* Font decryption key */ + + +static fix15 +read_2b(ufix8 *ptr) +{ + fix15 tmp; + + tmp = *ptr++; + tmp = (tmp << 8) + *ptr; + return tmp; +} + +static fix31 +read_4b(ufix8 *ptr) +{ + fix31 tmp; + + tmp = *ptr++; + tmp = (tmp << 8) + *ptr++; + tmp = (tmp << 8) + *ptr++; + tmp = (tmp << 8) + *ptr; + return tmp; +} + +/* + * loads the specified char's data + */ +buff_t * +sp_load_char_data(fix31 file_offset, fix15 num, fix15 cb_offset) +{ + SpeedoMasterFontPtr master = sp_fp_cur->master; + + if (fseek(master->fp, (long) file_offset, (int) 0)) { + SpeedoErr("can't seek to char\n"); + } + if ((num + cb_offset) > master->mincharsize) { + SpeedoErr("char buf overflow\n"); + } + if (fread((master->c_buffer + cb_offset), sizeof(ufix8), num, + master->fp) != num) { + SpeedoErr("can't get char data\n"); + } + master->char_data.org = (ufix8 *) master->c_buffer + cb_offset; + master->char_data.no_bytes = num; + + return &master->char_data; +} + +struct speedo_encoding { + char *name; + int *enc; + int enc_size; +}; + +/* Takes care of caching encodings already referenced */ +static int +find_encoding(const char *fontname, const char *filename, + int **enc, int *enc_size) +{ + static struct speedo_encoding *known_encodings=0; + static int number_known_encodings=0; + static int known_encodings_size=0; + + char *encoding_name; + int iso8859_1; + FontMapPtr mapping; + int i, j, k, size; + struct speedo_encoding *temp; + int *new_enc; + char *new_name; + + iso8859_1 = 0; + + encoding_name = FontEncFromXLFD(fontname, strlen(fontname)); + if(!encoding_name) { + encoding_name="iso8859-1"; + iso8859_1=1; + } + /* We don't go through the font library if asked for Latin-1 */ + iso8859_1 = iso8859_1 || !strcmp(encoding_name, "iso8859-1"); + + for(i=0; i<number_known_encodings; i++) { + if(!strcmp(encoding_name, known_encodings[i].name)) { + *enc=known_encodings[i].enc; + *enc_size=known_encodings[i].enc_size; + return Successful; + } + } + + /* it hasn't been cached yet, need to compute it */ + + /* ensure we've got enough storage first */ + + if(known_encodings==0) { + if((known_encodings= + (struct speedo_encoding*)xalloc(2*sizeof(struct speedo_encoding))) + ==0) + return AllocError; + number_known_encodings=0; + known_encodings_size=2; + } + + if(number_known_encodings >= known_encodings_size) { + if((temp= + (struct speedo_encoding*)xrealloc(known_encodings, + 2*sizeof(struct speedo_encoding)* + known_encodings_size))==0) + return AllocError; + known_encodings=temp; + known_encodings_size*=2; + } + + mapping=0; + if(!iso8859_1) { + mapping = FontEncMapFind(encoding_name, + FONT_ENCODING_UNICODE, -1, -1, + filename); + } +#define SPEEDO_RECODE(c) \ + (mapping? \ + unicode_to_bics(FontEncRecode(c, mapping)): \ + unicode_to_bics(c)) + + if((new_name = (char*)xalloc(strlen(encoding_name)))==0) + return AllocError; + strcpy(new_name, encoding_name); + + /* For now, we limit ourselves to 256 glyphs */ + size=0; + for(i=0; i < (mapping?mapping->encoding->size:256) && i < 256; i++) + if(SPEEDO_RECODE(i)>=0) + size++; + new_enc = (int*)xalloc(2*size*sizeof(int)); + if(!new_enc) { + xfree(new_name); + return AllocError; + } + for(i=j=0; i < (mapping?mapping->encoding->size:256) && i < 256; i++) + if((k = SPEEDO_RECODE(i))>=0) { + new_enc[2*j] = i; + new_enc[2*j+1] = k; + j++; + } + known_encodings[number_known_encodings].name = new_name; + known_encodings[number_known_encodings].enc = new_enc; + known_encodings[number_known_encodings].enc_size = size; + number_known_encodings++; + + *enc = new_enc; + *enc_size = size; + return Successful; +#undef SPEEDO_RECODE +} + +int +sp_open_master(const char *fontname, const char *filename, + SpeedoMasterFontPtr *master) +{ + SpeedoMasterFontPtr spmf; + ufix8 tmp[16]; + ufix16 cust_no; + FILE *fp; + ufix32 minbufsize; + ufix16 mincharsize; + ufix8 *f_buffer; + ufix8 *c_buffer; + int ret; + ufix8 *key; + + spmf = (SpeedoMasterFontPtr) xalloc(sizeof(SpeedoMasterFontRec)); + if (!spmf) + return AllocError; + bzero(spmf, sizeof(SpeedoMasterFontRec)); + spmf->entry = NULL; + spmf->f_buffer = NULL; + spmf->c_buffer = NULL; + + /* open font */ + spmf->fname = (char *) xalloc(strlen(filename) + 1); + if (!spmf->fname) + return AllocError; + fp = fopen(filename, "r"); + if (!fp) { + ret = BadFontName; + goto cleanup; + } + strcpy(spmf->fname, filename); + spmf->fp = fp; + spmf->state |= MasterFileOpen; + + if (fread(tmp, sizeof(ufix8), 16, fp) != 16) { + ret = BadFontName; + goto cleanup; + } + minbufsize = (ufix32) read_4b(tmp + FH_FBFSZ); + f_buffer = (ufix8 *) xalloc(minbufsize); + if (!f_buffer) { + ret = AllocError; + goto cleanup; + } + spmf->f_buffer = f_buffer; + + fseek(fp, (ufix32) 0, 0); + + /* read in the font */ + if (fread(f_buffer, sizeof(ufix8), (ufix16) minbufsize, fp) != minbufsize) { + ret = BadFontName; + goto cleanup; + } + spmf->copyright = (char *) (f_buffer + FH_CPYRT); + spmf->mincharsize = mincharsize = read_2b(f_buffer + FH_CBFSZ); + + c_buffer = (ufix8 *) xalloc(mincharsize); + if (!c_buffer) { + ret = AllocError; + goto cleanup; + } + spmf->c_buffer = c_buffer; + + spmf->font.org = spmf->f_buffer; + spmf->font.no_bytes = minbufsize; + + cust_no = sp_get_cust_no(spmf->font); + + /* XXX add custom encryption stuff here */ + +#ifdef EXTRAFONTS + if (cust_no == SCUS0) { + key = skey; + } else if (cust_no == RCUS0) { + key = rkey; + } else +#endif + +#ifdef XSAMPLEFONTS + if (cust_no == XCUS0) { + key = xkey; + } else +#endif + + if (cust_no == CUS0) { + key = mkey; + } else { + SpeedoErr("Non - standard encryption for \"%s\"\n", filename); + ret = BadFontName; + goto cleanup; + } + spmf->key = key; + sp_set_key(key); + + spmf->first_char_id = read_2b(f_buffer + FH_FCHRF); + spmf->num_chars = read_2b(f_buffer + FH_NCHRL); + + + spmf->enc = 0; + spmf->enc_size = 0; + +#ifdef EXTRAFONTS + { /* choose the proper encoding */ + char *f; + + f = strrchr(filename, '/'); + if (f) { + f++; + if (strncmp(f, "bx113", 5) == 0) { + spmf->enc = adobe_map; + spmf->enc_size = adobe_map_size; + } + } + } +#endif + + if(!spmf->enc) + if((ret=find_encoding(fontname, filename, &spmf->enc, &spmf->enc_size)) + !=Successful) + goto cleanup; + + spmf->first_char_id = spmf->enc[0]; + /* size of extents array */ + spmf->max_id = spmf->enc[(spmf->enc_size - 1) * 2]; + spmf->num_chars = spmf->enc_size; + + *master = spmf; + + return Successful; + +cleanup: + *master = (SpeedoMasterFontPtr) 0; + sp_close_master_font(spmf); + return ret; +} + +void +sp_close_master_font(SpeedoMasterFontPtr spmf) +{ + if (!spmf) + return; + if (spmf->state & MasterFileOpen) + fclose(spmf->fp); + if (spmf->entry) + spmf->entry->u.scalable.extra->private = NULL; + xfree(spmf->fname); + xfree(spmf->f_buffer); + xfree(spmf->c_buffer); + xfree(spmf); +} + +void +sp_close_master_file(SpeedoMasterFontPtr spmf) +{ + (void) fclose(spmf->fp); + spmf->state &= ~MasterFileOpen; +} + + +/* + * reset the encryption key, and make sure the file is opened + */ +void +sp_reset_master(SpeedoMasterFontPtr spmf) +{ + sp_set_key(spmf->key); + if (!(spmf->state & MasterFileOpen)) { + spmf->fp = fopen(spmf->fname, "r"); + /* XXX -- what to do if we can't open the file? */ + spmf->state |= MasterFileOpen; + } + fseek(spmf->fp, 0, 0); +} diff --git a/nx-X11/lib/font/Speedo/spfont.c b/nx-X11/lib/font/Speedo/spfont.c new file mode 100644 index 000000000..c209d5a51 --- /dev/null +++ b/nx-X11/lib/font/Speedo/spfont.c @@ -0,0 +1,453 @@ +/* $Xorg: spfont.c,v 1.4 2001/02/09 02:04:00 xorgcvs Exp $ */ +/* + * Copyright 1990, 1991 Network Computing Devices; + * Portions Copyright 1987 by Digital Equipment Corporation + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the names of Network Computing Devices or Digital + * not be used in advertising or publicity pertaining to distribution of + * the software without specific, written prior permission. + * + * NETWORK COMPUTING DEVICES AND DIGITAL DISCLAIM ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES OR DIGITAL BE + * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Dave Lemke, Network Computing Devices Inc + */ +/* $XFree86: xc/lib/font/Speedo/spfont.c,v 3.12tsi Exp $ */ + +/* + +Copyright 1987, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + +*/ + +/* + * Speedo font loading + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <X11/fonts/FSproto.h> +#include "spint.h" +#include <X11/fonts/fontutil.h> +#ifndef FONTMODULE +#ifdef _XOPEN_SOURCE +#include <math.h> +#else +#define _XOPEN_SOURCE /* to get prototype for hypot on some systems */ +#include <math.h> +#undef _XOPEN_SOURCE +#endif +#else +#include "servermd.h" +#include "xf86_ansic.h" +#endif + +#ifndef M_PI +#define M_PI 3.14159 +#endif /* M_PI */ +#ifndef DEFAULT_BIT_ORDER + +#ifdef BITMAP_BIT_ORDER +#define DEFAULT_BIT_ORDER BITMAP_BIT_ORDER +#else +#define DEFAULT_BIT_ORDER UNKNOWN_BIT_ORDER +#endif + +#endif + +static void SpeedoCloseFont(FontPtr pfont); + +static int +sp_get_glyphs( + FontPtr pFont, + unsigned long count, + register unsigned char *chars, + FontEncoding charEncoding, + unsigned long *glyphCount, /* RETURN */ + CharInfoPtr *glyphs) /* RETURN */ +{ + SpeedoFontPtr spf; + unsigned int firstCol; + register unsigned int numCols; + unsigned int firstRow; + unsigned int numRows; + CharInfoPtr *glyphsBase; + register unsigned int c; + register CharInfoPtr pci; + unsigned int r; + CharInfoPtr encoding; + CharInfoPtr pDefault; +#ifdef notyet + int itemSize; +#endif + int err = Successful; + + spf = (SpeedoFontPtr) pFont->fontPrivate; + encoding = spf->encoding; + pDefault = spf->pDefault; + firstCol = pFont->info.firstCol; + numCols = pFont->info.lastCol - firstCol + 1; + glyphsBase = glyphs; + + + /* XXX - this should be much smarter */ + /* make sure the glyphs are there */ +#ifdef notyet + if (charEncoding == Linear8Bit || charEncoding == TwoD8Bit) + itemSize = 1; + else + itemSize = 2; + + if (!fsd->complete) + err = fs_load_glyphs(NULL, pFont, count, itemSize, chars); +#endif + + if (err != Successful) + return err; + + switch (charEncoding) { + + case Linear8Bit: + case TwoD8Bit: + if (pFont->info.firstRow > 0) + break; + if (pFont->info.allExist && pDefault) { + while (count--) { + c = (*chars++) - firstCol; + if (c < numCols) + *glyphs++ = &encoding[c]; + else + *glyphs++ = pDefault; + } + } else { + while (count--) { + c = (*chars++) - firstCol; + if (c < numCols && (pci = &encoding[c])->bits) + *glyphs++ = pci; + else if (pDefault) + *glyphs++ = pDefault; + } + } + break; + case Linear16Bit: + if (pFont->info.allExist && pDefault) { + while (count--) { + c = *chars++ << 8; + c = (c | *chars++) - firstCol; + if (c < numCols) + *glyphs++ = &encoding[c]; + else + *glyphs++ = pDefault; + } + } else { + while (count--) { + c = *chars++ << 8; + c = (c | *chars++) - firstCol; + if (c < numCols && (pci = &encoding[c])->bits) + *glyphs++ = pci; + else if (pDefault) + *glyphs++ = pDefault; + } + } + break; + + case TwoD16Bit: + firstRow = pFont->info.firstRow; + numRows = pFont->info.lastRow - firstRow + 1; + while (count--) { + r = (*chars++) - firstRow; + c = (*chars++) - firstCol; + if (r < numRows && c < numCols && + (pci = &encoding[r * numCols + c])->bits) + *glyphs++ = pci; + else if (pDefault) + *glyphs++ = pDefault; + } + break; + } + *glyphCount = glyphs - glyphsBase; + return Successful; +} + +static CharInfoRec nonExistantChar; + +static int +sp_get_metrics( + FontPtr pFont, + unsigned long count, + register unsigned char *chars, + FontEncoding charEncoding, + unsigned long *glyphCount, /* RETURN */ + xCharInfo **glyphs) /* RETURN */ +{ + int ret; + SpeedoFontPtr spf; + CharInfoPtr oldDefault; + + spf = (SpeedoFontPtr) pFont->fontPrivate; + oldDefault = spf->pDefault; + spf->pDefault = &nonExistantChar; + ret = sp_get_glyphs(pFont, count, chars, charEncoding, + glyphCount, (CharInfoPtr *) glyphs); + + spf->pDefault = oldDefault; + return ret; +} + +int +sp_open_font( + char *fontname, + char *filename, + FontEntryPtr entry, + FontScalablePtr vals, + fsBitmapFormat format, + fsBitmapFormatMask fmask, + Mask flags, + SpeedoFontPtr *spfont) +{ + SpeedoFontPtr spf; + SpeedoMasterFontPtr spmf; + int ret; + specs_t specs; + int xx8, xy8, yx8, yy8; + + /* find a master (create it if necessary) */ + spmf = (SpeedoMasterFontPtr) entry->u.scalable.extra->private; + if (!spmf) + { + ret = sp_open_master(fontname, filename, &spmf); + if (ret != Successful) + return ret; + entry->u.scalable.extra->private = (pointer) spmf; + spmf->entry = entry; + } + + spf = (SpeedoFontPtr) xalloc(sizeof(SpeedoFontRec)); + if (!spf) + return AllocError; + bzero((char *) spf, sizeof(SpeedoFontRec)); + + *spfont = spf; + + /* clobber everything -- this may be leaking, but other wise evil + * stuff is left behind -- succesive transformed fonts get mangled */ + bzero((char *)&sp_globals, sizeof(sp_globals)); + + spf->master = spmf; + spf->entry = entry; + spmf->refcount++; + sp_reset_master(spmf); + /* now we've done enough that if we bail out we must call sp_close_font */ + + spf->vals = *vals; + + /* set up specs */ + + specs.pfont = &spmf->font; + + specs.xxmult = (int)(vals->pixel_matrix[0] * (double)(1L << 16)); + specs.xymult = (int)(vals->pixel_matrix[2] * (double)(1L << 16)); + specs.yxmult = (int)(vals->pixel_matrix[1] * (double)(1L << 16)); + specs.yymult = (int)(vals->pixel_matrix[3] * (double)(1L << 16)); + + specs.xoffset = 0L << 16; /* XXX tweak? */ + specs.yoffset = 0L << 16; /* XXX tweak? */ + + specs.flags = MODE_SCREEN; + specs.out_info = NULL; + + /* When Speedo tries to generate a very small font bitmap, it + often crashes or goes into an infinite loop. + Don't know why this is so, but until we can fix it properly, + return BadFontName for anything smaller than 4 pixels. + */ +#define TINY_FACTOR (16 << 16) + xx8 = specs.xxmult >> 8; + xy8 = specs.xymult >> 8; + yx8 = specs.yxmult >> 8; + yy8 = specs.yymult >> 8; + if (xx8 * xx8 + xy8 * xy8 < TINY_FACTOR || + yx8 * yx8 + yy8 * yy8 < TINY_FACTOR) + { + sp_close_font(spf); + return BadFontName; + } + + /* clobber global state to avoid wrecking future transformed fonts */ + bzero ((char *) &sp_globals, sizeof(sp_globals)); + + if (!sp_set_specs(&specs)) + { + sp_close_font(spf); + return BadFontName; + } + + spf->specs = specs; + spf->master = spmf; + + *spfont = spf; + return Successful; +} + +static int +sp_load_font( + char *fontname, + char *filename, + FontEntryPtr entry, + FontScalablePtr vals, + fsBitmapFormat format, + fsBitmapFormatMask fmask, + FontPtr pfont, + Mask flags) +{ + SpeedoFontPtr spf; + SpeedoMasterFontPtr spmf; + int esize; + int ret; + long sWidth; + + ret = sp_open_font(fontname, filename, entry, vals, format, fmask, + flags, &spf); + + if (ret != Successful) + return ret; + + spmf = spf->master; + sp_reset_master(spmf); + esize = sizeof(CharInfoRec) * (spmf->max_id - spmf->first_char_id + 1); + + spf->encoding = (CharInfoPtr) xalloc(esize); + if (!spf->encoding) { + sp_close_font(spf); + return AllocError; + } + bzero((char *) spf->encoding, esize); + + sp_fp_cur = spf; + + sp_make_header(spf, &pfont->info); + + sp_compute_bounds(spf, &pfont->info, SaveMetrics, &sWidth); + + sp_compute_props(spf, fontname, &pfont->info, sWidth); + + pfont->fontPrivate = (pointer) spf; + +/* XXX */ + flags |= FontLoadBitmaps; + + if (flags & FontLoadBitmaps) { + sp_fp_cur = spf; + ret = sp_build_all_bitmaps(pfont, format, fmask); + } + if (ret != Successful) + return ret; + + /* compute remaining accelerators */ + FontComputeInfoAccelerators(&pfont->info); + + pfont->format = format; + + pfont->get_metrics = sp_get_metrics; + pfont->get_glyphs = sp_get_glyphs; + pfont->unload_font = SpeedoCloseFont; + pfont->unload_glyphs = NULL; + pfont->refcnt = 0; + + /* have to hold on to master for min/max id */ + sp_close_master_file(spmf); + + return ret; +} + +int +SpeedoFontLoad( + FontPtr *ppfont, + char *fontname, + char *filename, + FontEntryPtr entry, + FontScalablePtr vals, + fsBitmapFormat format, + fsBitmapFormatMask fmask, + Mask flags) +{ + FontPtr pfont; + int ret; + + /* Reject ridiculously small sizes that will blow up the math */ + if (hypot(vals->pixel_matrix[0], vals->pixel_matrix[1]) < 1.0 || + hypot(vals->pixel_matrix[2], vals->pixel_matrix[3]) < 1.0) + return BadFontName; + + if (!(pfont = CreateFontRec())) + return AllocError; + + ret = sp_load_font(fontname, filename, entry, vals, format, fmask, + pfont, flags); + + if (ret == Successful) + *ppfont = pfont; + else + DestroyFontRec (pfont); + + return ret; +} + +void +sp_close_font(SpeedoFontPtr spf) +{ + SpeedoMasterFontPtr spmf; + + spmf = spf->master; + --spmf->refcount; + if (spmf->refcount == 0) + sp_close_master_font (spmf); + xfree(spf->encoding); + xfree(spf->bitmaps); + xfree(spf); +} + +static void +SpeedoCloseFont(FontPtr pfont) +{ + SpeedoFontPtr spf; + + spf = (SpeedoFontPtr) pfont->fontPrivate; + sp_close_font(spf); + xfree(pfont->info.isStringProp); + xfree(pfont->info.props); + DestroyFontRec(pfont); + +} diff --git a/nx-X11/lib/font/Speedo/spfuncs.c b/nx-X11/lib/font/Speedo/spfuncs.c new file mode 100644 index 000000000..da4d5c55e --- /dev/null +++ b/nx-X11/lib/font/Speedo/spfuncs.c @@ -0,0 +1,167 @@ +/* $Xorg: spfuncs.c,v 1.4 2001/02/09 02:04:00 xorgcvs Exp $ */ +/* + * Copyright 1990, 1991 Network Computing Devices; + * Portions Copyright 1987 by Digital Equipment Corporation + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the names of Network Computing Devices or Digital + * not be used in advertising or publicity pertaining to distribution of + * the software without specific, written prior permission. + * + * NETWORK COMPUTING DEVICES AND DIGITAL DISCLAIM ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES OR DIGITAL BE + * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Dave Lemke, Network Computing Devices, Inc + */ + +/* + +Copyright 1987, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + +*/ +/* $XFree86: xc/lib/font/Speedo/spfuncs.c,v 1.7 2001/08/27 19:49:51 dawes Exp $ */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#ifndef FONTMODULE +#include <X11/Xos.h> +#endif +#include <X11/fonts/fntfilst.h> +#include <X11/fonts/fontutil.h> +#include "spint.h" + +/* ARGSUSED */ +static int +SpeedoOpenScalable ( + FontPathElementPtr fpe, + FontPtr *pFont, + int flags, + FontEntryPtr entry, + char *fileName, + FontScalablePtr vals, + fsBitmapFormat format, + fsBitmapFormatMask fmask, + FontPtr non_cachable_font) /* We don't do licensing */ +{ + char fullName[MAXFONTNAMELEN]; + + strcpy (fullName, entry->name.name); + return SpeedoFontLoad (pFont, fullName, fileName, entry, vals, + format, fmask, flags); +} + +/* + * XXX + * + * this does a lot more then i'd like, but it has to get the bitmaps + * in order to get accurate metrics (which it *must* have). + * + * a possible optimization is to avoid allocating the glyph memory + * and to simply save the values without doing the work. + */ +static int +get_font_info( + FontInfoPtr pinfo, + char *fontname, + char *filename, + FontEntryPtr entry, + FontScalablePtr vals, + SpeedoFontPtr *spfont) +{ + SpeedoFontPtr spf; + int err; + long sWidth; + + err = sp_open_font(fontname, filename, entry, vals, + (fsBitmapFormat) 0, (fsBitmapFormatMask) 0, (unsigned long) 0, + &spf); + + if (err != Successful) + return err; + + sp_fp_cur = spf; + sp_reset_master(spf->master); + + sp_make_header(spf, pinfo); + + sp_compute_bounds(spf, pinfo, (unsigned long) 0, &sWidth); + + sp_compute_props(spf, fontname, pinfo, sWidth); + + /* compute remaining accelerators */ + FontComputeInfoAccelerators (pinfo); + + *spfont = spf; + + return Successful; +} + +/* ARGSUSED */ +static int +SpeedoGetInfoScaleable( + FontPathElementPtr fpe, + FontInfoPtr pFontInfo, + FontEntryPtr entry, + FontNamePtr fontName, + char *fileName, + FontScalablePtr vals) +{ + SpeedoFontPtr spf = NULL; + char fullName[MAXFONTNAMELEN]; + int err; + + strcpy(fullName, entry->name.name); + FontParseXLFDName(fullName, vals, FONT_XLFD_REPLACE_VALUE); + + err = get_font_info(pFontInfo, fullName, fileName, entry, vals, &spf); + + if (spf) + sp_close_font(spf); + + return err; +} + +static FontRendererRec renderer = { + ".spd", 4, NULL, SpeedoOpenScalable, + NULL, SpeedoGetInfoScaleable, 0 + , CAP_MATRIX | CAP_CHARSUBSETTING +}; + +void +SpeedoRegisterFontFileFunctions() +{ + sp_make_standard_props(); + sp_reset(); + FontFileRegisterRenderer(&renderer); +} diff --git a/nx-X11/lib/font/Speedo/spglyph.c b/nx-X11/lib/font/Speedo/spglyph.c new file mode 100644 index 000000000..3577f5567 --- /dev/null +++ b/nx-X11/lib/font/Speedo/spglyph.c @@ -0,0 +1,399 @@ +/* $Xorg: spglyph.c,v 1.4 2001/02/09 02:04:00 xorgcvs Exp $ */ +/* + * Copyright 1990, 1991 Network Computing Devices; + * Portions Copyright 1987 by Digital Equipment Corporation + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the names of Network Computing Devices or Digital + * not be used in advertising or publicity pertaining to distribution of + * the software without specific, written prior permission. + * + * NETWORK COMPUTING DEVICES AND DIGITAL DISCLAIM ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES OR DIGITAL BE + * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Dave Lemke, Network Computing Devices Inc + */ + +/* + +Copyright 1987, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + +*/ +/* $XFree86: xc/lib/font/Speedo/spglyph.c,v 1.6 2001/01/17 19:43:20 dawes Exp $ */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <X11/X.h> /* for bit order #defines */ +#include "spint.h" +#include <X11/fonts/fontutil.h> + +#undef CLIP_BBOX_NOISE + +static CurrentFontValuesRec current_font_values; +static CurrentFontValuesPtr cfv = ¤t_font_values; +static int bit_order, + byte_order, + scan; + +unsigned long +sp_compute_data_size( + FontPtr pfont, + int mappad, + int scanlinepad, + unsigned long start, + unsigned long end) +{ + unsigned long ch; + unsigned long size = 0; + int bpr; + SpeedoFontPtr spf = (SpeedoFontPtr) pfont->fontPrivate; + FontInfoPtr pinfo = &pfont->info; + int firstChar; + + firstChar = spf->master->first_char_id; + + /* allocate the space */ + switch (mappad) { + int charsize; + CharInfoPtr ci; + xCharInfo *cim; + + case BitmapFormatImageRectMin: + cfv->bpr = 0; + for (ch = start; ch <= end; ch++) { + ci = &spf->encoding[ch - firstChar]; + if (!ci) + ci = spf->pDefault; + cim = &ci->metrics; + charsize = GLYPH_SIZE(ci, scanlinepad); + charsize *= cim->ascent + cim->descent; + size += charsize; + } + break; + case BitmapFormatImageRectMaxWidth: + bpr = GLWIDTHBYTESPADDED(FONT_MAX_WIDTH(pinfo), scanlinepad); + cfv->bpr = bpr; + for (ch = start; ch <= end; ch++) { + ci = &spf->encoding[ch - firstChar]; + if (!ci) + ci = spf->pDefault; + cim = &ci->metrics; + charsize = bpr * (cim->ascent + cim->descent); + size += charsize; + } + break; + case BitmapFormatImageRectMax: + bpr = GLWIDTHBYTESPADDED(FONT_MAX_WIDTH(pinfo), scanlinepad); + cfv->bpr = bpr; + size = (end - start + 1) * bpr * FONT_MAX_HEIGHT(pinfo); + break; + default: + assert(0); + } + + return size; +} + +static void +finish_line(SpeedoFontPtr spf) +{ + int bpr = cfv->bpr; + CharInfoPtr ci = &spf->encoding[cfv->char_id - spf->master->first_char_id]; + + if (bpr == 0) { + bpr = GLYPH_SIZE(ci, cfv->scanpad); + } + if (bpr) { /* char may not have any metrics... */ + cfv->bp = (char *)cfv->bp + bpr; + } + assert(cfv->bp - sp_fp_cur->bitmaps <= sp_fp_cur->bitmap_size); +} + + +void +sp_set_bitmap_bits(fix15 y, fix15 xbit1, fix15 xbit2) +{ + int nmiddle; + CARD8 startmask, + endmask; + CARD8 *dst; + + if (xbit1 > cfv->bit_width) { + +#ifdef CLIP_BBOX_NOISE + SpeedoErr("Run wider than bitmap width -- truncated\n"); +#endif + + xbit1 = cfv->bit_width; + } + if (xbit2 > cfv->bit_width) { + +#ifdef CLIP_BBOX_NOISE + SpeedoErr("Run wider than bitmap width -- truncated\n"); +#endif + + xbit2 = cfv->bit_width; + } + + if (xbit2 < xbit1) { + xbit2 = xbit1; + } + + while (cfv->cur_y != y) { + finish_line(sp_fp_cur); + cfv->cur_y++; + } + + cfv->last_y = y; + if (y >= cfv->bit_height) { + +#ifdef CLIP_BBOX_NOISE + SpeedoErr("Y larger than bitmap height -- truncated\n"); +#endif + + cfv->trunc = 1; + return; + } + if (xbit1 < 0) /* XXX this is more than a little bit rude... */ + xbit1 = 0; + + nmiddle = (xbit1 >> 3); + dst = (CARD8 *)cfv->bp + nmiddle; + xbit2 -= (xbit1 & ~7); + nmiddle = (xbit2 >> 3); + xbit1 &= 7; + xbit2 &= 7; + if (bit_order == MSBFirst) { + startmask = ((CARD8) ~0) >> xbit1; + endmask = ~(((CARD8) ~0) >> xbit2); + } else { + startmask = ((CARD8) ~0) << xbit1; + endmask = ~(((CARD8) ~0) << xbit2); + } + if (nmiddle == 0) + *dst |= endmask & startmask; + else { + *dst++ |= startmask; + while (--nmiddle) + *dst++ = (CARD8)~0; + *dst |= endmask; + } +} + +/* ARGSUSED */ +void +sp_open_bitmap(fix31 x_set_width, fix31 y_set_width, fix31 xorg, fix31 yorg, + fix15 xsize, fix15 ysize) +{ + CharInfoPtr ci = &sp_fp_cur->encoding[cfv->char_id - sp_fp_cur->master->first_char_id]; + +/*- + * this is set to provide better quality bitmaps. since the Speedo + * sp_get_bbox() function returns an approximate (but guarenteed to contain) + * set of metrics, some of the bitmaps can be place poorly inside and + * look bad. + * + * with this set, the actual bitmap values are used instead of the bboxes. + * it makes things look better, but causes two possible problems: + * + * 1 - the reported min & max bounds may not correspond to the extents + * reported + * 2 - if the extents are reported before the character is generated, + * a client could see them change. this currently never happens, + * but will when a desired enhancement (don't reneder till needed) + * is made. + */ + +#define BBOX_FIXUP 1 + +#ifdef BBOX_FIXUP + int off_horz; + int off_vert; + + if (xorg < 0) + off_horz = (fix15) ((xorg - 32768L) / 65536); + else + off_horz = (fix15) ((xorg + 32768L) / 65536); + if (yorg < 0) + off_vert = (fix15) ((yorg - 32768L) / 65536); + else + off_vert = (fix15) ((yorg + 32768L) / 65536); + if (xsize != 0 || ysize != 0 || ci->metrics.characterWidth) + { + ci->metrics.leftSideBearing = off_horz; + ci->metrics.descent = -off_vert; + ci->metrics.rightSideBearing = xsize + off_horz; + ci->metrics.ascent = ysize + off_vert; + } + else + { + /* If setting the proper size would cause the character to appear to + be non-existent, fudge things by giving it a pixel to occupy. */ + xsize = ysize = 1; + ci->metrics.leftSideBearing = ci->metrics.descent = 0; + ci->metrics.rightSideBearing = ci->metrics.ascent = 1; + } + + cfv->bit_width = xsize; + cfv->bit_height = ysize; +#else + cfv->bit_width = ci->metrics.rightSideBearing - + ci->metrics.leftSideBearing; + cfv->bit_height = ci->metrics.ascent + ci->metrics.descent; +#endif + + assert(cfv->bp - sp_fp_cur->bitmaps <= sp_fp_cur->bitmap_size); + ci->bits = (char *) cfv->bp; + + cfv->cur_y = 0; +} + +void +sp_close_bitmap() +{ + CharInfoPtr ci = &sp_fp_cur->encoding[cfv->char_id - sp_fp_cur->master->first_char_id]; + int bpr = cfv->bpr; + + if (bpr == 0) + bpr = GLYPH_SIZE(ci, cfv->scanpad); + if (!cfv->trunc) + finish_line(sp_fp_cur); + cfv->trunc = 0; + cfv->last_y++; + while (cfv->last_y < cfv->bit_height) { + finish_line(sp_fp_cur); + cfv->last_y++; + } + if (byte_order != bit_order) { + switch (scan) { + case 1: + break; + case 2: + TwoByteSwap(cfv->bp, bpr * cfv->bit_height); + break; + case 4: + FourByteSwap(cfv->bp, bpr * cfv->bit_height); + break; + } + } +} + +int +sp_build_all_bitmaps( + FontPtr pfont, + fsBitmapFormat format, + fsBitmapFormatMask fmask) +{ + int ret, + glyph = 1, + image = BitmapFormatImageRectMin; + unsigned long glyph_size; + SpeedoFontPtr spf = (SpeedoFontPtr) pfont->fontPrivate; + SpeedoMasterFontPtr spmf = spf->master; + pointer bitmaps; + int start, + end, + i; + + scan = 1; + ret = CheckFSFormat(format, fmask, + &bit_order, &byte_order, &scan, &glyph, &image); + + pfont->bit = bit_order; + pfont->byte = byte_order; + pfont->glyph = glyph; + pfont->scan = scan; + if (ret != Successful) + return BadFontFormat; + + start = spmf->first_char_id; + end = spmf->max_id; + glyph_size = sp_compute_data_size(pfont, image, glyph, start, end); + + /* XXX -- MONDO KLUDGE -- add some slop */ + /* + * not sure why this is wanted, but it keeps the packer from going off the + * end and toasting us down the line + */ + glyph_size += 20; + +#ifdef DEBUG + spf->bitmap_size = glyph_size; +#endif + + bitmaps = (pointer) xalloc(glyph_size); + if (!bitmaps) + return AllocError; + bzero((char *) bitmaps, glyph_size); + + /* set up some state */ + sp_fp_cur = spf; + spf->bitmaps = bitmaps; + cfv->format = format; + cfv->scanpad = glyph; + cfv->bp = bitmaps; + + for (i = 0; i < spmf->num_chars; i++) { + int j; + cfv->char_index = spmf->enc[i * 2 + 1]; + cfv->char_id = spmf->enc[i * 2]; +#ifdef DEBUG +fprintf(stderr, "build_all_sp_bitmaps:i = %d, Char ID = %d\n", i, cfv->char_id); +#endif + if (!cfv->char_id) + continue; + + /* + * See if this character is in the list of ranges specified in the + * XLFD name + */ + for (j = 0; j < spf->vals.nranges; j++) + if (cfv->char_id >= mincharno(spf->vals.ranges[j]) && + cfv->char_id <= maxcharno(spf->vals.ranges[j])) + break; + + /* If not, don't realize it. */ + if (spf->vals.nranges && j == spf->vals.nranges) + continue; + + if (!sp_make_char(cfv->char_index)) { + +#ifdef DEBUG /* can be very common with some encodings */ + SpeedoErr("Can't make char %d\n", cfv->char_index); +#endif + } + } + + return Successful; +} diff --git a/nx-X11/lib/font/Speedo/spinfo.c b/nx-X11/lib/font/Speedo/spinfo.c new file mode 100644 index 000000000..d7a1edd98 --- /dev/null +++ b/nx-X11/lib/font/Speedo/spinfo.c @@ -0,0 +1,462 @@ +/* $Xorg: spinfo.c,v 1.4 2001/02/09 02:04:00 xorgcvs Exp $ */ +/* + * Copyright 1990, 1991 Network Computing Devices; + * Portions Copyright 1987 by Digital Equipment Corporation + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the names of Network Computing Devices or Digital + * not be used in advertising or publicity pertaining to distribution of + * the software without specific, written prior permission. + * + * NETWORK COMPUTING DEVICES AND DIGITAL DISCLAIM ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES OR DIGITAL BE + * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Dave Lemke, Network Computing Devices, Inc + */ + +/* + +Copyright 1987, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + +*/ +/* $XFree86: xc/lib/font/Speedo/spinfo.c,v 1.12 2001/12/14 19:56:42 dawes Exp $ */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <X11/fonts/fntfilst.h> +#include <X11/fonts/fontutil.h> +#include "spint.h" +#ifndef FONTMODULE +#include <math.h> +#else +#include "xf86_ansic.h" +#endif + +/* percentage of pointsize used to specify ascent & descent */ +#define STRETCH_FACTOR 120 + +enum scaleType { + atom, truncate_atom, pixel_size, point_size, resolution_x, + resolution_y, average_width +}; + +typedef struct _fontProp { + char *name; + long atom; + enum scaleType type; +} fontProp; + +static fontProp fontNamePropTable[] = { + { "FOUNDRY", 0, atom }, + { "FAMILY_NAME", 0, atom }, + { "WEIGHT_NAME", 0, atom }, + { "SLANT", 0, atom }, + { "SETWIDTH_NAME", 0, atom }, + { "ADD_STYLE_NAME", 0, atom }, + { "PIXEL_SIZE", 0, pixel_size }, + { "POINT_SIZE", 0, point_size }, + { "RESOLUTION_X", 0, resolution_x }, + { "RESOLUTION_Y", 0, resolution_y }, + { "SPACING", 0, atom }, + { "AVERAGE_WIDTH", 0, average_width }, + { "CHARSET_REGISTRY", 0, atom }, + { "CHARSET_ENCODING", 0, truncate_atom } +}; + +/* Warning: following array is closely related to the sequence of + defines after it. */ + +static fontProp extraProps[] = { + { "FONT", 0, }, + { "COPYRIGHT", 0, }, + { "RAW_PIXEL_SIZE", 0, }, + { "RAW_POINT_SIZE", 0, }, + { "RAW_ASCENT", 0, }, + { "RAW_DESCENT", 0, }, + { "RAW_AVERAGE_WIDTH", 0, }, + { "FONT_TYPE", 0, }, + { "RASTERIZER_NAME", 0, } +}; + +/* this is a bit kludgy */ +#define FONTPROP 0 +#define COPYRIGHTPROP 1 +#define RAWPIXELPROP 2 +#define RAWPOINTPROP 3 +#define RAWASCENTPROP 4 +#define RAWDESCENTPROP 5 +#define RAWWIDTHPROP 6 +#define FONT_TYPEPROP 7 +#define RASTERIZER_NAMEPROP 8 + +#define NNAMEPROPS (sizeof(fontNamePropTable) / sizeof(fontProp)) +#define NEXTRAPROPS (sizeof(extraProps) / sizeof(fontProp)) + +#define NPROPS (NNAMEPROPS + NEXTRAPROPS) + +void +sp_make_standard_props() +{ + int i; + fontProp *t; + + i = sizeof(fontNamePropTable) / sizeof(fontProp); + for (t = fontNamePropTable; i; i--, t++) + t->atom = MakeAtom(t->name, (unsigned) strlen(t->name), TRUE); + i = sizeof(extraProps) / sizeof(fontProp); + for (t = extraProps; i; i--, t++) + t->atom = MakeAtom(t->name, (unsigned) strlen(t->name), TRUE); +} + +void +sp_make_header( + SpeedoFontPtr spf, + FontInfoPtr pinfo) +{ + int pixel_size; + SpeedoMasterFontPtr spmf = spf->master; + + pinfo->firstCol = spmf->first_char_id & 0xff; + pinfo->firstRow = spmf->first_char_id >> 8; + pinfo->lastCol = spmf->max_id & 0xff; + pinfo->lastRow = spmf->max_id >> 8; + + /* XXX -- hackery here */ + pinfo->defaultCh = 0; +/* computed by FontComputeInfoAccelerators: + * noOverlap + * constantMetrics + * terminalFont + * constantWidth + * inkInside + */ + pinfo->inkMetrics = 0; + pinfo->allExist = 0; + pinfo->drawDirection = LeftToRight; + pinfo->cachable = 1; + if (spf->specs.xxmult != spf->specs.yymult) + pinfo->anamorphic = TRUE; + else + pinfo->anamorphic = FALSE; +/* computed by sp_compute_bounds: + * maxOverlap + * maxbounds + * minbounds + * ink_maxbounds + * ink_minbounds + */ + pixel_size = spf->vals.pixel_matrix[3] * STRETCH_FACTOR / 100; + pinfo->fontAscent = pixel_size * 764 / 1000; /* 764 == EM_TOP */ + pinfo->fontDescent = pixel_size - pinfo->fontAscent; +} + +static void +adjust_min_max( + xCharInfo *minc, + xCharInfo *maxc, + xCharInfo *tmp) +{ +#define MINMAX(field,ci) \ + if (minc->field > (ci)->field) \ + minc->field = (ci)->field; \ + if (maxc->field < (ci)->field) \ + maxc->field = (ci)->field; + + MINMAX(ascent, tmp); + MINMAX(descent, tmp); + MINMAX(leftSideBearing, tmp); + MINMAX(rightSideBearing, tmp); + MINMAX(characterWidth, tmp); + + if ((INT16)minc->attributes > (INT16)tmp->attributes) + minc->attributes = tmp->attributes; + if ((INT16)maxc->attributes < (INT16)tmp->attributes) + maxc->attributes = tmp->attributes; + +#undef MINMAX +} + + +void +sp_compute_bounds( + SpeedoFontPtr spf, + FontInfoPtr pinfo, + unsigned long flags, + long *sWidth) +{ + int i, + id, + index, + maxOverlap, + overlap, + total_width = 0; + xCharInfo minchar, + maxchar, + tmpchar; + bbox_t bbox; + fix31 width; + double pix_width; + SpeedoMasterFontPtr spmf = spf->master; + int firstChar; + int num_chars = 0; + + firstChar = spmf->first_char_id; + minchar.ascent = minchar.descent = + minchar.leftSideBearing = minchar.rightSideBearing = + minchar.characterWidth = minchar.attributes = 32767; + maxchar.ascent = maxchar.descent = + maxchar.leftSideBearing = maxchar.rightSideBearing = + maxchar.characterWidth = maxchar.attributes = -32767; + maxOverlap = -32767; + *sWidth = 0; + for (i = 0; i < spmf->num_chars; i++) { + int j; + int char_id; + + index = spmf->enc[i * 2 + 1]; + char_id = spmf->enc[i * 2]; + /* + * See if this character is in the list of ranges specified in the + * XLFD name + */ + for (j = 0; j < spf->vals.nranges; j++) + if (char_id >= mincharno(spf->vals.ranges[j]) && + char_id <= maxcharno(spf->vals.ranges[j])) + break; + if (spf->vals.nranges && j == spf->vals.nranges) + continue; + num_chars++; + + if (!(flags & ComputeBoundsOnly)) { + + width = sp_get_char_width(index); + + /* convert to pixel coords */ + pix_width = (int)width * (spf->specs.xxmult / 65536L) + + ((int) width * (spf->specs.xxmult % 65536L)) + / 65536L; + pix_width /= 65536L; + + (void) sp_get_char_bbox(index, &bbox); + bbox.ymax = (bbox.ymax + 32768L) >> 16; + bbox.ymin = (bbox.ymin + 32768L) >> 16; + bbox.xmin = (bbox.xmin + 32768L) >> 16; + bbox.xmax = (bbox.xmax + 32768L) >> 16; + tmpchar.ascent = bbox.ymax; + tmpchar.descent = -bbox.ymin; + tmpchar.characterWidth = (int)(pix_width + /* round */ + (pix_width > 0 ? 0.5 : -0.5)); + tmpchar.rightSideBearing = bbox.xmax; + tmpchar.leftSideBearing = bbox.xmin; + + if (!tmpchar.characterWidth && + tmpchar.ascent == -tmpchar.descent && + tmpchar.rightSideBearing == tmpchar.leftSideBearing) + { + /* Character appears non-existent, probably as a result + of the transformation. Let's give it one pixel in + the universe so it's not mistaken for non-existent. */ + tmpchar.leftSideBearing = tmpchar.descent = 0; + tmpchar.rightSideBearing = tmpchar.ascent = 1; + } + + tmpchar.attributes = (int)((double)(int)width / 65.536 + .5); + } + else + tmpchar = spf->encoding[char_id - firstChar].metrics; + + adjust_min_max(&minchar, &maxchar, &tmpchar); + overlap = tmpchar.rightSideBearing - tmpchar.characterWidth; + if (maxOverlap < overlap) + maxOverlap = overlap; + + total_width += ((int)(INT16)tmpchar.attributes); + *sWidth += abs((int)(INT16)tmpchar.attributes); + + if (flags & SaveMetrics) { + id = spmf->enc[i * 2] - firstChar; + assert(id <= spmf->max_id - firstChar); + spf->encoding[id].metrics = tmpchar; + } + } + + + if (num_chars > 0) + { + *sWidth = (int)(((double)*sWidth * 10.0 + (double)num_chars / 2.0) / + num_chars); + if (total_width < 0) + { + /* Predominant direction is R->L */ + *sWidth = -*sWidth; + } + spf->vals.width = (int)((double)*sWidth * spf->vals.pixel_matrix[0] / + 1000.0 + + (spf->vals.pixel_matrix[0] > 0 ? .5 : -.5)); + } + else + { + spf->vals.width = 0; + } + pinfo->maxbounds = maxchar; + pinfo->minbounds = minchar; + pinfo->ink_maxbounds = maxchar; + pinfo->ink_minbounds = minchar; + pinfo->maxOverlap = maxOverlap; +} + +void +sp_compute_props( + SpeedoFontPtr spf, + char *fontname, + FontInfoPtr pinfo, + long sWidth) +{ + FontPropPtr pp; + int i, + nprops; + fontProp *fpt; + char *is_str; + char *ptr1 = NULL, + *ptr2; + char *ptr3; + char tmpname[1024]; + FontScalableRec tmpvals; + + nprops = pinfo->nprops = NPROPS; + pinfo->isStringProp = (char *) xalloc(sizeof(char) * nprops); + pinfo->props = (FontPropPtr) xalloc(sizeof(FontPropRec) * nprops); + if (!pinfo->isStringProp || !pinfo->props) { + xfree(pinfo->isStringProp); + pinfo->isStringProp = (char *) 0; + xfree(pinfo->props); + pinfo->props = (FontPropPtr) 0; + pinfo->nprops = 0; + return; + } + bzero(pinfo->isStringProp, (sizeof(char) * nprops)); + + ptr2 = fontname; + for (i = NNAMEPROPS, pp = pinfo->props, fpt = fontNamePropTable, + is_str = pinfo->isStringProp; + i; + i--, pp++, fpt++, is_str++) { + + if (*ptr2) + { + ptr1 = ptr2 + 1; + if (!(ptr2 = strchr(ptr1, '-'))) ptr2 = strchr(ptr1, '\0'); + } + + pp->name = fpt->atom; + switch (fpt->type) { + case atom: + *is_str = TRUE; + pp->value = MakeAtom(ptr1, ptr2 - ptr1, TRUE); + break; + case truncate_atom: + *is_str = TRUE; + for (ptr3 = ptr1; *ptr3; ptr3++) + if (*ptr3 == '[') + break; + pp->value = MakeAtom(ptr1, ptr3 - ptr1, TRUE); + break; + case pixel_size: + pp->value = (int)(spf->vals.pixel_matrix[3] + + (spf->vals.pixel_matrix[3] > 0 ? .5 : -.5)); + break; + case point_size: + pp->value = (int)(spf->vals.point_matrix[3] * 10.0 + + (spf->vals.point_matrix[3] > 0 ? .5 : -.5)); + break; + case resolution_x: + pp->value = spf->vals.x; + break; + case resolution_y: + pp->value = spf->vals.y; + break; + case average_width: + pp->value = spf->vals.width; + break; + } + } + + for (i = 0, fpt = extraProps; i < NEXTRAPROPS; i++, is_str++, pp++, fpt++) { + pp->name = fpt->atom; + switch (i) { + case FONTPROP: + *is_str = TRUE; + strcpy(tmpname, fontname); + FontParseXLFDName(tmpname, &tmpvals, FONT_XLFD_REPLACE_ZERO); + FontParseXLFDName(tmpname, &spf->vals, FONT_XLFD_REPLACE_VALUE); + pp->value = MakeAtom(tmpname, strlen(tmpname), TRUE); + break; + case COPYRIGHTPROP: + *is_str = TRUE; + pp->value = MakeAtom(spf->master->copyright, + strlen(spf->master->copyright), TRUE); + break; + case FONT_TYPEPROP: + *is_str = TRUE; + pp->value = MakeAtom("Speedo", strlen("Speedo"), TRUE); + break; + case RASTERIZER_NAMEPROP: + *is_str = TRUE; + pp->value = MakeAtom("X Consortium Speedo Rasterizer", + strlen("X Consortium Speedo Rasterizer"), + TRUE); + break; + case RAWPIXELPROP: + *is_str = FALSE; + pp->value = 1000; + break; + case RAWPOINTPROP: + *is_str = FALSE; + pp->value = (long)(72270.0 / (double)spf->vals.y + .5); + break; + case RAWASCENTPROP: + *is_str = FALSE; + pp->value = STRETCH_FACTOR * 764 / 100; + break; + case RAWDESCENTPROP: + *is_str = FALSE; + pp->value = STRETCH_FACTOR * 236 / 100; + break; + case RAWWIDTHPROP: + *is_str = FALSE; + pp->value = sWidth; + break; + } + } +} diff --git a/nx-X11/lib/font/Speedo/spint.h b/nx-X11/lib/font/Speedo/spint.h new file mode 100644 index 000000000..118ea8f42 --- /dev/null +++ b/nx-X11/lib/font/Speedo/spint.h @@ -0,0 +1,180 @@ +/* $Xorg: spint.h,v 1.4 2001/02/09 02:04:00 xorgcvs Exp $ */ +/* + * Copyright 1990, 1991 Network Computing Devices; + * Portions Copyright 1987 by Digital Equipment Corporation + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the names of Network Computing Devices or Digital + * not be used in advertising or publicity pertaining to distribution of + * the software without specific, written prior permission. + * + * NETWORK COMPUTING DEVICES AND DIGITAL DISCLAIM ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES OR DIGITAL BE + * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + +Copyright 1987, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + +*/ +/* $XFree86: xc/lib/font/Speedo/spint.h,v 1.9 2001/01/17 19:43:20 dawes Exp $ */ + +#ifndef _SPINT_H_ +#define _SPINT_H_ + +#include <X11/fonts/fntfilst.h> +#ifndef XFree86LOADER +#include <stdio.h> +#else +#include <xf86_ansic.h> +#endif +#include <X11/Xfuncproto.h> +#include "speedo.h" + +#define SaveMetrics 0x1 +#define ComputeBoundsOnly 0x2 + +#define GLWIDTHBYTESPADDED(bits,nbytes) \ + ((nbytes) == 1 ? (((bits)+7)>>3) /* pad to 1 byte */ \ + :(nbytes) == 2 ? ((((bits)+15)>>3)&~1) /* pad to 2 bytes */ \ + :(nbytes) == 4 ? ((((bits)+31)>>3)&~3) /* pad to 4 bytes */ \ + :(nbytes) == 8 ? ((((bits)+63)>>3)&~7) /* pad to 8 bytes */ \ + : 0) + +#define GLYPH_SIZE(ch, nbytes) \ + GLWIDTHBYTESPADDED((ch)->metrics.rightSideBearing - \ + (ch)->metrics.leftSideBearing, (nbytes)) + +#define mincharno(p) ((p).min_char_low + ((p).min_char_high << 8)) +#define maxcharno(p) ((p).max_char_low + ((p).max_char_high << 8)) + +#define MasterFileOpen 0x1 + +typedef struct _sp_master { + FontEntryPtr entry; /* back pointer */ + FILE *fp; + char *fname; + ufix8 *f_buffer; + ufix8 *c_buffer; + char *copyright; + ufix8 *key; + buff_t font; + buff_t char_data; + ufix16 mincharsize; + int first_char_id; + int num_chars; + int max_id; + int state; /* open, closed */ + int refcount; /* number of instances */ + int *enc; + int enc_size; +} SpeedoMasterFontRec, *SpeedoMasterFontPtr; + +typedef struct _cur_font_stats { + fsBitmapFormat format; + /* current glyph info */ + ufix16 char_index; + ufix16 char_id; + + fix15 bit_width, + bit_height; + fix15 cur_y; + int bpr; + + /* + * since Speedo returns extents that are not identical to what it feeds to + * the bitmap builder, and we want to be able to use the extents for + * preformance reasons, some of the bitmaps require padding out. the next + * two flags keep track of this. + */ + fix15 last_y; + int trunc; + + pointer bp; + int scanpad; +} CurrentFontValuesRec, *CurrentFontValuesPtr; + + +typedef struct _sp_font { + struct _sp_master *master; + specs_t specs; + + FontEntryPtr entry; + + FontScalableRec vals; + + /* char & metric data */ + CharInfoPtr encoding; + CharInfoPtr pDefault; + pointer bitmaps; + +#ifdef DEBUG + unsigned long bitmap_size; +#endif + +} SpeedoFontRec, *SpeedoFontPtr; + +extern SpeedoFontPtr sp_fp_cur; + +extern int sp_open_font(char *, char *, FontEntryPtr, FontScalablePtr, + fsBitmapFormat, fsBitmapFormatMask, Mask, + SpeedoFontPtr *); +extern int sp_open_master(const char *, const char *, SpeedoMasterFontPtr *); +extern void sp_close_font(SpeedoFontPtr); +extern void sp_close_master_font(SpeedoMasterFontPtr); +extern void sp_close_master_file(SpeedoMasterFontPtr); +extern void sp_reset_master(SpeedoMasterFontPtr); +extern void SpeedoErr(char *fmt, ...); + +extern void sp_make_standard_props(void); +extern void sp_make_header(SpeedoFontPtr, FontInfoPtr); +extern void sp_compute_bounds(SpeedoFontPtr, FontInfoPtr, unsigned long, long *); +extern void sp_compute_props(SpeedoFontPtr, char *, FontInfoPtr, long); +extern int sp_build_all_bitmaps(FontPtr, fsBitmapFormat, fsBitmapFormatMask); +extern unsigned long sp_compute_data_size(FontPtr, int, int, unsigned long, + unsigned long); + +extern int SpeedoFontLoad(FontPtr *, char *, char *, FontEntryPtr, + FontScalablePtr, fsBitmapFormat, fsBitmapFormatMask, + Mask); + +extern int sp_bics_map[]; +extern int sp_bics_map_size; + +#ifdef EXTRAFONTS +extern int adobe_map[]; +extern int adobe_map_size; + +#endif + +#endif /* _SPINT_H_ */ diff --git a/nx-X11/lib/font/Speedo/sptobdf.c b/nx-X11/lib/font/Speedo/sptobdf.c new file mode 100644 index 000000000..ca3caa515 --- /dev/null +++ b/nx-X11/lib/font/Speedo/sptobdf.c @@ -0,0 +1,678 @@ +/* $Xorg: sptobdf.c,v 1.4 2001/02/09 02:04:00 xorgcvs Exp $ */ +/* + * Copyright 1990, 1991 Network Computing Devices; + * Portions Copyright 1987 by Digital Equipment Corporation + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the names of Network Computing Devices and + * Digital not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior permission. + * Network Computing Devices and Digital make no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * NETWORK COMPUTING DEVICES AND DIGITAL DISCLAIM ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES OR DIGITAL BE + * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Dave Lemke + */ + +/* + +Copyright 1987, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + +*/ + +/* + * Speedo outline to BFD format converter + */ + +#include <stdio.h> +#include "speedo.h" + +#ifdef EXTRAFONTS +#include "ncdkeys.h" +#else +#include "keys.h" +#endif + +#include "iso8859.h" + +#define MAX_BITS 1024 + +#define BBOX_CLIP + +static char line_of_bits[MAX_BITS + 1]; + +static FILE *fp; +static ufix16 char_index, + char_id; +static buff_t font; +static buff_t char_data; +static ufix8 *f_buffer, + *c_buffer; +static ufix16 mincharsize; +static fix15 cur_y; +static fix15 bit_width, + bit_height; + +static ufix8 key[] = +{ + KEY0, + KEY1, + KEY2, + KEY3, + KEY4, + KEY5, + KEY6, + KEY7, + KEY8 +}; /* Font decryption key */ + + +static char *progname; +static char *fontname = NULL; +static char *fontfile = NULL; + +static int point_size = 120; +static int x_res = 72; +static int y_res = 72; +static int quality = 0; +static int iso_encoding = 1; + +static int num_props = 7; +static int stretch = 120; + +static specs_t specs; + +static void dump_header(); + +static void +usage() +{ + fprintf(stderr, "Usage: %s [-xres x resolution] [-yres y resolution]\n\t[-ptsize pointsize] [-fn fontname] [-q quality (0-1)] fontfile\n", progname); + fprintf(stderr, "Where:\n"); + fprintf(stderr, "-xres specifies the X resolution (72)\n"); + fprintf(stderr, "-yres specifies the Y resolution (72)\n"); + fprintf(stderr, "-pts specifies the pointsize in decipoints (120)\n"); + fprintf(stderr, "-fn specifies the font name (full Bitstream name)\n"); + fprintf(stderr, "-q specifies the font quality [0-1] (0)\n"); + fprintf(stderr, "\n"); + exit(0); +} + +static fix15 +read_2b(ptr) + ufix8 *ptr; +{ + fix15 tmp; + + tmp = *ptr++; + tmp = (tmp << 8) + *ptr; + return tmp; +} + +static fix31 +read_4b(ptr) + ufix8 *ptr; +{ + fix31 tmp; + + tmp = *ptr++; + tmp = (tmp << 8) + *ptr++; + tmp = (tmp << 8) + *ptr++; + tmp = (tmp << 8) + *ptr; + return tmp; +} + +static void +process_args(ac, av) + int ac; + char **av; +{ + int i; + + for (i = 1; i < ac; i++) { + if (!strncmp(av[i], "-xr", 3)) { + if (av[i + 1]) { + x_res = atoi(av[++i]); + } else + usage(); + } else if (!strncmp(av[i], "-yr", 3)) { + if (av[i + 1]) { + y_res = atoi(av[++i]); + } else + usage(); + } else if (!strncmp(av[i], "-pt", 3)) { + if (av[i + 1]) { + point_size = atoi(av[++i]); + } else + usage(); + } else if (!strncmp(av[i], "-fn", 3)) { + if (av[i + 1]) { + fontname = av[++i]; + } else + usage(); + } else if (!strncmp(av[i], "-q", 2)) { + if (av[i + 1]) { + quality = atoi(av[++i]); + } else + usage(); + } else if (!strncmp(av[i], "-st", 3)) { + if (av[i + 1]) { + stretch = atoi(av[++i]); + } else + usage(); + } else if (!strncmp(av[i], "-noni", 5)) { + iso_encoding = 0; + } else if (*av[i] == '-') { + usage(); + } else + fontfile = av[i]; + } + if (!fontfile) + usage(); +} + +void +main(argc, argv) + int argc; + char **argv; +{ + ufix32 i; + ufix8 tmp[16]; + ufix32 minbufsize; + ufix16 cust_no; + int first_char_index, + num_chars; + + progname = argv[0]; + process_args(argc, argv); + fp = fopen(fontfile, "r"); + if (!fp) { + fprintf(stderr, "No such font file, \"%s\"\n", fontfile); + exit(-1); + } + if (fread(tmp, sizeof(ufix8), 16, fp) != 16) { + fprintf(stderr, "error reading \"%s\"\n", fontfile); + exit(-1); + } + minbufsize = (ufix32) read_4b(tmp + FH_FBFSZ); + f_buffer = (ufix8 *) malloc(minbufsize); + if (!f_buffer) { + fprintf(stderr, "can't get %x bytes of memory\n", minbufsize); + exit(-1); + } + fseek(fp, (ufix32) 0, 0); + + if (fread(f_buffer, sizeof(ufix8), (ufix16) minbufsize, fp) != minbufsize) { + fprintf(stderr, "error reading file \"%s\"\n", fontfile); + exit(-1); + } + mincharsize = read_2b(f_buffer + FH_CBFSZ); + + c_buffer = (ufix8 *) malloc(mincharsize); + if (!c_buffer) { + fprintf(stderr, "can't get %x bytes for char buffer\n", mincharsize); + exit(-1); + } + /* init */ + sp_reset(); + + font.org = f_buffer; + font.no_bytes = minbufsize; + + if ((cust_no = sp_get_cust_no(font)) != CUS0) { + fprintf(stderr, "Non-standard encryption for \"%s\"\n", fontfile); + exit(-1); + } + sp_set_key(key); + + first_char_index = read_2b(f_buffer + FH_FCHRF); + num_chars = read_2b(f_buffer + FH_NCHRL); + + /* set up specs */ + /* Note that point size is in decipoints */ + specs.pfont = &font; + /* XXX beware of overflow */ + specs.xxmult = point_size * x_res / 720 * (1 << 16); + specs.xymult = 0L << 16; + specs.xoffset = 0L << 16; + specs.yxmult = 0L << 16; + specs.yymult = point_size * y_res / 720 * (1 << 16); + specs.yoffset = 0L << 16; + switch (quality) { + case 0: + specs.flags = 0; + break; + case 1: + specs.flags = MODE_SCREEN; + break; + case 2: + specs.flags = MODE_2D; + break; + default: + fprintf(stderr, "bogus quality value %d\n", quality); + break; + } + specs.out_info = NULL; + + if (!fontname) { + fontname = (char *) (f_buffer + FH_FNTNM); + } + if (iso_encoding) + num_chars = num_iso_chars; + dump_header(num_chars); + + if (!sp_set_specs(&specs)) { + fprintf(stderr, "can't set specs\n"); + } else { + if (iso_encoding) { + for (i = 0; i < num_iso_chars * 2; i += 2) { + char_index = iso_map[i + 1]; + char_id = iso_map[i]; + if (!sp_make_char(char_index)) { + fprintf(stderr, "can't make char %x\n", char_index); + } + } + } else { + for (i = 0; i < num_chars; i++) { + char_index = i + first_char_index; + char_id = sp_get_char_id(char_index); + if (char_id) { + if (!sp_make_char(char_index)) { + fprintf(stderr, "can't make char %x\n", char_index); + } + } + } + } + } + + (void) fclose(fp); + + printf("ENDFONT\n"); + exit(0); +} + +static void +dump_header(num_chars) + ufix32 num_chars; +{ + fix15 xmin, + ymin, + xmax, + ymax; + fix15 ascent, + descent; + fix15 pixel_size; + + xmin = read_2b(f_buffer + FH_FXMIN); + ymin = read_2b(f_buffer + FH_FYMIN); + xmax = read_2b(f_buffer + FH_FXMAX); + ymax = read_2b(f_buffer + FH_FYMAX); + pixel_size = point_size * x_res / 720; + + printf("STARTFONT 2.1\n"); + printf("COMMENT\n"); + printf("COMMENT Generated from Bitstream Speedo outlines via sptobdf\n"); + printf("COMMENT\n"); + printf("FONT %s\n", fontname); + printf("SIZE %d %d %d\n", pixel_size, x_res, y_res); + printf("FONTBOUNDINGBOX %d %d %d %d\n", xmin, ymin, xmax, ymax); + printf("STARTPROPERTIES %d\n", num_props); + + printf("RESOLUTION_X %d\n", x_res); + printf("RESOLUTION_Y %d\n", y_res); + printf("POINT_SIZE %d\n", point_size); + printf("PIXEL_SIZE %d\n", pixel_size); + printf("COPYRIGHT \"%s\"\n", f_buffer + FH_CPYRT); + + /* do some stretching here so that its isn't too tight */ + pixel_size = pixel_size * stretch / 100; + ascent = pixel_size * 764 / 1000; /* 764 == EM_TOP */ + descent = pixel_size - ascent; + printf("FONT_ASCENT %d\n", ascent); + printf("FONT_DESCENT %d\n", descent); + + printf("ENDPROPERTIES\n"); + printf("CHARS %d\n", num_chars); +} + +buff_t * +sp_load_char_data(file_offset, num, cb_offset) + fix31 file_offset; + fix15 num; + fix15 cb_offset; +{ + if (fseek(fp, (long) file_offset, (int) 0)) { + fprintf(stderr, "can't seek to char\n"); + (void) fclose(fp); + exit(-1); + } + if ((num + cb_offset) > mincharsize) { + fprintf(stderr, "char buf overflow\n"); + (void) fclose(fp); + exit(-2); + } + if (fread((c_buffer + cb_offset), sizeof(ufix8), num, fp) != num) { + fprintf(stderr, "can't get char data\n"); + exit(-1); + } + char_data.org = (ufix8 *) c_buffer + cb_offset; + char_data.no_bytes = num; + + return &char_data; +} + +/* + * Called by Speedo character generator to report an error. + * + * Since character data not available is one of those errors + * that happens many times, don't report it to user + */ +void +sp_report_error(n) + fix15 n; +{ + switch (n) { + case 1: + fprintf(stderr, "Insufficient font data loaded\n"); + break; + case 3: + fprintf(stderr, "Transformation matrix out of range\n"); + break; + case 4: + fprintf(stderr, "Font format error\n"); + break; + case 5: + fprintf(stderr, "Requested specs not compatible with output module\n"); + break; + case 7: + fprintf(stderr, "Intelligent transformation requested but not supported\n"); + break; + case 8: + fprintf(stderr, "Unsupported output mode requested\n"); + break; + case 9: + fprintf(stderr, "Extended font loaded but only compact fonts supported\n"); + break; + case 10: + fprintf(stderr, "Font specs not set prior to use of font\n"); + break; + case 12: + break; + case 13: + fprintf(stderr, "Track kerning data not available()\n"); + break; + case 14: + fprintf(stderr, "Pair kerning data not available()\n"); + break; + default: + fprintf(stderr, "report_error(%d)\n", n); + break; + } +} + +void +sp_open_bitmap(x_set_width, y_set_width, xorg, yorg, xsize, ysize) + fix31 x_set_width; + fix31 y_set_width; + fix31 xorg; + fix31 yorg; + fix15 xsize; + fix15 ysize; +{ + fix15 i; + fix15 off_horz; + fix15 off_vert; + fix31 width, + pix_width; + bbox_t bb; + + bit_width = xsize; + + bit_height = ysize; + off_horz = (fix15) ((xorg + 32768L) >> 16); + off_vert = (fix15) ((yorg + 32768L) >> 16); + + if (bit_width > MAX_BITS) { + +#ifdef DEBUG + fprintf(stderr, "char wider than max bits -- truncated\n"); +#endif + + bit_width = MAX_BITS; + } + width = sp_get_char_width(char_index); + pix_width = width * (specs.xxmult / 65536L) + + ((ufix32) width * ((ufix32) specs.xxmult & 0xffff)) / 65536L; + pix_width /= 65536L; + + width = (pix_width * 7200L) / (point_size * y_res); + + (void) sp_get_char_bbox(char_index, &bb); + bb.xmin >>= 16; + bb.ymin >>= 16; + bb.xmax >>= 16; + bb.ymax >>= 16; + +#ifdef DEBUG + if ((bb.xmax - bb.xmin) != bit_width) + fprintf(stderr, "bbox & width mismatch 0x%x (%d) (%d vs %d)\n", + char_index, char_id, (bb.xmax - bb.xmin), bit_width); + if ((bb.ymax - bb.ymin) != bit_height) + fprintf(stderr, "bbox & height mismatch 0x%x (%d) (%d vs %d)\n", + char_index, char_id, (bb.ymax - bb.ymin), bit_height); + if (bb.xmin != off_horz) + fprintf(stderr, "x min mismatch 0x%x (%d) (%d vs %d)\n", + char_index, char_id, bb.xmin, off_horz); + if (bb.ymin != off_vert) + fprintf(stderr, "y min mismatch 0x%x (%d) (%d vs %d)\n", + char_index, char_id, bb.ymin, off_vert); +#endif + +#ifdef BBOX_CLIP + bit_width = bb.xmax - bb.xmin; + bit_height = bb.ymax - bb.ymin; + off_horz = bb.xmin; + off_vert = bb.ymin; +#endif + + /* XXX kludge to handle space */ + if (bb.xmin == 0 && bb.ymin == 0 && bb.xmax == 0 && bb.ymax == 0 && + width) { + bit_width = 1; + bit_height = 1; + } + printf("STARTCHAR %d\n", char_id); + printf("ENCODING %d\n", char_id); + printf("SWIDTH %d 0\n", width); + printf("DWIDTH %d 0\n", pix_width); + printf("BBX %d %d %d %d\n", bit_width, bit_height, off_horz, off_vert); + printf("BITMAP\n"); + + for (i = 0; i < bit_width; i++) { + line_of_bits[i] = '.'; + } + line_of_bits[bit_width] = '\0'; + cur_y = 0; +} + +static void +dump_line(line) + ufix8 *line; +{ + int bit; + unsigned byte; + + byte = 0; + for (bit = 0; bit < bit_width; bit++) { + if (line[bit] == 'X') + byte |= (1 << (7 - (bit & 7))); + if ((bit & 7) == 7) { + printf("%02X", byte); + byte = 0; + } + } + if ((bit & 7) != 0) + printf("%02X", byte); + printf("\n"); +} + +#ifdef BBOX_CLIP +static fix15 last_y; +static int trunc = 0; + +#endif + +void +sp_set_bitmap_bits(y, xbit1, xbit2) + fix15 y; + fix15 xbit1; + fix15 xbit2; +{ + fix15 i; + + if (xbit1 > MAX_BITS) { + +#ifdef DEBUG + fprintf(stderr, "run wider than max bits -- truncated\n"); +#endif + + xbit1 = MAX_BITS; + } + if (xbit2 > MAX_BITS) { + +#ifdef DEBUG + fprintf(stderr, "run wider than max bits -- truncated\n"); +#endif + + xbit2 = MAX_BITS; + } + while (cur_y != y) { + dump_line(line_of_bits); + for (i = 0; i < bit_width; i++) { + line_of_bits[i] = '.'; + } + cur_y++; + } + +#ifdef BBOX_CLIP + last_y = y; + if (y >= bit_height) { + +#ifdef DEBUG + fprintf(stderr, + "y value is larger than height 0x%x (%d) -- truncated\n", + char_index, char_id); +#endif + + trunc = 1; + return; + } +#endif /* BBOX_CLIP */ + + for (i = xbit1; i < xbit2; i++) { + line_of_bits[i] = 'X'; + } +} + +void +sp_close_bitmap() +{ + +#ifdef BBOX_CLIP + int i; + + if (!trunc) + dump_line(line_of_bits); + trunc = 0; + + + last_y++; + while (last_y < bit_height) { + +#ifdef DEBUG + fprintf(stderr, "padding out height for 0x%x (%d)\n", + char_index, char_id); +#endif + + for (i = 0; i < bit_width; i++) { + line_of_bits[i] = '.'; + } + dump_line(line_of_bits); + last_y++; + } + +#else + dump_line(line_of_bits); +#endif + + printf("ENDCHAR\n"); +} + +/* outline stubs */ +void +sp_open_outline() +{ +} + +void +sp_start_new_char() +{ +} + +void +sp_start_contour() +{ +} + +void +sp_curve_to() +{ +} + +void +sp_line_to() +{ +} + +void +sp_close_contour() +{ +} + +void +sp_close_outline() +{ +} diff --git a/nx-X11/lib/font/Speedo/useropt.h b/nx-X11/lib/font/Speedo/useropt.h new file mode 100644 index 000000000..e879aae96 --- /dev/null +++ b/nx-X11/lib/font/Speedo/useropt.h @@ -0,0 +1,41 @@ +/* $Xorg: useropt.h,v 1.4 2001/02/09 02:04:00 xorgcvs Exp $ */ +/* + +Copyright 1993, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + +*/ + +#define INCL_LCD 1 +#define STATIC_ALLOC 1 + +#define INCL_BLACK 1 +#define INCL_SCREEN 1 +#define INCL_2D 1 +#define SHORT_LISTS 0 + +#define INCL_RULES 1 +#define INCL_METRICS 1 + +#define INCL_KEYS 1 diff --git a/nx-X11/lib/font/Type1/AFM.h b/nx-X11/lib/font/Type1/AFM.h new file mode 100644 index 000000000..f2c997a3f --- /dev/null +++ b/nx-X11/lib/font/Type1/AFM.h @@ -0,0 +1,62 @@ +/* Copyright (c) 1994-1999 Silicon Graphics, Inc. All Rights Reserved. + * + * The contents of this file are subject to the CID Font Code Public Licence + * Version 1.0 (the "License"). You may not use this file except in compliance + * with the Licence. You may obtain a copy of the License at Silicon Graphics, + * Inc., attn: Legal Services, 2011 N. Shoreline Blvd., Mountain View, CA + * 94043 or at http://www.sgi.com/software/opensource/cid/license.html. + * + * Software distributed under the License is distributed on an "AS IS" basis. + * ALL WARRANTIES ARE DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED + * WARRANTIES OF MERCHANTABILITY, OF FITNESS FOR A PARTICULAR PURPOSE OR OF + * NON-INFRINGEMENT. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Software is CID font code that was developed by Silicon + * Graphics, Inc. + */ +#ifdef BUILDCID +#define XFONT_CID 1 +#endif + +#if XFONT_CID +#ifndef AFM_H +#define AFM_H + +/* Bounding box definition. Used for the Font BBox as well as the + * Character BBox. + */ +typedef struct +{ + int llx; /* lower left x-position */ + int lly; /* lower left y-position */ + int urx; /* upper right x-position */ + int ury; /* upper right y-position */ +} BBox; + +/* Character Metric Information. This structure is used only if ALL + * character metric information is requested. If only the character + * widths is requested, then only an array of the character x-widths + * is returned. + * + * The key that each field is associated with is in comments. For an + * explanation about each key and its value please refer to the + * Character Metrics section of the AFM documentation (full title + * & version given above). + */ +typedef struct +{ + long code; /* CID code */ + int wx; /* key: WX or W0X */ + BBox charBBox; /* key: B */ +} Metrics; + +typedef struct +{ + int nChars; /* number of entries in char metrics array */ + Metrics *metrics; /* ptr to char metrics array */ +} FontInfo; + +int CIDAFM(FILE *, FontInfo **); +#endif /* AFM_H */ +#endif diff --git a/nx-X11/lib/font/Type1/Imakefile b/nx-X11/lib/font/Type1/Imakefile new file mode 100644 index 000000000..3b10c0399 --- /dev/null +++ b/nx-X11/lib/font/Type1/Imakefile @@ -0,0 +1,91 @@ +XCOMM $Xorg: Imakefile,v 1.3 2000/08/17 19:46:28 cpqbld Exp $ + + + + +XCOMM $XFree86: xc/lib/font/Type1/Imakefile,v 1.12 2002/02/13 21:32:48 dawes Exp $ + +#if BuildServer && DoLoadableServer +#define IHaveSubdirs +#define NoLibSubdirs +#define PassCDebugFlags +SUBDIRS = module +#endif + +INCLUDES = -I$(FONTINCSRC) -I../include -I$(XINCLUDESRC) \ + -I$(SERVERSRC)/include + +#if BuildCID +CIDSRCS = cidchar.c afm.c +CIDOBJS = cidchar.o afm.o +#if HasUsableFileMmap +MMAPDEFINES = -DUSE_MMAP +#endif +DEFINES = -DBUILDCID -DHAVE_CFM $(MMAPDEFINES) +#endif + +SRCS = \ + arith.c \ + curves.c \ + fontfcn.c \ + hints.c \ + lines.c \ + objects.c \ + paths.c \ + regions.c \ + scanfont.c \ + spaces.c \ + t1funcs.c \ + t1info.c \ + t1io.c \ + t1malloc.c \ + t1snap.c \ + t1stub.c \ + token.c \ + type1.c \ + util.c \ + $(CIDSRCS) \ + t1unicode.c + + +OBJS = \ + arith.o \ + curves.o \ + fontfcn.o \ + hints.o \ + lines.o \ + objects.o \ + paths.o \ + regions.o \ + scanfont.o \ + spaces.o \ + t1funcs.o \ + t1info.o \ + t1io.o \ + t1malloc.o \ + t1snap.o \ + t1stub.o \ + token.o \ + type1.o \ + util.o \ + $(CIDOBJS) \ + t1unicode.o + +#if BuildFontLib +#define DoNormalLib NormalLibFont +#define DoSharedLib SharedLibFont +#define DoDebugLib DebugLibFont +#define DoProfileLib ProfileLibFont +#include <Library.tmpl> +LibraryObjectRule() + +SubdirLibraryRule($(OBJS)) +NormalLintTarget($(SRCS)) +#endif + +#if BuildServer && DoLoadableServer +MakeSubdirs($(SUBDIRS)) +DependSubdirs($(SUBDIRS)) +#endif + +DependTarget() diff --git a/nx-X11/lib/font/Type1/afm.c b/nx-X11/lib/font/Type1/afm.c new file mode 100644 index 000000000..9a6dafee7 --- /dev/null +++ b/nx-X11/lib/font/Type1/afm.c @@ -0,0 +1,200 @@ +/* Copyright (c) 1994-1999 Silicon Graphics, Inc. All Rights Reserved. + * + * The contents of this file are subject to the CID Font Code Public Licence + * Version 1.0 (the "License"). You may not use this file except in compliance + * with the Licence. You may obtain a copy of the License at Silicon Graphics, + * Inc., attn: Legal Services, 2011 N. Shoreline Blvd., Mountain View, CA + * 94043 or at http://www.sgi.com/software/opensource/cid/license.html. + * + * Software distributed under the License is distributed on an "AS IS" basis. + * ALL WARRANTIES ARE DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED + * WARRANTIES OF MERCHANTABILITY, OF FITNESS FOR A PARTICULAR PURPOSE OR OF + * NON-INFRINGEMENT. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Software is CID font code that was developed by Silicon + * Graphics, Inc. + */ +/* $XFree86: xc/lib/font/Type1/afm.c,v 1.2 1999/08/21 13:47:38 dawes Exp $ */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#ifdef BUILDCID +#define XFONT_CID 1 +#endif + +#ifdef XFONT_CID +#ifndef FONTMODULE +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <limits.h> +#else +#include "Xmd.h" /* For INT32 declaration */ +#include "Xdefs.h" /* For Bool */ +#include "xf86_ansic.h" +#endif +#include <X11/fonts/fontmisc.h> /* for xalloc/xfree */ +#include "AFM.h" + +#define PBUF 256 +#define KBUF 20 + +char *gettoken(FILE *); + +static char *afmbuf = NULL; + +char *gettoken(FILE *fd) { + char *bp; + int c, found; + + bp = afmbuf; + found = 0; + + while((c = getc(fd)) != EOF) { + if (found == 0 && (c == ' ' || c == '\t' || c == '\n' || c == '\r' || + c == ';' || c == ',')) continue; + found = 1; + if (c != ' ' && c != '\t' && c != '\n' && c != '\r' && c != ';') { + *bp++ = c; + if (bp - afmbuf >= PBUF) { + bp = afmbuf; + break; + } + } else + break; + } + + *bp = 0; + return(afmbuf); +} + +int CIDAFM(FILE *fd, FontInfo **pfi) { + char *p = 0; + int i, j, k = 0, found = 0; + FontInfo *fi; + + if (fd == NULL || pfi == NULL) return(1); + + *pfi = NULL; + + if ((afmbuf = (char *)xalloc(PBUF)) == NULL) + return(1); + + while(1) { + if (!(p = gettoken(fd))) { + xfree(afmbuf); + return(1); + } + + if (strncmp(p, "StartFontMetrics", 16) == 0) { + if (!(p = gettoken(fd))) { + xfree(afmbuf); + return(1); + } + if (strncmp(p, "4", 1) < 0) { + free(afmbuf); + return(1); + } + found = 1; + } else if (strncmp(p, "StartCharMetrics", 16) == 0) { + if (!found) { + xfree(afmbuf); + return(1); + } + + if (!(p = gettoken(fd))) { + xfree(afmbuf); + return(1); + } + + fi = (FontInfo *)xalloc(sizeof(FontInfo)); + + if (fi == NULL) { + xfree(afmbuf); + return(1); + } + bzero(fi, sizeof(FontInfo)); + + fi->nChars = atoi(p); + + if (fi->nChars < 0 || fi->nChars > INT_MAX / sizeof(Metrics)) { + xfree(afmbuf); + xfree(fi); + return(1); + } + fi->metrics = (Metrics *)xalloc(fi->nChars * + sizeof(Metrics)); + if (fi->metrics == NULL) { + xfree(afmbuf); + xfree(fi); + return(1); + } + + j = 0; + for (i = 0; i < fi->nChars; i++) { + k = 0; + while(1) { + if (!(p = gettoken(fd))) { + k = KBUF; + break; + } + if (strncmp(p, "W0X", 3) == 0) { + if (!(p = gettoken(fd))) { + k = KBUF; + break; + } + fi->metrics[j].wx = atoi(p); + } else if (strncmp(p, "N", 1) == 0) { + if (!(p = gettoken(fd))) { + k = KBUF; + break; + } + fi->metrics[j].code = (long)atoi(p); + } else if (strncmp(p, "B", 1) == 0) { + if (!(p = gettoken(fd))) { + k = KBUF; + break; + } + fi->metrics[j].charBBox.llx = atoi(p); + if (!(p = gettoken(fd))) { + k = KBUF; + break; + } + fi->metrics[j].charBBox.lly = atoi(p); + if (!(p = gettoken(fd))) { + k = KBUF; + break; + } + fi->metrics[j].charBBox.urx = atoi(p); + if (!(p = gettoken(fd))) { + k = KBUF; + break; + } + fi->metrics[j].charBBox.ury = atoi(p); + j++; + break; + } + k++; + if (k >= KBUF) break; + } + if (k >= KBUF) break; + } + if (k >= KBUF || j != fi->nChars) { + xfree(fi->metrics); + xfree(fi); + xfree(afmbuf); + return(1); + } else { + *pfi = fi; + xfree(afmbuf); + return(0); + } + } + } + + xfree(afmbuf); + return(1); +} +#endif diff --git a/nx-X11/lib/font/Type1/arith.c b/nx-X11/lib/font/Type1/arith.c new file mode 100644 index 000000000..961154335 --- /dev/null +++ b/nx-X11/lib/font/Type1/arith.c @@ -0,0 +1,486 @@ +/* $Xorg: arith.c,v 1.3 2000/08/17 19:46:29 cpqbld Exp $ */ +/* Copyright International Business Machines, Corp. 1991 + * All Rights Reserved + * Copyright Lexmark International, Inc. 1991 + * All Rights Reserved + * + * License to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, + * provided that the above copyright notice appear in all copies and that + * both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of IBM or Lexmark not be + * used in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * + * IBM AND LEXMARK PROVIDE THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES OF + * ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO ANY + * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, + * AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE + * QUALITY AND PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT + * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF THE + * SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM OR LEXMARK) ASSUMES THE + * ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN NO EVENT SHALL + * IBM OR LEXMARK BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF + * THIS SOFTWARE. + */ +/* $XFree86: xc/lib/font/Type1/arith.c,v 1.6tsi Exp $ */ + + /* ARITH CWEB V0006 ******** */ +/* +:h1.ARITH Module - Portable Module for Multiple Precision Fixed Point Arithmetic + +This module provides division and multiplication of 64-bit fixed point +numbers. (To be more precise, the module works on numbers that take +two 'longs' to store. That is almost always equivalent to saying 64-bit +numbers.) + +Note: it is frequently easy and desirable to recode these functions in +assembly language for the particular processor being used, because +assembly language, unlike C, will have 64-bit multiply products and +64-bit dividends. This module is offered as a portable version. + +&author. Jeffrey B. Lotspiech (lotspiech@almaden.ibm.com) and Sten F. Andler + + +:h3.Include Files + +The included files are: +*/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#ifdef FONTMODULE +# include "os.h" +#endif +#include "objects.h" +#include "spaces.h" +#include "arith.h" + + +/* +:h3. +*/ +/*SHARED LINE(S) ORIGINATED HERE*/ +/* +Reference for all algorithms: Donald E. Knuth, "The Art of Computer +Programming, Volume 2, Semi-Numerical Algorithms," Addison-Wesley Co., +Massachusetts, 1969, pp. 229-279. + +Knuth talks about a 'digit' being an arbitrary sized unit and a number +being a sequence of digits. We'll take a digit to be a 'short'. +The following assumption must be valid for these algorithms to work: +:ol. +:li.A 'long' is two 'short's. +:eol. +The following code is INDEPENDENT of: +:ol. +:li.The actual size of a short. +:li.Whether shorts and longs are stored most significant byte +first or least significant byte first. +:eol. + +SHORTSIZE is the number of bits in a short; LONGSIZE is the number of +bits in a long; MAXSHORT is the maximum unsigned short: +*/ +/*SHARED LINE(S) ORIGINATED HERE*/ +/* +ASSEMBLE concatenates two shorts to form a long: +*/ +#define ASSEMBLE(hi,lo) ((((unsigned long)hi)<<SHORTSIZE)+(lo)) +/* +HIGHDIGIT extracts the most significant short from a long; LOWDIGIT +extracts the least significant short from a long: +*/ +#define HIGHDIGIT(u) ((u)>>SHORTSIZE) +#define LOWDIGIT(u) ((u)&MAXSHORT) + +/* +SIGNBITON tests the high order bit of a long 'w': +*/ +#define SIGNBITON(w) (((long)w)<0) + +/*SHARED LINE(S) ORIGINATED HERE*/ + +/* +:h2.Double Long Arithmetic + +:h3.DLmult() - Multiply Two Longs to Yield a Double Long + +The two multiplicands must be positive. +*/ + +void +DLmult(doublelong *product, unsigned long u, unsigned long v) +{ +#ifdef LONG64 +/* printf("DLmult(? ?, %lx, %lx)\n", u, v); */ + *product = u*v; +/* printf("DLmult returns %lx\n", *product); */ +#else + register unsigned long u1, u2; /* the digits of u */ + register unsigned long v1, v2; /* the digits of v */ + register unsigned int w1, w2, w3, w4; /* the digits of w */ + register unsigned long t; /* temporary variable */ +/* printf("DLmult(? ?, %x, %x)\n", u, v); */ + u1 = HIGHDIGIT(u); + u2 = LOWDIGIT(u); + v1 = HIGHDIGIT(v); + v2 = LOWDIGIT(v); + + if (v2 == 0) w4 = w3 = w2 = 0; + else + { + t = u2 * v2; + w4 = LOWDIGIT(t); + t = u1 * v2 + HIGHDIGIT(t); + w3 = LOWDIGIT(t); + w2 = HIGHDIGIT(t); + } + + if (v1 == 0) w1 = 0; + else + { + t = u2 * v1 + w3; + w3 = LOWDIGIT(t); + t = u1 * v1 + w2 + HIGHDIGIT(t); + w2 = LOWDIGIT(t); + w1 = HIGHDIGIT(t); + } + + product->high = ASSEMBLE(w1, w2); + product->low = ASSEMBLE(w3, w4); +#endif /* LONG64 else */ +} + +/* +:h2.DLdiv() - Divide Two Longs by One Long, Yielding Two Longs + +Both the dividend and the divisor must be positive. +*/ + +void +DLdiv(doublelong *quotient, /* also where dividend is, originally */ + unsigned long divisor) +{ +#ifdef LONG64 +/* printf("DLdiv(%lx %lx)\n", quotient, divisor); */ + *quotient /= divisor; +/* printf("DLdiv returns %lx\n", *quotient); */ +#else + register unsigned long u1u2 = quotient->high; + register unsigned long u3u4 = quotient->low; + register long u3; /* single digit of dividend */ + register int v1,v2; /* divisor in registers */ + register long t; /* signed copy of u1u2 */ + register int qhat; /* guess at the quotient digit */ + register unsigned long q3q4; /* low two digits of quotient */ + register int shift; /* holds the shift value for normalizing */ + register int j; /* loop variable */ + +/* printf("DLdiv(%x %x, %x)\n", quotient->high, quotient->low, divisor); */ + /* + * Knuth's algorithm works if the dividend is smaller than the + * divisor. We can get to that state quickly: + */ + if (u1u2 >= divisor) { + quotient->high = u1u2 / divisor; + u1u2 %= divisor; + } + else + quotient->high = 0; + + if (divisor <= MAXSHORT) { + + /* + * This is the case where the divisor is contained in one + * 'short'. It is worthwhile making this fast: + */ + u1u2 = ASSEMBLE(u1u2, HIGHDIGIT(u3u4)); + q3q4 = u1u2 / divisor; + u1u2 %= divisor; + u1u2 = ASSEMBLE(u1u2, LOWDIGIT(u3u4)); + quotient->low = ASSEMBLE(q3q4, u1u2 / divisor); + return; + } + + + /* + * At this point the divisor is a true 'long' so we must use + * Knuth's algorithm. + * + * Step D1: Normalize divisor and dividend (this makes our 'qhat' + * guesses more accurate): + */ + for (shift=0; !SIGNBITON(divisor); shift++, divisor <<= 1) { ; } + shift--; + divisor >>= 1; + + if ((u1u2 >> (LONGSIZE - shift)) != 0 && shift != 0) + Abort("DLdiv: dividend too large"); + u1u2 = (u1u2 << shift) + ((shift == 0) ? 0 : u3u4 >> (LONGSIZE - shift)); + u3u4 <<= shift; + + /* + * Step D2: Begin Loop through digits, dividing u1,u2,u3 by v1,v2, + * then shifting U left by 1 digit: + */ + v1 = HIGHDIGIT(divisor); + v2 = LOWDIGIT(divisor); + q3q4 = 0; + u3 = HIGHDIGIT(u3u4); + + for (j=0; j < 2; j++) { + + /* + * Step D3: make a guess (qhat) at the next quotient denominator: + */ + qhat = (HIGHDIGIT(u1u2) == v1) ? MAXSHORT : u1u2 / v1; + /* + * At this point Knuth would have us further refine our + * guess, since we know qhat is too big if + * + * v2 * qhat > ASSEMBLE(u1u2 % v, u3) + * + * That would make sense if u1u2 % v was easy to find, as it + * would be in assembly language. I ignore this step, and + * repeat step D6 if qhat is too big. + */ + + /* + * Step D4: Multiply v1,v2 times qhat and subtract it from + * u1,u2,u3: + */ + u3 -= qhat * v2; + /* + * The high digit of u3 now contains the "borrow" for the + * rest of the substraction from u1,u2. + * Sometimes we can lose the sign bit with the above. + * If so, we have to force the high digit negative: + */ + t = HIGHDIGIT(u3); + if (t > 0) + t |= -1 << SHORTSIZE; + t += u1u2 - qhat * v1; +/* printf("..>divide step qhat=%x t=%x u3=%x u1u2=%x v1=%x v2=%x\n", + qhat, t, u3, u1u2, v1, v2); */ + while (t < 0) { /* Test is Step D5. */ + + /* + * D6: Oops, qhat was too big. Add back in v1,v2 and + * decrease qhat by 1: + */ + u3 = LOWDIGIT(u3) + v2; + t += HIGHDIGIT(u3) + v1; + qhat--; +/* printf("..>>qhat correction t=%x u3=%x qhat=%x\n", t, u3, qhat); */ + } + /* + * Step D7: shift U left one digit and loop: + */ + u1u2 = t; + if (HIGHDIGIT(u1u2) != 0) + Abort("divide algorithm error"); + u1u2 = ASSEMBLE(u1u2, LOWDIGIT(u3)); + u3 = LOWDIGIT(u3u4); + q3q4 = ASSEMBLE(q3q4, qhat); + } + quotient->low = q3q4; +/* printf("DLdiv returns %x %x\n", quotient->high, quotient->low); */ +#endif /* !LONG64 */ + return; +} + +/* +:h3.DLadd() - Add Two Double Longs + +In this case, the doublelongs may be signed. The algorithm takes the +piecewise sum of the high and low longs, with the possibility that the +high should be incremented if there is a carry out of the low. How to +tell if there is a carry? Alex Harbury suggested that if the sum of +the lows is less than the max of the lows, there must have been a +carry. Conversely, if there was a carry, the sum of the lows must be +less than the max of the lows. So, the test is "if and only if". +*/ + +void +DLadd(doublelong *u, /* u = u + v */ + doublelong *v) +{ +#ifdef LONG64 +/* printf("DLadd(%lx %lx)\n", *u, *v); */ + *u = *u + *v; +/* printf("DLadd returns %lx\n", *u); */ +#else + register unsigned long lowmax = MAX(u->low, v->low); + +/* printf("DLadd(%x %x, %x %x)\n", u->high, u->low, v->high, v->low); */ + u->high += v->high; + u->low += v->low; + if (lowmax > u->low) + u->high++; +#endif +} +/* +:h3.DLsub() - Subtract Two Double Longs + +Testing for a borrow is even easier. If the v.low is greater than +u.low, there must be a borrow. +*/ + +void +DLsub(doublelong *u, /* u = u - v */ + doublelong *v) +{ +#ifdef LONG64 +/* printf("DLsub(%lx %lx)\n", *u, *v); */ + *u = *u - *v; +/* printf("DLsub returns %lx\n", *u); */ +#else +/* printf("DLsub(%x %x, %x %x)\n", u->high, u->low, v->high, v->low);*/ + u->high -= v->high; + if (v->low > u->low) + u->high--; + u->low -= v->low; +#endif +} +/* +:h3.DLrightshift() - Macro to Shift Double Long Right by N +*/ + +/*SHARED LINE(S) ORIGINATED HERE*/ + +/* +:h2.Fractional Pel Arithmetic +*/ +/* +:h3.FPmult() - Multiply Two Fractional Pel Values + +This funtion first calculates w = u * v to "doublelong" precision. +It then shifts w right by FRACTBITS bits, and checks that no +overflow will occur when the resulting value is passed back as +a fractpel. +*/ + +fractpel +FPmult(fractpel u, fractpel v) +{ + doublelong w; + register int negative = FALSE; /* sign flag */ +#ifdef LONG64 + register fractpel ret; +#endif + + if ((u == 0) || (v == 0)) return (0); + + + if (u < 0) {u = -u; negative = TRUE;} + if (v < 0) {v = -v; negative = !negative;} + + if (u == TOFRACTPEL(1)) return ((negative) ? -v : v); + if (v == TOFRACTPEL(1)) return ((negative) ? -u : u); + + DLmult(&w, u, v); + DLrightshift(w, FRACTBITS); +#ifndef LONG64 + if (w.high != 0 || SIGNBITON(w.low)) { + w.low = TOFRACTPEL(MAXSHORT); + } + + return ((negative) ? -w.low : w.low); +#else + if (w & 0xffffffff80000000L ) { + ret = TOFRACTPEL(MAXSHORT); + } + else + ret = (fractpel)w; + + return ((negative) ? -ret : ret); +#endif +} + +/* +:h3.FPdiv() - Divide Two Fractional Pel Values + +These values may be signed. The function returns the quotient. +*/ + +fractpel +FPdiv(fractpel dividend, fractpel divisor) +{ + doublelong w; /* result will be built here */ + int negative = FALSE; /* flag for sign bit */ +#ifdef LONG64 + register fractpel ret; +#endif + + if (dividend < 0) { + dividend = -dividend; + negative = TRUE; + } + if (divisor < 0) { + divisor = -divisor; + negative = !negative; + } +#ifndef LONG64 + w.low = dividend << FRACTBITS; + w.high = dividend >> (LONGSIZE - FRACTBITS); + DLdiv(&w, divisor); + if (w.high != 0 || SIGNBITON(w.low)) { + w.low = TOFRACTPEL(MAXSHORT); + } + return( (negative) ? -w.low : w.low); +#else + w = ((long)dividend) << FRACTBITS; + DLdiv(&w, divisor); + if (w & 0xffffffff80000000L ) { + ret = TOFRACTPEL(MAXSHORT); + } + else + ret = (fractpel)w; + return( (negative) ? -ret : ret); +#endif +} + +/* +:h3.FPstarslash() - Multiply then Divide + +Borrowing a chapter from the language Forth, it is useful to define +an operator that first multiplies by one constant then divides by +another, keeping the intermediate result in extended precision. +*/ + +fractpel +FPstarslash(fractpel a, /* result = a * b / c */ + fractpel b, + fractpel c) +{ + doublelong w; /* result will be built here */ + int negative = FALSE; +#ifdef LONG64 + register fractpel ret; +#endif + + if (a < 0) { a = -a; negative = TRUE; } + if (b < 0) { b = -b; negative = !negative; } + if (c < 0) { c = -c; negative = !negative; } + + DLmult(&w, a, b); + DLdiv(&w, c); +#ifndef LONG64 + if (w.high != 0 || SIGNBITON(w.low)) { + w.low = TOFRACTPEL(MAXSHORT); + } + return((negative) ? -w.low : w.low); +#else + if (w & 0xffffffff80000000L ) { + ret = TOFRACTPEL(MAXSHORT); + } + else + ret = (fractpel)w; + return( (negative) ? -ret : ret); +#endif +} diff --git a/nx-X11/lib/font/Type1/arith.h b/nx-X11/lib/font/Type1/arith.h new file mode 100644 index 000000000..6c810b946 --- /dev/null +++ b/nx-X11/lib/font/Type1/arith.h @@ -0,0 +1,77 @@ +/* $Xorg: arith.h,v 1.3 2000/08/17 19:46:29 cpqbld Exp $ */ +/* Copyright International Business Machines, Corp. 1991 + * All Rights Reserved + * Copyright Lexmark International, Inc. 1991 + * All Rights Reserved + * + * License to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, + * provided that the above copyright notice appear in all copies and that + * both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of IBM or Lexmark not be + * used in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * + * IBM AND LEXMARK PROVIDE THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES OF + * ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO ANY + * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, + * AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE + * QUALITY AND PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT + * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF THE + * SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM OR LEXMARK) ASSUMES THE + * ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN NO EVENT SHALL + * IBM OR LEXMARK BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF + * THIS SOFTWARE. + */ +/* $XFree86: xc/lib/font/Type1/arith.h,v 1.4 1999/08/21 13:47:39 dawes Exp $ */ + +/*SHARED*/ + +#include <X11/Xmd.h> /* LONG64 */ + +/*END SHARED*/ +/*SHARED*/ + +#undef SHORTSIZE +#define SHORTSIZE (sizeof(short)*8) +#undef LONGSIZE +#define LONGSIZE (SHORTSIZE*2) +#undef MAXSHORT +#define MAXSHORT ((1<<SHORTSIZE)-1) + +/*END SHARED*/ +/*SHARED*/ + +#ifdef LONG64 +typedef long doublelong; +#else +typedef struct { + long high; + unsigned long low; +} doublelong; +#endif /* LONG64 else */ + +/*END SHARED*/ +/*SHARED*/ + +#ifdef LONG64 +#define DLrightshift(dl,N) ((dl) >>= (N)) +#else +#define DLrightshift(dl,N) { \ + dl.low = (dl.low >> N) + (((unsigned long) dl.high) << (LONGSIZE - N)); \ + dl.high >>= N; \ +} +#endif + +extern void DLmult ( doublelong *product, unsigned long u, unsigned long v ); +extern void DLdiv ( doublelong *quotient, unsigned long divisor ); +extern void DLadd ( doublelong *u, doublelong *v ); +extern void DLsub ( doublelong *u, doublelong *v ); +extern fractpel FPmult ( fractpel u, fractpel v ); +extern fractpel FPdiv ( fractpel dividend, fractpel divisor ); +extern fractpel FPstarslash ( fractpel a, fractpel b, fractpel c ); + +/*END SHARED*/ diff --git a/nx-X11/lib/font/Type1/blues.h b/nx-X11/lib/font/Type1/blues.h new file mode 100644 index 000000000..88602f79e --- /dev/null +++ b/nx-X11/lib/font/Type1/blues.h @@ -0,0 +1,95 @@ +/* $Xorg: blues.h,v 1.3 2000/08/17 19:46:29 cpqbld Exp $ */ +/* Copyright International Business Machines, Corp. 1991 + * All Rights Reserved + * Copyright Lexmark International, Inc. 1991 + * All Rights Reserved + * Portions Copyright (c) 1990 Adobe Systems Incorporated. + * All Rights Reserved + * + * License to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, + * provided that the above copyright notice appear in all copies and that + * both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of IBM or Lexmark or Adobe + * not be used in advertising or publicity pertaining to distribution of + * the software without specific, written prior permission. + * + * IBM, LEXMARK, AND ADOBE PROVIDE THIS SOFTWARE "AS IS", WITHOUT ANY + * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT + * LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE, AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. THE + * ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE, INCLUDING + * ANY DUTY TO SUPPORT OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY + * PORTION OF THE SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM, + * LEXMARK, OR ADOBE) ASSUMES THE ENTIRE COST OF ALL SERVICING, REPAIR AND + * CORRECTION. IN NO EVENT SHALL IBM, LEXMARK, OR ADOBE BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +/* $XFree86: xc/lib/font/Type1/blues.h,v 1.3 1999/08/22 08:58:49 dawes Exp $ */ + + +extern psobj *GetType1CharString ( psfont *fontP, unsigned char code ); + +#define TOPLEFT 1 +#define BOTTOMRIGHT 2 + +#define NUMBLUEVALUES 14 +#define NUMOTHERBLUES 10 +#define NUMFAMILYBLUES 14 +#define NUMFAMILYOTHERBLUES 10 +#define NUMSTEMSNAPH 12 +#define NUMSTEMSNAPV 12 +#define NUMSTDHW 1 +#define NUMSTDVW 1 + +#define DEFAULTBOLDSTEMWIDTH 2.0 + +#define MAXALIGNMENTZONES ((NUMBLUEVALUES+NUMOTHERBLUES)/2) +#define DEFAULTBLUESCALE 0.039625 +#define DEFAULTBLUESHIFT 7 +#define DEFAULTBLUEFUZZ 1 +#define DEFAULTSTDHW 0 +#define DEFAULTSTDVW 0 +#define DEFAULTFORCEBOLD FALSE +#define DEFAULTLANGUAGEGROUP 0 +#define DEFAULTRNDSTEMUP FALSE +#define DEFAULTLENIV 4 +#define DEFAULTEXPANSIONFACTOR 0.06 + +/* see Type 1 Font Format book for explanations of these values */ +/* Note that we're currently doing nothing for minfeature and password. */ +struct blues_struct { + struct blues_struct *next; /* ptr to next Blues structure in list */ + int numBlueValues; /* # of BlueValues in following array */ + int BlueValues[NUMBLUEVALUES]; + int numOtherBlues; /* # of OtherBlues values in following array */ + int OtherBlues[NUMOTHERBLUES]; + int numFamilyBlues; /* # of FamilyBlues values in following array */ + int FamilyBlues[NUMFAMILYBLUES]; + int numFamilyOtherBlues; /* # of FamilyOtherBlues values in */ + int FamilyOtherBlues[NUMFAMILYOTHERBLUES]; /* this array */ + double BlueScale; + int BlueShift; + int BlueFuzz; + double StdHW; + double StdVW; + int numStemSnapH; /* # of StemSnapH values in following array */ + double StemSnapH[NUMSTEMSNAPH]; + int numStemSnapV; /* # of StemSnapV values in following array */ + double StemSnapV[NUMSTEMSNAPV]; + int ForceBold; + int LanguageGroup; + int RndStemUp; + int lenIV; + double ExpansionFactor; +}; + +/* the alignment zone structure -- somewhat similar to the stem structure */ +/* see Adobe Type1 Font Format book about the terms used in this structure */ +struct alignmentzone { + int topzone; /* TRUE if a topzone, FALSE if a bottom zone */ + double bottomy, topy; /* interval of this alignment zone */ +}; diff --git a/nx-X11/lib/font/Type1/cidchar.c b/nx-X11/lib/font/Type1/cidchar.c new file mode 100644 index 000000000..20d26650c --- /dev/null +++ b/nx-X11/lib/font/Type1/cidchar.c @@ -0,0 +1,621 @@ +/* Copyright (c) 1994-1999 Silicon Graphics, Inc. All Rights Reserved. + * + * The contents of this file are subject to the CID Font Code Public Licence + * Version 1.0 (the "License"). You may not use this file except in compliance + * with the Licence. You may obtain a copy of the License at Silicon Graphics, + * Inc., attn: Legal Services, 2011 N. Shoreline Blvd., Mountain View, CA + * 94043 or at http://www.sgi.com/software/opensource/cid/license.html. + * + * Software distributed under the License is distributed on an "AS IS" basis. + * ALL WARRANTIES ARE DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED + * WARRANTIES OF MERCHANTABILITY, OF FITNESS FOR A PARTICULAR PURPOSE OR OF + * NON-INFRINGEMENT. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Software is CID font code that was developed by Silicon + * Graphics, Inc. + */ +/* $XFree86: xc/lib/font/Type1/cidchar.c,v 1.9tsi Exp $ */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#ifdef BUILDCID +#define XFONT_CID 1 +#endif + +#if XFONT_CID +#ifndef FONTMODULE +#include <stdio.h> +#include <string.h> +#include <sys/stat.h> +#ifdef USE_MMAP +#include <sys/mman.h> +#ifndef MAP_FAILED +#define MAP_FAILED ((caddr_t)(-1)) +#endif +#endif +#else +#include "Xmd.h" /* For INT32 declaration */ +#include "Xdefs.h" /* For Bool */ +#include "xf86_ansic.h" +#endif +#ifndef FONTMODULE +#ifdef _XOPEN_SOURCE +#include <math.h> +#else +#define _XOPEN_SOURCE +#include <math.h> +#undef _XOPEN_SOURCE +#endif +#endif +#include <X11/fonts/fntfilst.h> +#include "objects.h" +#include "spaces.h" +#include "range.h" +#include "util.h" +#include "fontfcn.h" +#include "blues.h" +#include "AFM.h" +#include "t1intf.h" + +#define BSIZE 4096 + +extern cidfont *CIDFontP; +extern psfont *FDArrayP; +extern psfont *FontP; + +static unsigned char sd[] = "StartData"; + +CharInfoPtr +CIDGetGlyphInfo(FontPtr pFont, unsigned int cidcode, CharInfoPtr pci, int *rc) +{ + CharInfoPtr cp = NULL; +#ifdef USE_MMAP + int fd; + unsigned char *buf; + long total_len = 0; +#else + FILE *fp; + unsigned char buf[BSIZE]; + unsigned int count = 0; +#endif + cidglyphs *cid; + unsigned char *p1 = NULL; +#ifndef USE_MMAP + unsigned char *p2; +#endif + register int i = 0, j; + long byteoffset; + int FDindex, FDBytes, GDBytes, SDBytes, SubrCount, CIDMapOffset, len; + psobj *arrayP; + psobj charstring; + long *subroffsets = NULL, cstringoffset, nextcstringoffset; + struct blues_struct *blues; + + cid = (cidglyphs *)pFont->fontPrivate; + +#ifdef USE_MMAP + if (!cid->CIDdata) { + if (!(fd = open(cid->CIDFontName, O_RDONLY, 0))) { + *rc = BadFontName; + return(cp); + } + cid->CIDsize = lseek(fd, 0, SEEK_END); + cid->CIDdata = (unsigned char *) + mmap(0, (size_t)cid->CIDsize, PROT_READ, MAP_SHARED, fd, 0); + close(fd); + if (cid->CIDdata == (unsigned char *)MAP_FAILED) { + *rc = AllocError; + cid->CIDdata = NULL; + return (cp); + } + } +#else + if (!(fp = fopen(cid->CIDFontName,"rb"))) { + *rc = BadFontName; + return(cp); + } +#endif + +#ifdef USE_MMAP + if (cid->dataoffset == 0) { + if ((p1 = (unsigned char *)strstr((char *)cid->CIDdata, (char *)sd)) + != NULL) { + cid->dataoffset = (p1 - cid->CIDdata) + strlen((char *)sd); + } + else { + *rc = BadFontFormat; + return(cp); + } + } +#else /* USE_MMAP */ + if (cid->dataoffset == 0) { + p2 = sd; + + /* find "StartData" */ + while (*p2) { + cid->dataoffset += count; + if ((count = fread(buf, 1, BSIZE, fp)) == 0) + break; + p1 = buf; + for (i=0; i < count && *p2; i++) { + if (*p1 == *p2) + p2++; + else { + p2 = sd; + if (*p1 == *p2) + p2++; + } + p1++; + } + } + + /* if "StartData" not found, or end of file */ + if (*p2 || count == 0) { + *rc = BadFontFormat; + fclose(fp); + return(cp); + } + + if (i >= count) { + cid->dataoffset += count; + count = fread(buf, 1, BSIZE, fp); + p1 = buf; + } else { + cid->dataoffset += p1 - buf; + count = count - (p1 - buf); + } + } else { + if (fseek(fp, cid->dataoffset, SEEK_SET)) { + *rc = BadFontFormat; + fclose(fp); + return(cp); + } + if ((count = fread(buf, 1, BSIZE, fp)) == 0) { + *rc = BadFontFormat; + fclose(fp); + return(cp); + } + p1 = buf; + } + + /* if "StartData" not found, or "Binary" data and the next character */ + /* is not the space character (0x20) */ + + if (count == 0 || (CIDFontP->binarydata && (*p1 != ' '))) { + *rc = BadFontFormat; + fclose(fp); + return(cp); + } +#endif /* USE_MMAP */ + + FDBytes = CIDFontP->CIDfontInfoP[CIDFDBYTES].value.data.integer; + GDBytes = CIDFontP->CIDfontInfoP[CIDGDBYTES].value.data.integer; + CIDMapOffset = CIDFontP->CIDfontInfoP[CIDMAPOFFSET].value.data.integer; + byteoffset = cid->dataoffset + 1 + CIDMapOffset + + cidcode * (FDBytes + GDBytes); +#ifdef USE_MMAP + buf = &cid->CIDdata[byteoffset]; +#else + if (fseek(fp, byteoffset, SEEK_SET)) { + *rc = BadFontFormat; + fclose(fp); + return(cp); + } + if ((count = fread(buf, 1, BSIZE, fp)) < 2*(FDBytes + GDBytes)) { + *rc = BadFontFormat; + fclose(fp); + return(cp); + } +#endif + + /* if FDBytes is equal to 0, the CIDMap contains no FD indices, and the */ + /* FD index of 0 is assumed. */ + if (FDBytes == 0) + FDindex = 0; + else { + FDindex = 0; + for (i = 0; i < FDBytes; i++) + FDindex += (unsigned char)buf[i] << (8 * (FDBytes - 1 - i)); + } + + if (FDindex >= CIDFontP->CIDfontInfoP[CIDFDARRAY].value.len) { + *rc = BadFontFormat; +#ifndef USE_MMAP + fclose(fp); +#endif + return(cp); + } + + cstringoffset = 0; + for (i = 0; i < GDBytes; i++) + cstringoffset += (unsigned char)buf[FDBytes + i] << + (8 * (GDBytes - 1 - i)); + + nextcstringoffset = 0; + for (i = 0; i < GDBytes; i++) + nextcstringoffset += (unsigned char)buf[2*FDBytes + GDBytes + i] << + (8 * (GDBytes - 1 - i)); + + len = nextcstringoffset - cstringoffset; + + if (len <= 0) { /* empty interval, missing glyph */ + *rc = BadFontFormat; +#ifndef USE_MMAP + fclose(fp); +#endif + return(cp); + } + + FontP = &FDArrayP[FDindex]; + + charstring.type = OBJ_INTEGER; + charstring.len = len; + +#ifndef USE_MMAP + if (!(charstring.data.stringP = (unsigned char *)xalloc(len))) { + *rc = AllocError; + fclose(fp); + return(cp); + } +#endif + + byteoffset = cid->dataoffset + 1 + cstringoffset; + +#ifdef USE_MMAP + charstring.data.stringP = &cid->CIDdata[byteoffset]; +#else + if (fseek(fp, byteoffset, SEEK_SET)) { + *rc = BadFontFormat; + xfree(charstring.data.stringP); + fclose(fp); + return(cp); + } + + if ((count = fread(charstring.data.stringP, 1, len, fp)) != len) { + *rc = BadFontFormat; + xfree(charstring.data.stringP); + fclose(fp); + return(cp); + } +#endif + + if (FontP->Subrs.data.arrayP == NULL) { + /* get subroutine data */ + byteoffset = cid->dataoffset + 1 + + FDArrayP[FDindex].Private[CIDT1SUBMAPOFF].value.data.integer; + + SDBytes = FDArrayP[FDindex].Private[CIDT1SDBYTES].value.data.integer; + + SubrCount = FDArrayP[FDindex].Private[CIDT1SUBRCNT].value.data.integer; +#ifdef USE_MMAP + buf = &cid->CIDdata[byteoffset]; +#else + if (fseek(fp, byteoffset, SEEK_SET)) { + *rc = BadFontFormat; + fclose(fp); + return(cp); + } + + if ((count = fread(buf, 1, BSIZE, fp)) < SDBytes * (SubrCount + 1)) { + *rc = BadFontFormat; + fclose(fp); + return(cp); + } +#endif + + arrayP = (psobj *)vm_alloc(SubrCount*sizeof(psobj)); + if (!arrayP) { + *rc = AllocError; +#ifndef USE_MMAP + fclose(fp); +#endif + return(cp); + } + + if (!(subroffsets = (long *)xalloc((SubrCount + 1)*sizeof(long)))) { + *rc = AllocError; +#ifndef USE_MMAP + fclose(fp); +#endif + return(cp); + } + + for (i = 0; i <= SubrCount; i++) { + subroffsets[i] = 0; + for (j = 0; j < SDBytes; j++) + subroffsets[i] += (unsigned char)buf[i * SDBytes + j] << + (8 * (SDBytes - 1 - j)); + } + + byteoffset = cid->dataoffset + 1 + subroffsets[0]; + + /* get subroutine info */ +#ifndef USE_MMAP + if (fseek(fp, byteoffset, SEEK_SET)) { + *rc = BadFontFormat; + xfree(subroffsets); + fclose(fp); + return(cp); + } +#else + total_len = byteoffset; +#endif + for (i = 0; i < SubrCount; i++) { + len = subroffsets[i + 1] - subroffsets[i]; +#ifndef USE_MMAP + arrayP[i].data.valueP = vm_alloc(len); + if (!arrayP[i].data.valueP) { + *rc = AllocError; + xfree(subroffsets); + fclose(fp); + return(cp); + } +#endif + arrayP[i].len = len; +#ifdef USE_MMAP + arrayP[i].data.valueP = (char *)&cid->CIDdata[total_len]; + total_len += len; +#else + if ((count = fread(arrayP[i].data.valueP, 1, len, fp)) != len) { + *rc = BadFontFormat; + xfree(subroffsets); + fclose(fp); + return(cp); + } +#endif + } + + FontP->Subrs.len = SubrCount; + FontP->Subrs.data.arrayP = arrayP; + xfree(subroffsets); + } + + if (FontP->BluesP == NULL) { + blues = (struct blues_struct *) vm_alloc(sizeof(struct blues_struct)); + if (!blues) { + *rc = AllocError; +#ifndef USE_MMAP + xfree(subroffsets); + fclose(fp); +#endif + return(cp); + } + bzero(blues, sizeof(struct blues_struct)); + blues->numBlueValues = + FDArrayP[FDindex].Private[CIDT1BLUEVALUES].value.len; + for (i = 0; i < blues->numBlueValues; i++) + blues->BlueValues[i] = + FDArrayP[FDindex].Private[CIDT1BLUEVALUES].value.data.arrayP[i].data.integer; + blues->numOtherBlues = + FDArrayP[FDindex].Private[CIDT1OTHERBLUES].value.len; + for (i = 0; i < blues->numOtherBlues; i++) + blues->OtherBlues[i] = + FDArrayP[FDindex].Private[CIDT1OTHERBLUES].value.data.arrayP[i].data.integer; + blues->numFamilyBlues = + FDArrayP[FDindex].Private[CIDT1FAMBLUES].value.len; + for (i = 0; i < blues->numFamilyBlues; i++) + blues->FamilyBlues[i] = + FDArrayP[FDindex].Private[CIDT1FAMBLUES].value.data.arrayP[i].data.integer; + blues->numFamilyOtherBlues = + FDArrayP[FDindex].Private[CIDT1FAMOTHERBLUES].value.len; + for (i = 0; i < blues->numFamilyOtherBlues; i++) + blues->FamilyOtherBlues[i] = + FDArrayP[FDindex].Private[CIDT1FAMOTHERBLUES].value.data.arrayP[i].data.integer; + blues->BlueScale = FDArrayP[FDindex].Private[CIDT1BLUESCALE].value.data.real; + blues->BlueShift = FDArrayP[FDindex].Private[CIDT1BLUESHIFT].value.data.integer; + blues->BlueFuzz = FDArrayP[FDindex].Private[CIDT1BLUEFUZZ].value.data.integer; + blues->StdHW = (double)FDArrayP[FDindex].Private[CIDT1STDHW].value.data.arrayP[0].data.integer; + blues->StdVW = (double)FDArrayP[FDindex].Private[CIDT1STDVW].value.data.arrayP[0].data.integer; + + blues->numStemSnapH = + FDArrayP[FDindex].Private[CIDT1STEMSNAPH].value.len; + for (i = 0; i < blues->numStemSnapH; i++) + blues->StemSnapH[i] = + FDArrayP[FDindex].Private[CIDT1STEMSNAPH].value.data.arrayP[i].data.integer; + blues->numStemSnapV = + FDArrayP[FDindex].Private[CIDT1STEMSNAPV].value.len; + for (i = 0; i < blues->numStemSnapV; i++) + blues->StemSnapV[i] = + FDArrayP[FDindex].Private[CIDT1STEMSNAPV].value.data.arrayP[i].data.integer; + blues->ForceBold = + FDArrayP[FDindex].Private[CIDT1FORCEBOLD].value.data.boolean; + + blues->LanguageGroup = + FDArrayP[FDindex].Private[CIDT1LANGGROUP].value.data.integer; + + blues->RndStemUp = + FDArrayP[FDindex].Private[CIDT1RNDSTEMUP].value.data.boolean; + + blues->lenIV = + FDArrayP[FDindex].Private[CIDT1LENIV].value.data.integer; + + blues->ExpansionFactor = + FDArrayP[FDindex].Private[CIDT1EXPFACTOR].value.data.real; + + FontP->BluesP = blues; + } + + cp = CIDRenderGlyph(pFont, &charstring, &FontP->Subrs, FontP->BluesP, pci, rc); + +#ifndef USE_MMAP + xfree(charstring.data.stringP); + + fclose(fp); +#endif + return(cp); +} + +static int +node_compare(const void *node1, const void *node2) +{ + return (((Metrics *)node1)->code - ((Metrics *)node2)->code); +} + +static CharInfoRec * +CIDGetCharMetrics(FontPtr pFont, FontInfo *fi, unsigned int charcode, double sxmult) +{ + CharInfoPtr cp; + Metrics *p, node; + unsigned int cidcode; + + cidcode = node.code = getCID(pFont, charcode); + if ((cidcode < fi->nChars) && (cidcode == fi->metrics[cidcode].code)) + p = &fi->metrics[cidcode]; + else + p = (Metrics *)bsearch(&node, fi->metrics, fi->nChars, sizeof(Metrics), node_compare); + + if (!p) + p = &fi->metrics[0]; + + if (!(cp = (CharInfoRec *)Xalloc(sizeof(CharInfoRec)))) + return NULL; + bzero(cp, sizeof(CharInfoRec)); + + /* indicate that character bitmap is not defined */ + cp->bits = (char *)CID_BITMAP_UNDEFINED; + + + /* get metric data for this CID code from the CID AFM file */ + cp->metrics.leftSideBearing = + floor(p->charBBox.llx / sxmult + 0.5); + cp->metrics.rightSideBearing = + floor(p->charBBox.urx / sxmult + 0.5); + cp->metrics.characterWidth = floor(p->wx / sxmult + 0.5); + cp->metrics.ascent = floor(p->charBBox.ury / sxmult + 0.5); + cp->metrics.descent = -floor(p->charBBox.lly / sxmult + 0.5); + + cp->metrics.attributes = p->wx; + + return cp; +} + +int +CIDGetAFM(FontPtr pFont, unsigned long count, unsigned char *chars, FontEncoding charEncoding, unsigned long *glyphCount, CharInfoPtr *glyphs, char *cidafmfile) +{ + FILE *fp; + FontInfo *fi = NULL; + cidglyphs *cid; + CharInfoPtr *glyphsBase; + register unsigned int c; + + register CharInfoPtr pci; + CharInfoPtr pDefault; + unsigned int firstCol, code, char_row, char_col; + double sxmult; + + cid = (cidglyphs *)pFont->fontPrivate; + + if (cid->AFMinfo == NULL) { + if (!(fp = fopen(cidafmfile, "rb"))) + return(BadFontName); + + if (CIDAFM(fp, &fi) != 0) { + fprintf(stderr, + "There is something wrong with Adobe Font Metric file %s.\n", + cidafmfile); + fclose(fp); + return(BadFontName); + } + fclose(fp); + cid->AFMinfo = fi; + } + fi = cid->AFMinfo; + + firstCol = pFont->info.firstCol; + pDefault = cid->pDefault; + glyphsBase = glyphs; + + /* multiplier for computation of raw values */ + sxmult = hypot(cid->pixel_matrix[0], cid->pixel_matrix[1]); + if (sxmult > EPS) sxmult = 1000.0 / sxmult; + if (sxmult == 0.0) return(0); + + switch (charEncoding) { + +#define EXIST(pci) \ + ((pci)->metrics.attributes || \ + (pci)->metrics.ascent != -(pci)->metrics.descent || \ + (pci)->metrics.leftSideBearing != (pci)->metrics.rightSideBearing) + + case Linear8Bit: + case TwoD8Bit: + if (pFont->info.firstRow > 0) + break; + while (count--) { + c = (*chars++); + if (c >= firstCol && c <= pFont->info.lastCol) { + code = c - firstCol; + if (!(pci = (CharInfoRec *)cid->glyphs[code])) + pci = CIDGetCharMetrics(pFont, fi, c, sxmult); + if (pci && EXIST(pci)) { + *glyphs++ = pci; + cid->glyphs[code] = pci; + } + } else if (pDefault) + *glyphs++ = pDefault; + } + break; + case Linear16Bit: + while (count--) { + char_row = *chars++; + char_col = *chars++; + c = char_row << 8; + c = (c | char_col); + if (pFont->info.firstRow <= char_row && char_row <= + pFont->info.lastRow && pFont->info.firstCol <= char_col && + char_col <= pFont->info.lastCol) { + code = pFont->info.lastCol - pFont->info.firstCol + 1; + char_row = char_row - pFont->info.firstRow; + char_col = char_col - pFont->info.firstCol; + code = char_row * code + char_col; + if (!(pci = (CharInfoRec *)cid->glyphs[code])) + pci = CIDGetCharMetrics(pFont, fi, c, sxmult); + if (pci && EXIST(pci)) { + *glyphs++ = pci; + cid->glyphs[code] = pci; + } else if (pDefault) { + *glyphs++ = pDefault; + cid->glyphs[code] = pDefault; + } + } else if (pDefault) + *glyphs++ = pDefault; + } + break; + + case TwoD16Bit: + while (count--) { + char_row = (*chars++); + char_col = (*chars++); + c = char_row << 8; + c = (c | char_col); + if (pFont->info.firstRow <= char_row && char_row <= + pFont->info.lastRow && pFont->info.firstCol <= char_col && + char_col <= pFont->info.lastCol) { + code = pFont->info.lastCol - pFont->info.firstCol + 1; + char_row = char_row - pFont->info.firstRow; + char_col = char_col - pFont->info.firstCol; + code = char_row * code + char_col; + if (!(pci = (CharInfoRec *)cid->glyphs[code])) + pci = CIDGetCharMetrics(pFont, fi, c, sxmult); + if (pci && EXIST(pci)) { + *glyphs++ = pci; + cid->glyphs[code] = pci; + } else if (pDefault) { + *glyphs++ = pDefault; + cid->glyphs[code] = pDefault; + } + } else if (pDefault) + *glyphs++ = pDefault; + } + break; + } + *glyphCount = glyphs - glyphsBase; + +#undef EXIST + + return Successful; + +} +#endif diff --git a/nx-X11/lib/font/Type1/cluts.h b/nx-X11/lib/font/Type1/cluts.h new file mode 100644 index 000000000..67d930324 --- /dev/null +++ b/nx-X11/lib/font/Type1/cluts.h @@ -0,0 +1,35 @@ +/* $Xorg: cluts.h,v 1.3 2000/08/17 19:46:29 cpqbld Exp $ */ +/* Copyright International Business Machines,Corp. 1991 + * All Rights Reserved + * + * License to use, copy, modify, and distribute this software + * and its documentation for any purpose and without fee is + * hereby granted, provided that the above copyright notice + * appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, + * and that the name of IBM not be used in advertising or + * publicity pertaining to distribution of the software without + * specific, written prior permission. + * + * IBM PROVIDES THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES + * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT + * LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE QUALITY AND + * PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT + * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF + * THE SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM) ASSUMES + * THE ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN + * NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ +/* STUB */ + +#define KillCLUT(T) +#define CopyCLUT(T) T +#define UniqueCLUT(T) + diff --git a/nx-X11/lib/font/Type1/curves.c b/nx-X11/lib/font/Type1/curves.c new file mode 100644 index 000000000..9d0c3f8cc --- /dev/null +++ b/nx-X11/lib/font/Type1/curves.c @@ -0,0 +1,228 @@ +/* $Xorg: curves.c,v 1.3 2000/08/17 19:46:29 cpqbld Exp $ */ +/* Copyright International Business Machines,Corp. 1991 */ +/* All Rights Reserved */ + +/* License to use, copy, modify, and distribute this software */ +/* and its documentation for any purpose and without fee is */ +/* hereby granted, provided that licensee provides a license to */ +/* IBM, Corp. to use, copy, modify, and distribute derivative */ +/* works and their documentation for any purpose and without */ +/* fee, that the above copyright notice appear in all copies */ +/* and that both that copyright notice and this permission */ +/* notice appear in supporting documentation, and that the name */ +/* of IBM not be used in advertising or publicity pertaining to */ +/* distribution of the software without specific, written prior */ +/* permission. */ + +/* IBM PROVIDES THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES */ +/* OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT */ +/* LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY, */ +/* FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT OF */ +/* THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE QUALITY AND */ +/* PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT */ +/* OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF */ +/* THE SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM) ASSUMES */ +/* THE ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN */ +/* NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR */ +/* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING */ +/* FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF */ +/* CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT */ +/* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS */ +/* SOFTWARE. */ +/* $XFree86: xc/lib/font/Type1/curves.c,v 1.7 2001/08/27 19:49:52 dawes Exp $ */ + +/* +:h1.CURVES Module - Stepping Beziers + +This module is responsible for "rasterizing" +third order curves. That is, it changes the high level curve +specification into a list of pels that that curve travels +through. + +:h3.Include Files + +Include files needed: +*/ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#ifdef FONTMODULE +# include "os.h" +#endif +#include "objects.h" +#include "spaces.h" +#include "paths.h" +#include "regions.h" +#include "curves.h" +#include "lines.h" +#include "arith.h" + + +/* +:h3.Functions Provided to Other Modules + +External entry points: +*/ +/*SHARED LINE(S) ORIGINATED HERE*/ + +/* +Note that "stepping" and "flattening" are so similiar that they use the +same routine. When the "region" parameter is NULL, that is a flag that +we are flattening instead of stepping. +*/ +/* +:h2.Bezier Third Order Curves +*/ +/* +:h3.The "bezierinfo" Structure + +This structure is used to store information used when we subdivide +Bezier curves. +*/ + +struct bezierinfo { + struct region *region; /* the region being built or NULL */ + struct fractpoint last; /* not used yet; maybe could save some work */ + struct fractpoint origin; /* the origin of the bezier */ +} ; + +/* + Checking for termination of the subdivision process: + This is the stupidest test in the world, just check if the coordinatewise + distance from an end control point to the next control point is less than + one half pel. If so, we must be done. + This returns 1 if the subdivision is terminated and 0 if you still need + to subdivide. +*/ + +static int +BezierTerminationTest(fractpel xa, fractpel ya, + fractpel xb, fractpel yb, + fractpel xc, fractpel yc, + fractpel xd, fractpel yd) +{ + fractpel dmax; + dmax = ABS(xa - xb); + dmax = MAX(dmax,ABS(ya - yb)); + dmax = MAX(dmax,ABS(xd - xc)); + dmax = MAX(dmax,ABS(yd - yc)); + if(dmax > FPHALF) + return(0); /* not done yet */ + else + return(1); /* done */ +} + +/* +:h3.StepBezierRecurse() - The Recursive Logic in StepBezier() + +The recursion involves dividing the control polygon into two smaller +control polygons by finding the midpoints of the lines. This idea is +described in any graphics text book and its simplicity is what caused +Bezier to define his curves as he did. If the input region 'R' is NULL, +the result is a path that is the 'flattened' curve; otherwise StepBezier +returns nothing special. +*/ +static struct segment * +StepBezierRecurse(struct bezierinfo *I, /* Region under construction or NULL */ + fractpel xA, fractpel yA, /* A control point */ + fractpel xB, fractpel yB, /* B control point */ + fractpel xC, fractpel yC, /* C control point */ + fractpel xD, fractpel yD) /* D control point */ +{ + if (BezierTerminationTest(xA,yA,xB,yB,xC,yC,xD,yD)) + { + if (I->region == NULL) + return(PathSegment(LINETYPE, xD - xA, yD - yA)); + else + StepLine(I->region, I->origin.x + xA, I->origin.y + yA, + I->origin.x + xD, I->origin.y + yD); + } + else + { + fractpel xAB,yAB; + fractpel xBC,yBC; + fractpel xCD,yCD; + fractpel xABC,yABC; + fractpel xBCD,yBCD; + fractpel xABCD,yABCD; + + xAB = xA + xB; yAB = yA + yB; + xBC = xB + xC; yBC = yB + yC; + xCD = xC + xD; yCD = yC + yD; + + xABC = xAB + xBC; yABC = yAB + yBC; + xBCD = xBC + xCD; yBCD = yBC + yCD; + + xABCD = xABC + xBCD; yABCD = yABC + yBCD; + + xAB >>= 1; yAB >>= 1; + xBC >>= 1; yBC >>= 1; + xCD >>= 1; yCD >>= 1; + xABC >>= 2; yABC >>= 2; + xBCD >>= 2; yBCD >>= 2; + xABCD >>= 3; yABCD >>= 3; + + if (I->region == NULL) + { + return( Join( + StepBezierRecurse(I, xA, yA, xAB, yAB, xABC, yABC, xABCD, yABCD), + StepBezierRecurse(I, xABCD, yABCD, xBCD, yBCD, xCD, yCD, xD, yD) + ) + ); + } + else + { + StepBezierRecurse(I, xA, yA, xAB, yAB, xABC, yABC, xABCD, yABCD); + StepBezierRecurse(I, xABCD, yABCD, xBCD, yBCD, xCD, yCD, xD, yD); + } + } + return NULL; + /*NOTREACHED*/ +} + +/* +:h3.TOOBIG() - Macro to Test if a Coordinate is Too Big to Bezier SubDivide Normally + +Intermediate values in the Bezier subdivision are 8 times bigger than +the starting values. If this overflows, a 'long', we are in trouble: +*/ + +#undef BITS +#define BITS (sizeof(long)*8) +#define HIGHTEST(p) (((p)>>(BITS-4)) != 0) /* includes sign bit */ +#define TOOBIG(xy) ((xy < 0) ? HIGHTEST(-xy) : HIGHTEST(xy)) + +/* +:h3.StepBezier() - Produce Run Ends for a Bezier Curve + +This is the entry point called from outside the module. +*/ + +struct segment * +StepBezier(struct region *R, /* Region under construction or NULL */ + fractpel xA, fractpel yA, /* A control point */ + fractpel xB, fractpel yB, /* B control point */ + fractpel xC, fractpel yC, /* C control point */ + fractpel xD, fractpel yD) /* D control point */ +{ + struct bezierinfo Info; + + Info.region = R; + Info.origin.x = xA; + Info.origin.y = yA; + + xB -= xA; + xC -= xA; + xD -= xA; + yB -= yA; + yC -= yA; + yD -= yA; + + if ( TOOBIG(xB) || TOOBIG(yB) || TOOBIG(xC) || TOOBIG(yC) + || TOOBIG(xD) || TOOBIG(yD) ) + Abort("Beziers this big not yet supported"); + + return(StepBezierRecurse(&Info, + (fractpel) 0, (fractpel) 0, xB, yB, xC, yC, xD, yD)); +} + diff --git a/nx-X11/lib/font/Type1/curves.h b/nx-X11/lib/font/Type1/curves.h new file mode 100644 index 000000000..ca54bad62 --- /dev/null +++ b/nx-X11/lib/font/Type1/curves.h @@ -0,0 +1,44 @@ +/* $Xorg: curves.h,v 1.3 2000/08/17 19:46:29 cpqbld Exp $ */ +/* Copyright International Business Machines, Corp. 1991 + * All Rights Reserved + * Copyright Lexmark International, Inc. 1991 + * All Rights Reserved + * + * License to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, + * provided that the above copyright notice appear in all copies and that + * both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of IBM or Lexmark not be + * used in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * + * IBM AND LEXMARK PROVIDE THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES OF + * ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO ANY + * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, + * AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE + * QUALITY AND PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT + * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF THE + * SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM OR LEXMARK) ASSUMES THE + * ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN NO EVENT SHALL + * IBM OR LEXMARK BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF + * THIS SOFTWARE. + */ +/* $XFree86: xc/lib/font/Type1/curves.h,v 1.3 1999/08/22 08:58:50 dawes Exp $ */ + +/*SHARED*/ + +#define StepConic(R,xA,yA,xB,yB,xC,yC,r) t1_StepConic(R,xA,yA,xB,yB,xC,yC,r) +#define StepBezier(R,xA,yA,xB,yB,xC,yC,xD,yD) t1_StepBezier(R,xA,yA,xB,yB,xC,yC,xD,yD) + +#define FlattenConic(xM,yM,xC,yC,r) t1_StepConic(NULL,(fractpel)0,(fractpel)0,xM,yM,xC,yC,r) +#define FlattenBezier(xB,yB,xC,yC,xD,yD) t1_StepBezier(NULL,(fractpel)0,(fractpel)0,xB,yB,xC,yC,xD,yD) + +#if 0 +struct segment *t1_StepConic(); +#endif +extern struct segment *t1_StepBezier ( struct region *R, fractpel xA, fractpel yA, fractpel xB, fractpel yB, fractpel xC, fractpel yC, fractpel xD, fractpel yD ); + +/*END SHARED*/ diff --git a/nx-X11/lib/font/Type1/digit.h b/nx-X11/lib/font/Type1/digit.h new file mode 100644 index 000000000..c69380954 --- /dev/null +++ b/nx-X11/lib/font/Type1/digit.h @@ -0,0 +1,64 @@ +/* $Xorg: digit.h,v 1.3 2000/08/17 19:46:29 cpqbld Exp $ */ +/* Copyright International Business Machines,Corp. 1991 + * All Rights Reserved + * + * License to use, copy, modify, and distribute this software + * and its documentation for any purpose and without fee is + * hereby granted, provided that the above copyright notice + * appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, + * and that the name of IBM not be used in advertising or + * publicity pertaining to distribution of the software without + * specific, written prior permission. + * + * IBM PROVIDES THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES + * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT + * LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE QUALITY AND + * PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT + * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF + * THE SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM) ASSUMES + * THE ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN + * NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ +/* -------------------------------------- */ +/* --- MACHINE GENERATED, DO NOT EDIT --- */ +/* -------------------------------------- */ + +#ifndef DIGIT +#define DIGIT 1 + +/* + * Digit Value Table -- + * + * The entries in the Digit Value Table map character + * codes in the set {0-9,a-z,A-Z} to their numeric + * values as part of numbers of radix 2-36. + * + */ +unsigned char digit_value[256] = { +0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18, + 0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,0x20,0x21,0x22,0x23,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18, + 0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,0x20,0x21,0x22,0x23,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF +}; + +#endif diff --git a/nx-X11/lib/font/Type1/fontfcn.c b/nx-X11/lib/font/Type1/fontfcn.c new file mode 100644 index 000000000..9b48b9834 --- /dev/null +++ b/nx-X11/lib/font/Type1/fontfcn.c @@ -0,0 +1,709 @@ +/* $Xorg: fontfcn.c,v 1.4 2000/08/17 19:46:30 cpqbld Exp $ */ +/* Copyright International Business Machines,Corp. 1991 + * All Rights Reserved + * + * License to use, copy, modify, and distribute this software + * and its documentation for any purpose and without fee is + * hereby granted, provided that the above copyright notice + * appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, + * and that the name of IBM not be used in advertising or + * publicity pertaining to distribution of the software without + * specific, written prior permission. + * + * IBM PROVIDES THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES + * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT + * LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE QUALITY AND + * PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT + * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF + * THE SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM) ASSUMES + * THE ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN + * NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ +/* Author: Katherine A. Hitchcock IBM Almaden Research Laboratory */ +/* Copyright (c) 1994-1999 Silicon Graphics, Inc. All Rights Reserved. + * + * The contents of this file are subject to the CID Font Code Public Licence + * Version 1.0 (the "License"). You may not use this file except in compliance + * with the Licence. You may obtain a copy of the License at Silicon Graphics, + * Inc., attn: Legal Services, 2011 N. Shoreline Blvd., Mountain View, CA + * 94043 or at http://www.sgi.com/software/opensource/cid/license.html. + * + * Software distributed under the License is distributed on an "AS IS" basis. + * ALL WARRANTIES ARE DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED + * WARRANTIES OF MERCHANTABILITY, OF FITNESS FOR A PARTICULAR PURPOSE OR OF + * NON-INFRINGEMENT. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Software is CID font code that was developed by Silicon + * Graphics, Inc. + */ +/* $XFree86: xc/lib/font/Type1/fontfcn.c,v 1.10 2001/04/05 17:42:27 dawes Exp $ */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#ifdef BUILDCID +#define XFONT_CID 1 +#endif + +#ifndef FONTMODULE +#include <stdio.h> +#include <string.h> +#else +#include "Xmd.h" /* For INT32 declaration */ +#include "Xdefs.h" /* For Bool */ +#include "xf86_ansic.h" +#endif +#include "t1imager.h" +#include "util.h" +#if XFONT_CID +#include "range.h" +#include <X11/Xdefs.h> +#endif +#include <X11/fonts/fntfilst.h> +#include "fontfcn.h" + +extern struct segment *Type1Char ( char *env, XYspace S, + psobj *charstrP, psobj *subrsP, + psobj *osubrsP, + struct blues_struct *bluesP, int *modeP ); + +#if XFONT_CID +extern struct xobject *CIDChar ( char *env, XYspace S, + psobj *charstrP, psobj *subrsP, + psobj *osubrsP, + struct blues_struct *bluesP, int *modeP ); +static boolean initCIDFont( int cnt ); +#endif + +/***================================================================***/ +/* GLOBALS */ +/***================================================================***/ +char CurFontName[120]; +char *CurFontEnv; +char *vm_base = NULL; +psfont *FontP = NULL; +psfont TheCurrentFont; +#if XFONT_CID +char CurCIDFontName[CID_PATH_MAX]; +char CurCMapName[CID_PATH_MAX]; +cidfont *CIDFontP = NULL; +cmapres *CMapP = NULL; +cidfont TheCurrentCIDFont; +cmapres TheCurrentCMap; +psfont *FDArrayP = NULL; +int FDArrayIndex = 0; +#endif + +/***================================================================***/ +/* SearchDict - look for name */ +/* - compare for match on len and string */ +/* return 0 - not found. */ +/* return n - nth element in dictionary. */ +/***================================================================***/ +int +SearchDictName(psdict *dictP, psobj *keyP) +{ + int i,n; + + + n = dictP[0].key.len; + for (i=1;i<=n;i++) { /* scan the intire dictionary */ + if ( + (dictP[i].key.len == keyP->len ) + && + (strncmp(dictP[i].key.data.valueP, + keyP->data.valueP, + keyP->len) == 0 + ) + ) return(i); + } + return(0); +} + +#if XFONT_CID +static boolean +initCIDFont(int cnt) +{ + if (!(vm_init(cnt))) return(FALSE); + vm_base = vm_next_byte(); + strcpy(CurCIDFontName, ""); /* initialize to none */ + strcpy(CurCMapName, ""); /* initialize to none */ + /* cause a font data reset on the next Type 1 font */ + strcpy(CurFontName, ""); /* initialize to none */ + CIDFontP = &TheCurrentCIDFont; + CMapP = &TheCurrentCMap; + CIDFontP->vm_start = vm_next_byte(); + CIDFontP->spacerangecnt = 0; + CIDFontP->notdefrangecnt = 0; + CIDFontP->cidrangecnt = 0; + CIDFontP->spacerangeP = NULL; + CIDFontP->notdefrangeP = NULL; + CIDFontP->cidrangeP = NULL; + CIDFontP->CIDFontFileName.len = 0; + CIDFontP->CIDFontFileName.data.valueP = CurCIDFontName; + CMapP->CMapFileName.len = 0; + CMapP->CMapFileName.data.valueP = CurCMapName; + CMapP->firstRow = 0xFFFF; + CMapP->firstCol = 0xFFFF; + CMapP->lastRow = 0; + CMapP->lastCol = 0; + return(TRUE); +} + +/***================================================================***/ +boolean +initCIDType1Font(void) +{ + strcpy(CurFontName, ""); /* initialize to none */ + FontP = &FDArrayP[FDArrayIndex]; + FontP->vm_start = vm_next_byte(); + FontP->FontFileName.len = 0; + FontP->FontFileName.data.valueP = CurFontName; + FontP->Subrs.len = 0; + FontP->Subrs.data.stringP = NULL; + FontP->CharStringsP = NULL; + FontP->Private = NULL; + FontP->fontInfoP = NULL; + FontP->BluesP = NULL; + return(TRUE); +} +#endif + +boolean +initFont(int cnt) +{ + + if (!(vm_init(cnt))) return(FALSE); + vm_base = vm_next_byte(); + if (!(Init_BuiltInEncoding())) return(FALSE); + strcpy(CurFontName, ""); /* iniitialize to none */ +#if XFONT_CID + /* cause a font data reset on the next CID-keyed font */ + strcpy(CurCIDFontName, ""); /* initialize to none */ +#endif + FontP = &TheCurrentFont; + FontP->vm_start = vm_next_byte(); + FontP->FontFileName.len = 0; + FontP->FontFileName.data.valueP = CurFontName; + return(TRUE); +} +/***================================================================***/ +#if XFONT_CID +static void +resetCIDFont(char *cidfontname, char *cmapfile) +{ + + vm_next = CIDFontP->vm_start; + vm_free = vm_size - ( vm_next - vm_base); + CIDFontP->spacerangecnt = 0; + CIDFontP->notdefrangecnt = 0; + CIDFontP->cidrangecnt = 0; + CIDFontP->spacerangeP = NULL; + CIDFontP->notdefrangeP = NULL; + CIDFontP->cidrangeP = NULL; + CIDFontP->CIDfontInfoP = NULL; + /* This will load the font into the FontP */ + strcpy(CurCIDFontName,cidfontname); + strcpy(CurCMapName,cmapfile); + CIDFontP->CIDFontFileName.len = strlen(CurCIDFontName); + CIDFontP->CIDFontFileName.data.valueP = CurCIDFontName; + CMapP->CMapFileName.len = strlen(CurCMapName); + CMapP->CMapFileName.data.valueP = CurCMapName; + CMapP->firstRow = 0xFFFF; + CMapP->firstCol = 0xFFFF; + CMapP->lastRow = 0; + CMapP->lastCol = 0; +} + +static void +resetCIDType1Font(void) +{ + + vm_next = FontP->vm_start; + vm_free = vm_size - ( vm_next - vm_base); + FontP->Subrs.len = 0; + FontP->Subrs.data.stringP = NULL; + FontP->CharStringsP = NULL; + FontP->Private = NULL; + FontP->fontInfoP = NULL; + FontP->BluesP = NULL; + /* This will load the font into the FontP */ + FontP->FontFileName.len = strlen(CurFontName); + FontP->FontFileName.data.valueP = CurFontName; +} +#endif + +static void +resetFont(char *env) +{ + + vm_next = FontP->vm_start; + vm_free = vm_size - ( vm_next - vm_base); + FontP->Subrs.len = 0; + FontP->Subrs.data.stringP = NULL; + FontP->CharStringsP = NULL; + FontP->Private = NULL; + FontP->fontInfoP = NULL; + FontP->BluesP = NULL; + /* This will load the font into the FontP */ + strcpy(CurFontName,env); + FontP->FontFileName.len = strlen(CurFontName); + FontP->FontFileName.data.valueP = CurFontName; + +} + +#if XFONT_CID +/***================================================================***/ +int +readCIDFont(char *cidfontname, char *cmapfile) +{ + int rcode; + + /* restore the virtual memory and eliminate old font */ + resetCIDFont(cidfontname, cmapfile); + /* This will load the font into the FontP */ + rcode = scan_cidfont(CIDFontP, CMapP); + if (rcode == SCAN_OUT_OF_MEMORY) { + /* free the memory and start again */ + if (!(initCIDFont(vm_size * 2))) { + /* we are really out of memory */ + return(SCAN_OUT_OF_MEMORY); + } + resetCIDFont(cidfontname, cmapfile); + rcode = scan_cidfont(CIDFontP, CMapP); + /* only double the memory twice, then report error */ + if (rcode == SCAN_OUT_OF_MEMORY) { + /* free the memory and start again */ + if (!(initCIDFont(vm_size * 2))) { + /* we are really out of memory */ + return(SCAN_OUT_OF_MEMORY); + } + resetCIDFont(cidfontname, cmapfile); + rcode = scan_cidfont(CIDFontP, CMapP); + } + } + return(rcode); +} + +int +readCIDType1Font(void) +{ + int rcode; + + resetCIDType1Font(); + + /* This will load the font into the FontP */ + rcode = scan_cidtype1font(FontP); + return(rcode); +} +#endif + +int +readFont(char *env) +{ + int rcode; + + /* restore the virtual memory and eliminate old font */ + resetFont(env); + /* This will load the font into the FontP */ + rcode = scan_font(FontP); + if (rcode == SCAN_OUT_OF_MEMORY) { + /* free the memory and start again */ +#if XFONT_CID + /* xfree(vm_base); */ +#else + xfree(vm_base); +#endif + if (!(initFont(vm_size * 2))) { + /* we are really out of memory */ + return(SCAN_OUT_OF_MEMORY); + } + resetFont(env); + rcode = scan_font(FontP); +#if XFONT_CID + /* only double the memory twice, then report error */ + if (rcode == SCAN_OUT_OF_MEMORY) { + /* free the memory and start again */ + /* xfree(vm_base) */ + if (!(initFont(vm_size * 2))) { + /* we are really out of memory */ + return(SCAN_OUT_OF_MEMORY); + } + resetFont(env); + rcode = scan_font(FontP); + } +#else + /* only double the memory once, then report error */ +#endif + } + return(rcode); +} +/***================================================================***/ +struct xobject * +fontfcnB(struct XYspace *S, unsigned char *code, int *lenP, int *mode) +{ + psobj *charnameP; /* points to psobj that is name of character*/ + int N; + psdict *CharStringsDictP; /* dictionary with char strings */ + psobj CodeName; /* used to store the translation of the name*/ + psobj *SubrsArrayP; + psobj *theStringP; + + struct xobject *charpath; /* the path for this character */ + + charnameP = &CodeName; + charnameP->len = *lenP; + charnameP->data.stringP = code; + + CharStringsDictP = FontP->CharStringsP; + + /* search the chars string for this charname as key */ + N = SearchDictName(CharStringsDictP,charnameP); + if (N<=0) { + *mode = FF_PARSE_ERROR; + return(NULL); + } + /* ok, the nth item is the psobj that is the string for this char */ + theStringP = &(CharStringsDictP[N].value); + + /* get the dictionary pointers to the Subrs */ + + SubrsArrayP = &(FontP->Subrs); + /* scale the Adobe fonts to 1 unit high */ + /* call the type 1 routine to rasterize the character */ + charpath = (struct xobject *)Type1Char((char *)FontP,S,theStringP, + SubrsArrayP,NULL, + FontP->BluesP , mode); + /* if Type1Char reported an error, then return */ + if ( *mode == FF_PARSE_ERROR) return(NULL); + /* fill with winding rule unless path was requested */ + if (*mode != FF_PATH) { + charpath = (struct xobject *)Interior((struct segment *)charpath, + WINDINGRULE+CONTINUITY); + } + return(charpath); +} + +#if XFONT_CID +/***================================================================***/ +/* CIDfontfcnA(cidfontname, cmapfile, mode) */ +/* */ +/* 1) initialize the font - global indicates it has been done */ +/* 2) load the font */ +/***================================================================***/ +Bool +CIDfontfcnA(char *cidfontname, char *cmapfile, int *mode) +{ + int rcode, cidinit; + + cidinit = 0; + if (CIDFontP == NULL || strcmp(CurCIDFontName, "") == 0) { + InitImager(); + if (!(initCIDFont(VM_SIZE))) { + /* we are really out of memory */ + *mode = SCAN_OUT_OF_MEMORY; + return(FALSE); + } + cidinit = 1; + } + + /* if the cidfontname is null, then use font already loaded */ + + /* if not the same font name */ + if (cidinit || (cidfontname && strcmp(cidfontname,CurCIDFontName) != 0) || + (cmapfile && strcmp(cmapfile,CurCMapName) != 0)) { + /* restore the virtual memory and eliminate old font, read new one */ + rcode = readCIDFont(cidfontname, cmapfile); + if (rcode != 0 ) { + strcpy(CurCIDFontName, ""); /* no CIDFont loaded */ + strcpy(CurCMapName, ""); /* no CMap loaded */ + *mode = rcode; + return(FALSE); + } + } + return(TRUE); + +} + +/***================================================================***/ +/* CIDType1fontfcnA(mode) */ +/* */ +/* 1) initialize the font - global indicates it has been done */ +/* 2) load the font */ +/***================================================================***/ +Bool +CIDType1fontfcnA(int *mode) +{ + int rcode; + + if (!(initCIDType1Font())) { + /* we are really out of memory */ + *mode = SCAN_OUT_OF_MEMORY; + return(FALSE); + } + + if ((rcode = readCIDType1Font()) != 0) { + strcpy(CurFontName, ""); /* no font loaded */ + *mode = rcode; + return(FALSE); + } + return(TRUE); + +} +#endif + +/***================================================================***/ +/* fontfcnA(env, mode) */ +/* */ +/* env is a pointer to a string that contains the fontname. */ +/* */ +/* 1) initialize the font - global indicates it has been done */ +/* 2) load the font */ +/***================================================================***/ +Bool +fontfcnA(char *env, int *mode) +{ + int rc; + + /* Has the FontP initialized? If not, then */ + /* Initialize */ +#if XFONT_CID + if (FontP == NULL || strcmp(CurFontName, "") == 0) { +#else + if (FontP == NULL) { +#endif + InitImager(); + if (!(initFont(VM_SIZE))) { + /* we are really out of memory */ + *mode = SCAN_OUT_OF_MEMORY; + return(FALSE); + } + } + + /* if the env is null, then use font already loaded */ + + /* if the not same font name */ + if ( (env) && (strcmp(env,CurFontName) != 0 ) ) { + /* restore the virtual memory and eliminate old font, read new one */ + rc = readFont(env); + if (rc != 0 ) { + strcpy(CurFontName, ""); /* no font loaded */ + *mode = rc; + return(FALSE); + } + } + return(TRUE); + +} + +#if XFONT_CID +/***================================================================***/ +/* CIDQueryFontLib(cidfontname,cmapfile,infoName,infoValue,rcodeP) */ +/* */ +/* cidfontname is a pointer to a string that contains the fontname. */ +/* */ +/* 1) initialize the font - global indicates it has been done */ +/* 2) load the font */ +/* 3) use the font to call getInfo for that value. */ +/***================================================================***/ + +void +CIDQueryFontLib(char *cidfontname, char *cmapfile, char *infoName, + pointer infoValue, /* parameter returned here */ + int *rcodeP) +{ + int rc,N,i,cidinit; + psdict *dictP; + psobj nameObj; + psobj *valueP; + + /* Has the CIDFontP initialized? If not, then */ + /* Initialize */ + cidinit = 0; + if (CIDFontP == NULL || strcmp(CurCIDFontName, "") == 0) { + InitImager(); + if (!(initCIDFont(VM_SIZE))) { + *rcodeP = 1; + return; + } + cidinit = 1; + } + /* if the file name is null, then use font already loaded */ + /* if the not same font name, reset and load next font */ + if (cidinit || (cidfontname && strcmp(cidfontname,CurCIDFontName) != 0) || + (cmapfile && strcmp(cmapfile,CurCMapName) != 0)) { + /* restore the virtual memory and eliminate old font */ + rc = readCIDFont(cidfontname, cmapfile); + if (rc != 0 ) { + strcpy(CurCIDFontName, ""); /* no font loaded */ + strcpy(CurCMapName, ""); /* no font loaded */ + *rcodeP = 1; + return; + } + } + dictP = CIDFontP->CIDfontInfoP; + objFormatName(&nameObj,strlen(infoName),infoName); + N = SearchDictName(dictP,&nameObj); + /* if found */ + if ( N > 0 ) { + *rcodeP = 0; + switch (dictP[N].value.type) { + case OBJ_ARRAY: + valueP = dictP[N].value.data.arrayP; + /* Just double check valueP. H.J. */ + if (valueP == NULL) break; + if (strcmp(infoName,"FontMatrix") == 0) { + /* 6 elments, return them as floats */ + for (i=0;i<6;i++) { + if (valueP->type == OBJ_INTEGER ) + ((float *)infoValue)[i] = valueP->data.integer; + else + ((float *)infoValue)[i] = valueP->data.real; + valueP++; + } + } + if (strcmp(infoName,"FontBBox") == 0) { + /* 4 elments for Bounding Box. all integers */ + for (i=0;i<4;i++) { + ((int *)infoValue)[i] = valueP->data.integer; + valueP++; + } + break; + case OBJ_INTEGER: + case OBJ_BOOLEAN: + *((int *)infoValue) = dictP[N].value.data.integer; + break; + case OBJ_REAL: + *((float *)infoValue) = dictP[N].value.data.real; + break; + case OBJ_NAME: + case OBJ_STRING: + *((char **)infoValue) = dictP[N].value.data.valueP; + break; + default: + *rcodeP = 1; + break; + } + } + } + else *rcodeP = 1; +} +#endif + +/***================================================================***/ +/* QueryFontLib(env, infoName,infoValue,rcodeP) */ +/* */ +/* env is a pointer to a string that contains the fontname. */ +/* */ +/* 1) initialize the font - global indicates it has been done */ +/* 2) load the font */ +/* 3) use the font to call getInfo for that value. */ +/***================================================================***/ + +void +QueryFontLib(char *env, char *infoName, + pointer infoValue, /* parameter returned here */ + int *rcodeP) +{ + int rc,N,i; + psdict *dictP; + psobj nameObj; + psobj *valueP; + + /* Has the FontP initialized? If not, then */ + /* Initialize */ + if (FontP == NULL) { + InitImager(); + if (!(initFont(VM_SIZE))) { + *rcodeP = 1; + return; + } + } + /* if the env is null, then use font already loaded */ + /* if the not same font name, reset and load next font */ + if ( (env) && (strcmp(env,CurFontName) != 0 ) ) { + /* restore the virtual memory and eliminate old font */ + rc = readFont(env); + if (rc != 0 ) { + strcpy(CurFontName, ""); /* no font loaded */ + *rcodeP = 1; + return; + } + } + dictP = FontP->fontInfoP; + objFormatName(&nameObj,strlen(infoName),infoName); + N = SearchDictName(dictP,&nameObj); + /* if found */ + if ( N > 0 ) { + *rcodeP = 0; + switch (dictP[N].value.type) { + case OBJ_ARRAY: + valueP = dictP[N].value.data.arrayP; + /* Just double check valueP. H.J. */ + if (valueP == NULL) break; + if (strcmp(infoName,"FontMatrix") == 0) { + /* 6 elments, return them as floats */ + for (i=0;i<6;i++) { + if (valueP->type == OBJ_INTEGER ) + ((float *)infoValue)[i] = valueP->data.integer; + else + ((float *)infoValue)[i] = valueP->data.real; + valueP++; + } + } + if (strcmp(infoName,"FontBBox") == 0) { + /* 4 elments for Bounding Box. all integers */ + for (i=0;i<4;i++) { + ((int *)infoValue)[i] = valueP->data.integer; + valueP++; + } + break; + case OBJ_INTEGER: + case OBJ_BOOLEAN: + *((int *)infoValue) = dictP[N].value.data.integer; + break; + case OBJ_REAL: + *((float *)infoValue) = dictP[N].value.data.real; + break; + case OBJ_NAME: + case OBJ_STRING: + *((char **)infoValue) = dictP[N].value.data.valueP; + break; + default: + *rcodeP = 1; + break; + } + } + } + else *rcodeP = 1; +} + +#if XFONT_CID +struct xobject * +CIDfontfcnC(struct XYspace *S, psobj *theStringP, + psobj *SubrsArrayP, struct blues_struct *BluesP, + int *lenP, int *mode) +{ + struct xobject *charpath; /* the path for this character */ + + charpath = (struct xobject *)CIDChar((char *)FontP,S,theStringP, + SubrsArrayP,NULL,BluesP,mode); + /* if Type1Char reported an error, then return */ + if ( *mode == FF_PARSE_ERROR) return(NULL); + /* fill with winding rule unless path was requested */ + if (*mode != FF_PATH) { + charpath = (struct xobject *)Interior((struct segment *)charpath, + WINDINGRULE+CONTINUITY); + } + return(charpath); +} +#endif diff --git a/nx-X11/lib/font/Type1/fontfcn.h b/nx-X11/lib/font/Type1/fontfcn.h new file mode 100644 index 000000000..1409eb9a9 --- /dev/null +++ b/nx-X11/lib/font/Type1/fontfcn.h @@ -0,0 +1,250 @@ +/* $Xorg: fontfcn.h,v 1.3 2000/08/17 19:46:30 cpqbld Exp $ */ +/* Copyright International Business Machines,Corp. 1991 + * All Rights Reserved + * + * License to use, copy, modify, and distribute this software + * and its documentation for any purpose and without fee is + * hereby granted, provided that the above copyright notice + * appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, + * and that the name of IBM not be used in advertising or + * publicity pertaining to distribution of the software without + * specific, written prior permission. + * + * IBM PROVIDES THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES + * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT + * LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE QUALITY AND + * PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT + * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF + * THE SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM) ASSUMES + * THE ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN + * NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ +/* Copyright (c) 1994-1999 Silicon Graphics, Inc. All Rights Reserved. + * + * The contents of this file are subject to the CID Font Code Public Licence + * Version 1.0 (the "License"). You may not use this file except in compliance + * with the Licence. You may obtain a copy of the License at Silicon Graphics, + * Inc., attn: Legal Services, 2011 N. Shoreline Blvd., Mountain View, CA + * 94043 or at http://www.sgi.com/software/opensource/cid/license.html. + * + * Software distributed under the License is distributed on an "AS IS" basis. + * ALL WARRANTIES ARE DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED + * WARRANTIES OF MERCHANTABILITY, OF FITNESS FOR A PARTICULAR PURPOSE OR OF + * NON-INFRINGEMENT. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Software is CID font code that was developed by Silicon + * Graphics, Inc. + */ +/* $XFree86: xc/lib/font/Type1/fontfcn.h,v 1.4 1999/08/22 08:58:50 dawes Exp $ */ + + +#ifdef BUILDCID +#define XFONT_CID 1 +#endif + +/* modular config.h defines VERSION as libXfont version */ +#ifdef VERSION +#undef VERSION +#endif + +#if XFONT_CID +/* Definition of a PostScript CIDFont resource */ +typedef struct cid_font { + char *vm_start; + int spacerangecnt; + int notdefrangecnt; + int cidrangecnt; + spacerange *spacerangeP; + cidrange *notdefrangeP; + cidrange *cidrangeP; + int binarydata; /* 1=binary data, 0=hex data */ + long bytecnt; + psobj CIDFontFileName; + psdict *CIDfontInfoP; +} cidfont; + +/* Definition of a PostScript CMap resource */ +typedef struct cmap_res { + unsigned short firstCol; + unsigned short lastCol; + unsigned short firstRow; + unsigned short lastRow; + psobj CMapFileName; + psdict *CMapInfoP; +} cmapres; +#endif + +/* Definition of a PostScript FONT */ +typedef struct ps_font { + char *vm_start; + psobj FontFileName; + psobj Subrs; + psdict *CharStringsP; + psdict *Private; + psdict *fontInfoP; +struct blues_struct *BluesP; +} psfont; +/***================================================================***/ +/* Routines in scan_font */ +/***================================================================***/ + +extern boolean Init_BuiltInEncoding ( void ); +#if XFONT_CID +extern int scan_cidfont ( cidfont *CIDFontP, cmapres *CMapP ); +extern int scan_cidtype1font ( psfont *FontP ); +#endif +extern int scan_font ( psfont *FontP ); +/***================================================================***/ +/* Return codes from scan_font */ +/***================================================================***/ +#define SCAN_OK 0 +#define SCAN_FILE_EOF -1 +#define SCAN_ERROR -2 +#define SCAN_OUT_OF_MEMORY -3 +#define SCAN_FILE_OPEN_ERROR -4 +#define SCAN_TRUE -5 +#define SCAN_FALSE -6 +#define SCAN_END -7 + +#if XFONT_CID +/***================================================================***/ +/* Name of CID FontInfo fields */ +/***================================================================***/ +#define CIDCOUNT 1 +#define CIDFONTNAME 2 +#define CIDFONTTYPE 3 +#define CIDVERSION 4 +#define CIDREGISTRY 5 +#define CIDORDERING 6 +#define CIDSUPPLEMENT 7 +#define CIDMAPOFFSET 8 +#define CIDFDARRAY 9 +#define CIDFDBYTES 10 +#define CIDFONTBBOX 11 +#define CIDFULLNAME 12 +#define CIDFAMILYNAME 13 +#define CIDWEIGHT 14 +#define CIDNOTICE 15 +#define CIDGDBYTES 16 +#define CIDUIDBASE 17 +#define CIDXUID 18 + +/***================================================================***/ +/* Name of CMapInfo fields */ +/***================================================================***/ +#define CMAPREGISTRY 1 +#define CMAPORDERING 2 +#define CMAPSUPPLEMENT 3 +#define CMAPNAME 4 +#define CMAPVERSION 5 +#define CMAPTYPE 6 +#define CMAPWMODE 7 +#define CMAPCIDCOUNT 8 +#endif + +/***================================================================***/ +/* Name of FontInfo fields */ +/***================================================================***/ + +#define FONTNAME 1 +#define PAINTTYPE 2 +#define FONTTYPENUM 3 +#define FONTMATRIX 4 +#define FONTBBOX 5 +#define UNIQUEID 6 +#define STROKEWIDTH 7 +#define VERSION 8 +#define NOTICE 9 +#define FULLNAME 10 +#define FAMILYNAME 11 +#define WEIGHT 12 +#define ITALICANGLE 13 +#define ISFIXEDPITCH 14 +#define UNDERLINEPOSITION 15 +#define UNDERLINETHICKNESS 16 +#define ENCODING 17 +/***================================================================***/ +/* Name of Private values */ +/***================================================================***/ +#define BLUEVALUES 1 +#define OTHERBLUES 2 +#define FAMILYBLUES 3 +#define FAMILYOTHERBLUES 4 +#define BLUESCALE 5 +#define BLUESHIFT 6 +#define BLUEFUZZ 7 +#define STDHW 8 +#define STDVW 9 +#define STEMSNAPH 10 +#define STEMSNAPV 11 +#define FORCEBOLD 12 +#define LANGUAGEGROUP 13 +#define LENIV 14 +#define RNDSTEMUP 15 +#define EXPANSIONFACTOR 16 + +#if XFONT_CID +/***================================================================***/ +/* Name of CID Type 1 Private values */ +/***================================================================***/ +#define CIDT1MINFEATURE 1 +#define CIDT1LENIV 2 +#define CIDT1LANGGROUP 3 +#define CIDT1BLUEVALUES 4 +#define CIDT1OTHERBLUES 5 +#define CIDT1BLUESCALE 6 +#define CIDT1BLUEFUZZ 7 +#define CIDT1BLUESHIFT 8 +#define CIDT1FAMBLUES 9 +#define CIDT1FAMOTHERBLUES 10 +#define CIDT1STDHW 11 +#define CIDT1STDVW 12 +#define CIDT1STEMSNAPH 13 +#define CIDT1STEMSNAPV 14 +#define CIDT1SUBMAPOFF 15 +#define CIDT1SDBYTES 16 +#define CIDT1SUBRCNT 17 +#define CIDT1FORCEBOLD 18 +#define CIDT1RNDSTEMUP 19 +#define CIDT1EXPFACTOR 20 + +#define CID_BITMAP_UNDEFINED 0 +extern int SearchDictName ( psdict *dictP, psobj *keyP ); +#if XFONT_CID +extern boolean initCIDType1Font ( void ); +#endif +extern boolean initFont ( int cnt ); +#if XFONT_CID +extern int readCIDFont ( char *cidfontname, char *cmapfile ); +extern int readCIDType1Font ( void ); +#endif +extern int readFont ( char *env ); +extern struct xobject *fontfcnB ( struct XYspace *S, unsigned char *code, + int *lenP, int *mode ); +#if XFONT_CID +extern Bool CIDfontfcnA ( char *cidfontname, char *cmapfile, int *mode ); +extern Bool CIDType1fontfcnA ( int *mode ); +#endif +extern Bool fontfcnA ( char *env, int *mode ); +#if XFONT_CID +extern void CIDQueryFontLib ( char *cidfontname, char *cmapfile, + char *infoName, pointer infoValue, int *rcodeP ); +#endif +extern void QueryFontLib ( char *env, char *infoName, pointer infoValue, + int *rcodeP ); +#if XFONT_CID +extern struct xobject *CIDfontfcnC ( struct XYspace *S, psobj *theStringP, + psobj *SubrsArrayP, + struct blues_struct *BluesP, int *lenP, + int *mode ); +#endif +#endif diff --git a/nx-X11/lib/font/Type1/fonts.h b/nx-X11/lib/font/Type1/fonts.h new file mode 100644 index 000000000..7215e0f7a --- /dev/null +++ b/nx-X11/lib/font/Type1/fonts.h @@ -0,0 +1,49 @@ +/* $Xorg: fonts.h,v 1.3 2000/08/17 19:46:30 cpqbld Exp $ */ +/* Copyright International Business Machines,Corp. 1991 + * All Rights Reserved + * + * License to use, copy, modify, and distribute this software + * and its documentation for any purpose and without fee is + * hereby granted, provided that the above copyright notice + * appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, + * and that the name of IBM not be used in advertising or + * publicity pertaining to distribution of the software without + * specific, written prior permission. + * + * IBM PROVIDES THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES + * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT + * LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE QUALITY AND + * PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT + * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF + * THE SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM) ASSUMES + * THE ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN + * NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +/* STUB */ + +#define CopyFont(f) f +#define UniqueFont(f) f +#define KillFont(f) +#define KillText(t) +#define CopyText(t) t +#define I_DumpText(t) +#define CoerceText(t) t +#define TextDelta(t,pt) +#define XformText(p,s) +#define GimeSpace() FALSE + +#define LibInit() +#define InitFonts() +#define InitFiles() +#define TraceClose() + +#define FF_PARSE_ERROR -1 diff --git a/nx-X11/lib/font/Type1/hdigit.h b/nx-X11/lib/font/Type1/hdigit.h new file mode 100644 index 000000000..fbaa9c1db --- /dev/null +++ b/nx-X11/lib/font/Type1/hdigit.h @@ -0,0 +1,94 @@ +/* $Xorg: hdigit.h,v 1.3 2000/08/17 19:46:30 cpqbld Exp $ */ +/* Copyright International Business Machines,Corp. 1991 + * All Rights Reserved + * + * License to use, copy, modify, and distribute this software + * and its documentation for any purpose and without fee is + * hereby granted, provided that the above copyright notice + * appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, + * and that the name of IBM not be used in advertising or + * publicity pertaining to distribution of the software without + * specific, written prior permission. + * + * IBM PROVIDES THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES + * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT + * LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE QUALITY AND + * PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT + * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF + * THE SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM) ASSUMES + * THE ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN + * NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ +/* -------------------------------------- */ +/* --- MACHINE GENERATED, DO NOT EDIT --- */ +/* -------------------------------------- */ + +#ifndef HDIGIT +#define HDIGIT 1 + +/* + * Hex Digit Value Table -- + * + * The entries in the Digit Value Table map character codes in the set + * {0-9,a-f,A-F} to their numeric values for readhexstring + * (00 10...F0 for the high hex digit and 00 01...0F for the low). + * The white-space and hex string termination characters are. + * mapped to codes > 0xf0 to enable usage by several modules. + * 2 tables are build HighHex and LowHex. + * + */ + +/* Indicators for special characters in these tables */ +#define HERROR (0xfe) +#define HWHITE_SPACE (0xfd) +#define HRIGHT_ANGLE (0xfc) +#define LAST_HDIGIT (0xf0) + +#define HighHexP (HighHex+1) +unsigned char HighHex[257] = { 0xFF, + 0xFD,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFD,0xFD,0xFE,0xFE,0xFE,0xFE,0xFE, + 0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE, + 0xFD,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE, + 0x00,0x10,0x20,0x30,0x40,0x50,0x60,0x70,0x80,0x90,0xFE,0xFE,0xFE,0xFE,0xFC,0xFE, + 0xFE,0xA0,0xB0,0xC0,0xD0,0xE0,0xF0,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE, + 0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE, + 0xFE,0xA0,0xB0,0xC0,0xD0,0xE0,0xF0,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE, + 0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE, + 0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE, + 0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE, + 0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE, + 0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE, + 0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE, + 0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE, + 0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE, + 0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE +}; +#define LowHexP (LowHex+1) +unsigned char LowHex[257] = { 0xFF, + 0xFD,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFD,0xFD,0xFE,0xFE,0xFE,0xFE,0xFE, + 0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE, + 0xFD,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE, + 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0xFE,0xFE,0xFE,0xFE,0xFC,0xFE, + 0xFE,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE, + 0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE, + 0xFE,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE, + 0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE, + 0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE, + 0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE, + 0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE, + 0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE, + 0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE, + 0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE, + 0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE, + 0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE +}; + +#endif diff --git a/nx-X11/lib/font/Type1/hints.c b/nx-X11/lib/font/Type1/hints.c new file mode 100644 index 000000000..14deac229 --- /dev/null +++ b/nx-X11/lib/font/Type1/hints.c @@ -0,0 +1,890 @@ +/* $Xorg: hints.c,v 1.3 2000/08/17 19:46:30 cpqbld Exp $ */ +/* Copyright International Business Machines, Corp. 1991 + * All Rights Reserved + * Copyright Lexmark International, Inc. 1991 + * All Rights Reserved + * + * License to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, + * provided that the above copyright notice appear in all copies and that + * both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of IBM or Lexmark not be + * used in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * + * IBM AND LEXMARK PROVIDE THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES OF + * ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO ANY + * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, + * AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE + * QUALITY AND PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT + * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF THE + * SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM OR LEXMARK) ASSUMES THE + * ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN NO EVENT SHALL + * IBM OR LEXMARK BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF + * THIS SOFTWARE. + */ +/* $XFree86: xc/lib/font/Type1/hints.c,v 1.7tsi Exp $ */ + + /* HINTS CWEB V0006 ******** */ +/* +:h1.HINTS Module - Processing Rasterization Hints + +&author. Sten F. Andler; continuity by Jeffrey B. Lotspiech (lotspiech@almaden.ibm.com) and Duaine +W. Pryor, Jr. + + +:h3.Include Files + +The included files are: +*/ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#ifdef FONTMODULE +# include "os.h" +#endif +#include "objects.h" +#include "spaces.h" +#include "paths.h" +#include "regions.h" +#include "hints.h" + +/* +:h3.Functions Provided to the TYPE1IMAGER User + +None. +*/ + +/* +:h3.Functions Provided to Other Modules + +This module provides the following entry point to other modules: +*/ + + +/*SHARED LINE(S) ORIGINATED HERE*/ + +/* +:h3.Macros Provided to Other Modules + +None. +*/ + +/* +:h2.InitHints() - Initialize hint data structure +*/ + +#define MAXLABEL 20 +static struct { + int inuse; + int computed; + struct fractpoint hint; +} oldHint[MAXLABEL]; + +#define ODD(x) (((int)(x)) & 01) +#define FPFLOOR(fp) TOFRACTPEL((fp) >> FRACTBITS) +#define FPROUND(fp) FPFLOOR((fp) + FPHALF) + +void +InitHints(void) +{ + int i; + + for (i = 0; i < MAXLABEL; i++) + { + oldHint[i].inuse = FALSE; + oldHint[i].computed = FALSE; + } +} + +/* +:h3.CloseHints(hintP) - Reverse hints that are still open +*/ + +void +CloseHints(struct fractpoint *hintP) +{ + int i; + + for (i = 0; i < MAXLABEL; i++) + { + if (oldHint[i].inuse) + { + hintP->x -= oldHint[i].hint.x; + hintP->y -= oldHint[i].hint.y; + + oldHint[i].inuse = FALSE; + } + } +} + +/* +:h3.ComputeHint(hP, currX, currY, hintP) - Compute the value of a hint +*/ + +static void +ComputeHint(struct hintsegment *hP, + fractpel currX, fractpel currY, + struct fractpoint *hintP) +{ + fractpel currRef, currWidth; + int idealWidth; + fractpel hintValue; + char orientation; + +/* +By construction, width is never zero. Therefore we can use the +width value to determine if the hint has been rotated by a +multiple of 90 degrees. +*/ + + if (hP->width.y == 0) + { + orientation = 'v'; /* vertical */ + } + else if (hP->width.x == 0) + { + orientation = 'h'; /* horizontal */ + } + else + { + hintP->x = hintP->y = 0; + return; + } + + /* Compute currRef and currWidth with a unit of 1 pel */ + if (orientation == 'v') /* vertical */ + { + currRef = hP->ref.x + currX; + currWidth = ABS(hP->width.x); + } + else if (orientation == 'h') /* horizontal */ + { + currRef = hP->ref.y + currY; + currWidth = ABS(hP->width.y); + } + else /* error */ + { + Abort("ComputeHint: invalid orientation"); + } + + if ((hP->hinttype == 'b') /* Bar or stem */ + || (hP->hinttype == 's')) /* Serif */ + { + idealWidth = NEARESTPEL(currWidth); + if (idealWidth == 0) idealWidth = 1; + if (ODD(idealWidth)) /* Is ideal width odd? */ + { + /* center "ref" over pel */ + hintValue = FPFLOOR(currRef) + FPHALF - currRef; + } + else + { + /* align "ref" on pel boundary */ + hintValue = FPROUND(currRef) - currRef; + } + } + else if (hP->hinttype == 'c') /* Curve extrema */ + { + /* align "ref" on pel boundary */ + hintValue = FPROUND(currRef) - currRef; + } + else /* error */ + { + Abort("ComputeHint: invalid hinttype"); + } + + if (orientation == 'v') /* vertical */ + { + hintP->x = hintValue; + hintP->y = 0; + } + else if (orientation == 'h') /* horizontal */ + { + hintP->x = 0; + hintP->y = hintValue; + } + else /* error */ + { + Abort("ComputeHint: invalid orientation"); + } +} + +/* +:h3.ProcessHint(hP, currX, currY, hintP) - Process a rasterization hint +*/ + +void +ProcessHint(struct hintsegment *hP, + fractpel currX, fractpel currY, + struct fractpoint *hintP) +{ + struct fractpoint thisHint; + + if ((hP->adjusttype == 'm') /* Move */ + || (hP->adjusttype == 'a')) /* Adjust */ + { + /* Look up hint in oldHint table */ + if ((hP->label >= 0) && (hP->label < MAXLABEL)) + { + if (oldHint[hP->label].computed) + /* Use old hint value if already computed */ + { + thisHint.x = oldHint[hP->label].hint.x; + thisHint.y = oldHint[hP->label].hint.y; + oldHint[hP->label].inuse = TRUE; + } + else + /* Compute new value for hint and store it for future use */ + { + ComputeHint(hP, currX, currY, &thisHint); + + oldHint[hP->label].hint.x = thisHint.x; + oldHint[hP->label].hint.y = thisHint.y; + oldHint[hP->label].inuse = TRUE; + oldHint[hP->label].computed = TRUE; + } + } + else /* error */ + { + Abort("ProcessHint: invalid label"); + } + } + else if (hP->adjusttype == 'r') /* Reverse */ + { + /* Use the inverse of the existing hint value to reverse hint */ + if ((hP->label >= 0) && (hP->label < MAXLABEL)) + { + if (oldHint[hP->label].inuse) + { + thisHint.x = -oldHint[hP->label].hint.x; + thisHint.y = -oldHint[hP->label].hint.y; + oldHint[hP->label].inuse = FALSE; + } + else /* error */ + { + Abort("ProcessHint: label is not in use"); + } + } + else /* error */ + { + Abort("ProcessHint: invalid label"); + } + + } + else /* error */ + { + Abort("ProcessHint: invalid adjusttype"); + } + + hintP->x += thisHint.x; + hintP->y += thisHint.y; +} + +/* +:h2 id=subpath.Navigation Through Edge Lists + +For continuity checking purposes, we need to navigate through edge +lists by the "subpath" chains and answer questions about edges. The +subpath chain links together edges that were part of the same subpath +(no intervening move segments) when the interior of the path was +calculated. Here we use the term "edge" to mean every edge list +that was created in between changes of direction. + +The subpath chains are singly-linked circular chains. For the convenience +of building them, they direction of the list (from edge to edge) is the +reverse of the order in which they were built. Within any single edge, +the subpath chain goes from top-to-bottom. (There might be a violation +of this because of the way the user started the first chain; see +:hdref refid=fixsubp..). + +:h3.ISTOP() and ISBOTTOM() - Flag Bits for Edge Lists at the Top and +Bottom of Their SubPaths +*/ + +#define ISTOP(flag) ((flag)&0x20) +#define ISBOTTOM(flag) ((flag)&0x10) +/* +:h3.ISLEFT() - Flag Bit for Left Edges +*/ + +#define ISLEFT(flag) ((flag)&0x08) + +/* +:h3.XofY() - Macro to Find X Value at Given Y + +This macro can only be used if it is known that the Y is within the +given edgelist's ymin and ymax. +*/ + +#define XofY(edge, y) edge->xvalues[y - edge->ymin] + +/* +:h3.findXofY() - Like XofY(), Except not Restricted + +If the Y is out of bounds of the given edgelist, this macro will +call SearchXofY to search the edge's subpath chain for the correct +Y range. If the Y value is off the edge, MINPEL is returned. +*/ +#define findXofY(edge, y) ((y < edge->ymin || y >= edge->ymax) ? SearchXofY(edge, y) : XofY(edge, y)) + +/* +:h4.SearchXofY() - Routine Called by FindXofY() for Difficult Cases + +The concept of this routine is to follow the subpath chain to find the +edge just below (i.e., next in chain) or just above (i.e., immediately +before in chain. It is assumed that the Y value is no more than one +off of the edge's range; XofY() could be replace by FindXofY() to +call ourselves recursively if this were not true. +*/ + +static pel +SearchXofY(register struct edgelist *edge, /* represents edge */ + register pel y) /* 'y' value to find edge for */ +{ + register struct edgelist *e; /* loop variable */ + + if (y < edge->ymin) { + if (ISTOP(edge->flag)) + return(MINPEL); + for (e = edge->subpath; e->subpath != edge; e = e->subpath) { ; } + if (e->ymax == edge->ymin) + return(XofY(e, y)); + } + else if (y >= edge->ymax) { + if (ISBOTTOM(edge->flag)) + return(MINPEL); + e = edge->subpath; + if (e->ymin == edge->ymax) + return(XofY(e, y)); + } + else + return(XofY(edge, y)); + + Abort("bad subpath chain"); + /*NOTREACHED*/ +} +/* +:h3.ISBREAK() Macro - Tests if an Edge List is at a "Break" + +The subpath chains are organized top to bottom. When the bottom of +a given edge is reached, the subpath chain points to the top of the +next edge. We call this a "break" in the chain. The following macro +is the simple test for the break condition: +*/ + +#define ISBREAK(top,bot) (top->ymax != bot->ymin) + + +/* +:h3.ImpliedHorizontalLine() - Tests for Horizontal Connectivity + +This function returns true if two edges are connected horizontally. +They are connected horizontally if they are consecutive in the subpath, +and either we are at the bottom and the first edge is going down or we +are at the top and the first edge is going up. +*/ + +#define BLACKABOVE -1 +#define BLACKBELOW +1 +#define NONE 0 + +static int +ImpliedHorizontalLine(struct edgelist *e1, /* two edges to check */ + struct edgelist *e2, + int y) /* y where they might be connected */ +{ + register struct edgelist *e3,*e4; + + if (ISDOWN(e1->flag) == ISDOWN(e2->flag)) + return(NONE); /* can't be consecutive unless different directions */ +/* +Now we check for consecutiveness: Can we get from 'e1' to 'e2' with +only one intervening break? Can we get from 'e2' to 'e1' with only one +intervening break? 'e3' will be as far as we can get after 'e1'; 'e4' +will be has far as we can get after 'e2': +*/ + for (e3 = e1; !ISBREAK(e3, e3->subpath); e3 = e3->subpath) { ; } + for (e3 = e3->subpath; e3 != e2; e3 = e3->subpath) + if (ISBREAK(e3, e3->subpath)) + break; + + for (e4 = e2; !ISBREAK(e4, e4->subpath); e4 = e4->subpath) { ; } + for (e4 = e4->subpath; e4 != e1; e4 = e4->subpath) + if (ISBREAK(e4, e4->subpath)) + break; +/* +If the edges are mutually consecutive, we must have horizontal lines +both top and bottom: +*/ + if (e3 == e2 && e4 == e1) + return(TRUE); +/* +If the edges are not consecutive either way, no horizontal lines are +possible: +*/ + if (e3 != e2 && e4 != e1) + return(NONE); +/* +Now let's swap 'e1' and 'e2' if necessary to enforce the rule that 'e2' +follows 'e1'. Remember that subpath chains go in the opposite direction +from the way the subpaths were built; this led to the simplest way +do build them. +*/ + if (e4 != e1) { + e2 = e1; + e1 = e3; /* remember e3 == e2, this just swaps 'e1' and 'e2' */ + } +/* +Now we have everything to return the answer: +*/ + if (ISTOP(e1->flag) && y == e1->ymin) + return(ISDOWN(e2->flag)); + else if (ISBOTTOM(e1->flag) && y == e1->ymax) + return(!ISDOWN(e2->flag)); + else + Abort("ImpliedHorizontalLine: why ask?"); + /*NOTREACHED*/ +} + +/* +:h3 id=fixsubp.FixSubPaths() - Must be Called to Organize Subpath Chains + +The region-building code in Interior(), in particular splitedge(), +maintains the rule that sub-paths are linked top-to-bottom except +at breaks. However, it is possible that there may be a "false break" +because the user started the subpath in the middle of an edge (and +went in the "wrong" direction from there, up instead of down). This +routine finds and fixes false breaks. + +Also, this routine sets the ISTOP and ISBOTTOM flags in the edge lists. +*/ + +static void +FixSubPaths(struct region *R) /* anchor of region */ +{ + register struct edgelist *e; /* fast loop variable */ + register struct edgelist *edge; /* current edge in region */ + register struct edgelist *next; /* next in subpath after 'edge' */ + register struct edgelist *break1; /* first break after 'next' */ + register struct edgelist *break2 = NULL; /* last break before 'edge' */ + register struct edgelist *prev; /* previous edge for fixing links */ + int left = TRUE; + + for (edge = R->anchor; edge != NULL; edge = edge->link) { + + if (left) + edge->flag |= ISLEFT(ON); + left = !left; + + next = edge->subpath; + + if (!ISBREAK(edge, next)) + continue; + if (edge->ymax < next->ymin) + Abort("disjoint subpath?"); +/* +'edge' now contains an edgelist at the bottom of an edge, and 'next' +contains the next subsequent edgelist in the subpath, which must be at +the top. We refer to this a "break" in the subpath. +*/ + next->flag |= ISTOP(ON); + edge->flag |= ISBOTTOM(ON); + + if (ISDOWN(edge->flag) != ISDOWN(next->flag)) + continue; +/* +We are now in the unusual case; both edges are going in the same +direction so this must be a "false break" due to the way that the user +created the path. We'll have to fix it. +*/ + for (break1 = next; !ISBREAK(break1, break1->subpath); break1 = break1->subpath) { ; } + + for (e = break1->subpath; e != edge; e = e->subpath) + if (ISBREAK(e, e->subpath)) + break2 = e; +/* +Now we've set up 'break1' and 'break2'. I've found the following +diagram invaluable. 'break1' is the first break after 'next'. 'break2' +is the LAST break before 'edge'. +&drawing. + next + +------+ +---->+------+ + +--->| >-----+ | | >-----+ + | | | | | | | | + | +-------------+ | +-------------+ + | | |break1| | | | | + | +->| >-------+ +->| >-----+ + | | | | | | + | | | +-------------+ + | +------+ | | | + | +----------------+ | | | + | | +------+ | +->| >-----+ + | +->| >-----+ | | | | + | | | | | +-------------+ + | +-------------+ | | | | + | | |edge | | | |break2| + | +->| >-----+ | +->| >-----+ + | | | | | | | | + | | | | | | | | + | | | | | | | | + | +------+ | | +------+ | + | | | | + +---------------+ +---------------+ + +&edrawing. +We want to fix this situation by having 'edge' point to where 'break1' +now points, and having 'break1' point to where 'break2' now points. +Finally, 'break2' should point to 'next'. Also, we observe that +'break1' can't be a bottom, and is also not a top unless it is the same +as 'next': +*/ + edge->subpath = break1->subpath; + + break1->subpath = break2->subpath; + if (ISBREAK(break1, break1->subpath)) + Abort("unable to fix subpath break?"); + + break2->subpath = next; + + break1->flag &= ~ISBOTTOM(ON); + if (break1 != next) + break1->flag &= ~ISTOP(ON); + } +/* +This region might contain "ambiguous" edges; edges exactly equal to +edge->link. Due to the random dynamics of where they get sorted into +the list, they can yield false crossings, where the edges appear +to cross. This confuses our continuity logic no end. Since we can +swap them without changing the region, we do. +*/ + for (edge = R->anchor, prev = NULL; VALIDEDGE(edge); prev = edge, edge = prev->link) { + + if (! ISAMBIGUOUS(edge->flag)) + continue; + + next = edge->subpath; + + while (ISAMBIGUOUS(next->flag) && next != edge) + next = next->subpath; +/* +We've finally found a non-ambiguous edge; we make sure it is left/right +compatible with 'edge': +*/ + if ( (ISLEFT(edge->flag) == ISLEFT(next->flag) && ISDOWN(edge->flag) == ISDOWN(next->flag) ) + || (ISLEFT(edge->flag) != ISLEFT(next->flag) && ISDOWN(edge->flag) != ISDOWN(next->flag) ) ) + continue; + +/* +Incompatible, we will swap 'edge' and the following edge in the list. +You may think that there must be a next edge in this swath. So did I. +No! If there is a totally ambiguous inner loop, for example, we could +get all the way to the outside without resolving ambiguity. +*/ + next = edge->link; /* note new meaning of 'next' */ + if (next == NULL || edge->ymin != next->ymin) + continue; + if (prev == NULL) + R->anchor = next; + else + prev->link = next; + edge->link = next->link; + next->link = edge; + edge->flag ^= ISLEFT(ON); + edge->flag &= ~ISAMBIGUOUS(ON); + next->flag ^= ISLEFT(ON); + next->flag &= ~ISAMBIGUOUS(ON); + edge = next; + } +} +/* +:h3.DumpSubPaths() + +A debug tool. +*/ + +static struct edgelist *before(struct edgelist *e); /* subroutine of DumpSubPaths */ + +static void +DumpSubPaths(struct edgelist *anchor) +{ + + register struct edgelist *edge,*e,*e2; + pel y; + + for (edge = anchor; VALIDEDGE(edge); edge = edge->link) { + if (ISPERMANENT(edge->flag)) + continue; + for (e2 = edge; !ISPERMANENT(e2->flag);) { + if (ISDOWN(e2->flag)) { + for (e = e2;; e = e->subpath) { + for (y=e->ymin+1; y < e->ymax; y++) + e->flag |= ISPERMANENT(ON); + if (ISBREAK(e, e->subpath)) + break; + } + } + else { + for (e = e2; !ISBREAK(e, e->subpath); e = e->subpath) { ; } + for (;; e=before(e)) { + for (y=e->ymax-2; y >= e->ymin; y--) + e->flag |= ISPERMANENT(ON); + if (e == e2) + break; + } + } + do { + e2 = before(e2); + } while (!ISBREAK(before(e2), e2)); + } + } +} + +static struct edgelist * +before(struct edgelist *e) +{ + struct edgelist *r; + for (r = e->subpath; r->subpath != e; r = r->subpath) { ; } + return(r); +} + +/* +:h2.Fixing Region Continuity Problems + +Small regions may become disconnected when their connecting segments are +less than a pel wide. This may be correct in some applications, but in +many (especially small font characters), it is more pleasing to keep +connectivity. ApplyContinuity() (invoked by +CONTINUITY on the +Interior() fill rule) fixes connection breaks. The resulting region +is geometrically less accurate, but may be more pleasing to the eye. +*/ +/* +Here are some macros which we will need: +*/ + +#define IsValidPel(j) (j!=MINPEL) + +/* +:h3.writeXofY() - Stuffs an X Value Into an "edgelist" + +writeXofY writes an x value into an edge at position 'y'. It must +update the edge's xmin and xmax. If there is a possibility that this +new x might exceed the region's bounds, updating those are the +responsibility of the caller. +*/ + +static void +writeXofY(struct edgelist *e,/* relevant edgelist */ + int y, /* y value */ + int x) /* new x value */ +{ + if (e->xmin > x) e->xmin = x; + if (e->xmax < x) e->xmax = x; + e->xvalues[y - e->ymin] = x; +} + +/*-------------------------------------------------------------------------*/ +/* the following three macros tell us whether we are at a birth point, a */ +/* death point, or simply in the middle of the character */ +/*-------------------------------------------------------------------------*/ +#define WeAreAtTop(e,i) (ISTOP(e->flag) && e->ymin == i) +#define WeAreAtBottom(e,i) (ISBOTTOM(e->flag) && e->ymax-1 == i) +#define WeAreInMiddle(e,i) \ + ((!ISTOP(e->flag) && !ISBOTTOM(e->flag))||(i < e->ymax-1 && i > e->ymin)) +/* +The following macro tests if two "edgelist" structures are in the same +swath: +*/ +#define SAMESWATH(e1,e2) (e1->ymin == e2->ymin) + +/* +:h3.CollapseWhiteRun() - Subroutine of ApplyContinuity() + +When we have a white run with an implied horizontal line above or +below it, we better have black on the other side of this line. This +function both tests to see if black is there, and adjusts the end +points (collapses) the white run as necessary if it is not. The +goal is to collapse the white run as little as possible. +*/ + +static void +CollapseWhiteRun(struct edgelist *anchor, /* anchor of edge list */ + pel yblack, /* y of (hopefully) black run above or below */ + struct edgelist *left, /* edgelist at left of WHITE run */ + struct edgelist *right, /* edgelist at right of WHITE run */ + pel ywhite) /* y location of white run */ +{ + struct edgelist *edge; + struct edgelist *swathstart = anchor; + register pel x; + + if (XofY(left, ywhite) >= XofY(right, ywhite)) + return; +/* +Find the swath with 'yblack'. If we don't find it, completely collapse +the white run and return: +*/ + while (VALIDEDGE(swathstart)) { + if (yblack < swathstart->ymin) { + writeXofY(left, ywhite, XofY(right, ywhite)); + return; + } + if (yblack < swathstart->ymax) break; + swathstart = swathstart->link->link; + } + if(!VALIDEDGE(swathstart)) { + writeXofY(left, ywhite, XofY(right, ywhite)); + return; + } +/* +Now we are in the swath that contains 'y', the reference line above +or below that we are trying to maintain continuity with. If black +in this line begins in the middle of our white run, we must collapse +the white run from the left to that point. If black ends in the +middle of our white run, we must collapse the white run from the right +to that point. +*/ + for (edge = swathstart; VALIDEDGE(edge); edge = edge->link) { + + if (!SAMESWATH(swathstart,edge)) + break; + if( XofY(edge, yblack) > XofY(left, ywhite)) { + if (ISLEFT(edge->flag)) { + x = XofY(edge, yblack); + if (XofY(right, ywhite) < x) + x = XofY(right, ywhite); + writeXofY(left, ywhite, x); + } + else { + x = XofY(edge, yblack); + while (edge->link != NULL && SAMESWATH(edge, edge->link) + && x >= XofY(edge->link, yblack) ) { + edge = edge->link->link; + x = XofY(edge, yblack); + } + if (x < XofY(right, ywhite)) + writeXofY(right, ywhite, x); + return; + } + } + } + writeXofY(left, ywhite, XofY(right, ywhite)); +} + +/* +:h3.ApplyContinuity() - Fix False Breaks in a Region + +This is the externally visible routine called from the REGIONS module +when the +CONTINUITY flag is on the Interior() fill rule. +*/ + +void +ApplyContinuity(struct region *R) +{ + struct edgelist *left; + struct edgelist *right; + struct edgelist *edge,*e2; + pel rightXabove,rightXbelow,leftXabove,leftXbelow; + pel leftX,rightX; + int i; + long newcenter,abovecenter,belowcenter; + + FixSubPaths(R); + if (RegionDebug >= 3) + DumpSubPaths(R->anchor); + left = R->anchor; +/* loop through and do all of the easy checking. ( no tops or bottoms) */ + while(VALIDEDGE(left)) + { + right = left->link; + for(i=left->ymin;i<left->ymax;++i) + { + leftX = findXofY(left,i); + rightX = findXofY(right,i); + leftXbelow = findXofY(left,i+1); + rightXbelow = findXofY(right,i+1); + if(rightX <= leftX) + { +/* then, we have a break in a near vertical line */ + leftXabove = findXofY(left,i-1); + rightXabove = findXofY(right,i-1); + if( IsValidPel(leftXabove) && IsValidPel(rightXabove) ) + { + abovecenter = leftXabove + rightXabove; + } + else + { + abovecenter = leftX + rightX; + } + if( IsValidPel(leftXbelow) && IsValidPel(rightXbelow) ) + { + belowcenter = leftXbelow + rightXbelow; + } + else + { + belowcenter = leftX + rightX; + } + newcenter = abovecenter + belowcenter; + if( newcenter > 4*leftX ) + { + rightX = rightX + 1; + } + else if( newcenter < 4*leftX) + { + leftX = leftX - 1; + } + else + { + rightX = rightX + 1; + } + writeXofY(right,i,rightX); + writeXofY(left,i,leftX); + if(rightX > R->xmax) {R->xmax = rightX;} + if(leftX < R->xmin) {R->xmin = leftX;} + } + if( !WeAreAtBottom(left,i) && (leftXbelow>=rightX)) + { +/* then we have a break in a near horizontal line in the middle */ + writeXofY(right,i,leftXbelow); + } + if( !WeAreAtBottom(right,i) && (leftX >=rightXbelow)) + { +/* then we have a break in a near horizontal line in the middle */ + writeXofY(left,i,rightXbelow); + } + } + left = right->link; + } +/* +There may be "implied horizontal lines" between edges that have +implications for continuity. This loop looks for white runs that +have implied horizontal lines on the top or bottom, and calls +CollapseWhiteRuns to check and fix any continuity problems from +them. +*/ + for (edge = R->anchor; VALIDEDGE(edge); edge = edge->link) { + if ((!ISTOP(edge->flag) && !ISBOTTOM(edge->flag)) || ISLEFT(edge->flag)) + continue; /* at some future date we may want left edge logic here too */ + for (e2 = edge->link; VALIDEDGE(e2) && SAMESWATH(edge,e2); e2 = e2->link) { + if (ISTOP(e2->flag) && ISTOP(edge->flag) + && NONE != ImpliedHorizontalLine(edge,e2,edge->ymin)) { + if (ISLEFT(e2->flag)) + CollapseWhiteRun(R->anchor, edge->ymin-1, + edge, e2, edge->ymin); + } + if (ISBOTTOM(e2->flag) && ISBOTTOM(edge->flag) + && NONE != ImpliedHorizontalLine(edge,e2, edge->ymax)) { + if (ISLEFT(e2->flag)) + CollapseWhiteRun(R->anchor, edge->ymax, + edge, e2, edge->ymax-1); + } + } + } +} + + + + diff --git a/nx-X11/lib/font/Type1/hints.h b/nx-X11/lib/font/Type1/hints.h new file mode 100644 index 000000000..8e2ae2ade --- /dev/null +++ b/nx-X11/lib/font/Type1/hints.h @@ -0,0 +1,48 @@ +/* $Xorg: hints.h,v 1.3 2000/08/17 19:46:30 cpqbld Exp $ */ +/* Copyright International Business Machines, Corp. 1991 + * All Rights Reserved + * Copyright Lexmark International, Inc. 1991 + * All Rights Reserved + * + * License to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, + * provided that the above copyright notice appear in all copies and that + * both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of IBM or Lexmark not be + * used in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * + * IBM AND LEXMARK PROVIDE THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES OF + * ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO ANY + * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, + * AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE + * QUALITY AND PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT + * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF THE + * SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM OR LEXMARK) ASSUMES THE + * ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN NO EVENT SHALL + * IBM OR LEXMARK BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF + * THIS SOFTWARE. + */ +/* $XFree86: xc/lib/font/Type1/hints.h,v 1.3 1999/08/22 08:58:51 dawes Exp $ */ + +/*SHARED*/ + +#define InitHints t1_InitHints +extern void t1_InitHints ( void ); /* Initialize hint data structure */ + +#define CloseHints(hintP) t1_CloseHints(hintP) +/* Reverse hints that are still open */ +extern void t1_CloseHints ( struct fractpoint *hintP ); + +#define ProcessHint(hP, currX, currY, hintP) t1_ProcessHint(hP, currX, currY, hintP) +/* Process a rasterization hint */ +extern void t1_ProcessHint ( struct hintsegment *hP, fractpel currX, fractpel currY, struct fractpoint *hintP ); + +#define ApplyContinuity(R) t1_ApplyContinuity(R) +/* fix false connection breaks in a region */ +extern void t1_ApplyContinuity ( struct region *R ); + +/*END SHARED*/ diff --git a/nx-X11/lib/font/Type1/lines.c b/nx-X11/lib/font/Type1/lines.c new file mode 100644 index 000000000..835afc6ed --- /dev/null +++ b/nx-X11/lib/font/Type1/lines.c @@ -0,0 +1,189 @@ +/* $Xorg: lines.c,v 1.3 2000/08/17 19:46:30 cpqbld Exp $ */ +/* Copyright International Business Machines, Corp. 1991 + * All Rights Reserved + * Copyright Lexmark International, Inc. 1991 + * All Rights Reserved + * + * License to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, + * provided that the above copyright notice appear in all copies and that + * both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of IBM or Lexmark not be + * used in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * + * IBM AND LEXMARK PROVIDE THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES OF + * ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO ANY + * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, + * AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE + * QUALITY AND PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT + * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF THE + * SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM OR LEXMARK) ASSUMES THE + * ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN NO EVENT SHALL + * IBM OR LEXMARK BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF + * THIS SOFTWARE. + */ +/* $XFree86: xc/lib/font/Type1/lines.c,v 1.4tsi Exp $ */ + + /* LINES CWEB V0003 ******** */ +/* +:h1.LINES Module - Rasterizing Lines + +&author. Duaine W. Pryor, Jr. and Jeffrey B. Lotspiech (lotspiech@almaden.ibm.com) + + +:h3.Include Files + +The included files are: +*/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include "objects.h" +#include "spaces.h" +#include "paths.h" +#include "regions.h" +#include "lines.h" + +/* +:h3.Functions Provided to the TYPE1IMAGER User + +None. +*/ + +/* +:h3.Functions Provided to Other Modules + +This module provides the following entry point to other modules: +*/ + +/*SHARED LINE(S) ORIGINATED HERE*/ + +/* +:h3.Macros Provided to Other Modules + +None. +*/ + +/* +:h2.StepLine() - Produces Run Ends for a Line After Checks + +The main work is done by Bresenham(); here we just perform checks and +get the line so that its Y direction is always increasing: +*/ + +void StepLine(R, x1, y1, x2, y2) + register struct region *R; /* region being built */ + register fractpel x1,y1; /* starting point */ + register fractpel x2,y2; /* ending point */ +{ + register fractpel dy; + + dy = y2 - y1; + +/* +We execute the "GOING_TO" macro to call back the REGIONS module, if +necessary (like if the Y direction of the edge has changed): +*/ + GOING_TO(R, x1, y1, x2, y2, dy); + + if (dy == 0) + return; + + if (dy < 0) + Bresenham(R->edge, x2, y2, x1, y1); + else + Bresenham(R->edge, x1, y1, x2, y2); + return; +} +/* +:h3.Bresenham() - Actually Produces Run Ends + +This routine runs a Bresenham line-stepping +algorithm. See, for example, Newman and Sproul, :hp1/Principles +of Interactive Computer Graphics/, pp. 25-27. +When we enter this, we +are guaranteed that dy is positive. +We'd like to work in 8 bit precision, so we'll define some macros and +constants to let us do that: +*/ + +#define PREC 8 /* we'll keep fraction pels in 8 bit precision */ +/* +RoundFP() rounds down by 'b' bits: +*/ +#define RoundFP(xy,b) (((xy)+(1<<((b)-1)))>>(b)) + +/* +TruncFP() truncates down by 'b' bits: +*/ +#define TruncFP(xy,b) ((xy)>>(b)) + + +void Bresenham(edgeP,x1,y1,x2,y2) + register pel *edgeP; /* pointer to top of list (y == 0) */ + register fractpel x1,y1; /* starting point on line */ + register fractpel x2,y2; /* ending point on the line (down) */ +{ + register long dx,dy; /* change in x and y, in my own precision */ + register long x,y; /* integer pel starting point */ + register int count; /* integer pel delta y */ + register long d; /* the Bresenham algorithm error term */ + + x1 = TruncFP(x1, FRACTBITS-PREC); + y1 = TruncFP(y1, FRACTBITS-PREC); + x2 = TruncFP(x2, FRACTBITS-PREC); + y2 = TruncFP(y2, FRACTBITS-PREC); + + dx = x2 - x1; + dy = y2 - y1; +/* +Find the starting x and y integer pel coordinates: +*/ + + x = RoundFP(x1,PREC); + y = RoundFP(y1,PREC); + edgeP += y; + count = RoundFP(y2,PREC) - y; +/*------------------------------------------------------------------*/ +/* Force dx to be positive so that dfy will be negative */ +/* this means that vertical moves will decrease d */ +/*------------------------------------------------------------------*/ + if (dx<0) + { + dx = -dx; +#define P PREC + d=(dy*(x1-(x<<P)+(1<<(P-1)))-dx*((y<<P)-y1+(1<<(P-1))))>>P; +#undef P + while(--count >= 0 ) + { + while(d<0) + { + --x; + d += dy; + } + *(edgeP++) = x; + d -= dx; + } + } + else /* positive dx */ + { +#define P PREC + d = (dy*((x<<P)-x1+(1<<(P-1)))-dx*((y<<P)-y1+(1<<(P-1))))>>P; +#undef P + while(--count >= 0 ) + { + while(d<0) + { + ++x; + d += dy; + } + *(edgeP++) = x; + d -= dx; + } + } +} diff --git a/nx-X11/lib/font/Type1/lines.h b/nx-X11/lib/font/Type1/lines.h new file mode 100644 index 000000000..f8ffd3a43 --- /dev/null +++ b/nx-X11/lib/font/Type1/lines.h @@ -0,0 +1,39 @@ +/* $Xorg: lines.h,v 1.3 2000/08/17 19:46:30 cpqbld Exp $ */ +/* Copyright International Business Machines, Corp. 1991 + * All Rights Reserved + * Copyright Lexmark International, Inc. 1991 + * All Rights Reserved + * + * License to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, + * provided that the above copyright notice appear in all copies and that + * both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of IBM or Lexmark not be + * used in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * + * IBM AND LEXMARK PROVIDE THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES OF + * ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO ANY + * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, + * AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE + * QUALITY AND PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT + * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF THE + * SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM OR LEXMARK) ASSUMES THE + * ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN NO EVENT SHALL + * IBM OR LEXMARK BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF + * THIS SOFTWARE. + */ +/* $XFree86: xc/lib/font/Type1/lines.h,v 1.3 1999/08/22 08:58:52 dawes Exp $ */ + +/*SHARED*/ + +#define StepLine(R,x1,y1,x2,y2) t1_StepLine(R,x1,y1,x2,y2) +#define Bresenham(e,x1,y1,x2,y2) t1_Bresenham(e,x1,y1,x2,y2) + +extern void t1_StepLine ( struct region *R, fractpel x1, fractpel y1, fractpel x2, fractpel y2 ); +extern void t1_Bresenham ( pel *edgeP, fractpel x1, fractpel y1, fractpel x2, fractpel y2 ); + +/*END SHARED*/ diff --git a/nx-X11/lib/font/Type1/minimain.c b/nx-X11/lib/font/Type1/minimain.c new file mode 100644 index 000000000..4aa826dc1 --- /dev/null +++ b/nx-X11/lib/font/Type1/minimain.c @@ -0,0 +1,48 @@ +/* $Xorg: minimain.c,v 1.4 2001/02/09 02:04:01 xorgcvs Exp $ */ + +/* + +Copyright 1993, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + +*/ + +#include "ximager5.h" + +main() +{ + XYspace S; + path p; + + InitImager(); + S = Scale(IDENTITY, 300.0, -300.0); + p = Join(Line(Loc(S, 0.0, 1.0)), Line(Loc(S, 1.0, 0.0))); + Interior(ClosePath(p), EVENODDRULE); +} + +void Trace() +{ +} + +void *DEFAULTDEVICE; diff --git a/nx-X11/lib/font/Type1/module/Imakefile b/nx-X11/lib/font/Type1/module/Imakefile new file mode 100644 index 000000000..db8ab54f7 --- /dev/null +++ b/nx-X11/lib/font/Type1/module/Imakefile @@ -0,0 +1,99 @@ +XCOMM $XFree86: xc/lib/font/Type1/module/Imakefile,v 1.6 1999/08/14 10:49:18 dawes Exp $ + +#define IHaveModules +#include <Server.tmpl> + +INCLUDES = -I$(FONTINCSRC) -I../ -I../../include -I$(XINCLUDESRC) \ + -I$(SERVERSRC)/include + +#if BuildCID +CIDSRCS = cidchar.c afm.c +CIDOBJS = cidchar.o afm.o +#if HasUsableFileMmap +MMAPDEFINES = -DUSE_MMAP +#endif +CIDDEFINES = -DBUILDCID -DHAVE_CFM $(MMAPDEFINES) +#endif + +DEFINES = -DFONTMODULE $(CIDDEFINES) + +SRCS = \ + arith.c \ + curves.c \ + fontfcn.c \ + hints.c \ + lines.c \ + objects.c \ + paths.c \ + regions.c \ + scanfont.c \ + spaces.c \ + t1funcs.c \ + t1info.c \ + t1io.c \ + t1malloc.c \ + t1snap.c \ + t1stub.c \ + token.c \ + type1.c \ + util.c \ + t1unicode.c \ + $(CIDSRCS) \ + type1mod.c + +OBJS = \ + arith.o \ + curves.o \ + fontfcn.o \ + hints.o \ + lines.o \ + objects.o \ + paths.o \ + regions.o \ + scanfont.o \ + spaces.o \ + t1funcs.o \ + t1info.o \ + t1io.o \ + t1malloc.o \ + t1snap.o \ + t1stub.o \ + token.o \ + type1.o \ + util.o \ + t1unicode.o \ + $(CIDOBJS) \ + type1mod.o + +LinkSourceFile(arith.c,..) +LinkSourceFile(curves.c,..) +LinkSourceFile(fontfcn.c,..) +LinkSourceFile(hints.c,..) +LinkSourceFile(lines.c,..) +LinkSourceFile(objects.c,..) +LinkSourceFile(paths.c,..) +LinkSourceFile(regions.c,..) +LinkSourceFile(scanfont.c,..) +LinkSourceFile(spaces.c,..) +LinkSourceFile(t1funcs.c,..) +LinkSourceFile(t1info.c,..) +LinkSourceFile(t1io.c,..) +LinkSourceFile(t1malloc.c,..) +LinkSourceFile(t1snap.c,..) +LinkSourceFile(t1stub.c,..) +LinkSourceFile(t1unicode.c,..) +LinkSourceFile(token.c,..) +LinkSourceFile(type1.c,..) +LinkSourceFile(util.c,..) +#if BuildCID +LinkSourceFile(afm.c,..) +LinkSourceFile(cidchar.c,..) +#endif + +ModuleObjectRule() +LibraryModuleTarget(type1,$(OBJS)) +InstallLibraryModule(type1,$(MODULEDIR),fonts) + +DependTarget() + +InstallDriverSDKLibraryModule(type1,$(DRIVERSDKMODULEDIR),fonts) diff --git a/nx-X11/lib/font/Type1/module/type1mod.c b/nx-X11/lib/font/Type1/module/type1mod.c new file mode 100644 index 000000000..e652591a2 --- /dev/null +++ b/nx-X11/lib/font/Type1/module/type1mod.c @@ -0,0 +1,91 @@ +/* + * Copyright (C) 1998 The XFree86 Project, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of the XFree86 Project shall + * not be used in advertising or otherwise to promote the sale, use or other + * dealings in this Software without prior written authorization from the + * XFree86 Project. + */ +/* $XFree86: xc/lib/font/Type1/module/type1mod.c,v 1.10 2002/12/09 17:29:59 dawes Exp $ */ + +#include "misc.h" + +#include <X11/fonts/fontmod.h> +#include "xf86Module.h" + +#ifdef HAVE_XORG_CONFIG_H +#include <xorg-config.h> +#endif + +static MODULESETUPPROTO(type1Setup); + + /* + * This is the module data function that is accessed when loading + * libtype1 as a module. + */ + +static XF86ModuleVersionInfo VersRec = +{ + "type1", + MODULEVENDORSTRING, + MODINFOSTRING1, + MODINFOSTRING2, + XORG_VERSION_CURRENT, + 1, 0, 2, + ABI_CLASS_FONT, /* Font module */ + ABI_FONT_VERSION, + MOD_CLASS_FONT, + {0,0,0,0} /* signature, to be patched into the file by a tool */ +}; + +XF86ModuleData type1ModuleData = { &VersRec, type1Setup, NULL }; + +extern void Type1RegisterFontFileFunctions(void); +#ifdef BUILDCID +extern void CIDRegisterFontFileFunctions(void); +#endif + +FontModule type1Module = { + Type1RegisterFontFileFunctions, + "Type1", + NULL +}; + +#ifdef BUILDCID +FontModule CIDModule = { + CIDRegisterFontFileFunctions, + "CID", + NULL +}; +#endif + +static pointer +type1Setup(pointer module, pointer opts, int *errmaj, int *errmin) +{ + type1Module.module = module; + LoadFont(&type1Module); +#ifdef BUILDCID + CIDModule.module = module; + LoadFont(&CIDModule); +#endif + + /* Need a non-NULL return */ + return (pointer)1; +} diff --git a/nx-X11/lib/font/Type1/objects.c b/nx-X11/lib/font/Type1/objects.c new file mode 100644 index 000000000..c86587dba --- /dev/null +++ b/nx-X11/lib/font/Type1/objects.c @@ -0,0 +1,1101 @@ +/* $Xorg: objects.c,v 1.3 2000/08/17 19:46:30 cpqbld Exp $ */ +/* Copyright International Business Machines, Corp. 1991 + * All Rights Reserved + * Copyright Lexmark International, Inc. 1991 + * All Rights Reserved + * + * License to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, + * provided that the above copyright notice appear in all copies and that + * both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of IBM or Lexmark not be + * used in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * + * IBM AND LEXMARK PROVIDE THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES OF + * ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO ANY + * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, + * AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE + * QUALITY AND PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT + * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF THE + * SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM OR LEXMARK) ASSUMES THE + * ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN NO EVENT SHALL + * IBM OR LEXMARK BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF + * THIS SOFTWARE. + */ +/* $XFree86: xc/lib/font/Type1/objects.c,v 1.10tsi Exp $ */ + /* OBJECTS CWEB V0025 ******** */ +/* +:h1.OBJECTS Module - TYPE1IMAGER Objects Common Routines + +This module defines and implements the C structures that represent +objects in the TYPE1IMAGER. All common routines for manipulating these +objects are defined in this module. Specific routines for +specific objects are defined in the modules that deal with that +object type. + + +&author. Jeffrey B. Lotspiech (lotspiech@almaden.ibm.com) + + +:h3.Include Files + +The included files are: +*/ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#define GLOBALS 1 /* see :hdref refid=debugvar. */ +/* +The following two includes are C standards; we include them because we +use 'toupper' and the 'str'-type functions in this module. Potentially +these may be defined as macros; if these ".h" files do not exist on your +system it is a pretty safe bet that these are external entry points and +you do do not need to include these header files. +*/ + +#ifndef FONTMODULE +#include <string.h> +#include <ctype.h> +#include <stdarg.h> +#include <stdio.h> +#else +#include "Xdefs.h" /* Bool declaration */ +#include "Xmd.h" /* INT32 declaration */ +#include "os.h" +#include "xf86_ansic.h" +#endif + +/* +override incorrect system functions; for example you might define +a macro for "strcpy" that diverts it to "my_strcpy". +*/ + + /* moved these includes from above the */ + /* was included first (it contains com- */ + /* piler defines). dsr 081291 */ +#include "objects.h" +#include "spaces.h" +#include "paths.h" +#include "regions.h" +#include "fonts.h" +#include "pictures.h" +#include "strokes.h" +#include "cluts.h" + + +static char *TypeFmt(int type); + +/* +:h3.The "pointer" Macro - Define a Generic Pointer + +Sadly, many compilers will give a warning message when a pointer to +one structure is assigned to a pointer to another. We've even seen +some that give severe errors (when the wrong pointer type is used as +an initializer or returned from a function). TYPE1IMAGER has routines +like Dup and Allocate that are perfectly willing to duplicate or +allocate any of a number of different types of structures. How to +declare them in a truely portable way? + +Well, there is no single good answer that I've found. You can always +beg the question and "cast" everything. I find this distracting and the +resulting code ugly. On the other hand, we have found at least one +compiler that will accept "void *" as a generic pointer that can +assigned to any other pointer type without error or warning (apparently +this is also the ANSI standard). So, we define "void *" to be a generic +pointer. (You might have to change this for your compiler; the "ifndef" +allows the change to be made on the command line if you want.) +:i1/portability assumptions/ +*/ +/*SHARED LINE(S) ORIGINATED HERE*/ +/* +:h3.Functions Provided to the TYPE1IMAGER User + +This module provides the following TYPE1IMAGER entry points: +*/ +/*SHARED LINE(S) ORIGINATED HERE*/ +/* +Note that entry points that are intended for use external to TYPE1IMAGER +begin with the characters :q/xi/. Macros are used to make the names +more mnemonic. +*/ + +/* +:h3.Functions Provided to Other Modules + +This module provides the following functions for other modules: +*/ +/*SHARED LINE(S) ORIGINATED HERE*/ +/* +Note that entry points that intended for use within TYPE1IMAGER, but +which must be global because they are used across module boundaries, +begin with the characters :q/I_/. Macros are used to make the names +more mnemonic. + +Entry points totally within a module use mnemonic names and are +declared :hp2/static/. One of the compilers I used had a bug when +static functions were passed as addresses. Thus, some functions +which are logically "static" are not so declared. + +Note also the trick of declaring routines, like Consume(), with a +variable number of arguments. To avoid the restrictions on variable +numbers of arguments in the macro processor, we just replace the +text 'Consume' with 'I_Consume'. +*/ +/* +:h3.Macros Provided to Other Modules + +This is the module where we define all the useful constants like +TRUE, FALSE, and NULL, and simple expressions like MIN(), MAX(), and ABS(). +We might as well get to it right here: +*/ +/*SHARED LINE(S) ORIGINATED HERE*/ +/* +Notice that upper case is used for constant values and macro +definitions. I generally follow that convention. + +Many more global macros are defined later in this module. +*/ +/* +:h2.Basic TYPE1IMAGER Object Structure + +All TYPE1IMAGER objects which are available to the user have a common +header. This header is defined below: +*/ + +/*SHARED LINE(S) ORIGINATED HERE*/ +/* +The following define is an attempt to centralize the definition of the +common xobject data shared by structures that are derived from the +generic xobject structure. For example, the structure font, defined in +fonts.shr : +&code. + struct font { + char type; + char flag; + int references; + ... other data types & structs ... + } +&ecode. +would now be defined as: +&code. + struct font { + XOBJ_COMMON + ... other data types & structs ... + } +&ecode. +Thus we have a better-structured inheritance mechanism. 3-26-91 PNM +*/ +/*SHARED LINE(S) ORIGINATED HERE*/ +/* +:h3.Object Type Definitions + +These constants define the values which go in the 'type' field of +an TYPE1IMAGER object structure: +*/ +/*SHARED LINE(S) ORIGINATED HERE*/ +/* +:h3.Flag Byte Definitions + +Many programmers define flag bits as a mask (for example, 0x04), and +test, set, and reset them as follows: + +&code. + if ((flag & PERMANENT) != 0) + + flag |= PERMANENT; + flag &= &inv.PERMANENT; +:exmp. + +I favor a style where the 'if' statement can ask a question: + +&code. + if (ISPERMANENT(flag)) + + flag |= ISPERMANENT(ON); + flag &= &inv.ISPERMANENT(ON); + +:exmp. +This said, we now define two bit settings of the flag byte of the +object. "ISPERMANENT" will be set by the user, when he calls +Permanent(). "ISIMMORTAL" will be used for compiled-in objects +that we don't want the user to ever destroy. +*/ +/*SHARED LINE(S) ORIGINATED HERE*/ +/* +Flag bit definitions that apply to all objects are assigned +starting with the least significant (0x01) bit. Flag bit definitions +specific to a certain object type are assigned starting with the +most significant (0x80) bit. We hope they never meet. +*/ +/* +:h3 id=preserve.PRESERVE() Macro + +Occasionally an TYPE1IMAGER operator is implemented by calling other +TYPE1IMAGER operators. For example, Arc2() calls Conic(). When we +call more than one operator as a subroutine, we have to be careful +of temporary objects. A temporary object will be consumed by the +subroutine operator and then is no longer available for the caller. +This can be prevented simply by bumping a temporary object's reference +count. +*/ +/*SHARED LINE(S) ORIGINATED HERE*/ + +/* +:h3.RefRoll() Macro to Detect References Count Rollover + +The following macro is designed to check for reference count rollover. +A return value of TRUE means rollover has not occurred; a return value +of FALSE means we cannot increment the reference count. Note also that +those functions that use this macro must decrement the reference count +afterwards. 3-26-91 PNM +*/ + +#define RefRoll(obj) (++(obj)->references > 0) + +/* +:h2.TYPE1IMAGER Object Functions + +:h3.LONGCOPY() - Macro to Copy "long" Aligned Data + +Copying arbitrary bytes in C is a bit of a problem. "strcpy" can't be +used, because 0 bytes are special-cased. Most environments have a +routine "memcopy" or "bcopy" or "bytecopy" that copies memory containing +zero bytes. Sadly, there is no standard on the name of such a routine, +which makes it impossible to write truely portable code to use it. + +It turns out that TYPE1IMAGER, when it wants to copy data, frequently +knows that both the source and destination are aligned on "long" +boundaries. This allows us to copy by using "long *" pointers. This +is usually very efficient on almost all processors. Frequently, it +is more efficient than using general-purpose assembly language routines. +So, we define a macro to do this in a portable way. "dest" and "source" +must be long-aligned, and "bytes" must be a multiple of "sizeof(long)": +*/ +/*SHARED LINE(S) ORIGINATED HERE*/ +/* +:h3.Allocate() - Allocating a Memory Block + +Allocate returns a pointer to memory object that is a copy of +the template passed (if any). In addition, extra bytes may be +allocated contiguously with the object. (This may be useful for +variable size objects such as edge lists. See :hdref refid=regions..) + +Allocate() always returns a non-immortal object, even if the template is +immortal. Therefore a non-NULL template must have a "flag" byte. + +If the template is NULL, then 'size' bytes are cleared to all NULLs. + +If the template is non-NULL, a new object is allocated in memory. +It therefore seems logical that its reference count field should be +set to 1. So, a nun-NULL template must also have a "references" field. +PNM 3-26-91 +*/ + +struct xobject * +t1_Allocate(int size, /* number of bytes to allocate & initialize */ + pointer ptr, /* example structure to allocate */ + int extra) /* any extra uninitialized bytes needed contiguously */ +{ + register struct xobject *template = (struct xobject *)ptr; + register struct xobject *r; + + /* + * round up 'size' and 'extra' to be an integer number of 'long's: + */ + size = (size + sizeof(long) - 1) & -(int)sizeof(long); + extra = (extra + sizeof(long) - 1) & -(int)sizeof(long); + if (size + extra <= 0) + Abort("Non-positive allocate?"); + r = (struct xobject *) xiMalloc(size + extra); + + while (r == NULL) { + if (!GimeSpace()) { + Abort("We have REALLY run out of memory"); + } + r = (struct xobject *) xiMalloc(size + extra); + } + + /* + * copy the template into the new memory: + */ + if (template != NULL) { + /* Added references count decrement if template is not permanent. + This is for the case where Allocate is called by a Dupxxxx + function, which was in turn called by Unique(). (PNM) */ + if (!ISPERMANENT(template->flag)) + --template->references; + LONGCOPY(r, template, size); + r->flag &= ~(ISPERMANENT(ON) | ISIMMORTAL(ON)); + /* added reference field 3-2-6-91 PNM */ + r->references = 1; + } + else { + register char **p1; + + for (p1=(char **)r; size > 0; size -= sizeof(char *)) + *p1++ = NULL; + } + + return(r); +} + +/* +:h3.Free() - Frees an Allocated Object + +This routine makes a sanity check to make sure the "type" field of the +standard object structure has not been cleared. If the object is +not a standard structure, then the macro "NonObjectFree" is available +that does not perform this check. + +In either case, the object must not be the NULL pointer. This preserves +portability, as the C system xiFree() will not always accept NULL. +*/ + +void +Free(pointer objPtr) +{ + struct xobject *obj = (struct xobject *)objPtr; /* structure to free */ + + if (obj->type == INVALIDTYPE) + Abort("Free of already freed object?"); + obj->type = INVALIDTYPE; + + xiFree((long *)obj); +} + +/* +:h3.Permanent() - Makes an Object Permanent + +Real simple--just set a flag. Every routine that consumes its objects +(which is almost every user entry) must check this flag, and not consume +the object if it is set. + +If a temporary object is made permanent, and there is more than one +reference to it, we must first Copy() it, then set the ISPERMANENT +flag. Note also that the reference count must be incremented when an +object is changed from temporary to permanent (see the ISUNIQUE macro). + +Note that the purpose of this function is to convert an object into a +permanent object: + If it was permanent to begin with, we do nothing; + If it was temporary and unique, we set the PERMANENT flag and increment +the reference count; + If it was temporary and nonunique, we must make a unique Copy(), set +the PERMANENT flag, and set the reference count to 2. We must also +decrement the original object's reference count, because what we have +done is to change one of the old temporary handles to a permanent one. +3-26-91 PNM +*/ + +struct xobject * +t1_Permanent(pointer objPtr) +{ + struct xobject *obj = (struct xobject *)objPtr; /* object to be made permanent */ + + if ( (obj != NULL) && ( !(ISPERMANENT(obj->flag)) ) ) + { + /* there is a non-NULL, temporary object to be made permanent. + If there are multiple references to this object, first get + a new COPY(). + Note also that we have to decrement the reference count if + we do a Copy() here, because we are consuming the temporary + argument passed, and returning a unique, permanent one. + */ + if ( obj->references > 1) + { + obj = Copy(obj); + } + /* now set the permanent flag, and increment the reference + count, since a temporary object has now become permanent. */ + obj->references++; + obj->flag |= ISPERMANENT(ON); + } + return(obj); +} + +#ifdef notused +/* +:h3.Temporary() - Undoes the Effect of "Permanent()" + +This simply resets the "ISPERMANENT" flag. + +If a permanent object is made temporary, and there is more than one reference +to it, we must first Copy() it, then reset the ISPERMANENT flag. However, +if the permanent object has obly one reference, we need only decrement the +reference count ( and reset the flag). + +Note that this function, in the case of a PERMANENT argument, basically +converts the PERMANENT handle to a TEMPORARY one. Thus, in the case of +a nonunique, permanent argument passed, we not only make a Copy(), +we also decrement the reference count, to reflect the fact that we have +lost a permanent handle and gained a temporary one. +PNM 3-2-6-91 +*/ + +struct xobject * +xiTemporary(pointer objPtr) +{ + register struct xobject *obj + = (struct xobject *)objPtr; /* object to be made permanent */ + if (obj != NULL) { + /* if it's already temporary, there's nothing to do. */ + if ISPERMANENT(obj->flag) + { + /* if there are multiple references to this object, get a + Copy we can safely alter. Recall that the reference count + is incremented for permanent objects. + Recall further that Copy returns an object with the + same flag state and a reference count of 2 (for PERMANENT + objects). + Thus, regardless of whether or not we need to copy a + permanent object, we still decrement its reference + count and reset the flag. + */ + if (obj->references != 2 || ISIMMORTAL(obj->flag)) + { + /* not unique; consume handle, get a temporary Copy! */ + obj = Copy(obj); + } + /* else decrement the reference count (since it's going from + permanent to temporary) and clear the flag. */ + else { + obj->references--; + obj->flag &= ~ISPERMANENT(ON); + } + } + } + return(obj); +} +#endif /* notused */ + +/* +:h3.Dup() - Duplicate an Object + +Dup will increment the reference count of an object, only making a +Copy() if needed. +Note that Dup() retains the state of the permanent flag. +3-26-91 PNM +*/ + + +struct xobject * +t1_Dup(pointer objPtr) +{ + register struct xobject *obj + = (struct xobject *)objPtr; /* object to be duplicated */ + register char oldflag; /* copy of original object's flag byte */ + + if (obj == NULL) + return(NULL); + /* An immortal object must be Copy'ed, so that we get a mortal + copy of it, since we try not to destroy immortal objects. */ + if (ISIMMORTAL(obj->flag)) + return(Copy(obj)); + + /* if incrementing the reference count doesn't cause the count + to wrap, simply return the object with the count bumped. Note + that the RefRoll macro increments the count to perform the + rollover check, so we must decrement the count. */ + if (RefRoll(obj)) + return(obj); + + /* that didn't work out, so put the count back and call Copy(). */ + --obj->references; + oldflag = obj->flag; + obj = Copy(obj); + if (ISPERMANENT(oldflag)) + obj = Permanent(obj); + return(obj); +} + +/* +:h3.Copy() - Make a New Copy of an Object + +This is the generic Copy() where the object type is unknown. There +are specific Copyxxx functions for known object types. + +Copy will create a NEW temporary object, and WILL NOT simply bump the +reference count. + +Sometimes duplicating an object is just as simple as Allocating with it +as a template. But other objects are complicated linked lists. So, we +let each module provide us a routine (or macro) that duplicates the +objects it knows about. +*/ + +struct xobject * +t1_Copy(pointer objPtr) +{ + register struct xobject *obj + = (struct xobject *)objPtr; /* object to be Copy'ed */ + if (obj == NULL) + return(NULL); + + if (ISPATHTYPE(obj->type)) + obj = (struct xobject *) CopyPath((struct segment *)obj); + else + switch (obj->type) { + case SPACETYPE: + obj = (struct xobject *) + CopySpace((struct XYspace *)obj); + break; + case FONTTYPE: + obj = (struct xobject *) CopyFont(obj); break; + case REGIONTYPE: + obj = (struct xobject *) + CopyRegion((struct region *)obj); + break; + case PICTURETYPE: + obj = (struct xobject *) CopyPicture(obj); break; + case LINESTYLETYPE: + obj = (struct xobject *) CopyLineStyle(obj); break; + case STROKEPATHTYPE: + obj = (struct xobject *) CopyStrokePath(obj); break; + case CLUTTYPE: + obj = (struct xobject *) CopyCLUT(obj); break; + default: + return(ArgErr("Copy: invalid object", obj, NULL)); + } + + return(obj); +} + +/* +:h3.Destroy() - Destroys an Object + +This can get complicated. Just like with Copy(), we let the experts +handle it. +*/ +struct xobject * +Destroy(pointer objPtr) +{ + register struct xobject *obj + = (struct xobject *)objPtr; /* object to be destroyed */ + if (obj == NULL) + return(NULL); + if (ISIMMORTAL(obj->flag)) { + return(NULL); + } + if (ISPATHTYPE(obj->type)) + KillPath((struct segment *)obj); + else { + switch (obj->type) { + case REGIONTYPE: + KillRegion((struct region *)obj); + break; + case SPACETYPE: + KillSpace(obj); + break; + case LINESTYLETYPE: + KillLineStyle(obj); + break; + case FONTTYPE: + KillFont(obj); + break; + case PICTURETYPE: + KillPicture(obj); + break; + case STROKEPATHTYPE: + KillStrokePath(obj); + break; + case CLUTTYPE: + KillCLUT(obj); + break; + default: + return(ArgErr("Destroy: invalid object", obj, NULL)); + } + } + return(NULL); +} +/* +:h2.Generally Useful Macros + +:h3.FOLLOWING() - Macro to Point to the Data Following a Structure + +There are several places in TYPE1IMAGER where we will allocate variable +data that belongs to a structure immediately after that structure. +This is a performance technique, because it reduces the number of +trips we have to take through xiMalloc() and xiFree(). It turns out C has +a very convenient way to point past a structure--if 'p' is a pointer +to a structure, 'p+1' is a pointer to the data after it. This +behavior of C is somewhat startling and somewhat hard to follow, if +you are not used to it, so we define a macro to point to the data +following a structure: +*/ +/*SHARED LINE(S) ORIGINATED HERE*/ +/* +:h3.TYPECHECK() - Verify the Type of an Argument + +This macro tests the type of an argument. If the test fails, it consumes +any other arguments as necessary and causes the imbedding routine to +return the value 'whenBAD'. + +Note that the consumeables list should be an argument list itself, for +example (0) or (2,A,B). See :hdref refid=consume. below. +*/ + +/*SHARED LINE(S) ORIGINATED HERE*/ +/* +:h3.ARGCHECK() - Perform an Arbitrary Check on an Argument + +This macro is a generalization of TYPECHECK to take an arbitrary +predicate. If the error occurs (i.e., the predicate is true), the +arbitrary message 'msg' is returned. +*/ + +/*SHARED LINE(S) ORIGINATED HERE*/ +/* +:h3.TYPENULLCHECK() - Extension of TYPECHECK() for NULL arguments + +Many routines allow NULLs to be passed as arguments. 'whenBAD' will +be returned in this case, too. +*/ + +/*SHARED LINE(S) ORIGINATED HERE*/ +/* +:h3.MAKECONSUME() - Create a "Consume"-type Macro + +Consuming an object means destroying it if it is not permanent. This +logic is so common to all the routines, that it is immortalized in this +macro. For example, ConsumePath(p) can be simply defined as +MAKECONSUME(p,KillPath(p)). In effect, this macro operates on a +meta-level. +:i1/consuming objects/ +*/ + +/*SHARED LINE(S) ORIGINATED HERE*/ + +/* +:h3.MAKEUNIQUE() - Create a "Unique"-type Macro + +Many routines are written to modify their arguments in place. Thus, +they want to insure that they duplicate an object if it is permanent. +This is called making an object "unique". For example, UniquePath(p) +can be simply defined as MAKEUNIQUE(p,DupPath(p)). +:i1/unique objects/ +*/ + +/*SHARED LINE(S) ORIGINATED HERE*/ + +/* +An object is unique (and directly alterable) if there is only one +reference to it, and it is not permanent (in which case we increment +the reference count, so we don't have to check the permanent bit). +3-26-91 PNM + +Note the rules for making a unique object: +&drawing. + IF (obj->references = 1) return(obj); + ELSE (references > 1) + IF (ISPERMANENT(obj->flag)) return(Dupxxx(obj)); + ELSE (nonunique, temporary object!) + obj->references--; return(Dupxxx(obj)); +&edrawing. +If we must make a Copy of a nonunique, temporary object, we decrement +reference count of the original object! +*/ + +/* +:h3.Unique() - Make a Unique Object + +Here is a generic 'Unique' function if the object type is not known. +Why didn't we build it with the MAKEUNIQUE macro, you ask? Well, we +used to, but there is at least one damn compiler in the world that +raises errors if the types of an "(a) ? b : c" expression do not match. +Also, when we changed Dup() to retain the permanent/temporary flag, we +wanted to make sure "Unique" always returned a temporary object. + +Note that we cannot use Dup() to create a copy of the object in question, +because Dup() may simply bump the reference count, and not return a +unique copy to us. That is why we use t1_Copy(). + +The purpose of this function is to make sure we have a copy of an object +that we can safely alter: +:ol. +:li.If we have a unique, temporary object, we simply return the argument. +:li.If we have a nonunique, temporary object, we have to make a new copy +of it, and decrement the reference count of the original object, to reflect +the fact that we traded temporary handles. +:li.If we have a permanent object, we make a temporary copy of it, but +we do not decrement the reference count of the original permanent object, +because permanent objects, by definition, are persistent. 3-2-6-91 PNM +:eol. +*/ + +struct xobject * +t1_Unique(pointer objPtr) +{ + struct xobject *obj = (struct xobject *)objPtr; + + /* if the original object is not already unique, make a unique + copy...Note also that if the object was not permanent, we must + consume the old handle! 3-26-91 PNM + NOTE : consumption of the old handle moved to Allocate. 4-18-91 */ + if (!obj || obj->references == 1) + return(obj); + + obj = Copy(obj); + /* and make sure we return a temporary object ! */ + if (ISPERMANENT(obj->flag)) + { + obj->flag &= ~ISPERMANENT(ON); + obj->references--; + } + return(obj); +} + + +/* +:h2.Initialization, Error, and Debug Routines + +:h3 id=debugvar.Declarations for Debug Purposes + +We declare all the debug flags here. Some link editors make the not +unreasonable restriction that only one module may declare and +initialize global variables; all the rest must declare the variable +'extern'. This is logical, but is somewhat awkward to implement with +C include files. We solve the problem by temporarily making the name +'extern' a null name if GLOBALS is defined. (GLOBALS is only defined +in this OBJECTS module.) Since 'externs' can't be initialized, we +have to handle that with #defines too. +:i1/GLOBALS (&#define.)/ +*/ + +/*SHARED LINE(S) ORIGINATED HERE*/ +static char *ErrorMessage = NULL; + +/* +:h3.Pragmatics() - Set/Reset Debug Flags + +We provide a controlled way for the TYPE1IMAGER user to set and reset +our debugging and tracing: +*/ +void +Pragmatics(char *username, /* name of the flag */ + int value) /* value to set it to */ +{ + register char *p; /* temporary loop variable */ +#define NAMESIZE 40 + char name[NAMESIZE]; /* buffer to store my copy of 'username' */ + + if (strlen(username) >= (unsigned)NAMESIZE) + Abort("Pragmatics name too large"); + strcpy(name, username); + for (p = name; *p != '\0'; p++) + *p = toupper(*p); + + if (!strcmp(name, "ALL")) + MustTraceCalls = InternalTrace = /* MustCrash = */ + LineIOTrace = value; + + else if (!strcmp(name, "LINEIOTRACE")) + LineIOTrace = value; + + else if (!strcmp(name, "TRACECALLS")) + MustTraceCalls = value; + + else if (!strcmp(name, "CHECKARGS")) + MustCheckArgs = value; + + else if (!strcmp(name, "PROCESSHINTS")) + ProcessHints = value; + + else if (!strcmp(name, "SAVEFONTPATHS")) + SaveFontPaths = value; + + else if (!strcmp(name, "CRASTERCOMPRESSIONTYPE")) + CRASTERCompressionType = value; + + else if (!strcmp(name, "CRASHONUSERERROR")) + MustCrash = value; + + else if (!strcmp(name, "DEBUG")) + StrokeDebug = SpaceDebug = PathDebug = ConicDebug = LineDebug = + RegionDebug = MemoryDebug = FontDebug = + HintDebug = ImageDebug = OffPageDebug = value; + + else if (!strcmp(name, "CONICDEBUG")) + ConicDebug = value; + + else if (!strcmp(name, "LINEDEBUG")) + LineDebug = value; + + else if (!strcmp(name, "REGIONDEBUG")) + RegionDebug = value; + + else if (!strcmp(name, "PATHDEBUG")) + PathDebug = value; + + else if (!strcmp(name, "SPACEDEBUG")) + SpaceDebug = value; + + else if (!strcmp(name, "STROKEDEBUG")) + StrokeDebug = value; + + else if (!strcmp(name, "MEMORYDEBUG")) + MemoryDebug = value; + + else if (!strcmp(name, "FONTDEBUG")) + FontDebug = value; + + else if (!strcmp(name, "HINTDEBUG")) + HintDebug = value; + + else if (!strcmp(name, "IMAGEDEBUG")) + ImageDebug = value; + + else if (!strcmp(name, "OFFPAGEDEBUG")) + OffPageDebug = value; + +#ifdef MC68000 +/* +The following pragmatics flag turns on or off instruction histograming +for performance analysis. It is only defined in the Delta card +environment. +*/ + else if (!strcmp(name, "PROFILE")) { + if (value) + StartProfile(); + else + StopProfile(); + } +#endif + else if (!strcmp(name, "FLUSHCACHE")) { +#ifdef notdef + while (GimeSpace()) { ; } +#endif + } + + else if (!strcmp(name, "CACHEDCHARS")) + CachedChars = (value <= 0) ? 1 : value; + + else if (!strcmp(name, "CACHEDFONTS")) + CachedFonts = (value <= 0) ? 1 : value; + + else if (!strcmp(name, "CACHEBLIMIT")) + CacheBLimit = value; + + else if (!strcmp(name, "CONTINUITY")) + Continuity = value; + + + else { + printf("Pragmatics flag = '%s'\n", name); + ArgErr("Pragmatics: flag not known", NULL, NULL); + } + return; +} + +/* +:h3.Consume() - Consume a List of Arguments + +This general purpose routine is provided in the case where the object +type(s) to be consumed are unknown or not yet verified, and/or it is +not known whether the object is permanent. + +If the type of the argument is known, it is faster to directly consume +that type, for example, ConsumeRegion() or ConsumePath(). Furthermore, +if it is already known that the object is temporary, it is faster to +just kill it rather than consume it, for example, KillSpace(). +*/ + +void +Consume(int n, ...) +{ + struct xobject *obj; + va_list ap; + + va_start(ap, n); + + while (n-- > 0) { + obj = va_arg(ap, struct xobject *); + if (obj != NULL && !ISPERMANENT(obj->flag)) + Destroy(obj); + } +} + +/* +:h3.TypeErr() - Handles "Invalid Object Type" Errors +*/ + +struct xobject * +TypeErr(char *name, /* Name of routine (for error message) */ + pointer objPtr, /* Object in error */ + int expect, /* type expected */ + pointer retPtr) /* object to return to caller */ +{ + struct xobject *obj = (struct xobject *)objPtr; + struct xobject *ret = (struct xobject *)retPtr; + /* + * This buffer must be large enough to hold 'name' plus + * two of the largest strings that can be returned by TypeFmt. + * The largest value of 'name' is currently 9 ("ClosePath") + * and the longest strings in TypeFmt are 30 characters. + */ + static char typemsg[115]; + + if (MustCrash) + LineIOTrace = TRUE; + + sprintf(typemsg, "Wrong object type in %s. Expected %s; was %s.\n", + name, TypeFmt(expect), TypeFmt(obj->type)); + + if (MustCrash) + Abort("Terminating because of CrashOnUserError..."); + else + ErrorMessage = typemsg; + +/* changed ISPERMANENT to ret->references > 1 3-26-91 PNM */ + if (ret != NULL && (ret->references > 1)) + ret = Dup(ret); + return(ret); +} + +/* +:h4.TypeFmt() - Returns Pointer to English Name of Object Type + +This is a subroutine of TypeErr(). +*/ + +static char * +TypeFmt(int type) /* type field */ +{ + char *r; + + if (ISPATHTYPE(type)) + if (type == TEXTTYPE) + r = "path or region (from TextPath)"; + else + r = "path"; + else { + switch (type) { + case INVALIDTYPE: + r = "INVALID (previously consumed?)"; + break; + case REGIONTYPE: + r = "region"; + break; + case SPACETYPE: + r = "XYspace"; + break; + case LINESTYLETYPE: + r = "linestyle"; + break; + case FONTTYPE: + r = "font"; + break; + case PICTURETYPE: + r = "picture"; + break; + case STROKEPATHTYPE: + r = "path (from StrokePath)"; + break; + default: + r = "UNKNOWN"; + break; + } + } + return(r); +} +/* +:h3.ArgErr() - Invalid Argument Passed to a Routine + +A common routine to report argument errors. It is usually called +is returned to the caller in case MustCrash is FALSE and ArgErr +returns to its caller. +*/ + +struct xobject * +ArgErr(char *string, /* description of error */ + pointer objPtr, /* object, if any, that was in error */ + pointer retPtr) /* object returned to caller or NULL */ +{ + struct xobject *ret = (struct xobject *)retPtr; + + if (MustCrash) + LineIOTrace = TRUE; + + if (MustCrash) + Abort("Terminating because of CrashOnUserError..."); + else + ErrorMessage = string; + return(ret); +} + +/* +:h3.Abort() - Crash Due to Error + +Defined in objects.h to be FatalError(), the server's abort routine. +*/ + +/* +:h3.REAL Miscellaneous Stuff + +:h4.ErrorMsg() - Return the User an Error Message +*/ + +char * +ErrorMsg(void) +{ + register char *r; + + r = ErrorMessage; + ErrorMessage = NULL; + return(r); +} + +/* +:h4.InitImager() - Initialize TYPE1IMAGER + +We check that a short is 16 bits and a long 32 bits; we have made +those assumptions elsewhere in the code. (This is almost a C standard, +anyway.) Note that TYPE1IMAGER makes no assumptions about the size of an +'int'! +:i1/portability assumptions/ +*/ + +void +InitImager(void) +{ + +/* Check to see if we have been using our own malloc. If so,*/ +/* Undef malloc so that we can get to the system call. */ +/* All other calls to malloc are defined to xiMalloc. */ + + +/* if (sizeof(short) != 2 || sizeof(INT32) != 4) + Abort("Fundamental TYPE1IMAGER assumptions invalid in this port"); +*/ + InitSpaces(); + InitFonts(); + InitFiles(); +/* +In some environments, constants and/or exception handling need to be +*/ + LibInit(); +} +/* +:h4.TermImager() - Terminate TYPE1IMAGER + +This only makes sense in a server environment; true TYPE1IMAGER needs do +nothing. +*/ +void +TermImager(void) +{ + return; +} +#ifdef notused +/* +:h4.reportusage() - A Stub to Get a Clean Link with Portable PMP +*/ +void +reportusage(void) +{ + return; +} +#endif diff --git a/nx-X11/lib/font/Type1/objects.h b/nx-X11/lib/font/Type1/objects.h new file mode 100644 index 000000000..7552f98d9 --- /dev/null +++ b/nx-X11/lib/font/Type1/objects.h @@ -0,0 +1,354 @@ +/* $Xorg: objects.h,v 1.3 2000/08/17 19:46:31 cpqbld Exp $ */ +/* Copyright International Business Machines, Corp. 1991 + * All Rights Reserved + * Copyright Lexmark International, Inc. 1991 + * All Rights Reserved + * + * License to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, + * provided that the above copyright notice appear in all copies and that + * both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of IBM or Lexmark not be + * used in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * + * IBM AND LEXMARK PROVIDE THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES OF + * ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO ANY + * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, + * AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE + * QUALITY AND PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT + * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF THE + * SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM OR LEXMARK) ASSUMES THE + * ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN NO EVENT SHALL + * IBM OR LEXMARK BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF + * THIS SOFTWARE. + */ +/* Copyright (c) 1994-1999 Silicon Graphics, Inc. All Rights Reserved. + * + * The contents of this file are subject to the CID Font Code Public Licence + * Version 1.0 (the "License"). You may not use this file except in compliance + * with the Licence. You may obtain a copy of the License at Silicon Graphics, + * Inc., attn: Legal Services, 2011 N. Shoreline Blvd., Mountain View, CA + * 94043 or at http://www.sgi.com/software/opensource/cid/license.html. + * + * Software distributed under the License is distributed on an "AS IS" basis. + * ALL WARRANTIES ARE DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED + * WARRANTIES OF MERCHANTABILITY, OF FITNESS FOR A PARTICULAR PURPOSE OR OF + * NON-INFRINGEMENT. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Software is CID font code that was developed by Silicon + * Graphics, Inc. + */ +/* $XFree86: xc/lib/font/Type1/objects.h,v 1.14tsi Exp $ */ +/*SHARED*/ + +/*END SHARED*/ +#ifdef BUILDCID +#define XFONT_CID 1 +#endif + +#include <X11/Xdefs.h> +#include <X11/Xfuncproto.h> +#ifndef FONTMODULE +#include <stdlib.h> +#endif +/*SHARED*/ + +#define Permanent(obj) t1_Permanent(obj) +#ifdef notused +#define Temporary(obj) t1_Temporary(obj) +#endif +#define Destroy(obj) t1_Destroy(obj) +#define Dup(obj) t1_Dup(obj) +#define InitImager t1_InitImager +#define TermImager t1_TermImager +#define Pragmatics(f,v) t1_Pragmatics(f,v) +#define ErrorMsg t1_ErrorMsg + +/* make an object permanent */ +extern struct xobject *t1_Permanent ( pointer obj ); + +#ifdef notused +/* make an object temporary */ +extern struct xobject *t1_Temporary( pointer obj ); +#endif + +/* destroy an object */ +extern struct xobject *t1_Destroy ( pointer obj ); + +/* duplicate an object */ +extern struct xobject *t1_Dup ( pointer obj ); + + +extern void t1_InitImager ( void ); /* initialize TYPE1IMAGER */ +extern void t1_TermImager ( void ); /* terminate TYPE1IMAGER */ +/* set debug flags, etc. */ +extern void t1_Pragmatics ( char *username, int value ); + +/* return last TYPE1IMAGER error message */ +extern char *t1_ErrorMsg ( void ); + +/*END SHARED*/ +/*SHARED*/ +extern void xiFree ( long *addr ); +extern char *xiMalloc ( unsigned Size ); +extern void addmemory ( long *addr, long size ); +extern void delmemory ( void ); + +#ifndef OS_H +extern void FatalError(const char *f, ...) +#if defined(__GNUC__) && \ + ((__GNUC__ > 2) || ((__GNUC__ == 2) && (__GNUC_MINOR__ > 4))) +__attribute((noreturn)) +#endif +; + +extern void ErrorF(const char *f, ...); +#endif + +#define Abort(line) FatalError(line) +#define Allocate(n,t,s) t1_Allocate(n,t,s) +#define Free(obj) t1_Free(obj) +#define NonObjectFree(a) xiFree((long *)(a)) +#define Consume t1_Consume +#define ArgErr(s,o,r) t1_ArgErr(s,o,r) +#define TypeErr(n,o,e,r) t1_TypeErr(n,o,e,r) +#define Copy(obj) t1_Copy(obj) +#define Unique(obj) t1_Unique(obj) + +/* allocate memory */ +extern struct xobject *t1_Allocate( int size, pointer template, + int extra ); + +/* free memory */ +extern void t1_Free ( pointer obj ); + +/* make a unique temporary copy of an object */ +extern struct xobject *t1_Unique ( pointer obj ); + +/* handle argument errors */ +extern struct xobject *t1_ArgErr ( char *string, pointer obj, pointer ret ); + +/* handle 'bad type' argument errors */ +extern struct xobject *t1_TypeErr ( char *name, pointer obj, + int expect, pointer ret ); + +/* consume a variable number of arguments */ +extern void t1_Consume ( int n, ... ); + +/* make a new copy, not reference bump PNM */ +extern struct xobject *t1_Copy ( pointer obj ); + + +/*END SHARED*/ +/*SHARED*/ + +#define ON (~0) /* all bits on */ +#ifndef FALSE +#define FALSE 0 /* handy zero value */ +#endif +#ifndef TRUE +#define TRUE 1 /* handy non-zero value */ +#endif + +#ifndef NULL +#include <stddef.h> +/* +The NULL pointer is system specific. (Most systems, however, use 0.) +TYPE1IMAGER could have its own NULL, independent of the rest of the system, +were it not for malloc(). The system call malloc() returns NULL when +out of memory. +:i1/portibility assumptions/ +*/ +#endif + +#ifndef MIN +#define MIN(a,b) (((a)<(b)) ? a : b) +#endif +#ifndef MAX +#define MAX(a,b) (((a)>(b)) ? a : b) +#endif +#ifndef ABS +#define ABS(a) (((a)>=0)?(a):-(a)) +#endif + +/*END SHARED*/ +/*SHARED*/ + +struct xobject { + char type; /* encoded type of object */ + unsigned char flag; /* flag byte for temporary object characteristics*/ + short references; /* count of pointers to this object + (plus 1 for permanent objects) PNM */ +} ; + +/*END SHARED*/ +/*SHARED*/ + +#define XOBJ_COMMON char type; unsigned char flag; short references; + +/*END SHARED*/ +/*SHARED*/ + + +#define INVALIDTYPE 0 +#define FONTTYPE 1 +#define REGIONTYPE 3 +#define PICTURETYPE 4 +#define SPACETYPE 5 +#define LINESTYLETYPE 6 +#define EDGETYPE 7 +#define STROKEPATHTYPE 8 +#define CLUTTYPE 9 + +#define ISPATHTYPE(type) ((type)&0x10) /* all path segments have this bit on */ +#define LINETYPE (0+ISPATHTYPE(ON)) +#define CONICTYPE (1+ISPATHTYPE(ON)) +#define BEZIERTYPE (2+ISPATHTYPE(ON)) +#define HINTTYPE (3+ISPATHTYPE(ON)) + +#define MOVETYPE (5+ISPATHTYPE(ON)) +#define TEXTTYPE (6+ISPATHTYPE(ON)) + +/*END SHARED*/ +/*SHARED*/ + +#define ISPERMANENT(flag) ((flag)&0x01) +#define ISIMMORTAL(flag) ((flag)&0x02) + +/*END SHARED*/ +/*SHARED*/ + +#define PRESERVE(obj) if (!ISPERMANENT((obj)->flag)) \ + (obj)->references++; + +/*END SHARED*/ +/*SHARED*/ + +#define LONGCOPY(dest,source,bytes) { \ + register long *p1 = (long *)dest; register long *p2 = (long *)source; \ + register int count = (bytes) / sizeof(long); \ + while (--count >= 0) *p1++ = *p2++; } + + +/*END SHARED*/ +/*SHARED*/ + +#define FOLLOWING(p) ((p)+1) + +/*END SHARED*/ +/*SHARED*/ + +#define TYPECHECK(name, obj, expect, whenBAD, consumables, rettype) { \ + if (obj->type != expect) { \ + (Consume)consumables; \ + return((rettype)TypeErr(name, obj, expect, whenBAD)); \ + } \ +} + +/*END SHARED*/ +/*SHARED*/ + +#define ARGCHECK(test,msg,obj,whenBAD,consumables,rettype) { \ + if (test) { \ + (Consume)consumables; \ + return((rettype)ArgErr(msg, obj, whenBAD)); \ + } \ +} + +/*END SHARED*/ +/*SHARED*/ + +/* Changed use of Dup() below to Temporary(Copy()) because Dup() does not + necessarily return a Unique Copy anymore! 3-26-91 */ +#define TYPENULLCHECK(name, obj, expect, whenBAD, consumables,rettype) \ + if (obj == NULL) { \ + (Consume)consumables; \ + if (whenBAD != NULL && ISPERMANENT(whenBAD->flag)) \ + return((rettype)Temporary(Copy(whenBAD))); \ + else return((rettype)whenBAD); \ + } else { \ + if (obj->type != expect) { \ + (Consume)consumables; \ + return((rettype)TypeErr(name, obj, expect, whenBAD)); \ + } \ + } +/*END SHARED*/ +/*SHARED*/ + +#define MAKECONSUME(obj,stmt) { if (!ISPERMANENT(obj->flag)) stmt; } + +/*END SHARED*/ +/*SHARED*/ + +#define MAKEUNIQUE(obj,stmt) ( ( (obj)->references > 1 ) ? stmt : obj ) + +/*END SHARED*/ +/*SHARED*/ + +#ifdef GLOBALS + +#define extern +#define INITIALIZED(value) = value + +#else + +#define INITIALIZED(value) + +#endif + +extern char MustCheckArgs INITIALIZED(TRUE); +extern char MustTraceCalls INITIALIZED(FALSE); +#if XFONT_CID +extern char MustCrash INITIALIZED(FALSE); +#else +extern char MustCrash INITIALIZED(TRUE); +#endif +extern char InternalTrace INITIALIZED(TRUE); +extern char LineIOTrace INITIALIZED(TRUE); + +extern char ProcessHints INITIALIZED(TRUE); + +extern char SaveFontPaths INITIALIZED(TRUE); + +extern short CRASTERCompressionType INITIALIZED(1); + +extern char ConicDebug INITIALIZED(0); +extern char LineDebug INITIALIZED(0); +extern char RegionDebug INITIALIZED(0); +extern char PathDebug INITIALIZED(0); +extern char FontDebug INITIALIZED(0); +extern char SpaceDebug INITIALIZED(0); +extern char StrokeDebug INITIALIZED(0); +extern char MemoryDebug INITIALIZED(0); +extern char HintDebug INITIALIZED(0); +extern char ImageDebug INITIALIZED(0); +extern char OffPageDebug INITIALIZED(0); + +extern short CachedChars INITIALIZED(0x7FFF); +extern short CachedFonts INITIALIZED(0x7FFF); +extern int CacheBLimit INITIALIZED(12500); +extern char Continuity INITIALIZED(2); + +#ifdef extern +#undef extern +#endif + +/* +We define other routines formatting parameters +*/ +#define DumpArea(area) t1_DumpArea(area) +#define DumpText(text) t1_DumpText(text) +#define DumpPath(path) t1_DumpPath(path) +#define DumpSpace(space) t1_DumpSpace(space) +#define DumpEdges(e) t1_DumpEdges(e) +#define FormatFP(s,p) t1_FormatFP(s,p) + +/* dump a textpath structure */ +extern void t1_DumpText(void); + +/*END SHARED*/ diff --git a/nx-X11/lib/font/Type1/paths.c b/nx-X11/lib/font/Type1/paths.c new file mode 100644 index 000000000..1ab25ecef --- /dev/null +++ b/nx-X11/lib/font/Type1/paths.c @@ -0,0 +1,1406 @@ +/* $Xorg: paths.c,v 1.3 2000/08/17 19:46:31 cpqbld Exp $ */ +/* Copyright International Business Machines, Corp. 1991 + * All Rights Reserved + * Copyright Lexmark International, Inc. 1991 + * All Rights Reserved + * + * License to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, + * provided that the above copyright notice appear in all copies and that + * both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of IBM or Lexmark not be + * used in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * + * IBM AND LEXMARK PROVIDE THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES OF + * ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO ANY + * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, + * AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE + * QUALITY AND PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT + * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF THE + * SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM OR LEXMARK) ASSUMES THE + * ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN NO EVENT SHALL + * IBM OR LEXMARK BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF + * THIS SOFTWARE. + */ +/* $XFree86: xc/lib/font/Type1/paths.c,v 1.7tsi Exp $ */ + + /* PATHS CWEB V0021 ******** */ +/* +:h1 id=paths.PATHS Module - Path Operator Handler + +This is the module that is responsible for building and transforming +path lists. + +&author. Jeffrey B. Lotspiech (lotspiech@almaden.ibm.com) + + +:h3.Include Files + +The included files are: +*/ + + /* after the system includes (dsr) */ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#ifdef FONTMODULE +# include "os.h" +#endif +#include "objects.h" +#include "spaces.h" +#include "paths.h" +#include "regions.h" /* understands about Union */ +#include "fonts.h" /* understands about TEXTTYPEs */ +#include "pictures.h" /* understands about handles */ +#include "strokes.h" /* understands how to coerce stroke paths */ +#include "trig.h" + + +/* +:h3.Routines Available to the TYPE1IMAGER User + +The PATHS routines that are made available to the outside user are: +*/ + +/*SHARED LINE(S) ORIGINATED HERE*/ +/* +:h3.Functions Provided to Other Modules + +The path routines that are made available to other TYPE1IMAGER modules +are defined here: +*/ + +/*SHARED LINE(S) ORIGINATED HERE*/ +/* +NOTE: because of the casts put in the macros for Loc, ArcCA, Conic, +RoundConic, PathSegment, and JoinSegment, we cannot use the macro names +when the functions are actually defined. We have to use the unique +names with their unique first two characters. Thus, if anyone in the +future ever decided to change the first two characters, it would not be +enough just to change the macro (as it would for most other functions). +He would have to also change the function definition. +*/ +/* +:h3.Macros Provided to Other Modules + +The CONCAT macro is defined here and used in the STROKES module. See +:hdref refid=pathmac.. +*/ + +/*SHARED LINE(S) ORIGINATED HERE*/ + +/* +:h2.Path Segment Structures + +A path is represented as a linked list of the following structure: +*/ + +/*SHARED LINE(S) ORIGINATED HERE*/ +/* +When 'link' is NULL, we are at the last segment in the path (surprise!). + +'last' is only non-NULL on the first segment of a path, +for all the other segments 'last' == NULL. We test for a non-NULL +'last' (ISPATHANCHOR predicate) when we are given an alleged path +to make sure the user is not trying to pull a fast one on us. + +A path may be a collection of disjoint paths. Every break in the +disjoint path is represented by a MOVETYPE segment. + +Closed paths are discussed in :hdref refid=close.. + +:h3.CopyPath() - Physically Duplicating a Path + +This simple function illustrates moving through the path linked list. +Duplicating a segment just involves making a copy of it, except for +text, which has some auxilliary things involved. We don't feel +competent to duplicate text in this module, so we call someone who +knows how (in the FONTS module). +*/ +struct segment * +CopyPath(struct segment *p0) /* path to duplicate */ +{ + register struct segment *p,*n = NULL,*last = NULL,*anchor; + + for (p = p0, anchor = NULL; p != NULL; p = p->link) { + + ARGCHECK((!ISPATHTYPE(p->type) || (p != p0 && p->last != NULL)), + "CopyPath: invalid segment", p, NULL, (0), struct segment *); + + if (p->type == TEXTTYPE) + n = (struct segment *) CopyText(p); + else + n = (struct segment *)Allocate(p->size, p, 0); + n->last = NULL; + if (anchor == NULL) + anchor = n; + else + last->link = n; + last = n; + } +/* +At this point we have a chain of newly allocated segments hanging off +'anchor'. We need to make sure the first segment points to the last: +*/ + if (anchor != NULL) { + n->link = NULL; + anchor->last = n; + } + + return(anchor); +} +/* +:h3.KillPath() - Destroying a Path + +Destroying a path is simply a matter of freeing each segment in the +linked list. Again, we let the experts handle text. +*/ +void +KillPath(struct segment *p) /* path to destroy */ +{ + register struct segment *linkp; /* temp register holding next segment*/ + + /* return conditional based on reference count 3-26-91 PNM */ + if ( (--(p->references) > 1) || + ( (p->references == 1) && !ISPERMANENT(p->flag) ) ) + return; + + while (p != NULL) { + if (!ISPATHTYPE(p->type)) { + ArgErr("KillPath: bad segment", p, NULL); + return; + } + linkp = p->link; + if (p->type == TEXTTYPE) + KillText(p); + else + Free(p); + p = linkp; + } +} + +/* +:h2 id=location."location" Objects + +The TYPE1IMAGER user creates and destroys objects of type "location". These +objects locate points for the primitive path operators. We play a trick +here and store these objects in the same "segment" structure used for +paths, with a type field == MOVETYPE. + +This allows the Line() operator, for example, to be very trivial: +It merely stamps its input structure as a LINETYPE and returns it to the +caller--assuming, of course, the input structure was not permanent (as +it usually isn't). + +:h3.The "movesegment" Template Structure + +This template is used as a generic segment structure for Allocate: +*/ + +/* added reference field 1 to temporary template below 3-26-91 PNM */ +static struct segment movetemplate = { MOVETYPE, 0, 1, sizeof(struct segment), 0, + NULL, NULL, {0, 0} }; +/* +:h3.Loc() - Create an "Invisible Line" Between (0,0) and a Point + +*/ + +struct segment * +t1_Loc(struct XYspace *S, /* coordinate space to interpret X,Y */ + double x, double y) /* destination point */ +{ + register struct segment *r; + + + r = (struct segment *)Allocate(sizeof(struct segment), &movetemplate, 0); + TYPECHECK("Loc", S, SPACETYPE, r, (0), struct segment *); + + r->last = r; + r->context = S->context; + (*S->convert)(&r->dest, S, x, y); + ConsumeSpace(S); + return(r); +} +/* +:h3.ILoc() - Loc() With Integer Arguments + +*/ +struct segment * +ILoc(struct XYspace *S, /* coordinate space to interpret X,Y */ + int x, int y) /* destination point */ +{ + register struct segment *r; + + r = (struct segment *)Allocate(sizeof(struct segment), &movetemplate, 0); + TYPECHECK("Loc", S, SPACETYPE, r, (0), struct segment *); + + r->last = r; + r->context = S->context; + (*S->iconvert)(&r->dest, S, (long) x, (long) y); + ConsumeSpace(S); + return(r); +} + +/* +:h3.SubLoc() - Vector Subtraction of Two Locition Objects + +This user operator subtracts two location objects, yielding a new +location object that is the result. + +The symmetrical function AddLoc() is totally redundent with Join(), +so it is not provided. +*/ + +struct segment * +SubLoc(struct segment *p1, struct segment *p2) +{ + ARGCHECK(!ISLOCATION(p1), "SubLoc: bad first arg", p1, NULL, (0), struct segment *); + ARGCHECK(!ISLOCATION(p2), "SubLoc: bad second arg", p2, NULL, (0), struct segment *); + p1 = UniquePath(p1); + p1->dest.x -= p2->dest.x; + p1->dest.y -= p2->dest.y; + ConsumePath(p2); + return(p1); +} + +/* +:h2.Straight Line Segments + +:h3.PathSegment() - Create a Generic Path Segment + +Many routines need a LINETYPE or MOVETYPE path segment, but do not +want to go through the external user's interface, because, for example, +they already know the "fractpel" destination of the segment and the +conversion is unnecessary. PathSegment() is an internal routine +provided to the rest of TYPE1IMAGER for handling these cases. +*/ + +struct segment * +t1_PathSegment(int type, /* LINETYPE or MOVETYPE */ + fractpel x, fractpel y) /* where to go to, if known */ +{ + register struct segment *r; /* newly created segment */ + + r = (struct segment *)Allocate(sizeof(struct segment), &movetemplate, 0); + r->type = type; + r->last = r; /* last points to itself for singleton */ + r->dest.x = x; + r->dest.y = y; + return(r); +} +/* +:h3.Line() - Create a Line Segment Between (0,0) and a Point P + +This involves just creating and filling out a segment structure: +*/ +struct segment * +Line(struct segment *P) /* relevant coordinate space */ +{ + ARGCHECK(!ISLOCATION(P), "Line: arg not a location", P, NULL, (0), struct segment *); + + P = UniquePath(P); + P->type = LINETYPE; + return(P); +} +/* +:h2.Curved Path Segments + +We need more points to describe curves. So, the structures for curved +path segments are slightly different. The first part is identical; +the curved structures are larger with the extra points on the end. + +:h3.Bezier Segment Structure + +We support third order Bezier curves. They are specified with four +control points A, B, C, and D. The curve starts at A with slope AB +and ends at D with slope CD. The curvature at the point A is inversely +related to the length |AB|, and the curvature at the point D is +inversely related to the length |CD|. Point A is always point (0,0). + +*/ + +/*SHARED LINE(S) ORIGINATED HERE*/ +/* +:h3.Bezier() - Generate a Bezier Segment + +This is just a simple matter of filling out a 'beziersegment' structure: +*/ + +struct beziersegment * +Bezier(struct segment *B, /* second control point */ + struct segment *C, /* third control point */ + struct segment *D) /* fourth control point (ending point) */ +{ +/* added reference field of 1 to temporary template below 3-26-91 PNM */ + static struct beziersegment template = + { BEZIERTYPE, 0, 1, sizeof(struct beziersegment), 0, + NULL, NULL, { 0, 0 }, { 0, 0 }, { 0, 0 } }; + + register struct beziersegment *r; /* output segment */ + + ARGCHECK(!ISLOCATION(B), "Bezier: bad B", B, NULL, (2,C,D), struct beziersegment *); + ARGCHECK(!ISLOCATION(C), "Bezier: bad C", C, NULL, (2,B,D), struct beziersegment *); + ARGCHECK(!ISLOCATION(D), "Bezier: bad D", D, NULL, (2,B,C), struct beziersegment *); + + r = (struct beziersegment *)Allocate(sizeof(struct beziersegment), &template, 0); + r->last = (struct segment *) r; + r->dest.x = D->dest.x; + r->dest.y = D->dest.y; + r->B.x = B->dest.x; + r->B.y = B->dest.y; + r->C.x = C->dest.x; + r->C.y = C->dest.y; + + ConsumePath(B); + ConsumePath(C); + ConsumePath(D); + return(r); +} + +/* +:h2.Font "Hint" Segments + +:h3.Hint() - A Font 'Hint' Segment + +This is temporary code while we experiment with hints. +*/ + +/*SHARED LINE(S) ORIGINATED HERE*/ +struct hintsegment * +Hint(struct XYspace *S, float ref, float width, + char orientation, char hinttype, char adjusttype, char direction, + int label) +{ +/* added reference field of 1 to hintsegment template below 3-26-91 PNM */ + static struct hintsegment template = { HINTTYPE, 0, 1, sizeof(struct hintsegment), 0, + NULL, NULL, { 0, 0 }, { 0, 0 }, { 0, 0 }, + ' ', ' ', ' ', ' ', 0}; + + register struct hintsegment *r; + + r = (struct hintsegment *)Allocate(sizeof(struct hintsegment), &template, 0); + + r->orientation = orientation; + if (width == 0.0) width = 1.0; + + if (orientation == 'h') { + (*S->convert)(&r->ref, S, 0.0, ref); + (*S->convert)(&r->width, S, 0.0, width); + } + else if (orientation == 'v') { + (*S->convert)(&r->ref, S, ref, 0.0); + (*S->convert)(&r->width, S, width, 0.0); + } + else + return((struct hintsegment *)ArgErr("Hint: orient not 'h' or 'v'", NULL, NULL)); + if (r->width.x < 0) r->width.x = - r->width.x; + if (r->width.y < 0) r->width.y = - r->width.y; + r->hinttype = hinttype; + r->adjusttype = adjusttype; + r->direction = direction; + r->label = label; + r->last = (struct segment *) r; + ConsumeSpace(S); + return(r); +} + +/* +*/ + +/*SHARED LINE(S) ORIGINATED HERE*/ + +/* +POP removes the first segment in a path 'p' and Frees it. 'p' is left +pointing to the end of the path: +*/ +#define POP(p) \ + { register struct segment *linkp; \ + linkp = p->link; \ + if (linkp != NULL) \ + linkp->last = p->last; \ + Free(p); \ + p = linkp; } +/* +INSERT inserts a single segment in the middle of a chain. 'b' is +the segment before, 'p' the segment to be inserted, and 'a' the +segment after. +*/ +#define INSERT(b,p,a) b->link=p; p->link=a; p->last=NULL + +/* +:h3.Join() - Join Two Objects Together + +If these are paths, this operator simply invokes the CONCAT macro. +Why so much code then, you ask? Well we have to check for object +types other than paths, and also check for certain path consistency +rules. +*/ + +struct segment * +Join(struct segment *p1, struct segment *p2) +{ +/* +We start with a whole bunch of very straightforward argument tests: +*/ + if (p2 != NULL) { + if (!ISPATHTYPE(p2->type)) { + + if (p1 == NULL) + return((struct segment *)Unique(p2)); + + switch (p1->type) { + + case REGIONTYPE: + + case STROKEPATHTYPE: + p1 = CoercePath(p1); + break; + + default: + return((struct segment *)BegHandle(p1, p2)); + } + } + + ARGCHECK((p2->last == NULL), "Join: right arg not anchor", p2, NULL, (1,p1), struct segment *); + p2 = UniquePath(p2); + +/* +In certain circumstances, we don't have to duplicate a permanent +location. (We would just end up destroying it anyway). These cases +are when 'p2' begins with a move-type segment: +*/ + if (p2->type == TEXTTYPE || p2->type == MOVETYPE) { + if (p1 == NULL) + return(p2); + if (ISLOCATION(p1)) { + p2->dest.x += p1->dest.x; + p2->dest.y += p1->dest.y; + ConsumePath(p1); + return(p2); + } + } + } + else + return((struct segment *)Unique(p1)); + + if (p1 != NULL) { + if (!ISPATHTYPE(p1->type)) + + switch (p2->type) { + + case REGIONTYPE: + + case STROKEPATHTYPE: + p2 = CoercePath(p2); + break; + + default: + return((struct segment *)EndHandle(p1, p2)); + } + + ARGCHECK((p1->last == NULL), "Join: left arg not anchor", p1, NULL, (1,p2), struct segment *); + p1 = UniquePath(p1); + } + else + return(p2); + +/* +At this point all the checking is done. We have two temporary non-null +path types in 'p1' and 'p2'. If p1 ends with a MOVE, and p2 begins with +a MOVE, we collapse the two MOVEs into one. We enforce the rule that +there may not be two MOVEs in a row: +*/ + + if (p1->last->type == MOVETYPE && p2->type == MOVETYPE) { + p1->last->flag |= p2->flag; + p1->last->dest.x += p2->dest.x; + p1->last->dest.y += p2->dest.y; + POP(p2); + if (p2 == NULL) + return(p1); + } +/* +Now we check for another silly rule. If a path has any TEXTTYPEs, +then it must have only TEXTTYPEs and MOVETYPEs, and furthermore, +it must begin with a TEXTTYPE. This rule makes it easy to check +for the special case of text. If necessary, we will coerce +TEXTTYPEs into paths so we don't mix TEXTTYPEs with normal paths. +*/ + if (p1->type == TEXTTYPE) { + if (p2->type != TEXTTYPE && !ISLOCATION(p2)) + p1 = CoerceText(p1); + } + else { + if (p2->type == TEXTTYPE) { + if (ISLOCATION(p1)) { + p2->dest.x += p1->dest.x; + p2->dest.y += p1->dest.y; + Free(p1); + return(p2); + } + else + p2 = CoerceText(p2); + } + } +/* +Thank God! Finally! It's hard to believe, but we are now able to +actually do the join. This is just invoking the CONCAT macro: +*/ + CONCAT(p1, p2); + + return(p1); +} + +/* +:h3.JoinSegment() - Create a Path Segment and Join It to a Known Path + +This internal function is quicker than a full-fledged join because +it can do much less checking. +*/ + +struct segment * +t1_JoinSegment(struct segment *before, /* path to join before new segment */ + int type, /* type of new segment (MOVETYPE or LINETYPE) */ + fractpel x, fractpel y, /* x,y of new segment */ + struct segment *after) /* path to join after new segment */ +{ + register struct segment *r; /* returned path built here */ + + r = PathSegment(type, x, y); + if (before != NULL) { + CONCAT(before, r); + r = before; + } + else + r->context = after->context; + if (after != NULL) + CONCAT(r, after); + return(r); +} + +/* +:h2.Other Path Functions + +*/ + + +struct segment * +t1_ClosePath(struct segment *p0, /* path to close */ + int lastonly) /* flag deciding to close all subpaths or... */ +{ + register struct segment *p,*last = NULL,*start; /* used in looping through path */ + register fractpel x,y; /* current position in path */ + register fractpel firstx = 0,firsty = 0; /* start position of sub path */ + register struct segment *lastnonhint = NULL; /* last non-hint segment in path */ + + if (p0 != NULL && p0->type == TEXTTYPE) + return(UniquePath(p0)); + if (p0->type == STROKEPATHTYPE) + return((struct segment *)Unique(p0)); + /* + * NOTE: a null closed path is different from a null open path + * and is denoted by a closed (0,0) move segment. We make + * sure this path begins and ends with a MOVETYPE: + */ + if (p0 == NULL || p0->type != MOVETYPE) + p0 = JoinSegment(NULL, MOVETYPE, 0, 0, p0); + TYPECHECK("ClosePath", p0, MOVETYPE, NULL, (0), struct segment *); + if (p0->last->type != MOVETYPE) + p0 = JoinSegment(p0, MOVETYPE, 0, 0, NULL); + + p0 = UniquePath(p0); + +/* +We now begin a loop through the path, +incrementing current 'x' and 'y'. We are searching +for MOVETYPE segments (breaks in the path) that are not already closed. +At each break, we insert a close segment. +*/ + for (p = p0, x = y = 0, start = NULL; + p != NULL; + x += p->dest.x, y += p->dest.y, last = p, p = p->link) + { + + if (p->type == MOVETYPE) { + if (start != NULL && (lastonly?p->link==NULL:TRUE) && + !(ISCLOSED(start->flag) && LASTCLOSED(last->flag))) { + register struct segment *r; /* newly created */ + + start->flag |= ISCLOSED(ON); + r = PathSegment(LINETYPE, firstx - x, + firsty - y); + INSERT(last, r, p); + r->flag |= LASTCLOSED(ON); + /*< adjust 'last' if possible for a 0,0 close >*/ +{ + +#define CLOSEFUDGE 3 /* if we are this close, let's change last segment */ + + if (r->dest.x != 0 || r->dest.y != 0) { + if (r->dest.x <= CLOSEFUDGE && r->dest.x >= -CLOSEFUDGE + && r->dest.y <= CLOSEFUDGE && r->dest.y >= -CLOSEFUDGE) { + lastnonhint->dest.x += r->dest.x; + lastnonhint->dest.y += r->dest.y; + r->dest.x = r->dest.y = 0; + } + } +} + if (p->link != NULL) { + p->dest.x += x - firstx; + p->dest.y += y - firsty; + x = firstx; + y = firsty; + } + } + start = p; + firstx = x + p->dest.x; + firsty = y + p->dest.y; + } + else if (p->type != HINTTYPE) + lastnonhint = p; + } + return(p0); +} +/* +*/ +/* +:h2.Reversing the Direction of a Path + +This turned out to be more difficult than I thought at first. The +trickiness was due to the fact that closed paths must remain closed, +etc. + +We need three subroutines: +*/ + +/* break a path at any point */ +static struct segment *SplitPath ( struct segment *anchor, + struct segment *before ); +/* breaks a path after first sub-path */ +static struct segment *DropSubPath ( struct segment *p0 ); +/* reverses a single sub-path */ +static struct segment *ReverseSubPath ( struct segment *p ); + +/* +:h3.Reverse() - User Operator to Reverse a Path + +This operator reverses the entire path. +*/ + +struct segment * +Reverse(struct segment *p) /* full path to reverse */ +{ + register struct segment *r; /* output path built here */ + register struct segment *nextp; /* contains next sub-path */ + + if (p == NULL) + return(NULL); + + ARGCHECK(!ISPATHANCHOR(p), "Reverse: invalid path", p, NULL, (0), struct segment *); + + if (p->type == TEXTTYPE) + p = CoerceText(p); + p = UniquePath(p); + + r = NULL; + + do { + nextp = DropSubPath(p); + p = ReverseSubPath(p); + r = Join(p, r); + p = nextp; + + } while (p != NULL); + + return(r); +} + +/* +:h4.ReverseSubPath() - Subroutine to Reverse a Single Sub-Path +*/ + +static struct segment * +ReverseSubPath(struct segment *p) /* input path */ +{ + register struct segment *r; /* reversed path will be created here */ + register struct segment *nextp; /* temporary variable used in loop */ + register int wasclosed; /* flag, path was closed */ + + if (p == NULL) + return(NULL); + + wasclosed = ISCLOSED(p->flag); + r = NULL; + + do { +/* +First we reverse the direction of this segment and clean up its flags: +*/ + p->dest.x = - p->dest.x; p->dest.y = - p->dest.y; + p->flag &= ~(ISCLOSED(ON) | LASTCLOSED(ON)); + + switch (p->type) { + + case LINETYPE: + case MOVETYPE: + break; + + case CONICTYPE: + { +/* +The logic of this is that the new M point (stored relative to the new +beginning) is (M - C). However, C ("dest") has already been reversed +So, we add "dest" instead of subtracting it: +*/ + register struct conicsegment *cp = (struct conicsegment *) p; + + cp->M.x += cp->dest.x; cp->M.y += cp->dest.y; + } + break; + + case BEZIERTYPE: + { + register struct beziersegment *bp = (struct beziersegment *) p; + + bp->B.x += bp->dest.x; bp->B.y += bp->dest.y; + bp->C.x += bp->dest.x; bp->C.y += bp->dest.y; + } + break; + + case HINTTYPE: + { + register struct hintsegment *hp = (struct hintsegment *) p; + + hp->ref.x = -hp->ref.x; hp->ref.y = -hp->ref.y; + } + break; + + default: + Abort("Reverse: bad path segment"); + } +/* +We need to reverse the order of segments too, so we break this segment +off of the input path, and tack it on the front of the growing path +in 'r': +*/ + nextp = p->link; + p->link = NULL; + p->last = p; + if (r != NULL) + CONCAT(p,r); /* leaves result in 'p'... not what we want */ + r = p; + p = nextp; /* advance to next segment in input path */ + + } while (p != NULL); + + if (wasclosed) + r = ClosePath(r); + + return(r); +} + +/* +:h4.DropSubPath() - Drops the First Sub-Path Off a Path + +This subroutine returns the remaining sub-path(s). While doing so, it +breaks the input path after the first sub-path so that a pointer to +the original path now contains the first sub-path only. +*/ + +static struct segment * +DropSubPath(struct segment *p0) /* original path */ +{ + register struct segment *p; /* returned remainder here */ + + for (p = p0; p->link != NULL; p = p->link) { + if (p->link->type == MOVETYPE) + break; + } + + return(SplitPath(p0, p)); +} + +static struct segment * +SplitPath(struct segment *anchor, struct segment *before) +{ + register struct segment *r; + + if (before == anchor->last) + return(NULL); + + r = before->link; + r->last = anchor->last; + anchor->last = before; + before->link = NULL; + + return(r); +} + +static void +UnClose(struct segment *p0) +{ + register struct segment *p; + + for (p=p0; p->link->link != NULL; p=p->link) { ; } + + if (!LASTCLOSED(p->link->flag)) + Abort("UnClose: no LASTCLOSED"); + + Free(SplitPath(p0, p)); + p0->flag &= ~ISCLOSED(ON); +} + +/* +:h3.ReverseSubPaths() - Reverse the Direction of Sub-paths Within a Path + +This user operator reverses the sub-paths in a path, but leaves the +'move' segments unchanged. It builds on top of the subroutines +already established. +*/ + +struct segment * +ReverseSubPaths(struct segment *p) /* input path */ +{ + register struct segment *r; /* reversed path will be created here */ + register struct segment *nextp; /* temporary variable used in loop */ + int wasclosed; /* flag; subpath was closed */ + register struct segment *nomove; /* the part of sub-path without move segment */ + struct fractpoint delta; + + if (p == NULL) + return(NULL); + + ARGCHECK(!ISPATHANCHOR(p), "ReverseSubPaths: invalid path", p, NULL, (0), struct segment *); + + if (p->type == TEXTTYPE) + p = CoerceText(p); + if (p->type != MOVETYPE) + p = JoinSegment(NULL, MOVETYPE, 0, 0, p); + + p = UniquePath(p); + + r = NULL; + + for (; p != NULL;) { + nextp = DropSubPath(p); + wasclosed = ISCLOSED(p->flag); + if (wasclosed) + UnClose(p); + + nomove = SplitPath(p, p); + r = Join(r, p); + + PathDelta(nomove, &delta); + + nomove = ReverseSubPath(nomove); + p->dest.x += delta.x; + p->dest.y += delta.y; + if (nextp != NULL) { + nextp->dest.x += delta.x; + nextp->dest.y += delta.y; + } + if (wasclosed) { + nomove = ClosePath(nomove); + nextp->dest.x -= delta.x; + nextp->dest.y -= delta.y; + } + r = Join(r, nomove); + p = nextp; + + } + + return(r); +} + +/* +:h2.Transforming and Putting Handles on Paths + +:h3.PathTransform() - Transform a Path + +Transforming a path involves transforming all the points. In order +that closed paths do not become "unclosed" when their relative +positions are slightly changed due to loss of arithmetic precision, +all point transformations are in absolute coordinates. + +(It might be better to reset the "absolute" coordinates every time a +move segment is encountered. This would mean that we could accumulate +error from subpath to subpath, but we would be less likely to make +the "big error" where our fixed point arithmetic "wraps". However, I +think I'll keep it this way until something happens to convince me +otherwise.) + +The transform is described as a "space", that way we can use our +old friend the "iconvert" function, which should be very efficient. +*/ + +struct segment * +PathTransform(struct segment *p0, /* path to transform */ + struct XYspace *S) /* pseudo space to transform in */ +{ + register struct segment *p; /* to loop through path with */ + register fractpel newx,newy; /* current transformed position in path */ + register fractpel oldx,oldy; /* current untransformed position in path */ + register fractpel savex,savey; /* save path delta x,y */ + + p0 = UniquePath(p0); + + newx = newy = oldx = oldy = 0; + + for (p=p0; p != NULL; p=p->link) { + + savex = p->dest.x; savey = p->dest.y; + + (*S->iconvert)(&p->dest, S, p->dest.x + oldx, p->dest.y + oldy); + p->dest.x -= newx; + p->dest.y -= newy; + + switch (p->type) { + + case LINETYPE: + case MOVETYPE: + break; + + case CONICTYPE: + { + register struct conicsegment *cp = (struct conicsegment *) p; + + (*S->iconvert)(&cp->M, S, cp->M.x + oldx, cp->M.y + oldy); + cp->M.x -= newx; + cp->M.y -= newy; + /* + * Note roundness doesn't change... linear transform + */ + break; + } + + + case BEZIERTYPE: + { + register struct beziersegment *bp = (struct beziersegment *) p; + + (*S->iconvert)(&bp->B, S, bp->B.x + oldx, bp->B.y + oldy); + bp->B.x -= newx; + bp->B.y -= newy; + (*S->iconvert)(&bp->C, S, bp->C.x + oldx, bp->C.y + oldy); + bp->C.x -= newx; + bp->C.y -= newy; + break; + } + + case HINTTYPE: + { + register struct hintsegment *hp = (struct hintsegment *) p; + + (*S->iconvert)(&hp->ref, S, hp->ref.x + oldx, hp->ref.y + oldy); + hp->ref.x -= newx; + hp->ref.y -= newy; + (*S->iconvert)(&hp->width, S, hp->width.x, hp->width.y); + /* Note: width is not relative to origin */ + break; + } + + case TEXTTYPE: + { + XformText(p,S); + break; + } + + default: + Abort("PathTransform: invalid segment"); + } + oldx += savex; + oldy += savey; + newx += p->dest.x; + newy += p->dest.y; + } + return(p0); +} + +/* +:h3.PathDelta() - Return a Path's Ending Point +*/ + +void +PathDelta(struct segment *p, /* input path */ + struct fractpoint *pt) /* pointer to x,y to set */ +{ + struct fractpoint mypoint; /* I pass this to TextDelta */ + register fractpel x,y; /* working variables for path current point */ + + for (x=y=0; p != NULL; p=p->link) { + x += p->dest.x; + y += p->dest.y; + if (p->type == TEXTTYPE) { + TextDelta(p, &mypoint); + x += mypoint.x; + y += mypoint.y; + } + } + + pt->x = x; + pt->y = y; +} + +/* +:h3.BoundingBox() - Produce a Bounding Box Path + +This function is called by image code, when we know the size of the +image in pels, and need to get a bounding box path that surrounds it. +The starting/ending handle is in the lower right hand corner. +*/ +struct segment * +BoundingBox(pel h, pel w) /* size of box */ +{ + register struct segment *path; + + path = PathSegment(LINETYPE, -TOFRACTPEL(w), 0); + path = JoinSegment(NULL, LINETYPE, 0, -TOFRACTPEL(h), path); + path = JoinSegment(NULL, LINETYPE, TOFRACTPEL(w), 0, path); + path = ClosePath(path); + + return(path); +} + +/* +:h2.Querying Locations and Paths + +:h3.QueryLoc() - Return the X,Y of a Locition +*/ + +void +QueryLoc(struct segment *P, /* location to query, not consumed */ + struct XYspace *S, /* XY space to return coordinates in */ + double *xP, double *yP) /* coordinates returned here */ +{ + if (!ISLOCATION(P)) { + ArgErr("QueryLoc: first arg not a location", P, NULL); + return; + } + if (S->type != SPACETYPE) { + ArgErr("QueryLoc: second arg not a space", S, NULL); + return; + } + UnConvert(S, &P->dest, xP, yP); +} +/* +:h3.QueryPath() - Find Out the Type of Segment at the Head of a Path + +This is a very simple routine that looks at the first segment of a +path and tells the caller what it is, as well as returning the control +point(s) of the path segment. Different path segments have different +number of control points. If the caller knows that the segment is +a move segment, for example, he only needs to pass pointers to return +one control point. +*/ + +void +QueryPath(struct segment *path, /* path to check */ + int *typeP, /* return the type of path here */ + struct segment **Bp, /* return location of first point */ + struct segment **Cp, /* return location of second point */ + struct segment **Dp, /* return location of third point */ + double *fP) /* return Conic sharpness */ +{ + register int coerced = FALSE; /* did I coerce a text path? */ + + if (path == NULL) { + *typeP = -1; + return; + } + if (!ISPATHANCHOR(path)) { + ArgErr("QueryPath: arg not a valid path", path, NULL); + } + if (path->type == TEXTTYPE) { + path = CoerceText(path); + coerced = TRUE; + } + + switch (path->type) { + + case MOVETYPE: + *typeP = 0; + *Bp = PathSegment(MOVETYPE, path->dest.x, path->dest.y); + break; + + case LINETYPE: + *typeP = (LASTCLOSED(path->flag)) ? 4 : 1; + *Bp = PathSegment(MOVETYPE, path->dest.x, path->dest.y); + break; + + case CONICTYPE: + { + register struct conicsegment *cp = (struct conicsegment *) path; + + *typeP = 2; + *Bp = PathSegment(MOVETYPE, cp->M.x, cp->M.y); + *Cp = PathSegment(MOVETYPE, cp->dest.x, cp->dest.y); + *fP = cp->roundness; + } + break; + + case BEZIERTYPE: + { + register struct beziersegment *bp = (struct beziersegment *) path; + + *typeP = 3; + *Bp = PathSegment(MOVETYPE, bp->B.x, bp->B.y); + *Cp = PathSegment(MOVETYPE, bp->C.x, bp->C.y); + *Dp = PathSegment(MOVETYPE, bp->dest.x, bp->dest.y); + } + break; + + case HINTTYPE: + *typeP = 5; + break; + + default: + Abort("QueryPath: unknown segment"); + } + if (coerced) + KillPath(path); +} +/* +:h3.QueryBounds() - Return the Bounding Box of a Path + +Returns the bounding box by setting the user's variables. +*/ + +void +QueryBounds(struct segment *p0, /* object to check for bound */ + struct XYspace *S, /* coordinate space of returned values */ + double *xminP, /* lower left hand corner (set by routine) */ + double *yminP, + double *xmaxP, /* upper right hand corner (set by routine) */ + double *ymaxP) +{ + register struct segment *path; /* loop variable for path segments */ + register fractpel lastx,lasty; /* loop variables: previous endingpoint */ + register fractpel x,y; /* loop variables: current ending point */ + struct fractpoint min; /* registers to keep lower left hand corner */ + struct fractpoint max; /* registers to keep upper right hand corner */ + int coerced = FALSE; /* we have coerced the path from another object */ + double x1,y1,x2,y2,x3,y3,x4,y4; /* corners of rectangle in space X */ + + if (S->type != SPACETYPE) { + ArgErr("QueryBounds: bad XYspace", S, NULL); + return; + } + + min.x = min.y = max.x = max.y = 0; + if (p0 != NULL) { + if (!ISPATHANCHOR(p0)) { + switch(p0->type) { + case STROKEPATHTYPE: + /* replaced DupStrokePath() with Dup() 3-26-91 PNM */ + p0 = (struct segment *) DoStroke(Dup(p0)); + /* no break here, we have a region in p0 */ + case REGIONTYPE: + p0 = RegionBounds((struct region *)p0); + break; + + case PICTURETYPE: + p0 = PictureBounds(p0); + break; + + default: + ArgErr("QueryBounds: bad object", p0, NULL); + return; + } + coerced = TRUE; + } + if (p0->type == TEXTTYPE) { + /* replaced CopyPath() with Dup() 3-26-91 PNM */ + p0 = (struct segment *)CoerceText(Dup(p0)); /* there are faster ways */ + coerced = TRUE; + } + if (p0->type == MOVETYPE) { + min.x = max.x = p0->dest.x; + min.y = max.y = p0->dest.y; + } + } + lastx = lasty = 0; + + for (path = p0; path != NULL; path = path->link) { + + x = lastx + path->dest.x; + y = lasty + path->dest.y; + + switch (path->type) { + + case LINETYPE: + break; + + case CONICTYPE: + { + register struct conicsegment *cp = (struct conicsegment *) path; + register fractpel Mx = lastx + cp->M.x; + register fractpel My = lasty + cp->M.y; + register fractpel deltax = 0.5 * cp->roundness * cp->dest.x; + register fractpel deltay = 0.5 * cp->roundness * cp->dest.y; + register fractpel Px = Mx - deltax; + register fractpel Py = My - deltay; + register fractpel Qx = Mx + deltax; + register fractpel Qy = My + deltay; + + + if (Mx < min.x) min.x = Mx; + else if (Mx > max.x) max.x = Mx; + if (My < min.y) min.y = My; + else if (My > max.y) max.y = My; + + if (Px < min.x) min.x = Px; + else if (Px > max.x) max.x = Px; + if (Py < min.y) min.y = Py; + else if (Py > max.y) max.y = Py; + + if (Qx < min.x) min.x = Qx; + else if (Qx > max.x) max.x = Qx; + if (Qy < min.y) min.y = Qy; + else if (Qy > max.y) max.y = Qy; + } + break; + + + case MOVETYPE: + /* + * We can't risk adding trailing Moves to the + * bounding box: + */ + if (path->link == NULL) + goto done; /* God forgive me */ + break; + + case BEZIERTYPE: + { + register struct beziersegment *bp = (struct beziersegment *) path; + register fractpel Bx = lastx + bp->B.x; + register fractpel By = lasty + bp->B.y; + register fractpel Cx = lastx + bp->C.x; + register fractpel Cy = lasty + bp->C.y; + + if (Bx < min.x) min.x = Bx; + else if (Bx > max.x) max.x = Bx; + if (By < min.y) min.y = By; + else if (By > max.y) max.y = By; + + if (Cx < min.x) min.x = Cx; + else if (Cx > max.x) max.x = Cx; + if (Cy < min.y) min.y = Cy; + else if (Cy > max.y) max.y = Cy; + } + break; + + case HINTTYPE: + break; + default: + Abort("QueryBounds: unknown type"); + } + + if (x < min.x) min.x = x; + else if (x > max.x) max.x = x; + if (y < min.y) min.y = y; + else if (y > max.y) max.y = y; + + lastx = x; lasty = y; + } +done: + UnConvert(S, &min, &x1, &y1); + UnConvert(S, &max, &x4, &y4); + x = min.x; min.x = max.x; max.x = x; + UnConvert(S, &min, &x2, &y2); + UnConvert(S, &max, &x3, &y3); + + *xminP = *xmaxP = x1; + if (x2 < *xminP) *xminP = x2; + else if (x2 > *xmaxP) *xmaxP = x2; + if (x3 < *xminP) *xminP = x3; + else if (x3 > *xmaxP) *xmaxP = x3; + if (x4 < *xminP) *xminP = x4; + else if (x4 > *xmaxP) *xmaxP = x4; + + *yminP = *ymaxP = y1; + if (y2 < *yminP) *yminP = y2; + else if (y2 > *ymaxP) *ymaxP = y2; + if (y3 < *yminP) *yminP = y3; + else if (y3 > *ymaxP) *ymaxP = y3; + if (y4 < *yminP) *yminP = y4; + else if (y4 > *ymaxP) *ymaxP = y4; + + if (coerced) + Destroy(p0); +} +/* +:h3.BoxPath() +*/ +struct segment * +BoxPath(struct XYspace *S, int h, int w) +{ + struct segment *path; + + path = Join( Line(ILoc(S, w, 0)), Line(ILoc(S, 0, h)) ); + path = JoinSegment(path, LINETYPE, -path->dest.x, -path->dest.y, NULL); + return(ClosePath(path)); +} + +/* +:h3.DropSegment() - Drop the First Segment in a Path + +This routine takes the path and returns a new path that is one segment +shorter. It can be used in conjunction with QueryPath(), for example, +to ask about an entire path. +*/ + +struct segment * +DropSegment(struct segment *path) +{ + if (path != NULL && path->type == STROKEPATHTYPE) + path = CoercePath(path); + ARGCHECK((path == NULL || !ISPATHANCHOR(path)), + "DropSegment: arg not a non-null path", path, path, (0), struct segment *); + if (path->type == TEXTTYPE) + path = CoerceText(path); + path = UniquePath(path); + + POP(path); + return(path); +} +/* +:h3.HeadSegment() - Return the First Segment in a Path + +This routine takes the path and returns a new path consists of the +first segment only. +*/ + +struct segment * +HeadSegment(struct segment *path) /* input path */ +{ + if (path == NULL) + return(NULL); + if (path->type == STROKEPATHTYPE) + path = CoercePath(path); + ARGCHECK(!ISPATHANCHOR(path), "HeadSegment: arg not a path", path, path, (0), struct segment *); + if (path->type == TEXTTYPE) + path = CoerceText(path); + path = UniquePath(path); + + if (path->link != NULL) + KillPath(path->link); + path->link = NULL; + path->last = path; + return(path); +} + +/* +:h2.Path Debug Routines + +:h3.DumpPath() - Display a Path on the Trace File +*/ + +void +DumpPath(struct segment *p) +{ +} diff --git a/nx-X11/lib/font/Type1/paths.h b/nx-X11/lib/font/Type1/paths.h new file mode 100644 index 000000000..b61275b9c --- /dev/null +++ b/nx-X11/lib/font/Type1/paths.h @@ -0,0 +1,239 @@ +/* $Xorg: paths.h,v 1.3 2000/08/17 19:46:31 cpqbld Exp $ */ +/* Copyright International Business Machines, Corp. 1991 + * All Rights Reserved + * Copyright Lexmark International, Inc. 1991 + * All Rights Reserved + * + * License to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, + * provided that the above copyright notice appear in all copies and that + * both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of IBM or Lexmark not be + * used in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * + * IBM AND LEXMARK PROVIDE THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES OF + * ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO ANY + * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, + * AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE + * QUALITY AND PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT + * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF THE + * SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM OR LEXMARK) ASSUMES THE + * ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN NO EVENT SHALL + * IBM OR LEXMARK BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF + * THIS SOFTWARE. + */ +/* $XFree86: xc/lib/font/Type1/paths.h,v 1.3 1999/08/22 08:58:53 dawes Exp $ */ + +/*SHARED*/ + +#define Loc(S,x,y) t1_Loc(S,(double)x,(double)y) +#define ILoc(S,x,y) t1_ILoc(S,x,y) +#define Line(P) t1_Line(P) +#define Join(p1,p2) t1_Join(p1,p2) +#define ClosePath(p) t1_ClosePath(p,0) +#define CloseLastSubPath(p) t1_ClosePath(p,1) +#define Conic(B,C,s) t1_Conic(B,C,(double)s) +#define RoundConic(M,C,r) t1_RoundConic(M,C,(double)r) +#define ArcP3(S,P2,P3) t1_ArcP3(S,P2,P3) +#define ArcCA(S,C,d) t1_ArcCA(S,C,(double)d) +#define Bezier(B,C,D) t1_Bezier(B,C,D) +#define Hint(S,r,w,o,h,a,d,l) t1_Hint(S,r,w,o,h,a,d,l) +#define Reverse(p) t1_Reverse(p) +#define ReverseSubPaths(p) t1_ReverseSubPaths(p) +#define AddLoc(p1,p2) t1_Join(p1,p2) +#define SubLoc(p1,p2) t1_SubLoc(p1,p2) +#define DropSegment(p) t1_DropSegment(p) +#define HeadSegment(p) t1_HeadSegment(p) +#define QueryLoc(P,S,x,y) t1_QueryLoc(P,S,x,y) +#define QueryPath(p,t,B,C,D,r) t1_QueryPath(p,t,B,C,D,r) +#define QueryBounds(p,S,x1,y1,x2,y2) t1_QueryBounds(p,S,x1,y1,x2,y2) + + +/* create a location object (or "move" segment) */ +extern struct segment *t1_Loc ( struct XYspace *S, double x, double y ); +/* integer argument version of same */ +extern struct segment *t1_ILoc ( struct XYspace *S, int x, int y ); +/* straight line path segment */ +extern struct segment *t1_Line ( struct segment *P ); +/* join two paths or regions together */ +extern struct segment *t1_Join ( struct segment *p1, struct segment *p2 ); +/* close a path or path set */ +extern struct segment *t1_ClosePath ( struct segment *p0, int lastonly ); +#if 0 +struct conicsegment *t1_Conic(); /* conic curve path segment */ + +struct conicsegment *t1_RoundConic(); /* ditto, specified another way */ +struct conicsegment *t1_ArcP3(); /* circular path segment with three points */ +struct conicsegment *t1_ArcCA(); /* ditto, with center point and angle */ +#endif +/* Bezier third order curve path segment */ +extern struct beziersegment *t1_Bezier ( struct segment *B, struct segment *C, + struct segment *D ); +/* produce a font 'hint' path segment */ +extern struct hintsegment *t1_Hint ( struct XYspace *S, float ref, float width, + char orientation, char hinttype, + char adjusttype, char direction, + int label ); +/* reverse the complete order of paths */ +extern struct segment *t1_Reverse ( struct segment *p ); +/* reverse only sub-paths; moves unchanged */ +extern struct segment *t1_ReverseSubPaths ( struct segment *p ); +/* subtract two location objects */ +extern struct segment *t1_SubLoc ( struct segment *p1, struct segment *p2 ); +/* Drop the first segment in a path */ +extern struct segment *t1_DropSegment ( struct segment *path ); +/* return the first segment in a path */ +extern struct segment *t1_HeadSegment ( struct segment *path ); +/* Query location; return its (x,y) */ +extern void t1_QueryLoc ( struct segment *P, struct XYspace *S, double *xP, + double *yP ); +/* Query segment at head of a path */ +extern void t1_QueryPath ( struct segment *path, int *typeP, + struct segment **Bp, struct segment **Cp, + struct segment **Dp, double *fP ); +/* Query the bounding box of a path */ +extern void t1_QueryBounds ( struct segment *p0, struct XYspace *S, + double *xminP, double *yminP, + double *xmaxP, double *ymaxP ); + +/*END SHARED*/ +/*SHARED*/ + +#define CopyPath(p) t1_CopyPath(p) +#define KillPath(p) t1_KillPath(p) +#define PathTransform(p,m) t1_PathXform(p,m) +#define PathDelta(p,pt) t1_PathDelta(p,pt) +#define BoundingBox(h,w) t1_BoundingBox(h,w) +#define PathSegment(t,x,y) t1_PathSegment(t,(fractpel)x,(fractpel)y) +#define JoinSegment(b,t,x,y,a) t1_JoinSegment(b,t,(fractpel)x,(fractpel)y,a) +#define Hypoteneuse(dx,dy) t1_Hypoteneuse(dx,dy) +#define BoxPath(S,h,w) t1_BoxPath(S,h,w) + +/* duplicate a path */ +extern struct segment *t1_CopyPath ( struct segment *p0 ); +/* destroy a path */ +extern void t1_KillPath ( struct segment *p ); +/* transform a path arbitrarily */ +extern struct segment *t1_PathXform ( struct segment *p0, struct XYspace *S ); +/* calculate the ending point of a path */ +extern void t1_PathDelta ( struct segment *p, struct fractpoint *pt ); +/* */ +extern struct segment *t1_BoundingBox ( pel h, pel w ); +/* produce a MOVE or LINE segment */ +extern struct segment *t1_PathSegment ( int type, fractpel x, fractpel y ); +/* join a MOVE or LINE segment to a path */ +extern struct segment *t1_JoinSegment ( struct segment *before, int type, fractpel x, fractpel y, struct segment *after ); +#if 0 +double t1_Hypoteneuse(); /* returns the length of a line */ +#endif +/* returns a rectangular path */ +extern struct segment *t1_BoxPath ( struct XYspace *S, int h, int w ); + +/*END SHARED*/ +/*SHARED*/ + +#define ConsumePath(p) MAKECONSUME(p,KillPath(p)) +#define UniquePath(p) MAKEUNIQUE(p,CopyPath(p)) + +/*END SHARED*/ +/*SHARED*/ + +struct segment { + XOBJ_COMMON /* xobject common data define 3-26-91 PNM */ + unsigned char size; /* size of the structure */ + unsigned char context; /* index to device context */ + struct segment *link; /* pointer to next structure in linked list */ + struct segment *last; /* pointer to last structure in list */ + struct fractpoint dest; /* relative ending location of path segment */ +} ; + +#define ISCLOSED(flag) ((flag)&0x80) /* subpath is closed */ +#define LASTCLOSED(flag) ((flag)&0x40) /* last segment in closed subpath */ + +/* +NOTE: The ISCLOSED flag is set on the MOVETYPE segment before the +subpath proper; the LASTCLOSED flag is set on the last segment (LINETYPE) +in the subpath + +We define the ISPATHANCHOR predicate to test that a path handle +passed by the user is valid: +*/ + +#define ISPATHANCHOR(p) (ISPATHTYPE(p->type)&&p->last!=NULL) + +/* +For performance reasons, a user's "location" object is identical to +a path whose only segment is a move segment. We define a predicate +to test for this case. See also :hdref refid=location.. +*/ + +#define ISLOCATION(p) ((p)->type == MOVETYPE && (p)->link == NULL) + +/*END SHARED*/ +/*SHARED*/ + +struct conicsegment { + XOBJ_COMMON /* xobject common data define 3-26-91 PNM */ + /* type = CONICTYPE */ + unsigned char size; /* as with any 'segment' type */ + unsigned char context; /* as with any 'segment' type */ + struct segment *link; /* as with any 'segment' type */ + struct segment *last; /* as with any 'segment' type */ + struct fractpoint dest; /* Ending point (C point) */ + struct fractpoint M; /* "midpoint" of conic explained above */ + float roundness; /* explained above */ +} ; +/*END SHARED*/ +/*SHARED*/ + +struct beziersegment { + XOBJ_COMMON /* xobject common data define 3-26-91 PNM */ + /* type = BEZIERTYPE */ + unsigned char size; /* as with any 'segment' type */ + unsigned char context; /* as with any 'segment' type */ + struct segment *link; /* as with any 'segment' type */ + struct segment *last; /* as with any 'segment' type */ + struct fractpoint dest; /* ending point (D) */ + struct fractpoint B; /* control point B */ + struct fractpoint C; /* control point C */ +} ; + +/*END SHARED*/ +/*SHARED*/ + +struct hintsegment { + XOBJ_COMMON /* xobject common data define 3-26-91 PNM */ + /* type = HINTTYPE */ + unsigned char size; /* size of the structure */ + unsigned char context; /* device context */ + struct segment *link; /* pointer to next structure in linked list */ + struct segment *last; /* pointer to last structure in list */ + struct fractpoint dest; /* ALWAYS 0,0 */ + struct fractpoint ref; + struct fractpoint width; + char orientation; + char hinttype; + char adjusttype; + char direction; + int label; +} ; + +/*END SHARED*/ +/*SHARED*/ + +/* +CONCAT links the 'p2' path chain on the end of the 'p1' chain. (This macro +is also used by the STROKES module.) +*/ +#define CONCAT(p1, p2) { \ + p1->last->link = p2; /* link p2 on end of p1 */ \ + p1->last = p2->last; /* last of new is last of p2 */ \ + p2->last = NULL; } /* only first segment has non-NULL "last" */ + +/*END SHARED*/ +/* dump a path list */ +extern void t1_DumpPath ( struct segment *p ); diff --git a/nx-X11/lib/font/Type1/pictures.h b/nx-X11/lib/font/Type1/pictures.h new file mode 100644 index 000000000..0abc715ce --- /dev/null +++ b/nx-X11/lib/font/Type1/pictures.h @@ -0,0 +1,50 @@ +/* $Xorg: pictures.h,v 1.3 2000/08/17 19:46:31 cpqbld Exp $ */ +/* Copyright International Business Machines,Corp. 1991 + * All Rights Reserved + * + * License to use, copy, modify, and distribute this software + * and its documentation for any purpose and without fee is + * hereby granted, provided that the above copyright notice + * appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, + * and that the name of IBM not be used in advertising or + * publicity pertaining to distribution of the software without + * specific, written prior permission. + * + * IBM PROVIDES THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES + * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT + * LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE QUALITY AND + * PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT + * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF + * THE SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM) ASSUMES + * THE ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN + * NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ +/* $XFree86: xc/lib/font/Type1/pictures.h,v 1.3 1999/08/22 08:58:53 dawes Exp $ */ + +/* STUB */ + +#define CopyPicture(p) p +#define UniquePicture(p) p +#define KillPicture(p) +#define BegHandle(o,m) o +#define EndHandle(o,m) o +#define PictureBounds(P) P + +struct picture { + struct fractpoint origin; + struct fractpoint ending; +}; + +#define Phantom(o) t1_Phantom(o) +#define Snap(o) t1_Snap(o) + +extern struct segment *t1_Phantom ( struct segment *p ); +extern struct segment *t1_Snap ( struct segment *p ); diff --git a/nx-X11/lib/font/Type1/range.h b/nx-X11/lib/font/Type1/range.h new file mode 100644 index 000000000..496f000da --- /dev/null +++ b/nx-X11/lib/font/Type1/range.h @@ -0,0 +1,48 @@ +/* Copyright (c) 1994-1999 Silicon Graphics, Inc. All Rights Reserved. + * + * The contents of this file are subject to the CID Font Code Public Licence + * Version 1.0 (the "License"). You may not use this file except in compliance + * with the Licence. You may obtain a copy of the License at Silicon Graphics, + * Inc., attn: Legal Services, 2011 N. Shoreline Blvd., Mountain View, CA + * 94043 or at http://www.sgi.com/software/opensource/cid/license.html. + * + * Software distributed under the License is distributed on an "AS IS" basis. + * ALL WARRANTIES ARE DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED + * WARRANTIES OF MERCHANTABILITY, OF FITNESS FOR A PARTICULAR PURPOSE OR OF + * NON-INFRINGEMENT. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Software is CID font code that was developed by Silicon + * Graphics, Inc. + */ +#ifdef BUILDCID +#define XFONT_CID 1 +#endif + +#if XFONT_CID +#define CID_NAME_MAX 255 /* max # of characters in a file name */ +#define CID_PATH_MAX 1024 /* max # of characters in a path name */ + +typedef struct spacerange_code { + unsigned int srcCodeLo; + unsigned int srcCodeHi; +} spacerangecode; + +typedef struct space_range { + struct space_range *next; + int rangecnt; + struct spacerange_code *spacecode; +} spacerange; + +typedef struct cidrange_code { + unsigned int srcCodeLo; + unsigned int srcCodeHi; + unsigned int dstCIDLo; +} cidrangecode; + +typedef struct cid_range { + struct cid_range *next; + int rangecnt; + struct cidrange_code *range; +} cidrange; +#endif diff --git a/nx-X11/lib/font/Type1/regions.c b/nx-X11/lib/font/Type1/regions.c new file mode 100644 index 000000000..f8875dafb --- /dev/null +++ b/nx-X11/lib/font/Type1/regions.c @@ -0,0 +1,1651 @@ +/* $Xorg: regions.c,v 1.3 2000/08/17 19:46:31 cpqbld Exp $ */ +/* Copyright International Business Machines, Corp. 1991 + * All Rights Reserved + * Copyright Lexmark International, Inc. 1991 + * All Rights Reserved + * + * License to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, + * provided that the above copyright notice appear in all copies and that + * both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of IBM or Lexmark not be + * used in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * + * IBM AND LEXMARK PROVIDE THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES OF + * ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO ANY + * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, + * AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE + * QUALITY AND PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT + * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF THE + * SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM OR LEXMARK) ASSUMES THE + * ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN NO EVENT SHALL + * IBM OR LEXMARK BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF + * THIS SOFTWARE. + */ +/* $XFree86: xc/lib/font/Type1/regions.c,v 3.8tsi Exp $ */ + /* REGIONS CWEB V0023 LOTS */ +/* +:h1 id=regions.REGIONS Module - Regions Operator Handler + +This module is responsible for creating and manipulating regions. + +&author. Jeffrey B. Lotspiech (lotspiech@almaden.ibm.com) + + +:h3.Include Files + +The included files are: +*/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#ifdef FONTMODULE +# include "os.h" +#endif +#include "objects.h" +#include "spaces.h" +#include "paths.h" +#include "regions.h" +#include "curves.h" +#include "lines.h" +#include "pictures.h" +#include "fonts.h" +#include "hints.h" +#include "strokes.h" /* to pick up 'DoStroke' */ + + +static void newfilledge ( struct region *R, fractpel xmin, fractpel xmax, + fractpel ymin, fractpel ymax, int isdown ); +static struct edgelist *splitedge ( struct edgelist *list, pel y ); +static void vertjoin ( struct edgelist *top, struct edgelist *bottom ); +static int touches ( int h, pel *left, pel *right ); +static int crosses ( int h, pel *left, pel *right ); +static void edgemin ( int h, pel *e1, pel *e2 ); +static void edgemax ( int h, pel *e1, pel *e2 ); +static struct edgelist *NewEdge ( pel xmin, pel xmax, pel ymin, pel ymax, + pel *xvalues, int isdown ); +static struct edgelist *swathxsort ( struct edgelist *before0, + struct edgelist *edge ); +/* +:h3.Functions Provided to the TYPE1IMAGER User + +This module provides the following TYPE1IMAGER entry points: +*/ + +/*SHARED LINE(S) ORIGINATED HERE*/ +/* +:h3.Functions Provided to Other Modules + +This module provides the following entry points to other modules: +*/ + +/*SHARED LINE(S) ORIGINATED HERE*/ +/* +:h3.Macros Provided to Other Modules + +:h4.GOING_TO() - Macro Predicate Needed for Changing Direction, Etc. + +The actual generation of run end lists (edge boundaries) is left +to the low level rasterizing modules, LINES and CURVES. There +are some global region-type +questions that occur when doing a low-level +rasterization: +:ol. +:li.Did we just change direction in Y and therefore need to start +a new edge? +:li.Did we run out of allocated edge space? +:li.Do the minimum or maximum X values for the current edge need +updating? +:eol. +In general the REGIONS is not smart enough to answer those questions +itself. (For example, determining if and when a curve changes direction +may need detailed curve knowledge.) Yet, this must be done efficiently. +We provide a macro "GOING_TO" where the invoker tells us where it is +heading for (x2,y2), plus where it is now (x1,y1), plus the current +region under construction, and the macro answers the questions above. +*/ + +/*SHARED LINE(S) ORIGINATED HERE*/ +/* +:h2.Data Structures Used to Represent Regions + +:h3.The "region" Structure + +The region structure is an anchor for a linked list of "edgelist" +structures (see :hdref refid=edgelist..). It also summarizes the +information in the edgelist structures (for example, the bounding +box of the region). And, it contains scratch areas used during +the creation of a region. +*/ + +/*SHARED LINE(S) ORIGINATED HERE*/ +/* +The ISOPTIMIZED flag tells us if we've put a permanent region in +'optimal' form. +*/ +#define ISOPTIMIZED(flag) ((flag)&0x10) + +/* +The ISRECTANGULAR flag tells us if a region is a rectangle. We don't +always notice rectangles--if this flag is set, the region definitely +is a rectangle, but some rectangular regions will not have the flag +set. The flag is used to optimize some paths. +*/ + +/*SHARED LINE(S) ORIGINATED HERE*/ +/* +:h4."TT_INFINITY" - A Constant Region Structure of Infinite Extent + +Infinity is the complement of a null area: +Note - removed the refcount = 1 init, replaced with references = 2 3-26-91 PNM +*/ +static struct region _infinity = { REGIONTYPE, + ISCOMPLEMENT(ON)+ISINFINITE(ON)+ISPERMANENT(ON)+ISIMMORTAL(ON), 2, + {0, 0}, {0, 0}, + 0, 0, 0, 0, + NULL, NULL, + 0, 0, 0, 0, 0, NULL, NULL, + NULL, 0, NULL, NULL }; +struct region *TT_INFINITY = &_infinity; + +/* +:h4."EmptyRegion" - A Region Structure with Zero Area + +This structure is used to initialize the region to be built in +Interior(): +Note - replaced refcount = 1 init with references = 2 3-26-91 PNM +*/ + +/*SHARED LINE(S) ORIGINATED HERE*/ +struct region EmptyRegion = { REGIONTYPE, + ISPERMANENT(ON)+ISIMMORTAL(ON), 2, + {0, 0}, {0, 0}, + MAXPEL, MAXPEL, MINPEL, MINPEL, + NULL, NULL, + 0, 0, 0, 0, 0, NULL, NULL, + NULL, 0, NULL, NULL }; + +/* +:h3 id=edgelist.The "edgelist" Structure + +Regions are represented by a linked list of 'edgelist' structures. +When a region is complete, the structures are paired, one for the +left and one for the right edge. While a region is being built, +this rule may be violated temporarily. + +An 'edgelist' structure contains the X values for a given span +of Y values. The (X,Y) pairs define an edge. We use the crack +and edge coordinate system, so that integer values of X and Y +go between pels. The edge is defined between the minimum Y and +maximum Y. + +The linked list is kept sorted from top to bottom, that is, in +increasing y. Also, if 'e1' is an edgelist structure and 'e2' is the +next one in the list, they must have exactly the same ymin,ymax values +or be totally disjoint. These two requirements mean that if e2's ymin +is less than e1's ymax, it must be exactly equal to e1's ymin. A +sublist of structures with identical ymin and ymax values is called a +'swath'. + +In addition, edgelist structures are separately linked together based +on what subpath originally created them; each subpath is kept as a +separate circular linked list. This information is ignored unless +continuity checking is invoked. See :hdref refid=subpath. for a +complete description of this. +*/ + + +/*SHARED LINE(S) ORIGINATED HERE*/ + +/* +The "edgelist" structure follows the convention of TYPE1IMAGER user +objects, having a type field and a flag field as the first two +elements. However, the user never sees "edgelist" structures +directly; he is given handles to "region" structures only. + +By having a type field, we can use the "copy" feature of Allocate() +to duplicate edge lists quickly. + +We also define two flag bits for this structure. The ISDOWN bit is set +if the edge is going in the direction of increasing Y. The ISAMBIGUOUS +bit is set if the edge is identical to its neighbor (edge->link); such +edges may be "left" when they should be "right", or vice versa, +unnecessarily confusing the continuity checking logic. The FixSubPaths() +routine in HINTS will swap ambiguous edges if that avoids crossing edges; +see :hdref refid=fixsubp.. +*/ + +/*SHARED LINE(S) ORIGINATED HERE*/ + +/* +:h3.KillRegion() - Destroys a Region + +KillRegion nominally just decrements the reference count to that region. +If the reference count becomes 0, all memory associated with it is +freed. We just follow the linked list, freeing as we go, then kill any +associated (thresholded) picture. +Note - added conditional return based on references 3-26-91 PNM +*/ + +void +KillRegion(struct region *area) /* area to free */ +{ + register struct edgelist *p; /* loop variable */ + register struct edgelist *next; /* loop variable */ + + if (area->references < 0) + Abort("KillRegion: negative reference count"); + if ( (--(area->references) > 1) || + ( (area->references == 1) && !ISPERMANENT(area->flag) ) ) + return; + + for (p=area->anchor; p != NULL; p=next) { + next = p->link; + Free(p); + } + if (area->thresholded != NULL) + KillPicture(area->thresholded); + Free(area); +} +/* +:h3.CopyRegion() - Makes a Copy of a Region +*/ +struct region * +CopyRegion(struct region *area) /* region to duplicate */ +{ + register struct region *r; /* output region built here */ + register struct edgelist *last = NULL; /* loop variable */ + register struct edgelist *p,*newp; /* loop variables */ + + r = (struct region *)Allocate(sizeof(struct region), area, 0); + r->anchor = NULL; + + for (p=area->anchor; VALIDEDGE(p); p=p->link) { + + newp = NewEdge(p->xmin, p->xmax, p->ymin, p->ymax, p->xvalues, ISDOWN(p->flag)); + if (r->anchor == NULL) + r->anchor = last = newp; + else + last->link = newp; + + last = newp; + } + if (area->thresholded != NULL) + /* replaced DupPicture with Dup() 3-26-91 PNM */ + r->thresholded = (struct picture *)Dup(area->thresholded); + return(r); +} +/* +:h4.NewEdge() - Allocates and Returns a New "edgelist" Structure + +We allocate space for the X values contiguously with the 'edgelist' +structure that locates them. That way, we only have to free the +edgelist structure to free all memory associated with it. Damn +clever, huh? +*/ + +static struct edgelist * +NewEdge(pel xmin, pel xmax, /* X extent of edge */ + pel ymin, pel ymax, /* Y extent of edge */ + pel *xvalues, /* list of X values for entire edge */ + int isdown) /* flag: TRUE means edge progresses downward */ +{ + static struct edgelist template = { + EDGETYPE, 0, 1, NULL, NULL, + 0, 0, 0, 0, NULL }; + + register struct edgelist *r; /* returned structure */ + register int iy; /* ymin adjusted for 'long' alignment purposes */ + + if (ymin >= ymax) + Abort("newedge: height not positive"); +/* +We are going to copy the xvalues into a newly allocated area. It +helps performance if the values are all "long" aligned. We can test +if the xvalues are long aligned by ANDing the address with the +(sizeof(long) - 1)--if non zero, the xvalues are not aligned well. We +set 'iy' to the ymin value that would give us good alignment: +*/ + iy = ymin - (((unsigned long)xvalues) & (sizeof(long)-1)) / sizeof(pel); + + r = (struct edgelist *)Allocate(sizeof(struct edgelist), &template, + (ymax - iy) * sizeof(pel)); + + if (isdown) r->flag = ISDOWN(ON); + r->xmin = xmin; + r->xmax = xmax; + r->ymin = ymin; + r->ymax = ymax; + + r->xvalues = (pel *) FOLLOWING(r); + if (ymin != iy) { + r->xvalues += ymin - iy; + xvalues -= ymin - iy; + } + +/* +We must round up (ymax - iy) so we get the ceiling of the number of +longs. The destination must be able to hold these extra bytes because +Allocate() makes everything it allocates be in multiples of longs. +*/ + LONGCOPY(&r[1], xvalues, (ymax - iy) * sizeof(pel) + sizeof(long) - 1); + + return(r); +} + +/* +:h3 id=discard.discard() - Discard All Edges Between Two Edges + +At first glance it would seem that we could discard an edgelist +structure merely by unlinking it from the list and freeing it. You are +wrong, region-breath! For performance, the X values associated with an +edge are allocated contiguously with it. So, we free the X values when +we free a structure. However, once an edge has been split, we are no +longer sure which control block actually is part of the memory block +that contains the edges. Rather than trying to decide, we play it safe +and never free part of a region. + +So, to mark a 'edgelist' structure as discarded, we move it to the end +of the list and set ymin=ymax. +*/ + +static void +discard(struct edgelist *left, /* all edges between here exclusive */ + struct edgelist *right) /* should be discarded */ +{ + register struct edgelist *beg,*end,*p; + + beg = left->link; + if (beg == right) + return; + + for (p = beg; p != right; p = p->link) { + if (p->link == NULL && right != NULL) + Abort("discard(): ran off end"); + p->ymin = p->ymax = 32767; + end = p; + } + /* + * now put the chain beg/end at the end of right, if it is not + * already there: + */ + if (right != NULL) { + left->link = right; + while (right->link != NULL) + right = right->link; + right->link = beg; + } + end->link = NULL; +} + +/* +:h4.Unwind() - Discards Edges That Fail the Winding Rule Test + +The winding rule says that upward going edges should be paired with +downward going edges only, and vice versa. So, if two upward edges +or two downward edges are nominally left/right pairs, Unwind() should +discard the second one. Everything should balance; we should discard +an even number of edges; of course, we abort if we don't. +*/ +static void +Unwind(struct edgelist *area) /* input area modified in place */ +{ + register struct edgelist *last = NULL,*next; /* struct before and after current one */ + register int y; /* ymin of current swath */ + register int count,newcount; /* winding count registers */ + + while (VALIDEDGE(area)) { + + count = 0; + y = area->ymin; + + do { + next = area->link; + + if (ISDOWN(area->flag)) + newcount = count + 1; + else + newcount = count - 1; + + if (count == 0 || newcount == 0) + last = area; + else + discard(last, next); + + count = newcount; + area = next; + + } while (area != NULL && area->ymin == y); + + if (count != 0) + Abort("Unwind: uneven edges"); + } +} +/* +:h2.Building Regions + +:h3.Interior() - Iterate Through a Path, Building a Region + +This routine is the workhorse driver routine that iterates through a +path, calling the appropriate stepping routines to actually produce the +run end "edgelist" structures. + +:ol. +:li."Interior" calls StepLine or StepConic or StepBezier as appropriate +to produce run ends. +:li.Occasionally these routines will notice a change in Y direction +and will call ChangeDirection (through the GOING_TO macro); this is +a call back to the REGIONS module. +:li.ChangeDirection will call whatever function is in the region +structure; for Interior, this function is 'newfilledge'. +:li.Newfilledge will call NewEdge to create a new edgelist structure, +then, call SortSwath to sort it onto the linked list being built at +the region "anchor". +:eol. + +By making the function called by ChangeDirection be a parameter of the +region, we allow the same ChangeDirection logic to be used by stroking. +*/ + +/*SHARED LINE(S) ORIGINATED HERE*/ + +struct region * +Interior(struct segment *p, /* take interior of this path */ + int fillrule) /* rule to follow if path crosses itself */ +{ + register fractpel x,y; /* keeps ending point of path segment */ + fractpel lastx,lasty; /* previous x,y from path segment before */ + register struct region *R; /* region I will build */ + register struct segment *nextP; /* next segment of path */ + struct fractpoint hint; /* accumulated hint value */ + char tempflag; /* flag; is path temporary? */ + char Cflag; /* flag; should we apply continuity? */ + + if (p == NULL) + return(NULL); +/* +Establish the 'Cflag' continuity flag based on user's fill rule and +our own 'Continuity' pragmatic (0: never do continuity, 1: do what +user asked, >1: do it regardless). +*/ + if (fillrule > 0) { + Cflag = Continuity > 0; + fillrule -= CONTINUITY; + } + else + Cflag = Continuity > 1; + + ARGCHECK((fillrule != WINDINGRULE && fillrule != EVENODDRULE), + "Interior: bad fill rule", NULL, NULL, (1,p), struct region *); + + if (p->type == TEXTTYPE) +/* if (fillrule != EVENODDRULE) + else */ + return((struct region *)UniquePath(p)); + if (p->type == STROKEPATHTYPE) { + if (fillrule == WINDINGRULE) + return((struct region *)DoStroke(p)); + else + p = CoercePath(p); + } + + R = (struct region *)Allocate(sizeof(struct region), &EmptyRegion, 0); + + ARGCHECK(!ISPATHANCHOR(p), "Interior: bad path", p, R, (0), struct region *); + ARGCHECK((p->type != MOVETYPE), "Interior: path not closed", p, R, (0), struct region *); + + +/* changed definition from !ISPERMANENT to references <= 1 3-26-91 PNM */ + tempflag = (p->references <= 1); /* only first segment in path is so marked */ + if (!ISPERMANENT(p->flag)) p->references -= 1; + + R->newedgefcn = newfilledge; +/* +Believe it or not, "R" is now completely initialized. We are counting +on the copy of template to get other fields the way we want them, +namely +:ol. +:li.anchor = NULL +:li.xmin, ymin, xmax, ymax, to minimum and maximum values respectively. +:eol. +Anchor = NULL is very +important to ChangeDirection. +See :hdref refid=CD.. + +To minimize problems of "wrapping" in our pel arithmetic, we keep an +origin of the region which is the first move. Hopefully, that keeps +numbers within plus or minus 32K pels. +*/ + R->origin.x = 0/*TOFRACTPEL(NEARESTPEL(p->dest.x))*/; + R->origin.y = 0/*TOFRACTPEL(NEARESTPEL(p->dest.y))*/; + lastx = - R->origin.x; + lasty = - R->origin.y; +/* +ChangeDirection initializes other important fields in R, such as +lastdy, edge, edgeYstop, edgexmin, and edgexmax. The first segment +is a MOVETYPE, so it will be called first. +*/ +/* +The hints data structure must be initialized once for each path. +*/ + + if (ProcessHints) + InitHints(); /* initialize hint data structure */ + + while (p != NULL) { + + x = lastx + p->dest.x; + y = lasty + p->dest.y; + + nextP = p->link; + +/* +Here we start the hints processing by initializing the hint value to +zero. If ProcessHints is FALSE, the value will remain zero. +Otherwise, hint accumulates the computed hint values. +*/ + + hint.x = hint.y = 0; + +/* +If we are processing hints, and this is a MOVE segment (other than +the first on the path), we need to close (reverse) any open hints. +*/ + + if (ProcessHints) + if ((p->type == MOVETYPE) && (p->last == NULL)) { + CloseHints(&hint); + } + +/* +Next we run through all the hint segments (if any) attached to this +segment. If ProcessHints is TRUE, we will accumulate computed hint +values. In either case, nextP will be advanced to the first non-HINT +segment (or NULL), and each hint segment will be freed if necessary. +*/ + + while ((nextP != NULL) && (nextP->type == HINTTYPE)) { + if (ProcessHints) + ProcessHint((struct hintsegment *)nextP, + x + hint.x, y + hint.y, &hint); + + { + register struct segment *saveP = nextP; + + nextP = nextP->link; + if (tempflag) + Free(saveP); + } + } + +/* +We now apply the full hint value to the ending point of the path segment. +*/ + + x += hint.x; + y += hint.y; + + switch(p->type) { + + case LINETYPE: + StepLine(R, lastx, lasty, x, y); + break; + + case CONICTYPE: + { + +/* +For a conic curve, we apply half the hint value to the conic midpoint. +*/ + + } + break; + + case BEZIERTYPE: + { + register struct beziersegment *bp = (struct beziersegment *) p; + +/* +For a Bezier curve, we apply the full hint value to the Bezier C point. +*/ + + StepBezier(R, lastx, lasty, + lastx + bp->B.x, lasty + bp->B.y, + lastx + bp->C.x + hint.x, + lasty + bp->C.y + hint.y, + x, y); + } + break; + + case MOVETYPE: +/* +At this point we have encountered a MOVE segment. This breaks the +path, making it disjoint. +*/ + if (p->last == NULL) /* i.e., not first in path */ + ChangeDirection(CD_LAST, R, lastx, lasty, (fractpel) 0); + + ChangeDirection(CD_FIRST, R, x, y, (fractpel) 0); +/* +We'll just double check for closure here. We forgive an appended +MOVETYPE at the end of the path, if it isn't closed: +*/ + if (!ISCLOSED(p->flag) && p->link != NULL) + return((struct region *)ArgErr("Fill: sub-path not closed", p, NULL)); + break; + + default: + Abort("Interior: path type error"); + } +/* +We're done with this segment. Advance to the next path segment in +the list, freeing this one if necessary: +*/ + lastx = x; lasty = y; + + if (tempflag) + Free(p); + p = nextP; + } + ChangeDirection(CD_LAST, R, lastx, lasty, (fractpel) 0); + R->ending.x = lastx; + R->ending.y = lasty; +/* +Finally, clean up the region's based on the user's 'fillrule' request: +*/ + if (Cflag) + ApplyContinuity(R); + if (fillrule == WINDINGRULE) + Unwind(R->anchor); + return(R); +} +/* +:h3."workedge" Array + +This is a statically allocated array where edges are built +before being copied into more permanent storage by NewEdge(). +*/ + +#ifndef MAXEDGE +#define MAXEDGE 1000 +#endif + +static pel workedge[MAXEDGE]; +static pel *currentworkarea = workedge; +static pel currentsize = MAXEDGE; + +/* +:h3 id=cd.ChangeDirection() - Called When Y Direction Changes + +The rasterizing routines call this entry point when they detect +a change in Y. We then build the current edge and sort it into +emerging edgelist at 'anchor' by calling whatever "newedgefcn" +is appropriate. +*/ + +void +ChangeDirection(int type, /* CD_FIRST, CD_CONTINUE, or CD_LAST */ + struct region *R, /* region in which we are changing direction */ + fractpel x, fractpel y, /* current beginning x,y */ + fractpel dy) /* direction and magnitude of change in y */ +{ + register fractpel ymin,ymax; /* minimum and maximum Y since last call */ + register pel iy; /* nearest integer pel to 'y' */ + register pel idy; /* nearest integer pel to 'dy' */ + register int ydiff; /* allowed Y difference in 'currentworkarea' */ + + if (type != CD_FIRST) { + + if (R->lastdy > 0) { + ymin = R->firsty; + ymax = y; + } + else { + ymin = y; + ymax = R->firsty; + } + + if (ymax < ymin) + Abort("negative sized edge?"); + + + (*R->newedgefcn)(R, R->edgexmin, R->edgexmax, ymin, ymax, + R->lastdy > 0); + + } + + R->firsty = y; + R->firstx = x; + R->lastdy = dy; + + iy = NEARESTPEL(y); + idy = NEARESTPEL(dy); + if (currentworkarea != workedge && idy < MAXEDGE && idy > -MAXEDGE) { + NonObjectFree(currentworkarea); + currentworkarea = workedge; + currentsize = MAXEDGE; + } + ydiff = currentsize - 1; + if (dy > 0) { + R->edge = ¤tworkarea[-iy]; + R->edgeYstop = TOFRACTPEL(ydiff + iy) + FPHALF; + } + else { + R->edge = ¤tworkarea[ydiff - iy]; + R->edgeYstop = TOFRACTPEL(iy - ydiff) - FPHALF; + } + R->edgexmax = R->edgexmin = x; +/* +If this is the end of a subpath, we complete the subpath circular +chain: +*/ + if (type == CD_LAST && R->lastedge != NULL) { + register struct edgelist *e = R->firstedge; + + while (e->subpath != NULL) + e = e->subpath; + e->subpath = R->lastedge; + R->lastedge = R->firstedge = NULL; + } +} +/* +:h3 id=newfill.newfilledge() - Called When We Have a New Edge While Filling + +This is the prototypical "newedge" function passed to "Rasterize" and +stored in "newedgefcn" in the region being built. + +If the edge is non-null, we sort it onto the list of edges we are +building at "anchor". + +This function also has to keep the bounding box of the region +up to date. +*/ + +static void +newfilledge(struct region *R, /* region being built */ + fractpel xmin, fractpel xmax, /* X range of this edge */ + fractpel ymin, fractpel ymax, /* Y range of this edge */ + int isdown) /* flag: TRUE means edge goes down, else up */ +{ + + register pel pelxmin,pelymin,pelxmax,pelymax; /* pel versions of bounds */ + register struct edgelist *edge; /* newly created edge */ + + pelymin = NEARESTPEL(ymin); + pelymax = NEARESTPEL(ymax); + if (pelymin == pelymax) + return; + + pelxmin = NEARESTPEL(xmin); + pelxmax = NEARESTPEL(xmax); + + if (pelxmin < R->xmin) R->xmin = pelxmin; + if (pelxmax > R->xmax) R->xmax = pelxmax; + if (pelymin < R->ymin) R->ymin = pelymin; + if (pelymax > R->ymax) R->ymax = pelymax; + + edge = NewEdge(pelxmin, pelxmax, pelymin, pelymax, &R->edge[pelymin], isdown); + edge->subpath = R->lastedge; + R->lastedge = edge; + if (R->firstedge == NULL) + R->firstedge = edge; + + R->anchor = SortSwath(R->anchor, edge, swathxsort); + +} + +/* +:h2.Sorting Edges + +:h3.SortSwath() - Vertically Sort an Edge into a Region + +This routine sorts an edge or a pair of edges into a growing region, +so that the region maintains its top-to-bottom, left-to-right form. +The rules for sorting horizontally may vary depending on what you +are doing, but the rules for vertical sorting are always the same. +This routine is passed an argument that is a function that will +perform the horizontal sort on demand (for example, swathxsort() or +SwathUnion()). + +This is a recursive routine. A new edge (or edge pair) may overlap +the list I am building in strange and wonderful ways. Edges may +cross. When this happens, my strategy is to split the incoming edge +(or the growing list) in two at that point, execute the actual sort on +the top part of the split, and recursively call myself to figure out +exactly where the bottom part belongs. +*/ + +#define TOP(e) ((e)->ymin) /* the top of an edge (for readability */ +#define BOTTOM(e) ((e)->ymax) /* the bottom of an edge (for readability */ + +struct edgelist * +SortSwath(struct edgelist *anchor, /* list being built */ + struct edgelist *edge, /* incoming edge or pair of edges */ + SwathFunc swathfcn) /* horizontal sorter */ +{ + register struct edgelist *before,*after; + struct edgelist base; + + if (anchor == NULL) + return(edge); + + before = &base; + before->ymin = before->ymax = MINPEL; + before->link = after = anchor; + +/* +If the incoming edge is above the current list, we connect the current +list to the bottom of the incoming edge. One slight complication is +if the incoming edge overlaps into the current list. Then, we +first split the incoming edge in two at the point of overlap and recursively +call ourselves to sort the bottom of the split into the current list: +*/ + if (TOP(edge) < TOP(after)) { + if (BOTTOM(edge) > TOP(after)) { + + after = SortSwath(after, splitedge(edge, TOP(after)), swathfcn); + } + vertjoin(edge, after); + return(edge); + } +/* +At this point the top of edge is not higher than the top of the list, +which we keep in 'after'. We move the 'after' point down the list, +until the top of the edge occurs in the swath beginning with 'after'. + +If the bottom of 'after' is below the bottom of the edge, we have to +split the 'after' swath into two parts, at the bottom of the edge. +If the bottom of 'after' is above the bottom of the swath, +*/ + + while (VALIDEDGE(after)) { + + if (TOP(after) == TOP(edge)) { + if (BOTTOM(after) > BOTTOM(edge)) + vertjoin(after, splitedge(after, BOTTOM(edge))); + else if (BOTTOM(after) < BOTTOM(edge)) { + after = SortSwath(after, + splitedge(edge, BOTTOM(after)), swathfcn); + } + break; + } + else if (TOP(after) > TOP(edge)) { + if (BOTTOM(edge) > TOP(after)) { + after = SortSwath(after, + splitedge(edge, TOP(after)), swathfcn); + } + break; + } + else if (BOTTOM(after) > TOP(edge)) + vertjoin(after, splitedge(after, TOP(edge))); + + before = after; + after = after->link; + } + +/* +At this point 'edge' exactly corresponds in height to the current +swath pointed to by 'after'. +*/ + if (after != NULL && TOP(after) == TOP(edge)) { + before = (*swathfcn)(before, edge); + after = before->link; + } +/* +At this point 'after' contains all the edges after 'edge', and 'before' +contains all the edges before. Whew! A simple matter now of adding +'edge' to the linked list in its rightful place: +*/ + before->link = edge; + if (RegionDebug > 1) { + while (edge->link != NULL) { + edge = edge->link; + } + } + else + for (; edge->link != NULL; edge = edge->link) { ; } + + edge->link = after; + return(base.link); +} + +/* +:h3.splitedge() - Split an Edge or Swath in Two at a Given Y Value + +This function returns the edge or swath beginning at the Y value, and +is guaranteed not to change the address of the old swath while splitting +it. +*/ + +static struct edgelist * +splitedge(struct edgelist *list, /* area to split */ + pel y) /* Y value to split list at */ +{ + register struct edgelist *new; /* anchor for newly built list */ + register struct edgelist *last = NULL; /* end of newly built list */ + register struct edgelist *r; /* temp pointer to new structure */ + register struct edgelist *lastlist; /* temp pointer to last 'list' value */ + + lastlist = new = NULL; + + while (list != NULL) { + if (y < list->ymin) + break; + if (y >= list->ymax) + Abort("splitedge: above top of list"); + if (y == list->ymin) + Abort("splitedge: would be null"); + + r = (struct edgelist *)Allocate(sizeof(struct edgelist), list, 0); +/* +At this point 'r' points to a copy of the single structure at 'list'. +We will make 'r' be the new split 'edgelist'--the lower half. +We don't bother to correct 'xmin' and 'xmax', we'll take the +the pessimistic answer that results from using the old values. +*/ + r->ymin = y; + r->xvalues = list->xvalues + (y - list->ymin); +/* +Note that we do not need to allocate new memory for the X values, +they can remain with the old "edgelist" structure. We do have to +update that old structure so it is not as high: +*/ + list->ymax = y; +/* +Insert 'r' in the subpath chain: +*/ + r->subpath = list->subpath; + list->subpath = r; +/* +Now attach 'r' to the list we are building at 'new', and advance +'list' to point to the next element in the old list: +*/ + if (new == NULL) + new = r; + else + last->link = r; + last = r; + lastlist = list; + list = list->link; + } +/* +At this point we have a new list built at 'new'. We break the old +list at 'lastlist', and add the broken off part to the end of 'new'. +Then, we return the caller a pointer to 'new': +*/ + if (new == NULL) + Abort("null splitedge"); + lastlist->link = NULL; + last->link = list; + return(new); +} + +/* +:h3.vertjoin() - Join Two Disjoint Edge Lists Vertically + +The two edges must be disjoint vertically. +*/ +static void vertjoin(top, bottom) + register struct edgelist *top; /* uppermost region */ + register struct edgelist *bottom; /* bottommost region */ +{ + if (BOTTOM(top) > TOP(bottom)) + Abort("vertjoin not disjoint"); + + for (; top->link != NULL; top=top->link) { ; } + + top->link = bottom; + return; +} + +/* +:h3.swathxsort() - Sorting by X Values + +We need to sort 'edge' into its rightful +place in the swath by X value, taking care that we do not accidentally +advance to the next swath while searching for the correct X value. Like +all swath functions, this function returns a pointer to the edge +BEFORE the given edge in the sort. +*/ + +static struct edgelist * +swathxsort(struct edgelist *before0, /* edge before this swath */ + struct edgelist *edge) /* input edge */ +{ + register struct edgelist *before; + register struct edgelist *after; + register pel y = 0; + + before = before0; + after = before->link; + + while (after != NULL && TOP(after) == TOP(edge)) { + + register pel *x1,*x2; + + y = TOP(edge); + x1 = after->xvalues; + x2 = edge->xvalues; + + while (y < BOTTOM(edge) && *x1 == *x2) { + x1++; x2++; y++; + } + if (y >= BOTTOM(edge)) { + edge->flag |= ISAMBIGUOUS(ON); + after->flag |= ISAMBIGUOUS(ON); + break; + } + + if (*x1 >= *x2) + break; + + before = after; + after = after->link; + } + +/* +At this point, 'edge' is between 'before' and 'after'. If 'edge' didn't +cross either of those other edges, we would be done. We check for +crossing. If it does cross, we split the problem up by calling SortSwath +recursively with the part of the edge that is below the crossing point: +*/ +{ + register int h0,h; /* height of edge--number of scans */ + + h0 = h = BOTTOM(edge) - y; + y -= TOP(edge); + + if (h0 <= 0) { + return(before); + } + + if (TOP(before) == TOP(edge)) + h -= crosses(h, &before->xvalues[y], &edge->xvalues[y]); + if (after != NULL && TOP(after) == TOP(edge)) + h -= crosses(h, &edge->xvalues[y], &after->xvalues[y]); + + if (h < h0) { + SortSwath(before0->link, + splitedge(edge, TOP(edge) + y + h), + swathxsort); + + } +} + + return(before); +} +/* +:h3.SwathUnion() - Union Two Edges by X Value + +We have a left and right edge that must be unioned into a growing +swath. If they are totally disjoint, they are just added in. The +fun comes in they overlap the existing edges. Then some edges +will disappear. +*/ + +struct edgelist * +SwathUnion(struct edgelist *before0, /* edge before the swath */ + struct edgelist *edge) /* list of two edges to be unioned */ +{ + register int h; /* saves height of edge */ + register struct edgelist *rightedge; /* saves right edge of 'edge' */ + register struct edgelist *before,*after; /* edge before and after */ + int h0; /* saves initial height */ + + h0 = h = edge->ymax - edge->ymin; + if (h <= 0) + Abort("SwathUnion: 0 height swath?"); + + before = before0; + after = before->link; + + while (after != NULL && TOP(after) == TOP(edge)) { + register struct edgelist *right; + + right = after->link; + if (right->xvalues[0] >= edge->xvalues[0]) + break; + before = right; + after = before->link; + } +/* +This is the picture at this point. 'L' indicates a left hand edge, +'R' indicates the right hand edge. +'<--->' indicates the degree of uncertainty as to its placement +relative to other edges: +:xmp atomic. + before after + R <---L----> R L R L R + <---L---> <------R--------------------------> + edge +:exmp. +In case the left of 'edge' touches 'before', we need to reduce +the height by that amount. +*/ + if (TOP(before) == TOP(edge)) + h -= touches(h, before->xvalues, edge->xvalues); + + rightedge = edge->link; + + if (after == NULL || TOP(after) != TOP(edge) || + after->xvalues[0] > rightedge->xvalues[0]) { +/* +On this side of the the above 'if', the new edge is disjoint from the +existing edges in the swath. This is the picture: +:xmp atomic. + before after + R L R L R L R + L R + edge +:exmp. +We will verify it remains disjoint for the entire height. If the +situation changes somewhere down the edge, we split the edge at that +point and recursively call ourselves (through 'SortSwath') to figure +out the new situation: +*/ + if (after != NULL && TOP(after) == TOP(edge)) + h -= touches(h, rightedge->xvalues, after->xvalues); + if (h < h0) + SortSwath(before0->link, splitedge(edge, edge->ymin + h), t1_SwathUnion); + /* go to "return" this edge pair; it is totally disjoint */ + } + else { +/* +At this point, at the 'else', we know that the +new edge overlaps one or more pairs in the existing swath. Here is +a picture of our knowledge and uncertainties: +:xmp atomic. + before after + R L R L R L R + <---L---> <---R-------------------> + edge +:exmp. +We need to move 'after' along until it is to the right of the +right of 'edge'. ('After' should always point to a left edge of a pair:) +*/ + register struct edgelist *left; /* variable to keep left edge in */ + + do { + left = after; + after = (after->link)->link; + + } while (after != NULL && TOP(after) == TOP(edge) + && after->xvalues[0] <= rightedge->xvalues[0]); +/* +At this point this is the picture: +:xmp atomic. + before left after + R L R L R L R + <---L---> <---R---> + edge +:exmp. +We need to verify that the situation stays like this all the way +down the edge. Again, if the +situation changes somewhere down the edge, we split the edge at that +point and recursively call ourselves (through 'SortSwath') to figure +out the new situation: +*/ + + h -= crosses(h, left->xvalues, rightedge->xvalues); + h -= crosses(h, edge->xvalues, ((before->link)->link)->xvalues); + + if (after != NULL && TOP(after) == TOP(edge)) + + h -= touches(h, rightedge->xvalues, after->xvalues); + +/* +OK, if we touched either of our neighbors we need to split at that point +and recursively sort the split edge onto the list. One tricky part +is that when we recursively sort, 'after' will change if it was not +in our current swath: +*/ + if (h < h0) { + SortSwath(before0->link, + splitedge(edge, edge->ymin + h), + t1_SwathUnion); + + if (after == NULL || TOP(after) != TOP(edge)) + for (after = before0->link; + TOP(after) == TOP(edge); + after = after->link) { ; } + } +/* +Now we need to augment 'edge' by the left and right of the overlapped +swath, and to discard all edges between before and after, because they +were overlapped and have been combined with the new incoming 'edge': +*/ + edge->xmin = MIN(edge->xmin, (before->link)->xmin); + edge->xmax = MIN(edge->xmax, (before->link)->xmax); + edgemin(h, edge->xvalues, (before->link)->xvalues); + rightedge->xmin = MAX(rightedge->xmin, (left->link)->xmin); + rightedge->xmax = MAX(rightedge->xmax, (left->link)->xmax); + edgemax(h, rightedge->xvalues, (left->link)->xvalues); + discard(before, after); + } + return(before); +} +#ifdef notused +/* +:h3.swathrightmost() - Simply Sorts New Edge to Rightmost of Swath + +Like all swath functions, this function returns a pointer to the edge +BEFORE the given edge in the sort. +*/ + +static struct edgelist * +swathrightmost(struct edgelist *before, /* edge before this swath */ + struct edgelist *edge) /* input edge */ +{ + register struct edgelist *after; + + after = before->link; + + while (after != NULL && TOP(after) == TOP(edge)) { + before = after; + after = after->link; + } + + return(before); + +} +#endif +/* +:h3.touches() - Returns the Remaining Height When Two Edges Touch + +So, it will return 0 if they never touch. Allows incredibly(?) mnemonic +if (touches(...)) construct. +*/ + +static int +touches(int h, pel *left, pel *right) +{ + for (; h > 0; h--) + if (*left++ >= *right++) + break; + return(h); +} +/* +:h3.crosses() - Returns the Remaining Height When Two Edges Cross + +So, it will return 0 if they never cross. +*/ + +static int +crosses(int h, pel *left, pel *right) +{ + for (; h > 0; h--) + if (*left++ > *right++) + break; + return(h); +} +/* +:h3.cedgemin() - Stores the Mininum of an Edge and an X Value +*/ + +static void +cedgemin(int h, pel *e1, pel x) +{ + for (; --h >= 0; e1++) + if (*e1 > x) + *e1 = x; +} +/* +:h3.cedgemax() - Stores the Maximum of an Edge and an X Value +*/ + +static void +cedgemax(int h, pel *e1, pel x) +{ + for (; --h >= 0; e1++) + if (*e1 < x) + *e1 = x; +} +/* +:h3.edgemin() - Stores the Mininum of Two Edges in First Edge +*/ + +static void +edgemin(int h, pel *e1, pel *e2) +{ + for (; --h >= 0; e1++,e2++) + if (*e1 > *e2) + *e1 = *e2; +} +/* +:h3.edgemax() - Stores the Maximum of Two Edges in First Edge +*/ + +static void +edgemax(int h, pel *e1, pel *e2) +{ + for (; --h >= 0; e1++,e2++) + if (*e1 < *e2) + *e1 = *e2; +} + +/* +:h2.Changing the Representation of Regions + +For convenience and/or performance, we sometimes like to change the way +regions are represented. This does not change the object itself, just +the representation, so these transformations can be made on a permanent +region. + +*/ + +void +MoveEdges(struct region *R, /* region to modify */ + fractpel dx, fractpel dy) /* delta X and Y to move edge list by */ +{ + register struct edgelist *edge; /* for looping through edges */ + + R->origin.x += dx; + R->origin.y += dy; + R->ending.x += dx; + R->ending.y += dy; + if (R->thresholded != NULL) { + R->thresholded->origin.x -= dx; + R->thresholded->origin.y -= dy; + } +/* +From now on we will deal with dx and dy as integer pel values: +*/ + dx = NEARESTPEL(dx); + dy = NEARESTPEL(dy); + if (dx == 0 && dy == 0) + return; + + R->xmin += dx; + R->xmax += dx; + R->ymin += dy; + R->ymax += dy; + + for (edge = R->anchor; VALIDEDGE(edge); edge = edge->link) { + edge->ymin += dy; + edge->ymax += dy; + if (dx != 0) { + register int h; /* loop index; height of edge */ + register pel *Xp; /* loop pointer to X values */ + + edge->xmin += dx; + edge->xmax += dx; + for (Xp = edge->xvalues, h = edge->ymax - edge->ymin; + --h >= 0; ) + *Xp++ += dx; + } + } +} + +/* +:h3.UnJumble() - Sort a Region Top to Bottom + +It is an open question whether it pays in general to do this. +*/ + +void +UnJumble(struct region *region) /* region to sort */ +{ + register struct edgelist *anchor; /* new lists built here */ + register struct edgelist *edge; /* edge pointer for loop */ + register struct edgelist *next; /* ditto */ + + anchor = NULL; + + for (edge=region->anchor; VALIDEDGE(edge); edge=next) { + if (edge->link == NULL) + Abort("UnJumble: unpaired edge?"); + next = edge->link->link; + edge->link->link = NULL; + anchor = SortSwath(anchor, edge, t1_SwathUnion); + } + + if (edge != NULL) + vertjoin(anchor, edge); + + region->anchor = anchor; + region->flag &= ~ISJUMBLED(ON); +} + +/* +*/ +#ifdef notused +static void +OptimizeRegion(struct region *R) /* region to optimize */ +{ + register pel *xP; /* pel pointer for inner loop */ + register int x; /* holds X value */ + register int xmin,xmax; /* holds X range */ + register int h; /* loop counter */ + register struct edgelist *e; /* edgelist pointer for loop */ + + R->flag |= ISRECTANGULAR(ON); + + for (e = R->anchor; VALIDEDGE(e); e=e->link) { + xmin = MAXPEL; + xmax = MINPEL; + for (h = e->ymax - e->ymin, xP = e->xvalues; --h >= 0;) { + x = *xP++; + if (x < xmin) xmin = x; + if (x > xmax) xmax = x; + } + if (xmin != xmax || (xmin != R->xmin && xmax != R->xmax)) + R->flag &= ~ISRECTANGULAR(ON); + if (xmin < e->xmin || xmax > e->xmax) + Abort("Tighten: existing edge bound was bad"); + if (xmin < R->xmin || xmax > R->xmax) + Abort("Tighten: existing region bound was bad"); + e->xmin = xmin; + e->xmax = xmax; + } + R->flag |= ISOPTIMIZED(ON); +} +#endif + +/* +:h2.Miscelaneous Routines + +:h3.MoreWorkArea() - Allocate New Space for "edge" + +Our strategy is to temporarily allocate an array to hold this +unexpectedly large edge. ChangeDirection frees this array any time +it gets a shorter 'dy'. +*/ + +/*ARGSUSED*/ +void +MoreWorkArea(struct region *R, /* region we are generating */ + fractpel x1, fractpel y1, /* starting point of line */ + fractpel x2, fractpel y2) /* ending point of line */ +{ + register int idy; /* integer dy of line */ + + idy = NEARESTPEL(y1) - NEARESTPEL(y2); + if (idy < 0) idy = - idy; + + /* + * we must add one to the delta for the number of run ends we + * need to store: + */ + if (++idy > currentsize) { + if (currentworkarea != workedge) + NonObjectFree(currentworkarea); + currentworkarea = (pel *)Allocate(0, NULL, idy * sizeof(pel)); + currentsize = idy; + } + ChangeDirection(CD_CONTINUE, R, x1, y1, y2 - y1); +} + +/* +:h3.BoxClip() - Clip a Region to a Rectangle + +BoxClip also duplicates the region if it is permanent. Note the +clipping box is specified in REGION coordinates, that is, in +coordinates relative to the region (0,0) point +*/ + +struct region * +BoxClip(struct region *R, /* region to clip */ + pel xmin, pel ymin, /* upper left hand corner of rectangle */ + pel xmax, pel ymax) /* lower right hand corner */ +{ + struct edgelist anchor; /* pretend edgelist to facilitate discards */ + register struct edgelist *e,*laste; + + R = UniqueRegion(R); + + if (xmin > R->xmin) { + R->xmin = xmin; + } + if (xmax < R->xmax) { + R->xmax = xmax; + } + + if (ymin > R->ymin) { + R->ymin = ymin; + } + if (ymax < R->ymax) { + R->ymax = ymax; + } + + + laste = &anchor; + anchor.link = R->anchor; + + for (e = R->anchor; VALIDEDGE(e); e = e->link) { + if (TOP(e) < ymin) { + e->xvalues += ymin - e->ymin; + e->ymin = ymin; + } + if (BOTTOM(e) > ymax) + e->ymax = ymax; + if (TOP(e) >= BOTTOM(e)) { + discard(laste, e->link->link); + e = laste; + continue; + } + if (e->xmin < xmin) { + cedgemax(BOTTOM(e) - TOP(e), e->xvalues, xmin); + e->xmin = xmin; + e->xmax = MAX(e->xmax, xmin); + } + if (e->xmax > xmax) { + cedgemin(BOTTOM(e) - TOP(e), e->xvalues, xmax); + e->xmin = MIN(e->xmin, xmax); + e->xmax = xmax; + } + laste = e; + } + + R->anchor = anchor.link; + + return(R); +} + +#ifdef notdef +/* +:h3.CoerceRegion() - Force a TextPath Structure to Become a Region + +We also save the newly created region in the textpath structure, if the +structure was permanent. Then we don't have to do this again. Why not +save it all the time? Well, we certainly could, but I suspect it +wouldn't pay. We would have to make this region permanent (because we +couldn't have it be consumed) and this would probably require +unnecessary CopyRegions in most cases. +*/ + +struct region * +CoerceRegion(struct textpath *tp) /* input TEXTTYPE */ +{ + struct segment *path; /* temporary character path */ + struct region *R; /* returned region */ + + + R = Interior(path, EVENODDRULE); + return(R); +} +#endif + +/* +:h3.RegionBounds() - Returns Bounding Box of a Region +*/ + +struct segment * +RegionBounds(struct region *R) +{ + register struct segment *path; /* returned path */ + + path = BoxPath(IDENTITY, R->ymax - R->ymin, R->xmax - R->xmin); + path = Join(PathSegment(MOVETYPE, R->origin.x + TOFRACTPEL(R->xmin), + R->origin.y + TOFRACTPEL(R->ymin) ), + path); + return(path); +} + +/* +:h2.Formatting/Dump Routines for Debug + +:h3.DumpArea() - Display a Region +*/ +void +DumpArea(struct region *area) +{ + DumpEdges(area->anchor); +} + +#define INSWATH(p, y0, y1) (p != NULL && p->ymin == y0 && p->ymax == y1) +/* +:h3.DumpEdges() - Display Run End Lists (Edge Lists) +*/ + +/* +:h3.edgecheck() - For Debug, Verify that an Edge Obeys the Rules +*/ + +/*ARGSUSED*/ +static void +edgecheck(struct edgelist *edge, int oldmin, int oldmax) +{ + if (edge->type != EDGETYPE) + Abort("EDGE ERROR: non EDGETYPE in list"); +/* +The following check is not valid if the region is jumbled so I took it +out: +*/ +/* if (edge->ymin < oldmax && edge->ymin != oldmin) + Abort("EDGE ERROR: overlapping swaths"); */ +} + +void +DumpEdges(struct edgelist *edges) +{ + register struct edgelist *p,*p2; + register pel ymin = MINPEL; + register pel ymax = MINPEL; + + if (edges == NULL) { + return; + } + if (RegionDebug <= 1) { + for (p=edges; p != NULL; p = p->link) { + edgecheck(p, ymin, ymax); + ymin = p->ymin; ymax = p->ymax; + } + } + else { + + for (p2=edges; p2 != NULL; ) { + + edgecheck(p2, ymin, ymax); + ymin = p2->ymin; + ymax = p2->ymax; + + while (INSWATH(p2, ymin, ymax)) + p2 = p2->link; + } + } +} diff --git a/nx-X11/lib/font/Type1/regions.h b/nx-X11/lib/font/Type1/regions.h new file mode 100644 index 000000000..96ad1a53a --- /dev/null +++ b/nx-X11/lib/font/Type1/regions.h @@ -0,0 +1,250 @@ +/* $Xorg: regions.h,v 1.3 2000/08/17 19:46:32 cpqbld Exp $ */ +/* Copyright International Business Machines, Corp. 1991 + * All Rights Reserved + * Copyright Lexmark International, Inc. 1991 + * All Rights Reserved + * + * License to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, + * provided that the above copyright notice appear in all copies and that + * both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of IBM or Lexmark not be + * used in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * + * IBM AND LEXMARK PROVIDE THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES OF + * ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO ANY + * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, + * AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE + * QUALITY AND PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT + * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF THE + * SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM OR LEXMARK) ASSUMES THE + * ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN NO EVENT SHALL + * IBM OR LEXMARK BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF + * THIS SOFTWARE. + */ +/* $XFree86: xc/lib/font/Type1/regions.h,v 1.7 2001/01/17 19:43:23 dawes Exp $ */ +/*SHARED*/ + +#define Interior(p,rule) t1_Interior(p,rule) +#define Union(a1,a2) t1_Union(a1,a2) +#define Intersect(a1,a2) t1_Intersect(a1,a2) +#define Complement(area) t1_Complement(area) +#define Overlap(a1,a2) t1_OverLap(a1,a2) + + +/* returns the interior of a closed path */ +extern struct region *t1_Interior ( struct segment *p, int fillrule ); +#if 0 +struct region *t1_Union(); /* set union of paths or regions */ +struct region *t1_Intersect(); /* set intersection of regions */ +struct region *t1_Complement(); /* complement of a region */ +int t1_Overlap(); /* returns a Boolean; TRUE if regions overlap */ +#endif + +#define TT_INFINITY t1_Infinity + +/*END SHARED*/ +/*SHARED*/ + +#define ChangeDirection(type,R,x,y,dy) t1_ChangeDirection(type,R,x,y,dy) + +/* called when we change direction in Y */ +extern void t1_ChangeDirection ( int type, struct region *R, fractpel x, + fractpel y, fractpel dy ); +#define CD_FIRST -1 /* enumeration of ChangeDirection type */ +#define CD_CONTINUE 0 /* enumeration of ChangeDirection type */ +#define CD_LAST 1 /* enumeration of ChangeDirection type */ + +#define MoreWorkArea(R,x1,y1,x2,y2) t1_MoreWorkArea(R,x1,y1,x2,y2) +#define KillRegion(area) t1_KillRegion(area) +#define CopyRegion(area) t1_CopyRegion(area) +#define BoxClip(R,xmin,ymin,xmax,ymax) t1_BoxClip(R,xmin,ymin,xmax,ymax) +#define SortSwath(a,p,f) t1_SortSwath(a,p,f) +#define SwathUnion(b,e) t1_SwathUnion(b,e) +#define RegionBounds(r) t1_RegionBounds(r) +#define CoerceRegion(p) t1_CoerceRegion(p) +#define MoveEdges(R,dx,dy) t1_MoveEdges(R,dx,dy) +#define UnJumble(R) t1_UnJumble(R) + +typedef struct edgelist *(*SwathFunc)(struct edgelist *, struct edgelist *); + +/* get longer edge list for stepping */ +extern void t1_MoreWorkArea ( struct region *R, fractpel x1, fractpel y1, + fractpel x2, fractpel y2 ); +/* duplicate a region */ +extern struct region *t1_CopyRegion ( struct region *area ); +/* destroy a region */ +extern void t1_KillRegion ( struct region *area ); +/* clip a region to a rectangle */ +extern struct region *t1_BoxClip ( struct region *R, pel xmin, pel ymin, + pel xmax, pel ymax ); +/* sort edges onto growing edge list */ +extern struct edgelist *t1_SortSwath ( struct edgelist *anchor, + struct edgelist *edge, + SwathFunc swathfcn ); +/* 'union' two edges into a swath */ +extern struct edgelist *t1_SwathUnion ( struct edgelist *before0, + struct edgelist *edge ); +/* returns bounding box of a region */ +extern struct segment *t1_RegionBounds ( struct region *R ); +#ifdef notdef +/* force text to become a true region */ +struct region *t1_CoerceRegion(struct textpath *tp); +#endif +/* moves the edge values in a region */ +extern void t1_MoveEdges ( struct region *R, fractpel dx, fractpel dy ); +/* sort the edges and reset the jumbled flag */ +extern void t1_UnJumble ( struct region *region ); + + +/*END SHARED*/ +/*SHARED*/ + +#define GOING_TO(R, x1, y1, x2, y2, dy) { \ + if (dy < 0) { \ + if (R->lastdy >= 0) \ + ChangeDirection(CD_CONTINUE, R, x1, y1, dy); \ + if (y2 < R->edgeYstop) \ + MoreWorkArea(R, x1, y1, x2, y2); \ + } \ + else if (dy > 0) { \ + if (R->lastdy <= 0) \ + ChangeDirection(CD_CONTINUE, R, x1, y1, dy); \ + if (y2 > R->edgeYstop) \ + MoreWorkArea(R, x1, y1, x2, y2); \ + } \ + else /* dy == 0 */ ChangeDirection(CD_CONTINUE, R, x1, y1, dy); \ + if (x2 < R->edgexmin) R->edgexmin = x2; \ + else if (x2 > R->edgexmax) R->edgexmax = x2; \ +} + +#ifndef FONTMODULE +#ifndef __sxg__ +#include <limits.h> +#endif +#endif +#ifdef SHRT_MIN +#define MINPEL SHRT_MIN +#else +#define MINPEL ((pel)(-1<<(8*sizeof(pel)-1))) /* smallest value fitting in a pel */ +#endif +#ifdef SHRT_MAX +#define MAXPEL SHRT_MAX +#else +#define MAXPEL ((pel)((1<<(8*sizeof(pel)-1))-1))/* largest value fitting in a pel */ +#endif + +/* +The "Unique"-type macro is different (unique?) for regions, because some +regions structures are shared among several objects, and might have +to be made unique for that reason (i.e., references > 1). +*/ + +#define ConsumeRegion(R) MAKECONSUME(R,KillRegion(R)) +#define UniqueRegion(R) MAKEUNIQUE(R,CopyRegion(R)) + + +/*END SHARED*/ +/*SHARED*/ + +typedef void (*NewEdgeFunc)(struct region *, + fractpel, fractpel, fractpel, fractpel, int); + +struct region { + XOBJ_COMMON /* xobject common data define 3-26-91 PNM */ + /* type = REGIONTYPE */ + struct fractpoint origin; /* beginning handle: X,Y origin of region */ + struct fractpoint ending; /* ending handle: X,Y change after painting region */ + pel xmin,ymin; /* minimum X,Y of region */ + pel xmax,ymax; /* mat1_mum X,Y of region */ + struct edgelist *anchor; /* list of edges that bound the region */ + struct picture *thresholded; /* region defined by thresholded picture*/ +/* +Note that the ending handle and the bounding box values are stored +relative to 'origin'. + +The above elements describe a region. The following elements are +scratchpad areas used while the region is being built: +*/ + fractpel lastdy; /* direction of last segment */ + fractpel firstx,firsty; /* starting point of current edge */ + fractpel edgexmin,edgexmax; /* x extent of current edge */ + struct edgelist *lastedge,*firstedge; /* last and first edges in subpath */ + pel *edge; /* pointer to array of X values for edge */ + fractpel edgeYstop; /* Y value where 'edges' array ends */ + NewEdgeFunc newedgefcn; /* function to use when building a new edge */ + struct strokeinfo *strokeinfo; /* scratchpad info during stroking only */ +} ; +/* +The ISCOMPLEMENT flag indicates the region is reversed--it is the +"outside" of the nominal region. +*/ +#define ISCOMPLEMENT(flag) ((flag)&0x80) +/* +The ISJUMBLED flag indicates the region is not sorted top-to-bottom. +*/ +#define ISJUMBLED(flag) ((flag)&0x40) +/* +The ISINFINITE flag allows a quick check for an INFINITE region, which +is frequently intersected. +*/ +#define ISINFINITE(flag) ((flag)&0x20) + +/*END SHARED*/ +/*SHARED*/ + +#define ISRECTANGULAR(flag) ((flag)&0x08) + +/*END SHARED*/ +/*SHARED*/ + +#define EmptyRegion t1_EmptyRegion + +/*END SHARED*/ +/*SHARED*/ + +struct edgelist { + XOBJ_COMMON /* xobject common data define 3-26-91 PNM */ + /* type = EDGETYPE */ + struct edgelist *link; /* pointer to next in linked list */ + struct edgelist *subpath; /* informational link for "same subpath" */ + pel xmin,xmax; /* range of edge in X */ + pel ymin,ymax; /* range of edge in Y */ + pel *xvalues; /* pointer to ymax-ymin X values */ +} ; +/* +The end of the list is marked by either "link" being NULL, or by +ymin == ymax. See :hdref refid=discard.. We define the VALIDEDGE +predicate to test for the opposite of these conditions: +*/ + +#define VALIDEDGE(p) ((p)!=NULL&&(p)->ymin<(p)->ymax) + +/*END SHARED*/ +/*SHARED*/ + +#define ISDOWN(f) ((f)&0x80) + +#define ISAMBIGUOUS(f) ((f)&0x40) + +/*END SHARED*/ +/*SHARED*/ + +/* +Interior() rule enumerations: +*/ +#define WINDINGRULE -2 +#define EVENODDRULE -3 + +#define CONTINUITY 0x80 /* can be added to above rules; e.g. WINDINGRULE+CONTINUITY */ + +/*END SHARED*/ + +/* dump a region structure */ +extern void t1_DumpArea ( struct region *area ); +/* dump a region's edge list */ +extern void t1_DumpEdges ( struct edgelist *edges ); diff --git a/nx-X11/lib/font/Type1/scanfont.c b/nx-X11/lib/font/Type1/scanfont.c new file mode 100644 index 000000000..8db497959 --- /dev/null +++ b/nx-X11/lib/font/Type1/scanfont.c @@ -0,0 +1,2370 @@ +/* $XdotOrg: xc/lib/font/Type1/scanfont.c,v 1.5 2005/07/09 23:30:06 keithp Exp $ */ +/* $Xorg: scanfont.c,v 1.3 2000/08/17 19:46:32 cpqbld Exp $ */ +/* Copyright International Business Machines,Corp. 1991 + * All Rights Reserved + * + * License to use, copy, modify, and distribute this software + * and its documentation for any purpose and without fee is + * hereby granted, provided that the above copyright notice + * appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, + * and that the name of IBM not be used in advertising or + * publicity pertaining to distribution of the software without + * specific, written prior permission. + * + * IBM PROVIDES THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES + * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT + * LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE QUALITY AND + * PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT + * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF + * THE SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM) ASSUMES + * THE ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN + * NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ +/* Author: Katherine A. Hitchcock IBM Almaden Research Laboratory */ +/* Copyright (c) 1994-1999 Silicon Graphics, Inc. All Rights Reserved. + * + * The contents of this file are subject to the CID Font Code Public Licence + * Version 1.0 (the "License"). You may not use this file except in compliance + * with the Licence. You may obtain a copy of the License at Silicon Graphics, + * Inc., attn: Legal Services, 2011 N. Shoreline Blvd., Mountain View, CA + * 94043 or at http://www.sgi.com/software/opensource/cid/license.html. + * + * Software distributed under the License is distributed on an "AS IS" basis. + * ALL WARRANTIES ARE DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED + * WARRANTIES OF MERCHANTABILITY, OF FITNESS FOR A PARTICULAR PURPOSE OR OF + * NON-INFRINGEMENT. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Software is CID font code that was developed by Silicon + * Graphics, Inc. + */ +/* $XFree86: xc/lib/font/Type1/scanfont.c,v 1.16 2003/05/27 22:26:46 tsi Exp $ */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#ifdef BUILDCID +#define XFONT_CID 1 +#endif + +#ifndef FONTMODULE +#include <string.h> +#include <limits.h> +#else +#include "Xdefs.h" /* Bool declaration */ +#include "Xmd.h" /* INT32 declaration */ +#include "xf86_ansic.h" +#endif +#include "t1stdio.h" +#include "util.h" +#include "token.h" +#if XFONT_CID +#include "range.h" +#endif +#include "objects.h" +#include "spaces.h" +#include "fontfcn.h" +#include "blues.h" + +#if XFONT_CID +#define CID_BUFSIZE 80 + +extern psfont *FDArrayP; +static spacerange *spacerangeP; +static cidrange *notdefrangeP; +static cidrange *cidrangeP; +extern int FDArrayIndex; +static boolean CIDWantFontInfo; +static psobj inputFile1; +#endif + +static int rc; +static boolean InPrivateDict; +static boolean WantFontInfo; +static boolean TwoSubrs; +static psobj inputFile; +static psobj filterFile; +static psobj *inputP; + + +/**********************************************************************/ +/* Init_BuiltInEncoding() */ +/* */ +/* Initializes the StandardEncoding and ISOLatin1Encoding vector. */ +/* */ +/**********************************************************************/ +typedef struct /* Builtin Standard Encoding */ +{ + int index; + char *name; +} EncodingTable; + +static EncodingTable StdEnc[] = { + { 040 , "space" }, + { 041 , "exclam" }, + { 042 , "quotedbl" }, + { 043 , "numbersign" }, + { 044 , "dollar" }, + { 045 , "percent" }, + { 046 , "ampersand" }, + { 047 , "quoteright" }, + { 050 , "parenleft" }, + { 051 , "parenright" }, + { 052 , "asterisk" }, + { 053 , "plus" }, + { 054 , "comma" }, + { 055 , "hyphen" }, + { 056 , "period" }, + { 057 , "slash" }, + { 060 , "zero" }, + { 061 , "one" }, + { 062 , "two" }, + { 063 , "three" }, + { 064 , "four" }, + { 065 , "five" }, + { 066 , "six" }, + { 067 , "seven" }, + { 070 , "eight" }, + { 071 , "nine" }, + { 072 , "colon" }, + { 073 , "semicolon" }, + { 074 , "less" }, + { 075 , "equal" }, + { 076 , "greater" }, + { 077 , "question" }, + { 0100 , "at" }, + { 0101 , "A" }, + { 0102 , "B" }, + { 0103 , "C" }, + { 0104 , "D" }, + { 0105 , "E" }, + { 0106 , "F" }, + { 0107 , "G" }, + { 0110 , "H" }, + { 0111 , "I" }, + { 0112 , "J" }, + { 0113 , "K" }, + { 0114 , "L" }, + { 0115 , "M" }, + { 0116 , "N" }, + { 0117 , "O" }, + { 0120 , "P" }, + { 0121 , "Q" }, + { 0122 , "R" }, + { 0123 , "S" }, + { 0124 , "T" }, + { 0125 , "U" }, + { 0126 , "V" }, + { 0127 , "W" }, + { 0130 , "X" }, + { 0131 , "Y" }, + { 0132 , "Z" }, + { 0133 , "bracketleft" }, + { 0134 , "backslash" }, + { 0135 , "bracketright" }, + { 0136 , "asciicircum" }, + { 0137 , "underscore" }, + { 0140 , "quoteleft" }, + { 0141 , "a" }, + { 0142 , "b" }, + { 0143 , "c" }, + { 0144 , "d" }, + { 0145 , "e" }, + { 0146 , "f" }, + { 0147 , "g" }, + { 0150 , "h" }, + { 0151 , "i" }, + { 0152 , "j" }, + { 0153 , "k" }, + { 0154 , "l" }, + { 0155 , "m" }, + { 0156 , "n" }, + { 0157 , "o" }, + { 0160 , "p" }, + { 0161 , "q" }, + { 0162 , "r" }, + { 0163 , "s" }, + { 0164 , "t" }, + { 0165 , "u" }, + { 0166 , "v" }, + { 0167 , "w" }, + { 0170 , "x" }, + { 0171 , "y" }, + { 0172 , "z" }, + { 0173 , "braceleft" }, + { 0174 , "bar" }, + { 0175 , "braceright" }, + { 0176 , "asciitilde" }, + { 0241 , "exclamdown" }, + { 0242 , "cent" }, + { 0243 , "sterling" }, + { 0244 , "fraction" }, + { 0245 , "yen" }, + { 0246 , "florin" }, + { 0247 , "section" }, + { 0250 , "currency" }, + { 0251 , "quotesingle" }, + { 0252 , "quotedblleft" }, + { 0253 , "guillemotleft" }, + { 0254 , "guilsinglleft" }, + { 0255 , "guilsinglright" }, + { 0256 , "fi" }, + { 0257 , "fl" }, + { 0261 , "endash" }, + { 0262 , "dagger" }, + { 0263 , "daggerdbl" }, + { 0264 , "periodcentered" }, + { 0266 , "paragraph" }, + { 0267 , "bullet" }, + { 0270 , "quotesinglbase" }, + { 0271 , "quotedblbase" }, + { 0272 , "quotedblright" }, + { 0273 , "guillemotright" }, + { 0274 , "ellipsis" }, + { 0275 , "perthousand" }, + { 0277 , "questiondown" }, + { 0301 , "grave" }, + { 0302 , "acute" }, + { 0303 , "circumflex" }, + { 0304 , "tilde" }, + { 0305 , "macron" }, + { 0306 , "breve" }, + { 0307 , "dotaccent" }, + { 0310 , "dieresis" }, + { 0312 , "ring" }, + { 0313 , "cedilla" }, + { 0315 , "hungarumlaut" }, + { 0316 , "ogonek" }, + { 0317 , "caron" }, + { 0320 , "emdash" }, + { 0341 , "AE" }, + { 0343 , "ordfeminine" }, + { 0350 , "Lslash" }, + { 0351 , "Oslash" }, + { 0352 , "OE" }, + { 0353 , "ordmasculine" }, + { 0361 , "ae" }, + { 0365 , "dotlessi" }, + { 0370 , "lslash" }, + { 0371 , "oslash" }, + { 0372 , "oe" }, + { 0373 , "germandbls" }, + { 0, 0 } +}; + +static EncodingTable ISO8859Enc[] = { + { 32, "space" }, + { 33, "exclam" }, + { 34, "quotedbl" }, + { 35, "numbersign" }, + { 36, "dollar" }, + { 37, "percent" }, + { 38, "ampersand" }, + { 39, "quoteright" }, + { 40, "parenleft" }, + { 41, "parenright" }, + { 42, "asterisk" }, + { 43, "plus" }, + { 44, "comma" }, + { 45, "minus" }, + { 46, "period" }, + { 47, "slash" }, + { 48, "zero" }, + { 49, "one" }, + { 50, "two" }, + { 51, "three" }, + { 52, "four" }, + { 53, "five" }, + { 54, "six" }, + { 55, "seven" }, + { 56, "eight" }, + { 57, "nine" }, + { 58, "colon" }, + { 59, "semicolon" }, + { 60, "less" }, + { 61, "equal" }, + { 62, "greater" }, + { 63, "question" }, + { 64, "at" }, + { 65, "A" }, + { 66, "B" }, + { 67, "C" }, + { 68, "D" }, + { 69, "E" }, + { 70, "F" }, + { 71, "G" }, + { 72, "H" }, + { 73, "I" }, + { 74, "J" }, + { 75, "K" }, + { 76, "L" }, + { 77, "M" }, + { 78, "N" }, + { 79, "O" }, + { 80, "P" }, + { 81, "Q" }, + { 82, "R" }, + { 83, "S" }, + { 84, "T" }, + { 85, "U" }, + { 86, "V" }, + { 87, "W" }, + { 88, "X" }, + { 89, "Y" }, + { 90, "Z" }, + { 91, "bracketleft" }, + { 92, "backslash" }, + { 93, "bracketright" }, + { 94, "asciicircum" }, + { 95, "underscore" }, + { 96, "quoteleft" }, + { 97, "a" }, + { 98, "b" }, + { 99, "c" }, + { 100, "d" }, + { 101, "e" }, + { 102, "f" }, + { 103, "g" }, + { 104, "h" }, + { 105, "i" }, + { 106, "j" }, + { 107, "k" }, + { 108, "l" }, + { 109, "m" }, + { 110, "n" }, + { 111, "o" }, + { 112, "p" }, + { 113, "q" }, + { 114, "r" }, + { 115, "s" }, + { 116, "t" }, + { 117, "u" }, + { 118, "v" }, + { 119, "w" }, + { 120, "x" }, + { 121, "y" }, + { 122, "z" }, + { 123, "braceleft" }, + { 124, "bar" }, + { 125, "braceright" }, + { 126, "asciitilde" }, + { 160, "space" }, + { 161, "exclamdown" }, + { 162, "cent" }, + { 163, "sterling" }, + { 164, "currency" }, + { 165, "yen" }, + { 166, "brokenbar" }, + { 167, "section" }, + { 168, "dieresis" }, + { 169, "copyright" }, + { 170, "ordfeminine" }, + { 171, "guillemotleft" }, + { 172, "logicalnot" }, + { 173, "hyphen" }, + { 174, "registered" }, + { 175, "macron" }, + { 176, "degree" }, + { 177, "plusminus" }, + { 178, "twosuperior" }, + { 179, "threesuperior" }, + { 180, "acute" }, + { 181, "mu" }, + { 182, "paragraph" }, + { 183, "periodcentered" }, + { 184, "cedilla" }, + { 185, "onesuperior" }, + { 186, "ordmasculine" }, + { 187, "guillemotright" }, + { 188, "onequarter" }, + { 189, "onehalf" }, + { 190, "threequarters" }, + { 191, "questiondown" }, + { 192, "Agrave" }, + { 193, "Aacute" }, + { 194, "Acircumflex" }, + { 195, "Atilde" }, + { 196, "Adieresis" }, + { 197, "Aring" }, + { 198, "AE" }, + { 199, "Ccedilla" }, + { 200, "Egrave" }, + { 201, "Eacute" }, + { 202, "Ecircumflex" }, + { 203, "Edieresis" }, + { 204, "Igrave" }, + { 205, "Iacute" }, + { 206, "Icircumflex" }, + { 207, "Idieresis" }, + { 208, "Eth" }, + { 209, "Ntilde" }, + { 210, "Ograve" }, + { 211, "Oacute" }, + { 212, "Ocircumflex" }, + { 213, "Otilde" }, + { 214, "Odieresis" }, + { 215, "multiply" }, + { 216, "Oslash" }, + { 217, "Ugrave" }, + { 218, "Uacute" }, + { 219, "Ucircumflex" }, + { 220, "Udieresis" }, + { 221, "Yacute" }, + { 222, "Thorn" }, + { 223, "germandbls" }, + { 224, "agrave" }, + { 225, "aacute" }, + { 226, "acircumflex" }, + { 227, "atilde" }, + { 228, "adieresis" }, + { 229, "aring" }, + { 230, "ae" }, + { 231, "ccedilla" }, + { 232, "egrave" }, + { 233, "eacute" }, + { 234, "ecircumflex" }, + { 235, "edieresis" }, + { 236, "igrave" }, + { 237, "iacute" }, + { 238, "icircumflex" }, + { 239, "idieresis" }, + { 240, "eth" }, + { 241, "ntilde" }, + { 242, "ograve" }, + { 243, "oacute" }, + { 244, "ocircumflex" }, + { 245, "otilde" }, + { 246, "odieresis" }, + { 247, "divide" }, + { 248, "oslash" }, + { 249, "ugrave" }, + { 250, "uacute" }, + { 251, "ucircumflex" }, + { 252, "udieresis" }, + { 253, "yacute" }, + { 254, "thorn" }, + { 255, "ydieresis" }, + { 0, 0 } +}; + +static psobj *StdEncArrayP = NULL; +psobj *ISOLatin1EncArrayP = NULL; + +static psobj * +MakeEncodingArrayP(EncodingTable *encodingTable) +{ + int i; + psobj *encodingArrayP; + + encodingArrayP = (psobj *)vm_alloc(256*(sizeof(psobj))); + if (!encodingArrayP) + return NULL; + + /* initialize everything to .notdef */ + for (i=0; i<256;i++) + objFormatName(&(encodingArrayP[i]),7, ".notdef"); + + for (i=0; encodingTable[i].name; i++) + { + objFormatName(&(encodingArrayP[encodingTable[i].index]), + strlen(encodingTable[i].name), + encodingTable[i].name); + } + + return(encodingArrayP); +} + +boolean +Init_BuiltInEncoding(void) +{ + StdEncArrayP = MakeEncodingArrayP(StdEnc); + ISOLatin1EncArrayP = MakeEncodingArrayP(ISO8859Enc); + return (StdEncArrayP && ISOLatin1EncArrayP); +} + +/********************************************************************/ +/***================================================================***/ +static int +getNextValue(int valueType) +{ + scan_token(inputP); + if (tokenType != valueType) { + return(SCAN_ERROR); + } + return(SCAN_OK); + +} +/***================================================================***/ +/* This routine will set the global rc if there is an error */ +/***================================================================***/ +static int +getInt(void) +{ + scan_token(inputP); + if (tokenType != TOKEN_INTEGER) { + rc = SCAN_ERROR; + return(0); + } + else { + return( tokenValue.integer); + } + +} +/***================================================================***/ +/* + * See Sec 10.3 of ``Adobe Type 1 Font Format'' v1.1, + * for parsing Encoding. + */ +static int +getEncoding(psobj *arrayP) +{ + scan_token(inputP); + if ((tokenType == TOKEN_NAME && (tokenLength==16 || tokenLength==17))) + { + if((tokenLength==16) && (!strncmp(tokenStartP,"StandardEncoding",16))) + arrayP->data.valueP = (char *) StdEncArrayP; + else + arrayP->data.valueP = (char *) ISOLatin1EncArrayP; + arrayP->len = 256; + return(SCAN_OK); + } + else if ( (tokenType == TOKEN_LEFT_BRACE) || + (tokenType == TOKEN_LEFT_BRACKET) ) + { + /* Array of literal names */ + + psobj *objP; + int i; + + objP = (psobj *)vm_alloc(256*(sizeof(psobj))); + if (!(objP)) return(SCAN_OUT_OF_MEMORY); + + arrayP->data.valueP = (char *) objP; + arrayP->len = 256; + + for (i=0; i<256; i++, objP++) + { + scan_token(inputP); + + if (tokenType != TOKEN_LITERAL_NAME) + return(SCAN_ERROR); + + if (!(vm_alloc(tokenLength)) ) return(SCAN_OUT_OF_MEMORY); + objFormatName(objP,tokenLength,tokenStartP); + } + + scan_token(inputP); + if ( (tokenType == TOKEN_RIGHT_BRACE) || + (tokenType == TOKEN_RIGHT_BRACKET) ) + return(SCAN_OK); + } + else + { + /* Must be sequences of ``dup <index> <charactername> put" */ + + psobj *objP; + int i; + + objP = (psobj *)vm_alloc(256*(sizeof(psobj))); + if (!(objP)) return(SCAN_OUT_OF_MEMORY); + + arrayP->data.valueP = (char *) objP; + arrayP->len = 256; + + for (i=0; i<256; i++) + objFormatName(objP + i, 7, ".notdef"); + + while (TRUE) + { + scan_token(inputP); + + switch (tokenType) + { + case TOKEN_NAME: + if (tokenLength == 3) + { + if (strncmp(tokenStartP,"dup",3) == 0) + { + /* get <index> */ + scan_token(inputP); + if (tokenType != TOKEN_INTEGER || + tokenValue.integer < 0 || + tokenValue.integer > 255) + return (SCAN_ERROR); + i = tokenValue.integer; + + /* get <characer_name> */ + scan_token(inputP); + if (tokenType != TOKEN_LITERAL_NAME) + return(SCAN_ERROR); + + if (!(vm_alloc(tokenLength)) ) + return(SCAN_OUT_OF_MEMORY); + objFormatName(objP + i,tokenLength,tokenStartP); + + /* get "put" */ + scan_token(inputP); + if (tokenType != TOKEN_NAME) + return(SCAN_ERROR); + } + else if (strncmp(tokenStartP,"def",3) == 0) + return (SCAN_OK); + } + break; + case TOKEN_EOF: + case TOKEN_NONE: + case TOKEN_INVALID: + return (SCAN_ERROR); + } + } + } + + return (SCAN_ERROR); +} +/***================================================================***/ +#if XFONT_CID +static int +getFDArray(psobj *arrayP) +{ + int rc; + + /* get the number of items in the FDArray */ + scan_token(inputP); + if (tokenType == TOKEN_INTEGER) { + /* an FD array must contain at least one element */ + if (tokenValue.integer <= 0) + return(SCAN_ERROR); + arrayP->len = tokenValue.integer; + } else + return(SCAN_ERROR); + + /* get the token "array" */ + scan_token(inputP); + if (tokenType != TOKEN_NAME || strncmp(tokenStartP, "array", 5) != 0) + return(SCAN_ERROR); + + /* format the array in memory, save pointer to the beginning */ + arrayP->data.valueP = tokenStartP; + + /* allocate FDArray */ + /* No integer overflow since arrayP->len is unsigned short */ + FDArrayP = (psfont *)vm_alloc(arrayP->len*(sizeof(psfont))); + if (!(FDArrayP)) return(SCAN_OUT_OF_MEMORY); + + /* get a specified number of font dictionaries */ + for (FDArrayIndex = 0; FDArrayIndex < arrayP->len; FDArrayIndex++) { + /* get "dup" */ + scan_token(inputP); + if (tokenType != TOKEN_NAME || strncmp(tokenStartP, "dup", 3) != 0) + return(SCAN_ERROR); + /* get an integer digit */ + scan_token(inputP); + if (tokenType != TOKEN_INTEGER) + return(SCAN_ERROR); + + /* read a CID version of a Type 1 font */ + if (!CIDType1fontfcnA(&rc)) + return(rc); + + /* get "put" */ + scan_token(inputP); + if (tokenType != TOKEN_NAME || strncmp(tokenStartP, "put", 3) != 0) + return(SCAN_ERROR); + } + return(SCAN_OK); +} +#endif + +static int +getArray(psobj *arrayP) +{ + int N; /* count the items in the array */ + psobj *objP; + + /* That is totally a kludge. If some stupid font file has + * /foo/foo # ftp://ftp.cdrom.com/pub/os2/fonts/future.zip + * we will treat it as /foo. + * H.J. */ + char tmp [1024]; + + strncpy (tmp, tokenStartP, sizeof (tmp)); + tmp [sizeof (tmp) - 1] = '\0'; + +restart: + scan_token(inputP); + switch (tokenType) + { + case TOKEN_LEFT_BRACE: + case TOKEN_LEFT_BRACKET: + break; + + case TOKEN_LITERAL_NAME: + tokenStartP[tokenLength] = '\0'; + if (strcmp (tokenStartP, tmp) == 0) + { + /* Ok, We see /foo/foo. Let's restart. */ + goto restart; + } + + default: + return(SCAN_ERROR); + } + /* format the array in memory, save pointer to the beginning */ + arrayP->data.valueP = tokenStartP; + /* loop, picking up next object, until right BRACE or BRACKET */ + N = 0; + do { + scan_token(inputP); + if ( (tokenType == TOKEN_RIGHT_BRACE) || + (tokenType == TOKEN_RIGHT_BRACKET) ) { + /* save then number of items in the array */ + arrayP->len = N; + return(SCAN_OK); + } + /* allocate the space for the object */ + objP = (psobj *)vm_alloc(sizeof(psobj)); + if (!(objP)) return(SCAN_OUT_OF_MEMORY); + + /* array is an array of numbers, (real or integer) */ + if (tokenType == TOKEN_REAL) { + objFormatReal(objP, tokenValue.real); + } + else + if (tokenType == TOKEN_INTEGER) { + objFormatInteger(objP, tokenValue.integer); + } + else return(SCAN_ERROR); + N++; + } while ( 1>0 ); + /* NOTREACHED*/ +} +/***================================================================***/ +static int +getName(char *nameP) +{ + do { + scan_token(inputP); + if (tokenType <= TOKEN_NONE) { + if (tokenTooLong) return(SCAN_OUT_OF_MEMORY); + return(SCAN_ERROR); + } + } while ((tokenType != TOKEN_NAME) || + (0 != strncmp(tokenStartP,nameP,strlen(nameP))) ); + /* found */ + return(SCAN_OK); +} +/***================================================================***/ +static int +getNbytes(int N) +{ + int I; + + + tokenStartP = vm_next_byte(); + tokenMaxP = tokenStartP + MIN(vm_free_bytes(), MAX_STRING_LEN); + if (N > vm_free_bytes()) { + return(SCAN_OUT_OF_MEMORY); + } + I = T1Read(tokenStartP,1,N,inputP->data.fileP); + if ( I != N ) return(SCAN_FILE_EOF); + return(SCAN_OK); +} + +/***================================================================***/ +/* getLiteralName(nameObjP) */ +/* scan for next literal. */ +/* if we encounter the name 'end' then terminate and say ok. */ +/* It means that the CharStrings does not have as many characters */ +/* as the dictionary said it would and that is ok. */ +/***================================================================***/ +static int +getLiteralName(psobj *nameObjP) +{ + do { + scan_token(inputP); + if (tokenType <= TOKEN_NONE) { + if (tokenTooLong) return(SCAN_OUT_OF_MEMORY); + return(SCAN_ERROR); + } + if (tokenType == TOKEN_NAME) { + if (0 == strncmp(tokenStartP,"end",3) ) { + return(SCAN_END); + } + } + } while (tokenType != TOKEN_LITERAL_NAME) ; + nameObjP->len = tokenLength; + /* allocate all the names in the CharStrings Structure */ + if (!(vm_alloc(tokenLength)) ) return(SCAN_OUT_OF_MEMORY); + nameObjP->data.valueP = tokenStartP; + /* found */ + return(SCAN_OK); +} + +/***================================================================***/ +/* + * BuildSubrs routine + */ +/***================================================================***/ + +static int +BuildSubrs(psfont *FontP) +{ + int N; /* number of values in Subrs */ + int I; /* index into Subrs */ + int i; /* loop thru Subrs */ + int J; /* length of Subrs entry */ + psobj *arrayP; + + /* next token should be a positive int */ + /* note: rc is set by getInt. */ + N = getInt(); + if (rc) return(rc); + if (N < 0 ) return(SCAN_ERROR); + /* if we already have a Subrs, then skip the second one */ + /* The second one is for hiresolution devices. */ + if (FontP->Subrs.data.arrayP != NULL) { + TwoSubrs = TRUE; + /* process all the Subrs, but do not update anything */ + /* can not just skip them because of the binary data */ + for (i=0;i<N;i++) { + /* look for dup */ + rc = getName("dup"); + if (rc) return(rc); + /* get 2 integers */ + I = getInt(); + if (rc) return(rc); + J = getInt(); + if (rc) return(rc); + if ( (I < 0) || (J < 0 ) ) return (SCAN_ERROR); + /* get the next token, it should be RD or -|, either is ok */ + rc = getNextValue(TOKEN_NAME); + if ( rc != SCAN_OK ) return(rc); + rc = getNbytes(J); + if (rc) return(rc); + } + return(SCAN_OK); + } + if (N > INT_MAX / sizeof(psobj)) + return (SCAN_ERROR); + arrayP = (psobj *)vm_alloc(N*sizeof(psobj)); + if (!(arrayP) ) return(SCAN_OUT_OF_MEMORY); + FontP->Subrs.len = N; + FontP->Subrs.data.arrayP = arrayP; + /* get N values for Subrs */ + for (i=0;i<N;i++) { + /* look for dup */ + rc = getName("dup"); + if (rc) return(rc); + /* get 2 integers */ + I = getInt(); + if (rc) return(rc); + J = getInt(); + if (rc) return(rc); + if ( (I < 0) || (J < 0 ) ) return (SCAN_ERROR); + arrayP[I].len = J; + /* get the next token, it should be RD or -|, either is ok */ + rc = getNextValue(TOKEN_NAME); + if ( rc != SCAN_OK ) return(rc); + rc = getNbytes(J); + if (rc == SCAN_OK) { + arrayP[I].data.valueP = tokenStartP; + if ( !(vm_alloc(J)) ) return(SCAN_OUT_OF_MEMORY); + } + else return(rc); + } + return(SCAN_OK); + +} +/***================================================================***/ +/***================================================================***/ +/* + * BuildCharStrings routine + */ +/***================================================================***/ + +static int +BuildCharStrings(psfont *FontP) +{ + int N; /* number of values in CharStrings */ + int i; /* loop thru Subrs */ + int J; /* length of Subrs entry */ + psdict *dictP; + + /* next token should be a positive int */ + N = getInt(); + if (rc) { + /* check if file had TwoSubrs, hi resolution stuff is in file*/ + if (TwoSubrs) { + do { + scan_token(inputP); + if (tokenType <= TOKEN_NONE) { + if (tokenTooLong) return(SCAN_OUT_OF_MEMORY); + return(SCAN_ERROR); + } + } while (tokenType != TOKEN_INTEGER); + N = tokenValue.integer; + } + else return(rc); /* if next token was not an Int */ + } + if (N<=0 || N > INT_MAX / sizeof(psdict)) return(SCAN_ERROR); + /* save number of entries in the dictionary */ + + dictP = (psdict *)vm_alloc((N+1)*sizeof(psdict)); + if (!(dictP)) return(SCAN_OUT_OF_MEMORY); + FontP->CharStringsP = dictP; + dictP[0].key.len = N; + /* get N values for CharStrings */ + for (i=1;i<=N;i++) { + /* look for next literal name */ + rc = getLiteralName(&(dictP[i].key)); + if (rc) return(rc); + /* get 1 integer */ + J = getInt(); + if (rc) return(rc); /* if next token was not an Int */ + if (J<0) return (SCAN_ERROR); + dictP[i].value.len = J; + /* get the next token, it should be RD or -|, either is ok */ + rc = getNextValue(TOKEN_NAME); + if ( rc != SCAN_OK ) return(rc); + rc = getNbytes(J); + if (rc == SCAN_OK) { + dictP[i].value.data.valueP = tokenStartP; + if ( !(vm_alloc(J)) ) return(SCAN_OUT_OF_MEMORY); + } + else return(rc); + } + return(SCAN_OK); + +} +/***================================================================***/ +#if XFONT_CID +/***================================================================***/ +/* + * BuildCIDFontInfo Dictionary + */ +/***================================================================***/ +static int +BuildCIDFontInfo(cidfont *CIDfontP) +{ + psdict *dictP; + + /* allocate the private dictionary (max number of entries + 1) */ + dictP = (psdict *)vm_alloc(20*sizeof(psdict)); + if (!(dictP)) return(SCAN_OUT_OF_MEMORY); + + CIDfontP->CIDfontInfoP = dictP; + CIDfontP->CIDfontInfoP[0].key.len = 18; /* number of actual entries */ + objFormatName(&(dictP[CIDCOUNT].key),8,"CIDCount"); + objFormatInteger(&(dictP[CIDCOUNT].value),-1); + objFormatName(&(dictP[CIDFONTNAME].key),11,"CIDFontName"); + objFormatName(&(dictP[CIDFONTNAME].value),0,NULL); + objFormatName(&(dictP[CIDFONTTYPE].key),11,"CIDFontType"); + objFormatInteger(&(dictP[CIDFONTTYPE].value),-1); + objFormatName(&(dictP[CIDVERSION].key),14,"CIDFontVersion"); + objFormatInteger(&(dictP[CIDVERSION].value),-1); + objFormatName(&(dictP[CIDREGISTRY].key),8,"Registry"); + objFormatString(&(dictP[CIDREGISTRY].value),0,NULL); + objFormatName(&(dictP[CIDORDERING].key),8,"Ordering"); + objFormatString(&(dictP[CIDORDERING].value),0,NULL); + objFormatName(&(dictP[CIDSUPPLEMENT].key),10,"Supplement"); + objFormatInteger(&(dictP[CIDSUPPLEMENT].value),-1); + objFormatName(&(dictP[CIDMAPOFFSET].key),12,"CIDMapOffset"); + objFormatInteger(&(dictP[CIDMAPOFFSET].value),-1); + objFormatName(&(dictP[CIDFDARRAY].key),7,"FDArray"); + objFormatArray(&(dictP[CIDFDARRAY].value),0,NULL); + objFormatName(&(dictP[CIDFDBYTES].key),7,"FDBytes"); + objFormatInteger(&(dictP[CIDFDBYTES].value),-1); + objFormatName(&(dictP[CIDFONTBBOX].key),8,"FontBBox"); + objFormatArray(&(dictP[CIDFONTBBOX].value),0,NULL); + objFormatName(&(dictP[CIDFULLNAME].key),8,"FullName"); + objFormatString(&(dictP[CIDFULLNAME].value),0,NULL); + objFormatName(&(dictP[CIDFAMILYNAME].key),10,"FamilyName"); + objFormatString(&(dictP[CIDFAMILYNAME].value),0,NULL); + objFormatName(&(dictP[CIDWEIGHT].key),6,"Weight"); + objFormatString(&(dictP[CIDWEIGHT].value),0,NULL); + objFormatName(&(dictP[CIDNOTICE].key),6,"Notice"); + objFormatString(&(dictP[CIDNOTICE].value),0,NULL); + objFormatName(&(dictP[CIDGDBYTES].key),7,"GDBytes"); + objFormatInteger(&(dictP[CIDGDBYTES].value),-1); + objFormatName(&(dictP[CIDUIDBASE].key),7,"UIDBase"); + objFormatInteger(&(dictP[CIDUIDBASE].value),0); + objFormatName(&(dictP[CIDXUID].key),4,"XUID"); + objFormatInteger(&(dictP[CIDXUID].value),0); + return(SCAN_OK); +} +/***================================================================***/ +/* + * BuildCMapInfo Dictionary + */ +/***================================================================***/ +static int +BuildCMapInfo(cmapres *CMapP) +{ + psdict *dictP; + + /* allocate the private dictionary (max number of entries + 1) */ + dictP = (psdict *)vm_alloc(20*sizeof(psdict)); + if (!(dictP)) return(SCAN_OUT_OF_MEMORY); + + CMapP->CMapInfoP = dictP; + CMapP->CMapInfoP[0].key.len = 8; /* number of actual entries */ + objFormatName(&(dictP[CMAPREGISTRY].key),8,"Registry"); + objFormatString(&(dictP[CMAPREGISTRY].value),0,NULL); + objFormatName(&(dictP[CMAPORDERING].key),8,"Ordering"); + objFormatString(&(dictP[CMAPORDERING].value),0,NULL); + objFormatName(&(dictP[CMAPSUPPLEMENT].key),10,"Supplement"); + objFormatInteger(&(dictP[CMAPSUPPLEMENT].value),-1); + objFormatName(&(dictP[CMAPNAME].key),8,"CMapName"); + objFormatString(&(dictP[CMAPNAME].value),0,NULL); + objFormatName(&(dictP[CMAPVERSION].key),11,"CMapVersion"); + objFormatInteger(&(dictP[CMAPVERSION].value),-1); + objFormatName(&(dictP[CMAPTYPE].key),8,"CMapType"); + objFormatInteger(&(dictP[CMAPTYPE].value),-1); + objFormatName(&(dictP[CMAPWMODE].key),5,"WMode"); + objFormatInteger(&(dictP[CMAPWMODE].value),-1); + objFormatName(&(dictP[CMAPCIDCOUNT].key),8,"CIDCount"); + objFormatInteger(&(dictP[CMAPCIDCOUNT].value),-1); + return(SCAN_OK); +} +#endif + +/***================================================================***/ +/* + * BuildFontInfo Dictionary + */ +/***================================================================***/ +static int +BuildFontInfo(psfont *fontP) +{ + psdict *dictP; + + /* allocate the private dictionary */ + dictP = (psdict *)vm_alloc(20*sizeof(psdict)); + if (!(dictP)) return(SCAN_OUT_OF_MEMORY); + + fontP->fontInfoP = dictP; + fontP->fontInfoP[0].key.len = 17; /* number of actual entries */ + objFormatName(&(dictP[FONTNAME].key),8,"FontName"); + objFormatName(&(dictP[FONTNAME].value),0,NULL); + objFormatName(&(dictP[PAINTTYPE].key),9,"PaintType"); + objFormatInteger(&(dictP[PAINTTYPE].value),0); + objFormatName(&(dictP[FONTTYPENUM].key),8,"FontType"); + objFormatInteger(&(dictP[FONTTYPENUM].value),0); + objFormatName(&(dictP[FONTMATRIX].key),10,"FontMatrix"); + objFormatArray(&(dictP[FONTMATRIX].value),0,NULL); + objFormatName(&(dictP[FONTBBOX].key),8,"FontBBox"); + objFormatArray(&(dictP[FONTBBOX].value),0,NULL); + objFormatName(&(dictP[ENCODING].key),8,"Encoding"); + objFormatEncoding(&(dictP[ENCODING].value),0,NULL); + objFormatName(&(dictP[UNIQUEID].key),8,"UniqueID"); + objFormatInteger(&(dictP[UNIQUEID].value),0); + objFormatName(&(dictP[STROKEWIDTH].key),11,"StrokeWidth"); + objFormatReal(&(dictP[STROKEWIDTH].value),0.0); + objFormatName(&(dictP[VERSION].key),7,"version"); + objFormatString(&(dictP[VERSION].value),0,NULL); + objFormatName(&(dictP[NOTICE].key),6,"Notice"); + objFormatString(&(dictP[NOTICE].value),0,NULL); + objFormatName(&(dictP[FULLNAME].key),8,"FullName"); + objFormatString(&(dictP[FULLNAME].value),0,NULL); + objFormatName(&(dictP[FAMILYNAME].key),10,"FamilyName"); + objFormatString(&(dictP[FAMILYNAME].value),0,NULL); + objFormatName(&(dictP[WEIGHT].key),6,"Weight"); + objFormatString(&(dictP[WEIGHT].value),0,NULL); + objFormatName(&(dictP[ITALICANGLE].key),11,"ItalicAngle"); + objFormatReal(&(dictP[ITALICANGLE].value),0.0); + objFormatName(&(dictP[ISFIXEDPITCH].key),12,"isFixedPitch"); + objFormatBoolean(&(dictP[ISFIXEDPITCH].value),FALSE); + objFormatName(&(dictP[UNDERLINEPOSITION].key),17,"UnderlinePosition"); + objFormatReal(&(dictP[UNDERLINEPOSITION].value),0.0); + objFormatName(&(dictP[UNDERLINETHICKNESS].key),18,"UnderlineThickness"); + objFormatReal(&(dictP[UNDERLINETHICKNESS].value),0.0); + return(SCAN_OK); +} +#if XFONT_CID +/***================================================================***/ +/* + * BuildCIDType1Private Dictionary + */ +/***================================================================***/ +static int +BuildCIDType1Private(psfont *fontP) +{ + psdict *Private; + + /* allocate the private dictionary */ + Private = (psdict *)vm_alloc(21*sizeof(psdict)); + + if (!(Private)) return(SCAN_OUT_OF_MEMORY); + + fontP->Private = Private; + fontP->Private[0].key.len = 20; /* number of actual entries */ + + objFormatName(&(Private[CIDT1MINFEATURE].key),10,"MinFeature"); + objFormatArray(&(Private[CIDT1MINFEATURE].value),0,NULL); + objFormatName(&(Private[CIDT1LENIV].key),5,"lenIV"); + objFormatInteger(&(Private[CIDT1LENIV].value),DEFAULTLENIV); + objFormatName(&(Private[CIDT1LANGGROUP].key),13,"LanguageGroup"); + objFormatInteger(&(Private[CIDT1LANGGROUP].value),DEFAULTLANGUAGEGROUP); + objFormatName(&(Private[CIDT1BLUEVALUES].key),10,"BlueValues"); + objFormatArray(&(Private[CIDT1BLUEVALUES].value),0,NULL); + objFormatName(&(Private[CIDT1OTHERBLUES].key),10,"OtherBlues"); + objFormatArray(&(Private[CIDT1OTHERBLUES].value),0,NULL); + objFormatName(&(Private[CIDT1BLUESCALE].key),9,"BlueScale"); + objFormatReal(&(Private[CIDT1BLUESCALE].value),DEFAULTBLUESCALE); + objFormatName(&(Private[CIDT1BLUEFUZZ].key),8,"BlueFuzz"); + objFormatInteger(&(Private[CIDT1BLUEFUZZ].value),DEFAULTBLUEFUZZ); + objFormatName(&(Private[CIDT1BLUESHIFT].key),9,"BlueShift"); + objFormatInteger(&(Private[CIDT1BLUESHIFT].value),DEFAULTBLUESHIFT); + objFormatName(&(Private[CIDT1FAMBLUES].key),11,"FamilyBlues"); + objFormatArray(&(Private[CIDT1FAMBLUES].value),0,NULL); + objFormatName(&(Private[CIDT1FAMOTHERBLUES].key),16,"FamilyOtherBlues"); + objFormatArray(&(Private[CIDT1FAMOTHERBLUES].value),0,NULL); + objFormatName(&(Private[CIDT1STDHW].key),5,"StdHW"); + objFormatArray(&(Private[CIDT1STDHW].value),0,NULL); + objFormatName(&(Private[CIDT1STDVW].key),5,"StdVW"); + objFormatArray(&(Private[CIDT1STDVW].value),0,NULL); + objFormatName(&(Private[CIDT1STEMSNAPH].key),9,"StemSnapH"); + objFormatArray(&(Private[CIDT1STEMSNAPH].value),0,NULL); + objFormatName(&(Private[CIDT1STEMSNAPV].key),9,"StemSnapV"); + objFormatArray(&(Private[CIDT1STEMSNAPV].value),0,NULL); + /* skip password */ + objFormatName(&(Private[CIDT1SUBMAPOFF].key),13,"SubrMapOffset"); + objFormatInteger(&(Private[CIDT1SUBMAPOFF].value),0); + objFormatName(&(Private[CIDT1SDBYTES].key),7,"SDBytes"); + objFormatInteger(&(Private[CIDT1SDBYTES].value),0); + objFormatName(&(Private[CIDT1SUBRCNT].key),9,"SubrCount"); + objFormatInteger(&(Private[CIDT1SUBRCNT].value),0); + objFormatName(&(Private[CIDT1FORCEBOLD].key),9,"ForceBold"); + objFormatBoolean(&(Private[CIDT1FORCEBOLD].value),DEFAULTFORCEBOLD); + objFormatName(&(Private[CIDT1RNDSTEMUP].key),9,"RndStemUp"); + objFormatBoolean(&(Private[CIDT1RNDSTEMUP].value),DEFAULTRNDSTEMUP); + objFormatName(&(Private[CIDT1EXPFACTOR].key),15,"ExpansionFactor"); + objFormatReal(&(Private[CIDT1EXPFACTOR].value), + DEFAULTEXPANSIONFACTOR); + return(SCAN_OK); +} +#endif +/***================================================================***/ +/* + * BuildPrivate Dictionary + */ +/***================================================================***/ +static int +BuildPrivate(psfont *fontP) +{ + psdict *Private; + + /* allocate the private dictionary */ + Private = (psdict *)vm_alloc(20*sizeof(psdict)); + + if (!(Private)) return(SCAN_OUT_OF_MEMORY); + + fontP->Private = Private; + fontP->Private[0].key.len = 16; /* number of actual entries */ + + objFormatName(&(Private[BLUEVALUES].key),10,"BlueValues"); + objFormatArray(&(Private[BLUEVALUES].value),0,NULL); + objFormatName(&(Private[OTHERBLUES].key),10,"OtherBlues"); + objFormatArray(&(Private[OTHERBLUES].value),0,NULL); + objFormatName(&(Private[FAMILYBLUES].key),11,"FamilyBlues"); + objFormatArray(&(Private[FAMILYBLUES].value),0,NULL); + objFormatName(&(Private[FAMILYOTHERBLUES].key),16,"FamilyOtherBlues"); + objFormatArray(&(Private[FAMILYOTHERBLUES].value),0,NULL); + objFormatName(&(Private[BLUESCALE].key),9,"BlueScale"); + objFormatReal(&(Private[BLUESCALE].value),DEFAULTBLUESCALE); + objFormatName(&(Private[BLUESHIFT].key),9,"BlueShift"); + objFormatInteger(&(Private[BLUESHIFT].value),DEFAULTBLUESHIFT); + objFormatName(&(Private[BLUEFUZZ].key),8,"BlueFuzz"); + objFormatInteger(&(Private[BLUEFUZZ].value),DEFAULTBLUEFUZZ); + objFormatName(&(Private[STDHW].key),5,"StdHW"); + objFormatArray(&(Private[STDHW].value),0,NULL); + objFormatName(&(Private[STDVW].key),5,"StdVW"); + objFormatArray(&(Private[STDVW].value),0,NULL); + objFormatName(&(Private[STEMSNAPH].key),9,"StemSnapH"); + objFormatArray(&(Private[STEMSNAPH].value),0,NULL); + objFormatName(&(Private[STEMSNAPV].key),9,"StemSnapV"); + objFormatArray(&(Private[STEMSNAPV].value),0,NULL); + objFormatName(&(Private[FORCEBOLD].key),9,"ForceBold"); + objFormatBoolean(&(Private[FORCEBOLD].value),DEFAULTFORCEBOLD); + objFormatName(&(Private[LANGUAGEGROUP].key),13,"LanguageGroup"); + objFormatInteger(&(Private[LANGUAGEGROUP].value),DEFAULTLANGUAGEGROUP); + objFormatName(&(Private[LENIV].key),5,"lenIV"); + objFormatInteger(&(Private[LENIV].value),DEFAULTLENIV); + objFormatName(&(Private[RNDSTEMUP].key),9,"RndStemUp"); + objFormatBoolean(&(Private[RNDSTEMUP].value),DEFAULTRNDSTEMUP); + objFormatName(&(Private[EXPANSIONFACTOR].key),9,"ExpansionFactor"); + objFormatReal(&(Private[EXPANSIONFACTOR].value), + DEFAULTEXPANSIONFACTOR); + return(SCAN_OK); +} +/***================================================================***/ +/**********************************************************************/ +/* GetType1Blues(fontP) */ +/* */ +/* Routine to support font-level hints. */ +/* */ +/* Gets all the Blues information from the Private dictionary */ +/* for the font. */ +/* */ +/* */ +/**********************************************************************/ +static int +GetType1Blues(psfont *fontP) +{ + psdict *PrivateDictP; /* the Private dict relating to hints */ + struct blues_struct *blues; /* ptr for the blues struct we will allocate */ + int i; + psobj *HintEntryP; + + + + /* get the Private dictionary pointer */ + PrivateDictP = fontP->Private; + + /* allocate the memory for the blues structure */ + blues = (struct blues_struct *) vm_alloc(sizeof(struct blues_struct)); + + if (!blues) return(SCAN_OUT_OF_MEMORY); + + /* Make fontP's blues ptr point to this newly allocated structure. */ + fontP->BluesP = blues; + + /* fill in the BlueValues array */ + HintEntryP = &(PrivateDictP[BLUEVALUES].value); + /* check to see if the entry exists and if it's an array */ + if ( !objPIsArray(HintEntryP) || (HintEntryP->len == 0 )) + blues->numBlueValues = 0; + else { + /* get the number of values in the array */ + if (HintEntryP->len > NUMBLUEVALUES) { + blues->numBlueValues = NUMBLUEVALUES; + } else + blues->numBlueValues = HintEntryP->len; + for (i = 0; i<= blues->numBlueValues-1; ++i) { + if (objPIsInteger(&HintEntryP->data.arrayP[i])) + blues->BlueValues[i] = + HintEntryP->data.arrayP[i].data.integer; + else if (objPIsReal(&HintEntryP->data.arrayP[i])) + blues->BlueValues[i] = + HintEntryP->data.arrayP[i].data.real; + else + blues->BlueValues[i] = 0; + } + } + + /* fill in the OtherBlues array */ + HintEntryP = &(PrivateDictP[OTHERBLUES].value); + /* check to see if the entry exists and if it's an array */ + if ( !objPIsArray(HintEntryP) || (HintEntryP->len == 0 )) + blues->numOtherBlues = 0; + else { + /* get the number of values in the array */ + if (HintEntryP->len > NUMOTHERBLUES) { + blues->numOtherBlues = NUMOTHERBLUES; + } else + blues->numOtherBlues = HintEntryP->len; + for (i = 0; i<= blues->numOtherBlues-1; ++i) { + if (objPIsInteger(&HintEntryP->data.arrayP[i])) + blues->OtherBlues[i] = + HintEntryP->data.arrayP[i].data.integer; + else if (objPIsReal(&HintEntryP->data.arrayP[i])) + blues->OtherBlues[i] = + HintEntryP->data.arrayP[i].data.real; + else + blues->OtherBlues[i] = 0; + } + } + + /* fill in the FamilyBlues array */ + HintEntryP = &(PrivateDictP[FAMILYBLUES].value); + /* check to see if the entry exists and if it's an array */ + if ( !objPIsArray(HintEntryP) || (HintEntryP->len == 0 )) + blues->numFamilyBlues = 0; + else { + /* get the number of values in the array */ + if (HintEntryP->len > NUMFAMILYBLUES) { + blues->numFamilyBlues = NUMFAMILYBLUES; + } else + blues->numFamilyBlues = HintEntryP->len; + for (i = 0; i<= blues->numFamilyBlues-1; ++i) { + if (objPIsInteger(&HintEntryP->data.arrayP[i])) + blues->FamilyBlues[i] = + HintEntryP->data.arrayP[i].data.integer; + else if (objPIsReal(&HintEntryP->data.arrayP[i])) + blues->FamilyBlues[i] = + HintEntryP->data.arrayP[i].data.real; + else + blues->FamilyBlues[i] = 0; + } + } + + /* fill in the FamilyOtherBlues array */ + HintEntryP = &(PrivateDictP[FAMILYOTHERBLUES].value); + /* check to see if the entry exists and if it's an array */ + if ( !objPIsArray(HintEntryP) || (HintEntryP->len == 0 )) + blues->numFamilyOtherBlues = 0; + else { + /* get the number of values in the array */ + if (HintEntryP->len > NUMFAMILYOTHERBLUES) { + blues->numFamilyOtherBlues = NUMFAMILYOTHERBLUES; + } else + blues->numFamilyOtherBlues = HintEntryP->len; + for (i = 0; i<= blues->numFamilyOtherBlues-1; ++i) { + if (objPIsInteger(&HintEntryP->data.arrayP[i])) + blues->FamilyOtherBlues[i] = + HintEntryP->data.arrayP[i].data.integer; + else if (objPIsReal(&HintEntryP->data.arrayP[i])) + blues->FamilyOtherBlues[i] = + HintEntryP->data.arrayP[i].data.real; + else + blues->FamilyOtherBlues[i] = 0; + } + } + + /* fill in the StemSnapH array */ + HintEntryP = &(PrivateDictP[STEMSNAPH].value); + /* check to see if the entry exists and if it's an array */ + if ( !objPIsArray(HintEntryP) || (HintEntryP->len == 0 )) + blues->numStemSnapH = 0; + else { + /* get the number of values in the array */ + if (HintEntryP->len > NUMSTEMSNAPH) { + blues->numStemSnapH = NUMSTEMSNAPH; + } else + blues->numStemSnapH = HintEntryP->len; + for (i = 0; i<= blues->numStemSnapH-1; ++i) { + if (objPIsInteger(&HintEntryP->data.arrayP[i])) + blues->StemSnapH[i] = + HintEntryP->data.arrayP[i].data.integer; + else if (objPIsReal(&HintEntryP->data.arrayP[i])) + blues->StemSnapH[i] = + HintEntryP->data.arrayP[i].data.real; + else + blues->StemSnapH[i] = 0; + } + } + + /* fill in the StemSnapV array */ + HintEntryP = &(PrivateDictP[STEMSNAPV].value); + /* check to see if the entry exists and if it's an array */ + if ( !objPIsArray(HintEntryP) || (HintEntryP->len == 0 )) + blues->numStemSnapV = 0; + else { + /* get the number of values in the array */ + if (HintEntryP->len > NUMSTEMSNAPV) { + blues->numStemSnapV = NUMSTEMSNAPV; + } else + blues->numStemSnapV = HintEntryP->len; + for (i = 0; i<= blues->numStemSnapV-1; ++i) { + if (objPIsInteger(&HintEntryP->data.arrayP[i])) + blues->StemSnapV[i] = + HintEntryP->data.arrayP[i].data.integer; + else if (objPIsReal(&HintEntryP->data.arrayP[i])) + blues->StemSnapV[i] = + HintEntryP->data.arrayP[i].data.real; + else + blues->StemSnapV[i] = 0; + } + } + + /* fill in the StdVW array */ + HintEntryP = &(PrivateDictP[STDVW].value); + /* check to see if the entry exists and if it's an array */ + if ( !objPIsArray(HintEntryP) || (HintEntryP->len == 0 )) + /* a value of zero signifies no entry */ + blues->StdVW = 0; + else { + if (HintEntryP->len > NUMSTDVW) { + } + if (objPIsInteger(&HintEntryP->data.arrayP[0])) + blues->StdVW = HintEntryP->data.arrayP[0].data.integer; + else if (objPIsReal(&HintEntryP->data.arrayP[0])) + blues->StdVW = HintEntryP->data.arrayP[0].data.real; + else + blues->StdVW = 0; + } + + /* fill in the StdHW array */ + HintEntryP = &(PrivateDictP[STDHW].value); + /* check to see if the entry exists and if it's an array */ + if ( !objPIsArray(HintEntryP) || (HintEntryP->len == 0 )) + /* a value of zero signifies no entry */ + blues->StdHW = 0; + else { + if (HintEntryP->len > NUMSTDHW) { + } + if (objPIsInteger(&HintEntryP->data.arrayP[0])) + blues->StdHW = HintEntryP->data.arrayP[0].data.integer; + else if (objPIsReal(&HintEntryP->data.arrayP[0])) + blues->StdHW = HintEntryP->data.arrayP[0].data.real; + else + blues->StdHW = 0; + } + + + /* get the ptr to the BlueScale entry */ + HintEntryP = &(PrivateDictP[BLUESCALE].value); + /* put the BlueScale in the blues structure */ + if (objPIsInteger(HintEntryP)) /* Must be integer! */ + blues->BlueScale = HintEntryP->data.integer; + else if (objPIsReal(HintEntryP)) /* Error? */ + blues->BlueScale = HintEntryP->data.real; + else + blues->BlueScale = DEFAULTBLUESCALE; + + /* get the ptr to the BlueShift entry */ + HintEntryP = &(PrivateDictP[BLUESHIFT].value); + if (objPIsInteger(HintEntryP)) /* Must be integer! */ + blues->BlueShift = HintEntryP->data.integer; + else if (objPIsReal(HintEntryP)) /* Error? */ + blues->BlueShift = HintEntryP->data.real; + else + blues->BlueShift = DEFAULTBLUESHIFT; + + /* get the ptr to the BlueFuzz entry */ + HintEntryP = &(PrivateDictP[BLUEFUZZ].value); + if (objPIsInteger(HintEntryP)) /* Must be integer! */ + blues->BlueFuzz = HintEntryP->data.integer; + else if (objPIsReal(HintEntryP)) /* Error? */ + blues->BlueFuzz = HintEntryP->data.real; + else + blues->BlueFuzz = DEFAULTBLUEFUZZ; + + /* get the ptr to the ForceBold entry */ + HintEntryP = &(PrivateDictP[FORCEBOLD].value); + if (objPIsBoolean(HintEntryP)) /* Must be integer! */ + blues->ForceBold = HintEntryP->data.boolean; + else + blues->ForceBold = DEFAULTFORCEBOLD; + + /* get the ptr to the LanguageGroup entry */ + HintEntryP = &(PrivateDictP[LANGUAGEGROUP].value); + if (objPIsInteger(HintEntryP)) /* Must be integer! */ + blues->LanguageGroup = HintEntryP->data.integer; + else + blues->LanguageGroup = DEFAULTLANGUAGEGROUP; + + /* get the ptr to the RndStemUp entry */ + HintEntryP = &(PrivateDictP[RNDSTEMUP].value); + if (objPIsBoolean(HintEntryP)) /* Must be integer! */ + blues->RndStemUp = HintEntryP->data.boolean; + else + blues->RndStemUp = DEFAULTRNDSTEMUP; + + /* get the ptr to the lenIV entry */ + HintEntryP = &(PrivateDictP[LENIV].value); + if (objPIsInteger(HintEntryP)) /* Must be integer! */ + blues->lenIV = HintEntryP->data.integer; + else + blues->lenIV = DEFAULTLENIV; + + /* get the ptr to the ExpansionFactor entry */ + HintEntryP = &(PrivateDictP[EXPANSIONFACTOR].value); + if (objPIsInteger(HintEntryP)) + blues->ExpansionFactor = HintEntryP->data.integer; + else if (objPIsReal(HintEntryP)) + blues->ExpansionFactor = HintEntryP->data.real; + else + blues->ExpansionFactor = DEFAULTEXPANSIONFACTOR; + return(SCAN_OK); +} +/**********************************************************************/ +/* GetType1CharString(fontP,code) */ +/* */ +/* Look up code in the standard encoding vector and return */ +/* the charstring associated with the character name. */ +/* */ +/* fontP is the psfont structure. */ +/* */ +/* Returns a psobj (string) */ +/**********************************************************************/ +psobj * +GetType1CharString(psfont *fontP, unsigned char code) +{ + int N; /* the 'Nth' entry in the CharStrings */ + psobj *charnameP; /* points to psobj that is name of character*/ + + psdict *CharStringsDictP; /* dictionary with char strings */ + psobj *theStringP; /* the definition for the code */ + + + + if (StdEncArrayP == NULL) { + return(NULL); + } + /* use the code to index into the standard encoding vector */ + charnameP = &(StdEncArrayP[code]); + + /* test if the encoding array points to a name */ + if (!(objPIsName(charnameP)) ) { + return(NULL); + } + + /* Now that we have the character name out of the standardencoding */ + /* get the character definition out of the current font */ + CharStringsDictP = fontP->CharStringsP; + + /* search the chars string for this charname as key */ + N = SearchDictName(CharStringsDictP,charnameP); + if (N<=0) { + return(NULL); + } + /* OK, the nth item is the psobj that is the string for this char */ + theStringP = &(CharStringsDictP[N].value); + + return(theStringP); +} + +/***================================================================***/ +/* + * FindDictValue + */ +/***================================================================***/ + +static int +FindDictValue(psdict *dictP) +{ + psobj LitName; + int N; + int V; + + /* we have just scanned a token and it is a literal name */ + /* need to check if that name is in Private dictionary */ + objFormatName(&LitName,tokenLength,tokenStartP); + /* is it in the dictP */ + N = SearchDictName(dictP,&LitName); + /* if found */ + if ( N > 0 ) { + /* what type */ + switch (dictP[N].value.type) { + case OBJ_ENCODING: + V = getEncoding(&(dictP[N].value)); + if ( V != SCAN_OK ) return(V); + break; + case OBJ_ARRAY: +#if XFONT_CID + if (0 == strncmp(tokenStartP,"FDArray",7)) + V = getFDArray(&(dictP[N].value)); + else + V = getArray(&(dictP[N].value)); +#else + V = getArray(&(dictP[N].value)); +#endif + if ( V != SCAN_OK ) return(V); + break; + case OBJ_INTEGER: + /* next value in integer */ + dictP[N].value.data.integer = getInt(); + if (rc) return(rc); /* if next token was not an Int */ + break; + case OBJ_REAL: + /* next value must be real or int, store as a real */ + scan_token(inputP); + if (tokenType == TOKEN_REAL) { + dictP[N].value.data.real = tokenValue.real; + } + else + if (tokenType == TOKEN_INTEGER) { + dictP[N].value.data.real = tokenValue.integer; + } + else return(SCAN_ERROR); + break; + case OBJ_NAME: + V = getNextValue(TOKEN_LITERAL_NAME); + if ( V != SCAN_OK ) return(V); + if (!(vm_alloc(tokenLength)) ) return(SCAN_OUT_OF_MEMORY); + objFormatName(&(dictP[N].value),tokenLength,tokenStartP); + break; + case OBJ_STRING: + V = getNextValue(TOKEN_STRING); + if ( V != SCAN_OK ) return(V); + if (!(vm_alloc(tokenLength)) ) return(SCAN_OUT_OF_MEMORY); + objFormatString(&(dictP[N].value),tokenLength,tokenStartP); + break; + case OBJ_BOOLEAN: + scan_token(inputP); + if (tokenType != TOKEN_NAME) { + return(SCAN_ERROR); + } + if (0 == strncmp(tokenStartP,"true",4) ) { + dictP[N].value.data.boolean =TRUE; + } + else + if (0 == strncmp(tokenStartP,"false",5) ) { + dictP[N].value.data.boolean =FALSE; + } + else return(SCAN_ERROR); + break; + + default: + return(SCAN_ERROR); + } + } + /* Name is not in dictionary. That is ok. */ + return(SCAN_OK); + +} +/***================================================================***/ + +#if XFONT_CID +/* + * ------------------------------------------------------------------- + * Scan the next token and convert it into an object + * Result is placed on the Operand Stack as next object + * ------------------------------------------------------------------- + */ +int +scan_cidfont(cidfont *CIDFontP, cmapres *CMapP) +{ + char filename[CID_PATH_MAX]; + char cmapfile[CID_PATH_MAX]; + char buf[CID_BUFSIZE]; + char filetype[3]; + FILE *fileP; + FILE *fileP1; + char *nameP; + int namelen; + int i, j; + int cread, rangecnt; + unsigned int char_row, char_col; + + filetype[0] = 'r'; + filetype[1] = 'b'; + filetype[2] = '\0'; + + /* copy the filename and remove leading or trailing blanks */ + /* point to name and search for leading blanks */ + nameP= CIDFontP->CIDFontFileName.data.nameP; + namelen = CIDFontP->CIDFontFileName.len; + while (nameP[0] == ' ') { + nameP++; + namelen--; + } + /* now remove any trailing blanks */ + while ((namelen>0) && ( nameP[namelen-1] == ' ')) { + namelen--; + } + strncpy(filename,nameP,namelen); + filename[namelen] = '\0'; + /* file name is now constructed */ + inputFile.data.fileP = NULL; + filterFile.data.fileP = NULL; + + /* check whether a CIDFont file */ + if ((fileP = fopen(filename,filetype))) { + cread = fread(buf, 1, CID_BUFSIZE, fileP); + fclose(fileP); + if (cread > 17) { + if (strncmp(buf, "%!", 2) || + strstr(buf, "Resource-CIDFont") == NULL) + return(SCAN_FILE_OPEN_ERROR); + } else + return(SCAN_FILE_OPEN_ERROR); + } else + return(SCAN_FILE_OPEN_ERROR); + + /* copy the CMap file name and remove leading or trailing blanks */ + /* point to name and search for leading blanks */ + nameP = CMapP->CMapFileName.data.nameP; + namelen = CMapP->CMapFileName.len; + while (nameP[0] == ' ') { + nameP++; + namelen--; + } + /* now remove any trailing blanks */ + while ((namelen>0) && ( nameP[namelen-1] == ' ')) { + namelen--; + } + strncpy(cmapfile,nameP,namelen); + cmapfile[namelen] = '\0'; + /* CMap file name is now constructed */ + inputFile1.data.fileP = NULL; + + /* check whether a CMap file */ + if ((fileP1 = fopen(cmapfile,filetype))) { + cread = fread(buf, 1, CID_BUFSIZE, fileP1); + fclose(fileP1); + if (cread > 17) { + if (strncmp(buf, "%!", 2) || + strstr(buf, "Resource-CMap") == NULL) + return(SCAN_FILE_OPEN_ERROR); + } else + return(SCAN_FILE_OPEN_ERROR); + } else + return(SCAN_FILE_OPEN_ERROR); + + /* read the specified CMap file */ + inputP = &inputFile1; + + if (!(fileP1 = fopen(cmapfile,filetype))) + return(SCAN_FILE_OPEN_ERROR); + + objFormatFile(inputP,fileP1); + + if ((rc = BuildCMapInfo(CMapP)) != 0) + return(rc); + + /* Assume everything will be OK */ + rc = 0; + rangecnt = 0; + + do { + /* Scan the next token */ + scan_token(inputP); + if (tokenType == TOKEN_INTEGER) + rangecnt = tokenValue.integer; + + if (rangecnt < 0 || rangecnt > INT_MAX / sizeof(spacerangecode)) { + rc = SCAN_ERROR; + break; + } + /* ==> tokenLength, tokenTooLong, tokenType, and */ + /* tokenValue are now set */ + + switch (tokenType) { + case TOKEN_EOF: + case TOKEN_NONE: + case TOKEN_INVALID: + /* in this case we are done */ + if (tokenTooLong) return(SCAN_OUT_OF_MEMORY); + rc = SCAN_ERROR; + break; + case TOKEN_LITERAL_NAME: + /* Look up the name */ + tokenStartP[tokenLength] = '\0'; + + rc = FindDictValue(CMapP->CMapInfoP); + /* we are not going to report errors except out of memory */ + if (rc != SCAN_OUT_OF_MEMORY) + rc = SCAN_OK; + break; + case TOKEN_NAME: + if (0 == strncmp(tokenStartP,"begincodespacerange",19)) { + CIDFontP->spacerangecnt++; + spacerangeP = (spacerange *)vm_alloc(sizeof(spacerange)); + if (!spacerangeP) { + rc = SCAN_OUT_OF_MEMORY; + break; + } + spacerangeP->next = NULL; + spacerangeP->rangecnt = rangecnt; + spacerangeP->spacecode = + (spacerangecode *)vm_alloc(rangecnt*sizeof(spacerangecode)); + if (!spacerangeP->spacecode) { + rc = SCAN_OUT_OF_MEMORY; + break; + } + for (i = 0; i < rangecnt; i++) { + scan_token(inputP); + if (tokenType != TOKEN_HEX_STRING) { + rc = SCAN_ERROR; + break; + } + spacerangeP->spacecode[i].srcCodeLo = 0; + for (j = 0; j < tokenLength; j++) + spacerangeP->spacecode[i].srcCodeLo += + (unsigned char)tokenStartP[j] << (8 * (tokenLength - 1 - j)); + + scan_token(inputP); + if (tokenType != TOKEN_HEX_STRING) { + rc = SCAN_ERROR; + break; + } + spacerangeP->spacecode[i].srcCodeHi = 0; + for (j = 0; j < tokenLength; j++) + spacerangeP->spacecode[i].srcCodeHi += + (unsigned char)tokenStartP[j] << (8 * (tokenLength - 1 - j)); + } + + if (CIDFontP->spacerangeP) { + if (CIDFontP->spacerangeP->next == NULL) + CIDFontP->spacerangeP->next = spacerangeP; + else { + spacerangeP->next = CIDFontP->spacerangeP->next; + CIDFontP->spacerangeP->next = spacerangeP; + } + } else + CIDFontP->spacerangeP = spacerangeP; + + /* read "endcodespacerange" */ + scan_token(inputP); + if (tokenType != TOKEN_NAME || (tokenType == TOKEN_NAME && + (strncmp(tokenStartP,"endcodespacerange",17) != 0))) { + rc = SCAN_ERROR; + break; + } + } + if (0 == strncmp(tokenStartP,"begincidrange",13)) { + CIDFontP->cidrangecnt++; + cidrangeP = (cidrange *)vm_alloc(sizeof(cidrange)); + if (!cidrangeP) { + rc = SCAN_OUT_OF_MEMORY; + break; + } + cidrangeP->next = NULL; + cidrangeP->rangecnt = rangecnt; + cidrangeP->range = + (cidrangecode *)vm_alloc(rangecnt*sizeof(cidrangecode)); + if (!cidrangeP->range) { + rc = SCAN_OUT_OF_MEMORY; + break; + } + for (i = 0; i < rangecnt; i++) { + scan_token(inputP); + if (tokenType != TOKEN_HEX_STRING) { + rc = SCAN_ERROR; + break; + } + cidrangeP->range[i].srcCodeLo = 0; + for (j = 0; j < tokenLength; j++) + cidrangeP->range[i].srcCodeLo += + (unsigned char)tokenStartP[j] << (8 * (tokenLength - 1 - j)); + char_row = (cidrangeP->range[i].srcCodeLo >> 8) & 0xff; + char_col = cidrangeP->range[i].srcCodeLo & 0xff; + if (char_row < CMapP->firstRow) + CMapP->firstRow = char_row; + if (char_row > CMapP->lastRow) + CMapP->lastRow = char_row; + if (char_col < CMapP->firstCol) + CMapP->firstCol = char_col; + if (char_col > CMapP->lastCol) + CMapP->lastCol = char_col; + scan_token(inputP); + if (tokenType != TOKEN_HEX_STRING) { + rc = SCAN_ERROR; + break; + } + cidrangeP->range[i].srcCodeHi = 0; + for (j = 0; j < tokenLength; j++) + cidrangeP->range[i].srcCodeHi += + (unsigned char)tokenStartP[j] << (8 * (tokenLength - 1 - j)); + char_row = (cidrangeP->range[i].srcCodeHi >> 8) & 0xff; + char_col = cidrangeP->range[i].srcCodeHi & 0xff; + if (char_row < CMapP->firstRow) + CMapP->firstRow = char_row; + if (char_row > CMapP->lastRow) + CMapP->lastRow = char_row; + if (char_col < CMapP->firstCol) + CMapP->firstCol = char_col; + if (char_col > CMapP->lastCol) + CMapP->lastCol = char_col; + scan_token(inputP); + if (tokenType != TOKEN_INTEGER) { + rc = SCAN_ERROR; + break; + } + cidrangeP->range[i].dstCIDLo = tokenValue.integer; + } + + if (CIDFontP->cidrangeP) { + if (CIDFontP->cidrangeP->next == NULL) + CIDFontP->cidrangeP->next = cidrangeP; + else { + cidrangeP->next = CIDFontP->cidrangeP->next; + CIDFontP->cidrangeP->next = cidrangeP; + } + } else + CIDFontP->cidrangeP = cidrangeP; + + /* read "endcidrange" */ + scan_token(inputP); + if (tokenType != TOKEN_NAME || (tokenType == TOKEN_NAME && + (strncmp(tokenStartP,"endcidrange",11) != 0))) { + rc = SCAN_ERROR; + break; + } + } + + if (0 == strncmp(tokenStartP,"beginnotdefrange",16)) { + CIDFontP->notdefrangecnt++; + notdefrangeP = (cidrange *)vm_alloc(sizeof(cidrange)); + if (!notdefrangeP) { + rc = SCAN_OUT_OF_MEMORY; + break; + } + notdefrangeP->next = 0; + notdefrangeP->rangecnt = rangecnt; + notdefrangeP->range = + (cidrangecode *)vm_alloc(rangecnt*sizeof(cidrangecode)); + if (!notdefrangeP->range) { + rc = SCAN_OUT_OF_MEMORY; + break; + } + for (i = 0; i < rangecnt; i++) { + scan_token(inputP); + if (tokenType != TOKEN_HEX_STRING) { + rc = SCAN_ERROR; + break; + } + notdefrangeP->range[i].srcCodeLo = 0; + for (j = 0; j < tokenLength; j++) + notdefrangeP->range[i].srcCodeLo = (int)(tokenStartP[j] << + (8 * (tokenLength - 1 - j))); + scan_token(inputP); + if (tokenType != TOKEN_HEX_STRING) { + rc = SCAN_ERROR; + break; + } + notdefrangeP->range[i].srcCodeHi = 0; + for (j = 0; j < tokenLength; j++) + notdefrangeP->range[i].srcCodeHi = (int)(tokenStartP[j] << + (8 * (tokenLength - 1 - j))); + scan_token(inputP); + if (tokenType != TOKEN_INTEGER) { + rc = SCAN_ERROR; + break; + } + notdefrangeP->range[i].dstCIDLo = tokenValue.integer; + } + if (CIDFontP->notdefrangeP) { + if (CIDFontP->notdefrangeP->next == NULL) + CIDFontP->notdefrangeP->next = notdefrangeP; + else { + notdefrangeP->next = CIDFontP->notdefrangeP->next; + CIDFontP->notdefrangeP->next = notdefrangeP; + } + } else + CIDFontP->notdefrangeP = notdefrangeP; + + /* read "endnotdefrange" */ + scan_token(inputP); + if (tokenType != TOKEN_NAME || (tokenType == TOKEN_NAME && + (strncmp(tokenStartP,"endnotdefrange",14) != 0))) { + rc = SCAN_ERROR; + break; + } + } + + if (0 == strncmp(tokenStartP,"endcmap",7)) { + if (CMapP->CMapInfoP[CMAPREGISTRY].value.data.valueP == NULL || + CMapP->CMapInfoP[CMAPORDERING].value.data.valueP == NULL || + CMapP->CMapInfoP[CMAPSUPPLEMENT].value.data.integer == -1) { + rc = SCAN_ERROR; + break; + } else { + rc = SCAN_FILE_EOF; + break; + } + } + break; + } + } + while (rc == 0); + fclose(inputP->data.fileP); + if (tokenTooLong) + rc = SCAN_OUT_OF_MEMORY; + if (rc == SCAN_OUT_OF_MEMORY) return(rc); + + /* open the specified CIDFont file */ + if (!(fileP = fopen(filename,filetype))) + return(SCAN_FILE_OPEN_ERROR); + + inputP = &inputFile; + objFormatFile(inputP,fileP); + CIDWantFontInfo = TRUE; + TwoSubrs = FALSE; + rc = BuildCIDFontInfo(CIDFontP); + if (rc != 0) return(rc); + + /* Assume everything will be OK */ + rc = 0; + + /* Loop until complete font is read */ + do { + /* Scan the next token */ + scan_token(inputP); + + /* ==> tokenLength, tokenTooLong, tokenType, and tokenValue are */ + /* now set */ + + switch (tokenType) { + case TOKEN_EOF: + case TOKEN_NONE: + case TOKEN_INVALID: + /* in this case we are done */ + if (tokenTooLong) return(SCAN_OUT_OF_MEMORY); + rc = SCAN_ERROR; + break; + case TOKEN_LITERAL_NAME: + /* Look up the name */ + tokenStartP[tokenLength] = '\0'; + + if (CIDWantFontInfo) { + rc = FindDictValue(CIDFontP->CIDfontInfoP); + /* we are not going to report errors except out of memory */ + if (rc != SCAN_OUT_OF_MEMORY) + rc = SCAN_OK; + break; + } + break; + case TOKEN_STRING: + tokenStartP[tokenLength] = '\0'; + if (0 == strncmp(tokenStartP,"Binary",6)) { + CIDFontP->binarydata = 1; + scan_token(inputP); + if (tokenType == TOKEN_INTEGER) + CIDFontP->bytecnt = tokenValue.integer; + else { + rc = SCAN_ERROR; + break; + } + } else if (0 == strncmp(tokenStartP,"Hex",3)) { + /* not yet supported */ + rc = SCAN_ERROR; + break; +#if 0 + /* uncomment when the hex format is supported */ + CIDFontP->binarydata = 0; + scan_token(inputP); + if (tokenType == TOKEN_INTEGER) + CIDFontP->bytecnt = tokenValue.integer; + else { + rc = SCAN_ERROR; + break; + } +#endif + } + break; + case TOKEN_NAME: + /* end of PostScript and beginning of data */ + if (0 == strncmp(tokenStartP,"StartData",9)) { + /* every CIDFont must have an FDArray */ + /* check whether other required dictionary entries were found */ + if (CIDFontP->CIDfontInfoP[CIDFDARRAY].value.data.arrayP == NULL || + CIDFontP->CIDfontInfoP[CIDFONTNAME].value.data.nameP == NULL || + CIDFontP->CIDfontInfoP[CIDFONTTYPE].value.data.integer == -1 || + CIDFontP->CIDfontInfoP[CIDVERSION].value.data.integer == -1 || + CIDFontP->CIDfontInfoP[CIDREGISTRY].value.data.valueP == NULL || + CIDFontP->CIDfontInfoP[CIDORDERING].value.data.valueP == NULL || + CIDFontP->CIDfontInfoP[CIDSUPPLEMENT].value.data.integer == -1 || + CIDFontP->CIDfontInfoP[CIDFONTBBOX].value.data.arrayP == NULL || + CIDFontP->CIDfontInfoP[CIDMAPOFFSET].value.data.integer == -1 || + CIDFontP->CIDfontInfoP[CIDFDBYTES].value.data.integer == -1 || + CIDFontP->CIDfontInfoP[CIDGDBYTES].value.data.integer == -1 || + CIDFontP->CIDfontInfoP[CIDCOUNT].value.data.integer == -1) { + rc = SCAN_ERROR; + break; + } else { + /* do Registry and Ordering entries match? */ + if (strcmp(CIDFontP->CIDfontInfoP[CIDREGISTRY].value.data.valueP, + CMapP->CMapInfoP[CMAPREGISTRY].value.data.valueP) != 0 || + strcmp(CIDFontP->CIDfontInfoP[CIDORDERING].value.data.valueP, + CMapP->CMapInfoP[CMAPORDERING].value.data.valueP) != 0) { + rc = SCAN_ERROR; + break; + } else { + fclose(inputP->data.fileP); + return(SCAN_OK); + } + } + } + break; + } + + } + while (rc ==0); + fclose(inputP->data.fileP); + if (tokenTooLong) return(SCAN_OUT_OF_MEMORY); + return(rc); +} + +/* + * ------------------------------------------------------------------- + * Scan the next token and convert it into an object + * Result is placed on the Operand Stack as next object + * ------------------------------------------------------------------- + */ +int +scan_cidtype1font(psfont *FontP) +{ + int i; + int begincnt = 0; /* counter for the number of unpaired begin operators */ + int currentfilefound = 0; + + WantFontInfo = TRUE; + InPrivateDict = FALSE; + TwoSubrs = FALSE; + rc = BuildFontInfo(FontP); + if (rc != 0) return(rc); + + /* Assume everything will be OK */ + rc = 0; + filterFile.data.fileP = NULL; + + /* Loop until complete font is read */ + do { + /* Scan the next token */ + scan_token(inputP); + + /* ==> tokenLength, tokenTooLong, tokenType, and tokenValue are */ + /* now set */ + + switch (tokenType) { + case TOKEN_EOF: + case TOKEN_NONE: + case TOKEN_INVALID: + /* in this case we are done */ + if (tokenTooLong) return(SCAN_OUT_OF_MEMORY); + rc = SCAN_ERROR; + break; + case TOKEN_LITERAL_NAME: + /* Look up the name */ + tokenStartP[tokenLength] = '\0'; + if (InPrivateDict ) { + rc = FindDictValue(FontP->Private); + /* we are not going to report errors */ + /* Sometimes the font file may test a value such as */ + /* testing to see if the font is alreadly loaded with */ + /* same UniqueID. We would faile on /UniqueID get */ + /* because we are expecting a int to follow UniqueID*/ + /* If the correct object type does not follow a Name*/ + /* then we will skip over it without reporting error except */ + /* out of memory */ + if (rc != SCAN_OUT_OF_MEMORY) + rc = SCAN_OK; + break; + } /* end of reading Private dictionary */ + else + if (0 == strncmp(tokenStartP,"Private",7) ) { + InPrivateDict = TRUE; + rc = BuildCIDType1Private(FontP); + break; + } + else + if (WantFontInfo) { + rc = FindDictValue(FontP->fontInfoP); + /* we are not going to report errors except out of memory */ + if (rc != SCAN_OUT_OF_MEMORY) + rc = SCAN_OK; + break; + } + break; + case TOKEN_NAME: + if (0 == strncmp(tokenStartP,"currentfile",11)) { + currentfilefound = 1; + break; + } else if (0 == strncmp(tokenStartP,"eexec",5)) { + if (currentfilefound == 1) { + currentfilefound = 0; + filterFile.data.fileP = CIDeexec(inputP->data.fileP); + if (filterFile.data.fileP == NULL) { + fclose(inputFile.data.fileP); + return(SCAN_FILE_OPEN_ERROR); + } + inputP = &filterFile; + } else { + rc = SCAN_ERROR; + break; + } + } else if (0 == strncmp(tokenStartP,"begin",5)) { + begincnt++; + currentfilefound = 0; + } else if (0 == strncmp(tokenStartP,"end",3)) { + currentfilefound = 0; + begincnt--; + if (begincnt == 0) { + if (filterFile.data.fileP != NULL) { + scan_token(inputP); /* get 'currentfile' */ + scan_token(inputP); /* get 'closefile' */ + inputP = &inputFile; + resetDecrypt(); + inputP->data.fileP->b_cnt = + F_BUFSIZ - (inputP->data.fileP->b_ptr - + inputP->data.fileP->b_base); + if (inputP->data.fileP->b_cnt > 0) { + for (i = 0; i < inputP->data.fileP->b_cnt; i++) + if (*(inputP->data.fileP->b_ptr + i) == '%') + break; + if (i < inputP->data.fileP->b_cnt) { + inputP->data.fileP->b_cnt -= i; + inputP->data.fileP->b_ptr += i; + } else + inputP->data.fileP->b_cnt = 0; + } + } + rc = SCAN_OK; + return(rc); + } + if (begincnt < 0) { + rc = SCAN_ERROR; + break; + } + } + break; + } + + } + while (rc == 0); + if (tokenTooLong) return(SCAN_OUT_OF_MEMORY); + return(rc); +} +#endif + +/* + * ------------------------------------------------------------------- + * Scan the next token and convert it into an object + * Result is placed on the Operand Stack as next object + * ------------------------------------------------------------------- + */ +int +scan_font(psfont *FontP) +{ + + + char filename[128]; + char filetype[3]; + FILE *fileP; + char *nameP; + int namelen; + int V; + int i; + boolean starthex80; + + starthex80 = FALSE; + filetype[0] = 'r'; + filetype[1] = 'b'; + filetype[2] = '\0'; + /* copy the filename and remove leading or trailing blanks */ + /* point to name and search for leading blanks */ + nameP= FontP->FontFileName.data.nameP; + namelen = FontP->FontFileName.len; + while (nameP[0] == ' ') { + nameP++; + namelen--; + } + /* now remove any trailing blanks */ + while ((namelen>0) && ( nameP[namelen-1] == ' ')) { + namelen--; + } + strncpy(filename,nameP,namelen); + filename[namelen] = '\0'; + /* file name is now constructed */ + inputFile.data.fileP = NULL; + filterFile.data.fileP = NULL; + + inputP = &inputFile; + if ((fileP = T1Open(filename,filetype))) { + /* get the first byte of file */ + V = _XT1getc(fileP); + /* if file starts with x'80' then skip next 5 bytes */ + if ( V == 0X80 ) { + for (i=0;i<5;i++) V = _XT1getc(fileP); + starthex80 = TRUE; + } + else T1Ungetc(V,fileP); + objFormatFile(inputP,fileP); + } + else { + return(SCAN_FILE_OPEN_ERROR); + }; + + WantFontInfo = TRUE; + InPrivateDict = FALSE; + TwoSubrs = FALSE; + rc = BuildFontInfo(FontP); + if (rc != 0) return(rc); + + /* Assume everything will be OK */ + rc = 0; + + /* Loop until complete font is read */ + do { + /* Scan the next token */ + scan_token(inputP); + + /* ==> tokenLength, tokenTooLong, tokenType, and tokenValue are */ + /* now set */ + + switch (tokenType) { + case TOKEN_EOF: + case TOKEN_NONE: + case TOKEN_INVALID: + /* in this case we are done */ + if (tokenTooLong) return(SCAN_OUT_OF_MEMORY); + rc = SCAN_ERROR; + break; + case TOKEN_LITERAL_NAME: + /* Look up the name */ + tokenStartP[tokenLength] = '\0'; + if (InPrivateDict ) { + if (0== strncmp(tokenStartP,"Subrs",5) ) { + rc = BuildSubrs(FontP); + break; + } + if (0== strncmp(tokenStartP,"CharStrings",11) ) { + rc = BuildCharStrings(FontP); + if ( (rc == SCAN_OK) ||(rc == SCAN_END) ) { + T1Close(inputP->data.fileP); + /* Build the Blues Structure */ + rc = GetType1Blues(FontP); + /* whatever the return code, return it */ + /* all the work is done. This is the normal exit.*/ + return(rc); + } + break; + } + rc = FindDictValue(FontP->Private); + /* we are not going to report errors */ + /* Sometimes the font file may test a value such as */ + /* testing to see if the font is alreadly loaded with */ + /* same UniqueID. We would faile on /UniqueID get */ + /* because we are expecting a int to follow UniqueID*/ + /* If the correct object type does not follow a Name*/ + /* then we will skip over it without reporting error except */ + /* when out of memory */ + if (rc != SCAN_OUT_OF_MEMORY) + rc = SCAN_OK; + break; + } /* end of reading Private dictionary */ + else + if (0== strncmp(tokenStartP,"Private",7) ) { + InPrivateDict = TRUE; + rc = BuildPrivate(FontP); + break; + } + else + if (WantFontInfo) { + rc = FindDictValue(FontP->fontInfoP); + /* we are not going to report errors except out of memory */ + if (rc != SCAN_OUT_OF_MEMORY) + rc = SCAN_OK; + break; + } + break; + case TOKEN_NAME: + if (0 == strncmp(tokenStartP,"eexec",5) ) { + /* if file started with x'80', check next 5 bytes */ + if (starthex80) { + V = _XT1getc(fileP); + if ( V == 0X80 ) { + for (i=0;i<5;i++) V = _XT1getc(fileP); + } + else T1Ungetc(V,fileP); + } + filterFile.data.fileP = T1eexec(inputP->data.fileP); + if (filterFile.data.fileP == NULL) { + T1Close(inputFile.data.fileP); + return(SCAN_FILE_OPEN_ERROR); + } + inputP = &filterFile; + + WantFontInfo = FALSE; + } + break; + } + + } + while (rc ==0); + T1Close(inputP->data.fileP); + if (tokenTooLong) return(SCAN_OUT_OF_MEMORY); + return(rc); +} + diff --git a/nx-X11/lib/font/Type1/spaces.c b/nx-X11/lib/font/Type1/spaces.c new file mode 100644 index 000000000..55cc96f67 --- /dev/null +++ b/nx-X11/lib/font/Type1/spaces.c @@ -0,0 +1,998 @@ +/* $Xorg: spaces.c,v 1.4 2000/08/17 19:46:32 cpqbld Exp $ */ +/* Copyright International Business Machines, Corp. 1991 + * All Rights Reserved + * Copyright Lexmark International, Inc. 1991 + * All Rights Reserved + * + * License to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, + * provided that the above copyright notice appear in all copies and that + * both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of IBM or Lexmark not be + * used in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * + * IBM AND LEXMARK PROVIDE THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES OF + * ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO ANY + * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, + * AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE + * QUALITY AND PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT + * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF THE + * SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM OR LEXMARK) ASSUMES THE + * ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN NO EVENT SHALL + * IBM OR LEXMARK BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF + * THIS SOFTWARE. + */ +/* $XFree86: xc/lib/font/Type1/spaces.c,v 3.10tsi Exp $ */ + /* SPACES CWEB V0021 ******** */ +/* +:h1 id=spaces.SPACES Module - Handles Coordinate Spaces + +This module is responsible for handling the TYPE1IMAGER "XYspace" object. + +&author. Jeffrey B. Lotspiech (lotspiech@almaden.ibm.com) + + +:h3.Include Files +*/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#ifdef FONTMODULE +#include "Xdefs.h" /* Bool declaration ??? */ +#include "Xmd.h" /* INT32 declaration ??? */ +#include "os.h" +#include "xf86_ansic.h" +#else +#include "X11/Xos.h" +#include <stdio.h> +#endif +#include "objects.h" +#include "spaces.h" +#include "paths.h" +#include "pictures.h" +#include "fonts.h" +#include "arith.h" +#include "trig.h" + +static void FindFfcn ( double cx, double cy, + convertFunc *fcnP ); +static void FindIfcn ( double cx, double cy, + fractpel *icxP, fractpel *icyP, + iconvertFunc *fcnP ); + +/* +:h3.Entry Points Provided to the TYPE1IMAGER User +*/ + +/*SHARED LINE(S) ORIGINATED HERE*/ + +/* +:h3.Entry Points Provided to Other Modules +*/ + +/* +In addition, other modules call the SPACES module through function +vectors in the "XYspace" structure. The entry points accessed that +way are "FConvert()", "IConvert()", and "ForceFloat()". +*/ + +/*SHARED LINE(S) ORIGINATED HERE*/ +/* +:h3.Macros and Typedefs Provided to Other Modules + +:h4.Duplicating and Killing Spaces + +Destroying XYspaces is so simple we can do it with a +macro: +*/ + +/*SHARED LINE(S) ORIGINATED HERE*/ +/* +On the other hand, duplicating XYspaces is slightly more difficult +because of the need to keep a unique ID in the space, see +:hdref refid=dupspace.. + +:h4.Fixed Point Pel Representation + +We represent pel positions with fixed point numbers. This does NOT +mean integer, but truly means fixed point, with a certain number +of binary digits (FRACTBITS) representing the fractional part of the +pel. +*/ + +/*SHARED LINE(S) ORIGINATED HERE*/ +/* +:h2.Data Structures for Coordinate Spaces and Points +*/ +/* +:h3 id=matrix.Matrices + +TYPE1IMAGER uses 2x2 transformation matrices. We'll use C notation for +such a matrix (M[2][2]), the first index being rows, the second columns. +*/ + +/* +:h3.The "doublematrix" Structure + +We frequently find it desirable to store both a matrix and its +inverse. We store these in a "doublematrix" structure. +*/ + +/*SHARED LINE(S) ORIGINATED HERE*/ + +/* +:h3.The "XYspace" Structure + +The XYspace structure represents the XYspace object. +*/ + +/*SHARED LINE(S) ORIGINATED HERE*/ +#define RESERVED 10 /* 'n' IDs are reserved for invalid & immortal spaces */ +/* +*/ +#define NEXTID ((SpaceID < RESERVED) ? (SpaceID = RESERVED) : ++SpaceID) + +static unsigned int SpaceID = 1; + +struct XYspace * +CopySpace(struct XYspace *S) +{ + S = (struct XYspace *)Allocate(sizeof(struct XYspace), S, 0); + S->ID = NEXTID; + return(S); +} +/* +:h3.The "fractpoint" Structure + +A fractional point is just a "fractpel" x and y: +*/ + +/*SHARED LINE(S) ORIGINATED HERE*/ + +/* +:h3.Lazy Evaluation of Matrix Inverses + +Calculating the inverse of a matrix is somewhat involved, and we usually +do not need them. So, we flag whether or not the space has the inverse +already calculated: +*/ + +#define HASINVERSE(flag) ((flag)&0x80) + +/* +The following macro forces a space to have an inverse: +*/ + +#define CoerceInverse(S) if (!HASINVERSE((S)->flag)) { \ + MatrixInvert((S)->tofract.normal, (S)->tofract.inverse); (S)->flag |= HASINVERSE(ON); } +/* +:h3.IDENTITY Space + +IDENTITY space is (logically) the space corresponding to the identity +transformation matrix. However, since all our transformation matrices +have a common FRACTFLOAT scale factor to convert to 'fractpel's, that +is actually what we store in 'tofract' matrix of IDENTITY: +*/ + +static struct XYspace identity = { SPACETYPE, ISPERMANENT(ON) + ISIMMORTAL(ON) + + HASINVERSE(ON), 2, /* added 3-26-91 PNM */ + NULL, NULL, + NULL, NULL, NULL, NULL, + INVALIDID + 1, 0, + {{{FRACTFLOAT, 0.0}, {0.0, FRACTFLOAT}}, + {{1.0/FRACTFLOAT, 0.0}, {0.0, 1.0/FRACTFLOAT}}}, + {{0, 0}, {0, 0}}}; +struct XYspace *IDENTITY = &identity; + +/* +*/ +#define MAXCONTEXTS 16 + +static struct doublematrix contexts[MAXCONTEXTS]; + +#ifdef notdef + +static int nextcontext = 1; + +/*SHARED LINE(S) ORIGINATED HERE*/ + +/* +:h3.FindDeviceContext() - Find the Context Given a Device + +This routine, given a device, returns the index of the device's +transformation matrix in the context array. If it cannot find it, +it will allocate a new array entry and fill it out. +*/ + +static int +FindDeviceContext(pointer device) /* device token */ +{ + double M[2][2]; /* temporary matrix */ + float Xres,Yres; /* device resolution */ + int orient = -1; /* device orientation */ + int rc = -1; /* return code for QueryDeviceState */ + + if (rc != 0) /* we only bother with this check once */ + Abort("Context: QueryDeviceState didn't work"); + + M[0][0] = M[1][0] = M[0][1] = M[1][1] = 0.0; + + switch (orient) { + case 0: + M[0][0] = Xres; M[1][1] = -Yres; + break; + case 1: + M[1][0] = Yres; M[0][1] = Xres; + break; + case 2: + M[0][0] = -Xres; M[1][1] = Yres; + break; + case 3: + M[1][0] = -Yres; M[0][1] = -Xres; + break; + default: + Abort("QueryDeviceState returned invalid orientation"); + } + return(FindContext(M)); +} + +/* +:h3.FindContext() - Find the Context Given a Matrix + +This routine, given a matrix, returns the index of that matrix matrix in +the context array. If it cannot find it, it will allocate a new array +entry and fill it out. +*/ + +int +FindContext(double M[2][2]) /* array to search for */ +{ + register int i; /* loop variable for search */ + for (i=0; i < nextcontext; i++) + if (M[0][0] == contexts[i].normal[0][0] && M[1][0] == contexts[i].normal[1][0] + && M[0][1] == contexts[i].normal[0][1] && M[1][1] == contexts[i].normal[1][1]) + break; + + if (i >= nextcontext) { + if (i >= MAXCONTEXTS) + Abort("Context: out of them"); + LONGCOPY(contexts[i].normal, M, sizeof(contexts[i].normal)); + MatrixInvert(M, contexts[i].inverse); + nextcontext++; + } + + return(i); +} + +/* +:h3.Context() - Create a Coordinate Space for a Device + +This user operator is implemented by first finding the device context +array index, then transforming IDENTITY space to create an appropriate +cooridnate space. +*/ + +struct XYspace * +Context(pointer device, /* device token */ + double units) /* multiples of one inch */ +{ + double M[2][2]; /* device transformation matrix */ + register int n; /* will hold device context number */ + register struct XYspace *S; /* XYspace constructed */ + + ARGCHECK((device == NULL), "Context of NULLDEVICE not allowed", + NULL, IDENTITY, (0), struct XYspace *); + ARGCHECK((units == 0.0), "Context: bad units", NULL, IDENTITY, (0), struct XYspace *); + + n = FindDeviceContext(device); + + LONGCOPY(M, contexts[n].normal, sizeof(M)); + + M[0][0] *= units; + M[0][1] *= units; + M[1][0] *= units; + M[1][1] *= units; + + S = (struct XYspace *)Xform(IDENTITY, M); + + S->context = n; + return(S); +} +#endif + +/* +:h3.ConsiderContext() - Adjust a Matrix to Take Out Device Transform + +Remember, we have :f/x times U times D/ and :f/M/ and and we want :f/x +times U times M times D/. An easy way to do this is to calculate +:f/D sup <-1> times M times D/, because: +:formula. +x times U times D times D sup <-1> times M times D = x times U times M times D +:formula. +So this subroutine, given an :f/M/and an object, finds the :f/D/ for that +object and modifies :f/M/ so it is :f/D sup <-1> times M times D/. +*/ + +static void +ConsiderContext(struct xobject *obj, /* object to be transformed */ + double M[2][2]) /* matrix (may be changed) */ +{ + register int context = 0; /* index in contexts array */ + + if (obj == NULL) return; + + if (ISPATHTYPE(obj->type)) { + struct segment *path = (struct segment *) obj; + + context = path->context; + } + else if (obj->type == SPACETYPE) { + struct XYspace *S = (struct XYspace *) obj; + + context = S->context; + } + else if (obj->type == PICTURETYPE) { + + } + else + context = NULLCONTEXT; + + if (context != NULLCONTEXT) { + MatrixMultiply(contexts[context].inverse, M, M); + MatrixMultiply(M, contexts[context].normal, M); + } +} + +/* +:h2.Conversion from User's X,Y to "fractpel" X,Y + +When the user is building paths (lines, moves, curves, etc.) he passes +the control points (x,y) for the paths together with an XYspace. We +must convert from the user's (x,y) to our internal representation +which is in pels (fractpels, actually). This involves transforming +the user's (x,y) under the coordinate space transformation. It is +important that we do this quickly. So, we store pointers to different +conversion functions right in the XYspace structure. This allows us +to have simpler special case functions for the more commonly +encountered types of transformations. + +:h3.Convert(), IConvert(), and ForceFloat() - Called Through "XYspace" Structure + +These are functions that fit in the "convert" and "iconvert" function +pointers in the XYspace structure. They call the "xconvert", "yconvert", +"ixconvert", and "iyconvert" as appropriate to actually do the work. +These secondary routines come in many flavors to handle different +special cases as quickly as possible. +*/ + +static void +FXYConvert(struct fractpoint *pt, /* point to set */ + struct XYspace *S, /* relevant coordinate space */ + double x, double y) /* user's coordinates of point */ +{ + pt->x = (*S->xconvert)(S->tofract.normal[0][0], S->tofract.normal[1][0], x, y); + pt->y = (*S->yconvert)(S->tofract.normal[0][1], S->tofract.normal[1][1], x, y); +} + +static void +IXYConvert(struct fractpoint *pt, /* point to set */ + struct XYspace *S, /* relevant coordinate space */ + long x, long y) /* user's coordinates of point */ +{ + pt->x = (*S->ixconvert)(S->itofract[0][0], S->itofract[1][0], x, y); + pt->y = (*S->iyconvert)(S->itofract[0][1], S->itofract[1][1], x, y); +} + +/* +ForceFloat is a substitute for IConvert(), when we just do not have +enough significant digits in the coefficients to get high enough +precision in the answer with fixed point arithmetic. So, we force the +integers to floats, and do the arithmetic all with floats: +*/ + +static void +ForceFloat(struct fractpoint *pt, /* point to set */ + struct XYspace *S, /* relevant coordinate space */ + long x, long y) /* user's coordinates of point */ +{ + (*S->convert)(pt, S, (double) x, (double) y); +} + +/* +:h3.FXYboth(), FXonly(), FYonly() - Floating Point Conversion + +These are the routines we use when the user has given us floating +point numbers for x and y. FXYboth() is the general purpose routine; +FXonly() and FYonly() are special cases when one of the coefficients +is 0.0. +*/ + +static fractpel +FXYboth(double cx, double cy, /* x and y coefficients */ + double x, double y) /* user x,y */ +{ + register double r; /* temporary float */ + + r = x * cx + y * cy; + return((fractpel) r); +} + +/*ARGSUSED*/ +static fractpel +FXonly(double cx, double cy, /* x and y coefficients */ + double x, double y) /* user x,y */ +{ + register double r; /* temporary float */ + + r = x * cx; + return((fractpel) r); +} + +/*ARGSUSED*/ +static fractpel +FYonly(double cx, double cy, /* x and y coefficients */ + double x, double y) /* user x,y */ +{ + register double r; /* temporary float */ + + r = y * cy; + return((fractpel) r); +} + +/* +:h3.IXYboth(), IXonly(), IYonly() - Simple Integer Conversion + +These are the routines we use when the user has given us integers for +x and y, and the coefficients have enough significant digits to +provide precise answers with only "long" (32 bit?) multiplication. +IXYboth() is the general purpose routine; IXonly() and IYonly() are +special cases when one of the coefficients is 0. +*/ + +static fractpel +IXYboth(fractpel cx, fractpel cy, /* x and y coefficients */ + long x, long y) /* user x,y */ +{ + return(x * cx + y * cy); +} + +/*ARGSUSED*/ +static fractpel +IXonly(fractpel cx, fractpel cy, /* x and y coefficients */ + long x, long y) /* user x,y */ +{ + return(x * cx); +} + +/*ARGSUSED*/ +static fractpel +IYonly(fractpel cx, fractpel cy, /* x and y coefficients */ + long x, long y) /* user x,y */ +{ + return(y * cy); +} + + +/* +:h3.FPXYboth(), FPXonly(), FPYonly() - More Involved Integer Conversion + +These are the routines we use when the user has given us integers for +x and y, but the coefficients do not have enough significant digits to +provide precise answers with only "long" (32 bit?) multiplication. +We have increased the number of significant bits in the coefficients +by FRACTBITS; therefore we must use "double long" (64 bit?) +multiplication by calling FPmult(). FPXYboth() is the general purpose +routine; FPXonly() and FPYonly() are special cases when one of the +coefficients is 0. + +Note that it is perfectly possible for us to calculate X with the +"FP" method and Y with the "I" method, or vice versa. It all depends +on how the functions in the XYspace structure are filled out. +*/ + +static fractpel +FPXYboth(fractpel cx, fractpel cy, /* x and y coefficients */ + long x, long y) /* user x,y */ +{ + return( FPmult(x, cx) + FPmult(y, cy) ); +} + +/*ARGSUSED*/ +static fractpel +FPXonly(fractpel cx, fractpel cy, /* x and y coefficients */ + long x, long y) /* user x,y */ +{ + return( FPmult(x, cx) ); +} + +/*ARGSUSED*/ +static fractpel +FPYonly(fractpel cx, fractpel cy, /* x and y coefficients */ + long x, long y) /* user x,y */ +{ + return( FPmult(y, cy) ); +} + + + +/* +:h3.FillOutFcns() - Determine the Appropriate Functions to Use for Conversion + +This function fills out the "convert" and "iconvert" function pointers +in an XYspace structure, and also fills the "helper" +functions that actually do the work. +*/ + +static void +FillOutFcns(struct XYspace *S) /* functions will be set in this structure */ +{ + S->convert = FXYConvert; + S->iconvert = IXYConvert; + + FindFfcn(S->tofract.normal[0][0], S->tofract.normal[1][0], &S->xconvert); + FindFfcn(S->tofract.normal[0][1], S->tofract.normal[1][1], &S->yconvert); + FindIfcn(S->tofract.normal[0][0], S->tofract.normal[1][0], + &S->itofract[0][0], &S->itofract[1][0], &S->ixconvert); + FindIfcn(S->tofract.normal[0][1], S->tofract.normal[1][1], + &S->itofract[0][1], &S->itofract[1][1], &S->iyconvert); + + if (S->ixconvert == NULL || S->iyconvert == NULL) + S->iconvert = ForceFloat; +} + +/* +:h4.FindFfcn() - Subroutine of FillOutFcns() to Fill Out Floating Functions + +This function tests for the special case of one of the coefficients +being zero: +*/ + +static void +FindFfcn(double cx, double cy, /* x and y coefficients */ + convertFunc *fcnP) /* pointer to function to set */ +{ + if (cx == 0.0) + *fcnP = FYonly; + else if (cy == 0.0) + *fcnP = FXonly; + else + *fcnP = FXYboth; +} + +/* +:h4.FindIfcn() - Subroutine of FillOutFcns() to Fill Out Integer Functions + +There are two types of integer functions, the 'I' type and the 'FP' type. +We use the I type functions when we are satisfied with simple integer +arithmetic. We used the FP functions when we feel we need higher +precision (but still fixed point) arithmetic. If all else fails, +we store a NULL indicating that this we should do the conversion in +floating point. +*/ + +static void +FindIfcn(double cx, double cy, /* x and y coefficients */ + fractpel *icxP, fractpel *icyP, /* fixed point coefficients to set */ + iconvertFunc *fcnP) /* pointer to function to set */ +{ + register fractpel imax; /* maximum of cx and cy */ + + *icxP = cx; + *icyP = cy; + + if (cx != (float) (*icxP) || cy != (float) (*icyP)) { +/* +At this point we know our integer approximations of the coefficients +are not exact. However, we will still use them if the maximum +coefficient will not fit in a 'fractpel'. Of course, we have little +choice at that point, but we haven't lost that much precision by +staying with integer arithmetic. We have enough significant digits +so that +any error we introduce is less than one part in 2:sup/16/. +*/ + + imax = MAX(ABS(*icxP), ABS(*icyP)); + if (imax < (fractpel) (1<<(FRACTBITS-1)) ) { +/* +At this point we know our integer approximations just do not have +enough significant digits for accuracy. We will add FRACTBITS +significant digits to the coefficients (by multiplying them by +1<<FRACTBITS) and go to the "FP" form of the functions. First, we +check to see if we have ANY significant digits at all (that is, if +imax == 0). If we don't, we suspect that adding FRACTBITS digits +won't help, so we punt the whole thing. +*/ + if (imax == 0) { + *fcnP = NULL; + return; + } + cx *= FRACTFLOAT; + cy *= FRACTFLOAT; + *icxP = cx; + *icyP = cy; + *fcnP = FPXYboth; + } + else + *fcnP = IXYboth; + } + else + *fcnP = IXYboth; +/* +Now we check for special cases where one coefficient is zero (after +integer conversion): +*/ + if (*icxP == 0) + *fcnP = (*fcnP == FPXYboth) ? FPYonly : IYonly; + else if (*icyP == 0) + *fcnP = (*fcnP == FPXYboth) ? FPXonly : IXonly; +} +/* +:h3.UnConvert() - Find User Coordinates From FractPoints + +The interesting thing with this routine is that we avoid calculating +the matrix inverse of the device transformation until we really need +it, which is to say, until this routine is called for the first time +with a given coordinate space. + +We also only calculate it only once. If the inverted matrix is valid, +we don't calculate it; if not, we do. We never expect matrices with +zero determinants, so by convention, we mark the matrix is invalid by +marking both X terms zero. +*/ + +void +UnConvert(struct XYspace *S, /* relevant coordinate space */ + struct fractpoint *pt, /* device coordinates */ + double *xp, double *yp) /* where to store resulting x,y */ +{ + double x,y; + + CoerceInverse(S); + x = pt->x; + y = pt->y; + *xp = S->tofract.inverse[0][0] * x + S->tofract.inverse[1][0] * y; + *yp = S->tofract.inverse[0][1] * x + S->tofract.inverse[1][1] * y; +} + +/* +:h2.Transformations +*/ +/* +:h3 id=xform.Xform() - Transform Object in X and Y + +TYPE1IMAGER wants transformations of objects like paths to be identical +to transformations of spaces. For example, if you scale a line(1,1) +by 10 it should yield the same result as generating the line(1,1) in +a coordinate space that has been scaled by 10. + +We handle fonts by storing the accumulated transform, for example, SR +(accumulating on the right). Then when we map the font through space TD, +for example, we multiply the accumulated font transform on the left by +the space transform on the right, yielding SRTD in this case. We will +get the same result if we did S, then R, then T on the space and mapping +an unmodified font through that space. +*/ + +struct xobject * +t1_Xform(struct xobject *obj, /* object to transform */ + double M[2][2]) /* transformation matrix */ +{ + if (obj == NULL) + return(NULL); + + if (obj->type == FONTTYPE) { + register struct font *F = (struct font *) obj; + + F = UniqueFont(F); + return((struct xobject*)F); + } + if (obj->type == PICTURETYPE) { +/* +In the case of a picture, we choose both to update the picture's +transformation matrix and keep the handles up to date. +*/ + register struct picture *P = (struct picture *) obj; + register struct segment *handles; /* temporary path to transform handles */ + + P = UniquePicture(P); + handles = PathSegment(LINETYPE, P->origin.x, P->origin.y); + handles = Join(handles, + PathSegment(LINETYPE, P->ending.x, P->ending.y) ); + handles = (struct segment *)Xform((struct xobject *) handles, M); + P->origin = handles->dest; + P->ending = handles->link->dest; + KillPath(handles); + return((struct xobject *)P); + } + + if (ISPATHTYPE(obj->type)) { + struct XYspace pseudo; /* local temporary space */ + PseudoSpace(&pseudo, M); + return((struct xobject *) PathTransform((struct segment *)obj, + &pseudo)); + } + + + if (obj->type == SPACETYPE) { + register struct XYspace *S = (struct XYspace *) obj; + +/* replaced ISPERMANENT(S->flag) with S->references > 1 3-26-91 PNM */ + if (S->references > 1) + S = CopySpace(S); + else + S->ID = NEXTID; + + MatrixMultiply(S->tofract.normal, M, S->tofract.normal); + /* + * mark inverted matrix invalid: + */ + S->flag &= ~HASINVERSE(ON); + + FillOutFcns(S); + return((struct xobject *) S); + } + + return(ArgErr("Untransformable object", obj, obj)); +} + +/* +:h3.Transform() - Transform an Object + +This is the external user's entry point. +*/ +struct xobject * +t1_Transform(struct xobject *obj, + double cxx, double cyx, /* 2x2 transform matrix elements */ + double cxy, double cyy) /* in row order */ +{ + double M[2][2]; + + M[0][0] = cxx; + M[0][1] = cyx; + M[1][0] = cxy; + M[1][1] = cyy; + ConsiderContext(obj, M); + return(Xform(obj, M)); +} +/* +:h3.Scale() - Special Case of Transform() + +This is a user operator. +*/ + +struct xobject * +t1_Scale(struct xobject *obj, /* object to scale */ + double sx, double sy) /* scale factors in x and y */ +{ + double M[2][2]; + + M[0][0] = sx; + M[1][1] = sy; + M[1][0] = M[0][1] = 0.0; + ConsiderContext(obj, M); + return(Xform(obj, M)); +} + +/* +:h3 id=rotate.Rotate() - Special Case of Transform() + +We special-case different settings of 'degrees' for performance +and accuracy within the DegreeSin() and DegreeCos() routines themselves. +*/ + +#ifdef notdef +struct xobject * +xiRotate(struct xobject *obj, /* object to be transformed */ + double degrees) /* degrees of COUNTER-clockwise rotation */ +{ + double M[2][2]; + + M[0][0] = M[1][1] = DegreeCos(degrees); + M[1][0] = - (M[0][1] = DegreeSin(degrees)); + ConsiderContext(obj, M); + return(Xform(obj, M)); +} +#endif + +/* +:h3.PseudoSpace() - Build a Coordinate Space from a Matrix + +Since we have built all this optimized code that, given an (x,y) and +a coordinate space, yield transformed (x,y), it seems a shame not to +use the same logic when we need to multiply an (x,y) by an arbitrary +matrix that is not (initially) part of a coordinate space. This +subroutine takes the arbitrary matrix and builds a coordinate +space, with all its nifty function pointers. +*/ + +void +PseudoSpace(struct XYspace *S, /* coordinate space structure to fill out */ + double M[2][2]) /* matrix that will become 'tofract.normal' */ +{ + S->type = SPACETYPE; + S->flag = ISPERMANENT(ON) + ISIMMORTAL(ON); + S->references = 2; /* 3-26-91 added PNM */ + S->tofract.normal[0][0] = M[0][0]; + S->tofract.normal[1][0] = M[1][0]; + S->tofract.normal[0][1] = M[0][1]; + S->tofract.normal[1][1] = M[1][1]; + + FillOutFcns(S); +} + +/* +:h2 id=matrixa.Matrix Arithmetic + +Following the convention in Newman and Sproull, :hp1/Interactive +Computer Graphics/, +matrices are organized: +:xmp. + | cxx cyx | + | cxy cyy | +:exmp. +A point is horizontal, for example: +:xmp. + [ x y ] +:exmp. +This means that: +:formula/x prime = cxx times x + cxy times y/ +:formula/y prime = cyx times x + cyy times y/ +I've seen the other convention, where transform matrices are +transposed, equally often in the literature. +*/ + +/* +:h3.MatrixMultiply() - Implements Multiplication of Two Matrices + +Implements matrix multiplication, A * B = C. + +To remind myself, matrix multiplication goes rows of A times columns +of B. +The output matrix may be the same as one of the input matrices. +*/ +void +MatrixMultiply(double A[2][2], double B[2][2], /* input matrices */ + double C[2][2]) /* output matrix */ +{ + register double txx,txy,tyx,tyy; + + txx = A[0][0] * B[0][0] + A[0][1] * B[1][0]; + txy = A[1][0] * B[0][0] + A[1][1] * B[1][0]; + tyx = A[0][0] * B[0][1] + A[0][1] * B[1][1]; + tyy = A[1][0] * B[0][1] + A[1][1] * B[1][1]; + + C[0][0] = txx; + C[1][0] = txy; + C[0][1] = tyx; + C[1][1] = tyy; +} +/* +:h3.MatrixInvert() - Invert a Matrix + +My reference for matrix inversion was :hp1/Elementary Linear Algebra/ +by Paul C. Shields, Worth Publishers, Inc., 1968. +*/ +void +MatrixInvert(double M[2][2], /* input matrix */ + double Mprime[2][2]) /* output inverted matrix */ +{ + register double D; /* determinant of matrix M */ + register double txx,txy,tyx,tyy; + + txx = M[0][0]; + txy = M[1][0]; + tyx = M[0][1]; + tyy = M[1][1]; + + D = M[1][1] * M[0][0] - M[1][0] * M[0][1]; + if (D == 0.0) + Abort("MatrixInvert: can't"); + + Mprime[0][0] = tyy / D; + Mprime[1][0] = -txy / D; + Mprime[0][1] = -tyx / D; + Mprime[1][1] = txx / D; +} +/* +:h2.Initialization, Queries, and Debug +*/ +/* +:h3.InitSpaces() - Initialize Constant Spaces + +For compatibility, we initialize a coordinate space called USER which +maps 72nds of an inch to pels on the default device. +*/ + +struct XYspace *USER = &identity; + +void +InitSpaces(void) +{ + IDENTITY->type = SPACETYPE; + FillOutFcns(IDENTITY); + + contexts[NULLCONTEXT].normal[1][0] + = contexts[NULLCONTEXT].normal[0][1] + = contexts[NULLCONTEXT].inverse[1][0] + = contexts[NULLCONTEXT].inverse[0][1] = 0.0; + contexts[NULLCONTEXT].normal[0][0] + = contexts[NULLCONTEXT].normal[1][1] + = contexts[NULLCONTEXT].inverse[0][0] + = contexts[NULLCONTEXT].inverse[1][1] = 1.0; + + USER->flag |= ISIMMORTAL(ON); + CoerceInverse(USER); +} +/* +:h3.QuerySpace() - Returns the Transformation Matrix of a Space + +Since the tofract matrix of an XYspace includes the scale factor +necessary to produce fractpel results (i.e., FRACTFLOAT), this +must be taken out before we return the matrix to the user. Fortunately, +this is simple: just multiply by the inverse of IDENTITY! +*/ + +void +QuerySpace(struct XYspace *S, /* space asked about */ + double *cxxP, double *cyxP, /* where to put answer */ + double *cxyP, double *cyyP) +{ + double M[2][2]; /* temp matrix to build user's answer */ + + if (S->type != SPACETYPE) { + ArgErr("QuerySpace: not a space", S, NULL); + return; + } + MatrixMultiply(S->tofract.normal, IDENTITY->tofract.inverse, M); + *cxxP = M[0][0]; + *cxyP = M[1][0]; + *cyxP = M[0][1]; + *cyyP = M[1][1]; +} + +/* +:h3.FormatFP() - Format a Fixed Point Pel + +We format the pel as "dddd.XXXX", where XX's are hexidecimal digits, +and the dd's are decimal digits. This might be a little confusing +mixing hexidecimal and decimal like that, but it is convenient +to use for debug. + +We make sure we have N (FRACTBITS/4) digits past the decimal point. +*/ +#define FRACTMASK ((1<<FRACTBITS)-1) /* mask for fractional part */ + +void +FormatFP(char *string, /* output string */ + fractpel fpel) /* fractional pel input */ +{ + char temp[8]; + register char *s; + register char *sign; + + if (fpel < 0) { + sign = "-"; + fpel = -fpel; + } + else + sign = ""; + + sprintf(temp, "000%lx", fpel & FRACTMASK); + s = temp + strlen(temp) - (FRACTBITS/4); + + sprintf(string, "%s%d.%sx", sign, (int)(fpel >> FRACTBITS), s); +} + +/* +:h3.DumpSpace() - Display a Coordinate Space +*/ +/*ARGSUSED*/ +void +DumpSpace(struct XYspace *S) +{ +} diff --git a/nx-X11/lib/font/Type1/spaces.h b/nx-X11/lib/font/Type1/spaces.h new file mode 100644 index 000000000..ef78f2f47 --- /dev/null +++ b/nx-X11/lib/font/Type1/spaces.h @@ -0,0 +1,172 @@ +/* $Xorg: spaces.h,v 1.3 2000/08/17 19:46:32 cpqbld Exp $ */ +/* Copyright International Business Machines, Corp. 1991 + * All Rights Reserved + * Copyright Lexmark International, Inc. 1991 + * All Rights Reserved + * + * License to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, + * provided that the above copyright notice appear in all copies and that + * both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of IBM or Lexmark not be + * used in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * + * IBM AND LEXMARK PROVIDE THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES OF + * ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO ANY + * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, + * AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE + * QUALITY AND PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT + * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF THE + * SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM OR LEXMARK) ASSUMES THE + * ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN NO EVENT SHALL + * IBM OR LEXMARK BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF + * THIS SOFTWARE. + */ +/* $XFree86: xc/lib/font/Type1/spaces.h,v 3.3 1999/08/22 08:58:53 dawes Exp $ */ + +/*SHARED*/ + +#define USER t1_User +#define IDENTITY t1_Identity + +#define Context(d,u) t1_Context(d,u) +#define Transform(o,f1,f2,f3,f4) t1_Transform(o,f1,f2,f3,f4) +#define Rotate(o,d) t1_Rotate(o,d) +#define Scale(o,sx,sy) t1_Scale(o,sx,sy) +#define QuerySpace(S,f1,f2,f3,f4) t1_QuerySpace(S,f1,f2,f3,f4) +#define Warp(s1,o,s2) t1_Warp(s1,o,s2) + +/* IDENTITY space */ +extern struct XYspace *IDENTITY; + +/* creates a coordinate space for a device */ +extern struct XYspace *Context(pointer device, double units); +/* transform an object */ +extern struct xobject *t1_Transform ( struct xobject *obj, double cxx, + double cyx, double cxy, double cyy ); +#if 0 +struct xobject *t1_Rotate(); /* rotate an object */ +#endif +/* scale an object */ +extern struct xobject *t1_Scale ( struct xobject *obj, double sx, double sy ); +#if 0 +struct xobject *t1_Warp(); /* transform like delta of two spaces */ +#endif +/* returns coordinate space matrix */ +extern void t1_QuerySpace ( struct XYspace *S, double *cxxP, double *cyxP, + double *cxyP, double *cyyP ); + +/*END SHARED*/ +/*SHARED*/ + +/* #define KillSpace(s) Free(s) +Note - redefined KillSpace() to check references ! +3-26-91 PNM */ + +#define KillSpace(s) if ( (--(s->references) == 0) ||\ + ( (s->references == 1) && ISPERMANENT(s->flag) ) )\ + Free(s) + +#define ConsumeSpace(s) MAKECONSUME(s,KillSpace(s)) +#define UniqueSpace(s) MAKEUNIQUE(s,CopySpace(s)) + +/*END SHARED*/ +/*SHARED*/ + +typedef short pel; /* integer pel locations */ +typedef long fractpel; /* fractional pel locations */ + +#define FRACTBITS 16 /* number of fractional bits in 'fractpel' */ +/* +We define the following macros to convert from 'fractpel' to 'pel' and +vice versa: +*/ +#define TOFRACTPEL(p) (((fractpel)p)<<FRACTBITS) +#define FPHALF (1<<(FRACTBITS-1)) +#define NEARESTPEL(fp) (((fp)+FPHALF)>>FRACTBITS) +#define FRACTFLOAT (double)(1L<<FRACTBITS) + +/*END SHARED*/ +/*SHARED*/ + +struct doublematrix { + double normal[2][2]; + double inverse[2][2]; +} ; + +/*END SHARED*/ +/*SHARED*/ + +struct fractpoint { + fractpel x,y; +} ; + +/*SHARED*/ + +typedef fractpel (*convertFunc)(double, double, double, double); +typedef fractpel (*iconvertFunc)(fractpel, fractpel, long, long); + +struct XYspace { + XOBJ_COMMON /* xobject common data define 3-26-91 PNM */ + /* type = SPACETYPE */ + void (*convert)(struct fractpoint *, struct XYspace *, double, double); /* calculate "fractpoint" X,Y from float X,Y */ + void (*iconvert)(struct fractpoint *, struct XYspace *, long, long); /* calculate "fractpoint" X,Y from int X,Y */ + convertFunc xconvert; /* subroutine of convert */ + convertFunc yconvert; /* subroutine of convert */ + iconvertFunc ixconvert; /* subroutine of iconvert */ + iconvertFunc iyconvert; /* subroutine of iconvert */ + int ID; /* unique identifier (used in font caching) */ + unsigned char context; /* device context of coordinate space */ + struct doublematrix tofract; /* xform to get to fractional pels */ + fractpel itofract[2][2]; /* integer version of "tofract.normal" */ +} ; + +#define INVALIDID 0 /* no valid space will have this ID */ + +/*END SHARED*/ +/*END SHARED*/ +/*SHARED*/ + +#define DeviceResolution t1_DeviceResolution +#define InitSpaces t1_InitSpaces +#define CopySpace(s) t1_CopySpace(s) +#define Xform(o,M) t1_Xform(o,M) +#define UnConvert(S,pt,xp,yp) t1_UnConvert(S,pt,xp,yp) +#define MatrixMultiply(A,B,C) t1_MMultiply(A,B,C) +#define MatrixInvert(A,B) t1_MInvert(A,B) +#define PseudoSpace(S,M) t1_PseudoSpace(S,M) +#define FindContext(M) t1_FindContext(M) + +/* initialize pre-defined coordinate spaces */ +extern void t1_InitSpaces ( void ); +/* duplicate a coordinate space */ +extern struct XYspace *t1_CopySpace ( struct XYspace *S ); +/* transform object by matrix */ +extern struct xobject *t1_Xform ( struct xobject *obj, double M[2][2] ); +/* return user coordinates from device coordinates */ +extern void t1_UnConvert ( struct XYspace *S, struct fractpoint *pt, + double *xp, double *yp ); +/* multiply two matrices */ +extern void t1_MMultiply ( double A[2][2], double B[2][2], double C[2][2] ); +/* invert a matrix */ +extern void t1_MInvert ( double M[2][2], double Mprime[2][2] ); +/* force a coordinate space from a matrix */ +extern void t1_PseudoSpace ( struct XYspace *S, double M[2][2] ); +/* return the "context" represented by a matrix */ +int t1_FindContext(double M[2][2]); + +/*END SHARED*/ +/*SHARED*/ + +#define NULLCONTEXT 0 + +/*END SHARED*/ + +/* dump a coordinate space structure */ +extern void t1_DumpSpace ( struct XYspace *S ); +/* dump a format a "fractpel" coordinate */ +extern void t1_FormatFP ( char *string, fractpel fpel ); diff --git a/nx-X11/lib/font/Type1/strokes.h b/nx-X11/lib/font/Type1/strokes.h new file mode 100644 index 000000000..c374e16db --- /dev/null +++ b/nx-X11/lib/font/Type1/strokes.h @@ -0,0 +1,38 @@ +/* $Xorg: strokes.h,v 1.3 2000/08/17 19:46:32 cpqbld Exp $ */ +/* Copyright International Business Machines,Corp. 1991 + * All Rights Reserved + * + * License to use, copy, modify, and distribute this software + * and its documentation for any purpose and without fee is + * hereby granted, provided that the above copyright notice + * appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, + * and that the name of IBM not be used in advertising or + * publicity pertaining to distribution of the software without + * specific, written prior permission. + * + * IBM PROVIDES THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES + * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT + * LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE QUALITY AND + * PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT + * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF + * THE SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM) ASSUMES + * THE ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN + * NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ +/*STUB*/ + +#define CopyLineStyle(s) s +#define CopyStrokePath(p) p +#define KillStrokePath(p) +#define KillLineStyle(s) +#define CoercePath(sp) sp +#define DoStroke(sp) sp + diff --git a/nx-X11/lib/font/Type1/t1funcs.c b/nx-X11/lib/font/Type1/t1funcs.c new file mode 100644 index 000000000..9de819a0d --- /dev/null +++ b/nx-X11/lib/font/Type1/t1funcs.c @@ -0,0 +1,1668 @@ +/* $Xorg: t1funcs.c,v 1.5 2001/02/09 02:04:01 xorgcvs Exp $ */ +/* Copyright International Business Machines,Corp. 1991 + * All Rights Reserved + * + * License, subject to the license given below, to use, + * copy, modify, and distribute this software * and its + * documentation for any purpose and without fee is hereby + * granted, provided that the above copyright notice appear + * in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, + * and that the name of IBM not be used in advertising or + * publicity pertaining to distribution of the software + * without specific, written prior permission. + * + * IBM PROVIDES THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES + * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT + * LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE QUALITY AND + * PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT + * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF + * THE SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM) ASSUMES + * THE ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN + * NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + * + * Author: Jeffrey B. Lotspiech, IBM Almaden Research Center + * Modeled on spfuncs.c by Dave Lemke, Network Computing Devices, Inc + * which contains the following copyright and permission notices: + * + * Copyright 1990, 1991 Network Computing Devices; + * Portions Copyright 1987 by Digital Equipment Corporation + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the names of Network Computing Devices + * or Digital not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior permission. + * Network Computing Devices or Digital make no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * NETWORK COMPUTING DEVICES AND DIGITAL DISCLAIM ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES OR DIGITAL BE + * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +/* Copyright (c) 1994-1999 Silicon Graphics, Inc. All Rights Reserved. + * + * The contents of this file are subject to the CID Font Code Public Licence + * Version 1.0 (the "License"). You may not use this file except in compliance + * with the Licence. You may obtain a copy of the License at Silicon Graphics, + * Inc., attn: Legal Services, 2011 N. Shoreline Blvd., Mountain View, CA + * 94043 or at http://www.sgi.com/software/opensource/cid/license.html. + * + * Software distributed under the License is distributed on an "AS IS" basis. + * ALL WARRANTIES ARE DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED + * WARRANTIES OF MERCHANTABILITY, OF FITNESS FOR A PARTICULAR PURPOSE OR OF + * NON-INFRINGEMENT. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Software is CID font code that was developed by Silicon + * Graphics, Inc. + */ +/* $XFree86: xc/lib/font/Type1/t1funcs.c,v 3.33 2003/07/19 13:16:40 tsi Exp $ */ + +/* + +Copyright 1987, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + +*/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#ifdef BUILDCID +#define XFONT_CID 1 +#endif + +#ifndef FONTMODULE +#include <string.h> +#if XFONT_CID +#include <stdlib.h> +#include <sys/types.h> +#include <dirent.h> +#endif +#ifdef _XOPEN_SOURCE +#include <math.h> +#else +#define _XOPEN_SOURCE /* to get prototype for hypot on some systems */ +#include <math.h> +#undef _XOPEN_SOURCE +#endif +#include "X11/Xfuncs.h" +#ifdef USE_MMAP +#include <sys/types.h> +#include <sys/mman.h> +#endif +#else +#include "Xmd.h" +#include "Xdefs.h" +#endif + +#ifdef FONTMODULE +#include "os.h" +#include "xf86_ansic.h" +#endif + +#include <X11/fonts/fntfilst.h> +#include <X11/fonts/fontutil.h> +#include <X11/fonts/FSproto.h> +#include <X11/fonts/fontenc.h> +#include "t1unicode.h" + +#if XFONT_CID +#include "range.h" +#endif + +#include "objects.h" +#include "spaces.h" +#include "paths.h" +#include "regions.h" +#include "t1stdio.h" +#include "util.h" +#include "fontfcn.h" +#include "t1intf.h" + + +static int Type1GetGlyphs ( FontPtr pFont, unsigned long count, + unsigned char *chars, FontEncoding charEncoding, + unsigned long *glyphCount, CharInfoPtr *glyphs ); + +#if XFONT_CID +#define CMapDir "/CMap/" +#define CFMDir "/CFM/" +#define CIDFontDir "/CIDFont/" +#endif + +static int Type1GetMetrics ( FontPtr pFont, unsigned long count, + unsigned char *chars, + FontEncoding charEncoding, + unsigned long *glyphCount, + xCharInfo **glyphs ); + + +#define minchar(p) ((p).min_char_low + ((p).min_char_high << 8)) +#define maxchar(p) ((p).max_char_low + ((p).max_char_high << 8)) + +static void fillrun ( char *p, pel x0, pel x1, int bit ); + +extern psfont *FontP; +extern psobj *ISOLatin1EncArrayP; + +#if XFONT_CID +extern char CurCIDFontName[]; +extern char CurCMapName[]; + +static CharInfoPtr CIDGetGlyph ( FontPtr pFont, unsigned int charcode, + CharInfoPtr pci ); + +extern cidfont *CIDFontP; +extern cmapres *CMapP; +#endif + +static void fill ( char *dest, int h, int w, struct region *area, int byte, + int bit, int wordsize ); + +#if XFONT_CID +int +CIDOpenScalable (FontPathElementPtr fpe, + FontPtr *ppFont, + int flags, + FontEntryPtr entry, + char *fileName, + FontScalablePtr vals, + fsBitmapFormat format, + fsBitmapFormatMask fmask, + FontPtr non_cachable_font) /* We don't do licensing */ +{ + FontPtr pFont; + int bit, + byte, + glyph, + scan, + image; + long *pool; /* memory pool for ximager objects */ + int size; /* for memory size calculations */ + struct XYspace *S; /* coordinate space for character */ + register int i; + int nchars, len, rc; + cidglyphs *cid; + char *p; + double t1 = .001, t2 = 0.0, t3 = 0.0, t4 = .001; + double sxmult; + char CIDFontName[CID_NAME_MAX]; + char CMapName[CID_NAME_MAX]; + char cidfontname[CID_PATH_MAX]; + char cmapname[CID_PATH_MAX]; + char *path; + char cidfontpath[CID_PATH_MAX]; + char cmappath[CID_PATH_MAX]; +#if defined(HAVE_CFM) || defined(CID_ALL_CHARS) + char cfmdir[CID_PATH_MAX]; + char cfmfilename[CID_NAME_MAX]; +#endif +#if defined(CID_ALL_CHARS) + char *cf; +#else + long sAscent, sDescent; +#endif + + /* check the font name */ + len = strlen(fileName); + if (len <= 0 || len > CID_NAME_MAX - 1) + return BadFontName; + +#if defined(HAVE_CFM) || defined(CID_ALL_CHARS) + strcpy(cfmdir, fileName); + p = strrchr(cfmdir, '/'); + if (p) *p = '\0'; +#endif + + path = fileName; + if (!(fileName = strrchr(fileName, '/'))) + return BadFontName; + + len = fileName - path; + strncpy(cidfontpath, path, len); + cidfontpath[len] = '\0'; + strcpy(cmappath, cidfontpath); + strcat(cmappath, CMapDir); +#ifdef HAVE_CFM + strcpy(cfmdir, cidfontpath); + strcat(cfmdir, CFMDir); +#endif + strcat(cidfontpath, CIDFontDir); + + fileName++; + + /* extract the CIDFontName and CMapName from the font name */ + /* check for <CIDFontName>--<CMapName> */ + if ((p = strstr(fileName, "--"))) { + if (p == fileName) + return BadFontName; + else { + strcpy(CIDFontName, fileName); + CIDFontName[p - fileName] = '\0'; + p += 2; + i = 0; + while (*p && *p != '.') + CMapName[i++] = *p++; + CMapName[i] = '\0'; + if ((len = strlen(CMapName)) <= 0) + return BadFontName; + } + } else + return BadFontName; + + /* The CMap files whose names end with -V are not yet supported */ + len = strlen(CMapName); + if ((len >= 2 && CMapName[len - 2] == '-' && CMapName[len - 1] == 'V') || + (len == 1 && CMapName[len - 1] == 'V')) + return BadFontName; + + /* Reject ridiculously small font sizes that will blow up the math */ + if (hypot(vals->pixel_matrix[0], vals->pixel_matrix[1]) < 1.0 || + hypot(vals->pixel_matrix[2], vals->pixel_matrix[3]) < 1.0) + return BadFontName; + +#ifdef CID_ALL_CHARS + if ((cf = getenv("CFMDIR")) == NULL) + strcat(cfmdir, CFMDir); + else { + strcpy(cfmdir, cf); + strcat(cfmdir, "/"); + } +#endif + +#if defined(HAVE_CFM) || defined(CID_ALL_CHARS) + strcpy(cfmfilename, cfmdir); + strcat(cfmfilename, CIDFontName); + strcat(cfmfilename, "--"); + strcat(cfmfilename, CMapName); + strcat(cfmfilename, ".cfm"); +#endif + + /* create a full-path name for a CIDFont file */ + if (strlen(cidfontpath) + strlen(CIDFontName) + 2 > + CID_PATH_MAX) + return BadFontName; + strcpy(cidfontname, cidfontpath); + strcat(cidfontname, CIDFontName); + + /* create a full-path name for a CMap file */ + if (strlen(cmappath) + strlen(CMapName) + 2 > CID_PATH_MAX) + return BadFontName; + strcpy(cmapname, cmappath); + strcat(cmapname, CMapName); + + /* set up default values */ + FontDefaultFormat(&bit, &byte, &glyph, &scan); + /* get any changes made from above */ + rc = CheckFSFormat(format, fmask, &bit, &byte, &scan, &glyph, &image); + if (rc != Successful) + return rc; + +#define PAD(bits, pad) (((bits)+(pad)-1)&-(pad)) + + if (!(pFont = CreateFontRec())) + return AllocError; + + cid = (cidglyphs *)xalloc(sizeof(cidglyphs)); + if (cid == NULL) { + DestroyFontRec(pFont); + return AllocError; + } + bzero(cid, sizeof(cidglyphs)); + + /* heuristic for "maximum" size of pool we'll need: */ + size = 200000 + 600 * + (int)hypot(vals->pixel_matrix[2], vals->pixel_matrix[3]) + * sizeof(short); + if (size < 0 || NULL == (pool = (long *) xalloc(size))) { + xfree(cid); + DestroyFontRec(pFont); + return AllocError; + } + + addmemory(pool, size); + + /* load font if not already loaded */ + if (!CIDfontfcnA(cidfontname, cmapname, &rc)) { + FontP = NULL; + delmemory(); + xfree(pool); + xfree(cid); + DestroyFontRec(pFont); + return Type1ReturnCodeToXReturnCode(rc); + } + + FontP = NULL; + + S = (struct XYspace *) t1_Transform((struct xobject *)IDENTITY, + t1, t2, t3, t4); + + S = (struct XYspace *) Permanent(t1_Transform((struct xobject *)S, + vals->pixel_matrix[0], + -vals->pixel_matrix[1], + vals->pixel_matrix[2], + -vals->pixel_matrix[3])); + + /* multiplier for computation of raw values */ + sxmult = hypot(vals->pixel_matrix[0], vals->pixel_matrix[1]); + if (sxmult > EPS) sxmult = 1000.0 / sxmult; + + pFont->info.firstRow = CMapP->firstRow; + pFont->info.firstCol = CMapP->firstCol; + pFont->info.lastRow = CMapP->lastRow; + pFont->info.lastCol = CMapP->lastCol; + + nchars = (pFont->info.lastRow - pFont->info.firstRow + 1) * + (pFont->info.lastCol - pFont->info.firstCol + 1); + + delmemory(); + xfree(pool); + + if (pFont->info.firstCol > pFont->info.lastCol) + { + xfree(cid); + DestroyFontRec(pFont); + return BadFontName; + } + + cid->glyphs = (CharInfoRec **)xalloc(nchars*sizeof(CharInfoRec *)); + if (cid->glyphs == NULL) { + xfree(cid); + DestroyFontRec(pFont); + return AllocError; + } + bzero(cid->glyphs, nchars*sizeof(CharInfoRec *)); + + pFont->info.defaultCh = 0; + pFont->format = format; + + pFont->bit = bit; + pFont->byte = byte; + pFont->glyph = glyph; + pFont->scan = scan; + + pFont->get_metrics = CIDGetMetrics; + pFont->get_glyphs = CIDGetGlyphs; + pFont->unload_font = CIDCloseFont; + pFont->unload_glyphs = NULL; + pFont->refcnt = 0; + + len = strlen(cidfontname); + cid->CIDFontName = (char *)xalloc(len + 1); + if (cid->CIDFontName == NULL) { + xfree(cid->glyphs); + xfree(cid); + DestroyFontRec(pFont); + return AllocError; + } + strcpy(cid->CIDFontName, cidfontname); + + len = strlen(cmapname); + cid->CMapName = (char *)xalloc(len + 1); + if (cid->CMapName == NULL) { + xfree(cid->CIDFontName); + xfree(cid->glyphs); + xfree(cid); + DestroyFontRec(pFont); + return AllocError; + } + strcpy(cid->CMapName, cmapname); + + cid->pixel_matrix[0] = vals->pixel_matrix[0]; + cid->pixel_matrix[1] = vals->pixel_matrix[1]; + cid->pixel_matrix[2] = vals->pixel_matrix[2]; + cid->pixel_matrix[3] = vals->pixel_matrix[3]; + + pFont->fontPrivate = (unsigned char *)cid; + + pFont->info.fontAscent = + (CIDFontP->CIDfontInfoP[CIDFONTBBOX].value.data.arrayP[3].data.integer * + vals->pixel_matrix[3] + + (CIDFontP->CIDfontInfoP[CIDFONTBBOX].value.data.arrayP[3].data.integer > + 0 ? 500 : -500)) / 1000; + + pFont->info.fontDescent = + -(int)((double)CIDFontP->CIDfontInfoP[CIDFONTBBOX].value.data.arrayP[1].data.integer + * vals->pixel_matrix[3] + + (CIDFontP->CIDfontInfoP[CIDFONTBBOX].value.data.arrayP[1].data.integer > + 0 ? 500 : -500)) / 1000; + + /* Adobe does not put isFixedPitch entries in CID-keyed fonts. */ + /* CID-keyed are not constant-width fonts. */ + pFont->info.constantWidth = 0; + +#ifndef CID_ALL_CHARS + sAscent = CIDFontP->CIDfontInfoP[CIDFONTBBOX].value.data.arrayP[3].data.integer; + sDescent = -CIDFontP->CIDfontInfoP[CIDFONTBBOX].value.data.arrayP[1].data.integer; +#endif + + if (strncmp(entry->name.name, "-bogus", 6)) { +#ifdef CID_ALL_CHARS + ComputeBoundsAllChars(pFont, cfmfilename, sxmult); +#else +#ifdef HAVE_CFM + CIDFillFontInfo(pFont, vals, cidfontname, entry->name.name, cmapname, + cfmfilename, sAscent, sDescent, sxmult); +#else + CIDFillFontInfo(pFont, vals, cidfontname, entry->name.name, cmapname, + sAscent, sDescent, sxmult); +#endif /* HAVE_CFM */ +#endif /* CID_ALL_CHARS */ + } + + *ppFont = pFont; + + return Successful; +} +#endif + +/*ARGSUSED*/ +int +Type1OpenScalable (FontPathElementPtr fpe, + FontPtr *ppFont, + int flags, + FontEntryPtr entry, + char *fileName, + FontScalablePtr vals, + fsBitmapFormat format, + fsBitmapFormatMask fmask, + FontPtr non_cachable_font) /* We don't do licensing */ +{ + FontPtr pFont; + int bit, + byte, + glyph, + scan, + image; + int pad,wordsize; /* scan & image in bits */ + long *pool; /* memory pool for ximager objects */ + int size; /* for memory size calculations */ + struct XYspace *S; /* coordinate space for character */ + struct region *area; + CharInfoRec *glyphs; + int len, rc, count = 0, i = 0; + struct type1font *type1; + char *p; + FontMapPtr mapping = NULL; + int no_mapping; + psobj *fontmatrix; + long x0, total_width = 0, total_raw_width = 0; + double x1, y1, t1 = .001, t2 = 0.0, t3 = 0.0, t4 = .001; + double sxmult; + + /* Reject ridiculously small font sizes that will blow up the math */ + if (hypot(vals->pixel_matrix[0], vals->pixel_matrix[1]) < 1.0 || + hypot(vals->pixel_matrix[2], vals->pixel_matrix[3]) < 1.0) + return BadFontName; + + /* set up default values */ + FontDefaultFormat(&bit, &byte, &glyph, &scan); + /* get any changes made from above */ + rc = CheckFSFormat(format, fmask, &bit, &byte, &scan, &glyph, &image); + if (rc != Successful) + return rc; + + pad = glyph * 8; + wordsize = scan * 8; + +#define PAD(bits, pad) (((bits)+(pad)-1)&-(pad)) + + pFont = CreateFontRec(); + if (pFont == NULL) + return AllocError; + + type1 = (struct type1font *)xalloc(sizeof(struct type1font)); + if (type1 == NULL) { + DestroyFontRec(pFont); + return AllocError; + } + bzero(type1, sizeof(struct type1font)); + + /* heuristic for "maximum" size of pool we'll need: */ +#if XFONT_CID + size = 400000 + 600 * +#else + size = 200000 + 600 * +#endif + (int)hypot(vals->pixel_matrix[2], vals->pixel_matrix[3]) + * sizeof(short); + if (size < 0 || NULL == (pool = (long *) xalloc(size))) { + xfree(type1); + DestroyFontRec(pFont); + return AllocError; + } + + addmemory(pool, size); + + + glyphs = type1->glyphs; + + /* load font if not already loaded */ + if (!fontfcnA(fileName, &rc)) { + delmemory(); + xfree(type1); + DestroyFontRec(pFont); + xfree(pool); + return Type1ReturnCodeToXReturnCode(rc); + } + + fontmatrix = &FontP->fontInfoP[FONTMATRIX].value; + if (objPIsArray(fontmatrix) && fontmatrix->len == 6) + { +#define assign(n,d,f) if (objPIsInteger(fontmatrix->data.arrayP + n)) \ + d = fontmatrix->data.arrayP[n].data.integer; \ + else if (objPIsReal(fontmatrix->data.arrayP + n)) \ + d = fontmatrix->data.arrayP[n].data.real; \ + else d = f; + + assign(0, t1, .001); + assign(1, t2, 0.0); + assign(2, t3, 0.0); + assign(3, t4, .001); + } + + S = (struct XYspace *) t1_Transform((struct xobject *)IDENTITY, + t1, t2, t3, t4); + + S = (struct XYspace *) Permanent(t1_Transform((struct xobject *)S, + vals->pixel_matrix[0], + -vals->pixel_matrix[1], + vals->pixel_matrix[2], + -vals->pixel_matrix[3])); + + + /* multiplier for computation of raw values */ + sxmult = hypot(vals->pixel_matrix[0], vals->pixel_matrix[1]); + if (sxmult > EPS) sxmult = 1000.0 / sxmult; + + no_mapping=0; + p = FontEncFromXLFD(entry->name.name, entry->name.length); + + if(p==0) { /* XLFD does not specify an encoding */ + mapping=0; + no_mapping=2; /* ISO 8859-1 */ + } + + if(!strcmp(p, "adobe-fontspecific")) { + mapping=0; + no_mapping=1; /* font's native encoding vector */ + } + + pFont->info.firstCol = 255; + pFont->info.lastCol = 0; + + if(!no_mapping) { + mapping = FontEncMapFind(p, + FONT_ENCODING_POSTSCRIPT, -1, -1, + fileName); + if(!mapping) + mapping = FontEncMapFind(p, + FONT_ENCODING_UNICODE, -1, -1, + fileName); + if(!mapping) + goto NoEncoding; + else + no_mapping=0; + } + + for (i=0; i < 256; i++) { + long h,w; + long paddedW; + int j; + char *codename; + + if(no_mapping == 1) { + codename = FontP->fontInfoP[ENCODING]. + value.data.arrayP[i].data.valueP; + len = FontP->fontInfoP[ENCODING]. + value.data.arrayP[i].len; + } else if(no_mapping) { + codename = unicodetoPSname(i); + len = codename ? strlen(codename) : 0; + } else { + if(mapping->type == FONT_ENCODING_UNICODE) { + codename = unicodetoPSname(FontEncRecode(i, mapping)); + } else + codename = FontEncName(i, mapping); + len=codename?strlen(codename):0; + } + + /* Avoid multiply rasterising the undefined glyph */ + if(len==7 && !strncmp(codename, ".notdef", 7)) { + len=0; + codename=0; + } + + /* But do rasterise it at least once */ + if(len==0) { + if(i==0) { + codename=".notdef"; + len=7; + } else + continue; + } + + /* See if this character is in the list of ranges specified + in the XLFD name */ + if(i!=0) { + for (j = 0; j < vals->nranges; j++) + if (i >= minchar(vals->ranges[j]) && + i <= maxchar(vals->ranges[j])) + break; + + /* If not, don't realize it. */ + if (vals->nranges && j == vals->nranges) + continue; + } + + rc = 0; + area = (struct region *)fontfcnB(S, (unsigned char *)codename, + &len, &rc); + if (rc < 0) { + rc = Type1ReturnCodeToXReturnCode(rc); + break; + } + else if (rc > 0) + continue; + + if (area == NULL) + continue; + + if (pFont->info.firstCol > i) + pFont->info.firstCol = i; + if (pFont->info.lastCol < i) + pFont->info.lastCol = i; + + h = area->ymax - area->ymin; + w = area->xmax - area->xmin; + paddedW = PAD(w, pad); + + if (h > 0 && w > 0) { + size = h * paddedW / 8; + glyphs[i].bits = (char *)xalloc(size); + if (glyphs[i].bits == NULL) { + rc = AllocError; + break; + } + } + else { + size = 0; + h = w = 0; + area->xmin = area->xmax = 0; + area->ymax = area->ymax = 0; + } + + glyphs[i].metrics.leftSideBearing = area->xmin; + x1 = (double)(x0 = area->ending.x - area->origin.x); + y1 = (double)(area->ending.y - area->origin.y); + glyphs[i].metrics.characterWidth = + (x0 + (x0 > 0 ? FPHALF : -FPHALF)) / (1 << FRACTBITS); + if (!glyphs[i].metrics.characterWidth && size == 0) + { + /* Zero size and zero extents: presumably caused by + the choice of transformation. Let's create a + small bitmap so we're not mistaken for an undefined + character. */ + h = w = 1; + size = paddedW = PAD(w, pad); + glyphs[i].bits = (char *)xalloc(size); + if (glyphs[i].bits == NULL) { + rc = AllocError; + break; + } + } + glyphs[i].metrics.attributes = + NEARESTPEL((long)(hypot(x1, y1) * sxmult)); + total_width += glyphs[i].metrics.attributes; + total_raw_width += abs((int)(INT16)glyphs[i].metrics.attributes); + count++; + glyphs[i].metrics.rightSideBearing = w + area->xmin; + glyphs[i].metrics.descent = area->ymax - NEARESTPEL(area->origin.y); + glyphs[i].metrics.ascent = h - glyphs[i].metrics.descent; + + + bzero(glyphs[i].bits, size); + if (h > 0 && w > 0) { + fill(glyphs[i].bits, h, paddedW, area, byte, bit, wordsize ); + } + + Destroy(area); + } + NoEncoding: + + delmemory(); + xfree(pool); + + if (pFont->info.firstCol > pFont->info.lastCol) + { + xfree(type1); + DestroyFontRec(pFont); + return BadFontName; + } + + if (i != 256) { + for (i--; i >= 0; i--) + if (glyphs[i].bits != NULL) + xfree(glyphs[i].bits); + xfree(type1); + DestroyFontRec(pFont); + return rc; + } + type1->pDefault = NULL; + + pFont->format = format; + + pFont->bit = bit; + pFont->byte = byte; + pFont->glyph = glyph; + pFont->scan = scan; + + pFont->info.firstRow = 0; + pFont->info.lastRow = 0; + + pFont->get_metrics = Type1GetMetrics; + pFont->get_glyphs = Type1GetGlyphs; + pFont->unload_font = Type1CloseFont; + pFont->unload_glyphs = NULL; + pFont->refcnt = 0; + + pFont->fontPrivate = (unsigned char *) type1; + + if (count) + { + total_raw_width = (total_raw_width * 10 + count / 2) / count; + if (total_width < 0) + { + /* Predominant direction is R->L */ + total_raw_width = -total_raw_width; + } + vals->width = (int)((double)total_raw_width * + vals->pixel_matrix[0] / 1000.0 + + (vals->pixel_matrix[0] > 0 ? .5 : -.5)); + } + + T1FillFontInfo(pFont, vals, fileName, entry->name.name, total_raw_width); + + *ppFont = pFont; + return Successful; +} + +#if XFONT_CID +unsigned int +getCID(FontPtr pFont, unsigned int charcode) +{ + unsigned int cidcode = 0; + Bool charvalid = FALSE; + cidglyphs *cid; + int i, j; + unsigned int char_row, char_col, rangelo_row, rangelo_col, k; + unsigned int rangehi_row, rangehi_col; + spacerange *spacerangeP; + cidrange *notdefrangeP, *cidrangeP; + + cid = (cidglyphs *)pFont->fontPrivate; + + if (cid == NULL) + return cidcode; + + char_row = (charcode >> 8) & 0xff; + char_col = charcode & 0xff; + + spacerangeP = CIDFontP->spacerangeP; + for (i = 0; i < CIDFontP->spacerangecnt; i++) { + for (j = 0; j < spacerangeP->rangecnt; j++) { + rangelo_row = + (spacerangeP->spacecode[j].srcCodeLo >> 8) & 0xff; + rangelo_col = spacerangeP->spacecode[j].srcCodeLo & 0xff; + rangehi_row = + (spacerangeP->spacecode[j].srcCodeHi >> 8) & 0xff; + rangehi_col = spacerangeP->spacecode[j].srcCodeHi & 0xff; + if (char_row >= rangelo_row && char_row <= rangehi_row && + char_col >= rangelo_col && char_col <= rangehi_col) { + charvalid = TRUE; + break; + } + } + if (charvalid) break; + spacerangeP = spacerangeP->next; + } + + if (charvalid) { + charvalid = FALSE; + cidrangeP = CIDFontP->cidrangeP; + for (i = 0; i < CIDFontP->cidrangecnt; i++) { + for (j = 0; j < cidrangeP->rangecnt; j++) { + rangelo_row = + (cidrangeP->range[j].srcCodeLo >> 8) & 0xff; + rangelo_col = cidrangeP->range[j].srcCodeLo & 0xff; + rangehi_row = + (cidrangeP->range[j].srcCodeHi >> 8) & 0xff; + rangehi_col = cidrangeP->range[j].srcCodeHi & 0xff; + if (char_row >= rangelo_row && char_row <= rangehi_row && + char_col >= rangelo_col && char_col <= rangehi_col) { + charvalid = TRUE; + for (k = cidrangeP->range[j].srcCodeLo; + k <= cidrangeP->range[j].srcCodeHi; k++) { + if (k == charcode) + cidcode = cidrangeP->range[j].dstCIDLo + k - + cidrangeP->range[j].srcCodeLo; + } + break; + } + } + if (charvalid) break; + cidrangeP = cidrangeP->next; + } + } + + if (charvalid) { + charvalid = FALSE; + notdefrangeP = CIDFontP->notdefrangeP; + for (i = 0; i < CIDFontP->notdefrangecnt; i++) { + for (j = 0; j < notdefrangeP->rangecnt; j++) { + rangelo_row = + (notdefrangeP->range[j].srcCodeLo >> 8) & 0xff; + rangelo_col = notdefrangeP->range[j].srcCodeLo & 0xff; + rangehi_row = + (notdefrangeP->range[j].srcCodeHi >> 8) & 0xff; + rangehi_col = notdefrangeP->range[j].srcCodeHi & 0xff; + if (char_row >= rangelo_row && char_row <= rangehi_row && + char_col >= rangelo_col && char_col <= rangehi_col) { + charvalid = TRUE; + for (k = notdefrangeP->range[j].srcCodeLo; + k <= notdefrangeP->range[j].srcCodeHi; k++) { + if (k == charcode) + /* the whole range is mapped to a single CID code */ + cidcode = notdefrangeP->range[j].dstCIDLo; + } + break; + } + } + if (charvalid) break; + notdefrangeP = notdefrangeP->next; + } + } + + /* If you specify a CMap that has more CIDs than a specified CIDFont, */ + /* the program could go beyond the number of entries in CIDMap. Make */ + /* sure that that does not happen. */ + if (cidcode < CIDFontP->CIDfontInfoP[CIDCOUNT].value.data.integer) + return cidcode; + else + return 0; +} + +static CharInfoPtr +CIDGetGlyph(FontPtr pFont, unsigned int charcode, CharInfoPtr pci) +{ + int rc; + CharInfoPtr cp = NULL; + unsigned int cidcode; + + /* character code -> CID */ + cidcode = getCID(pFont, charcode); + + cp = CIDGetGlyphInfo(pFont, cidcode, pci, &rc); + + if (rc != Successful && cidcode) { + cidcode = 0; + cp = CIDGetGlyphInfo(pFont, cidcode, pci, &rc); + } + + return cp; +} + +int +CIDGetGlyphs(FontPtr pFont, + unsigned long count, + unsigned char *chars, + FontEncoding charEncoding, + unsigned long *glyphCount, /* RETURN */ + CharInfoPtr *glyphs) /* RETURN */ +{ + unsigned int code, char_row, char_col; + CharInfoPtr *glyphsBase; + register unsigned int c; + CharInfoPtr pci; + CharInfoPtr pDefault; + cidglyphs *cid; + register int firstCol; + int rc = 0; + int cid_valid = 0; + + cid = (cidglyphs *)pFont->fontPrivate; + + FontP = NULL; + + firstCol = pFont->info.firstCol; + pDefault = cid->pDefault; + glyphsBase = glyphs; + + switch (charEncoding) { + +#define EXIST(pci) \ + ((pci)->metrics.attributes || \ + (pci)->metrics.ascent != -(pci)->metrics.descent || \ + (pci)->metrics.leftSideBearing != (pci)->metrics.rightSideBearing) + + case Linear8Bit: + case TwoD8Bit: + if (pFont->info.firstRow > 0) + break; + while (count--) { + c = (*chars++); + if (c >= firstCol && c <= pFont->info.lastCol) { + code = c - firstCol; + if (!(pci = (CharInfoRec *)cid->glyphs[code]) || + ((long)pci->bits == CID_BITMAP_UNDEFINED)) { + /* load font if not already loaded */ + if(!cid_valid) { + if(!CIDfontfcnA(cid->CIDFontName, cid->CMapName, &rc)) { FontP = NULL; + return Type1ReturnCodeToXReturnCode(rc); + } + cid_valid = 1; + } + pci = CIDGetGlyph(pFont, c, pci); + } + if (pci && EXIST(pci)) { + *glyphs++ = pci; + cid->glyphs[code] = pci; + } else if (pDefault) { + *glyphs++ = pDefault; + cid->glyphs[code] = pDefault; + } + } else if (pDefault) + *glyphs++ = pDefault; + } + break; + case Linear16Bit: + while (count--) { + char_row = *chars++; + char_col = *chars++; + c = char_row << 8; + c = (c | char_col); + if (pFont->info.firstRow <= char_row && char_row <= + pFont->info.lastRow && pFont->info.firstCol <= char_col && + char_col <= pFont->info.lastCol) { + code = pFont->info.lastCol - pFont->info.firstCol + 1; + char_row = char_row - pFont->info.firstRow; + char_col = char_col - pFont->info.firstCol; + code = char_row * code + char_col; + if (!(pci = (CharInfoRec *)cid->glyphs[code]) || + ((long)pci->bits == CID_BITMAP_UNDEFINED)) { + /* load font if not already loaded */ + if(!cid_valid) { + if(!CIDfontfcnA(cid->CIDFontName, cid->CMapName, &rc)) { FontP = NULL; + return Type1ReturnCodeToXReturnCode(rc); + } + cid_valid = 1; + } + pci = CIDGetGlyph(pFont, c, pci); + } + if (pci && EXIST(pci)) { + *glyphs++ = pci; + cid->glyphs[code] = pci; + } else if (pDefault) { + *glyphs++ = pDefault; + cid->glyphs[code] = pDefault; + } + } else if (pDefault) + *glyphs++ = pDefault; + } + break; + + case TwoD16Bit: + while (count--) { + char_row = (*chars++); + char_col = (*chars++); + c = char_row << 8; + c = (c | char_col); + if (pFont->info.firstRow <= char_row && char_row <= + pFont->info.lastRow && pFont->info.firstCol <= char_col && + char_col <= pFont->info.lastCol) { + code = pFont->info.lastCol - pFont->info.firstCol + 1; + char_row = char_row - pFont->info.firstRow; + char_col = char_col - pFont->info.firstCol; + code = char_row * code + char_col; + if (!(pci = (CharInfoRec *)cid->glyphs[code]) || + ((long)pci->bits == CID_BITMAP_UNDEFINED)) { + /* load font if not already loaded */ + if(!cid_valid) { + if(!CIDfontfcnA(cid->CIDFontName, cid->CMapName, &rc)) { FontP = NULL; + return Type1ReturnCodeToXReturnCode(rc); + } + cid_valid = 1; + } + pci = CIDGetGlyph(pFont, c, pci); + } + if (pci && EXIST(pci)) { + *glyphs++ = pci; + cid->glyphs[code] = pci; + } else if (pDefault) { + *glyphs++ = pDefault; + cid->glyphs[code] = pDefault; + } + } else if (pDefault) + *glyphs++ = pDefault; + } + break; + } + *glyphCount = glyphs - glyphsBase; + return Successful; + +#undef EXIST +} +#endif + +static int +Type1GetGlyphs(FontPtr pFont, + unsigned long count, + unsigned char *chars, + FontEncoding charEncoding, + unsigned long *glyphCount, /* RETURN */ + CharInfoPtr *glyphs) /* RETURN */ +{ + unsigned int firstRow; + unsigned int numRows; + CharInfoPtr *glyphsBase; + register unsigned int c; + register CharInfoPtr pci; + unsigned int r; + CharInfoPtr pDefault; + register struct type1font *type1Font; + register int firstCol; + + type1Font = (struct type1font *) pFont->fontPrivate; + firstCol = pFont->info.firstCol; + pDefault = type1Font->pDefault; + glyphsBase = glyphs; + + switch (charEncoding) { + +#define EXIST(pci) \ + ((pci)->metrics.attributes || \ + (pci)->metrics.ascent != -(pci)->metrics.descent || \ + (pci)->metrics.leftSideBearing != (pci)->metrics.rightSideBearing) + + case Linear8Bit: + case TwoD8Bit: + if (pFont->info.firstRow > 0) + break; + while (count--) { + c = (*chars++); + if (c >= firstCol && + (pci = &type1Font->glyphs[c]) && + EXIST(pci)) + *glyphs++ = pci; + else if (pDefault) + *glyphs++ = pDefault; + } + break; + case Linear16Bit: + while (count--) { + c = *chars++ << 8; + c = (c | *chars++); + if (c < 256 && c >= firstCol && + (pci = &type1Font->glyphs[c]) && + EXIST(pci)) + *glyphs++ = pci; + else if (pDefault) + *glyphs++ = pDefault; + } + break; + + case TwoD16Bit: + firstRow = pFont->info.firstRow; + numRows = pFont->info.lastRow - firstRow + 1; + while (count--) { + r = (*chars++) - firstRow; + c = (*chars++); + if (r < numRows && c < 256 && c >= firstCol && + (pci = &type1Font->glyphs[(r << 8) + c]) && + EXIST(pci)) + *glyphs++ = pci; + else if (pDefault) + *glyphs++ = pDefault; + } + break; + } + *glyphCount = glyphs - glyphsBase; + return Successful; + +#undef EXIST +} + +#if XFONT_CID +static CharInfoRec nonExistantChar; + +int +CIDGetMetrics(FontPtr pFont, + unsigned long count, + unsigned char *chars, + FontEncoding charEncoding, + unsigned long *glyphCount, /* RETURN */ + xCharInfo **glyphs) /* RETURN */ +{ + int ret; + cidglyphs *cid; + CharInfoPtr oldDefault; + char cidafmname[CID_PATH_MAX]; + char CIDFontName[CID_NAME_MAX]; + char *ptr; + + cid = (cidglyphs *)pFont->fontPrivate; + + strcpy(cidafmname, cid->CIDFontName); + if (!(ptr = strrchr(cidafmname, '/'))) + return BadFontName; + + *ptr = '\0'; + + strcpy(CIDFontName, ptr + 1); + + if (!(ptr = strrchr(cidafmname, '/'))) + return BadFontName; + + *ptr = '\0'; + + strcat(cidafmname, "/AFM/"); + strcat(cidafmname, CIDFontName); + + strcat(cidafmname, ".afm"); + + oldDefault = cid->pDefault; + cid->pDefault = &nonExistantChar; + + ret = CIDGetAFM(pFont, count, chars, charEncoding, glyphCount, (CharInfoPtr +*)glyphs, cidafmname); + if (ret != Successful) + ret = CIDGetGlyphs(pFont, count, chars, charEncoding, glyphCount, + (CharInfoPtr *)glyphs); + + *ptr = 0; + cid->pDefault = oldDefault; + return ret; +} +#endif + +static int +Type1GetMetrics(FontPtr pFont, + unsigned long count, + unsigned char *chars, + FontEncoding charEncoding, + unsigned long *glyphCount, /* RETURN */ + xCharInfo **glyphs) /* RETURN */ +{ + static CharInfoRec nonExistantChar; + + int ret; + struct type1font *type1Font; + CharInfoPtr oldDefault; + + type1Font = (struct type1font *) pFont->fontPrivate; + oldDefault = type1Font->pDefault; + type1Font->pDefault = &nonExistantChar; + ret = Type1GetGlyphs(pFont, count, chars, charEncoding, glyphCount, (CharInfoPtr *) glyphs); + type1Font->pDefault = oldDefault; + return ret; +} + +#if XFONT_CID +void +CIDCloseFont(FontPtr pFont) +{ + register int i; + cidglyphs *cid; + int nchars; + + if (pFont) { + + cid = (cidglyphs *)pFont->fontPrivate; + + if (cid) { + + if (cid->CIDFontName && !strcmp(cid->CIDFontName, CurCIDFontName) + && cid->CMapName && !strcmp(cid->CMapName, CurCMapName)){ + strcpy(CurCIDFontName, ""); /* initialize to none */ + strcpy(CurCMapName, ""); /* initialize to none */ + } + + if (cid->CIDFontName) + xfree(cid->CIDFontName); + + if (cid->CMapName) + xfree(cid->CMapName); + + nchars = (pFont->info.lastRow - pFont->info.firstRow + 1) * + (pFont->info.lastCol - pFont->info.firstCol + 1); + + for (i = 0; i < nchars; i++) { + if (cid->glyphs[i] && (cid->glyphs[i] != &nonExistantChar)) { + if (cid->glyphs[i]->bits) + xfree(cid->glyphs[i]->bits); + xfree(cid->glyphs[i]); + } + } + + if (cid->glyphs) + xfree(cid->glyphs); + + if (cid->AFMinfo) + xfree(cid->AFMinfo); +#ifdef USE_MMAP + if (cid->CIDdata) + munmap(cid->CIDdata, cid->CIDsize); +#endif + xfree(cid); + } + + if (pFont->info.props) + xfree(pFont->info.props); + + if (pFont->info.isStringProp) + xfree(pFont->info.isStringProp); + + DestroyFontRec(pFont); + } +} +#endif + +void +Type1CloseFont(FontPtr pFont) +{ + register int i; + struct type1font *type1; + + type1 = (struct type1font *) pFont->fontPrivate; + for (i=0; i < 256; i++) + if (type1->glyphs[i].bits != NULL) + xfree(type1->glyphs[i].bits); + xfree(type1); + + if (pFont->info.props) + xfree(pFont->info.props); + + if (pFont->info.isStringProp) + xfree(pFont->info.isStringProp); + + DestroyFontRec(pFont); +} + +static void +fill(char *dest, /* destination bitmap */ + int h, int w, /* dimensions of 'dest', w padded */ + struct region *area, /* region to write to 'dest' */ + int byte, int bit, /* flags; LSBFirst or MSBFirst */ + int wordsize) /* number of bits per word for LSB/MSB purposes */ +{ + register struct edgelist *edge; /* for looping through edges */ + register char *p; /* current scan line in 'dest' */ + register int y; /* for looping through scans */ + register int wbytes = w / 8; /* number of bytes in width */ + register pel *leftP,*rightP; /* pointers to X values, left and right */ + int xmin = area->xmin; /* upper left X */ + int ymin = area->ymin; /* upper left Y */ + + for (edge = area->anchor; VALIDEDGE(edge); edge = edge->link->link) { + + p = dest + (edge->ymin - ymin) * wbytes; + leftP = edge->xvalues; + rightP = edge->link->xvalues; + + for (y = edge->ymin; y < edge->ymax; y++) { + fillrun(p, *leftP++ - xmin, *rightP++ - xmin, bit); + p += wbytes; + } + } +/* +Now, as an afterthought, we'll go reorganize if odd byte order requires +it: +*/ + if (byte == LSBFirst && wordsize != 8) { + register int i; + + switch (wordsize) { + case 16: + { + register unsigned short data,*p; + + p = (unsigned short *) dest; + + for (i = h * w /16; --i >= 0;) { + data = *p; + *p++ = (data << 8) + (data >> 8); + } + break; + } + case 64: + case 32: + { + register unsigned long data,*p; + + p = (unsigned long *) dest; + + for (i = h * w / 32; --i >= 0;) { + data = *p; + *p++ = (data << 24) + (data >> 24) + + (0xFF00 & (data >> 8)) + + (0xFF0000 & (data << 8)); + } + if (wordsize == 64) { + + p = (unsigned long *) dest; + + for (i = h * w / 64; --i >= 0;) { + data = *p++; + p[-1] = p[0]; + *p++ = data; + } + } + break; + } + default: + Abort("xiFill: unknown format"); + } + } + +} + +#define ALLONES 0xFF + +static void +fillrun(char *p, /* address of this scan line */ + pel x0, pel x1, /* left and right X */ + int bit) /* format: LSBFirst or MSBFirst */ +{ + register int startmask,endmask; /* bits to set in first and last char*/ + register int middle; /* number of chars between start and end + 1 */ + + if (x1 <= x0) + return; + middle = x1/8 - x0/8; + p += x0/8; + x0 &= 7; x1 &= 7; + if (bit == LSBFirst) { + startmask = ALLONES << x0; + endmask = ~(ALLONES << x1); + } + else { + startmask = ALLONES >> x0; + endmask = ~(ALLONES >> x1); + } + if (middle == 0) + *p++ |= startmask & endmask; + else { + *p++ |= startmask; + while (--middle > 0) + *p++ = (char)ALLONES; + *p |= endmask; + } +} + +#define CAPABILITIES (CAP_MATRIX | CAP_CHARSUBSETTING) + +#if XFONT_CID +FontRendererRec CIDRendererInfo[] = { + { ".cid", 4, NULL, CIDOpenScalable, + NULL, CIDGetInfoScalable, 0, CAPABILITIES } +}; +#endif + +#if XFONT_CID +FontRendererRec Type1RendererInfo[] = { +#else +static FontRendererRec renderers[] = { +#endif + { ".pfa", 4, NULL, Type1OpenScalable, + NULL, Type1GetInfoScalable, 0, CAPABILITIES }, + { ".pfb", 4, NULL, Type1OpenScalable, + NULL, Type1GetInfoScalable, 0, CAPABILITIES } +}; + +#if XFONT_CID +void +CIDRegisterFontFileFunctions(void) +{ + int i; + + Type1InitStdProps(); + for (i=0; i < sizeof(CIDRendererInfo) / sizeof(FontRendererRec); i++) + FontFileRegisterRenderer(&CIDRendererInfo[i]); +} +#endif + +void +Type1RegisterFontFileFunctions(void) +{ + int i; + +#if XFONT_CID + Type1InitStdProps(); + for (i=0; i < sizeof(Type1RendererInfo) / sizeof(FontRendererRec); i++) + FontFilePriorityRegisterRenderer(&Type1RendererInfo[i], -10); +#else + T1InitStdProps(); + for (i=0; i < sizeof(renderers) / sizeof(FontRendererRec); i++) + FontFilePriorityRegisterRenderer(&renderers[i], -10); +#endif +} + +int +Type1ReturnCodeToXReturnCode(int rc) +{ + switch(rc) { + case SCAN_OK: + return Successful; + case SCAN_FILE_EOF: + /* fall through to BadFontFormat */ + case SCAN_ERROR: + return BadFontFormat; + case SCAN_OUT_OF_MEMORY: + return AllocError; + case SCAN_FILE_OPEN_ERROR: + return BadFontName; + case SCAN_TRUE: + case SCAN_FALSE: + case SCAN_END: + /* fall through */ + default: + /* this should not happen */ +#if XFONT_CID + ErrorF("Font return code cannot be converted to X return code: %d\n", rc); +#else + ErrorF("Type1 return code not convertable to X return code: %d\n", rc); +#endif + return rc; + } +} + +#if XFONT_CID +CharInfoPtr +CIDRenderGlyph(FontPtr pFont, psobj *charstringP, psobj *subarrayP, + struct blues_struct *bluesP, CharInfoPtr pci, int *mode) +{ + int bit, + byte, + glyph, + scan, + image; + int pad,wordsize; /* scan & image in bits */ + long *pool; /* memory pool for ximager objects */ + int size; /* for memory size calculations */ + struct XYspace *S; /* coordinate space for character */ + struct region *area; + CharInfoRec *glyphs; + int len, rc; + long x0; + double x1, y1, t1 = .001, t2 = 0.0, t3 = 0.0, t4 = .001; + double sxmult; + long h,w; + long paddedW; + cidglyphs *cid; + fsBitmapFormat format = 0; + fsBitmapFormatMask fmask = 0; + + cid = (cidglyphs *)pFont->fontPrivate; + + /* set up default values */ + FontDefaultFormat(&bit, &byte, &glyph, &scan); + /* get any changes made from above */ + rc = CheckFSFormat(format, fmask, &bit, &byte, &scan, &glyph, &image); + if (rc != Successful) { + *mode = rc; + return(NULL); + } + + pad = glyph * 8; + wordsize = scan * 8; + +#define PAD(bits, pad) (((bits)+(pad)-1)&-(pad)) + + /* heuristic for "maximum" size of pool we'll need: */ + size = 200000 + 600 * + (int)hypot(cid->pixel_matrix[2], cid->pixel_matrix[3]) + * sizeof(short); + if (size < 0 || NULL == (pool = (long *) xalloc(size))) { + *mode = AllocError; + return(NULL); + } + + addmemory(pool, size); + + if (pci && (long)pci->bits == CID_BITMAP_UNDEFINED) + glyphs = pci; + else { + if (!(glyphs = (CharInfoRec *)xalloc(sizeof(CharInfoRec)))) { + delmemory(); + xfree(pool); + *mode = AllocError; + return(NULL); + } + bzero(glyphs, sizeof(CharInfoRec)); + } + + S = (struct XYspace *) t1_Transform((struct xobject *)IDENTITY, + t1, t2, t3, t4); + + S = (struct XYspace *) Permanent(t1_Transform((struct xobject *)S, + cid->pixel_matrix[0], + -cid->pixel_matrix[1], + cid->pixel_matrix[2], + -cid->pixel_matrix[3])); + + /* multiplier for computation of raw values */ + sxmult = hypot(cid->pixel_matrix[0], cid->pixel_matrix[1]); + if (sxmult > EPS) sxmult = 1000.0 / sxmult; + + rc = 0; + area = (struct region *)CIDfontfcnC(S, charstringP, subarrayP, bluesP, + &len, &rc); + if (rc < 0 || area == NULL) { + delmemory(); + xfree(pool); + if (pci != glyphs) xfree(glyphs); + *mode = Type1ReturnCodeToXReturnCode(rc); + return(NULL); + } + + h = area->ymax - area->ymin; + w = area->xmax - area->xmin; + paddedW = PAD(w, pad); + + if (h > 0 && w > 0) { + size = h * paddedW / 8; + glyphs[0].bits = (char *)xalloc(size); + if (glyphs[0].bits == NULL) { + Destroy(area); + delmemory(); + xfree(pool); + if (pci != glyphs) xfree(glyphs); + *mode = AllocError; + return(NULL); + } + bzero(glyphs[0].bits, size); + } + else { + size = 0; + h = w = 0; + area->xmin = area->xmax = 0; + area->ymax = area->ymax = 0; + glyphs[0].bits = NULL; + } + + glyphs[0].metrics.leftSideBearing = area->xmin; + x1 = (double)(x0 = area->ending.x - area->origin.x); + y1 = (double)(area->ending.y - area->origin.y); + glyphs[0].metrics.characterWidth = + (x0 + (x0 > 0 ? FPHALF : -FPHALF)) / (1 << FRACTBITS); + if (!glyphs[0].metrics.characterWidth && size == 0) + { + /* Zero size and zero extents: presumably caused by + the choice of transformation. Let's create a + small bitmap so we're not mistaken for an undefined + character. */ + h = w = 1; + size = paddedW = PAD(w, pad); + glyphs[0].bits = (char *)xalloc(size); + if (glyphs[0].bits == NULL) { + Destroy(area); + delmemory(); + xfree(pool); + if (pci != glyphs) xfree(glyphs); + *mode = AllocError; + return(NULL); + } + bzero(glyphs[0].bits, size); + } + glyphs[0].metrics.attributes = + NEARESTPEL((long)(hypot(x1, y1) * sxmult)); + glyphs[0].metrics.rightSideBearing = w + area->xmin; + glyphs[0].metrics.descent = area->ymax - NEARESTPEL(area->origin.y); + glyphs[0].metrics.ascent = h - glyphs[0].metrics.descent; + + if (h > 0 && w > 0) + fill(glyphs[0].bits, h, paddedW, area, byte, bit, wordsize); + Destroy(area); + delmemory(); + xfree(pool); + *mode = Successful; + return(glyphs); +} +#endif diff --git a/nx-X11/lib/font/Type1/t1hdigit.h b/nx-X11/lib/font/Type1/t1hdigit.h new file mode 100644 index 000000000..e05f0de5d --- /dev/null +++ b/nx-X11/lib/font/Type1/t1hdigit.h @@ -0,0 +1,40 @@ +/* $Xorg: t1hdigit.h,v 1.3 2000/08/17 19:46:33 cpqbld Exp $ */ +/* Copyright International Business Machines,Corp. 1991 + * All Rights Reserved + * + * License to use, copy, modify, and distribute this software + * and its documentation for any purpose and without fee is + * hereby granted, provided that the above copyright notice + * appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, + * and that the name of IBM not be used in advertising or + * publicity pertaining to distribution of the software without + * specific, written prior permission. + * + * IBM PROVIDES THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES + * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT + * LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE QUALITY AND + * PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT + * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF + * THE SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM) ASSUMES + * THE ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN + * NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ +/* Indicators for special characters in the p_hdigit.h tables */ +#define HERROR (0xfe) +#define HWHITE_SPACE (0xfd) +#define HRIGHT_ANGLE (0xfc) +#define LAST_HDIGIT (0xf0) + +/* Declarations for the tables */ +#define HighHexP (HighHex+1) +extern unsigned char HighHex[]; +#define LowHexP (LowHex+1) +extern unsigned char LowHex[]; diff --git a/nx-X11/lib/font/Type1/t1imager.h b/nx-X11/lib/font/Type1/t1imager.h new file mode 100644 index 000000000..9730f9a47 --- /dev/null +++ b/nx-X11/lib/font/Type1/t1imager.h @@ -0,0 +1,84 @@ +/* $Xorg: t1imager.h,v 1.3 2000/08/17 19:46:33 cpqbld Exp $ */ +/* Copyright International Business Machines,Corp. 1991 + * All Rights Reserved + * + * License to use, copy, modify, and distribute this software + * and its documentation for any purpose and without fee is + * hereby granted, provided that the above copyright notice + * appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, + * and that the name of IBM not be used in advertising or + * publicity pertaining to distribution of the software without + * specific, written prior permission. + * + * IBM PROVIDES THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES + * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT + * LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE QUALITY AND + * PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT + * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF + * THE SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM) ASSUMES + * THE ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN + * NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ +/* $XFree86: xc/lib/font/Type1/t1imager.h,v 1.4 2001/01/17 19:43:23 dawes Exp $ */ + + +#include "objects.h" +#include "spaces.h" +#include "paths.h" +#include "regions.h" + +typedef struct xobject *xobject; +typedef struct segment *path; +typedef struct region *region; +typedef struct XYspace *XYspace; + + +#ifndef NULL +#include <stddef.h> +#endif + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + + +#define WINDINGRULE -2 +#define EVENODDRULE -3 + +#define CONTINUITY 0x80 /* can be added to above rules; e.g. WINDINGRULE+CONTINUITY */ + + +/* +Generic null object definition: +*/ +#define NULLOBJECT ((xobject)NULL) + +/* +Null path definition: +*/ +#define NULLPATH NULLOBJECT + +/* +Full page and null region definition: +*/ +#define INFINITY t1_Infinity +#ifndef NOEXTERNS +extern region *INFINITY; +#endif +#define NULLREGION NULLOBJECT + +#define FF_PARSE_ERROR 5 +#define FF_PATH 1 + diff --git a/nx-X11/lib/font/Type1/t1info.c b/nx-X11/lib/font/Type1/t1info.c new file mode 100644 index 000000000..322572ee2 --- /dev/null +++ b/nx-X11/lib/font/Type1/t1info.c @@ -0,0 +1,1096 @@ +/* $Xorg: t1info.c,v 1.4 2001/02/09 02:04:01 xorgcvs Exp $ */ +/* Copyright International Business Machines,Corp. 1991 + * All Rights Reserved + * + * License, subject to the license given below, to use, + * copy, modify, and distribute this software * and its + * documentation for any purpose and without fee is hereby + * granted, provided that the above copyright notice appear + * in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, + * and that the name of IBM not be used in advertising or + * publicity pertaining to distribution of the software + * without specific, written prior permission. + * + * IBM PROVIDES THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES + * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT + * LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE QUALITY AND + * PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT + * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF + * THE SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM) ASSUMES + * THE ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN + * NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + * + * Author: Carol H. Thompson IBM Almaden Research Center + * Modeled on spinfo.c by Dave Lemke, Network Computing Devices, Inc + * which contains the following copyright and permission notices: + * + * Copyright 1990, 1991 Network Computing Devices; + * Portions Copyright 1987 by Digital Equipment Corporation + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the names of Network Computing Devices or Digital + * not be used in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. Network Computing + * Devices and Digital make no representations about the suitability of this + * software for any purpose. It is provided "as is" without express or + * implied warranty. + * + * NETWORK COMPUTING DEVICES AND DIGITAL DISCLAIM ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES OR DIGITAL BE + * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + +Copyright 1987, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + +*/ +/* Copyright (c) 1994-1999 Silicon Graphics, Inc. All Rights Reserved. + * + * The contents of this file are subject to the CID Font Code Public Licence + * Version 1.0 (the "License"). You may not use this file except in compliance + * with the Licence. You may obtain a copy of the License at Silicon Graphics, + * Inc., attn: Legal Services, 2011 N. Shoreline Blvd., Mountain View, CA + * 94043 or at http://www.sgi.com/software/opensource/cid/license.html. + * + * Software distributed under the License is distributed on an "AS IS" basis. + * ALL WARRANTIES ARE DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED + * WARRANTIES OF MERCHANTABILITY, OF FITNESS FOR A PARTICULAR PURPOSE OR OF + * NON-INFRINGEMENT. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Software is CID font code that was developed by Silicon + * Graphics, Inc. + */ +/* $XFree86: xc/lib/font/Type1/t1info.c,v 1.18tsi Exp $ */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#ifdef BUILDCID +#define XFONT_CID 1 +#endif + +#include <X11/fonts/fntfilst.h> +#include <X11/fonts/fontutil.h> +#ifndef FONTMODULE +#include <stdio.h> +#ifndef BUILDCID +#include <math.h> +#endif +#else +#include "xf86_ansic.h" +#endif +#include <X11/fonts/FSproto.h> + +#if XFONT_CID +#ifndef FONTMODULE +#ifdef _XOPEN_SOURCE +#include <math.h> +#else +#define _XOPEN_SOURCE +#include <math.h> +#undef _XOPEN_SOURCE +#endif +#endif +#include "objects.h" +#include "spaces.h" +#include "range.h" +#endif + +#if XFONT_CID +#include "util.h" +#include "fontfcn.h" + +#if defined(HAVE_CFM) || defined(CID_ALL_CHARS) +#ifndef DEFAULT_CFM_DIR +#define DEFAULT_CFM_DIR "./" +#endif +char cfmDefaultDir[] = DEFAULT_CFM_DIR; +#define CFMMAGIC 0x91239123 +#endif +#endif +#include "t1intf.h" + +#define DECIPOINTSPERINCH 722.7 +#define DEFAULTRES 75 +#define DEFAULTPOINTSIZE 120 + +enum scaleType { + atom, truncate_atom, pixel_size, point_size, resolution_x, + resolution_y, average_width +}; + +#if XFONT_CID +extern cidfont *CIDFontP; +static int stdpropsinit = 0; + +typedef struct cfm_rec { + xCharInfo maxbounds; + xCharInfo minbounds; + xCharInfo ink_maxbounds; + xCharInfo ink_minbounds; + INT32 totalrw; + INT16 maxo; + INT16 alle; +} cfmrec; +#endif + +typedef struct _fontProp { + char *name; + long atom; + enum scaleType type; +} fontProp; + +static fontProp fontNamePropTable[] = { /* Example: */ + { "FOUNDRY", 0, atom }, /* adobe */ + { "FAMILY_NAME", 0, atom }, /* times roman */ + { "WEIGHT_NAME", 0, atom }, /* bold */ + { "SLANT", 0, atom }, /* i */ + { "SETWIDTH_NAME", 0, atom }, /* normal */ + { "ADD_STYLE_NAME", 0, atom }, /* */ + { "PIXEL_SIZE", 0, pixel_size }, /* 18 */ + { "POINT_SIZE", 0, point_size }, /* 180 */ + { "RESOLUTION_X", 0, resolution_x }, /* 72 */ + { "RESOLUTION_Y", 0, resolution_y }, /* 72 */ + { "SPACING", 0, atom }, /* p */ + { "AVERAGE_WIDTH", 0, average_width }, /* 0 */ + { "CHARSET_REGISTRY", 0, atom }, /* ISO8859 */ + { "CHARSET_ENCODING", 0, truncate_atom } /* 1 */ +}; + +/* NOTICE: Following array is closely related to the sequence of defines + following it. */ +static fontProp extraProps[] = { + { "FONT", 0, }, + { "COPYRIGHT", 0, }, + { "RAW_PIXEL_SIZE", 0, }, + { "RAW_POINT_SIZE", 0, }, + { "RAW_ASCENT", 0, }, + { "RAW_DESCENT", 0, }, + { "RAW_AVERAGE_WIDTH", 0, }, + { "FACE_NAME", 0, }, + { "FONT_TYPE", 0, }, + { "RASTERIZER_NAME", 0, } +}; + +/* this is a bit kludgy */ +#define FONTPROP 0 +#define COPYRIGHTPROP 1 +#define RAWPIXELPROP 2 +#define RAWPOINTPROP 3 +#define RAWASCENTPROP 4 +#define RAWDESCENTPROP 5 +#define RAWWIDTHPROP 6 +#define FACE_NAMEPROP 7 +#define FONT_TYPEPROP 8 +#define RASTERIZER_NAMEPROP 9 + +#define NNAMEPROPS (sizeof(fontNamePropTable) / sizeof(fontProp)) +#define NEXTRAPROPS (sizeof(extraProps) / sizeof(fontProp)) + +#define NPROPS (NNAMEPROPS + NEXTRAPROPS) + +/*ARGSUSED*/ +static void +FillHeader(FontInfoPtr pInfo, FontScalablePtr Vals) +{ + /* OpenScalable in T1FUNCS sets the following: + pInfo->firstCol, + pInfo->firstRow, + pInfo->lastCol, and + pInfo->lastRow. */ + /* the following are ununsed + pInfo->pad. */ + + /* Items we should handle better someday +++ */ + pInfo->defaultCh = 0; + pInfo->drawDirection = LeftToRight; + if (Vals->point_matrix[0] == Vals->point_matrix[3]) + pInfo->anamorphic = 0; + else + pInfo->anamorphic = 1; + pInfo->inkMetrics = 0; /* no ink metrics here */ + pInfo->cachable = 1; /* no licensing (yet) */ +} + +static void +adjust_min_max(xCharInfo *minc, xCharInfo *maxc, xCharInfo *tmp) +{ +#define MINMAX(field,ci) \ + if (minc->field > (ci)->field) \ + minc->field = (ci)->field; \ + if (maxc->field < (ci)->field) \ + maxc->field = (ci)->field; + + MINMAX(ascent, tmp); + MINMAX(descent, tmp); + MINMAX(leftSideBearing, tmp); + MINMAX(rightSideBearing, tmp); + MINMAX(characterWidth, tmp); + + /* Do MINMAX for attributes field. Since that field is CARD16, + we'll cast to a signed integer */ + if ((INT16)minc->attributes > (INT16)tmp->attributes) + minc->attributes = tmp->attributes; + if ((INT16)maxc->attributes < (INT16)tmp->attributes) + maxc->attributes = tmp->attributes; + +#undef MINMAX +} + +static void +ComputeBounds(FontInfoPtr pInfo, CharInfoPtr pChars, FontScalablePtr Vals) +{ + int i; + xCharInfo minchar, maxchar; + int numchars = 0; + int totchars; + int overlap; + int maxlap; + + minchar.ascent = minchar.descent = + minchar.leftSideBearing = minchar.rightSideBearing = + minchar.characterWidth = minchar.attributes = 32767; + maxchar.ascent = maxchar.descent = + maxchar.leftSideBearing = maxchar.rightSideBearing = + maxchar.characterWidth = maxchar.attributes = -32767; + + maxlap = -32767; + totchars = pInfo->lastCol - pInfo->firstCol + 1; + pChars += pInfo->firstCol; + pInfo->allExist = 1; + for (i = 0; i < totchars; i++,pChars++) { + xCharInfo *pmetrics = &pChars->metrics; + + if (pmetrics->attributes || + pmetrics->ascent != -pmetrics->descent || + pmetrics->leftSideBearing != pmetrics->rightSideBearing) { + numchars++; + adjust_min_max(&minchar, &maxchar, pmetrics); + overlap = pmetrics->rightSideBearing - pmetrics->characterWidth; + if (overlap > maxlap) maxlap = overlap; + } + else pInfo->allExist = 0; + } + + /* If we're monospaced, round the average width field to the + nearest pixel */ + if (minchar.characterWidth == maxchar.characterWidth) + Vals->width = minchar.characterWidth * 10; + + pInfo->maxbounds = maxchar; + pInfo->minbounds = minchar; + pInfo->ink_maxbounds = maxchar; + pInfo->ink_minbounds = minchar; + pInfo->maxOverlap = maxlap + -(minchar.leftSideBearing); + + /* Set the pInfo flags */ + /* Properties set by FontComputeInfoAccelerators: + pInfo->noOverlap; + pInfo->terminalFont; + pInfo->constantMetrics; + pInfo->constantWidth; + pInfo->inkInside; + + */ + FontComputeInfoAccelerators (pInfo); +} + +#if XFONT_CID +#ifdef CID_ALL_CHARS +void +ComputeBoundsAllChars(FontPtr pFont, char *cfmfilename, double sxmult) +{ + FILE *cfm; + CARD32 magic; + int count = 0; + int maxlap, overlap, i, j, k, ret; + xCharInfo minchar, maxchar; + cidrange *cidrangeP; + unsigned char ccode[2]; + unsigned long ccount; + xCharInfo *pmetrics; + long total_raw_width = 0, total_width = 0; + char cfmd[CID_PATH_MAX]; + cfmrec *cfmp; + char *p; + + if (!(cfm = fopen(cfmfilename, "w"))) { + fprintf(stderr, + "Unable to open the file %s. You are probably not logged in as root.\n", + cfmfilename); + p = strrchr(cfmfilename, '/'); + if (p == NULL) exit(1); + strcpy(cfmd, cfmDefaultDir); + strcat(cfmd, p + 1); + if (!(cfm = fopen(cfmd, "w"))) { + fprintf(stderr, + "Switching to current directory. Unable to open the file %s.\n", + cfmd); + exit(1); + } + } + + if ((cfmp = (cfmrec *)xalloc(sizeof(cfmrec))) == NULL) { + fprintf(stderr, "Unable to allocate memory."); + exit(1); + } + bzero(cfmp, sizeof(cfmrec)); + + minchar.ascent = minchar.descent = + minchar.leftSideBearing = minchar.rightSideBearing = + minchar.characterWidth = minchar.attributes = 32767; + maxchar.ascent = maxchar.descent = + maxchar.leftSideBearing = maxchar.rightSideBearing = + maxchar.characterWidth = maxchar.attributes = -32767; + + maxlap = -32767; + cfmp->alle = 1; + cidrangeP = CIDFontP->cidrangeP; + + /* go through all character codes specified in a given CMap */ + for (i = 0; i < CIDFontP->cidrangecnt; i++) { + for (j = 0; j < cidrangeP->rangecnt; j++) { + for (k = cidrangeP->range[j].srcCodeLo; + k <= cidrangeP->range[j].srcCodeHi; k++) { + ccode[0] = (k >> 8) & 0xff; + ccode[1] = k & 0xff; + ret = CIDGetMetrics(pFont, 1, ccode, Linear16Bit, &ccount, &pmetrics); + if (ret != Successful || (ret == Successful && pmetrics == NULL)) + continue; + total_width += pmetrics->attributes; + total_raw_width += abs((int)(INT16)pmetrics->attributes); + if (pmetrics->attributes || + pmetrics->ascent != -pmetrics->descent || + pmetrics->leftSideBearing != pmetrics->rightSideBearing) { + count++; + adjust_min_max(&minchar, &maxchar, pmetrics); + overlap = pmetrics->rightSideBearing - pmetrics->characterWidth; + if (overlap > maxlap) maxlap = overlap; + } + else cfmp->alle = 0; + } + } + } + + if (count) + { + total_raw_width = (total_raw_width * 10 + count / 2) / count; + if (total_width < 0) + { + /* Predominant direction is R->L */ + total_raw_width = -total_raw_width; + } + } + + cfmp->totalrw = (INT32)total_raw_width; + + cfmp->maxbounds.leftSideBearing = + floor((double)maxchar.leftSideBearing * sxmult + 0.5); + cfmp->maxbounds.rightSideBearing = + floor((double)maxchar.rightSideBearing * sxmult + 0.5); + cfmp->maxbounds.characterWidth = + floor((double)maxchar.characterWidth * sxmult + 0.5); + cfmp->maxbounds.ascent = + floor((double)maxchar.ascent * sxmult + 0.5); + cfmp->maxbounds.descent = + floor((double)maxchar.descent * sxmult); + cfmp->maxbounds.attributes = maxchar.attributes; + + cfmp->minbounds.leftSideBearing = + floor((double)minchar.leftSideBearing * sxmult + 0.5); + cfmp->minbounds.rightSideBearing = + floor((double)minchar.rightSideBearing * sxmult + 0.5); + cfmp->minbounds.characterWidth = + floor((double)minchar.characterWidth * sxmult + 0.5); + cfmp->minbounds.ascent = + floor((double)minchar.ascent * sxmult + 0.5); + cfmp->minbounds.descent = + floor((double)minchar.descent * sxmult + 0.5); + cfmp->minbounds.attributes = minchar.attributes; + + cfmp->ink_maxbounds.leftSideBearing = + floor((double)maxchar.leftSideBearing * sxmult + 0.5); + cfmp->ink_maxbounds.rightSideBearing = + floor((double)maxchar.rightSideBearing * sxmult + 0.5); + cfmp->ink_maxbounds.characterWidth = + floor((double)maxchar.characterWidth * sxmult + 0.5); + cfmp->ink_maxbounds.ascent = + floor((double)maxchar.ascent * sxmult + 0.5); + cfmp->ink_maxbounds.descent = + floor((double)maxchar.descent * sxmult + 0.5); + cfmp->ink_maxbounds.attributes = maxchar.attributes; + + cfmp->ink_minbounds.leftSideBearing = + floor((double)minchar.leftSideBearing * sxmult + 0.5); + cfmp->ink_minbounds.rightSideBearing = + floor((double)minchar.rightSideBearing * sxmult + 0.5); + cfmp->ink_minbounds.characterWidth = + floor((double)minchar.characterWidth * sxmult + 0.5); + cfmp->ink_minbounds.ascent = + floor((double)minchar.ascent * sxmult + 0.5); + cfmp->ink_minbounds.descent = + floor((double)minchar.descent * sxmult + 0.5); + cfmp->ink_minbounds.attributes = minchar.attributes; + + cfmp->maxo = (INT32)(maxlap + -(minchar.leftSideBearing)); + + magic = CFMMAGIC; + fwrite(&magic, sizeof(CARD32), 1, cfm); + fwrite(cfmp, sizeof(cfmrec), 1, cfm); + xfree(cfmp); + fclose(cfm); +} +#else +static long +ComputeBoundsAll(FontPtr pFont) +{ + int count = 0; + int maxlap, overlap, i, j, k, ret; + xCharInfo minchar, maxchar; + cidrange *cidrangeP; + unsigned char ccode[2]; + unsigned long ccount; + xCharInfo *pmetrics; + CharInfoRec *cinfo[1]; + long total_raw_width = 0, total_width = 0; + FontInfoPtr pInfo = &(pFont->info); + + minchar.ascent = minchar.descent = + minchar.leftSideBearing = minchar.rightSideBearing = + minchar.characterWidth = minchar.attributes = 32767; + maxchar.ascent = maxchar.descent = + maxchar.leftSideBearing = maxchar.rightSideBearing = + maxchar.characterWidth = maxchar.attributes = -32767; + + maxlap = -32767; + pInfo->allExist = 1; + cidrangeP = CIDFontP->cidrangeP; + + /* go through all character codes specified in a given CMap */ + for (i = 0; i < CIDFontP->cidrangecnt; i++) { + for (j = 0; j < cidrangeP->rangecnt; j++) { + for (k = cidrangeP->range[j].srcCodeLo; + k <= cidrangeP->range[j].srcCodeHi; k++) { + ccode[0] = (k >> 8) & 0xff; + ccode[1] = k & 0xff; + ret = CIDGetMetrics(pFont, 1, ccode, Linear16Bit, &ccount, (xCharInfo **)cinfo); + if (ret != Successful || cinfo == NULL) + continue; + pmetrics = &cinfo[0]->metrics; + total_width += pmetrics->attributes; + total_raw_width += abs((int)(INT16)pmetrics->attributes); + if (pmetrics->attributes || + pmetrics->ascent != -pmetrics->descent || + pmetrics->leftSideBearing != pmetrics->rightSideBearing) { + count++; + adjust_min_max(&minchar, &maxchar, pmetrics); + overlap = pmetrics->rightSideBearing - pmetrics->characterWidth; + if (overlap > maxlap) maxlap = overlap; + } + else pInfo->allExist = 0; + } + } + } + + if (count) + { + total_raw_width = (total_raw_width * 10 + count / 2) / count; + if (total_width < 0) + { + /* Predominant direction is R->L */ + total_raw_width = -total_raw_width; + } + } + + pInfo->maxbounds.leftSideBearing = maxchar.leftSideBearing; + pInfo->maxbounds.rightSideBearing = maxchar.rightSideBearing; + pInfo->maxbounds.characterWidth = maxchar.characterWidth; + pInfo->maxbounds.ascent = maxchar.ascent; + pInfo->maxbounds.descent = maxchar.descent; + pInfo->maxbounds.attributes = maxchar.attributes; + + pInfo->minbounds.leftSideBearing = minchar.leftSideBearing; + pInfo->minbounds.rightSideBearing = minchar.rightSideBearing; + pInfo->minbounds.characterWidth = minchar.characterWidth; + pInfo->minbounds.ascent = minchar.ascent; + pInfo->minbounds.descent = minchar.descent; + pInfo->minbounds.attributes = minchar.attributes; + + pInfo->ink_maxbounds.leftSideBearing = maxchar.leftSideBearing; + pInfo->ink_maxbounds.rightSideBearing = maxchar.rightSideBearing; + pInfo->ink_maxbounds.characterWidth = maxchar.characterWidth; + pInfo->ink_maxbounds.ascent = maxchar.ascent; + pInfo->ink_maxbounds.descent = maxchar.descent; + pInfo->ink_maxbounds.attributes = maxchar.attributes; + + pInfo->ink_minbounds.leftSideBearing = minchar.leftSideBearing; + pInfo->ink_minbounds.rightSideBearing = minchar.rightSideBearing; + pInfo->ink_minbounds.characterWidth = minchar.characterWidth; + pInfo->ink_minbounds.ascent = minchar.ascent; + pInfo->ink_minbounds.descent = minchar.descent; + pInfo->ink_minbounds.attributes = minchar.attributes; + + pInfo->maxOverlap = maxlap + -(minchar.leftSideBearing); + + return total_raw_width; +} +#endif +#endif + +static void +ComputeProps(FontInfoPtr pInfo, FontScalablePtr Vals, char *Filename, + long *sAscent, long *sDescent) +{ + int infoint; + int infoBBox[4]; + int rc; + + QueryFontLib(Filename, "isFixedPitch", &infoint, &rc); + if (!rc) { + pInfo->constantWidth = infoint; + } + QueryFontLib((char *)0, "FontBBox", infoBBox, &rc); + if (!rc) { + pInfo->fontAscent = + (int)((double)infoBBox[3] * Vals->pixel_matrix[3] + + (infoBBox[3] > 0 ? 500 : -500)) / 1000; + pInfo->fontDescent = + -(int)((double)infoBBox[1] * Vals->pixel_matrix[3] + + (infoBBox[1] > 0 ? 500 : -500)) / 1000; + *sAscent = infoBBox[3]; + *sDescent = -infoBBox[1]; + } +} + +#if XFONT_CID +#ifndef CID_ALL_CHARS +static void +CIDComputeStdProps(FontInfoPtr pInfo, FontScalablePtr Vals, + char *Filename, char *Cmapname, char *Fontname, + long sAscent, long sDescent, long sWidth) +{ + FontPropPtr pp; + int i, + nprops; + fontProp *fpt; + char *is_str; + char *ptr1 = NULL, + *ptr2; + char *ptr3; + char *infostrP; + int rc; + char scaledName[CID_PATH_MAX]; + + strcpy (scaledName, Fontname); + /* Fill in our copy of the fontname from the Vals structure */ + FontParseXLFDName (scaledName, Vals, FONT_XLFD_REPLACE_VALUE); + + /* This form of the properties is used by the X-client; the X-server + doesn't care what they are. */ + nprops = pInfo->nprops = NPROPS; + pInfo->isStringProp = (char *) xalloc(sizeof(char) * nprops); + pInfo->props = (FontPropPtr) xalloc(sizeof(FontPropRec) * nprops); + if (!pInfo->isStringProp || !pInfo->props) { + xfree(pInfo->isStringProp); + pInfo->isStringProp = (char *) 0; + xfree(pInfo->props); + pInfo->props = (FontPropPtr) 0; + pInfo->nprops = 0; + return; + } + bzero(pInfo->isStringProp, (sizeof(char) * nprops)); + + ptr2 = scaledName; + for (i = NNAMEPROPS, pp = pInfo->props, fpt = fontNamePropTable, is_str = pInfo->isStringProp; + i; + i--, pp++, fpt++, is_str++) { + + if (*ptr2) + { + ptr1 = ptr2 + 1; + if (!(ptr2 = strchr(ptr1, '-'))) ptr2 = strchr(ptr1, '\0'); + } + + pp->name = fpt->atom; + switch (fpt->type) { + case atom: /* Just copy info from scaledName */ + *is_str = TRUE; + pp->value = MakeAtom(ptr1, ptr2 - ptr1, TRUE); + break; + case truncate_atom: + *is_str = TRUE; + for (ptr3 = ptr1; *ptr3; ptr3++) + if (*ptr3 == '[') + break; + pp->value = MakeAtom(ptr1, ptr3 - ptr1, TRUE); + break; + case pixel_size: + pp->value = (int)(fabs(Vals->pixel_matrix[3]) + .5); + break; + case point_size: + pp->value = (int)(fabs(Vals->point_matrix[3]) * 10.0 + .5); + break; + case resolution_x: + pp->value = Vals->x; + break; + case resolution_y: + pp->value = Vals->y; + break; + case average_width: + pp->value = Vals->width; + break; + } + } + + for (i = 0, fpt = extraProps; + i < NEXTRAPROPS; + i++, is_str++, pp++, fpt++) { + pp->name = fpt->atom; + switch (i) { + case FONTPROP: + *is_str = TRUE; + pp->value = MakeAtom(scaledName, strlen(scaledName), TRUE); + break; + case COPYRIGHTPROP: + *is_str = TRUE; + CIDQueryFontLib(Filename, Cmapname, "Notice", &infostrP, &rc); + if (rc || !infostrP) { + infostrP = "Copyright Notice not available"; + } + pp->value = MakeAtom(infostrP, strlen(infostrP), TRUE); + break; + case FACE_NAMEPROP: + *is_str = TRUE; + CIDQueryFontLib(Filename, Cmapname, "CIDFontName", &infostrP, &rc); + if (rc || !infostrP) { + infostrP = "(unknown)"; + } + pp->value = MakeAtom(infostrP, strlen(infostrP), TRUE); + break; + case FONT_TYPEPROP: + *is_str = TRUE; + infostrP = "CIDFont"; + pp->value = MakeAtom(infostrP, strlen(infostrP), TRUE); + break; + case RASTERIZER_NAMEPROP: + *is_str = TRUE; + infostrP = "X Consortium Type 1 Rasterizer"; + pp->value = MakeAtom(infostrP, strlen(infostrP), TRUE); + break; + case RAWPIXELPROP: + *is_str = FALSE; + pp->value = 1000; + break; + case RAWPOINTPROP: + *is_str = FALSE; + pp->value = (long)(72270.0 / (double)Vals->y + .5); + break; + case RAWASCENTPROP: + *is_str = FALSE; + pp->value = sAscent; + break; + case RAWDESCENTPROP: + *is_str = FALSE; + pp->value = sDescent; + break; + case RAWWIDTHPROP: + *is_str = FALSE; + pp->value = sWidth; + break; + } + } +} +#endif +#endif + +static void +ComputeStdProps(FontInfoPtr pInfo, FontScalablePtr Vals, + char *Filename, char *Fontname, + long sAscent, long sDescent, long sWidth) +{ + FontPropPtr pp; + int i, + nprops; + fontProp *fpt; + char *is_str; + char *ptr1 = NULL, + *ptr2; + char *ptr3; + char *infostrP; + int rc; + char scaledName[MAXFONTNAMELEN]; + + strcpy (scaledName, Fontname); + /* Fill in our copy of the fontname from the Vals structure */ + FontParseXLFDName (scaledName, Vals, FONT_XLFD_REPLACE_VALUE); + + /* This form of the properties is used by the X-client; the X-server + doesn't care what they are. */ + nprops = pInfo->nprops = NPROPS; + pInfo->isStringProp = (char *) xalloc(sizeof(char) * nprops); + pInfo->props = (FontPropPtr) xalloc(sizeof(FontPropRec) * nprops); + if (!pInfo->isStringProp || !pInfo->props) { + xfree(pInfo->isStringProp); + pInfo->isStringProp = (char *) 0; + xfree(pInfo->props); + pInfo->props = (FontPropPtr) 0; + return; + } + bzero(pInfo->isStringProp, (sizeof(char) * nprops)); + + ptr2 = scaledName; + for (i = NNAMEPROPS, pp = pInfo->props, fpt = fontNamePropTable, is_str = pInfo->isStringProp; + i; + i--, pp++, fpt++, is_str++) { + + if (*ptr2) + { + ptr1 = ptr2 + 1; + if (!(ptr2 = strchr(ptr1, '-'))) ptr2 = strchr(ptr1, '\0'); + } + + pp->name = fpt->atom; + switch (fpt->type) { + case atom: /* Just copy info from scaledName */ + *is_str = TRUE; + pp->value = MakeAtom(ptr1, ptr2 - ptr1, TRUE); + break; + case truncate_atom: + *is_str = TRUE; + for (ptr3 = ptr1; *ptr3; ptr3++) + if (*ptr3 == '[') + break; + pp->value = MakeAtom(ptr1, ptr3 - ptr1, TRUE); + break; + case pixel_size: + pp->value = (int)(fabs(Vals->pixel_matrix[3]) + .5); + break; + case point_size: + pp->value = (int)(fabs(Vals->point_matrix[3]) * 10.0 + .5); + break; + case resolution_x: + pp->value = Vals->x; + break; + case resolution_y: + pp->value = Vals->y; + break; + case average_width: + pp->value = Vals->width; + break; + } + } + + for (i = 0, fpt = extraProps; + i < NEXTRAPROPS; + i++, is_str++, pp++, fpt++) { + pp->name = fpt->atom; + switch (i) { + case FONTPROP: + *is_str = TRUE; + pp->value = MakeAtom(scaledName, strlen(scaledName), TRUE); + break; + case COPYRIGHTPROP: + *is_str = TRUE; + QueryFontLib(Filename, "Notice", &infostrP, &rc); + if (rc || !infostrP) { + infostrP = "Copyright Notice not available"; + } + pp->value = MakeAtom(infostrP, strlen(infostrP), TRUE); + break; + case FACE_NAMEPROP: + *is_str = TRUE; + QueryFontLib(Filename, "FontName", &infostrP, &rc); + if (rc || !infostrP) { + infostrP = "(unknown)"; + } + pp->value = MakeAtom(infostrP, strlen(infostrP), TRUE); + break; + case FONT_TYPEPROP: + *is_str = TRUE; + infostrP = "Type 1"; + pp->value = MakeAtom(infostrP, strlen(infostrP), TRUE); + break; + case RASTERIZER_NAMEPROP: + *is_str = TRUE; + infostrP = "X Consortium Type 1 Rasterizer"; + pp->value = MakeAtom(infostrP, strlen(infostrP), TRUE); + break; + case RAWPIXELPROP: + *is_str = FALSE; + pp->value = 1000; + break; + case RAWPOINTPROP: + *is_str = FALSE; + pp->value = (long)(72270.0 / (double)Vals->y + .5); + break; + case RAWASCENTPROP: + *is_str = FALSE; + pp->value = sAscent; + break; + case RAWDESCENTPROP: + *is_str = FALSE; + pp->value = sDescent; + break; + case RAWWIDTHPROP: + *is_str = FALSE; + pp->value = sWidth; + break; + } + } +} + +#if XFONT_CID +/*ARGSUSED*/ +int +CIDGetInfoScalable(FontPathElementPtr fpe, + FontInfoPtr pInfo, + FontEntryPtr entry, + FontNamePtr fontName, + char *fileName, + FontScalablePtr Vals) +{ + FontPtr pfont; + int flags = 0; + long format = 0; /* It doesn't matter what format for just info */ + long fmask = 0; + int ret; + + ret = CIDOpenScalable(fpe, &pfont, flags, entry, fileName, Vals, + format, fmask, NULL); + if (ret != Successful) + return ret; + *pInfo = pfont->info; + + /* XXX - Set pointers in pfont->info to NULL so they are not freed. */ + pfont->info.props = NULL; + pfont->info.isStringProp = NULL; + + CIDCloseFont(pfont); + return Successful; +} +#endif + +/*ARGSUSED*/ +int +Type1GetInfoScalable(FontPathElementPtr fpe, + FontInfoPtr pInfo, + FontEntryPtr entry, + FontNamePtr fontName, + char *fileName, + FontScalablePtr Vals) +{ + FontPtr pfont; + int flags = 0; + long format = 0; /* It doesn't matter what format for just info */ + long fmask = 0; + int ret; + + ret = Type1OpenScalable(fpe, &pfont, flags, entry, fileName, Vals, + format, fmask , NULL); + if (ret != Successful) + return ret; + *pInfo = pfont->info; + + /* XXX - Set pointers in pfont->info to NULL so they are not freed. */ + pfont->info.props = NULL; + pfont->info.isStringProp = NULL; + + Type1CloseFont(pfont); + return Successful; +} + +#if XFONT_CID +#ifndef CID_ALL_CHARS +void +CIDFillFontInfo(FontPtr pFont, FontScalablePtr Vals, + char *Filename, char *Fontname, char *Cmapname, +#ifdef HAVE_CFM + char *cfmfilename, +#endif + long sAscent, long sDescent, double sxmult) +{ +#ifdef HAVE_CFM + FILE *cfm; + cfmrec *cfmp; + int gotcfm = 0; + CARD32 magic; +#endif + long sWidth = 0; + FontInfoPtr pInfo = &pFont->info; + + FillHeader(pInfo, Vals); + +#ifdef HAVE_CFM + if ((cfm = fopen(cfmfilename,"r"))) { + fread(&magic,sizeof(CARD32),1,cfm); + if(magic == CFMMAGIC) { + if ((cfmp = (cfmrec *)xalloc(sizeof(cfmrec))) != NULL) { + fread(cfmp,sizeof(cfmrec),1,cfm); + sWidth = (long)cfmp->totalrw; + pInfo->allExist = cfmp->alle; + if (sxmult != 0) { + pInfo->maxbounds.leftSideBearing = + floor((double)cfmp->maxbounds.leftSideBearing / + sxmult + 0.5); + pInfo->maxbounds.rightSideBearing = + floor((double)cfmp->maxbounds.rightSideBearing / + sxmult + 0.5); + pInfo->maxbounds.characterWidth = + floor((double)cfmp->maxbounds.characterWidth / + sxmult + 0.5); + pInfo->maxbounds.ascent = + floor((double)cfmp->maxbounds.ascent / + sxmult + 0.5); + pInfo->maxbounds.descent = + floor((double)cfmp->maxbounds.descent / + sxmult + 0.5); + pInfo->maxbounds.attributes = + cfmp->maxbounds.attributes; + + pInfo->minbounds.leftSideBearing = + cfmp->minbounds.leftSideBearing / sxmult; + pInfo->minbounds.rightSideBearing = + cfmp->minbounds.rightSideBearing / sxmult; + pInfo->minbounds.characterWidth = + cfmp->minbounds.characterWidth / sxmult; + pInfo->minbounds.ascent = + cfmp->minbounds.ascent / sxmult; + pInfo->minbounds.descent = + cfmp->minbounds.descent / sxmult; + pInfo->minbounds.attributes = cfmp->minbounds.attributes; + + pInfo->ink_maxbounds.leftSideBearing = + cfmp->ink_maxbounds.leftSideBearing / sxmult; + pInfo->ink_maxbounds.rightSideBearing = + cfmp->ink_maxbounds.rightSideBearing / sxmult; + pInfo->ink_maxbounds.characterWidth = + cfmp->ink_maxbounds.characterWidth / sxmult; + pInfo->ink_maxbounds.ascent = + cfmp->ink_maxbounds.ascent / sxmult; + pInfo->ink_maxbounds.descent = + cfmp->ink_maxbounds.descent / sxmult; + pInfo->ink_maxbounds.attributes = + cfmp->ink_maxbounds.attributes; + + pInfo->ink_minbounds.leftSideBearing = + cfmp->ink_minbounds.leftSideBearing / sxmult; + pInfo->ink_minbounds.rightSideBearing = + cfmp->ink_minbounds.rightSideBearing / sxmult; + pInfo->ink_minbounds.characterWidth = + cfmp->ink_minbounds.characterWidth / sxmult; + pInfo->ink_minbounds.ascent = + cfmp->ink_minbounds.ascent / sxmult; + pInfo->ink_minbounds.descent = + cfmp->ink_minbounds.descent / sxmult; + pInfo->ink_minbounds.attributes = + cfmp->ink_minbounds.attributes; + pInfo->ink_minbounds.attributes = + cfmp->ink_minbounds.attributes; + + pInfo->maxOverlap = (short)cfmp->maxo; + + gotcfm = 1; + } + xfree(cfmp); + } + } + fclose(cfm); + } + + if (!gotcfm) +#endif + sWidth = ComputeBoundsAll(pFont); + + FontComputeInfoAccelerators(pInfo); + + CIDComputeStdProps(pInfo, Vals, Filename, Cmapname, Fontname, sAscent, + sDescent, sWidth); +} +#endif /* CID_ALL_CHARS */ +#endif /* BUILDCID */ + +void +T1FillFontInfo(FontPtr pFont, FontScalablePtr Vals, + char *Filename, char *Fontname, long sWidth) +{ + FontInfoPtr pInfo = &pFont->info; + struct type1font *p = (struct type1font *)pFont->fontPrivate; + long sAscent, sDescent; /* Scalable 1000-pixel values */ + + FillHeader(pInfo, Vals); + + ComputeBounds(pInfo, p->glyphs, Vals); + + ComputeProps(pInfo, Vals, Filename, &sAscent, &sDescent); + ComputeStdProps(pInfo, Vals, Filename, Fontname, sAscent, sDescent, sWidth); +} + +/* Called once, at renderer registration time */ +void +#if XFONT_CID +Type1InitStdProps(void) +#else +T1InitStdProps(void) +#endif +{ + int i; + fontProp *t; + +#if XFONT_CID + if (!stdpropsinit) { + stdpropsinit = 1; + i = sizeof(fontNamePropTable) / sizeof(fontProp); + for (t = fontNamePropTable; i; i--, t++) + t->atom = MakeAtom(t->name, (unsigned) strlen(t->name), TRUE); + i = sizeof(extraProps) / sizeof(fontProp); + for (t = extraProps; i; i--, t++) + t->atom = MakeAtom(t->name, (unsigned) strlen(t->name), TRUE); + } +#else + i = sizeof(fontNamePropTable) / sizeof(fontProp); + for (t = fontNamePropTable; i; i--, t++) + t->atom = MakeAtom(t->name, (unsigned) strlen(t->name), TRUE); + i = sizeof(extraProps) / sizeof(fontProp); + for (t = extraProps; i; i--, t++) + t->atom = MakeAtom(t->name, (unsigned) strlen(t->name), TRUE); +#endif +} diff --git a/nx-X11/lib/font/Type1/t1intf.h b/nx-X11/lib/font/Type1/t1intf.h new file mode 100644 index 000000000..831acc55d --- /dev/null +++ b/nx-X11/lib/font/Type1/t1intf.h @@ -0,0 +1,143 @@ +/* $Xorg: t1intf.h,v 1.3 2000/08/17 19:46:33 cpqbld Exp $ */ +/* Copyright International Business Machines,Corp. 1991 + * All Rights Reserved + * + * License to use, copy, modify, and distribute this software + * and its documentation for any purpose and without fee is + * hereby granted, provided that the above copyright notice + * appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, + * and that the name of IBM not be used in advertising or + * publicity pertaining to distribution of the software without + * specific, written prior permission. + * + * IBM PROVIDES THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES + * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT + * LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE QUALITY AND + * PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT + * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF + * THE SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM) ASSUMES + * THE ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN + * NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ +/* Copyright (c) 1994-1999 Silicon Graphics, Inc. All Rights Reserved. + * + * The contents of this file are subject to the CID Font Code Public Licence + * Version 1.0 (the "License"). You may not use this file except in compliance + * with the Licence. You may obtain a copy of the License at Silicon Graphics, + * Inc., attn: Legal Services, 2011 N. Shoreline Blvd., Mountain View, CA + * 94043 or at http://www.sgi.com/software/opensource/cid/license.html. + * + * Software distributed under the License is distributed on an "AS IS" basis. + * ALL WARRANTIES ARE DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED + * WARRANTIES OF MERCHANTABILITY, OF FITNESS FOR A PARTICULAR PURPOSE OR OF + * NON-INFRINGEMENT. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Software is CID font code that was developed by Silicon + * Graphics, Inc. + */ +/* $XFree86: xc/lib/font/Type1/t1intf.h,v 1.6 2001/01/17 19:43:23 dawes Exp $ */ + +#ifdef BUILDCID +#define XFONT_CID 1 +#endif + +#if XFONT_CID +#include "AFM.h" +#endif + +struct type1font { + CharInfoPtr pDefault; + CharInfoRec glyphs[256]; +}; + +#if XFONT_CID +typedef struct cid_glyphs { + char *CIDFontName; + char *CMapName; + long dataoffset; + double pixel_matrix[4]; + CharInfoPtr pDefault; + CharInfoRec **glyphs; + FontInfo *AFMinfo; +#ifdef USE_MMAP + unsigned char *CIDdata; + long CIDsize; +#endif +} cidglyphs; +#endif + +/* + * Function prototypes + */ +/* t1funcs.c */ +#if XFONT_CID +extern int CIDOpenScalable ( FontPathElementPtr fpe, FontPtr *ppFont, + int flags, FontEntryPtr entry, char *fileName, + FontScalablePtr vals, fsBitmapFormat format, + fsBitmapFormatMask fmask, + FontPtr non_cachable_font ); +#endif +extern int Type1OpenScalable ( FontPathElementPtr fpe, FontPtr *ppFont, + int flags, FontEntryPtr entry, char *fileName, + FontScalablePtr vals, fsBitmapFormat format, + fsBitmapFormatMask fmask, + FontPtr non_cachable_font ); +#if XFONT_CID +extern unsigned int getCID ( FontPtr pFont, unsigned int charcode ); +extern int CIDGetGlyphs ( FontPtr pFont, unsigned long count, + unsigned char *chars, FontEncoding charEncoding, + unsigned long *glyphCount, CharInfoPtr *glyphs ); +extern int CIDGetMetrics ( FontPtr pFont, unsigned long count, + unsigned char *chars, FontEncoding charEncoding, + unsigned long *glyphCount, xCharInfo **glyphs ); +extern void CIDCloseFont ( FontPtr pFont ); +#endif +extern void Type1CloseFont ( FontPtr pFont ); +extern int Type1ReturnCodeToXReturnCode ( int rc ); +#if XFONT_CID +extern CharInfoPtr CIDRenderGlyph ( FontPtr pFont, psobj *charstringP, + psobj *subarrayP, + struct blues_struct *bluesP, + CharInfoPtr pci, int *mode ); +#endif + +/* t1info.c */ +#ifdef CID_ALL_CHARS +extern void ComputeBoundsAllChars ( FontPtr pFont, char *cfmfilename, double sxmult ); +#endif +#if XFONT_CID +extern int CIDGetInfoScalable ( FontPathElementPtr fpe, FontInfoPtr pInfo, + FontEntryPtr entry, FontNamePtr fontName, + char *fileName, FontScalablePtr Vals ); +#endif +extern int Type1GetInfoScalable ( FontPathElementPtr fpe, FontInfoPtr pInfo, + FontEntryPtr entry, FontNamePtr fontName, + char *fileName, FontScalablePtr Vals ); +#if XFONT_CID +extern void CIDFillFontInfo ( FontPtr pFont, FontScalablePtr Vals, + char *Filename, char *Fontname, char *Cmapname, +#ifdef HAVE_CFM + char *cfmfilename, +#endif + long sAscent, long sDescent, double sxmult ); +#endif +extern void T1FillFontInfo ( FontPtr pFont, FontScalablePtr Vals, + char *Filename, char *Fontname, long sWidth ); +extern void Type1InitStdProps ( void ); + +/* cidchar.c */ +extern CharInfoPtr CIDGetGlyphInfo ( FontPtr pFont, unsigned int cidcode, + CharInfoPtr pci, int *rc ); +extern int CIDGetAFM ( FontPtr pFont, unsigned long count, + unsigned char *chars, FontEncoding charEncoding, + unsigned long *glyphCount, CharInfoPtr *glyphs, + char *cidafmfile ); diff --git a/nx-X11/lib/font/Type1/t1io.c b/nx-X11/lib/font/Type1/t1io.c new file mode 100644 index 000000000..42b8bb6be --- /dev/null +++ b/nx-X11/lib/font/Type1/t1io.c @@ -0,0 +1,388 @@ +/* $Xorg: t1io.c,v 1.3 2000/08/17 19:46:33 cpqbld Exp $ */ +/* Copyright International Business Machines,Corp. 1991 + * All Rights Reserved + * + * License to use, copy, modify, and distribute this software + * and its documentation for any purpose and without fee is + * hereby granted, provided that the above copyright notice + * appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, + * and that the name of IBM not be used in advertising or + * publicity pertaining to distribution of the software without + * specific, written prior permission. + * + * IBM PROVIDES THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES + * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT + * LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE QUALITY AND + * PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT + * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF + * THE SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM) ASSUMES + * THE ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN + * NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + * Author: Carol H. Thompson IBM Almaden Research Center + */ +/* Copyright (c) 1994-1999 Silicon Graphics, Inc. All Rights Reserved. + * + * The contents of this file are subject to the CID Font Code Public Licence + * Version 1.0 (the "License"). You may not use this file except in compliance + * with the Licence. You may obtain a copy of the License at Silicon Graphics, + * Inc., attn: Legal Services, 2011 N. Shoreline Blvd., Mountain View, CA + * 94043 or at http://www.sgi.com/software/opensource/cid/license.html. + * + * Software distributed under the License is distributed on an "AS IS" basis. + * ALL WARRANTIES ARE DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED + * WARRANTIES OF MERCHANTABILITY, OF FITNESS FOR A PARTICULAR PURPOSE OR OF + * NON-INFRINGEMENT. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Software is CID font code that was developed by Silicon + * Graphics, Inc. + */ +/* $XFree86: xc/lib/font/Type1/t1io.c,v 3.8 2001/01/17 19:43:23 dawes Exp $ */ +/******************************************************************* +* I/O package for Type 1 font reading +********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#ifdef BUILDCID +#define XFONT_CID 1 +#endif + +#ifndef STATIC +#define STATIC static +#endif + +#ifndef FONTMODULE +#include <fcntl.h> +#include <unistd.h> +#else +#include "Xdefs.h" +#include "Xmd.h" /* INT32 declaration */ +#include "xf86_ansic.h" +#endif +#include "t1stdio.h" +#include "t1hdigit.h" +#ifdef WIN32 +#include <X11/Xw32defs.h> +#endif +#include <X11/Xdefs.h> + +/* Constants and variables used in the decryption */ +#define c1 ((unsigned short)52845) +#define c2 ((unsigned short)22719) +static unsigned short r; +static int asc, Decrypt; +static int extrach; +static int haveextrach; + +/* Our single FILE structure and buffer for this package */ +STATIC F_FILE TheFile; +STATIC unsigned char TheBuffer[F_BUFSIZ]; + +/* Our routines */ +static int T1Decrypt ( unsigned char *p, int len ); +static int T1Fill ( F_FILE *f ); + +#if XFONT_CID +void +resetDecrypt(void) +{ + Decrypt = 0; +} +#endif + +/* -------------------------------------------------------------- */ +/*ARGSUSED*/ +F_FILE * +T1Open(char *fn, /* Pointer to filename */ + char *mode) /* Pointer to open mode string */ +{ + F_FILE *of = &TheFile; + int oflags = O_RDONLY; /* We know we are only reading */ + + Decrypt = 0; + +#ifdef O_BINARY /* VMS or DOS */ + oflags |= O_BINARY; +#endif + of->fd = open(fn, oflags, 0); + if (of->fd < 0) + return NULL; + + /* Initialize the buffer information of our file descriptor */ + of->b_base = TheBuffer; + of->b_size = F_BUFSIZ; + of->b_ptr = NULL; + of->b_cnt = 0; + of->flags = 0; + of->error = 0; + haveextrach = 0; + return &TheFile; +} /* end Open */ + +/* -------------------------------------------------------------- */ +int /* Read one character */ +T1Getc(F_FILE *f) /* Stream descriptor */ +{ + if (f->b_base == NULL) return EOF; /* already closed */ + + if (f->flags & UNGOTTENC) { /* there is an ungotten c */ + f->flags &= ~UNGOTTENC; + return (int) f->ungotc; + } + + if (f->b_cnt == 0) /* Buffer needs to be (re)filled */ + f->b_cnt = T1Fill(f); + if (f->b_cnt > 0) return (f->b_cnt--, (int) *(f->b_ptr++)); + else { + f->flags |= FIOEOF; + return EOF; + } +} /* end Getc */ + +/* -------------------------------------------------------------- */ +int /* Put back one character */ +T1Ungetc(int c, + F_FILE *f) /* Stream descriptor */ +{ + if (c != EOF) { + f->ungotc = c; + f->flags |= UNGOTTENC; /* set flag */ + f->flags &= ~FIOEOF; /* reset EOF */ + } + return c; +} /* end Ungetc */ + +/* -------------------------------------------------------------- */ +int /* Read n items into caller's buffer */ +T1Read(char *buffP, /* Buffer to be filled */ + int size, /* Size of each item */ + int n, /* Number of items to read */ + F_FILE *f) /* Stream descriptor */ +{ + int bytelen, cnt, i; + F_char *p = (F_char *)buffP; + int icnt; /* Number of characters to read */ + + if (f->b_base == NULL) return 0; /* closed */ + icnt = (size!=1)?n*size:n; /* Number of bytes we want */ + + if (f->flags & UNGOTTENC) { /* there is an ungotten c */ + f->flags &= ~UNGOTTENC; + *(p++) = f->ungotc; + icnt--; bytelen = 1; + } + else bytelen = 0; + + while (icnt > 0) { + /* First use any bytes we have buffered in the stream buffer */ + if ((cnt=f->b_cnt) > 0) { + if (cnt > icnt) cnt = icnt; + for (i=0; i<cnt; i++) *(p++) = *(f->b_ptr++); + f->b_cnt -= cnt; + icnt -= cnt; + bytelen += cnt; + } + + if ((icnt == 0) || (f->flags & FIOEOF)) break; + + f->b_cnt = T1Fill(f); + } + return ((size!=1)?bytelen/size:bytelen); +} /* end Read */ + +/* -------------------------------------------------------------- */ +int /* Close the file */ +T1Close(F_FILE *f) /* Stream descriptor */ +{ + if (f->b_base == NULL) return 0; /* already closed */ + f->b_base = NULL; /* no valid stream */ + return close(f->fd); +} /* end Close */ + + +/* -------------------------------------------------------------- */ +F_FILE * /* Initialization */ +T1eexec(F_FILE *f) /* Stream descriptor */ +{ + int i, c; + int H; + unsigned char *p; + unsigned char randomP[8]; + + r = 55665; /* initial key */ + asc = 1; /* indicate ASCII form */ + + /* Consume the 4 random bytes, determining if we are also to + ASCIIDecodeHex as we process our input. (See pages 63-64 + of the Adobe Type 1 Font Format book.) */ + + /* Skip over any initial white space chars */ + while (HighHexP[c=_XT1getc(f)] == HWHITE_SPACE) ; + + /* If ASCII, the next 7 chars are guaranteed consecutive */ + randomP[0] = c; /* store first non white space char */ + T1Read((pointer)(randomP+1), 1, 3, f); /* read 3 more, for a total of 4 */ + /* store first four chars */ + for (i=0,p=randomP; i<4; i++) { /* Check 4 valid ASCIIEncode chars */ + if (HighHexP[*p++] > LAST_HDIGIT) { /* non-ASCII byte */ + asc = 0; + break; + } + } + if (asc) { /* ASCII form, convert first eight bytes to binary */ + T1Read((pointer)(randomP+4), 1, 4, f); /* Need four more */ + for (i=0,p=randomP; i<4; i++) { /* Convert */ + H = HighHexP[*p++]; + randomP[i] = H | LowHexP[*p++]; + } + } + + /* Adjust our key */ + for (i=0,p=randomP; i<4; i++) { + r = (*p++ + r) * c1 + c2; + } + + /* Decrypt the remaining buffered bytes */ + f->b_cnt = T1Decrypt(f->b_ptr, f->b_cnt); + Decrypt = 1; + return (T1Feof(f))?NULL:f; +} /* end eexec */ + +#if XFONT_CID +F_FILE * /* Initialization */ +CIDeexec(F_FILE *f) /* Stream descriptor */ +{ + int i, c; + int H; + unsigned char *p; + unsigned char randomP[8]; + + r = 55665; /* initial key */ + asc = 1; /* indicate ASCII form */ + + /* Consume the 4 random bytes, determining if we are also to + ASCIIDecodeHex as we process our input. (See pages 63-64 + of the Adobe Type 1 Font Format book.) */ + + /* Skip over any initial white space chars */ + while (HighHexP[c=_XT1getc(f)] == HWHITE_SPACE) ; + + /* If ASCII, the next 7 chars are guaranteed consecutive */ + randomP[0] = c; /* store first non white space char */ + T1Read((pointer)(randomP+1), 1, 3, f); /* read 3 more, for a total of 4 */ + /* store first four chars */ + for (i=0,p=randomP; i<4; i++) { /* Check 4 valid ASCIIEncode chars */ + if (HighHexP[*p++] > LAST_HDIGIT) { /* non-ASCII byte */ + asc = 0; + break; + } + } + if (asc) { /* ASCII form, convert first eight bytes to binary */ + T1Read((pointer)(randomP+4), 1, 4, f); /* Need four more */ + for (i=0,p=randomP; i<4; i++) { /* Convert */ + H = HighHexP[*p++]; + randomP[i] = H | LowHexP[*p++]; + } + } + + /* Adjust our key */ + for (i=0,p=randomP; i<4; i++) { + r = (*p++ + r) * c1 + c2; + } + + /* Decrypt up to, but not including, the first '%' sign */ + if (f->b_cnt > 0) { + for (i = 0; i < f->b_cnt; i++) + if (*(f->b_ptr + i) == '%') + break; + + if (i < f->b_cnt) { + if (i == 0) + f->b_cnt = 0; + else + f->b_cnt = T1Decrypt(f->b_ptr, i); + } else + f->b_cnt = T1Decrypt(f->b_ptr, f->b_cnt); + } + Decrypt = 1; + return (T1Feof(f))?NULL:f; +} /* end eexec */ +#endif + +/* -------------------------------------------------------------- */ +STATIC int +T1Decrypt(unsigned char *p, int len) +{ + int n; + int H = 0, L; + unsigned char *inp = p; + unsigned char *tblP; + + if (asc) { + if (haveextrach) { + H = extrach; + tblP = LowHexP; + } + else tblP = HighHexP; + for (n=0; len>0; len--) { + L = tblP[*inp++]; + if (L == HWHITE_SPACE) continue; + if (L > LAST_HDIGIT) break; + if (tblP == HighHexP) { /* Got first hexit value */ + H = L; + tblP = LowHexP; + } else { /* Got second hexit value; compute value and store it */ + n++; + tblP = HighHexP; + H |= L; + /* H is an int, 0 <= H <= 255, so all of this will work */ + *p++ = H ^ (r >> 8); + r = (H + r) * c1 + c2; + } + } + if (tblP != HighHexP) { /* We had an odd number of hexits */ + extrach = H; + haveextrach = 1; + } else haveextrach = 0; + return n; + } else { + for (n = len; n>0; n--) { + H = *inp++; + *p++ = H ^ (r >> 8); + r = (H + r) * c1 + c2; + } + return len; + } +} /* end Decrypt */ + +/* -------------------------------------------------------------- */ +STATIC int /* Refill stream buffer */ +T1Fill(F_FILE *f) /* Stream descriptor */ +{ + int rc; + + rc = read(f->fd, f->b_base, F_BUFSIZ); + /* propagate any error or eof to current file */ + if (rc <= 0) { + if (rc == 0) /* means EOF */ + f->flags |= FIOEOF; + else { + f->error = (short)-rc; + f->flags |= FIOERROR; + rc = 0; + } + } + f->b_ptr = f->b_base; + if (Decrypt) rc = T1Decrypt(f->b_base, rc); + return rc; +} /* end Fill */ diff --git a/nx-X11/lib/font/Type1/t1malloc.c b/nx-X11/lib/font/Type1/t1malloc.c new file mode 100644 index 000000000..20d4212cd --- /dev/null +++ b/nx-X11/lib/font/Type1/t1malloc.c @@ -0,0 +1,759 @@ +/* $Xorg: t1malloc.c,v 1.3 2000/08/17 19:46:34 cpqbld Exp $ */ +/* Copyright International Business Machines, Corp. 1991 + * All Rights Reserved + * Copyright Lexmark International, Inc. 1991 + * All Rights Reserved + * + * License to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, + * provided that the above copyright notice appear in all copies and that + * both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of IBM or Lexmark not be + * used in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * + * IBM AND LEXMARK PROVIDE THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES OF + * ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO ANY + * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, + * AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE + * QUALITY AND PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT + * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF THE + * SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM OR LEXMARK) ASSUMES THE + * ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN NO EVENT SHALL + * IBM OR LEXMARK BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF + * THIS SOFTWARE. + */ +/* $XFree86: xc/lib/font/Type1/t1malloc.c,v 1.11 2002/02/18 20:51:57 herrb Exp $ */ + /* MALLOC CWEB V0004 LOTS */ +/* +:h1.MALLOC - Fast Memory Allocation + +This module is meant to provide portable C-style memory allocation +routines (malloc/free). + +&author. Jeffrey B. Lotspiech (lotspiech@almaden.ibm.com) + +*/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#ifndef FONTMODULE +#include <stdio.h> +#else +#include "Xdefs.h" /* Bool declaration */ +#include "Xmd.h" /* INT32 declaration */ +#include "os.h" +#include "xf86_ansic.h" +#endif +#include "objects.h" /* get #define for Abort() */ + + +/* +:h3.Define NULL + +In the beginning, C compilers made no assumptions about NULL. It was +even theoretically possible that NULL would not be 0. ANSI has tied +this down a bit. The following definition seems to be the most +popular (in terms of reducing compiler complaints), however, if your +compiler is unhappy about it, you can redefine it on the command line: +*/ +#ifndef NULL +#include <stddef.h> +#endif +/* +Of course, NULL is important because xiMalloc() is defined to return +NULL when out of memory. + +:h2.Data Structures Used to Manage Free Memory + +:h3.The "freeblock" Structure + +The list of available memory blocks is a doubly-linked list. Each +block begins with the following structure: +*/ + +struct freeblock { + long size; /* number of 'longs' in block, + including this header */ + struct freeblock *fore; /* forward in doubly-linked list */ + struct freeblock *back; /* backward in doubly-linked list */ +} ; +/* +In addition, each free block has a TRAILER that is simply the 'size' +repeated. Thus 'size' is found at the beginning of the block and at the +end of the block (size-1 longs away). 'size' includes both the header +and the trailer. + +When a block is allocated, its 'size' is turned negative (both at the +beginning and at the end). Thus, checking whether two blocks may be +combined is very simple. We merely examine both neighboring blocks' +size to see if they are positive (and hence available for combination). + +The memory address returned to the user is therefore one "long" below the +size, and one extra "long" is added to the end of the block (beyond what +the user requested) to store the trailing size. + +:h3."firstfree" and "lastfree", the Anchors to the Free List + +"firstfree" points to the first available free block; "lastfree" points +to the end of the chain of available blocks. These are linked together +by initialization code; see :hdref refid=addmem.. +*/ + +static struct freeblock firstfree = { 0L, NULL, NULL }; +static struct freeblock lastfree = { 0L, NULL, NULL }; + +/* +:h3."firstcombined" and "uncombined", Keeping Track of Uncombined Blocks + +This module is designed to make the combining of adjacent free memory +blocks be very fast. Nonetheless, combining blocks is naturally the +most expensive part of any memory system. In an X system, +it is worthwhile to defer the combination for a while, because +frequently we will end up asking for a block of exactly the same +size that we recently returned and we can save ourselves some work. + +"MAXUNCOMBINED" is the maximum number of uncombined blocks that we will +allow at any time: +*/ + +#define MAXUNCOMBINED 3 + +/* +"firstcombined" is a pointer into the free list. The uncombined blocks +are always at the front of the list. "firstcombined" points to the +first block that has been combined. +*/ +static struct freeblock *firstcombined = &lastfree; +static short uncombined = 0; /* current number of uncombined blocks */ + +/* +Uncombined blocks have a negative 'size'; in this they are like +allocated blocks. + +We store a distinctive hex pattern in 'size' when we combine a block +to help us debug: +*/ +#define COMBINED 0xBADBAD + +/* +:h3.DEBUGWORDS - Extra Memory Saved With Each Block for Debug + +We add 'DEBUGWORDS' words to each allocated block to put interesting +debug information: +*/ +#ifndef DEBUGWORDS +#define DEBUGWORDS 0 +#endif + +/* +:h3.MINEXCESS - Amount of "Excess" We Would be Willing to Ignore + +When we search the free list to find memory for a user request, we +frequently find an area that is bigger than what the user has asked for. +Normally we put the remaining words (the excess) back on the free list. +However, if the area is just slightly bigger than what the user needs, +it is counter-productive to do this, as the small amount recovered tends +to hurt by increasing memory fragmentation rather than help by providing +more available memory. "MINEXCESS" is the number of words that must be +recovered before we would bother to put the excess back on the free +list. If there is not enough excess, we just give the user more than he +asked for. +*/ + +#define MINEXCESS (7 + DEBUGWORDS) + +/* +:h3.Some Flags for Debug +*/ + +long AvailableWords = 0; /* number of words available in memory */ +char mallocdebug = 0; /* a flag that enables some chatty printf's */ + +/* +:h3.Prototypes of static functions +*/ + +static void combine ( void ); +static void freeuncombinable ( long *addr, long size ); +static void unhook ( struct freeblock *p ); +static void dumpchain ( void ); +#ifdef notused +static void reportarea ( long *area ); +#endif + +/* +:h3.whocalledme() - Debug for Memory Leaks + +This routine is 68000-specific; it copies the value of the application's +curOper variable (which is often a pointer to a character string), and +the first part of the stack at the time malloc was called into the +DEBUGWORDS area reserved with each block. +We use it to see who is malloc-ing memory without free-ing it. +*/ + +#if DEBUGWORDS + +static void +whocalledme(long *addr, /* address of memory block */ + long *stack) /* address of malloc's parameter on stack */ +{ + register long size; /* size of memory block */ + register int i; /* loop index */ + extern char *curOper; /* ptr to last operator (kept by appl.) */ + + stack--; + size = - *addr; + + addr += size - 1 - DEBUGWORDS; + *addr++ = (long) curOper; + for (i=0; i < DEBUGWORDS-1; i++) + *addr++ = *stack++; +} +#else + +#define whocalledme(addr, stack) + +#endif +/* +:h2.xiFree() - User-Callable "Return Memory" Routine + +The actual beginning of the block is one 'long' before the address we +gave to the user. The block begins and ends with '-size' in words. +*/ + +void +xiFree(long *addr) /* user's memory to be returned */ +{ + register long size; /* amount of memory in this block */ + register struct freeblock *p; /* identical to 'addr' */ + + if (addr == NULL) { /* common "mistake", so allow it (CHT) */ + printf("\nxiFree(NULL)?\n"); + return; + } + + size = *--addr; +/* +Make sure this address looks OK; 'size' must be less than zero (meaning +the block is allocated) and should be repeated at the end of the block. +*/ + if (size >= 0) + Abort("free: bad size"); + if (addr[-1 - size] != size) + Abort("free: mismatched size"); +/* +Now make this a 'freeblock' structure and tack it on the FRONT of the +free list (where uncombined blocks go): +*/ + AvailableWords -= size; /* actually INCREASES AvailableWords */ + p = (struct freeblock *) addr; + p->back = &firstfree; + (p->fore = firstfree.fore)->back = p; + firstfree.fore = p; +/* +If we have too many uncombined blocks, call combine() to combine one. +*/ + if (++uncombined > MAXUNCOMBINED) { + combine(); + if (mallocdebug) { + printf("xiFree(%p) with combine, ", (void *)addr); + dumpchain(); + } + } + else { + if (mallocdebug) { + printf("xiFree(%p), ", (void *)addr); + dumpchain(); + } + } + + return; +} + +/* +:h3.combine() - Subroutine of xiFree() to Combine Blocks + +This routine tries to combine the block just before 'firstcombined'. +In any event, that block will be moved to the end of the list (after +'firstcombined'). +*/ + +static void +combine(void) +{ + register struct freeblock *p; /* block we will try to combine */ + register long *addr; /* identical to 'p' for 'long' access */ + register long size; /* size of this block */ + register long size2; /* size of potential combinee */ + + p = firstcombined->back; + if (p == &firstfree) + Abort("why are we combining?"); + + addr = (long *) p; + size = - p->size; + if (--uncombined < 0) + Abort("too many combine()s"); + + if (addr[-1] < 0 && addr[size] < 0) { +/* +We special case the situation where no combining can be done. Then, we +just mark the chain "combined" (i.e., positive size), move the +'firstcombined' pointer back in the chain, and return. +*/ + addr[0] = addr[size - 1] = size; + firstcombined = (struct freeblock *) addr; + return; + } +/* +Otherwise, we unhook this pointer from the chain: +*/ + unhook(p); +/* +First we attempt to combine this with the block immediately above: +*/ + size2 = addr[-1]; + if (size2 > 0) { /* i.e., block above is free */ + *addr = COMBINED; /* might help debug */ + addr -= size2; + if (addr[0] != size2) + Abort("bad block above"); + unhook((struct freeblock *)addr); + size += size2; + } +/* +At this point 'addr' and 'size' may be the original block, or it may be +the newly combined block. Now we attempt to combine it with the block +below: +*/ + p = (struct freeblock *) (addr + size); + size2 = p->size; + + if (size2 > 0) { /* i.e., block below is free */ + p->size = COMBINED; + if (size2 != ((long *) p)[size2 - 1]) + Abort("bad block below"); + unhook(p); + size += size2; + } +/* +Finally we take the newly combined block and put it on the end of the +chain by calling the "freeuncombinable" subroutine: +*/ + freeuncombinable(addr, size); +} + +/* +:h3.freeuncombinable() - Free a Block That Need Not be Combined + +This block is "uncombinable" either because we have already combined +it with its eligible neighbors, or perhaps because we know it has +no neighbors. +*/ + +static void +freeuncombinable(long *addr, /* address of the block to be freed */ + long size) /* size of block in words */ +{ + register struct freeblock *p; /* a convenient synonym for 'addr' */ + +/* +Mark block allocated and combined by setting its 'size' positive: +*/ + addr[size - 1] = addr[0] = size; +/* +Now tack the block on the end of the doubly-linked free list: +*/ + p = (struct freeblock *) addr; + p->fore = &lastfree; + (p->back = lastfree.back)->fore = p; + lastfree.back = p; +/* +If we have previously had no combined blocks, we must update +'firstcombined' to point to this block: +*/ + if (firstcombined->fore == NULL) + firstcombined = p; +} + +/* +:h3.unhook() - Unhook a Block from the Doubly-linked List + +The only tricky thing here is to make sure that 'firstcombined' is +updated if this block happened to be the old 'firstcombined'. (We +would never be unhooking 'firstfree' or 'lastfree', so we do not +have to worry about the end cases.) +*/ + +static void +unhook(struct freeblock *p) /* block to unhook */ +{ + p->back->fore = p->fore; + p->fore->back = p->back; + + if (firstcombined == p) + firstcombined = p->fore; +} +/* +:h2.xiMalloc() - Main User Entry Point for Getting Memory + +We have two slightly different versions of xiMalloc(). In the case +where we have TYPE1IMAGER and a font cache, we are prepared, when nominally +out of memory, to loop calling TYPE1IMAGER's GimeSpace() to release font +cache. +*/ + +/* The following code put in by MDC on 11/10/90 */ + +#ifdef TYPE1IMAGER + +static char *malloc_local(unsigned size); + +char * +xiMalloc(unsigned size) +{ + char *memaddr; + + while ( (memaddr = malloc_local(size)) == NULL ) { + /* Ask TYPE1IMAGER to give us some of its cache back */ + if ( I_GimeSpace() == 0 ) break; /* We are really, really, out of memory */ + } + + return(memaddr); +} +#endif + +/* +Now begins the real workhorse xiMalloc() (called 'malloc_local' if +we are taking advantage of TYPE1IMAGER). Its argument is an unsigned; +at least that lets users with 16-bit integers get a 64K chunk of +memory, and it is also compatible with the definition of a "size_t" +in most systems. +*/ +#ifdef TYPE1IMAGER +static char * +malloc_local(unsigned Size) /* number of bytes the user requested */ +#else +char * +xiMalloc(unsigned Size) +#endif +{ + register long size = (long)Size; /* a working register for size */ + register struct freeblock *p; /* tentative block to be returned */ + register long excess; /* words in excess of user request */ + register long *area; /* a convenient synonym for 'p' */ + +/* +First, we increase 'size' to allow for the two size fields we will +save with the block, plus any information for debug purposes. +Then we ensure that the block will be large enough to hold our +'freeblock' information. Finally we convert it to be in words +(longs), not bytes, increased to span an integral number of double +words, so that all memory blocks dispensed with be properly aligned. +*/ + size += 2*sizeof(long) + DEBUGWORDS*sizeof(long); + if (size < sizeof(struct freeblock) + sizeof(long)) + size = sizeof(struct freeblock) + sizeof(long); + size = ((unsigned) (size + sizeof(double) - 1) / sizeof(double)) * (sizeof(double)/sizeof(long)); + +/* +For speed, we will try first to give the user back a very recently +returned block--one that is on the front of the chain before +'firstcombined'. These blocks still have negative sizes, and need +only to be "unhook"ed: +*/ + size = -size; + for (p=firstfree.fore; p != firstcombined; p=p->fore) { + if (p->size == size) { + unhook(p); + uncombined--; + if (mallocdebug) { + printf("fast xiMalloc(%ld) = %p, ", size, + (void *)p); + dumpchain(); + } + AvailableWords += size; /* decreases AvailableWords */ + whocalledme(p, &Size); + return((char *)&p->fore); + } + } +/* +Well, if we get here, there are no uncombined blocks matching the user's +request. So, we search the rest of the chain for a block that is big +enough. ('size' becomes positive again): +*/ + size = -size; + for (;; p = p->fore) { +/* +If we hit the end of the chain (p->size == 0), we are probably out of +memory. However, we should first try to combine any memory that has +not yet been combined before we give that pessimistic answer. If +we succeed in combining, we can call ourselves recursively to try to +allocate the requested amount: +*/ + if (p->size == 0) { + if (uncombined <= 0) + return(NULL); + while (firstfree.fore != firstcombined) + combine(); + return(xiMalloc(sizeof(long) * (size - 2 - DEBUGWORDS))); + } +/* +Otherwise, we keep searching until we find a big enough block: +*/ + if (p->size >= size) + break; + } +/* +At this point, 'p' contains a block at least as big as what the user +requested, so we take it off the free chain. If it is excessively big, +we return the excess to the free chain: +*/ + unhook(p); + excess = p->size - size; + area = (long *) p; + + if (excess > MINEXCESS) + freeuncombinable(area + size, excess); + else + size = p->size; + + AvailableWords -= size; +/* +Mark first and last word of block with the negative of the size, to +flag that this block is allocated: +*/ + area[size - 1] = area[0] = - size; + + if (mallocdebug) { + printf("slow xiMalloc(%ld) @ %p, ", size, (void *)area); + dumpchain(); + } + whocalledme(area, &Size); +/* +The address we return to the user is one 'long' BELOW the address of +the block. This protects our 'size' field, so we can tell the size +of the block when he returns it to us with xiFree(). Also, he better not +touch the 'size' field at the end of the block either. (That would be +nasty of him, as he would be touching memory outside of the bytes he +requested). +*/ + return((char *) (area + 1)); +} + +/* +:h2 id=addmem.addmemory() - Initialize Free Memory + +This routine should be called at initialization to initialize the +free chain. There is no standard way to do this in C. +We want the memory dispensed by malloc to be aligned on a double word +boundary (because some machines either require alignment, or are +more efficient if accesses are aligned). Since the total size of +any block created by malloc is an integral number of double words, +all we have to do to ensure alignment is to adjust each large block +added to the free chain to start on an odd long-word boundary. +(Malloc's size field will occupy the odd long and the user's memory +will then begin on an even boundary.) Since we fill in additional +size fields at the beginning and end of each of the large freeblocks, +we need only adjust the address passed to addmemory to a double word +boundary. +*/ + +#define MAXAREAS 10 /* there can be this many calls to addmemory() */ + +static long *freearea[MAXAREAS] = { NULL }; /* so we can report later */ + +void +addmemory(long *addr, /* beginning of free area */ + long size) /* number of bytes of free area */ +{ + register int i; /* loop index variable */ + register long *aaddr; /* aligned beginning of free area */ + +#if DEBUGWORDS + printf("malloc has DEBUGWORDS=%d\n", DEBUGWORDS); +#endif +/* +First link together firstfree and lastfree if necessary: +*/ + if (firstfree.fore == NULL) { + firstfree.fore = &lastfree; + lastfree.back = &firstfree; + } +/* +We'll record where the area was that was given to us for later reports: +*/ + for (i=0; i < MAXAREAS; i++) + if (freearea[i] == NULL) break; + if (i >= MAXAREAS) + Abort("too many addmemory()s"); + aaddr = (long *) ( ((long) addr + sizeof(double) - 1) & - (long)sizeof(double) ); + size -= (char *) aaddr - (char *) addr; + freearea[i] = aaddr; +/* +Convert 'size' to number of longs, and store '-size' guards at the +beginning and end of this area so we will not accidentally recombine the +first or last block: +*/ + size /= sizeof(long); + + AvailableWords += size - 2; + + aaddr[size - 1] = aaddr[0] = -size; +/* +Finally, call 'freeuncombinable' to put the remaining memory on the +free list: +*/ + freeuncombinable(aaddr + 1, size - 2); +} + +/* +:h3.delmemory() - Delete Memory Pool +*/ +void +delmemory(void) +{ + register int i; + + AvailableWords = 0; + firstfree.fore = &lastfree; + lastfree.back = &firstfree; + firstcombined = &lastfree; + uncombined = 0; + for (i=0; i<MAXAREAS; i++) + freearea[i] = NULL; +} + +/* +:h2.Debug Routines + +:h3.dumpchain() - Print the Chain of Free Blocks +*/ + +static void +dumpchain(void) +{ + register struct freeblock *p; /* current free block */ + register long size; /* size of block */ + register struct freeblock *back; /* block before 'p' */ + register int i; /* temp variable for counting */ + + printf("DUMPING FAST FREE LIST:\n"); + back = &firstfree; + for (p = firstfree.fore, i=uncombined; p != firstcombined; + p = p->fore) { + if (--i < 0) + Abort("too many uncombined areas"); + size = p->size; + printf(". . . area @ %p, size = %ld\n", (void *)p, -size); + if (size >= 0 || size != ((int *) p)[-1 - size]) + Abort("dumpchain: bad size"); + if (p->back != back) + Abort("dumpchain: bad back"); + back = p; + } + printf("DUMPING COMBINED FREE LIST:\n"); + for (; p != &lastfree; p = p->fore) { + size = p->size; + printf(". . . area @ %p, size = %ld\n", (void *)p, size); + if (size <= 0 || size != ((int *) p)[size - 1]) + Abort("dumpchain: bad size"); + if (p->back != back) + Abort("dumpchain: bad back"); + back = p; + } + if (back != lastfree.back) + Abort("dumpchain: bad lastfree"); +} + +#ifdef notused +/* +:h3.reportarea() - Display a Contiguous Set of Memory Blocks +*/ + +static void +reportarea(long *area) /* start of blocks (from addmemory) */ +{ + register long size; /* size of current block */ + register long wholesize; /* size of original area */ + register struct freeblock *p; /* pointer to block */ + + if (area == NULL) + return; + wholesize = - *area++; + wholesize -= 2; + + while (wholesize > 0) { + size = *area; + if (size < 0) { + register int i,j; + + size = -size; + printf("Allocated %5ld bytes at %p, first words=%08lx %08lx\n", + size * sizeof(long), area + 1, area[1], area[2]); +#if DEBUGWORDS + printf(" ...Last operator: %s\n", + (char *)area[size-DEBUGWORDS-1]); +#endif + for (i = size - DEBUGWORDS; i < size - 2; i += 8) { + printf(" ..."); + for (j=0; j<8; j++) + printf(" %08lx", area[i+j]); + printf("\n"); + } + + } + else { + printf("Free %ld bytes at %p\n", size * sizeof(long), + area); + if (size == 0) + Abort("zero sized memory block"); + + for (p = firstfree.fore; p != NULL; p = p->fore) + if ((long *) p == area) break; + if ((long *) p != area) + Abort("not found on forward chain"); + + for (p = lastfree.back; p != NULL; p = p->back) + if ((long *) p == area) break; + if ((long *) p != area) + Abort("not found on backward chain"); + } + if (area[0] != area[size - 1]) + Abort("unmatched check sizes"); + area += size; + wholesize -= size; + } +} + +/* +:h3.MemReport() - Display All of Memory +*/ + +void +MemReport(void) +{ + register int i; + + dumpchain(); + + for (i=0; i<MAXAREAS; i++) + reportarea(freearea[i]); +} + +/* +:h3.MemBytesAvail - Display Number of Bytes Now Available +*/ + +void +MemBytesAvail(void) +{ + printf("There are now %ld bytes available\n", AvailableWords * + sizeof(long) ); +} +#endif diff --git a/nx-X11/lib/font/Type1/t1snap.c b/nx-X11/lib/font/Type1/t1snap.c new file mode 100644 index 000000000..5618b581b --- /dev/null +++ b/nx-X11/lib/font/Type1/t1snap.c @@ -0,0 +1,85 @@ +/* $Xorg: t1snap.c,v 1.3 2000/08/17 19:46:34 cpqbld Exp $ */ +/* Copyright International Business Machines,Corp. 1991 + * All Rights Reserved + * + * License to use, copy, modify, and distribute this software + * and its documentation for any purpose and without fee is + * hereby granted, provided that the above copyright notice + * appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, + * and that the name of IBM not be used in advertising or + * publicity pertaining to distribution of the software without + * specific, written prior permission. + * + * IBM PROVIDES THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES + * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT + * LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE QUALITY AND + * PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT + * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF + * THE SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM) ASSUMES + * THE ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN + * NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ +/* $XFree86: xc/lib/font/Type1/t1snap.c,v 1.3 1999/08/22 08:58:54 dawes Exp $ */ + + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include "objects.h" +#include "spaces.h" +#include "paths.h" +#include "pictures.h" + +/* +:h2.Handle Functions + +:h3.Phantom() - Returns a Move Segment Equivalent to Handles + +This is a user operator. Its new name is QueryHandle. +*/ + +struct segment * +t1_Phantom(struct segment *p) /* object to take the Phantom of */ +{ + struct fractpoint pt; /* handle size will built here */ + + if (p == NULL) + pt.x = pt.y = 0; + else + PathDelta(p, &pt); + + return(PathSegment(MOVETYPE, pt.x, pt.y)); +} + +/* +:h3.Snap() - Force Ending Handle of Object to Origin + +This is a user operator. +*/ + +struct segment * +t1_Snap(struct segment *p) /* path to snap */ +{ + struct fractpoint pt; /* for finding length of path */ + + if (p == NULL) + return(NULL); + p = UniquePath(p); + + PathDelta(p, &pt); + if (p->last->type == MOVETYPE) { + p->last->dest.x -= pt.x; + p->last->dest.y -= pt.y; + } + else + p = JoinSegment(p, MOVETYPE, -pt.x, -pt.y, NULL); + return(p); +} diff --git a/nx-X11/lib/font/Type1/t1stdio.h b/nx-X11/lib/font/Type1/t1stdio.h new file mode 100644 index 000000000..2ed083253 --- /dev/null +++ b/nx-X11/lib/font/Type1/t1stdio.h @@ -0,0 +1,101 @@ +/* $Xorg: t1stdio.h,v 1.3 2000/08/17 19:46:34 cpqbld Exp $ */ +/* Copyright International Business Machines,Corp. 1991 + * All Rights Reserved + * + * License to use, copy, modify, and distribute this software + * and its documentation for any purpose and without fee is + * hereby granted, provided that the above copyright notice + * appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, + * and that the name of IBM not be used in advertising or + * publicity pertaining to distribution of the software without + * specific, written prior permission. + * + * IBM PROVIDES THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES + * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT + * LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE QUALITY AND + * PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT + * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF + * THE SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM) ASSUMES + * THE ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN + * NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ +/* $XFree86: xc/lib/font/Type1/t1stdio.h,v 1.9 2001/01/17 19:43:24 dawes Exp $ */ +/* T1IO FILE structure and related stuff */ +#ifdef BUILDCID +#define XFONT_CID 1 +#endif + +#ifdef XFree86LOADER +#undef FILE +#endif +#define FILE F_FILE +typedef unsigned char F_char; + +typedef struct F_FILE { + F_char *b_base; /* Pointer to beginning of buffer */ + long b_size; /* Size of the buffer */ + F_char *b_ptr; /* Pointer to next char in buffer */ + long b_cnt; /* Number of chars remaining in buffer */ + F_char flags; /* other flags; != 0 means getc must call fgetc */ + F_char ungotc; /* Place for ungotten char; flag set if present */ + short error; /* error status */ + int fd; /* underlying file descriptor */ +} F_FILE; + + +/* defines for flags */ +#define UNGOTTENC (0x01) +#define FIOEOF (0x80) +#define FIOERROR (0x40) + +#ifndef NULL +#include <stddef.h> +#endif + +#define EOF (-1) /* end of file */ +#define F_BUFSIZ (512) + +#define _XT1getc(f) \ + ( \ + ( ((f)->b_cnt > 0) && ((f)->flags == 0) ) ? \ + ( (f)->b_cnt--, (unsigned int)*( (f)->b_ptr++ ) ) : \ + T1Getc(f) \ + ) + +#define T1Feof(f) (((f)->flags & FIOEOF) && ((f)->b_cnt==0)) + +#if XFONT_CID +extern F_FILE *CIDeexec ( FILE *f ); +#endif + +extern FILE *T1Open ( char *fn, char *mode ); +extern int T1Getc ( FILE *f ); +extern int T1Ungetc ( int c, FILE *f ); +extern int T1Read ( char *buffP, int size, int n, FILE *f ); +extern int T1Close ( FILE *f ); +extern FILE *T1eexec ( FILE *f ); +extern void resetDecrypt ( void ); + +#undef fclose +#undef fopen +#undef ungetc +#undef fgetc +#undef fread +#undef feof +#undef ferror +#define fclose(f) T1Close(f) +#define fopen(name,mode) T1Open(name,mode) +#define ungetc(c,f) T1Ungetc(c,f) +#define fgetc(f) T1Getc(f) + +#define fread(bufP,size,n,f) T1Read(bufP,size,n,f) +#define feof(f) (((f)->flags & FIOEOF) && ((f)->b_cnt==0)) +#define ferror(f) (((f)->flags & FIOERROR)?(f)->error:0) diff --git a/nx-X11/lib/font/Type1/t1stub.c b/nx-X11/lib/font/Type1/t1stub.c new file mode 100644 index 000000000..2fb1d797f --- /dev/null +++ b/nx-X11/lib/font/Type1/t1stub.c @@ -0,0 +1,56 @@ +/* $Xorg: t1stub.c,v 1.3 2000/08/17 19:46:34 cpqbld Exp $ */ +/* Copyright International Business Machines,Corp. 1991 + * All Rights Reserved + * + * License to use, copy, modify, and distribute this software + * and its documentation for any purpose and without fee is + * hereby granted, provided that the above copyright notice + * appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, + * and that the name of IBM not be used in advertising or + * publicity pertaining to distribution of the software without + * specific, written prior permission. + * + * IBM PROVIDES THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES + * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT + * LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE QUALITY AND + * PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT + * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF + * THE SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM) ASSUMES + * THE ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN + * NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ +/* $XFree86: xc/lib/font/Type1/t1stub.c,v 1.8 2001/01/17 19:43:24 dawes Exp $ */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#ifdef FONTMODULE +#include "Xdefs.h" /* Bool declaration */ +#include "Xmd.h" /* INT32 declaration */ +#include "os.h" +#include "xf86_ansic.h" +#else +#include <stdio.h> +#endif +#include "objects.h" /* get #define for Abort() */ + +static void +xiStub(void) +{ + printf("xiStub called\n"); + Abort("xiStub called"); +} + +void +t1_DumpText(void) +{ + xiStub(); +} diff --git a/nx-X11/lib/font/Type1/t1test.c b/nx-X11/lib/font/Type1/t1test.c new file mode 100644 index 000000000..1da74168f --- /dev/null +++ b/nx-X11/lib/font/Type1/t1test.c @@ -0,0 +1,246 @@ +/* $Xorg: t1test.c,v 1.3 2000/08/17 19:46:34 cpqbld Exp $ */ +/* Copyright International Business Machines,Corp. 1991 + * All Rights Reserved + * + * License to use, copy, modify, and distribute this software + * and its documentation for any purpose and without fee is + * hereby granted, provided that the above copyright notice + * appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, + * and that the name of IBM not be used in advertising or + * publicity pertaining to distribution of the software without + * specific, written prior permission. + * + * IBM PROVIDES THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES + * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT + * LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE QUALITY AND + * PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT + * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF + * THE SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM) ASSUMES + * THE ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN + * NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +#include <X11/fonts/fntfilst.h> +#include <X11/fonts/FSproto.h> + +#define DECIPOINTSPERINCH 722.7 +#define DEFAULTRES 75 +#define DEFAULTPOINTSIZE 120 + +FontScalableRec vals; +FontEntryRec entry; + +int main(argc, argv) + int argc; + char *argv[]; +{ + int h; + char temp[80]; + char file[80]; + char glyphcode[1]; + FontPtr fontptr; + CharInfoRec *glyphs[1]; + int count; + int code; + int rc = -1; + + T1FillVals(&vals); + Type1RegisterFontFileFunctions(); + entry.name.name = "-adobe-utopia-medium-r-normal--0-0-0-0-p-0-iso8859-1"; + + for (;;) { + printf("T1TEST: "); + gets(temp); + glyphcode[0] = '\0'; + + switch(temp[0]) { + + case 'c': + if (1 != sscanf(&temp[2], "%c", glyphcode)) + printf("glyph code?\n"); + break; + + case 'x': + if (1 != sscanf(&temp[2], "%x", &code)) + printf("glyph code?\n"); + else + glyphcode[0] = code; + break; + + case 'd': + if (1 != sscanf(&temp[2], "%d", &code)) + printf("glyph code?\n"); + else + glyphcode[0] = code; + break; + + case 'h': + if (1 != sscanf(&temp[2], "%d", &h)) + printf("height?\n"); + vals.pixel = h; + rc = Type1OpenScalable(NULL, &fontptr, 0, &entry, file, &vals, 0, 0); + break; + + case 'f': + if (1 != sscanf(&temp[2], "%s", file)) + printf("file name?\n"); + rc = Type1OpenScalable(NULL, &fontptr, 0, &entry, file, &vals, 0, 0); + break; + + case 't': + if (1 != sscanf(&temp[2], "%s", file)) + printf("file name?\n"); + vals.pixel = 8; + rc = Type1OpenScalable(NULL, &fontptr, 0, &entry, file, &vals, 0, 0); + if (rc != Successful) break; + vals.pixel = 20; + rc = Type1OpenScalable(NULL, &fontptr, 0, &entry, file, &vals, 0, 0); + if (rc != Successful) break; + vals.pixel = 50; + rc = Type1OpenScalable(NULL, &fontptr, 0, &entry, file, &vals, 0, 0); + glyphcode[0] = 'A'; + printf("From font '%s':\n", file); + break; + + case 'q': + return 0; + + default: + printf("unknown command '%c', must one of 'qfchdxt'\n", temp[0]); + + } + if (rc == Successful) { + if (glyphcode[0] != '\0') { + (*fontptr->get_glyphs)(fontptr, 1, glyphcode, 0, &count, glyphs); + if (count > 0) + Display(glyphs[0]); + else + printf("Code %x not valid in this font\n", glyphcode[0]); + } + } + else + printf("Bad font (rc = %d, file='%s')\n", rc, file); + } +} + +static void Display(glyph) + CharInfoRec *glyph; +{ + int h,w; + unsigned char *p; + int data; + int i; + + p = glyph->bits; + + printf("Metrics: left=%d, right=%d, w=%d, above=%d, below=%d\n", + glyph->metrics.leftSideBearing, + glyph->metrics.rightSideBearing, + glyph->metrics.characterWidth, + glyph->metrics.ascent, + glyph->metrics.descent); + + for (h=glyph->metrics.ascent + glyph->metrics.descent; --h >= 0;) { + w = glyph->metrics.rightSideBearing - glyph->metrics.leftSideBearing; + while (w > 0) { + data = *p++; + for (i=0; i<8; i++) { + if (--w < 0) + break; + if (data & 0x80) + printf("X"); + else + printf("."); + data <<= 1; + } + } + printf("\n"); + } +} + +T1FillVals(vals) + FontScalablePtr vals; +{ + FontResolutionPtr res; + int x_res = DEFAULTRES; + int y_res = DEFAULTRES; + int pointsize = DEFAULTPOINTSIZE; /* decipoints */ + int num_res; + + /* Must have x, y, and pixel */ + if (!vals->x || !vals->y || !vals->pixel) { + res = GetClientResolutions(&num_res); + if (num_res) { + if (res->x_resolution) + x_res = res->x_resolution; + if (res->y_resolution) + y_res = res->y_resolution; + if (res->point_size) + pointsize = res->point_size; + } + if (!vals->x) + vals->x = x_res; + if (!vals->y) + vals->y = y_res; + if (!vals->point) { + if (!vals->pixel) vals->point = pointsize; + else vals->point = (vals->pixel * DECIPOINTSPERINCH) / vals->y; + } + if (!vals->pixel) + vals->pixel = (vals->point * vals->y) / DECIPOINTSPERINCH; + /* Make sure above arithmetic is normally in range and will + round properly. +++ */ + } +} + +int CheckFSFormat(format, fmask, bit, byte, scan, glyph, image) + int format,fmask,*bit,*byte,*scan,*glyph,*image; +{ + *bit = *byte = 1; + *glyph = *scan = *image = 1; + return Successful; + +} + +char *MakeAtom(p) + char *p; +{ + return p; +} + + +FontResolutionPtr GetClientResolutions(resP) + int *resP; +{ + *resP = 0; +}; + +char *Xalloc(size) + int size; +{ + extern char *malloc(); + return(malloc(size)); +} + +void Xfree() +{ + free(); +} + +FontDefaultFormat() { ; } + +FontFileRegisterRenderer() { ; } + +GenericGetBitmaps() { ; } +GenericGetExtents() { ; } + +FontParseXLFDName() { ; } +FontComputeInfoAccelerators() { ; } diff --git a/nx-X11/lib/font/Type1/t1unicode.c b/nx-X11/lib/font/Type1/t1unicode.c new file mode 100644 index 000000000..136cc4441 --- /dev/null +++ b/nx-X11/lib/font/Type1/t1unicode.c @@ -0,0 +1,251 @@ +/* +Copyright (c) 1998 by Juliusz Chroboczek + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +/* $XFree86$ */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include "t1unicode.h" + +static char* table_32[] = +{ "space", "exclam", "quotedbl", "numbersign", "dollar", "percent", + "ampersand", "quotesingle", "parenleft", "parenright", "asterisk", + "plus", "comma", "hyphen", "period", "slash", "zero", "one", "two", + "three", "four", "five", "six", "seven", "eight", "nine", "colon", + "semicolon", "less", "equal", "greater", "question", "at", "A", "B", + "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", + "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "bracketleft", + "backslash", "bracketright", "asciicircum", "underscore", "grave", + "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", + "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", + "braceleft", "bar", "braceright", "asciitilde", 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, "space", "exclamdown", "cent", "sterling", "currency", "yen", + "brokenbar", "section", "dieresis", "copyright", "ordfeminine", + "guillemotleft", "logicalnot", "hyphen", "registered", "macron", + "degree", "plusminus", "twosuperior", "threesuperior", "acute", "mu", + "paragraph", "periodcentered", "cedilla", "onesuperior", + "ordmasculine", "guillemotright", "onequarter", "onehalf", + "threequarters", "questiondown", "Agrave", "Aacute", "Acircumflex", + "Atilde", "Adieresis", "Aring", "AE", "Ccedilla", "Egrave", "Eacute", + "Ecircumflex", "Edieresis", "Igrave", "Iacute", "Icircumflex", + "Idieresis", "Eth", "Ntilde", "Ograve", "Oacute", "Ocircumflex", + "Otilde", "Odieresis", "multiply", "Oslash", "Ugrave", "Uacute", + "Ucircumflex", "Udieresis", "Yacute", "Thorn", "germandbls", "agrave", + "aacute", "acircumflex", "atilde", "adieresis", "aring", "ae", + "ccedilla", "egrave", "eacute", "ecircumflex", "edieresis", "igrave", + "iacute", "icircumflex", "idieresis", "eth", "ntilde", "ograve", + "oacute", "ocircumflex", "otilde", "odieresis", "divide", "oslash", + "ugrave", "uacute", "ucircumflex", "udieresis", "yacute", "thorn", + "ydieresis", "Amacron", "amacron", "Abreve", "abreve", "Aogonek", + "aogonek", "Cacute", "cacute", "Ccircumflex", "ccircumflex", + "Cdotaccent", "cdotaccent", "Ccaron", "ccaron", "Dcaron", "dcaron", + "Dcroat", "dcroat", "Emacron", "emacron", "Ebreve", "ebreve", + "Edotaccent", "edotaccent", "Eogonek", "eogonek", "Ecaron", "ecaron", + "Gcircumflex", "gcircumflex", "Gbreve", "gbreve", "Gdotaccent", + "gdotaccent", "Gcommaaccent", "gcommaaccent", "Hcircumflex", + "hcircumflex", "Hbar", "hbar", "Itilde", "itilde", "Imacron", + "imacron", "Ibreve", "ibreve", "Iogonek", "iogonek", "Idotaccent", + "dotlessi", "IJ", "ij", "Jcircumflex", "jcircumflex", "Kcommaaccent", + "kcommaaccent", "kgreenlandic", "Lacute", "lacute", "Lcommaaccent", + "lcommaaccent", "Lcaron", "lcaron", "Ldot", "ldot", "Lslash", + "lslash", "Nacute", "nacute", "Ncommaaccent", "ncommaaccent", + "Ncaron", "ncaron", "napostrophe", "Eng", "eng", "Omacron", "omacron", + "Obreve", "obreve", "Ohungarumlaut", "ohungarumlaut", "OE", "oe", + "Racute", "racute", "Rcommaaccent", "rcommaaccent", "Rcaron", + "rcaron", "Sacute", "sacute", "Scircumflex", "scircumflex", + "Scommaaccent", "scommaaccent", "Scaron", "scaron", "Tcommaaccent", + "tcommaaccent", "Tcaron", "tcaron", "Tbar", "tbar", "Utilde", + "utilde", "Umacron", "umacron", "Ubreve", "ubreve", "Uring", "uring", + "Uhungarumlaut", "uhungarumlaut", "Uogonek", "uogonek", "Wcircumflex", + "wcircumflex", "Ycircumflex", "ycircumflex", "Ydieresis", "Zacute", + "zacute", "Zdotaccent", "zdotaccent", "Zcaron", "zcaron", "longs", 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "florin", 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "Ohorn", "ohorn", 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, "Uhorn", "uhorn", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "Gcaron", + "gcaron", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + "Aringacute", "aringacute", "AEacute", "aeacute", "Oslashacute", + "oslashacute", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, "afii57929", "afii64937", 0, 0, 0, 0, 0, 0, + 0, 0, "circumflex", "caron", 0, "macron", 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, "breve", "dotaccent", "ring", "ogonek", "tilde", + "hungarumlaut", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "gravecomb", + "acutecomb", 0, "tildecomb", 0, 0, 0, 0, 0, "hookabovecomb", 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + "dotbelowcomb", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, "tonos", "dieresistonos", "Alphatonos", + "anoteleia", "Epsilontonos", "Etatonos", "Iotatonos", 0, + "Omicrontonos", 0, "Upsilontonos", "Omegatonos", "iotadieresistonos", + "Alpha", "Beta", "Gamma", "Delta", "Epsilon", "Zeta", "Eta", "Theta", + "Iota", "Kappa", "Lambda", "Mu", "Nu", "Xi", "Omicron", "Pi", "Rho", + 0, "Sigma", "Tau", "Upsilon", "Phi", "Chi", "Psi", "Omega", + "Iotadieresis", "Upsilondieresis", "alphatonos", "epsilontonos", + "etatonos", "iotatonos", "upsilondieresistonos", "alpha", "beta", + "gamma", "delta", "epsilon", "zeta", "eta", "theta", "iota", "kappa", + "lambda", "mu", "nu", "xi", "omicron", "pi", "rho", "sigma1", "sigma", + "tau", "upsilon", "phi", "chi", "psi", "omega", "iotadieresis", + "upsilondieresis", "omicrontonos", "upsilontonos", "omegatonos", 0, 0, + "theta1", "Upsilon1", 0, 0, "phi1", "omega1", 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "afii10023", "afii10051", + "afii10052", "afii10053", "afii10054", "afii10055", "afii10056", + "afii10057", "afii10058", "afii10059", "afii10060", "afii10061", 0, + "afii10062", "afii10145", "afii10017", "afii10018", "afii10019", + "afii10020", "afii10021", "afii10022", "afii10024", "afii10025", + "afii10026", "afii10027", "afii10028", "afii10029", "afii10030", + "afii10031", "afii10032", "afii10033", "afii10034", "afii10035", + "afii10036", "afii10037", "afii10038", "afii10039", "afii10040", + "afii10041", "afii10042", "afii10043", "afii10044", "afii10045", + "afii10046", "afii10047", "afii10048", "afii10049", "afii10065", + "afii10066", "afii10067", "afii10068", "afii10069", "afii10070", + "afii10072", "afii10073", "afii10074", "afii10075", "afii10076", + "afii10077", "afii10078", "afii10079", "afii10080", "afii10081", + "afii10082", "afii10083", "afii10084", "afii10085", "afii10086", + "afii10087", "afii10088", "afii10089", "afii10090", "afii10091", + "afii10092", "afii10093", "afii10094", "afii10095", "afii10096", + "afii10097", 0, "afii10071", "afii10099", "afii10100", "afii10101", + "afii10102", "afii10103", "afii10104", "afii10105", "afii10106", + "afii10107", "afii10108", "afii10109", 0, "afii10110", "afii10193", 0, + 0, "afii10146", "afii10194", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + "afii10147", "afii10195", "afii10148", "afii10196", 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + "afii10050", "afii10098", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "afii10846", 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + "afii57799", "afii57801", "afii57800", "afii57802", "afii57793", + "afii57794", "afii57795", "afii57798", "afii57797", "afii57806", 0, + "afii57796", "afii57807", "afii57839", "afii57645", "afii57841", + "afii57842", "afii57804", "afii57803", "afii57658", 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, "afii57664", "afii57665", "afii57666", "afii57667", + "afii57668", "afii57669", "afii57670", "afii57671", "afii57672", + "afii57673", "afii57674", "afii57675", "afii57676", "afii57677", + "afii57678", "afii57679", "afii57680", "afii57681", "afii57682", + "afii57683", "afii57684", "afii57685", "afii57686", "afii57687", + "afii57688", "afii57689", "afii57690", 0, 0, 0, 0, 0, "afii57716", + "afii57717", "afii57718", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "afii57388", 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, "afii57403", 0, 0, 0, "afii57407", 0, "afii57409", + "afii57410", "afii57411", "afii57412", "afii57413", "afii57414", + "afii57415", "afii57416", "afii57417", "afii57418", "afii57419", + "afii57420", "afii57421", "afii57422", "afii57423", "afii57424", + "afii57425", "afii57426", "afii57427", "afii57428", "afii57429", + "afii57430", "afii57431", "afii57432", "afii57433", "afii57434", 0, 0, + 0, 0, 0, "afii57440", "afii57441", "afii57442", "afii57443", + "afii57444", "afii57445", "afii57446", "afii57470", "afii57448", + "afii57449", "afii57450", "afii57451", "afii57452", "afii57453", + "afii57454", "afii57455", "afii57456", "afii57457", "afii57458", 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "afii57392", "afii57393", + "afii57394", "afii57395", "afii57396", "afii57397", "afii57398", + "afii57399", "afii57400", "afii57401", "afii57381", 0, 0, "afii63167", + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "afii57511", 0, 0, 0, 0, "afii57506", + 0, 0, 0, 0, 0, 0, 0, "afii57507", 0, "afii57512", 0, 0, 0, 0, 0, 0, 0, + 0, "afii57513", 0, 0, 0, 0, 0, 0, "afii57508", 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, "afii57505", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "afii57509", 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, "afii57514", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "afii57519", 0, 0, "afii57534", 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + +static char* table_2000[] = /* general punctuation, s*scripts, currency */ +{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "afii61664", "afii301", "afii299", + "afii300", 0, 0, "figuredash", "endash", "emdash", "afii00208", 0, + "underscoredbl", "quoteleft", "quoteright", "quotesinglbase", + "quotereversed", "quotedblleft", "quotedblright", "quotedblbase", 0, + "dagger", "daggerdbl", "bullet", 0, "onedotenleader", + "twodotenleader", "ellipsis", 0, 0, 0, 0, 0, "afii61573", "afii61574", + "afii61575", 0, "perthousand", 0, "minute", "second", 0, 0, 0, 0, 0, + "guilsinglleft", "guilsinglright", 0, "exclamdbl", 0, 0, 0, 0, 0, 0, + 0, "fraction", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, "zerosuperior", 0, 0, 0, "foursuperior", "fivesuperior", + "sixsuperior", "sevensuperior", "eightsuperior", "ninesuperior", 0, 0, + 0, "parenleftsuperior", "parenrightsuperior", "nsuperior", + "zeroinferior", "oneinferior", "twoinferior", "threeinferior", + "fourinferior", "fiveinferior", "sixinferior", "seveninferior", + "eightinferior", "nineinferior", 0, 0, 0, "parenleftinferior", + "parenrightinferior", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, "colonmonetary", 0, "franc", "lira", 0, 0, "peseta", 0, 0, + "afii57636", "dong", "Euro", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + +static char* table_2500[]= /* line and box drawing */ +{ "SF100000", 0, "SF110000", 0, 0, 0, 0, 0, 0, 0, 0, 0, "SF010000", 0, + 0, 0, "SF030000", 0, 0, 0, "SF020000", 0, 0, 0, "SF040000", 0, 0, 0, + "SF080000", 0, 0, 0, 0, 0, 0, 0, "SF090000", 0, 0, 0, 0, 0, 0, 0, + "SF060000", 0, 0, 0, 0, 0, 0, 0, "SF070000", 0, 0, 0, 0, 0, 0, 0, + "SF050000", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + "SF430000", "SF240000", "SF510000", "SF520000", "SF390000", + "SF220000", "SF210000", "SF250000", "SF500000", "SF490000", + "SF380000", "SF280000", "SF270000", "SF260000", "SF360000", + "SF370000", "SF420000", "SF190000", "SF200000", "SF230000", + "SF470000", "SF480000", "SF410000", "SF450000", "SF460000", + "SF400000", "SF540000", "SF530000", "SF440000", 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "upblock", 0, 0, 0, "dnblock", 0, + 0, 0, "block", 0, 0, 0, "lfblock", 0, 0, 0, "rtblock", "ltshade", + "shade", "dkshade", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + +static char* table_FB00[] = /* alphabetic presentation forms */ +{ "ff", "fi", "fl", "ffi", "ffl", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "afii57705", 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, "afii57694", "afii57695", 0, 0, 0, 0, 0, 0, 0, 0, 0, + "afii57723", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, "afii57700", 0, 0, 0, 0 }; + +char* +unicodetoPSname(unsigned short code) +{ + if(code<32) return 0; + else if(code<0x6FF) return table_32[code-32]; + else if(code<0x2000) return 0; + else if(code<0x20D0) return table_2000[code-0x2000]; + else if(code==0x2116) return "afii61352"; /* numero sign, for Koi */ + else if(code==0x2122) return "trademark"; + else if(code<0x2500) return 0; + else if(code<0x25A0) return table_2500[code-0x2500]; + else if(code<0xFB00) return 0; + else if(code<0xFB50) return table_FB00[code-0xFB00]; + else return 0; +} diff --git a/nx-X11/lib/font/Type1/t1unicode.h b/nx-X11/lib/font/Type1/t1unicode.h new file mode 100644 index 000000000..bad0274a0 --- /dev/null +++ b/nx-X11/lib/font/Type1/t1unicode.h @@ -0,0 +1,25 @@ +/* +Copyright (c) 1998 by Juliusz Chroboczek + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +/* $XFree86$ */ + +char *unicodetoPSname(unsigned short code); diff --git a/nx-X11/lib/font/Type1/token.c b/nx-X11/lib/font/Type1/token.c new file mode 100644 index 000000000..71a968b30 --- /dev/null +++ b/nx-X11/lib/font/Type1/token.c @@ -0,0 +1,1208 @@ +/* $Xorg: token.c,v 1.4 2000/08/17 19:46:34 cpqbld Exp $ */ +/* Copyright International Business Machines,Corp. 1991 + * All Rights Reserved + * + * License to use, copy, modify, and distribute this software + * and its documentation for any purpose and without fee is + * hereby granted, provided that the above copyright notice + * appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, + * and that the name of IBM not be used in advertising or + * publicity pertaining to distribution of the software without + * specific, written prior permission. + * + * IBM PROVIDES THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES + * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT + * LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE QUALITY AND + * PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT + * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF + * THE SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM) ASSUMES + * THE ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN + * NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ +/* $XFree86: xc/lib/font/Type1/token.c,v 1.5tsi Exp $ */ +/* Authors: Sig Nin & Carol Thompson IBM Almaden Research Laboratory */ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include "t1stdio.h" +#include "util.h" +#include "digit.h" +#include "token.h" +#include "tokst.h" +#include "hdigit.h" + +/* + * ------------------------------------------------------------------- + * Globals + * ------------------------------------------------------------------- + */ + +/* These variables are set by the caller */ +char *tokenStartP; /* Pointer to token buffer in VM */ +char *tokenMaxP; /* Pointer to last byte in buffer + 1 */ + +/* These variables are set by TOKEN */ +int tokenLength; /* Characters in token */ +boolean tokenTooLong; /* Token too long for buffer */ +int tokenType; /* Type of token identified */ +psvalue tokenValue; /* Token value */ + +/* + * ------------------------------------------------------------------- + * Private variables + * ------------------------------------------------------------------- + */ + +static FILE *inputFileP; /* Current input file */ + + +/* Token */ +static char *tokenCharP; /* Pointer to next character in token */ + +/* + * ------------------------------------------------------------------- + * Private routines for manipulating numbers + * ------------------------------------------------------------------- + */ + +#define Exp10(e) \ +((e) == 0\ + ? (double)(1.0)\ + : (-64 <= (e) && (e) <= 63\ + ? Exp10T[(e)+64]\ + : P10(e)\ + )\ +) + +static double Exp10T[128] = { + 1e-64, 1e-63, 1e-62, 1e-61, 1e-60, 1e-59, 1e-58, 1e-57, + 1e-56, 1e-55, 1e-54, 1e-53, 1e-52, 1e-51, 1e-50, 1e-49, + 1e-48, 1e-47, 1e-46, 1e-45, 1e-44, 1e-43, 1e-42, 1e-41, + 1e-40, 1e-39, 1e-38, 1e-37, 1e-36, 1e-35, 1e-34, 1e-33, + 1e-32, 1e-31, 1e-30, 1e-29, 1e-28, 1e-27, 1e-26, 1e-25, + 1e-24, 1e-23, 1e-22, 1e-21, 1e-20, 1e-19, 1e-18, 1e-17, + 1e-16, 1e-15, 1e-14, 1e-13, 1e-12, 1e-11, 1e-10, 1e-9, + 1e-8, 1e-7, 1e-6, 1e-5, 1e-4, 1e-3, 1e-2, 1e-1, + 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, + 1e8, 1e9, 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, + 1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22, 1e23, + 1e24, 1e25, 1e26, 1e27, 1e28, 1e29, 1e30, 1e31, + 1e32, 1e33, 1e34, 1e35, 1e36, 1e37, 1e38, 1e39, + 1e40, 1e41, 1e42, 1e43, 1e44, 1e45, 1e46, 1e47, + 1e48, 1e49, 1e50, 1e51, 1e52, 1e53, 1e54, 1e55, + 1e56, 1e57, 1e58, 1e59, 1e60, 1e61, 1e62, 1e63 +}; + +static double +P10(long exponent) +{ + double value, power; + + if (exponent < 0) { + power = 0.1; + value = (exponent & 1 ? power : 1.0); + exponent++; + exponent = -(exponent >> 1); /* portable C for -(exponent/2) */ + } + else { + power = 10.0; + value = (exponent & 1 ? power : 1.0); + exponent = exponent >> 1; + } + + while(exponent > 0) { + power *= power; + if (exponent & 1) + value *= power; + exponent >>= 1; + } + + return(value); +} + +/* + * ------------------------------------------------------------------- + * Private routines and macros for manipulating the input + * ------------------------------------------------------------------- + */ + +/* Get next character from the input -- + * + */ +#define next_ch() (_XT1getc(inputFileP)) + +/* Push a character back into the input -- + * + * Ungetc of EOF will fail, but that's ok: the next getc will + * return EOF. + * + * NOTE: These macros are presently written to return the character + * pushed, or EOF if none was pushed. However, they are not + * required to return anything in particular, and callers should + * not rely on the returned value. + */ +#define back_ch(ch) (T1Ungetc(ch, inputFileP)) + +/* Push a character back into the input if it was not white space. + * If it is a carriage return (\r) then check next char for + * linefeed and consume them both, otherwise put next char back. + * + */ +#define back_ch_not_white(ch) \ +(\ +isWHITE_SPACE(ch)\ + ? ((ch == '\r')\ + ? (((ch = next_ch()) == '\n')\ + ? EOF\ + : back_ch(ch)\ + )\ + : EOF\ + )\ + : back_ch(ch)\ +) + +/* + * ------------------------------------------------------------------- + * Private routines and macros for manipulating the token buffer + * ------------------------------------------------------------------- + */ + +/* Add a character to the token + * ---- use ONLY when you KNOW that this character will + * be stored within the token buffer. + */ +#define save_unsafe_ch(ch) (*tokenCharP++ = ch) + +/* Add a character to the token, if not too long to fit */ +#define save_ch(ch) \ +((tokenCharP < tokenMaxP)\ + ? save_unsafe_ch(ch)\ + : (tokenTooLong = TRUE)\ +) + +#define save_ch_no_inc(ch) \ +if (tokenCharP < tokenMaxP) *tokenCharP = ch + +/* + * ------------------------------------------------------------------- + * Action Routines + * + * These routines all + * -- take int ch as a parameter + * -- return int ch if no token was recognized, DONE otherwise + * -- leave the next character in the input, if returning DONE + * ------------------------------------------------------------------- + */ + +#define DONE (256) + +/* Get the next input character */ +static int +next_char(int ch) +{ + return(next_ch()); +} + +/* Add character to token */ +static int +add_char(int ch) +{ + save_ch(ch); + return(next_ch()); +} + + +/* ------------------------------------------------------------------- + * Skip white space and comments + */ + +/* Skip white space */ +static int +skip_space(int ch) +{ + do { + ch = next_ch(); + } while(isWHITE_SPACE(ch)); + return(ch); +} + +/* Skip comments */ +static int +skip_comment(int ch) +{ + do { + ch = next_ch(); + } while(isCOMMENT(ch)); + return(ch); +} + +/* ------------------------------------------------------------------- + * Collect value elements for a number + */ + +/* decimal integer or real number mantissa */ +static int m_sign; +static long m_value; +static long m_scale; + +/* real number exponent */ +static int e_sign; +static long e_value; + +/* radix number */ +static long r_base; +static long r_value; +static long r_scale; + +static int +add_sign(int ch) +{ + m_sign = ch; + save_unsafe_ch(ch); + return(next_ch()); +} + +static int +add_1st_digits(int ch) +{ + m_sign = '+'; + return(add_digits(ch)); +} + +static int +add_digits(int ch) +{ + long value, p_value, scale; + int digit; + + /* On entry, expect m_sign to be set to '+' or '-'; + * ch is a decimal digit. + * Expect at most one character saved at this point, + * a sign. This routine will save up to 10 more + * characters without checking the buffer boundary. + */ + + value = ch - '0'; + save_unsafe_ch(ch); + ch = next_ch(); + + while(isDECIMAL_DIGIT(ch) && value < (MAX_INTEGER/10)) { + value = (value << 3) + (value << 1) + (ch - '0'); + save_unsafe_ch(ch); + ch = next_ch(); + } + + /* Quick exit for small integers -- + * |x| <= 10*((MAX_INTEGER/10)-1)+9 + * |x| <= 2,147,483,639 for 32 bit integers + */ + if (isNUMBER_ENDER(ch)) { + back_ch_not_white(ch); + tokenValue.integer = (m_sign == '-' ? -value : value); + tokenType = TOKEN_INTEGER; + return(DONE); + } + + /* Handle additional digits. Beyond the boundary case, + * 10*(MAX_INTEGER/10) <= |number| <= MAX_INTEGER + * just count the digits: the number is too large to + * represent as an integer and will be returned as a real. + * The mantissa of a real holds fewer bits than an integer. + */ + p_value = value; + value = (m_sign == '-' ? -value : value); + scale = 0; + + if (isDECIMAL_DIGIT(ch)) { + + /* Handle the boundary case */ + if (p_value == (MAX_INTEGER/10)) { + digit = ch - '0'; + + /* Must handle positive and negative values separately */ + /* for 2's complement arithmetic */ + if (value > 0) { + if (digit <= MAX_INTEGER%10) + value = (value << 3) + (value << 1) + digit; + else + ++scale; /* Too big, just count it */ + } + else { + /* Use positive % operands for portability */ + if (digit <= -(MIN_INTEGER+10)%10) + value = (value << 3) + (value << 1) - digit; + else + ++scale; /* Too big, just count it */ + } + } + else + ++scale; /* Not boundary case, just count digit */ + + save_unsafe_ch(ch); + ch = next_ch(); + + /* Continue scanning digits, but can't store them */ + while(isDECIMAL_DIGIT(ch)) { + ++scale; + save_ch(ch); + ch = next_ch(); + } + } + + /* Continue from here scanning radix integer or real */ + m_value = value; + m_scale = scale; + + /* Initialize for possible real */ + e_sign = '+'; + e_value = 0; + + return(ch); +} + +static int +add_1st_decpt(int ch) +{ + m_sign = '+'; + return(add_decpt(ch)); +} + +static int +add_decpt(int ch) +{ + /* On entry, expect m_sign to be set to '+' or '-' */ + m_value = 0; + m_scale = 0; + save_unsafe_ch(ch); + return(next_ch()); +} + +static int +add_fraction(int ch) +{ + long value, scale; + int digit; + + /* On entry, expect m_value and m_scale to be initialized, + * and m_sign to be set to '+' or '-'. Expect m_value and m_sign + * to be consistent (this is not checked). + */ + value = m_value; + scale = m_scale; + + /* Scan leading zeroes */ + if (value == 0) { + while(ch == '0') { + --scale; + save_ch(ch); + ch = next_ch(); + } + + /* Scan first significant digit */ + if (isDECIMAL_DIGIT(ch)) { + --scale; + value = ch - '0'; + value = (m_sign == '-' ? -value : value); + save_ch(ch); + ch = next_ch(); + } + else + /* no significant digits -- number is zero */ + scale = 0; + } + /* value != 0 || value == 0 && !isDECIMAL_DIGIT(ch) */ + + /* Scan additional significant digits */ + if (isDECIMAL_DIGIT(ch)) { + if (value > 0) { + while(isDECIMAL_DIGIT(ch) && value < (MAX_INTEGER/10)) { + --scale; + value = (value << 3) + (value << 1) + (ch - '0'); + save_ch(ch); + ch = next_ch(); + } + /* Check boundary case */ + if (isDECIMAL_DIGIT(ch) && value == (MAX_INTEGER/10)) { + digit = ch - '0'; + if (digit <= MAX_INTEGER%10) { + --scale; + value = (value << 3) + (value << 1) + digit; + save_ch(ch); + ch = next_ch(); + } + } + } + else { + /* value < 0 */ + while(isDECIMAL_DIGIT(ch) && value > -(-(MIN_INTEGER+10)/10+1)) { + /* Use positive / operands for portability */ + --scale; + value = (value << 3) + (value << 1) - (ch - '0'); + save_ch(ch); + ch = next_ch(); + } + /* Check boundary case */ + if (isDECIMAL_DIGIT(ch) + && value == -(-(MIN_INTEGER+10)/10+1)) { + digit = ch - '0'; + if (digit <= -(MIN_INTEGER+10)%10) { + /* Use positive % operands for portability */ + --scale; + value = (value << 3) + (value << 1) - digit; + save_ch(ch); + ch = next_ch(); + } + } + } + + /* Additional digits can be discarded */ + while(isDECIMAL_DIGIT(ch)) { + save_ch(ch); + ch = next_ch(); + } + } + + /* Store results */ + m_value = value; + m_scale = scale; + + /* Initialize for possible real */ + e_sign = '+'; + e_value = 0; + + return(ch); +} + +static int +add_e_sign(int ch) +{ + e_sign = ch; + save_ch(ch); + return(next_ch()); +} + +static int +add_exponent(int ch) +{ + long value, p_value; + long scale = 0; + int digit; + + /* On entry, expect e_sign to be set to '+' or '-' */ + + value = ch - '0'; + save_ch(ch); + ch = next_ch(); + + while(isDECIMAL_DIGIT(ch) && value < (MAX_INTEGER/10)) { + value = (value << 3) + (value << 1) + (ch - '0'); + save_ch(ch); + ch = next_ch(); + } + + p_value = value; + value = (e_sign == '-' ? -value : value); + + /* Handle additional digits. Beyond the boundary case, + * 10*(MAX_INTEGER/10) <= |number| <= MAX_INTEGER + * just count the digits: the number is too large to + * represent as an integer. + */ + if (isDECIMAL_DIGIT(ch)) { + + /* Examine boundary case */ + if (p_value == (MAX_INTEGER/10)) { + digit = ch - '0'; + + /* Must handle positive and negative values separately */ + /* for 2's complement arithmetic */ + if (value > 0) { + if (digit <= MAX_INTEGER%10) + value = (value << 3) + (value << 1) + digit; + else + ++scale; /* Too big, just count it */ + } + else { + /* Use positive % operands for portability */ + if (digit <= -(MIN_INTEGER+10)%10) + value = (value << 3) + (value << 1) - digit; + else + ++scale; /* Too big, just count it */ + } + } + else + ++scale; /* Not boundary case, just count digit */ + + save_ch(ch); + ch = next_ch(); + + /* Continue scanning digits, but can't store any more */ + while(isDECIMAL_DIGIT(ch)) { + ++scale; + save_ch(ch); + ch = next_ch(); + } + } + + /* Store results */ + e_value = value; + + return(ch); +} + +static int +add_radix(int ch) +{ + if (2 <= m_value && m_value <= 36 && m_scale == 0) { + r_base = m_value; + save_ch(ch); + return(next_ch()); + } + else { + /* Radix invalid, complete a name token */ + return(AAH_NAME(ch)); + } +} + +static int +add_r_digits(int ch) +{ + unsigned long value; + long radix, scale; + int digit; + + /* NOTE: The syntax of a radix number allows only for + * values of zero or more. The value will be stored as + * a 32 bit integer, which PostScript then interprets + * as signed. This means, for example, that the numbers: + * + * 8#37777777777 + * 10#4294967295 + * 16#FFFFFFFF + * 36#1Z141Z3 + * + * are all interpreted as -1. This routine implements this + * idea explicitly: it accumulates the number's value + * as unsigned, then casts it to signed when done. + */ + + /* Expect r_base to be initialized */ + radix = r_base; + value = 0; + scale = 0; + + /* Scan leading zeroes */ + while(ch == '0') { + save_ch(ch); + ch = next_ch(); + } + + /* Handle first non-zero digit */ + if ((digit=digit_value[ch]) < radix) { + value = digit; + save_ch(ch); + ch = next_ch(); + + /* Add digits until boundary case reached */ + while((digit=digit_value[ch]) < radix + && value < (MAX_ULONG / radix)) { + value = value * radix + digit; + save_ch(ch); + ch = next_ch(); + }; + + /* Scan remaining digits */ + if ((digit=digit_value[ch]) < radix) { + + /* Examine boundary case --- + * radix*(MAX_ULONG/radix) <= number <= MAX_ULONG + */ + if (value == (MAX_ULONG/radix) && digit <= MAX_ULONG%radix) + value = value * radix + digit; + else + ++scale; + + /* Continue scanning digits, but can't store them */ + save_ch(ch); + ch = next_ch(); + while(digit_value[ch] < radix) { + ++scale; + save_ch(ch); + ch = next_ch(); + } + } + } + + /* Store result */ + r_value = (long) value; /* result is signed */ + r_scale = scale; + + return(ch); +} + +/* ------------------------------------------------------------------- + * Complete a number; set token type and done flag. + * Put current input character back, if it is not white space. + */ + +/* Done: Radix Number */ +static int +RADIX_NUMBER(int ch) +{ + back_ch_not_white(ch); + if (r_scale == 0) { + tokenValue.integer = r_value; + tokenType = TOKEN_INTEGER; + } + else { + tokenType = TOKEN_NAME; + } + return(DONE); +} + +/* Done: Integer */ +static int +INTEGER(int ch) +{ + back_ch_not_white(ch); + if (m_scale == 0) { + tokenValue.integer = m_value; + tokenType = TOKEN_INTEGER; + } + else { + tokenValue.real = (double)(m_value) * Exp10(m_scale); + tokenType = TOKEN_REAL; + } + return(DONE); +} + +/* Done: Real */ +static int +REAL(int ch) +{ + double temp; + + back_ch_not_white(ch); + + /* HAZARD: exponent overflow of intermediate result + * (e.g., in 370 floating point); this should not be a problem + * with IEEE floating point. Reduce exponent overflow hazard by + * combining m_scale and e_value first, if they have different signs, + * or multiplying m_value and one of the other factors, if both + * m_scale and e_value are negative. + */ + if ((m_scale >= 0 && e_value <= 0) + || (m_scale <= 0 && e_value >= 0)) { + tokenValue.real = (double)(m_value) * Exp10(m_scale + e_value); + } + else { + temp = (double)(m_value) * Exp10(m_scale); + tokenValue.real = temp * Exp10(e_value); + } + + tokenType = TOKEN_REAL; + return(DONE); +} + + +/* ------------------------------------------------------------------- + * Assemble a hex string; set token type and done flag. + */ + +/* Done: Hex String */ +static int +HEX_STRING(int ch) +{ + int value; + + while(TRUE) { + + /* Process odd digit */ + ch = next_ch(); + if (!isHEX_DIGIT(ch)) { + + /* Skip white space */ + while(isWHITE_SPACE(ch)) + ch = next_ch(); + + /* Check for terminator */ + if (!isHEX_DIGIT(ch)) { + break; + } + } + value = digit_value[ch] << 4; + + /* Process even digit */ + ch = next_ch(); + if (!isHEX_DIGIT(ch)) { + + /* Skip white space */ + while(isWHITE_SPACE(ch)) + ch = next_ch(); + + /* Check for terminator */ + if (!isHEX_DIGIT(ch)) { + save_ch(value); + break; + } + } + save_ch(value + digit_value[ch]); + } + + /* Classify result, based on why loop ended */ + if (ch == '>') + tokenType = TOKEN_HEX_STRING; + else { + /* save the invalid character for error reporting */ + save_ch(ch); + tokenType = TOKEN_INVALID; + } + + return(DONE); +} + +/* ------------------------------------------------------------------- + * Assemble a string; set token type and done flag + */ + +/* Save a backslash-coded character in a string -- + * + * Store the proper character for special cases + * "\b", "\f", "\n", "\r", and "\t". + * + * Decode and store octal-coded character, up to + * three octal digits, "\o", "\oo", and "\ooo". + * + * The sequence "\<newline>" is a line continuation, + * so consume both without storing anything. + * + * The sequence "\<EOF>" is an error; exit without + * storing anything and let the caller handle it. + * + * For other characters, including the sequences + * "\\", "\(", and "\)", simply store the second + * character. + */ +static void +save_digraph(int ch) +{ + int value; + + switch (ch) { + + case 'b': /* backspace */ + ch = '\b'; + break; + + case 'f': /* formfeed */ + ch = '\f'; + break; + + case 'n': /* newline */ + ch = '\n'; + break; + + case 'r': /* carriage return */ + ch = '\r'; + break; + + case 't': /* horizontal tab */ + ch = '\t'; + break; + + case '\n': /* line continuation -- consume it */ + return; + + case '\r': /* carriage return -- consume it */ + ch = next_ch(); /* look at next character, is it \n? */ + if (ch == '\n') return; + back_ch(ch); /* if not a line feed, then return it */ + return; + + case EOF: /* end of file -- forget it */ + return; + + default: + /* scan up to three octal digits to get value */ + if (isOCTAL_DIGIT(ch)) { + value = digit_value[ch]; + ch = next_ch(); + if (isOCTAL_DIGIT(ch)) { + value = (value << 3) + digit_value[ch]; + ch = next_ch(); + if (isOCTAL_DIGIT(ch)) + value = (value << 3) + digit_value[ch]; + else + back_ch(ch); + } + else + back_ch(ch); + ch = value; + } + } + + /* Found a character to save */ + save_ch(ch); +} + +/* Done: String */ +static int +STRING(int ch) +{ + int nest_level = 1; + + tokenType = TOKEN_STRING; + + do { + + ch = next_ch(); + while(!isSTRING_SPECIAL(ch)) { + save_ch(ch); + ch = next_ch(); + }; + + switch (ch) { + + case '(': + ++nest_level; + save_ch(ch); + break; + + case ')': + if (--nest_level > 0) + save_ch(ch); + break; + + case '\\': + save_digraph(next_ch()); + break; + + case '\r': + /* All carriage returns (\r) are turned into linefeeds (\n)*/ + ch = next_ch(); /* get the next one, is it \n? */ + if (ch != '\n') { /* if not, then put it back. */ + back_ch(ch); + } + save_ch('\n'); /* in either case, save a linefeed */ + break; + + + case EOF: + tokenType = TOKEN_INVALID; /* Unterminated string */ + nest_level = 0; + break; + } + + } while(nest_level > 0); + + /* If there's room, add a 0-byte termination without increasing string + length. This fixes certain dependencies on 0-terminated strings */ + save_ch_no_inc(0); + + return(DONE); +} + + +/* ------------------------------------------------------------------- + * Assemble a name; set token type and done flag. + * Put current input character back, if it is not white space. + */ + +/* Done: Name + * (Safe version used to complete name tokens that + * start out looking like something else). + */ + +static int +AAH_NAME(int ch) +{ + do { + save_ch(ch); + ch = next_ch(); + } while(isNAME(ch)); + + back_ch_not_white(ch); + tokenType = TOKEN_NAME; + return(DONE); +} + +/* Done: Name */ +static int +NAME(int ch) +{ + save_unsafe_ch(ch); + ch = next_ch(); + if (isNAME(ch)) { + save_unsafe_ch(ch); + ch = next_ch(); + if (isNAME(ch)) { + save_unsafe_ch(ch); + ch = next_ch(); + if (isNAME(ch)) { + save_unsafe_ch(ch); + ch = next_ch(); + if (isNAME(ch)) { + save_unsafe_ch(ch); + ch = next_ch(); + if (isNAME(ch)) { + save_unsafe_ch(ch); + ch = next_ch(); + if (isNAME(ch)) { + save_unsafe_ch(ch); + ch = next_ch(); + while(isNAME(ch)) { + save_ch(ch); + ch = next_ch(); + } + } + } + } + } + } + } + + back_ch_not_white(ch); + tokenType = TOKEN_NAME; + return(DONE); +} + +/* Done: Literal Name */ +static int +LITERAL_NAME(int ch) +{ + if (isNAME(ch)) { + save_unsafe_ch(ch); + ch = next_ch(); + if (isNAME(ch)) { + save_unsafe_ch(ch); + ch = next_ch(); + if (isNAME(ch)) { + save_unsafe_ch(ch); + ch = next_ch(); + if (isNAME(ch)) { + save_unsafe_ch(ch); + ch = next_ch(); + if (isNAME(ch)) { + save_unsafe_ch(ch); + ch = next_ch(); + if (isNAME(ch)) { + save_unsafe_ch(ch); + ch = next_ch(); + while(isNAME(ch)) { + save_ch(ch); + ch = next_ch(); + } + } + } + } + } + } + } + + back_ch_not_white(ch); + tokenType = TOKEN_LITERAL_NAME; + return(DONE); +} + +/* Done: immediate Name */ +static int +IMMED_NAME(int ch) +{ + ch = next_ch(); + if (isNAME(ch)) { + save_unsafe_ch(ch); + ch = next_ch(); + if (isNAME(ch)) { + save_unsafe_ch(ch); + ch = next_ch(); + if (isNAME(ch)) { + save_unsafe_ch(ch); + ch = next_ch(); + if (isNAME(ch)) { + save_unsafe_ch(ch); + ch = next_ch(); + if (isNAME(ch)) { + save_unsafe_ch(ch); + ch = next_ch(); + if (isNAME(ch)) { + save_unsafe_ch(ch); + ch = next_ch(); + while(isNAME(ch)) { + save_ch(ch); + ch = next_ch(); + } + } + } + } + } + } + } + + back_ch_not_white(ch); + tokenType = TOKEN_IMMED_NAME; + return(DONE); +} + +/* Done: Name found while looking for something else */ +static int +OOPS_NAME(int ch) +{ + back_ch_not_white(ch); + tokenType = TOKEN_NAME; + return(DONE); +} + + +/* ------------------------------------------------------------------- + * Complete a miscellaneous token; set token type and done flag. + */ + +/* Done: Unmatched Right Angle-Bracket */ +static int +RIGHT_ANGLE(int ch) +{ + tokenType = TOKEN_RIGHT_ANGLE; + return(DONE); +} + +/* Done: Unmatched Right Parenthesis */ +static int +RIGHT_PAREN(int ch) +{ + tokenType = TOKEN_RIGHT_PAREN; + return(DONE); +} + +/* Done: Left Brace */ +static int +LEFT_BRACE(int ch) +{ + tokenType = TOKEN_LEFT_BRACE; + return(DONE); +} + +/* Done: Right Brace */ +static int +RIGHT_BRACE(int ch) +{ + tokenType = TOKEN_RIGHT_BRACE; + return(DONE); +} + +/* Done: Left Bracket */ +static int +LEFT_BRACKET(int ch) +{ + save_unsafe_ch(ch); + tokenType = TOKEN_LEFT_BRACKET; + return(DONE); +} + +/* Done: Right Bracket */ +static int +RIGHT_BRACKET(int ch) +{ + save_unsafe_ch(ch); + tokenType = TOKEN_RIGHT_BRACKET; + return(DONE); +} + +/* Done: Break */ +static int +BREAK_SIGNAL(int ch) +{ + tokenType = TOKEN_BREAK; + return(DONE); +} + +/* Done: No Token Found */ +static int +NO_TOKEN(int ch) +{ + tokenType = TOKEN_EOF; + return(DONE); +} + + +/* + * ------------------------------------------------------------------- + * scan_token -- scan one token from the input. It uses a simple + * finite state machine to recognize token classes. + * + * The input is from a file. + * + * On entry -- + * + * inputP -> input PostScript object, a file. + * tokenStartP -> buffer in VM for accumulating the token. + * tokenMaxP -> last character in the token buffer + * + * On exit -- + * + * tokenLength = number of characters in the token + * tokenTooLong = TRUE if the token did not fit in the buffer + * tokenType = code for the type of token parsed. + * tokenValue = converted value of a numeric token. + * + * + * ------------------------------------------------------------------- + */ +void +scan_token(psobj *inputP) +{ + int ch; + unsigned char *stateP = s0; + unsigned char entry; + int (*actionP)(int); + + /* Define input source */ + inputFileP = inputP->data.fileP; + if (inputFileP == NULL) { + tokenType = TOKEN_EOF; + return; + } + + /* Ensure enough space for most cases + * (so we don't have to keep checking) + * The length needs to cover the maximum number + * of save_unsafe_ch() calls that might be executed. + * That number is 11 (a sign and 10 decimal digits, e.g., + * when scanning -2147483648), but use MAX_NAME_LEN + * in case someone changes that without checking. + */ + tokenStartP = vm_next_byte(); + tokenMaxP = tokenStartP + MIN(vm_free_bytes(), MAX_STRING_LEN); + + if ((tokenMaxP-tokenStartP) < (MAX_NAME_LEN)) { + tokenLength = 0; + tokenTooLong = TRUE; + tokenType = TOKEN_NONE; + tokenValue.integer = 0; + return; + } + + /* Reset token */ + tokenCharP = tokenStartP; + tokenTooLong = FALSE; + + /* Scan one token */ + ch = next_ch(); + do { + entry = stateP[ch]; + stateP = classActionTable[entry].nextStateP; + actionP = classActionTable[entry].actionRoutineP; + ch = (*actionP)(ch); + } while(ch != DONE); + + + /* Return results */ + tokenLength = tokenCharP - tokenStartP; +} diff --git a/nx-X11/lib/font/Type1/token.h b/nx-X11/lib/font/Type1/token.h new file mode 100644 index 000000000..663982889 --- /dev/null +++ b/nx-X11/lib/font/Type1/token.h @@ -0,0 +1,79 @@ +/* $Xorg: token.h,v 1.3 2000/08/17 19:46:34 cpqbld Exp $ */ +/* Copyright International Business Machines,Corp. 1991 + * All Rights Reserved + * + * License to use, copy, modify, and distribute this software + * and its documentation for any purpose and without fee is + * hereby granted, provided that the above copyright notice + * appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, + * and that the name of IBM not be used in advertising or + * publicity pertaining to distribution of the software without + * specific, written prior permission. + * + * IBM PROVIDES THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES + * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT + * LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE QUALITY AND + * PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT + * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF + * THE SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM) ASSUMES + * THE ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN + * NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ +/* $XFree86: xc/lib/font/Type1/token.h,v 1.3 1999/08/22 08:58:54 dawes Exp $ */ + +#ifndef TOKEN_H +#define TOKEN_H + +/* Special characters */ +#define CONTROL_C (3) + +/* Token type codes */ +#define TOKEN_INVALID (-3) +#define TOKEN_BREAK (-2) +#define TOKEN_EOF (-1) +#define TOKEN_NONE (0) +#define TOKEN_LEFT_PAREN (1) +#define TOKEN_RIGHT_PAREN (2) +#define TOKEN_LEFT_ANGLE (3) +#define TOKEN_RIGHT_ANGLE (4) +#define TOKEN_LEFT_BRACE (5) +#define TOKEN_RIGHT_BRACE (6) +#define TOKEN_LEFT_BRACKET (7) +#define TOKEN_RIGHT_BRACKET (8) +#define TOKEN_NAME (9) +#define TOKEN_LITERAL_NAME (10) +#define TOKEN_INTEGER (11) +#define TOKEN_REAL (12) +#define TOKEN_RADIX_NUMBER (13) +#define TOKEN_HEX_STRING (14) +#define TOKEN_STRING (15) +#define TOKEN_IMMED_NAME (16) + +/* Token routines */ +extern void scan_token( psobj *inputP ); + +/* + * ------------------------------------------------------------------------- + * Globals shared -- (everyone else KEEP YOUR MITTS OFF THEM!) + * ------------------------------------------------------------------------- + */ + +/* These variables are set by the caller */ +extern char *tokenStartP; /* Pointer to token buffer in VM */ +extern char *tokenMaxP; /* Pointer to end of VM we may use + 1 */ + +/* These variables are set by P_TOKEN */ +extern int tokenLength; /* Characters in token */ +extern boolean tokenTooLong; /* Token too long for space available */ +extern int tokenType; /* Type of token identified */ +extern psvalue tokenValue; /* Token value */ + +#endif /* TOKEN_H */ diff --git a/nx-X11/lib/font/Type1/tokst.h b/nx-X11/lib/font/Type1/tokst.h new file mode 100644 index 000000000..02166afde --- /dev/null +++ b/nx-X11/lib/font/Type1/tokst.h @@ -0,0 +1,510 @@ +/* $Xorg: tokst.h,v 1.3 2000/08/17 19:46:34 cpqbld Exp $ */ +/* Copyright International Business Machines,Corp. 1991 + * All Rights Reserved + * + * License to use, copy, modify, and distribute this software + * and its documentation for any purpose and without fee is + * hereby granted, provided that the above copyright notice + * appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, + * and that the name of IBM not be used in advertising or + * publicity pertaining to distribution of the software without + * specific, written prior permission. + * + * IBM PROVIDES THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES + * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT + * LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE QUALITY AND + * PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT + * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF + * THE SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM) ASSUMES + * THE ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN + * NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ +/* $XFree86: xc/lib/font/Type1/tokst.h,v 1.3 1999/08/22 08:58:54 dawes Exp $ */ + +/* -------------------------------------- */ +/* --- MACHINE GENERATED, DO NOT EDIT --- */ +/* -------------------------------------- */ + +#ifndef TOKST +#define TOKST 1 + +/* + * State Index Tables -- + * + * These tables map the input character to the + * proper entry in the Class Action Table. + * There is one table for each state. + * + */ +#define s0 (si0+2) +static unsigned char si0[258] = { 0x10,0x11, + 0x02,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x02,0x02,0x0F,0x0F,0x02,0x0F,0x0F, + 0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F, + 0x02,0x0F,0x0F,0x0F,0x0F,0x03,0x0F,0x0F,0x05,0x0B,0x0F,0x0D,0x0F,0x0D,0x0E,0x04, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x0F,0x0F,0x08,0x0F,0x0C,0x0F, + 0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x0F,0x0A,0x0F,0x0F, + 0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x0F,0x09,0x0F,0x0F, + 0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F, + 0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F, + 0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F, + 0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F, + 0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F, + 0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F, + 0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F, + 0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F +}; + +#define s1 (si1+2) +static unsigned char si1[258] = { 0x14,0x15, + 0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13, + 0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13, + 0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x12, + 0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13, + 0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13, + 0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13, + 0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13, + 0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13, + 0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13, + 0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13, + 0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13, + 0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13, + 0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13, + 0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13, + 0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13, + 0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13 +}; + +#define s2 (si2+2) +static unsigned char si2[258] = { 0x1B,0x1C, + 0x16,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x16,0x16,0x1A,0x1A,0x16,0x1A,0x1A, + 0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A, + 0x16,0x1A,0x1A,0x1A,0x1A,0x17,0x1A,0x1A,0x17,0x17,0x1A,0x1A,0x1A,0x1A,0x19,0x17, + 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1A,0x1A,0x17,0x1A,0x17,0x1A, + 0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A, + 0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x17,0x1A,0x17,0x1A,0x1A, + 0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A, + 0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x17,0x1A,0x17,0x1A,0x1A, + 0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A, + 0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A, + 0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A, + 0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A, + 0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A, + 0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A, + 0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A, + 0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A,0x1A +}; + +#define s3 (si3+2) +static unsigned char si3[258] = { 0x23,0x24, + 0x1D,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x1D,0x1D,0x22,0x22,0x1D,0x22,0x22, + 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22, + 0x1D,0x22,0x22,0x20,0x22,0x1E,0x22,0x22,0x1E,0x1E,0x22,0x22,0x22,0x22,0x1F,0x1E, + 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x1E,0x22,0x1E,0x22, + 0x22,0x22,0x22,0x22,0x22,0x21,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22, + 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x1E,0x22,0x1E,0x22,0x22, + 0x22,0x22,0x22,0x22,0x22,0x21,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22, + 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x1E,0x22,0x1E,0x22,0x22, + 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22, + 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22, + 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22, + 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22, + 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22, + 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22, + 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22, + 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22 +}; + +#define s4 (si4+2) +static unsigned char si4[258] = { 0x29,0x2A, + 0x25,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x25,0x25,0x28,0x28,0x25,0x28,0x28, + 0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28, + 0x25,0x28,0x28,0x28,0x28,0x26,0x28,0x28,0x26,0x26,0x28,0x28,0x28,0x28,0x28,0x26, + 0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x28,0x28,0x26,0x28,0x26,0x28, + 0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28, + 0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x26,0x28,0x26,0x28,0x28, + 0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28, + 0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x26,0x28,0x26,0x28,0x28, + 0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28, + 0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28, + 0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28, + 0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28, + 0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28, + 0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28, + 0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28, + 0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28 +}; + +#define s5 (si5+2) +static unsigned char si5[258] = { 0x30,0x31, + 0x2B,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2B,0x2B,0x2F,0x2F,0x2B,0x2F,0x2F, + 0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F, + 0x2B,0x2F,0x2F,0x2F,0x2F,0x2C,0x2F,0x2F,0x2C,0x2C,0x2F,0x2F,0x2F,0x2F,0x2F,0x2C, + 0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2E,0x2F,0x2F,0x2C,0x2F,0x2C,0x2F, + 0x2F,0x2F,0x2F,0x2F,0x2F,0x2D,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F, + 0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2C,0x2F,0x2C,0x2F,0x2F, + 0x2F,0x2F,0x2F,0x2F,0x2F,0x2D,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F, + 0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2C,0x2F,0x2C,0x2F,0x2F, + 0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F, + 0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F, + 0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F, + 0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F, + 0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F, + 0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F, + 0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F, + 0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F +}; + +#define s6 (si6+2) +static unsigned char si6[258] = { 0x36,0x37, + 0x32,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x32,0x32,0x35,0x35,0x32,0x35,0x35, + 0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35, + 0x32,0x35,0x35,0x35,0x35,0x33,0x35,0x35,0x33,0x33,0x35,0x35,0x35,0x35,0x35,0x33, + 0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x33,0x35,0x33,0x35, + 0x35,0x35,0x35,0x35,0x35,0x34,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35, + 0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x33,0x35,0x33,0x35,0x35, + 0x35,0x35,0x35,0x35,0x35,0x34,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35, + 0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x33,0x35,0x33,0x35,0x35, + 0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35, + 0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35, + 0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35, + 0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35, + 0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35, + 0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35, + 0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35, + 0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35,0x35 +}; + +#define s7 (si7+2) +static unsigned char si7[258] = { 0x3D,0x3E, + 0x38,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x38,0x38,0x3C,0x3C,0x38,0x3C,0x3C, + 0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C, + 0x38,0x3C,0x3C,0x3C,0x3C,0x39,0x3C,0x3C,0x39,0x39,0x3C,0x3A,0x3C,0x3A,0x3C,0x39, + 0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3B,0x3C,0x3C,0x39,0x3C,0x39,0x3C, + 0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C, + 0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x39,0x3C,0x39,0x3C,0x3C, + 0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C, + 0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x39,0x3C,0x39,0x3C,0x3C, + 0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C, + 0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C, + 0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C, + 0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C, + 0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C, + 0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C, + 0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C, + 0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C +}; + +#define s8 (si8+2) +static unsigned char si8[258] = { 0x43,0x44, + 0x3F,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x3F,0x3F,0x42,0x42,0x3F,0x42,0x42, + 0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42, + 0x3F,0x42,0x42,0x42,0x42,0x40,0x42,0x42,0x40,0x40,0x42,0x42,0x42,0x42,0x42,0x40, + 0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x42,0x42,0x40,0x42,0x40,0x42, + 0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42, + 0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x40,0x42,0x40,0x42,0x42, + 0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42, + 0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x40,0x42,0x40,0x42,0x42, + 0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42, + 0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42, + 0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42, + 0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42, + 0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42, + 0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42, + 0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42, + 0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42 +}; + +#define s9 (si9+2) +static unsigned char si9[258] = { 0x48,0x49, + 0x45,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x45,0x45,0x47,0x47,0x45,0x47,0x47, + 0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47, + 0x45,0x47,0x47,0x47,0x47,0x46,0x47,0x47,0x46,0x46,0x47,0x47,0x47,0x47,0x47,0x46, + 0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x46,0x47,0x46,0x47, + 0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47, + 0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x46,0x47,0x46,0x47,0x47, + 0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47, + 0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x46,0x47,0x46,0x47,0x47, + 0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47, + 0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47, + 0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47, + 0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47, + 0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47, + 0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47, + 0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47, + 0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47 +}; + +#define s10 (si10+2) +static unsigned char si10[258] = { 0x4E,0x4F, + 0x4A,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4A,0x4A,0x4D,0x4D,0x4A,0x4D,0x4D, + 0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D, + 0x4A,0x4D,0x4D,0x4D,0x4D,0x4B,0x4D,0x4D,0x4B,0x4B,0x4D,0x4D,0x4D,0x4D,0x4D,0x4B, + 0x4C,0x4C,0x4C,0x4C,0x4C,0x4C,0x4C,0x4C,0x4C,0x4C,0x4D,0x4D,0x4B,0x4D,0x4B,0x4D, + 0x4D,0x4C,0x4C,0x4C,0x4C,0x4C,0x4C,0x4C,0x4C,0x4C,0x4C,0x4C,0x4C,0x4C,0x4C,0x4C, + 0x4C,0x4C,0x4C,0x4C,0x4C,0x4C,0x4C,0x4C,0x4C,0x4C,0x4C,0x4B,0x4D,0x4B,0x4D,0x4D, + 0x4D,0x4C,0x4C,0x4C,0x4C,0x4C,0x4C,0x4C,0x4C,0x4C,0x4C,0x4C,0x4C,0x4C,0x4C,0x4C, + 0x4C,0x4C,0x4C,0x4C,0x4C,0x4C,0x4C,0x4C,0x4C,0x4C,0x4C,0x4B,0x4D,0x4B,0x4D,0x4D, + 0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D, + 0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D, + 0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D, + 0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D, + 0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D, + 0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D, + 0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D, + 0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D,0x4D +}; + +#define s11 (si11+2) +static unsigned char si11[258] = { 0x53,0x54, + 0x50,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x50,0x50,0x52,0x52,0x50,0x52,0x52, + 0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52, + 0x50,0x52,0x52,0x52,0x52,0x51,0x52,0x52,0x51,0x51,0x52,0x52,0x52,0x52,0x52,0x51, + 0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x51,0x52,0x51,0x52, + 0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52, + 0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x51,0x52,0x51,0x52,0x52, + 0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52, + 0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x51,0x52,0x51,0x52,0x52, + 0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52, + 0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52, + 0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52, + 0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52, + 0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52, + 0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52, + 0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52, + 0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52,0x52 +}; + +/* + * Class Action Table -- + * + * The entries in the Class Action Table indicate the + * action routine to be called, and the next state to + * enter, for each relevant character class in each. + * state. There are several entries for each state. + * + */ +static int AAH_NAME ( int ch ); +static int BREAK_SIGNAL ( int ch ); +static int HEX_STRING ( int ch ); +static int IMMED_NAME ( int ch ); +static int INTEGER ( int ch ); +static int LEFT_BRACE ( int ch ); +static int LEFT_BRACKET ( int ch ); +static int LITERAL_NAME ( int ch ); +static int NAME ( int ch ); +static int NO_TOKEN ( int ch ); +static int OOPS_NAME ( int ch ); +static int RADIX_NUMBER ( int ch ); +static int REAL ( int ch ); +static int RIGHT_ANGLE ( int ch ); +static int RIGHT_BRACE ( int ch ); +static int RIGHT_BRACKET ( int ch ); +static int RIGHT_PAREN ( int ch ); +static int STRING ( int ch ); +static int add_1st_decpt ( int ch ); +static int add_1st_digits ( int ch ); +static int add_char ( int ch ); +static int add_decpt ( int ch ); +static int add_digits ( int ch ); +static int add_exponent ( int ch ); +static int add_e_sign ( int ch ); +static int add_fraction ( int ch ); +static int add_radix ( int ch ); +static int add_r_digits ( int ch ); +static int add_sign ( int ch ); +static int next_char ( int ch ); +static int skip_comment ( int ch ); +static int skip_space ( int ch ); + +static struct cat { + int (*actionRoutineP)(int); + unsigned char *nextStateP; +} classActionTable[] = { + + /* s0: Classify initial character */ + /* 00 ALPHA */ {NAME, s0}, /* executable name */ + /* 01 DIGIT */ {add_1st_digits, s3}, /* number? */ + /* 02 WHITE_SPACE */ {skip_space, s0}, /* skip white space */ + /* 03 PERCENT */ {skip_comment, s0}, /* comment? */ + /* 04 SLASH */ {next_char, s1}, /* literal or imm name */ + /* 05 LEFT_PAREN */ {STRING, s0}, /* string */ + /* 06 LEFT_BRACE */ {LEFT_BRACE, s0}, /* begin procedure body */ + /* 07 LEFT_BRACKET */ {LEFT_BRACKET, s0}, /* begin array */ + /* 08 LEFT_ANGLE */ {HEX_STRING, s0}, /* hex string? */ + /* 09 RIGHT_BRACE */ {RIGHT_BRACE, s0}, /* end procedure body */ + /* 0A RIGHT_BRACKET */ {RIGHT_BRACKET, s0}, /* end array */ + /* 0B RIGHT_PAREN */ {RIGHT_PAREN, s0}, /* unmatched right paren */ + /* 0C RIGHT_ANGLE */ {RIGHT_ANGLE, s0}, /* unmatched right angle */ + /* 0D SIGN */ {add_sign, s2}, /* signed number? */ + /* 0E DECIMAL_POINT */ {add_1st_decpt, s4}, /* real number? */ + /* 0F ANY */ {NAME, s0}, /* executable name */ + /* 10 BREAK */ {BREAK_SIGNAL, s0}, /* break signalled */ + /* 11 EOF */ {NO_TOKEN, s0}, /* no token found */ + + /* s1: Further classify a '/' */ + /* 12 SLASH */ {IMMED_NAME, s0}, /* immediate name */ + /* 13 ANY */ {LITERAL_NAME, s0}, /* literal name */ + /* 14 BREAK */ {BREAK_SIGNAL, s0}, /* break signalled */ + /* 15 EOF */ {OOPS_NAME, s0}, /* isolated sign */ + + /* s2: sign */ + /* 16 WHITE_SPACE */ {OOPS_NAME, s0}, /* isolated sign */ + /* 17 SPECIAL */ {OOPS_NAME, s0}, /* isolated sign */ + /* 18 DIGIT */ {add_digits, s3}, /* number? */ + /* 19 DECIMAL_POINT */ {add_decpt, s4}, /* real number? */ + /* 1A ANY */ {NAME, s0}, /* executable name */ + /* 1B BREAK */ {BREAK_SIGNAL, s0}, /* break signalled */ + /* 1C EOF */ {OOPS_NAME, s0}, /* isolated sign */ + + /* s3: sign? digit+ */ + /* 1D WHITE_SPACE */ {INTEGER, s0}, /* n-digit integer */ + /* 1E SPECIAL */ {INTEGER, s0}, /* n-digit integer */ + /* 1F DECIMAL_POINT */ {add_char, s5}, /* real number? */ + /* 20 POUND */ {add_radix, s10}, /* radix number? */ + /* 21 eE */ {add_char, s7}, /* real with exponent? */ + /* 22 ANY */ {AAH_NAME, s0}, /* executable name */ + /* 23 BREAK */ {BREAK_SIGNAL, s0}, /* break signalled */ + /* 24 EOF */ {INTEGER, s0}, /* n-digit integer */ + + /* s4: sign? . */ + /* 25 WHITE_SPACE */ {OOPS_NAME, s0}, /* isolated +. or -. */ + /* 26 SPECIAL */ {OOPS_NAME, s0}, /* isolated +. or -. */ + /* 27 DIGIT */ {add_fraction, s6}, /* number? */ + /* 28 ANY */ {NAME, s0}, /* executable name */ + /* 29 BREAK */ {BREAK_SIGNAL, s0}, /* break signalled */ + /* 2A EOF */ {OOPS_NAME, s0}, /* isolated +. or -. */ + + /* s5: sign? digit+ . */ + /* 2B WHITE_SPACE */ {REAL, s0}, /* real with fraction */ + /* 2C SPECIAL */ {REAL, s0}, /* real with fraction */ + /* 2D eE */ {add_char, s7}, /* real with exponent? */ + /* 2E DIGIT */ {add_fraction, s6}, /* number? */ + /* 2F ANY */ {AAH_NAME, s0}, /* executable name */ + /* 30 BREAK */ {BREAK_SIGNAL, s0}, /* break signalled */ + /* 31 EOF */ {REAL, s0}, /* real with fraction */ + + /* s6: sign? (digit+ . digit+) | (. digit+) */ + /* 32 WHITE_SPACE */ {REAL, s0}, /* real with fraction */ + /* 33 SPECIAL */ {REAL, s0}, /* real with fraction */ + /* 34 eE */ {add_char, s7}, /* real with exponent? */ + /* 35 ANY */ {AAH_NAME, s0}, /* executable name */ + /* 36 BREAK */ {BREAK_SIGNAL, s0}, /* break signalled */ + /* 37 EOF */ {REAL, s0}, /* real with fraction */ + + /* s7: sign? ((digit+ (. digit*)?) | (. digit+)) Ee */ + /* 38 WHITE_SPACE */ {OOPS_NAME, s0}, /* invalid real number */ + /* 39 SPECIAL */ {OOPS_NAME, s0}, /* invalid real number */ + /* 3A SIGN */ {add_e_sign, s8}, /* real w signed exponent? */ + /* 3B DIGIT */ {add_exponent, s9}, /* real w exponent ? */ + /* 3C ANY */ {AAH_NAME, s0}, /* executable name */ + /* 3D BREAK */ {BREAK_SIGNAL, s0}, /* break signalled */ + /* 3E EOF */ {OOPS_NAME, s0}, /* invalid real number */ + + /* s8: sign? (digit+ (. digit*)? | (digit* . digit+) Ee sign */ + /* 3F WHITE_SPACE */ {OOPS_NAME, s0}, /* invalid real number */ + /* 40 SPECIAL */ {OOPS_NAME, s0}, /* invalid real number */ + /* 41 DIGIT */ {add_exponent, s9}, /* real w exponent? */ + /* 42 ANY */ {AAH_NAME, s0}, /* executable name */ + /* 43 BREAK */ {BREAK_SIGNAL, s0}, /* break signalled */ + /* 44 EOF */ {OOPS_NAME, s0}, /* invalid real number */ + + /* s9: sign? (digit+ (. digit*)? | (digit* . digit+) Ee sign? digit+ */ + /* 45 WHITE_SPACE */ {REAL, s0}, /* real w exponent */ + /* 46 SPECIAL */ {REAL, s0}, /* real w exponent */ + /* 47 ANY */ {AAH_NAME, s0}, /* executable name */ + /* 48 BREAK */ {BREAK_SIGNAL, s0}, /* break signalled */ + /* 49 EOF */ {REAL, s0}, /* real w exponent */ + + /* s10: digit+ # */ + /* 4A WHITE_SPACE */ {OOPS_NAME, s0}, /* invalid radix number */ + /* 4B SPECIAL */ {OOPS_NAME, s0}, /* invalid radix number */ + /* 4C R_DIGIT */ {add_r_digits, s11}, /* radix number? */ + /* 4D ANY */ {AAH_NAME, s0}, /* executable name */ + /* 4E BREAK */ {BREAK_SIGNAL, s0}, /* break signalled */ + /* 4F EOF */ {OOPS_NAME, s0}, /* invalid radix number */ + + /* s11: digit+ # r_digit+ */ + /* 50 WHITE_SPACE */ {RADIX_NUMBER, s0}, /* radix number */ + /* 51 SPECIAL */ {RADIX_NUMBER, s0}, /* radix number */ + /* 52 ANY */ {AAH_NAME, s0}, /* executable name */ + /* 53 BREAK */ {BREAK_SIGNAL, s0}, /* break signalled */ + /* 54 EOF */ {RADIX_NUMBER, s0} /* radix number */ +}; + +/* + * Character Classification Tables -- + * + * The entries in the Character Classification Tables + * map character codes to character classes. The + * tables contains one entry per code. The bits in + * each entry indicate which classes the character + * code belongs to. + * + * The macros 'isInCLASS(ch)' generate code to test + * whether 'ch' is a character in 'CLASS'. + * + */ +/* Membership macros for classes defined in table 1 ... */ +#define isRADIX_DIGIT(c) ((isInP1[c] & 0x80) != 0) +#define isHEX_DIGIT(c) ((isInP1[c] & 0x40) != 0) +#define isDECIMAL_DIGIT(c) ((isInP1[c] & 0x10) != 0) +#define isOCTAL_DIGIT(c) ((isInP1[c] & 0x20) != 0) + +/* Membership macros for classes defined in table 2 ... */ +#define isWHITE_SPACE(c) ((isInP2[c] & 0x80) != 0) +#define isCOMMENT(c) ((isInP2[c] & 0x40) != 0) +#define isNAME(c) ((isInP2[c] & 0x20) != 0) +#define isSTRING_SPECIAL(c) ((isInP2[c] & 0x10) != 0) +#define isNUMBER_ENDER(c) ((isInP2[c] & 0x08) != 0) + +#define isInP1 (isInT1+2) +static unsigned char isInT1[258] = { 0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xD0,0xD0,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, + 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00, + 0x00,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, + 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +}; + +#define isInP2 (isInT2+2) +static unsigned char isInT2[258] = { 0x18,0x18, + 0xC8,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0xC8,0x88,0x60,0x60,0x98,0x60,0x60, + 0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60, + 0xC8,0x60,0x60,0x60,0x60,0x48,0x60,0x60,0x58,0x58,0x60,0x60,0x60,0x60,0x60,0x48, + 0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x48,0x60,0x48,0x60, + 0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60, + 0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x48,0x70,0x48,0x60,0x60, + 0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60, + 0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x48,0x60,0x48,0x60,0x60, + 0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60, + 0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60, + 0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60, + 0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60, + 0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60, + 0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60, + 0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60, + 0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60 +}; + +#endif diff --git a/nx-X11/lib/font/Type1/trig.h b/nx-X11/lib/font/Type1/trig.h new file mode 100644 index 000000000..d569ed067 --- /dev/null +++ b/nx-X11/lib/font/Type1/trig.h @@ -0,0 +1,41 @@ +/* $Xorg: trig.h,v 1.3 2000/08/17 19:46:34 cpqbld Exp $ */ +/* Copyright International Business Machines,Corp. 1991 + * All Rights Reserved + * + * License to use, copy, modify, and distribute this software + * and its documentation for any purpose and without fee is + * hereby granted, provided that the above copyright notice + * appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, + * and that the name of IBM not be used in advertising or + * publicity pertaining to distribution of the software without + * specific, written prior permission. + * + * IBM PROVIDES THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES + * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT + * LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE QUALITY AND + * PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT + * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF + * THE SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM) ASSUMES + * THE ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN + * NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ +/*SHARED*/ + +/* $XFree86: xc/lib/font/Type1/trig.h,v 1.2 1998/07/25 06:57:00 dawes Exp $ */ + +#undef DegreeCos +#undef DegreeSin +#undef sqrt + +#define DegreeCos(d) xiStub() +#define DegreeSin(d) xiStub() +#define sqrt(d) xiStub() + diff --git a/nx-X11/lib/font/Type1/type1.c b/nx-X11/lib/font/Type1/type1.c new file mode 100644 index 000000000..b3fa4965a --- /dev/null +++ b/nx-X11/lib/font/Type1/type1.c @@ -0,0 +1,1892 @@ +/* $Xorg: type1.c,v 1.4 2000/08/17 19:46:34 cpqbld Exp $ */ +/* Copyright International Business Machines, Corp. 1991 + * All Rights Reserved + * Copyright Lexmark International, Inc. 1991 + * All Rights Reserved + * Portions Copyright (c) 1990 Adobe Systems Incorporated. + * All Rights Reserved + * + * License to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, + * provided that the above copyright notice appear in all copies and that + * both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of IBM or Lexmark or Adobe + * not be used in advertising or publicity pertaining to distribution of + * the software without specific, written prior permission. + * + * IBM, LEXMARK, AND ADOBE PROVIDE THIS SOFTWARE "AS IS", WITHOUT ANY + * WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT + * LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE, AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. THE + * ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE, INCLUDING + * ANY DUTY TO SUPPORT OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY + * PORTION OF THE SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM, + * LEXMARK, OR ADOBE) ASSUMES THE ENTIRE COST OF ALL SERVICING, REPAIR AND + * CORRECTION. IN NO EVENT SHALL IBM, LEXMARK, OR ADOBE BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +/* Copyright (c) 1994-1999 Silicon Graphics, Inc. All Rights Reserved. + * + * The contents of this file are subject to the CID Font Code Public Licence + * Version 1.0 (the "License"). You may not use this file except in compliance + * with the Licence. You may obtain a copy of the License at Silicon Graphics, + * Inc., attn: Legal Services, 2011 N. Shoreline Blvd., Mountain View, CA + * 94043 or at http://www.sgi.com/software/opensource/cid/license.html. + * + * Software distributed under the License is distributed on an "AS IS" basis. + * ALL WARRANTIES ARE DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED + * WARRANTIES OF MERCHANTABILITY, OF FITNESS FOR A PARTICULAR PURPOSE OR OF + * NON-INFRINGEMENT. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Software is CID font code that was developed by Silicon + * Graphics, Inc. + */ +/* $XFree86: xc/lib/font/Type1/type1.c,v 1.9tsi Exp $ */ + +/*********************************************************************/ +/* */ +/* Type 1 module - Converting fonts in Adobe Type 1 Font Format */ +/* to scaled and hinted paths for rasterization. */ +/* Files: type1.c, type1.h, and blues.h. */ +/* */ +/* Authors: Sten F. Andler, IBM Almaden Research Center */ +/* (Type 1 interpreter, stem & flex hints) */ +/* */ +/* Patrick A. Casey, Lexmark International, Inc. */ +/* (Font level hints & stem hints) */ +/* */ +/*********************************************************************/ + +/******************/ +/* Include Files: */ +/******************/ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#ifdef BUILDCID +#define XFONT_CID 1 +#endif + +#ifndef FONTMODULE +#include <stdio.h> /* a system-dependent include, usually */ +#include <math.h> +#else +#include "Xdefs.h" +#include "Xmd.h" +#include "xf86_ansic.h" +#endif +#include "objects.h" +#include "spaces.h" +#include "paths.h" +#include "fonts.h" /* understands about TEXTTYPEs */ +#include "pictures.h" /* understands about handles */ +#include "range.h" + +typedef struct xobject xobject; +#include "util.h" /* PostScript objects */ +#include "fontfcn.h" +#include "blues.h" /* Blues structure for font-level hints */ + +/**********************************/ +/* Type1 Constants and Structures */ +/**********************************/ +#define MAXSTACK 24 /* Adobe Type1 limit */ +#define MAXCALLSTACK 10 /* Adobe Type1 limit */ +#define MAXPSFAKESTACK 32 /* Max depth of fake PostScript stack (local) */ +#define MAXSTRLEN 512 /* Max length of a Type 1 string (local) */ +#define MAXLABEL 256 /* Maximum number of new hints */ +#if XFONT_CID +#define MAXSTEMS 500 /* Maximum number of VSTEM and HSTEM hints */ +#else +#define MAXSTEMS 128 /* Maximum number of VSTEM and HSTEM hints */ +#endif +#define EPS 0.001 /* Small number for comparisons */ + +/************************************/ +/* Adobe Type 1 CharString commands */ +/************************************/ +#define HSTEM 1 +#define VSTEM 3 +#define VMOVETO 4 +#define RLINETO 5 +#define HLINETO 6 +#define VLINETO 7 +#define RRCURVETO 8 +#define CLOSEPATH 9 +#define CALLSUBR 10 +#define RETURN 11 +#define ESCAPE 12 +#define HSBW 13 +#define ENDCHAR 14 +#define RMOVETO 21 +#define HMOVETO 22 +#define VHCURVETO 30 +#define HVCURVETO 31 + +/*******************************************/ +/* Adobe Type 1 CharString Escape commands */ +/*******************************************/ +#define DOTSECTION 0 +#define VSTEM3 1 +#define HSTEM3 2 +#define SEAC 6 +#define SBW 7 +#define DIV 12 +#define CALLOTHERSUBR 16 +#define POP 17 +#define SETCURRENTPOINT 33 + +/*****************/ +/* Useful macros */ +/*****************/ + +#define FABS(x) fabs(x) + +#define CEIL(x) ceil(x) + +#define FLOOR(x) floor(x) + +#define ROUND(x) FLOOR((x) + 0.5) + +#define ODD(x) (((int)(x)) & 01) + +#define Error {errflag = TRUE; return;} +#define ErrorRet(ret) {errflag = TRUE; return (ret);} + +/********************/ +/* global variables */ +/********************/ +struct stem { /* representation of a STEM hint */ + int vertical; /* TRUE if vertical, FALSE otherwise */ + double x, dx; /* interval of vertical stem */ + double y, dy; /* interval of horizontal stem */ + struct segment *lbhint, *lbrevhint; /* left or bottom hint adjustment */ + struct segment *rthint, *rtrevhint; /* right or top hint adjustment */ +}; + +struct xobject *Type1Char(char *env, struct XYspace *S, + psobj *charstrP, psobj *subrsP, psobj *osubrsP, + struct blues_struct *bluesP, int *modeP); +#if XFONT_CID +struct xobject *CIDChar(char *env, struct XYspace *S, + psobj *charstrP, psobj *subrsP, psobj *osubrsP, + struct blues_struct *bluesP, int *modeP); +#endif + +static double escapementX, escapementY; +static double sidebearingX, sidebearingY; +static double accentoffsetX, accentoffsetY; + +static struct segment *path; +static int errflag; + +/*************************************************/ +/* Global variables to hold Type1Char parameters */ +/*************************************************/ +static char *Environment; +static struct XYspace *CharSpace; +static psobj *CharStringP, *SubrsP; + +/************************/ +/* Forward declarations */ +/************************/ +static struct segment *Applyhint ( struct segment *p, int stemnumber, + int half ); +static struct segment *Applyrevhint ( struct segment *p, int stemnumber, + int half ); +static void CallOtherSubr ( int othersubrno ); +static void CallSubr ( int subrno ); +static struct segment *CenterStem ( double edge1, double edge2 ); +static void ClearCallStack ( void ); +static void ClearPSFakeStack ( void ); +static void ClearStack ( void ); +static void ComputeAlignmentZones ( void ); +static void ComputeStem ( int stemno ); +static void Decode ( int Code ); +static unsigned char Decrypt ( unsigned char cipher ); +static double Div ( double num1, double num2 ); +static void DoClosePath ( void ); +static void DoCommand ( int Code ); +static int DoRead ( int *CodeP ); +static void DotSection ( void ); +static void EndChar ( void ); +static void Escape ( int Code ); +static struct segment *FindStems ( double x, double y, double dx, double dy ); +static void FinitStems ( void ); +static void FlxProc ( double c1x2, double c1y2, double c3x0, double c3y0, + double c3x1, double c3y1, double c3x2, double c3y2, + double c4x0, double c4y0, double c4x1, double c4y1, + double c4x2, double c4y2, double epY, double epX, + int idmin ); +static void FlxProc1 ( void ); +static void FlxProc2 ( void ); +static void HintReplace ( void ); +static void HStem ( double y, double dy ); +static void InitStems ( void ); +static void PopCall ( psobj **CurrStrPP, int *CurrIndexP, + unsigned short *CurrKeyP ); +static double PSFakePop ( void ); +static void PSFakePush ( double Num ); +static void Push ( double Num ); +static void PushCall ( psobj *CurrStrP, int CurrIndex, + unsigned short CurrKey ); +static void Return ( void ); +static void RLineTo ( double dx, double dy ); +static void RMoveTo ( double dx, double dy ); +static void RRCurveTo ( double dx1, double dy1, double dx2, double dy2, + double dx3, double dy3 ); +static void Sbw ( double sbx, double sby, double wx, double wy ); +static void Seac ( double asb, double adx, double ady, unsigned char bchar, + unsigned char achar ); +static void SetCurrentPoint ( double x, double y ); +static void StartDecrypt ( void ); +static void VStem ( double x, double dx ); + +/*****************************************/ +/* statics for Flex procedures (FlxProc) */ +/*****************************************/ +static struct segment *FlxOldPath; /* save path before Flex feature */ + +/******************************************************/ +/* statics for Font level hints (Blues) (see blues.h) */ +/******************************************************/ +static struct blues_struct *blues; /* the blues structure */ +static struct alignmentzone alignmentzones[MAXALIGNMENTZONES]; +static int numalignmentzones; /* total number of alignment zones */ + +/****************************************************************/ +/* Subroutines for the Font level hints (Alignment zones, etc.) */ +/****************************************************************/ + +/******************************************/ +/* Fill in the alignment zone structures. */ +/******************************************/ +static void +ComputeAlignmentZones(void) +{ + int i; + double dummy, bluezonepixels, familyzonepixels; + struct segment *p; + + numalignmentzones = 0; /* initialize total # of zones */ + + /* do the BlueValues zones */ + for (i = 0; i < blues->numBlueValues; i +=2, ++numalignmentzones) { + /* the 0th & 1st numbers in BlueValues are for a bottom zone */ + /* the rest are topzones */ + if (i == 0) /* bottom zone */ + alignmentzones[numalignmentzones].topzone = FALSE; + else /* top zone */ + alignmentzones[numalignmentzones].topzone = TRUE; + if (i < blues->numFamilyBlues) { /* we must consider FamilyBlues */ + p = ILoc(CharSpace,0,blues->BlueValues[i] - blues->BlueValues[i+1]); + QueryLoc(p, IDENTITY, &dummy, &bluezonepixels); + Destroy(p); + p = ILoc(CharSpace,0,blues->FamilyBlues[i]-blues->FamilyBlues[i+1]); + QueryLoc(p, IDENTITY, &dummy, &familyzonepixels); + Destroy(p); + /* is the difference in size of the zones less than 1 pixel? */ + if (FABS(bluezonepixels - familyzonepixels) < 1.0) { + /* use the Family zones */ + alignmentzones[numalignmentzones].bottomy = + blues->FamilyBlues[i]; + alignmentzones[numalignmentzones].topy = + blues->FamilyBlues[i+1]; + continue; + } + } + /* use this font's Blue zones */ + alignmentzones[numalignmentzones].bottomy = blues->BlueValues[i]; + alignmentzones[numalignmentzones].topy = blues->BlueValues[i+1]; + } + + /* do the OtherBlues zones */ + for (i = 0; i < blues->numOtherBlues; i +=2, ++numalignmentzones) { + /* all of the OtherBlues zones are bottom zones */ + alignmentzones[numalignmentzones].topzone = FALSE; + if (i < blues->numFamilyOtherBlues) {/* consider FamilyOtherBlues */ + p = ILoc(CharSpace,0,blues->OtherBlues[i] - blues->OtherBlues[i+1]); + QueryLoc(p, IDENTITY, &dummy, &bluezonepixels); + Destroy(p); + p = ILoc(CharSpace,0,blues->FamilyOtherBlues[i] - + blues->FamilyOtherBlues[i+1]); + QueryLoc(p, IDENTITY, &dummy, &familyzonepixels); + Destroy(p); + /* is the difference in size of the zones less than 1 pixel? */ + if (FABS(bluezonepixels - familyzonepixels) < 1.0) { + /* use the Family zones */ + alignmentzones[numalignmentzones].bottomy = + blues->FamilyOtherBlues[i]; + alignmentzones[numalignmentzones].topy = + blues->FamilyOtherBlues[i+1]; + continue; + } + } + /* use this font's Blue zones (as opposed to the Family Blues */ + alignmentzones[numalignmentzones].bottomy = blues->OtherBlues[i]; + alignmentzones[numalignmentzones].topy = blues->OtherBlues[i+1]; + } +} + +/**********************************************************************/ +/* Subroutines and statics for handling of the VSTEM and HSTEM hints. */ +/**********************************************************************/ +static int InDotSection; /* DotSection flag */ +static struct stem stems[MAXSTEMS]; /* All STEM hints */ +static int numstems; /* Number of STEM hints */ +static int currstartstem; /* The current starting stem. */ +static int oldvert, oldhor; /* Remember hint in effect */ +static int oldhorhalf, oldverthalf; /* Remember which half of the stem */ +static double wsoffsetX, wsoffsetY; /* White space offset - for VSTEM3,HSTEM3 */ +static int wsset; /* Flag for whether we've set wsoffsetX,Y */ + +static void +InitStems(void) /* Initialize the STEM hint data structures */ +{ + InDotSection = FALSE; + currstartstem = numstems = 0; + oldvert = oldhor = -1; +} + +static void +FinitStems(void) /* Terminate the STEM hint data structures */ +{ + int i; + + for (i = 0; i < numstems; i++) { + Destroy(stems[i].lbhint); + Destroy(stems[i].lbrevhint); + Destroy(stems[i].rthint); + Destroy(stems[i].rtrevhint); + } +} + +/*******************************************************************/ +/* Compute the dislocation that a stemhint should cause for points */ +/* inside the stem. */ +/*******************************************************************/ +static void +ComputeStem(int stemno) +{ + int verticalondevice, idealwidth; + double stemstart, stemwidth; + struct segment *p; + int i; + double stembottom, stemtop, flatposition; + double Xpixels, Ypixels; + double unitpixels, onepixel; + int suppressovershoot, enforceovershoot; + double stemshift, flatpospixels, overshoot; + double widthdiff; /* Number of character space units to adjust width */ + double lbhintvalue, rthintvalue; + double cxx, cyx, cxy, cyy; /* Transformation matrix */ + int rotated; /* TRUE if character is on the side, FALSE if upright */ + + /************************************************/ + /* DETERMINE ORIENTATION OF CHARACTER ON DEVICE */ + /************************************************/ + + QuerySpace(CharSpace, &cxx, &cyx, &cxy, &cyy); /* Transformation matrix */ + + if (FABS(cxx) < 0.00001 || FABS(cyy) < 0.00001) + rotated = TRUE; /* Char is on side (90 or 270 degrees), possibly oblique. */ + else if (FABS(cyx) < 0.00001 || FABS(cxy) < 0.00001) + rotated = FALSE; /* Char is upright (0 or 180 degrees), possibly oblique. */ + else { + stems[stemno].lbhint = NULL; /* Char is at non-axial angle, ignore hints. */ + stems[stemno].lbrevhint = NULL; + stems[stemno].rthint = NULL; + stems[stemno].rtrevhint = NULL; + return; + } + + /* Determine orientation of stem */ + + if (stems[stemno].vertical) { + verticalondevice = !rotated; + stemstart = stems[stemno].x; + stemwidth = stems[stemno].dx; + } else { + verticalondevice = rotated; + stemstart = stems[stemno].y; + stemwidth = stems[stemno].dy; + } + + /* Determine how many pixels (non-negative) correspond to 1 character space + unit (unitpixels), and how many character space units (non-negative) + correspond to one pixel (onepixel). */ + + if (stems[stemno].vertical) + p = ILoc(CharSpace, 1, 0); + else + p = ILoc(CharSpace, 0, 1); + QueryLoc(p, IDENTITY, &Xpixels, &Ypixels); + Destroy(p); + if (verticalondevice) + unitpixels = FABS(Xpixels); + else + unitpixels = FABS(Ypixels); + + onepixel = 1.0 / unitpixels; + + /**********************/ + /* ADJUST STEM WIDTHS */ + /**********************/ + + widthdiff = 0.0; + + /* Find standard stem with smallest width difference from this stem */ + if (stems[stemno].vertical) { /* vertical stem */ + if (blues->StdVW != 0) /* there is an entry for StdVW */ + widthdiff = blues->StdVW - stemwidth; + for (i = 0; i < blues->numStemSnapV; ++i) { /* now look at StemSnapV */ + if (blues->StemSnapV[i] - stemwidth < widthdiff) + /* this standard width is the best match so far for this stem */ + widthdiff = blues->StemSnapV[i] - stemwidth; + } + } else { /* horizontal stem */ + if (blues->StdHW != 0) /* there is an entry for StdHW */ + widthdiff = blues->StdHW - stemwidth; + for (i = 0; i < blues->numStemSnapH; ++i) { /* now look at StemSnapH */ + if (blues->StemSnapH[i] - stemwidth < widthdiff) + /* this standard width is the best match so far for this stem */ + widthdiff = blues->StemSnapH[i] - stemwidth; + } + } + + /* Only expand or contract stems if they differ by less than 1 pixel from + the closest standard width, otherwise make the width difference = 0. */ + if (FABS(widthdiff) > onepixel) + widthdiff = 0.0; + + /* Expand or contract stem to the nearest integral number of pixels. */ + idealwidth = ROUND((stemwidth + widthdiff) * unitpixels); + /* Ensure that all stems are at least one pixel wide. */ + if (idealwidth == 0) + idealwidth = 1; + /* Apply ForceBold to vertical stems. */ + if (blues->ForceBold && stems[stemno].vertical) + /* Force this vertical stem to be at least DEFAULTBOLDSTEMWIDTH wide. */ + if (idealwidth < DEFAULTBOLDSTEMWIDTH) + idealwidth = DEFAULTBOLDSTEMWIDTH; + /* Now compute the number of character space units necessary */ + widthdiff = idealwidth * onepixel - stemwidth; + + /*********************************************************************/ + /* ALIGNMENT ZONES AND OVERSHOOT SUPPRESSION - HORIZONTAL STEMS ONLY */ + /*********************************************************************/ + + stemshift = 0.0; + + if (!stems[stemno].vertical) { + + /* Get bottom and top boundaries of the stem. */ + stembottom = stemstart; + stemtop = stemstart + stemwidth; + + /* Find out if this stem intersects an alignment zone (the BlueFuzz */ + /* entry in the Private dictionary specifies the number of character */ + /* units to extend (in both directions) the effect of an alignment */ + /* zone on a horizontal stem. The default value of BlueFuzz is 1. */ + for (i = 0; i < numalignmentzones; ++i) { + if (alignmentzones[i].topzone) { + if (stemtop >= alignmentzones[i].bottomy && + stemtop <= alignmentzones[i].topy + blues->BlueFuzz) { + break; /* We found a top-zone */ + } + } else { + if (stembottom <= alignmentzones[i].topy && + stembottom >= alignmentzones[i].bottomy - blues->BlueFuzz) { + break; /* We found a bottom-zone */ + } + } + } + + if (i < numalignmentzones) { /* We found an intersecting zone (number i). */ + suppressovershoot = FALSE; + enforceovershoot = FALSE; + + /* When 1 character space unit is rendered smaller than BlueScale + device units (pixels), we must SUPPRESS overshoots. Otherwise, + if the top (or bottom) of this stem is more than BlueShift character + space units away from the flat position, we must ENFORCE overshoot. */ + + if (unitpixels < blues->BlueScale) + suppressovershoot = TRUE; + else + if (alignmentzones[i].topzone) { + if (stemtop >= alignmentzones[i].bottomy + blues->BlueShift) + enforceovershoot = TRUE; + } else + if (stembottom <= alignmentzones[i].topy - blues->BlueShift) + enforceovershoot = TRUE; + + /*************************************************/ + /* ALIGN THE FLAT POSITION OF THE ALIGNMENT ZONE */ + /*************************************************/ + + /* Compute the position of the alignment zone's flat position in + device space and the amount of shift needed to align it on a + pixel boundary. Move all stems this amount. */ + + if (alignmentzones[i].topzone) + flatposition = alignmentzones[i].bottomy; + else + flatposition = alignmentzones[i].topy; + + /* Find the flat position in pixels */ + flatpospixels = flatposition * unitpixels; + + /* Find the stem shift necessary to align the flat + position on a pixel boundary, and use this shift for all stems */ + stemshift = (ROUND(flatpospixels) - flatpospixels) * onepixel; + + /************************************************/ + /* HANDLE OVERSHOOT ENFORCEMENT AND SUPPRESSION */ + /************************************************/ + + /* Compute overshoot amount (non-negative) */ + if (alignmentzones[i].topzone) + overshoot = stemtop - flatposition; + else + overshoot = flatposition - stembottom; + + if (overshoot > 0.0) { + /* ENFORCE overshoot by shifting the entire stem (if necessary) so that + it falls at least one pixel beyond the flat position. */ + + if (enforceovershoot) + if (overshoot < onepixel) { + if (alignmentzones[i].topzone) + stemshift += onepixel - overshoot; + else + stemshift -= onepixel - overshoot; + } + /* SUPPRESS overshoot by aligning the stem to the alignment zone's + flat position. */ + + if (suppressovershoot) { + if (alignmentzones[i].topzone) + stemshift -= overshoot; + else + stemshift += overshoot; + } + } + + /************************************************************/ + /* COMPUTE HINT VALUES FOR EACH SIDE OF THE HORIZONTAL STEM */ + /************************************************************/ + + /* If the stem was aligned by a topzone, we expand or contract the stem + only at the bottom - since the stem top was aligned by the zone. + If the stem was aligned by a bottomzone, we expand or contract the stem + only at the top - since the stem bottom was aligned by the zone. */ + if (alignmentzones[i].topzone) { + lbhintvalue = stemshift - widthdiff; /* bottom */ + rthintvalue = stemshift; /* top */ + } else { + lbhintvalue = stemshift; /* bottom */ + rthintvalue = stemshift + widthdiff; /* top */ + } + + stems[stemno].lbhint = (struct segment *)Permanent(Loc(CharSpace, 0.0, lbhintvalue)); + stems[stemno].lbrevhint = (struct segment *)Permanent(Loc(CharSpace, 0.0, -lbhintvalue)); + stems[stemno].rthint = (struct segment *)Permanent(Loc(CharSpace, 0.0, rthintvalue)); + stems[stemno].rtrevhint = (struct segment *)Permanent(Loc(CharSpace, 0.0, -rthintvalue)); + + return; + + } /* endif (i < numalignmentzones) */ + + /* We didn't find any alignment zones intersecting this stem, so + proceed with normal stem alignment below. */ + + } /* endif (!stems[stemno].vertical) */ + + /* Align stem with pixel boundaries on device */ + stemstart = stemstart - widthdiff / 2; + stemshift = ROUND(stemstart * unitpixels) * onepixel - stemstart; + + /* Adjust the boundaries of the stem */ + lbhintvalue = stemshift - widthdiff / 2; /* left or bottom */ + rthintvalue = stemshift + widthdiff / 2; /* right or top */ + + if (stems[stemno].vertical) { + stems[stemno].lbhint = (struct segment *)Permanent(Loc(CharSpace, lbhintvalue, 0.0)); + stems[stemno].lbrevhint = (struct segment *)Permanent(Loc(CharSpace, -lbhintvalue, 0.0)); + stems[stemno].rthint = (struct segment *)Permanent(Loc(CharSpace, rthintvalue, 0.0)); + stems[stemno].rtrevhint = (struct segment *)Permanent(Loc(CharSpace, -rthintvalue, 0.0)); + } else { + stems[stemno].lbhint = (struct segment *)Permanent(Loc(CharSpace, 0.0, lbhintvalue)); + stems[stemno].lbrevhint = (struct segment *)Permanent(Loc(CharSpace, 0.0, -lbhintvalue)); + stems[stemno].rthint = (struct segment *)Permanent(Loc(CharSpace, 0.0, rthintvalue)); + stems[stemno].rtrevhint = (struct segment *)Permanent(Loc(CharSpace, 0.0, -rthintvalue)); + } +} + +#define LEFT 1 +#define RIGHT 2 +#define BOTTOM 3 +#define TOP 4 + +/*********************************************************************/ +/* Adjust a point using the given stem hint. Use the left/bottom */ +/* hint value or the right/top hint value depending on where the */ +/* point lies in the stem. */ +/*********************************************************************/ +static struct segment * +Applyhint(struct segment *p, int stemnumber, int half) +{ + if (half == LEFT || half == BOTTOM) + return Join(p, stems[stemnumber].lbhint); /* left or bottom hint */ + else + return Join(p, stems[stemnumber].rthint); /* right or top hint */ +} + +/*********************************************************************/ +/* Adjust a point using the given reverse hint. Use the left/bottom */ +/* hint value or the right/top hint value depending on where the */ +/* point lies in the stem. */ +/*********************************************************************/ +static struct segment * +Applyrevhint(struct segment *p, int stemnumber, int half) +{ + if (half == LEFT || half == BOTTOM) + return Join(p, stems[stemnumber].lbrevhint); /* left or bottom hint */ + else + return Join(p, stems[stemnumber].rtrevhint); /* right or top hint */ +} + +/***********************************************************************/ +/* Find the vertical and horizontal stems that the current point */ +/* (x, y) may be involved in. At most one horizontal and one vertical */ +/* stem can apply to a single point, since there are no overlaps */ +/* allowed. */ +/* The actual hintvalue is returned as a location. */ +/* Hints are ignored inside a DotSection. */ +/***********************************************************************/ +static struct segment * +FindStems(double x, double y, double dx, double dy) +{ + int i; + int newvert, newhor; + struct segment *p; + int newhorhalf, newverthalf; + + if (InDotSection) return(NULL); + + newvert = newhor = -1; + newhorhalf = newverthalf = -1; + + for (i = currstartstem; i < numstems; i++) { + if (stems[i].vertical) { /* VSTEM hint */ + if ((x >= stems[i].x - EPS) && + (x <= stems[i].x+stems[i].dx + EPS)) { + newvert = i; + if (dy != 0.0) { + if (dy < 0) newverthalf = LEFT; + else newverthalf = RIGHT; + } else { + if (x < stems[i].x+stems[i].dx / 2) newverthalf = LEFT; + else newverthalf = RIGHT; + } + } + } else { /* HSTEM hint */ + if ((y >= stems[i].y - EPS) && + (y <= stems[i].y+stems[i].dy + EPS)) { + newhor = i; + if (dx != 0.0) { + if (dx < 0) newhorhalf = TOP; + else newhorhalf = BOTTOM; + } else { + if (y < stems[i].y+stems[i].dy / 2) newhorhalf = BOTTOM; + else newhorhalf = TOP; + } + } + } + } + + p = NULL; + + if (newvert == -1 && oldvert == -1) ; /* Outside of any hints */ + else if (newvert == oldvert && + newverthalf == oldverthalf); /* No hint change */ + else if (oldvert == -1) { /* New vertical hint in effect */ + p = Applyhint(p, newvert, newverthalf); + } else if (newvert == -1) { /* Old vertical hint no longer in effect */ + p = Applyrevhint(p, oldvert, oldverthalf); + } else { /* New vertical hint in effect, old hint no longer in effect */ + p = Applyrevhint(p, oldvert, oldverthalf); + p = Applyhint(p, newvert, newverthalf); + } + + if (newhor == -1 && oldhor == -1) ; /* Outside of any hints */ + else if (newhor == oldhor && + newhorhalf == oldhorhalf) ; /* No hint change */ + else if (oldhor == -1) { /* New horizontal hint in effect */ + p = Applyhint(p, newhor, newhorhalf); + } else if (newhor == -1) { /* Old horizontal hint no longer in effect */ + p = Applyrevhint(p, oldhor, oldhorhalf); + } + else { /* New horizontal hint in effect, old hint no longer in effect */ + p = Applyrevhint(p, oldhor, oldhorhalf); + p = Applyhint(p, newhor, newhorhalf); + } + + oldvert = newvert; oldverthalf = newverthalf; + oldhor = newhor; oldhorhalf = newhorhalf; + + return p; +} + +/******************************************************/ +/* Subroutines and statics for the Type1Char routines */ +/******************************************************/ + +static int strindex; /* index into PostScript string being interpreted */ +static double currx, curry; /* accumulated x and y values for hints */ + +struct callstackentry { + psobj *currstrP; /* current CharStringP */ + int currindex; /* current strindex */ + unsigned short currkey; /* current decryption key */ + }; + +static double Stack[MAXSTACK]; +static int Top; +static struct callstackentry CallStack[MAXCALLSTACK]; +static int CallTop; +static double PSFakeStack[MAXPSFAKESTACK]; +static int PSFakeTop; + +static void +ClearStack(void) +{ + Top = -1; +} + +static void +Push(double Num) +{ + if (++Top < MAXSTACK) Stack[Top] = Num; + else Error; +} + +static void +ClearCallStack(void) +{ + CallTop = -1; +} + +static void +PushCall(psobj *CurrStrP, int CurrIndex, unsigned short CurrKey) +{ + if (++CallTop < MAXCALLSTACK) { + CallStack[CallTop].currstrP = CurrStrP; /* save CharString pointer */ + CallStack[CallTop].currindex = CurrIndex; /* save CharString index */ + CallStack[CallTop].currkey = CurrKey; /* save decryption key */ + } + else Error; +} + +static void +PopCall(psobj **CurrStrPP, int *CurrIndexP, unsigned short *CurrKeyP) +{ + if (CallTop >= 0) { + *CurrStrPP = CallStack[CallTop].currstrP; /* restore CharString pointer */ + *CurrIndexP = CallStack[CallTop].currindex; /* restore CharString index */ + *CurrKeyP = CallStack[CallTop--].currkey; /* restore decryption key */ + } + else Error; +} + +static void +ClearPSFakeStack(void) +{ + PSFakeTop = -1; +} + +/* PSFakePush: Pushes a number onto the fake PostScript stack */ +static void +PSFakePush(double Num) +{ + if (++PSFakeTop < MAXPSFAKESTACK) PSFakeStack[PSFakeTop] = Num; + else Error; +} + +/* PSFakePop: Removes a number from the top of the fake PostScript stack */ +static double +PSFakePop (void) +{ + if (PSFakeTop >= 0) return(PSFakeStack[PSFakeTop--]); + else ErrorRet(0.0); + /*NOTREACHED*/ +} + +/***********************************************************************/ +/* Center a stem on the pixel grid -- used by HStem3 and VStem3 */ +/***********************************************************************/ +static struct segment * +CenterStem(double edge1, double edge2) +{ + int idealwidth, verticalondevice; + double leftx, lefty, rightx, righty, center, width; + double widthx, widthy; + double shift, shiftx, shifty; + double Xpixels, Ypixels; + struct segment *p; + + p = Loc(CharSpace, edge1, 0.0); + QueryLoc(p, IDENTITY, &leftx, &lefty); + + p = Join(p, Loc(CharSpace, edge2, 0.0)); + QueryLoc(p, IDENTITY, &rightx, &righty); + Destroy(p); + + widthx = FABS(rightx - leftx); + widthy = FABS(righty - lefty); + + if (widthy <= EPS) { /* verticalondevice hint */ + verticalondevice = TRUE; + center = (rightx + leftx) / 2.0; + width = widthx; + } + else if (widthx <= EPS) { /* horizontal hint */ + verticalondevice = FALSE; + center = (righty + lefty) / 2.0; + width = widthy; + } + else { /* neither horizontal nor verticalondevice and not oblique */ + return (NULL); + } + + idealwidth = ROUND(width); + if (idealwidth == 0) idealwidth = 1; + if (ODD(idealwidth)) { /* is ideal width odd? */ + /* center stem over pixel */ + shift = FLOOR(center) + 0.5 - center; + } + else { + /* align stem on pixel boundary */ + shift = ROUND(center) - center; + } + + if (verticalondevice) { + shiftx = shift; + shifty = 0.0; + } else { + shifty = shift; + shiftx = 0.0; + } + + p = Loc(IDENTITY, shiftx, shifty); + QueryLoc(p, CharSpace, &Xpixels, &Ypixels); + wsoffsetX = Xpixels; wsoffsetY = Ypixels; + currx += wsoffsetX; curry += wsoffsetY; + + return (p); +} + +/*----------------------------------------------------------------------- + Decrypt - From Adobe Type 1 book page 63, with some modifications +-----------------------------------------------------------------------*/ +#define KEY 4330 /* Initial key (seed) for CharStrings decryption */ +#define C1 52845 /* Multiplier for pseudo-random number generator */ +#define C2 22719 /* Constant for pseudo-random number generator */ + +static unsigned short r; /* Pseudo-random sequence of keys */ + +static unsigned char +Decrypt(unsigned char cipher) +{ + unsigned char plain; + + plain = cipher ^ (r >> 8); + r = (cipher + r) * C1 + C2; + return plain; +} + +/* Get the next byte from the codestring being interpreted */ +static int +DoRead(int *CodeP) +{ + if (strindex >= CharStringP->len) return(FALSE); /* end of string */ + *CodeP = Decrypt((unsigned char) CharStringP->data.stringP[strindex++]); + return(TRUE); +} + +/* Strip blues->lenIV bytes from CharString and update encryption key */ +/* (the lenIV entry in the Private dictionary specifies the number of */ +/* random bytes at the beginning of each CharString; default is 4) */ +static void +StartDecrypt(void) +{ + int Code; + + r = KEY; /* Initial key (seed) for CharStrings decryption */ + for (strindex = 0; strindex < blues->lenIV;) + if (!DoRead(&Code)) /* Read a byte and update decryption key */ + Error; +} + +static void +Decode(int Code) +{ + int Code1, Code2, Code3, Code4; + + if (Code <= 31) /* Code is [0,31] */ + DoCommand(Code); + else if (Code <= 246) /* Code is [32,246] */ + Push((double)(Code - 139)); + else if (Code <= 250) { /* Code is [247,250] */ + if (!DoRead(&Code2)) goto ended; + Push((double)(((Code - 247) << 8) + Code2 + 108)); + } + else if (Code <= 254) { /* Code is [251,254] */ + if (!DoRead(&Code2)) goto ended; + Push((double)( -((Code - 251) << 8) - Code2 - 108)); + } + else { /* Code is 255 */ + if (!DoRead(&Code1)) goto ended; + if (!DoRead(&Code2)) goto ended; + if (!DoRead(&Code3)) goto ended; + if (!DoRead(&Code4)) goto ended; + Push((double)((((((Code1<<8) + Code2)<<8) + Code3)<<8) + Code4)); + } + return; + +ended: Error; +} + +/* Interpret a command code */ +static void +DoCommand(int Code) +{ + switch(Code) { + case HSTEM: /* |- y dy HSTEM |- */ + /* Vertical range of a horizontal stem zone */ + if (Top < 1) Error; + HStem(Stack[0], Stack[1]); + ClearStack(); + break; + case VSTEM: /* |- x dx VSTEM |- */ + /* Horizontal range of a vertical stem zone */ + if (Top < 1) Error; + VStem(Stack[0], Stack[1]); + ClearStack(); + break; + case VMOVETO: /* |- dy VMOVETO |- */ + /* Vertical MOVETO, equivalent to 0 dy RMOVETO */ + if (Top < 0) Error; + RMoveTo(0.0, Stack[0]); + ClearStack(); + break; + case RLINETO: /* |- dx dy RLINETO |- */ + /* Like RLINETO in PostScript */ + if (Top < 1) Error; + RLineTo(Stack[0], Stack[1]); + ClearStack(); + break; + case HLINETO: /* |- dx HLINETO |- */ + /* Horizontal LINETO, equivalent to dx 0 RLINETO */ + if (Top < 0) Error; + RLineTo(Stack[0], 0.0); + ClearStack(); + break; + case VLINETO: /* |- dy VLINETO |- */ + /* Vertical LINETO, equivalent to 0 dy RLINETO */ + if (Top < 0) Error; + RLineTo(0.0, Stack[0]); + ClearStack(); + break; + case RRCURVETO: + /* |- dx1 dy1 dx2 dy2 dx3 dy3 RRCURVETO |- */ + /* Relative RCURVETO, equivalent to dx1 dy1 */ + /* (dx1+dx2) (dy1+dy2) (dx1+dx2+dx3) */ + /* (dy1+dy2+dy3) RCURVETO in PostScript */ + if (Top < 5) Error; + RRCurveTo(Stack[0], Stack[1], Stack[2], Stack[3], + Stack[4], Stack[5]); + ClearStack(); + break; + case CLOSEPATH: /* - CLOSEPATH |- */ + /* Closes a subpath without repositioning the */ + /* current point */ + DoClosePath(); + ClearStack(); + break; + case CALLSUBR: /* subr# CALLSUBR - */ + /* Calls a CharString subroutine with index */ + /* subr# from the Subrs array */ + if (Top < 0) Error; + CallSubr((int)Stack[Top--]); + break; + case RETURN: /* - RETURN - */ + /* Returns from a Subrs array CharString */ + /* subroutine called with CALLSUBR */ + Return(); + break; + case ESCAPE: /* ESCAPE to two-byte command code */ + if (!DoRead(&Code)) Error; + Escape(Code); + break; + case HSBW: /* |- sbx wx HSBW |- */ + /* Set the left sidebearing point to (sbx,0), */ + /* set the character width vector to (wx,0). */ + /* Equivalent to sbx 0 wx 0 SBW. Space */ + /* character should have sbx = 0 */ + if (Top < 1) Error; + Sbw(Stack[0], 0.0, Stack[1], 0.0); + ClearStack(); + break; + case ENDCHAR: /* - ENDCHAR |- */ + /* Finishes a CharString outline */ + EndChar(); + ClearStack(); + break; + case RMOVETO: /* |- dx dy RMOVETO |- */ + /* Behaves like RMOVETO in PostScript */ + if (Top < 1) Error; + RMoveTo(Stack[0], Stack[1]); + ClearStack(); + break; + case HMOVETO: /* |- dx HMOVETO |- */ + /* Horizontal MOVETO. Equivalent to dx 0 RMOVETO */ + if (Top < 0) Error; + RMoveTo(Stack[0], 0.0); + ClearStack(); + break; + case VHCURVETO: /* |- dy1 dx2 dy2 dx3 VHCURVETO |- */ + /* Vertical-Horizontal CURVETO, equivalent to */ + /* 0 dy1 dx2 dy2 dx3 0 RRCURVETO */ + if (Top < 3) Error; + RRCurveTo(0.0, Stack[0], Stack[1], Stack[2], + Stack[3], 0.0); + ClearStack(); + break; + case HVCURVETO: /* |- dx1 dx2 dy2 dy3 HVCURVETO |- */ + /* Horizontal-Vertical CURVETO, equivalent to */ + /* dx1 0 dx2 dy2 0 dy3 RRCURVETO */ + if (Top < 3) Error; + RRCurveTo(Stack[0], 0.0, Stack[1], Stack[2], 0.0, Stack[3]); + ClearStack(); + break; + default: /* Unassigned command code */ + ClearStack(); + Error; + } +} + +static void +Escape(int Code) +{ + int i, Num; + struct segment *p; + + switch(Code) { + case DOTSECTION: /* - DOTSECTION |- */ + /* Brackets an outline section for the dots in */ + /* letters such as "i", "j", and "!". */ + DotSection(); + ClearStack(); + break; + case VSTEM3: /* |- x0 dx0 x1 dx1 x2 dx2 VSTEM3 |- */ + /* Declares the horizontal ranges of three */ + /* vertical stem zones between x0 and x0+dx0, */ + /* x1 and x1+dx1, and x2 and x2+dx2. */ + if (Top < 5) Error; + if (!wsset && ProcessHints) { + /* Shift the whole character so that the middle stem is centered. */ + p = CenterStem(Stack[2] + sidebearingX, Stack[3]); + path = Join(path, p); + wsset = 1; + } + + VStem(Stack[0], Stack[1]); + VStem(Stack[2], Stack[3]); + VStem(Stack[4], Stack[5]); + ClearStack(); + break; + case HSTEM3: /* |- y0 dy0 y1 dy1 y2 dy2 HSTEM3 |- */ + /* Declares the vertical ranges of three hori- */ + /* zontal stem zones between y0 and y0+dy0, */ + /* y1 and y1+dy1, and y2 and y2+dy2. */ + if (Top < 5) Error; + HStem(Stack[0], Stack[1]); + HStem(Stack[2], Stack[3]); + HStem(Stack[4], Stack[5]); + ClearStack(); + break; + case SEAC: /* |- asb adx ady bchar achar SEAC |- */ + /* Standard Encoding Accented Character. */ + if (Top < 4) Error; + Seac(Stack[0], Stack[1], Stack[2], + (unsigned char) Stack[3], + (unsigned char) Stack[4]); + ClearStack(); + break; + case SBW: /* |- sbx sby wx wy SBW |- */ + /* Set the left sidebearing point to (sbx,sby), */ + /* set the character width vector to (wx,wy). */ + if (Top < 3) Error; + Sbw(Stack[0], Stack[1], Stack[2], Stack[3]); + ClearStack(); + break; + case DIV: /* num1 num2 DIV quotient */ + /* Behaves like DIV in the PostScript language */ + if (Top < 1) Error; + Stack[Top-1] = Div(Stack[Top-1], Stack[Top]); + Top--; + break; + case CALLOTHERSUBR: + /* arg1 ... argn n othersubr# CALLOTHERSUBR - */ + /* Make calls on the PostScript interpreter */ + if (Top < 1) Error; + Num = Stack[Top-1]; + if (Top < Num+1) Error; + for (i = 0; i < Num; i++) PSFakePush(Stack[Top - i - 2]); + Top -= Num + 2; +#if XFONT_CID + if ((int)Stack[Top + Num + 2] > 3) + ClearPSFakeStack(); + else + CallOtherSubr((int)Stack[Top + Num + 2]); +#else + CallOtherSubr((int)Stack[Top + Num + 2]); +#endif + break; + case POP: /* - POP number */ + /* Removes a number from the top of the */ + /* PostScript interpreter stack and pushes it */ + /* onto the Type 1 BuildChar operand stack */ + Push(PSFakePop()); + break; + case SETCURRENTPOINT: /* |- x y SETCURRENTPOINT |- */ + /* Sets the current point to (x,y) in absolute */ + /* character space coordinates without per- */ + /* forming a CharString MOVETO command */ + if (Top < 1) Error; + SetCurrentPoint(Stack[0], Stack[1]); + ClearStack(); + break; + default: /* Unassigned escape code command */ + ClearStack(); + Error; + } +} + +/* |- y dy HSTEM |- */ +/* Declares the vertical range of a horizontal stem zone */ +/* between coordinates y and y + dy */ +/* y is relative to the left sidebearing point */ +static void +HStem(double y, double dy) +{ + if (ProcessHints) { + if (numstems >= MAXSTEMS) Error; + if (dy < 0.0) {y += dy; dy = -dy;} + stems[numstems].vertical = FALSE; + stems[numstems].x = 0.0; + stems[numstems].y = sidebearingY + y + wsoffsetY; + stems[numstems].dx = 0.0; + stems[numstems].dy = dy; + ComputeStem(numstems); + numstems++; + } +} + +/* |- x dx VSTEM |- */ +/* Declares the horizontal range of a vertical stem zone */ +/* between coordinates x and x + dx */ +/* x is relative to the left sidebearing point */ + +static void +VStem(double x, double dx) +{ + if (ProcessHints) { + if (numstems >= MAXSTEMS) Error; + if (dx < 0.0) {x += dx; dx = -dx;} + stems[numstems].vertical = TRUE; + stems[numstems].x = sidebearingX + x + wsoffsetX; + stems[numstems].y = 0.0; + stems[numstems].dx = dx; + stems[numstems].dy = 0.0; + ComputeStem(numstems); + numstems++; + } +} + +/* |- dx dy RLINETO |- */ +/* Behaves like RLINETO in PostScript */ +static void +RLineTo(double dx, double dy) +{ + struct segment *B; + + B = Loc(CharSpace, dx, dy); + + if (ProcessHints) { + currx += dx; + curry += dy; + /* B = Join(B, FindStems(currx, curry)); */ + B = Join(B, FindStems(currx, curry, dx, dy)); + } + + path = Join(path, Line(B)); +} + +/* |- dx1 dy1 dx2 dy2 dx3 dy3 RRCURVETO |- */ +/* Relative RCURVETO, equivalent to dx1 dy1 */ +/* (dx1+dx2) (dy1+dy2) (dx1+dx2+dx3) */ +/* (dy1+dy2+dy3) RCURVETO in PostScript */ +static void +RRCurveTo(double dx1, double dy1, double dx2, double dy2, + double dx3, double dy3) +{ + struct segment *B, *C, *D; + + B = Loc(CharSpace, dx1, dy1); + C = Loc(CharSpace, dx2, dy2); + D = Loc(CharSpace, dx3, dy3); + + if (ProcessHints) { + /* For a Bezier curve, we apply the full hint value to + the Bezier C point (and thereby D point). */ + currx += dx1 + dx2 + dx3; + curry += dy1 + dy2 + dy3; + /* C = Join(C, FindStems(currx, curry)); */ + C = Join(C, FindStems(currx, curry, dx3, dy3)); + } + + /* Since XIMAGER is not completely relative, */ + /* we need to add up the delta values */ + + C = Join(C, (struct segment *)Dup(B)); + D = Join(D, (struct segment *)Dup(C)); + + path = Join(path, (struct segment *)Bezier(B, C, D)); +} + +/* - CLOSEPATH |- */ +/* Closes a subpath WITHOUT repositioning the */ +/* current point */ +static void +DoClosePath(void) +{ + struct segment *CurrentPoint; + + CurrentPoint = Phantom(path); + path = ClosePath(path); + path = Join(Snap(path), CurrentPoint); +} + +/* subr# CALLSUBR - */ +/* Calls a CharString subroutine with index */ +/* subr# from the Subrs array */ +static void +CallSubr(int subrno) +{ + if ((subrno < 0) || (subrno >= SubrsP->len)) + Error; + PushCall(CharStringP, strindex, r); + CharStringP = &SubrsP->data.arrayP[subrno]; + StartDecrypt(); +} + +/* - RETURN - */ +/* Returns from a Subrs array CharString */ +/* subroutine called with CALLSUBR */ +static void +Return(void) +{ + PopCall(&CharStringP, &strindex, &r); +} + +/* - ENDCHAR |- */ +/* Finishes a CharString outline */ +/* Executes SETCHACHEDEVICE using a bounding box */ +/* it computes directly from the character outline */ +/* and using the width information acquired from a previous */ +/* HSBW or SBW. It then calls a special version of FILL */ +/* or STROKE depending on the value of PaintType in the */ +/* font dictionary */ +static void +EndChar(void) +{ + /* There is no need to compute and set bounding box for + the cache, since XIMAGER does that on the fly. */ + + /* Perform a Closepath just in case the command was left out */ + path = ClosePath(path); + + /* Set character width */ + path = Join(Snap(path), Loc(CharSpace, escapementX, escapementY)); + +} + +/* |- dx dy RMOVETO |- */ +/* Behaves like RMOVETO in PostScript */ +static void +RMoveTo(double dx, double dy) +{ + struct segment *B; + + B = Loc(CharSpace, dx, dy); + + if (ProcessHints) { + currx += dx; + curry += dy; + /* B = Join(B, FindStems(currx, curry)); */ + B = Join(B, FindStems(currx, curry, 0.0, 0.0)); + } + + path = Join(path, B); +} + +/* - DOTSECTION |- */ +/* Brackets an outline section for the dots in */ +/* letters such as "i", "j", and "!". */ +static void +DotSection(void) +{ + InDotSection = !InDotSection; +} + +/* |- asb adx ady bchar achar SEAC |- */ +/* Standard Encoding Accented Character. */ +static void +Seac(double asb, double adx, double ady, + unsigned char bchar, unsigned char achar) +{ + int Code; + struct segment *mypath; + + /* Move adx - asb, ady over and up from base char's sbpoint. */ + /* (We use adx - asb to counteract the accents sb shift.) */ + /* The variables accentoffsetX/Y modify sidebearingX/Y in Sbw(). */ + /* Note that these incorporate the base character's sidebearing shift by */ + /* using the current sidebearingX, Y values. */ + accentoffsetX = sidebearingX + adx - asb; + accentoffsetY = sidebearingY + ady; + + /* Set path = NULL to avoid complaints from Sbw(). */ + path = NULL; + + /* Go find the CharString for the accent's code via an upcall */ + CharStringP = GetType1CharString((psfont *)Environment, achar); + StartDecrypt(); + + ClearStack(); + ClearPSFakeStack(); + ClearCallStack(); + + for (;;) { + if (!DoRead(&Code)) break; + Decode(Code); + if (errflag) return; + } + /* Copy snapped path to mypath and set path to NULL as above. */ + mypath = Snap(path); + path = NULL; + + /* We must reset these to null now. */ + accentoffsetX = accentoffsetY = 0; + + /* go find the CharString for the base char's code via an upcall */ + CharStringP = GetType1CharString((psfont *)Environment, bchar); + StartDecrypt(); + + ClearStack(); + ClearPSFakeStack(); + ClearCallStack(); + + FinitStems(); + InitStems(); + + for (;;) { + if (!DoRead(&Code)) break; + Decode(Code); + if (errflag) return; + } + path = Join(mypath, path); +} + + +/* |- sbx sby wx wy SBW |- */ +/* Set the left sidebearing point to (sbx,sby), */ +/* set the character width vector to (wx,wy). */ +static void +Sbw(double sbx, double sby, double wx, double wy) +{ + escapementX = wx; /* Character width vector */ + escapementY = wy; + + /* Sidebearing values are sbx, sby args, plus accent offset from Seac(). */ + sidebearingX = sbx + accentoffsetX; + sidebearingY = sby + accentoffsetY; + + path = Join(path, Loc(CharSpace, sidebearingX, sidebearingY)); + if (ProcessHints) {currx = sidebearingX; curry = sidebearingY;} +} + + /* num1 num2 DIV quotient */ +/* Behaves like DIV in the PostScript language */ +static double +Div(double num1, double num2) +{ + return(num1 / num2); +} + +/* + The following four subroutines (FlxProc, FlxProc1, FlxProc2, and + HintReplace) are C versions of the OtherSubrs Programs, which were + were published in the Adobe Type 1 Font Format book. + + The Flex outline fragment is described by + c1: (x0, y0) = c3: (x0, yshrink(y0)) or (xshrink(x0), y0) + " (x1, y1) = " (x1, yshrink(y1)) or (xshrink(x1), y1) + " (x2, y2) - reference point + c2: (x0, y0) = c4: (x0, yshrink(y0)) or (xshrink(x0), y0) + " (x1, y1) = " (x1, yshrink(y1)) or (xshrink(x1), y1) + " (x2, y2) = " (x2, y2), rightmost endpoint + c3: (x0, y0) - control point, 1st Bezier curve + " (x1, y1) - control point, -"- + " (x2, y2) - end point, -"- + c4: (x0, y0) - control point, 2nd Bezier curve + " (x1, y1) - control point, -"- + " (x2, y2) - end point, -"- + ep: (epY, epX) - final endpoint (should be same as c4: (x2, y2)) + idmin - minimum Flex height (1/100 pixel) at which to render curves +*/ + +#define dtransform(dxusr,dyusr,dxdev,dydev) { \ + register struct segment *point = Loc(CharSpace, dxusr, dyusr); \ + QueryLoc(point, IDENTITY, dxdev, dydev); \ + Destroy(point); \ +} + +#define itransform(xdev,ydev,xusr,yusr) { \ + register struct segment *point = Loc(IDENTITY, xdev, ydev); \ + QueryLoc(point, CharSpace, xusr, yusr); \ + Destroy(point); \ +} + +#define transform(xusr,yusr,xdev,ydev) dtransform(xusr,yusr,xdev,ydev) + +#define PaintType (0) + +#define lineto(x,y) { \ + struct segment *CurrentPoint; \ + double CurrentX, CurrentY; \ + CurrentPoint = Phantom(path); \ + QueryLoc(CurrentPoint, CharSpace, &CurrentX, &CurrentY); \ + Destroy(CurrentPoint); \ + RLineTo(x - CurrentX, y - CurrentY); \ +} + +#define curveto(x0,y0,x1,y1,x2,y2) { \ + struct segment *CurrentPoint; \ + double CurrentX, CurrentY; \ + CurrentPoint = Phantom(path); \ + QueryLoc(CurrentPoint, CharSpace, &CurrentX, &CurrentY); \ + Destroy(CurrentPoint); \ + RRCurveTo(x0 - CurrentX, y0 - CurrentY, x1 - x0, y1 - y0, x2 - x1, y2 - y1); \ +} + +#define xshrink(x) ((x - c4x2) * shrink +c4x2) +#define yshrink(y) ((y - c4y2) * shrink +c4y2) + +#define PickCoords(flag) \ + if (flag) { /* Pick "shrunk" coordinates */ \ + x0 = c1x0; y0 = c1y0; \ + x1 = c1x1; y1 = c1y1; \ + x2 = c1x2; y2 = c1y2; \ + x3 = c2x0; y3 = c2y0; \ + x4 = c2x1; y4 = c2y1; \ + x5 = c2x2; y5 = c2y2; \ + } else { /* Pick original coordinates */ \ + x0 = c3x0; y0 = c3y0; \ + x1 = c3x1; y1 = c3y1; \ + x2 = c3x2; y2 = c3y2; \ + x3 = c4x0; y3 = c4y0; \ + x4 = c4x1; y4 = c4y1; \ + x5 = c4x2; y5 = c4y2; \ + } + +/* FlxProc() = OtherSubrs[0]; Main part of Flex */ +/* Calling sequence: 'idmin epX epY 3 0 callothersubr' */ +/* Computes Flex values, and renders the Flex path, */ +/* and returns (leaves) ending coordinates on stack */ +static void +FlxProc(double c1x2, double c1y2, double c3x0, double c3y0, + double c3x1, double c3y1, double c3x2, double c3y2, + double c4x0, double c4y0, double c4x1, double c4y1, + double c4x2, double c4y2, double epY, double epX, int idmin) +{ + double dmin; + double c1x0, c1y0, c1x1, c1y1; + double c2x0, c2y0, c2x1, c2y1, c2x2, c2y2; + char yflag; + double x0, y0, x1, y1, x2, y2, x3, y3, x4, y4, x5, y5; + double cxx, cyx, cxy, cyy; /* Transformation matrix */ + int flipXY; + double x, y; + double erosion = 1; /* Device parameter */ + /* Erosion may have different value specified in 'internaldict' */ + double shrink; + double dX, dY; + char erode; + double eShift; + double cx, cy; + double ex, ey; + + c1x0 = c1y0 = c1x1 = c1y1 = c2x0 = c2y0 = c2x1 = c2y1 = c2x2 = c2y2 = 0.0; + + Destroy(path); + path = FlxOldPath; /* Restore previous path (stored in FlxProc1) */ + + if (ProcessHints) { + dmin = ABS(idmin) / 100.0; /* Minimum Flex height in pixels */ + + c2x2 = c4x2; c2y2 = c4y2; /* Point c2 = c4 */ + + yflag = FABS(c1y2 - c3y2) > FABS(c1x2 - c3x2); /* Flex horizontal? */ + + QuerySpace(CharSpace, &cxx, &cyx, &cxy, &cyy); /* Transformation matrix */ + + if (FABS(cxx) < 0.00001 || FABS(cyy) < 0.00001) + flipXY = -1; /* Char on side */ + else if (FABS(cyx) < 0.00001 || FABS(cxy) < 0.00001) + flipXY = 1; /* Char upright */ + else + flipXY = 0; /* Char at angle */ + + if (yflag) { /* Flex horizontal */ + if (flipXY == 0 || c3y2 == c4y2) { /* Char at angle or Flex height = 0 */ + PickCoords(FALSE); /* Pick original control points */ + } else { + shrink = FABS((c1y2 - c4y2) / (c3y2 - c4y2)); /* Slope */ + + c1x0 = c3x0; c1y0 = yshrink(c3y0); + c1x1 = c3x1; c1y1 = yshrink(c3y1); + c2x0 = c4x0; c2y0 = yshrink(c4y0); + c2x1 = c4x1; c2y1 = yshrink(c4y1); + + dtransform(0.0, ROUND(c3y2-c1y2), &x, &y); /* Flex height in pixels */ + dY = FABS((flipXY == 1) ? y : x); + PickCoords(dY < dmin); /* If Flex small, pick 'shrunk' control points */ + + if (FABS(y2 - c1y2) > 0.001) { /* Flex 'non-zero'? */ + transform(c1x2, c1y2, &x, &y); + + if (flipXY == 1) { + cx = x; cy = y; + } else { + cx = y; cy = x; + } + + dtransform(0.0, ROUND(y2-c1y2), &x, &y); + dY = (flipXY == 1) ? y : x; + if (ROUND(dY) != 0) + dY = ROUND(dY); + else + dY = (dY < 0) ? -1 : 1; + + erode = PaintType != 2 && erosion >= 0.5; + if (erode) + cy -= 0.5; + ey = cy + dY; + ey = CEIL(ey) - ey; + ey = ey + FLOOR(cy + dY); + if (erode) + ey += 0.5; + + if (flipXY == 1) { + itransform(cx, ey, &x, &y); + } else { + itransform(ey, cx, &x, &y); + } + + eShift = y - y2; + y1 += eShift; + y2 += eShift; + y3 += eShift; + } + } + } else { /* Flex vertical */ + if (flipXY == 0 || c3x2 == c4x2) { /* Char at angle or Flex height = 0 */ + PickCoords(FALSE); /* Pick original control points */ + } else { + shrink = FABS((c1x2 - c4x2) / (c3x2 - c4x2)); /* Slope */ + + c1x0 = xshrink(c3x0); c1y0 = c3y0; + c1x1 = xshrink(c3x1); c1y1 = c3y1; + c2x0 = xshrink(c4x0); c2y0 = c4y0; + c2x1 = xshrink(c4x1); c2y1 = c4y1; + + dtransform(ROUND(c3x2 - c1x2), 0.0, &x, &y); /* Flex height in pixels */ + dX = FABS((flipXY == -1) ? y : x); + PickCoords(dX < dmin); /* If Flex small, pick 'shrunk' control points */ + + if (FABS(x2 - c1x2) > 0.001) { + transform(c1x2, c1y2, &x, &y); + if (flipXY == -1) { + cx = y; cy = x; + } else { + cx = x; cy = y; + } + + dtransform(ROUND(x2-c1x2), 0.0, &x, &y); + dX = (flipXY == -1) ? y : x; + if (ROUND(dX) != 0) + dX = ROUND(dX); + else + dX = (dX < 0) ? -1 : 1; + + erode = PaintType != 2 && erosion >= 0.5; + if (erode) + cx -= 0.5; + ex = cx + dX; + ex = CEIL(ex) - ex; + ex = ex + FLOOR(cx + dX); + if (erode) + ex += 0.5; + + if (flipXY == -1) { + itransform(cy, ex, &x, &y); + } else { + itransform(ex, cy, &x, &y); + } + + eShift = x - x2; + x1 += eShift; + x2 += eShift; + x3 += eShift; + } + } + } + + if (x2 == x5 || y2 == y5) { + lineto(x5, y5); + } else { + curveto(x0, y0, x1, y1, x2, y2); + curveto(x3, y3, x4, y4, x5, y5); + } + } else { /* ProcessHints is off */ + PickCoords(FALSE); /* Pick original control points */ + curveto(x0, y0, x1, y1, x2, y2); + curveto(x3, y3, x4, y4, x5, y5); + } + + PSFakePush(epY); + PSFakePush(epX); +} + +/* FlxProc1() = OtherSubrs[1]; Part of Flex */ +/* Calling sequence: '0 1 callothersubr' */ +/* Saves and clears path, then restores currentpoint */ +static void +FlxProc1(void) +{ + struct segment *CurrentPoint; + + CurrentPoint = Phantom(path); + + FlxOldPath = path; + path = CurrentPoint; +} + +/* FlxProc2() = OtherSubrs[2]; Part of Flex */ +/* Calling sequence: '0 2 callothersubr' */ +/* Returns currentpoint on stack */ +static void +FlxProc2(void) +{ + struct segment *CurrentPoint; + double CurrentX, CurrentY; + + CurrentPoint = Phantom(path); + QueryLoc(CurrentPoint, CharSpace, &CurrentX, &CurrentY); + Destroy(CurrentPoint); + + /* Push CurrentPoint on fake PostScript stack */ + PSFakePush(CurrentX); + PSFakePush(CurrentY); +} + +/* HintReplace() = OtherSubrs[3]; Hint Replacement */ +/* Calling sequence: 'subr# 1 3 callothersubr pop callsubr' */ +/* Reinitializes stem hint structure */ +static void +HintReplace(void) +{ + /* Effectively retire the current stems, but keep them around for */ + /* revhint use in case we are in a stem when we replace hints. */ + currstartstem = numstems; + + /* 'subr#' is left on PostScript stack (for 'pop callsubr') */ +} + +/* arg1 ... argn n othersubr# CALLOTHERSUBR - */ +/* Make calls on the PostScript interpreter (or call equivalent C code) */ +/* NOTE: The n arguments have been pushed on the fake PostScript stack */ +static void +CallOtherSubr(int othersubrno) +{ + switch(othersubrno) { + case 0: /* OtherSubrs[0]; Main part of Flex */ + if (PSFakeTop < 16) Error; + ClearPSFakeStack(); + FlxProc( + PSFakeStack[0], PSFakeStack[1], PSFakeStack[2], PSFakeStack[3], + PSFakeStack[4], PSFakeStack[5], PSFakeStack[6], PSFakeStack[7], + PSFakeStack[8], PSFakeStack[9], PSFakeStack[10], PSFakeStack[11], + PSFakeStack[12], PSFakeStack[13], PSFakeStack[14], PSFakeStack[15], + (int) PSFakeStack[16] + ); + break; + case 1: /* OtherSubrs[1]; Part of Flex */ + FlxProc1(); + break; + case 2: /* OtherSubrs[2]; Part of Flex */ + FlxProc2(); + break; + case 3: /* OtherSubrs[3]; Hint Replacement */ + HintReplace(); + break; + default: { /* call OtherSubrs[4] or higher if PostScript is present */ + } + } +} + +/* |- x y SETCURRENTPOINT |- */ +/* Sets the current point to (x,y) in absolute */ +/* character space coordinates without per- */ +/* forming a CharString MOVETO command */ +static void +SetCurrentPoint(double x, double y) +{ + currx = x; + curry = y; +} + +/* The Type1Char routine for use by PostScript. */ +/************************************************/ +struct xobject * +Type1Char(char *env, struct XYspace *S, psobj *charstrP, psobj *subrsP, + psobj *osubrsP, + struct blues_struct *bluesP, /* FontID's ptr to the blues struct */ + int *modeP) +{ + int Code; + + path = NULL; + errflag = FALSE; + + /* Make parameters available to all Type1 routines */ + Environment = env; + CharSpace = S; /* used when creating path elements */ + CharStringP = charstrP; + SubrsP = subrsP; + + blues = bluesP; + + /* compute the alignment zones */ + ComputeAlignmentZones(); + + StartDecrypt(); + + ClearStack(); + ClearPSFakeStack(); + ClearCallStack(); + + InitStems(); + + currx = curry = 0; + escapementX = escapementY = 0; + sidebearingX = sidebearingY = 0; + accentoffsetX = accentoffsetY = 0; + wsoffsetX = wsoffsetY = 0; /* No shift to preserve whitspace. */ + wsset = 0; /* wsoffsetX,Y haven't been set yet. */ + + for (;;) { + if (!DoRead(&Code)) break; + Decode(Code); + if (errflag) break; + } + + FinitStems(); + + + /* Clean up if an error has occurred */ + if (errflag) { + if (path != NULL) { + Destroy(path); /* Reclaim storage */ + path = NULL; /* Indicate that character could not be built */ + } + } + + return((struct xobject *) path); +} + +#if XFONT_CID +struct xobject * +CIDChar(char *env, struct XYspace *S, + psobj *charstrP, psobj *subrsP, psobj *osubrsP, + struct blues_struct *bluesP, /* FontID's ptr to the blues struct */ + int *modeP) +{ + int Code; + + path = NULL; + errflag = FALSE; + + /* Make parameters available to all CID routines */ + Environment = env; + CharSpace = S; /* used when creating path elements */ + CharStringP = charstrP; + SubrsP = subrsP; + + blues = bluesP; + + /* compute the alignment zones */ + ComputeAlignmentZones(); + + StartDecrypt(); + + ClearStack(); + ClearPSFakeStack(); + ClearCallStack(); + + InitStems(); + + currx = curry = 0; + escapementX = escapementY = 0; + sidebearingX = sidebearingY = 0; + accentoffsetX = accentoffsetY = 0; + wsoffsetX = wsoffsetY = 0; /* No shift to preserve whitspace. */ + wsset = 0; /* wsoffsetX,Y haven't been set yet. */ + + for (;;) { + if (!DoRead(&Code)) break; + Decode(Code); + if (errflag) break; + } + + FinitStems(); + + /* Clean up if an error has occurred */ + if (errflag) { + if (path != NULL) { + Destroy(path); /* Reclaim storage */ + path = NULL; /* Indicate that character could not be built */ + } + } + + return((struct xobject *) path); +} +#endif diff --git a/nx-X11/lib/font/Type1/util.c b/nx-X11/lib/font/Type1/util.c new file mode 100644 index 000000000..7c5a81dee --- /dev/null +++ b/nx-X11/lib/font/Type1/util.c @@ -0,0 +1,222 @@ +/* $Xorg: util.c,v 1.3 2000/08/17 19:46:34 cpqbld Exp $ */ +/* Copyright International Business Machines,Corp. 1991 + * All Rights Reserved + * + * License to use, copy, modify, and distribute this software + * and its documentation for any purpose and without fee is + * hereby granted, provided that the above copyright notice + * appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, + * and that the name of IBM not be used in advertising or + * publicity pertaining to distribution of the software without + * specific, written prior permission. + * + * IBM PROVIDES THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES + * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT + * LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE QUALITY AND + * PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT + * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF + * THE SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM) ASSUMES + * THE ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN + * NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ +/* Copyright (c) 1994-1999 Silicon Graphics, Inc. All Rights Reserved. + * + * The contents of this file are subject to the CID Font Code Public Licence + * Version 1.0 (the "License"). You may not use this file except in compliance + * with the Licence. You may obtain a copy of the License at Silicon Graphics, + * Inc., attn: Legal Services, 2011 N. Shoreline Blvd., Mountain View, CA + * 94043 or at http://www.sgi.com/software/opensource/cid/license.html. + * + * Software distributed under the License is distributed on an "AS IS" basis. + * ALL WARRANTIES ARE DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED + * WARRANTIES OF MERCHANTABILITY, OF FITNESS FOR A PARTICULAR PURPOSE OR OF + * NON-INFRINGEMENT. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Software is CID font code that was developed by Silicon + * Graphics, Inc. + */ +/* $XFree86: xc/lib/font/Type1/util.c,v 1.5 1999/08/21 13:47:53 dawes Exp $ */ +/* Author: Katherine A. Hitchcock IBM Almaden Research Laboratory */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#ifdef BUILDCID +#define XFONT_CID 1 +#endif + +#ifndef FONTMODULE +#include <stdio.h> +#else +#include "Xdefs.h" +#include "Xmd.h" +#include "xf86_ansic.h" +#endif +#include "util.h" +#include <X11/fonts/fontmisc.h> /* for xalloc/xfree */ + +static char *vm_base = NULL; /* Start of virtual memory area */ + char *vm_next = NULL; /* Pointer to first free byte */ + long vm_free = 0; /* Count of free bytes */ + long vm_size = 0; /* Total size of memory */ + +/* + * Initialize memory. + */ +boolean +vm_init(int cnt) +{ +#if XFONT_CID + if (vm_base == NULL || (vm_base != NULL && vm_size != cnt)) { + if (vm_base != NULL) xfree(vm_base); + vm_next = vm_base = (char *)xalloc (cnt); + } else + vm_next = vm_base; +#else + vm_next = vm_base = (char *)xalloc (cnt); +#endif + + if (vm_base != NULL) { + vm_free = cnt; + vm_size = cnt; + return(TRUE); + } + else + return(FALSE); + +} + +char * +vm_alloc(int bytes) +{ + char *answer; + + /* Round to next word multiple */ + bytes = (bytes + 7) & ~7; + + /* Allocate the space, if it is available */ + if (bytes > 0 && bytes <= vm_free) { + answer = vm_next; + vm_free -= bytes; + vm_next += bytes; + } + else + answer = NULL; + + return(answer); +} + +/* + * Format an Integer object + */ +void +objFormatInteger(psobj *objP, int value) +{ + if (objP != NULL) { + objP->type = OBJ_INTEGER; + objP->len = 0; + objP->data.integer = value; + } +} + +/* + * Format a Real object + */ +void +objFormatReal(psobj *objP, float value) +{ + if (objP != NULL) { + objP->type = OBJ_REAL; + objP->len = 0; + objP->data.real = value; + } +} + +/* + * Format a Boolean object + */ +void +objFormatBoolean(psobj *objP, boolean value) +{ + if (objP != NULL) { + objP->type = OBJ_BOOLEAN; + objP->len = 0; + objP->data.boolean = value; + } +} + +/* + * Format an Encoding object + */ +void +objFormatEncoding(psobj *objP, int length, psobj *valueP) +{ + if (objP != NULL) { + objP->type = OBJ_ENCODING; + objP->len = length; + objP->data.arrayP = valueP; + } +} + +/* + * Format an Array object + */ +void +objFormatArray(psobj *objP, int length, psobj *valueP) +{ + if (objP != NULL) { + objP->type = OBJ_ARRAY; + objP->len = length; + objP->data.arrayP = valueP; + } +} + + +/* + * Format a String object + */ +void +objFormatString(psobj *objP, int length, char *valueP) +{ + if (objP != NULL) { + objP->type = OBJ_STRING; + objP->len = length; + objP->data.valueP = valueP; + } +} + +/* + * Format a Name object + */ +void +objFormatName(psobj *objP, int length, char *valueP) +{ + if (objP != NULL) { + objP->type = OBJ_NAME; + objP->len = length; + objP->data.nameP = valueP; + } +} + +/* + * Format a File object + */ +void +objFormatFile(psobj *objP, FILE *valueP) +{ + if (objP != NULL) { + objP->type = OBJ_FILE; + objP->len = 0; + objP->data.fileP = valueP; + } +} + diff --git a/nx-X11/lib/font/Type1/util.h b/nx-X11/lib/font/Type1/util.h new file mode 100644 index 000000000..a1a8b3e6b --- /dev/null +++ b/nx-X11/lib/font/Type1/util.h @@ -0,0 +1,217 @@ +/* $Xorg: util.h,v 1.3 2000/08/17 19:46:34 cpqbld Exp $ */ +/* Copyright International Business Machines,Corp. 1991 + * All Rights Reserved + * + * License to use, copy, modify, and distribute this software + * and its documentation for any purpose and without fee is + * hereby granted, provided that the above copyright notice + * appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, + * and that the name of IBM not be used in advertising or + * publicity pertaining to distribution of the software without + * specific, written prior permission. + * + * IBM PROVIDES THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES + * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT + * LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE QUALITY AND + * PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT + * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF + * THE SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM) ASSUMES + * THE ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN + * NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ +/* Copyright (c) 1994-1999 Silicon Graphics, Inc. All Rights Reserved. + * + * The contents of this file are subject to the CID Font Code Public Licence + * Version 1.0 (the "License"). You may not use this file except in compliance + * with the Licence. You may obtain a copy of the License at Silicon Graphics, + * Inc., attn: Legal Services, 2011 N. Shoreline Blvd., Mountain View, CA + * 94043 or at http://www.sgi.com/software/opensource/cid/license.html. + * + * Software distributed under the License is distributed on an "AS IS" basis. + * ALL WARRANTIES ARE DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED + * WARRANTIES OF MERCHANTABILITY, OF FITNESS FOR A PARTICULAR PURPOSE OR OF + * NON-INFRINGEMENT. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Software is CID font code that was developed by Silicon + * Graphics, Inc. + */ +/* $XFree86: xc/lib/font/Type1/util.h,v 1.4 1999/08/22 08:58:55 dawes Exp $ */ + +#ifndef UTIL_H +#define UTIL_H + +#ifdef BUILDCID +#define XFONT_CID 1 +#endif + +#ifndef boolean +typedef int boolean; +#endif + +#ifndef TRUE +#define TRUE (1) +#endif + +#ifndef FALSE +#define FALSE (0) +#endif + +/***================================================================***/ +/* Portable definitions for 2's complement machines. + * NOTE: These really should be based on PostScript types, + * for example, sizeof(ps_integer), or sizeof(ps_unsigned) + */ +#define MAX_ULONG (~(unsigned long)(0)) +/* This code is portable, assuming K&R C and 2's complement arithmetic */ +#define MAX_INTEGER \ + ((long)((((unsigned long) 1)<<(sizeof(unsigned long)*8-1))-1)) +#define MIN_INTEGER ((-MAX_INTEGER)-1) + +#define MAX_ARRAY_CNT (65535) +#define MAX_DICT_CNT (65535) +#define MAX_STRING_LEN (65535) +#define MAX_NAME_LEN (128) + +/* this is the size of memory allocated for reading fonts */ + +#if XFONT_CID +#define VM_SIZE (100*1024) +#else +#define VM_SIZE (50*1024) +#endif +/***================================================================***/ + +#ifndef MIN +#define MIN(a,b) (((a)<(b)) ? a : b ) +#endif + +/***================================================================***/ +/* Routines for managing virtual memory */ +/***================================================================***/ + +extern boolean vm_init ( int cnt ); +extern long vm_free; +extern long vm_size; +extern char *vm_next; +extern char *vm_alloc ( int bytes ); + +/***================================================================***/ +/* Macros for managing virtual memory */ +/***================================================================***/ +#define vm_next_byte() (vm_next) +#define vm_free_bytes() (vm_free) +#define vm_avail(B) (B <= vm_free) + + + +/***================================================================***/ +/* Types of PostScript objects */ +/***================================================================***/ +#define OBJ_INTEGER (0) +#define OBJ_REAL (1) +#define OBJ_BOOLEAN (2) +#define OBJ_ARRAY (3) +#define OBJ_STRING (4) +#define OBJ_NAME (5) +#define OBJ_FILE (6) +#define OBJ_ENCODING (7) + +/***================================================================***/ +/* Value of PostScript objects */ +/***================================================================***/ +typedef union ps_value { + char *valueP; /* value pointer for unspecified type */ + int value; /* value for unspecified type */ + int integer; /* when type is OBJ_INTEGER */ + float real; /* when type is OBJ_REAL */ + int boolean; /* when type is OBJ_BOOLEAN */ + struct ps_obj *arrayP; /* when type is OBJ_ARRAY */ + unsigned char *stringP; /* when type is OBJ_STRING */ + char *nameP; /* when type is OBJ_NAME */ + FILE *fileP; /* when type is OBJ_FILE */ +} psvalue; + +/***================================================================***/ +/* Definition of a PostScript object */ +/***================================================================***/ +typedef struct ps_obj { + char type; + char unused; + unsigned short len; + union ps_value data; +} psobj; + +/***================================================================***/ +/* Definition of a PostScript Dictionary Entry */ +/***================================================================***/ +typedef struct ps_dict { + psobj key; + psobj value; +} psdict; + +/***================================================================***/ +/* Macros for testing type of PostScript objects */ +/***================================================================***/ +#define objIsInteger(o) ((o).type == OBJ_INTEGER) +#define objIsReal(o) ((o).type == OBJ_REAL) +#define objIsBoolean(o) ((o).type == OBJ_BOOLEAN) +#define objIsArray(o) ((o).type == OBJ_ARRAY) +#define objIsString(o) ((o).type == OBJ_STRING) +#define objIsName(o) ((o).type == OBJ_NAME) +#define objIsFile(o) ((o).type == OBJ_FILE) + +/***================================================================***/ +/* Macros for setting type of PostScript objects */ +/***================================================================***/ +#define objSetInteger(o) ((o).type = OBJ_INTEGER) +#define objSetReal(o) ((o).type = OBJ_REAL) +#define objSetBoolean(o) ((o).type = OBJ_BOOLEAN) +#define objSetArray(o) ((o).type = OBJ_ARRAY) +#define objSetString(o) ((o).type = OBJ_STRING) +#define objSetName(o) ((o).type = OBJ_NAME) +#define objSetFile(o) ((o).type = OBJ_FILE) + +/***================================================================***/ +/* Macros for testing type of PostScript objects (pointer access) */ +/***================================================================***/ +#define objPIsInteger(o) ((o)->type == OBJ_INTEGER) +#define objPIsReal(o) ((o)->type == OBJ_REAL) +#define objPIsBoolean(o) ((o)->type == OBJ_BOOLEAN) +#define objPIsArray(o) ((o)->type == OBJ_ARRAY) +#define objPIsString(o) ((o)->type == OBJ_STRING) +#define objPIsName(o) ((o)->type == OBJ_NAME) +#define objPIsFile(o) ((o)->type == OBJ_FILE) + +/***================================================================***/ +/* Macros for setting type of PostScript objects (pointer access) */ +/***================================================================***/ +#define objPSetInteger(o) ((o)->type = OBJ_INTEGER) +#define objPSetReal(o) ((o)->type = OBJ_REAL) +#define objPSetBoolean(o) ((o)->type = OBJ_BOOLEAN) +#define objPSetArray(o) ((o)->type = OBJ_ARRAY) +#define objPSetString(o) ((o)->type = OBJ_STRING) +#define objPSetName(o) ((o)->type = OBJ_NAME) +#define objPSetFile(o) ((o)->type = OBJ_FILE) + +/***================================================================***/ +/* Prototypes of object formatting functions */ +/***================================================================***/ +extern void objFormatInteger ( psobj *objP, int value ); +extern void objFormatReal ( psobj *objP, float value ); +extern void objFormatBoolean ( psobj *objP, boolean value ); +extern void objFormatEncoding ( psobj *objP, int length, psobj *valueP ); +extern void objFormatArray ( psobj *objP, int length, psobj *valueP ); +extern void objFormatString ( psobj *objP, int length, char *valueP ); +extern void objFormatName ( psobj *objP, int length, char *valueP ); +extern void objFormatFile ( psobj *objP, FILE *valueP ); + +#endif diff --git a/nx-X11/lib/font/bitmap/Imakefile b/nx-X11/lib/font/bitmap/Imakefile new file mode 100644 index 000000000..9acbe7796 --- /dev/null +++ b/nx-X11/lib/font/bitmap/Imakefile @@ -0,0 +1,71 @@ +XCOMM $Xorg: Imakefile,v 1.3 2000/08/17 19:46:34 cpqbld Exp $ + + + + +XCOMM $XFree86: xc/lib/font/bitmap/Imakefile,v 1.11 2001/04/03 17:51:59 paulo Exp $ + +#if BuildServer && DoLoadableServer +#define IHaveSubdirs +#define NoLibSubdirs +#define PassCDebugFlags +SUBDIRS = module +#endif + +BDFSRCS=bdfread.c bdfutils.c +BDFOBJS=bdfread.o bdfutils.o +#ifndef KDriveXServer +BDFDEFS=-DBDFFORMAT + +SNFSRCS=snfread.c +SNFOBJS=snfread.o +SNFDEFS=-DSNFFORMAT +#endif + +PCFSRCS=pcfread.c pcfwrite.c +PCFOBJS=pcfread.o pcfwrite.o +PCFDEFS=-DPCFFORMAT + + + INCLUDES = -I$(FONTINCSRC) -I../include + HEADERS = bdfint.h pcf.h +#ifdef FontFormatDefines + FORMAT_DEFS = FontFormatDefines +#endif +#if GzipFontCompression + GZIP_DEFS = -DX_GZIP_FONT_COMPRESSION +#endif + DEFINES = $(BDFDEFS) $(PCFDEFS) $(SNFDEFS) + + SRCS = $(BDFSRCS) bitmap.c bitmaputil.c bitscale.c \ + bitmapfunc.c $(PCFSRCS) $(SNFSRCS) \ + fontink.c + + OBJS = $(BDFOBJS) bitmap.o bitmaputil.o bitscale.o \ + bitmapfunc.o $(PCFOBJS) $(SNFOBJS) \ + fontink.o + +#if BuildFontLib +#define DoNormalLib NormalLibFont +#define DoSharedLib SharedLibFont +#define DoDebugLib DebugLibFont +#define DoProfileLib ProfileLibFont +#include <Library.tmpl> +LibraryObjectRule() + +SpecialCLibObjectRule(bitmapfunc,$(ICONFIGFILES),$(GZIP_DEFS)) +SpecialCLibObjectRule(bitscale,$(ICONFIGFILES),$(GZIP_DEFS)) + +SubdirLibraryRule($(OBJS)) +NormalLintTarget($(SRCS)) +#endif + +#if BuildServer && DoLoadableServer +MakeSubdirs($(SUBDIRS)) +DependSubdirs($(SUBDIRS)) +#endif + +BuildIncludes($(HEADERS),X11/fonts,../..) +InstallMultipleFlags($(HEADERS),$(INCDIR)/X11/fonts,$(INSTINCFLAGS)) + +DependTarget() diff --git a/nx-X11/lib/font/bitmap/bdfint.h b/nx-X11/lib/font/bitmap/bdfint.h new file mode 100644 index 000000000..d41c4a556 --- /dev/null +++ b/nx-X11/lib/font/bitmap/bdfint.h @@ -0,0 +1,90 @@ +/* $Xorg: bdfint.h,v 1.4 2001/02/09 02:04:01 xorgcvs Exp $ */ + +/* + +Copyright 1990, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + +*/ +/* $XFree86: xc/lib/font/bitmap/bdfint.h,v 1.4 2001/01/17 19:43:26 dawes Exp $ */ + +#ifndef BDFINT_H +#define BDFINT_H + +#define bdfIsPrefix(buf,str) (!strncmp((char *)buf,str,strlen(str))) +#define bdfStrEqual(s1,s2) (!strcmp(s1,s2)) + +#define BDF_GENPROPS 6 +#define NullProperty ((FontPropPtr)0) + +/* + * This structure holds some properties we need to generate if they aren't + * specified in the BDF file and some other values read from the file + * that we'll need to calculate them. We need to keep track of whether + * or not we've read them. + */ +typedef struct BDFSTAT { + int linenum; + char *fileName; + char fontName[MAXFONTNAMELEN]; + float pointSize; + int resolution_x; + int resolution_y; + int digitCount; + int digitWidths; + int exHeight; + + FontPropPtr fontProp; + FontPropPtr pointSizeProp; + FontPropPtr resolutionXProp; + FontPropPtr resolutionYProp; + FontPropPtr resolutionProp; + FontPropPtr xHeightProp; + FontPropPtr weightProp; + FontPropPtr quadWidthProp; + BOOL haveFontAscent; + BOOL haveFontDescent; + BOOL haveDefaultCh; +} bdfFileState; + +extern void bdfError ( char * message, ... ); +extern void bdfWarning ( char *message, ... ); +extern unsigned char * bdfGetLine ( FontFilePtr file, unsigned char *buf, + int len ); +extern Atom bdfForceMakeAtom ( char *str, int *size ); +extern Atom bdfGetPropertyValue ( char *s ); +extern int bdfIsInteger ( char *str ); +extern unsigned char bdfHexByte ( unsigned char *s ); +extern Bool bdfSpecialProperty ( FontPtr pFont, FontPropPtr prop, + char isString, bdfFileState *bdfState ); +extern int bdfReadFont( FontPtr pFont, FontFilePtr file, + int bit, int byte, int glyph, int scan ); +extern int bdfReadFontInfo( FontInfoPtr pFontInfo, FontFilePtr file ); + +extern void FontCharInkMetrics ( FontPtr pFont, CharInfoPtr pCI, + xCharInfo *pInk ); +extern void FontCharReshape ( FontPtr pFont, CharInfoPtr pSrc, + CharInfoPtr pDst ); + +#endif /* BDFINT_H */ diff --git a/nx-X11/lib/font/bitmap/bdfread.c b/nx-X11/lib/font/bitmap/bdfread.c new file mode 100644 index 000000000..a6f0c1e7e --- /dev/null +++ b/nx-X11/lib/font/bitmap/bdfread.c @@ -0,0 +1,967 @@ +/* $Xorg: bdfread.c,v 1.5 2001/02/09 02:04:01 xorgcvs Exp $ */ + +/************************************************************************ +Copyright 1989 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +************************************************************************/ + +/* + +Copyright 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + +*/ +/* $XFree86: xc/lib/font/bitmap/bdfread.c,v 1.12tsi Exp $ */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#ifndef FONTMODULE +#include <ctype.h> +#endif +#include <X11/fonts/fntfilst.h> +#include <X11/fonts/fontutil.h> +/* use bitmap structure */ +#include <X11/fonts/bitmap.h> +#include <X11/fonts/bdfint.h> + +#if HAVE_STDINT_H +#include <stdint.h> +#elif !defined(INT32_MAX) +#define INT32_MAX 0x7fffffff +#endif + +#define INDICES 256 +#define MAXENCODING 0xFFFF +#define BDFLINELEN 1024 + +static Bool bdfPadToTerminal(FontPtr pFont); +extern int bdfFileLineNum; + +/***====================================================================***/ + +static Bool +bdfReadBitmap(CharInfoPtr pCI, FontFilePtr file, int bit, int byte, + int glyph, int scan, CARD32 *sizes) +{ + int widthBits, + widthBytes, + widthHexChars; + int height, + row; + int i, + inLineLen, + nextByte; + unsigned char *pInBits, + *picture, + *line = NULL; + unsigned char lineBuf[BDFLINELEN]; + + widthBits = GLYPHWIDTHPIXELS(pCI); + height = GLYPHHEIGHTPIXELS(pCI); + + widthBytes = BYTES_PER_ROW(widthBits, glyph); + if (widthBytes * height > 0) { + picture = (unsigned char *) xalloc(widthBytes * height); + if (!picture) { + bdfError("Couldn't allocate picture (%d*%d)\n", widthBytes, height); + goto BAILOUT; + } + } else + picture = NULL; + pCI->bits = (char *) picture; + + if (sizes) { + for (i = 0; i < GLYPHPADOPTIONS; i++) + sizes[i] += BYTES_PER_ROW(widthBits, (1 << i)) * height; + } + nextByte = 0; + widthHexChars = BYTES_PER_ROW(widthBits, 1); + +/* 5/31/89 (ef) -- hack, hack, hack. what *am* I supposed to do with */ +/* 0 width characters? */ + + for (row = 0; row < height; row++) { + line = bdfGetLine(file, lineBuf, BDFLINELEN); + if (!line) + break; + + if (widthBits == 0) { + if ((!line) || (bdfIsPrefix(line, "ENDCHAR"))) + break; + else + continue; + } + pInBits = line; + inLineLen = strlen((char *) pInBits); + + if (inLineLen & 1) { + bdfError("odd number of characters in hex encoding\n"); + line[inLineLen++] = '0'; + line[inLineLen] = '\0'; + } + inLineLen >>= 1; + i = inLineLen; + if (i > widthHexChars) + i = widthHexChars; + for (; i > 0; i--, pInBits += 2) + picture[nextByte++] = bdfHexByte(pInBits); + + /* pad if line is too short */ + if (inLineLen < widthHexChars) { + for (i = widthHexChars - inLineLen; i > 0; i--) + picture[nextByte++] = 0; + } else { + unsigned char mask; + + mask = 0xff << (8 - (widthBits & 0x7)); + if (mask && picture[nextByte - 1] & ~mask) { + picture[nextByte - 1] &= mask; + } + } + + if (widthBytes > widthHexChars) { + i = widthBytes - widthHexChars; + while (i-- > 0) + picture[nextByte++] = 0; + } + } + + if ((line && (!bdfIsPrefix(line, "ENDCHAR"))) || (height == 0)) + line = bdfGetLine(file, lineBuf, BDFLINELEN); + + if ((!line) || (!bdfIsPrefix(line, "ENDCHAR"))) { + bdfError("missing 'ENDCHAR'\n"); + goto BAILOUT; + } + if (nextByte != height * widthBytes) { + bdfError("bytes != rows * bytes_per_row (%d != %d * %d)\n", + nextByte, height, widthBytes); + goto BAILOUT; + } + if (picture != NULL) { + if (bit == LSBFirst) + BitOrderInvert(picture, nextByte); + if (bit != byte) { + if (scan == 2) + TwoByteSwap(picture, nextByte); + else if (scan == 4) + FourByteSwap(picture, nextByte); + } + } + return (TRUE); +BAILOUT: + if (picture) + xfree(picture); + pCI->bits = NULL; + return (FALSE); +} + +/***====================================================================***/ + +static Bool +bdfSkipBitmap(FontFilePtr file, int height) +{ + unsigned char *line; + int i = 0; + unsigned char lineBuf[BDFLINELEN]; + + do { + line = bdfGetLine(file, lineBuf, BDFLINELEN); + i++; + } while (line && !bdfIsPrefix(line, "ENDCHAR") && i <= height); + + if (i > 1 && line && !bdfIsPrefix(line, "ENDCHAR")) { + bdfError("Error in bitmap, missing 'ENDCHAR'\n"); + return (FALSE); + } + return (TRUE); +} + +/***====================================================================***/ + +static void +bdfFreeFontBits(FontPtr pFont) +{ + BitmapFontPtr bitmapFont; + BitmapExtraPtr bitmapExtra; + int i, nencoding; + + bitmapFont = (BitmapFontPtr) pFont->fontPrivate; + bitmapExtra = (BitmapExtraPtr) bitmapFont->bitmapExtra; + xfree(bitmapFont->ink_metrics); + if(bitmapFont->encoding) { + nencoding = (pFont->info.lastCol - pFont->info.firstCol + 1) * + (pFont->info.lastRow - pFont->info.firstRow + 1); + for(i=0; i<NUM_SEGMENTS(nencoding); i++) + xfree(bitmapFont->encoding[i]); + } + xfree(bitmapFont->encoding); + for (i = 0; i < bitmapFont->num_chars; i++) + xfree(bitmapFont->metrics[i].bits); + xfree(bitmapFont->metrics); + if (bitmapExtra) + { + xfree (bitmapExtra->glyphNames); + xfree (bitmapExtra->sWidths); + xfree (bitmapExtra); + } + xfree(pFont->info.props); + xfree(bitmapFont); +} + + +static Bool +bdfReadCharacters(FontFilePtr file, FontPtr pFont, bdfFileState *pState, + int bit, int byte, int glyph, int scan) +{ + unsigned char *line; + register CharInfoPtr ci; + int i, + ndx, + nchars, + nignored; + unsigned int char_row, char_col; + int numEncodedGlyphs = 0; + CharInfoPtr *bdfEncoding[256]; + BitmapFontPtr bitmapFont; + BitmapExtraPtr bitmapExtra; + CARD32 *bitmapsSizes; + unsigned char lineBuf[BDFLINELEN]; + int nencoding; + + bitmapFont = (BitmapFontPtr) pFont->fontPrivate; + bitmapExtra = (BitmapExtraPtr) bitmapFont->bitmapExtra; + + if (bitmapExtra) { + bitmapsSizes = bitmapExtra->bitmapsSizes; + for (i = 0; i < GLYPHPADOPTIONS; i++) + bitmapsSizes[i] = 0; + } else + bitmapsSizes = NULL; + + bzero(bdfEncoding, sizeof(bdfEncoding)); + bitmapFont->metrics = NULL; + ndx = 0; + + line = bdfGetLine(file, lineBuf, BDFLINELEN); + + if ((!line) || (sscanf((char *) line, "CHARS %d", &nchars) != 1)) { + bdfError("bad 'CHARS' in bdf file\n"); + return (FALSE); + } + if (nchars < 1) { + bdfError("invalid number of CHARS in BDF file\n"); + return (FALSE); + } + if (nchars > INT32_MAX / sizeof(CharInfoRec)) { + bdfError("Couldn't allocate pCI (%d*%d)\n", nchars, + sizeof(CharInfoRec)); + goto BAILOUT; + } + ci = (CharInfoPtr) xalloc(nchars * sizeof(CharInfoRec)); + if (!ci) { + bdfError("Couldn't allocate pCI (%d*%d)\n", nchars, + sizeof(CharInfoRec)); + goto BAILOUT; + } + bzero((char *)ci, nchars * sizeof(CharInfoRec)); + bitmapFont->metrics = ci; + + if (bitmapExtra) { + bitmapExtra->glyphNames = (Atom *) xalloc(nchars * sizeof(Atom)); + if (!bitmapExtra->glyphNames) { + bdfError("Couldn't allocate glyphNames (%d*%d)\n", + nchars, sizeof(Atom)); + goto BAILOUT; + } + } + if (bitmapExtra) { + bitmapExtra->sWidths = (int *) xalloc(nchars * sizeof(int)); + if (!bitmapExtra->sWidths) { + bdfError("Couldn't allocate sWidth (%d *%d)\n", + nchars, sizeof(int)); + return FALSE; + } + } + line = bdfGetLine(file, lineBuf, BDFLINELEN); + pFont->info.firstRow = 256; + pFont->info.lastRow = 0; + pFont->info.firstCol = 256; + pFont->info.lastCol = 0; + nignored = 0; + for (ndx = 0; (ndx < nchars) && (line) && (bdfIsPrefix(line, "STARTCHAR"));) { + int t; + int wx; /* x component of width */ + int wy; /* y component of width */ + int bw; /* bounding-box width */ + int bh; /* bounding-box height */ + int bl; /* bounding-box left */ + int bb; /* bounding-box bottom */ + int enc, + enc2; /* encoding */ + unsigned char *p; /* temp pointer into line */ + char charName[100]; + int ignore; + + if (sscanf((char *) line, "STARTCHAR %s", charName) != 1) { + bdfError("bad character name in BDF file\n"); + goto BAILOUT; /* bottom of function, free and return error */ + } + if (bitmapExtra) + bitmapExtra->glyphNames[ndx] = bdfForceMakeAtom(charName, NULL); + + line = bdfGetLine(file, lineBuf, BDFLINELEN); + if (!line || (t = sscanf((char *) line, "ENCODING %d %d", &enc, &enc2)) < 1) { + bdfError("bad 'ENCODING' in BDF file\n"); + goto BAILOUT; + } + if (enc < -1 || (t == 2 && enc2 < -1)) { + bdfError("bad ENCODING value"); + goto BAILOUT; + } + if (t == 2 && enc == -1) + enc = enc2; + ignore = 0; + if (enc == -1) { + if (!bitmapExtra) { + nignored++; + ignore = 1; + } + } else if (enc > MAXENCODING) { + bdfError("char '%s' has encoding too large (%d)\n", + charName, enc); + } else { + char_row = (enc >> 8) & 0xFF; + char_col = enc & 0xFF; + if (char_row < pFont->info.firstRow) + pFont->info.firstRow = char_row; + if (char_row > pFont->info.lastRow) + pFont->info.lastRow = char_row; + if (char_col < pFont->info.firstCol) + pFont->info.firstCol = char_col; + if (char_col > pFont->info.lastCol) + pFont->info.lastCol = char_col; + if (bdfEncoding[char_row] == (CharInfoPtr *) NULL) { + bdfEncoding[char_row] = + (CharInfoPtr *) xalloc(256 * sizeof(CharInfoPtr)); + if (!bdfEncoding[char_row]) { + bdfError("Couldn't allocate row %d of encoding (%d*%d)\n", + char_row, INDICES, sizeof(CharInfoPtr)); + goto BAILOUT; + } + for (i = 0; i < 256; i++) + bdfEncoding[char_row][i] = (CharInfoPtr) NULL; + } + if (bdfEncoding[char_row] != NULL) { + bdfEncoding[char_row][char_col] = ci; + numEncodedGlyphs++; + } + } + + line = bdfGetLine(file, lineBuf, BDFLINELEN); + if ((!line) || (sscanf((char *) line, "SWIDTH %d %d", &wx, &wy) != 2)) { + bdfError("bad 'SWIDTH'\n"); + goto BAILOUT; + } + if (wy != 0) { + bdfError("SWIDTH y value must be zero\n"); + goto BAILOUT; + } + if (bitmapExtra) + bitmapExtra->sWidths[ndx] = wx; + +/* 5/31/89 (ef) -- we should be able to ditch the character and recover */ +/* from all of these. */ + + line = bdfGetLine(file, lineBuf, BDFLINELEN); + if ((!line) || (sscanf((char *) line, "DWIDTH %d %d", &wx, &wy) != 2)) { + bdfError("bad 'DWIDTH'\n"); + goto BAILOUT; + } + if (wy != 0) { + bdfError("DWIDTH y value must be zero\n"); + goto BAILOUT; + } + line = bdfGetLine(file, lineBuf, BDFLINELEN); + if ((!line) || (sscanf((char *) line, "BBX %d %d %d %d", &bw, &bh, &bl, &bb) != 4)) { + bdfError("bad 'BBX'\n"); + goto BAILOUT; + } + if ((bh < 0) || (bw < 0)) { + bdfError("character '%s' has a negative sized bitmap, %dx%d\n", + charName, bw, bh); + goto BAILOUT; + } + line = bdfGetLine(file, lineBuf, BDFLINELEN); + if ((line) && (bdfIsPrefix(line, "ATTRIBUTES"))) { + for (p = line + strlen("ATTRIBUTES "); + (*p == ' ') || (*p == '\t'); + p++) + /* empty for loop */ ; + ci->metrics.attributes = (bdfHexByte(p) << 8) + bdfHexByte(p + 2); + line = bdfGetLine(file, lineBuf, BDFLINELEN); + } else + ci->metrics.attributes = 0; + + if (!line || !bdfIsPrefix(line, "BITMAP")) { + bdfError("missing 'BITMAP'\n"); + goto BAILOUT; + } + /* collect data for generated properties */ + if ((strlen(charName) == 1)) { + if ((charName[0] >= '0') && (charName[0] <= '9')) { + pState->digitWidths += wx; + pState->digitCount++; + } else if (charName[0] == 'x') { + pState->exHeight = (bh + bb) <= 0 ? bh : bh + bb; + } + } + if (!ignore) { + ci->metrics.leftSideBearing = bl; + ci->metrics.rightSideBearing = bl + bw; + ci->metrics.ascent = bh + bb; + ci->metrics.descent = -bb; + ci->metrics.characterWidth = wx; + ci->bits = NULL; + bdfReadBitmap(ci, file, bit, byte, glyph, scan, bitmapsSizes); + ci++; + ndx++; + } else + bdfSkipBitmap(file, bh); + + line = bdfGetLine(file, lineBuf, BDFLINELEN); /* get STARTCHAR or + * ENDFONT */ + } + + if (ndx + nignored != nchars) { + bdfError("%d too few characters\n", nchars - (ndx + nignored)); + goto BAILOUT; + } + nchars = ndx; + bitmapFont->num_chars = nchars; + if ((line) && (bdfIsPrefix(line, "STARTCHAR"))) { + bdfError("more characters than specified\n"); + goto BAILOUT; + } + if ((!line) || (!bdfIsPrefix(line, "ENDFONT"))) { + bdfError("missing 'ENDFONT'\n"); + goto BAILOUT; + } + if (numEncodedGlyphs == 0) + bdfWarning("No characters with valid encodings\n"); + + nencoding = (pFont->info.lastRow - pFont->info.firstRow + 1) * + (pFont->info.lastCol - pFont->info.firstCol + 1); + bitmapFont->encoding = + (CharInfoPtr **) xcalloc(NUM_SEGMENTS(nencoding), + sizeof(CharInfoPtr*)); + if (!bitmapFont->encoding) { + bdfError("Couldn't allocate ppCI (%d,%d)\n", + NUM_SEGMENTS(nencoding), + sizeof(CharInfoPtr*)); + goto BAILOUT; + } + pFont->info.allExist = TRUE; + i = 0; + for (char_row = pFont->info.firstRow; + char_row <= pFont->info.lastRow; + char_row++) { + if (bdfEncoding[char_row] == (CharInfoPtr *) NULL) { + pFont->info.allExist = FALSE; + i += pFont->info.lastCol - pFont->info.firstCol + 1; + } else { + for (char_col = pFont->info.firstCol; + char_col <= pFont->info.lastCol; + char_col++) { + if (!bdfEncoding[char_row][char_col]) + pFont->info.allExist = FALSE; + else { + if (!bitmapFont->encoding[SEGMENT_MAJOR(i)]) { + bitmapFont->encoding[SEGMENT_MAJOR(i)]= + (CharInfoPtr*)xcalloc(BITMAP_FONT_SEGMENT_SIZE, + sizeof(CharInfoPtr)); + if (!bitmapFont->encoding[SEGMENT_MAJOR(i)]) + goto BAILOUT; + } + ACCESSENCODINGL(bitmapFont->encoding,i) = + bdfEncoding[char_row][char_col]; + } + i++; + } + } + } + for (i = 0; i < 256; i++) + if (bdfEncoding[i]) + xfree(bdfEncoding[i]); + return (TRUE); +BAILOUT: + for (i = 0; i < 256; i++) + if (bdfEncoding[i]) + xfree(bdfEncoding[i]); + /* bdfFreeFontBits will clean up the rest */ + return (FALSE); +} + +/***====================================================================***/ + +static Bool +bdfReadHeader(FontFilePtr file, bdfFileState *pState) +{ + unsigned char *line; + char namebuf[BDFLINELEN]; + unsigned char lineBuf[BDFLINELEN]; + + line = bdfGetLine(file, lineBuf, BDFLINELEN); + if (!line || sscanf((char *) line, "STARTFONT %s", namebuf) != 1 || + !bdfStrEqual(namebuf, "2.1")) { + bdfError("bad 'STARTFONT'\n"); + return (FALSE); + } + line = bdfGetLine(file, lineBuf, BDFLINELEN); + if (!line || sscanf((char *) line, "FONT %[^\n]", pState->fontName) != 1) { + bdfError("bad 'FONT'\n"); + return (FALSE); + } + line = bdfGetLine(file, lineBuf, BDFLINELEN); + if (!line || !bdfIsPrefix(line, "SIZE")) { + bdfError("missing 'SIZE'\n"); + return (FALSE); + } + if (sscanf((char *) line, "SIZE %f%d%d", &pState->pointSize, + &pState->resolution_x, &pState->resolution_y) != 3) { + bdfError("bad 'SIZE'\n"); + return (FALSE); + } + if (pState->pointSize < 1 || + pState->resolution_x < 1 || pState->resolution_y < 1) { + bdfError("SIZE values must be > 0\n"); + return (FALSE); + } + line = bdfGetLine(file, lineBuf, BDFLINELEN); + if (!line || !bdfIsPrefix(line, "FONTBOUNDINGBOX")) { + bdfError("missing 'FONTBOUNDINGBOX'\n"); + return (FALSE); + } + return (TRUE); +} + +/***====================================================================***/ + +static Bool +bdfReadProperties(FontFilePtr file, FontPtr pFont, bdfFileState *pState) +{ + int nProps, props_left, + nextProp; + char *stringProps; + FontPropPtr props; + char namebuf[BDFLINELEN], + secondbuf[BDFLINELEN], + thirdbuf[BDFLINELEN]; + unsigned char *line; + unsigned char lineBuf[BDFLINELEN]; + BitmapFontPtr bitmapFont = (BitmapFontPtr) pFont->fontPrivate; + + line = bdfGetLine(file, lineBuf, BDFLINELEN); + if (!line || !bdfIsPrefix(line, "STARTPROPERTIES")) { + bdfError("missing 'STARTPROPERTIES'\n"); + return (FALSE); + } + if (sscanf((char *) line, "STARTPROPERTIES %d", &nProps) != 1) { + bdfError("bad 'STARTPROPERTIES'\n"); + return (FALSE); + } + pFont->info.isStringProp = NULL; + pFont->info.props = NULL; + pFont->info.nprops = 0; + + stringProps = (char *) xalloc((nProps + BDF_GENPROPS) * sizeof(char)); + pFont->info.isStringProp = stringProps; + if (stringProps == NULL) { + bdfError("Couldn't allocate stringProps (%d*%d)\n", + (nProps + BDF_GENPROPS), sizeof(Bool)); + goto BAILOUT; + } + pFont->info.props = props = (FontPropPtr) xalloc((nProps + BDF_GENPROPS) * + sizeof(FontPropRec)); + if (props == NULL) { + bdfError("Couldn't allocate props (%d*%d)\n", nProps + BDF_GENPROPS, + sizeof(FontPropRec)); + goto BAILOUT; + } + bzero((char *)props, (nProps + BDF_GENPROPS) * sizeof(FontPropRec)); + + nextProp = 0; + props_left = nProps; + while (props_left-- > 0) { + line = bdfGetLine(file, lineBuf, BDFLINELEN); + if (line == NULL || bdfIsPrefix(line, "ENDPROPERTIES")) { + bdfError("\"STARTPROPERTIES %d\" followed by only %d properties\n", + nProps, nProps - props_left - 1); + goto BAILOUT; + } + while (*line && isspace(*line)) + line++; + + switch (sscanf((char *) line, "%s%s%s", namebuf, secondbuf, thirdbuf)) { + default: + bdfError("missing '%s' parameter value\n", namebuf); + goto BAILOUT; + + case 2: + /* + * Possibilites include: valid quoted string with no white space + * valid integer value invalid value + */ + if (secondbuf[0] == '"') { + stringProps[nextProp] = TRUE; + props[nextProp].value = + bdfGetPropertyValue((char *)line + strlen(namebuf) + 1); + if (!props[nextProp].value) + goto BAILOUT; + break; + } else if (bdfIsInteger(secondbuf)) { + stringProps[nextProp] = FALSE; + props[nextProp].value = atoi(secondbuf); + break; + } else { + bdfError("invalid '%s' parameter value\n", namebuf); + goto BAILOUT; + } + + case 3: + /* + * Possibilites include: valid quoted string with some white space + * invalid value (reject even if second string is integer) + */ + if (secondbuf[0] == '"') { + stringProps[nextProp] = TRUE; + props[nextProp].value = + bdfGetPropertyValue((char *)line + strlen(namebuf) + 1); + if (!props[nextProp].value) + goto BAILOUT; + break; + } else { + bdfError("invalid '%s' parameter value\n", namebuf); + goto BAILOUT; + } + } + props[nextProp].name = bdfForceMakeAtom(namebuf, NULL); + if (props[nextProp].name == None) { + bdfError("Empty property name.\n"); + goto BAILOUT; + } + if (!bdfSpecialProperty(pFont, &props[nextProp], + stringProps[nextProp], pState)) + nextProp++; + } + + line = bdfGetLine(file, lineBuf, BDFLINELEN); + if (!line || !bdfIsPrefix(line, "ENDPROPERTIES")) { + bdfError("missing 'ENDPROPERTIES'\n"); + goto BAILOUT; + } + if (!pState->haveFontAscent || !pState->haveFontDescent) { + bdfError("missing 'FONT_ASCENT' or 'FONT_DESCENT' properties\n"); + goto BAILOUT; + } + if (bitmapFont->bitmapExtra) { + bitmapFont->bitmapExtra->info.fontAscent = pFont->info.fontAscent; + bitmapFont->bitmapExtra->info.fontDescent = pFont->info.fontDescent; + } + if (!pState->pointSizeProp) { + props[nextProp].name = bdfForceMakeAtom("POINT_SIZE", NULL); + props[nextProp].value = (INT32) (pState->pointSize * 10.0); + stringProps[nextProp] = FALSE; + pState->pointSizeProp = &props[nextProp]; + nextProp++; + } + if (!pState->fontProp) { + props[nextProp].name = bdfForceMakeAtom("FONT", NULL); + props[nextProp].value = (INT32) bdfForceMakeAtom(pState->fontName, NULL); + stringProps[nextProp] = TRUE; + pState->fontProp = &props[nextProp]; + nextProp++; + } + if (!pState->weightProp) { + props[nextProp].name = bdfForceMakeAtom("WEIGHT", NULL); + props[nextProp].value = -1; /* computed later */ + stringProps[nextProp] = FALSE; + pState->weightProp = &props[nextProp]; + nextProp++; + } + if (!pState->resolutionProp && + pState->resolution_x == pState->resolution_y) { + props[nextProp].name = bdfForceMakeAtom("RESOLUTION", NULL); + props[nextProp].value = (INT32) ((pState->resolution_x * 100.0) / 72.27); + stringProps[nextProp] = FALSE; + pState->resolutionProp = &props[nextProp]; + nextProp++; + } + if (!pState->resolutionXProp) { + props[nextProp].name = bdfForceMakeAtom("RESOLUTION_X", NULL); + props[nextProp].value = (INT32) pState->resolution_x; + stringProps[nextProp] = FALSE; + pState->resolutionProp = &props[nextProp]; + nextProp++; + } + if (!pState->resolutionYProp) { + props[nextProp].name = bdfForceMakeAtom("RESOLUTION_Y", NULL); + props[nextProp].value = (INT32) pState->resolution_y; + stringProps[nextProp] = FALSE; + pState->resolutionProp = &props[nextProp]; + nextProp++; + } + if (!pState->xHeightProp) { + props[nextProp].name = bdfForceMakeAtom("X_HEIGHT", NULL); + props[nextProp].value = -1; /* computed later */ + stringProps[nextProp] = FALSE; + pState->xHeightProp = &props[nextProp]; + nextProp++; + } + if (!pState->quadWidthProp) { + props[nextProp].name = bdfForceMakeAtom("QUAD_WIDTH", NULL); + props[nextProp].value = -1; /* computed later */ + stringProps[nextProp] = FALSE; + pState->quadWidthProp = &props[nextProp]; + nextProp++; + } + pFont->info.nprops = nextProp; + return (TRUE); +BAILOUT: + if (pFont->info.isStringProp) { + xfree(pFont->info.isStringProp); + pFont->info.isStringProp = NULL; + } + if (pFont->info.props) { + xfree(pFont->info.props); + pFont->info.props = NULL; + } + while (line && bdfIsPrefix(line, "ENDPROPERTIES")) + line = bdfGetLine(file, lineBuf, BDFLINELEN); + return (FALSE); +} + +/***====================================================================***/ + +static void +bdfUnloadFont(FontPtr pFont) +{ + bdfFreeFontBits (pFont); + DestroyFontRec(pFont); +} + +int +bdfReadFont(FontPtr pFont, FontFilePtr file, + int bit, int byte, int glyph, int scan) +{ + bdfFileState state; + xCharInfo *min, + *max; + BitmapFontPtr bitmapFont; + + pFont->fontPrivate = 0; + + bzero(&state, sizeof(bdfFileState)); + bdfFileLineNum = 0; + + if (!bdfReadHeader(file, &state)) + goto BAILOUT; + + bitmapFont = (BitmapFontPtr) xalloc(sizeof(BitmapFontRec)); + if (!bitmapFont) { + bdfError("Couldn't allocate bitmapFontRec (%d)\n", sizeof(BitmapFontRec)); + goto BAILOUT; + } + bzero((char *)bitmapFont, sizeof(BitmapFontRec)); + + pFont->fontPrivate = (pointer) bitmapFont; + bitmapFont->metrics = 0; + bitmapFont->ink_metrics = 0; + bitmapFont->bitmaps = 0; + bitmapFont->encoding = 0; + bitmapFont->pDefault = NULL; + + bitmapFont->bitmapExtra = (BitmapExtraPtr) xalloc(sizeof(BitmapExtraRec)); + if (!bitmapFont->bitmapExtra) { + bdfError("Couldn't allocate bitmapExtra (%d)\n", sizeof(BitmapExtraRec)); + goto BAILOUT; + } + bzero((char *)bitmapFont->bitmapExtra, sizeof(BitmapExtraRec)); + + bitmapFont->bitmapExtra->glyphNames = 0; + bitmapFont->bitmapExtra->sWidths = 0; + + if (!bdfReadProperties(file, pFont, &state)) + goto BAILOUT; + + if (!bdfReadCharacters(file, pFont, &state, bit, byte, glyph, scan)) + goto BAILOUT; + + if (state.haveDefaultCh) { + unsigned int r, c, cols; + + r = pFont->info.defaultCh >> 8; + c = pFont->info.defaultCh & 0xFF; + if (pFont->info.firstRow <= r && r <= pFont->info.lastRow && + pFont->info.firstCol <= c && c <= pFont->info.lastCol) { + cols = pFont->info.lastCol - pFont->info.firstCol + 1; + r = r - pFont->info.firstRow; + c = c - pFont->info.firstCol; + bitmapFont->pDefault = ACCESSENCODING(bitmapFont->encoding, + r * cols + c); + } + } + pFont->bit = bit; + pFont->byte = byte; + pFont->glyph = glyph; + pFont->scan = scan; + pFont->info.anamorphic = FALSE; + pFont->info.cachable = TRUE; + bitmapComputeFontBounds(pFont); + if (FontCouldBeTerminal(&pFont->info)) { + bdfPadToTerminal(pFont); + bitmapComputeFontBounds(pFont); + } + FontComputeInfoAccelerators(&pFont->info); + if (bitmapFont->bitmapExtra) + FontComputeInfoAccelerators(&bitmapFont->bitmapExtra->info); + if (pFont->info.constantMetrics) { + if (!bitmapAddInkMetrics(pFont)) { + bdfError("Failed to add bitmap ink metrics\n"); + goto BAILOUT; + } + } + if (bitmapFont->bitmapExtra) + bitmapFont->bitmapExtra->info.inkMetrics = pFont->info.inkMetrics; + + bitmapComputeFontInkBounds(pFont); +/* ComputeFontAccelerators (pFont); */ + + /* generate properties */ + min = &pFont->info.ink_minbounds; + max = &pFont->info.ink_maxbounds; + if (state.xHeightProp && (state.xHeightProp->value == -1)) + state.xHeightProp->value = state.exHeight ? + state.exHeight : min->ascent; + + if (state.quadWidthProp && (state.quadWidthProp->value == -1)) + state.quadWidthProp->value = state.digitCount ? + (INT32) (state.digitWidths / state.digitCount) : + (min->characterWidth + max->characterWidth) / 2; + + if (state.weightProp && (state.weightProp->value == -1)) + state.weightProp->value = bitmapComputeWeight(pFont); + + pFont->get_glyphs = bitmapGetGlyphs; + pFont->get_metrics = bitmapGetMetrics; + pFont->unload_font = bdfUnloadFont; + pFont->unload_glyphs = NULL; + return Successful; +BAILOUT: + if (pFont->fontPrivate) + bdfFreeFontBits (pFont); + return AllocError; +} + +int +bdfReadFontInfo(FontInfoPtr pFontInfo, FontFilePtr file) +{ + FontRec font; + int ret; + + bzero(&font, sizeof (FontRec)); + + ret = bdfReadFont(&font, file, MSBFirst, LSBFirst, 1, 1); + if (ret == Successful) { + *pFontInfo = font.info; + font.info.props = 0; + font.info.isStringProp = 0; + font.info.nprops = 0; + bdfFreeFontBits (&font); + } + return ret; +} + +static Bool +bdfPadToTerminal(FontPtr pFont) +{ + BitmapFontPtr bitmapFont; + BitmapExtraPtr bitmapExtra; + int i; + int new_size; + CharInfoRec new; + int w, + h; + + bitmapFont = (BitmapFontPtr) pFont->fontPrivate; + + bzero(&new, sizeof(CharInfoRec)); + new.metrics.ascent = pFont->info.fontAscent; + new.metrics.descent = pFont->info.fontDescent; + new.metrics.leftSideBearing = 0; + new.metrics.rightSideBearing = pFont->info.minbounds.characterWidth; + new.metrics.characterWidth = new.metrics.rightSideBearing; + new_size = BYTES_FOR_GLYPH(&new, pFont->glyph); + + for (i = 0; i < bitmapFont->num_chars; i++) { + new.bits = (char *) xalloc(new_size); + if (!new.bits) { + bdfError("Couldn't allocate bits (%d)\n", new_size); + return FALSE; + } + FontCharReshape(pFont, &bitmapFont->metrics[i], &new); + new.metrics.attributes = bitmapFont->metrics[i].metrics.attributes; + xfree(bitmapFont->metrics[i].bits); + bitmapFont->metrics[i] = new; + } + bitmapExtra = bitmapFont->bitmapExtra; + if (bitmapExtra) { + w = GLYPHWIDTHPIXELS(&new); + h = GLYPHHEIGHTPIXELS(&new); + for (i = 0; i < GLYPHPADOPTIONS; i++) + bitmapExtra->bitmapsSizes[i] = bitmapFont->num_chars * + (BYTES_PER_ROW(w, 1 << i) * h); + } + return TRUE; +} diff --git a/nx-X11/lib/font/bitmap/bdfutils.c b/nx-X11/lib/font/bitmap/bdfutils.c new file mode 100644 index 000000000..a0c5ae949 --- /dev/null +++ b/nx-X11/lib/font/bitmap/bdfutils.c @@ -0,0 +1,340 @@ +/* $Xorg: bdfutils.c,v 1.5 2001/02/09 02:04:02 xorgcvs Exp $ */ +/************************************************************************ +Copyright 1989 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +************************************************************************/ + +/* + +Copyright 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + +*/ +/* $XFree86: xc/lib/font/bitmap/bdfutils.c,v 1.10 2001/12/14 19:56:45 dawes Exp $ */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#ifndef FONTMODULE +#include <ctype.h> +#include <stdio.h> +#include <stdarg.h> +#endif + +#include <X11/fonts/fntfilst.h> +#include <X11/fonts/fontstruct.h> +/* use bitmap structure */ +#include <X11/fonts/bitmap.h> +#include <X11/fonts/bdfint.h> + +int bdfFileLineNum; + +/***====================================================================***/ + +void +bdfError(char* message, ...) +{ + va_list args; + + va_start (args, message); + fprintf(stderr, "BDF Error on line %d: ", bdfFileLineNum); + vfprintf(stderr, message, args); + va_end (args); +} + +/***====================================================================***/ + +void +bdfWarning(char *message, ...) +{ + va_list args; + + va_start (args, message); + fprintf(stderr, "BDF Warning on line %d: ", bdfFileLineNum); + vfprintf(stderr, message, args); + va_end (args); +} + +/* + * read the next (non-comment) line and keep a count for error messages. + * Returns buf, or NULL if EOF. + */ + +unsigned char * +bdfGetLine(FontFilePtr file, unsigned char *buf, int len) +{ + int c; + unsigned char *b; + + for (;;) { + b = buf; + while ((c = FontFileGetc(file)) != FontFileEOF) { + if (c == '\r') + continue; + if (c == '\n') { + bdfFileLineNum++; + break; + } + if (b - buf >= (len - 1)) + break; + *b++ = c; + } + *b = '\0'; + if (c == FontFileEOF) + return NULL; + if (b != buf && !bdfIsPrefix(buf, "COMMENT")) + break; + } + return buf; +} + +/***====================================================================***/ + +Atom +bdfForceMakeAtom(char *str, int *size) +{ + register int len = strlen(str); + Atom the_atom; + + if (size != NULL) + *size += len + 1; + the_atom = MakeAtom(str, len, TRUE); + if (the_atom == None) + bdfError("Atom allocation failed\n"); + return the_atom; +} + +/***====================================================================***/ + +/* + * Handle quoted strings. + */ + +Atom +bdfGetPropertyValue(char *s) +{ + register char *p, + *pp; + char *orig_s = s; + Atom atom; + + /* strip leading white space */ + while (*s && (*s == ' ' || *s == '\t')) + s++; + if (*s == 0) { + return bdfForceMakeAtom(s, NULL); + } + if (*s != '"') { + pp = s; + /* no white space in value */ + for (pp = s; *pp; pp++) + if (*pp == ' ' || *pp == '\t' || *pp == '\015' || *pp == '\n') { + *pp = 0; + break; + } + return bdfForceMakeAtom(s, NULL); + } + /* quoted string: strip outer quotes and undouble inner quotes */ + s++; + pp = p = (char *) xalloc((unsigned) strlen(s) + 1); + if (pp == NULL) { + bdfError("Couldn't allocate property value string (%d)\n", strlen(s) + 1); + return None; + } + while (*s) { + if (*s == '"') { + if (*(s + 1) != '"') { + *p++ = 0; + atom = bdfForceMakeAtom(pp, NULL); + xfree(pp); + return atom; + } else { + s++; + } + } + *p++ = *s++; + } + xfree (pp); + bdfError("unterminated quoted string property: %s\n", (pointer) orig_s); + return None; +} + +/***====================================================================***/ + +/* + * return TRUE if string is a valid integer + */ +int +bdfIsInteger(char *str) +{ + char c; + + c = *str++; + if (!(isdigit(c) || c == '-' || c == '+')) + return (FALSE); + + while ((c = *str++)) + if (!isdigit(c)) + return (FALSE); + + return (TRUE); +} + +/***====================================================================***/ + +/* + * make a byte from the first two hex characters in glyph picture + */ + +unsigned char +bdfHexByte(unsigned char *s) +{ + unsigned char b = 0; + register char c; + int i; + + for (i = 2; i; i--) { + c = *s++; + if ((c >= '0') && (c <= '9')) + b = (b << 4) + (c - '0'); + else if ((c >= 'A') && (c <= 'F')) + b = (b << 4) + 10 + (c - 'A'); + else if ((c >= 'a') && (c <= 'f')) + b = (b << 4) + 10 + (c - 'a'); + else + bdfError("bad hex char '%c'", c); + } + return b; +} + +/***====================================================================***/ + +/* + * check for known special property values + */ + +static char *SpecialAtoms[] = { + "FONT_ASCENT", +#define BDF_FONT_ASCENT 0 + "FONT_DESCENT", +#define BDF_FONT_DESCENT 1 + "DEFAULT_CHAR", +#define BDF_DEFAULT_CHAR 2 + "POINT_SIZE", +#define BDF_POINT_SIZE 3 + "RESOLUTION", +#define BDF_RESOLUTION 4 + "X_HEIGHT", +#define BDF_X_HEIGHT 5 + "WEIGHT", +#define BDF_WEIGHT 6 + "QUAD_WIDTH", +#define BDF_QUAD_WIDTH 7 + "FONT", +#define BDF_FONT 8 + "RESOLUTION_X", +#define BDF_RESOLUTION_X 9 + "RESOLUTION_Y", +#define BDF_RESOLUTION_Y 10 + 0, +}; + +Bool +bdfSpecialProperty(FontPtr pFont, FontPropPtr prop, + char isString, bdfFileState *bdfState) +{ + char **special; + char *name; + + name = NameForAtom(prop->name); + for (special = SpecialAtoms; *special; special++) + if (!strcmp(name, *special)) + break; + + switch (special - SpecialAtoms) { + case BDF_FONT_ASCENT: + if (!isString) { + pFont->info.fontAscent = prop->value; + bdfState->haveFontAscent = TRUE; + } + return TRUE; + case BDF_FONT_DESCENT: + if (!isString) { + pFont->info.fontDescent = prop->value; + bdfState->haveFontDescent = TRUE; + } + return TRUE; + case BDF_DEFAULT_CHAR: + if (!isString) { + pFont->info.defaultCh = prop->value; + bdfState->haveDefaultCh = TRUE; + } + return TRUE; + case BDF_POINT_SIZE: + bdfState->pointSizeProp = prop; + return FALSE; + case BDF_RESOLUTION: + bdfState->resolutionProp = prop; + return FALSE; + case BDF_X_HEIGHT: + bdfState->xHeightProp = prop; + return FALSE; + case BDF_WEIGHT: + bdfState->weightProp = prop; + return FALSE; + case BDF_QUAD_WIDTH: + bdfState->quadWidthProp = prop; + return FALSE; + case BDF_FONT: + bdfState->fontProp = prop; + return FALSE; + case BDF_RESOLUTION_X: + bdfState->resolutionXProp = prop; + return FALSE; + case BDF_RESOLUTION_Y: + bdfState->resolutionYProp = prop; + return FALSE; + default: + return FALSE; + } +} diff --git a/nx-X11/lib/font/bitmap/bitmap.c b/nx-X11/lib/font/bitmap/bitmap.c new file mode 100644 index 000000000..d238f4d30 --- /dev/null +++ b/nx-X11/lib/font/bitmap/bitmap.c @@ -0,0 +1,160 @@ +/* $Xorg: bitmap.c,v 1.4 2001/02/09 02:04:02 xorgcvs Exp $ */ + +/* + +Copyright 1991, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ +/* $XFree86: xc/lib/font/bitmap/bitmap.c,v 1.6 2001/01/17 19:43:27 dawes Exp $ */ + +/* + * Author: Keith Packard, MIT X Consortium + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <X11/fonts/fntfilst.h> +#include <X11/fonts/bitmap.h> + +int +bitmapGetGlyphs(FontPtr pFont, unsigned long count, unsigned char *chars, + FontEncoding charEncoding, + unsigned long *glyphCount, /* RETURN */ + CharInfoPtr *glyphs) /* RETURN */ +{ + BitmapFontPtr bitmapFont; + unsigned int firstCol; + register unsigned int numCols; + unsigned int firstRow; + unsigned int numRows; + CharInfoPtr *glyphsBase; + register unsigned int c; + register CharInfoPtr pci; + unsigned int r; + CharInfoPtr **encoding; + CharInfoPtr pDefault; + + bitmapFont = (BitmapFontPtr) pFont->fontPrivate; + encoding = bitmapFont->encoding; + pDefault = bitmapFont->pDefault; + firstCol = pFont->info.firstCol; + numCols = pFont->info.lastCol - firstCol + 1; + glyphsBase = glyphs; + switch (charEncoding) { + + case Linear8Bit: + case TwoD8Bit: + if (pFont->info.firstRow > 0) + break; + if (pFont->info.allExist && pDefault) { + while (count--) { + c = (*chars++) - firstCol; + if (c < numCols) + *glyphs++ = ACCESSENCODING(encoding,c); + else + *glyphs++ = pDefault; + } + } else { + while (count--) { + c = (*chars++) - firstCol; + if (c < numCols && (pci = ACCESSENCODING(encoding,c))) + *glyphs++ = pci; + else if (pDefault) + *glyphs++ = pDefault; + } + } + break; + case Linear16Bit: + if (pFont->info.allExist && pDefault) { + while (count--) { + c = *chars++ << 8; + c = (c | *chars++) - firstCol; + if (c < numCols) + *glyphs++ = ACCESSENCODING(encoding,c); + else + *glyphs++ = pDefault; + } + } else { + while (count--) { + c = *chars++ << 8; + c = (c | *chars++) - firstCol; + if (c < numCols && (pci = ACCESSENCODING(encoding,c))) + *glyphs++ = pci; + else if (pDefault) + *glyphs++ = pDefault; + } + } + break; + + case TwoD16Bit: + firstRow = pFont->info.firstRow; + numRows = pFont->info.lastRow - firstRow + 1; + while (count--) { + r = (*chars++) - firstRow; + c = (*chars++) - firstCol; + if (r < numRows && c < numCols && + (pci = ACCESSENCODING(encoding, r * numCols + c))) + *glyphs++ = pci; + else if (pDefault) + *glyphs++ = pDefault; + } + break; + } + *glyphCount = glyphs - glyphsBase; + return Successful; +} + +static CharInfoRec nonExistantChar; + +int +bitmapGetMetrics(FontPtr pFont, unsigned long count, unsigned char *chars, + FontEncoding charEncoding, + unsigned long *glyphCount, /* RETURN */ + xCharInfo **glyphs) /* RETURN */ +{ + int ret; + xCharInfo *ink_metrics; + CharInfoPtr metrics; + BitmapFontPtr bitmapFont; + CharInfoPtr oldDefault; + int i; + + bitmapFont = (BitmapFontPtr) pFont->fontPrivate; + oldDefault = bitmapFont->pDefault; + bitmapFont->pDefault = &nonExistantChar; + ret = bitmapGetGlyphs(pFont, count, chars, charEncoding, glyphCount, (CharInfoPtr *) glyphs); + if (ret == Successful) { + if (bitmapFont->ink_metrics) { + metrics = bitmapFont->metrics; + ink_metrics = bitmapFont->ink_metrics; + for (i = 0; i < *glyphCount; i++) { + if (glyphs[i] != (xCharInfo *) & nonExistantChar) + glyphs[i] = ink_metrics + (((CharInfoPtr) glyphs[i]) - metrics); + } + } + } + bitmapFont->pDefault = oldDefault; + return ret; +} diff --git a/nx-X11/lib/font/bitmap/bitmapfunc.c b/nx-X11/lib/font/bitmap/bitmapfunc.c new file mode 100644 index 000000000..e6187e5ee --- /dev/null +++ b/nx-X11/lib/font/bitmap/bitmapfunc.c @@ -0,0 +1,240 @@ +/* $Xorg: bitmapfunc.c,v 1.5 2001/02/09 02:04:02 xorgcvs Exp $ */ + +/* + +Copyright 1991, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ + +/* $XFree86: xc/lib/font/bitmap/bitmapfunc.c,v 3.17 2002/09/19 13:21:58 tsi Exp $ */ + +/* + * Author: Keith Packard, MIT X Consortium + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +/* + * Translate monolithic #defines to modular definitions + */ + +#ifdef PCFFORMAT +#define XFONT_PCFFORMAT 1 +#endif + +#ifdef SNFFORMAT +#define XFONT_SNFFORMAT 1 +#endif + +#ifdef BDFFORMAT +#define XFONT_BDFFORMAT 1 +#endif + +#include <X11/fonts/fntfilst.h> +#include <X11/fonts/bitmap.h> +#include <X11/fonts/fontutil.h> +#include <X11/fonts/bdfint.h> +#include <X11/fonts/pcf.h> +#include "snfstr.h" + +typedef struct _BitmapFileFunctions { + int (*ReadFont) (FontPtr /* pFont */, FontFilePtr /* file */, + int /* bit */, int /* byte */, + int /* glyph */, int /* scan */); + int (*ReadInfo) ( FontInfoPtr /* pFontInfo */, + FontFilePtr /* file */ ); +} BitmapFileFunctionsRec, *BitmapFileFunctionsPtr; + + +/* + * the readers[] and renderers[] arrays must be in the same order, + * and also in the same order as scale[] and find_scale[] in bitscale.c + * + */ +static BitmapFileFunctionsRec readers[] = { +#if XFONT_PCFFORMAT + { pcfReadFont, pcfReadFontInfo} , + { pcfReadFont, pcfReadFontInfo} , +#ifdef X_GZIP_FONT_COMPRESSION + { pcfReadFont, pcfReadFontInfo} , +#endif +#endif +#if XFONT_SNFFORMAT + { snfReadFont, snfReadFontInfo}, + { snfReadFont, snfReadFontInfo}, +#ifdef X_GZIP_FONT_COMPRESSION + { snfReadFont, snfReadFontInfo} , +#endif +#endif +#if XFONT_BDFFORMAT + { bdfReadFont, bdfReadFontInfo} , + { bdfReadFont, bdfReadFontInfo} , +#ifdef X_GZIP_FONT_COMPRESSION + { bdfReadFont, bdfReadFontInfo} , +#endif +#endif +#if XFONT_PCFFORMAT + { pmfReadFont, pcfReadFontInfo} , +#endif +}; + + +#define CAPABILITIES (CAP_MATRIX | CAP_CHARSUBSETTING) + +static FontRendererRec renderers[] = { +#if XFONT_PCFFORMAT + { ".pcf", 4, BitmapOpenBitmap, BitmapOpenScalable, + BitmapGetInfoBitmap, BitmapGetInfoScalable, 0, + CAPABILITIES }, + { ".pcf.Z", 6, BitmapOpenBitmap, BitmapOpenScalable, + BitmapGetInfoBitmap, BitmapGetInfoScalable, 0, + CAPABILITIES }, +#ifdef X_GZIP_FONT_COMPRESSION + { ".pcf.gz", 7, + BitmapOpenBitmap, BitmapOpenScalable, + BitmapGetInfoBitmap, BitmapGetInfoScalable, 0, + CAPABILITIES }, +#endif +#endif +#if XFONT_SNFFORMAT + { ".snf", 4, BitmapOpenBitmap, BitmapOpenScalable, + BitmapGetInfoBitmap, BitmapGetInfoScalable, 0, + CAPABILITIES }, + { ".snf.Z", 6, BitmapOpenBitmap, BitmapOpenScalable, + BitmapGetInfoBitmap, BitmapGetInfoScalable, 0, + CAPABILITIES }, +#ifdef X_GZIP_FONT_COMPRESSION + { ".snf.gz", 7, BitmapOpenBitmap, BitmapOpenScalable, + BitmapGetInfoBitmap, BitmapGetInfoScalable, 0, + CAPABILITIES }, +#endif +#endif +#if XFONT_BDFFORMAT + { ".bdf", 4, BitmapOpenBitmap, BitmapOpenScalable, + BitmapGetInfoBitmap, BitmapGetInfoScalable, 0, + CAPABILITIES }, + { ".bdf.Z", 6, BitmapOpenBitmap, BitmapOpenScalable, + BitmapGetInfoBitmap, BitmapGetInfoScalable, 0, + CAPABILITIES }, +#ifdef X_GZIP_FONT_COMPRESSION + { ".bdf.gz", 7, BitmapOpenBitmap, BitmapOpenScalable, + BitmapGetInfoBitmap, BitmapGetInfoScalable, 0, + CAPABILITIES }, +#endif +#endif +#if XFONT_PCFFORMAT + { ".pmf", 4, BitmapOpenBitmap, BitmapOpenScalable, + BitmapGetInfoBitmap, BitmapGetInfoScalable, 0, + CAPABILITIES } +#endif +}; + +int +BitmapOpenBitmap (FontPathElementPtr fpe, FontPtr *ppFont, int flags, + FontEntryPtr entry, char *fileName, + fsBitmapFormat format, fsBitmapFormatMask fmask, + FontPtr non_cachable_font) /* We don't do licensing */ +{ + FontFilePtr file; + FontPtr pFont; + int i; + int ret; + int bit, + byte, + glyph, + scan, + image; + + i = BitmapGetRenderIndex(entry->u.bitmap.renderer); + file = FontFileOpen (fileName); + if (!file) + return BadFontName; + if (!(pFont = CreateFontRec())) { + fprintf(stderr, "Error: Couldn't allocate pFont (%ld)\n", + (unsigned long)sizeof(FontRec)); + FontFileClose (file); + return AllocError; + } + /* set up default values */ + FontDefaultFormat(&bit, &byte, &glyph, &scan); + /* get any changes made from above */ + ret = CheckFSFormat(format, fmask, &bit, &byte, &scan, &glyph, &image); + + /* Fill in font record. Data format filled in by reader. */ + pFont->refcnt = 0; + + ret = (*readers[i].ReadFont) (pFont, file, bit, byte, glyph, scan); + + FontFileClose (file); + if (ret != Successful) { + xfree(pFont); + } else { + *ppFont = pFont; + } + return ret; +} + +int +BitmapGetInfoBitmap (FontPathElementPtr fpe, FontInfoPtr pFontInfo, + FontEntryPtr entry, char *fileName) +{ + FontFilePtr file; + int i; + int ret; + FontRendererPtr renderer; + + renderer = FontFileMatchRenderer (fileName); + if (!renderer) + return BadFontName; + i = BitmapGetRenderIndex(renderer); + file = FontFileOpen (fileName); + if (!file) + return BadFontName; + ret = (*readers[i].ReadInfo) (pFontInfo, file); + FontFileClose (file); + return ret; +} + +#define numRenderers (sizeof renderers / sizeof renderers[0]) + +void +BitmapRegisterFontFileFunctions (void) +{ + int i; + + for (i = 0; i < numRenderers; i++) + FontFileRegisterRenderer (&renderers[i]); +} + +/* + * compute offset into renderers array - used to find the font reader, + * the font info reader, and the bitmap scaling routine. All users + * of this routine must be kept in step with the renderer array. + */ +int +BitmapGetRenderIndex(FontRendererPtr renderer) +{ + return renderer - renderers; +} diff --git a/nx-X11/lib/font/bitmap/bitmaputil.c b/nx-X11/lib/font/bitmap/bitmaputil.c new file mode 100644 index 000000000..3487f7f92 --- /dev/null +++ b/nx-X11/lib/font/bitmap/bitmaputil.c @@ -0,0 +1,232 @@ +/* $Xorg: bitmaputil.c,v 1.5 2001/02/09 02:04:02 xorgcvs Exp $ */ + +/* + +Copyright 1990, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + +*/ +/* $XFree86: xc/lib/font/bitmap/bitmaputil.c,v 1.10 2002/09/24 20:52:48 tsi Exp $ */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <X11/fonts/fntfilst.h> +#include <X11/fonts/bitmap.h> +#include <X11/fonts/bdfint.h> + +#ifndef MAXSHORT +#define MAXSHORT 32767 +#endif + +#ifndef MINSHORT +#define MINSHORT -32768 +#endif + +static xCharInfo initMinMetrics = { +MAXSHORT, MAXSHORT, MAXSHORT, MAXSHORT, MAXSHORT, 0xFFFF}; +static xCharInfo initMaxMetrics = { +MINSHORT, MINSHORT, MINSHORT, MINSHORT, MINSHORT, 0x0000}; + +#define MINMAX(field,ci) \ + if (minbounds->field > (ci)->field) \ + minbounds->field = (ci)->field; \ + if (maxbounds->field < (ci)->field) \ + maxbounds->field = (ci)->field; + +#define COMPUTE_MINMAX(ci) \ + if ((ci)->ascent || (ci)->descent || \ + (ci)->leftSideBearing || (ci)->rightSideBearing || \ + (ci)->characterWidth) \ + { \ + MINMAX(ascent, (ci)); \ + MINMAX(descent, (ci)); \ + MINMAX(leftSideBearing, (ci)); \ + MINMAX(rightSideBearing, (ci)); \ + MINMAX(characterWidth, (ci)); \ + } + +void +bitmapComputeFontBounds(FontPtr pFont) +{ + BitmapFontPtr bitmapFont = (BitmapFontPtr) pFont->fontPrivate; + int nchars; + int r, + c; + CharInfoPtr ci; + int maxOverlap; + int overlap; + xCharInfo *minbounds, + *maxbounds; + int i; + int numneg = 0, numpos = 0; + + if (bitmapFont->bitmapExtra) { + minbounds = &bitmapFont->bitmapExtra->info.minbounds; + maxbounds = &bitmapFont->bitmapExtra->info.maxbounds; + } else { + minbounds = &pFont->info.minbounds; + maxbounds = &pFont->info.maxbounds; + } + *minbounds = initMinMetrics; + *maxbounds = initMaxMetrics; + maxOverlap = MINSHORT; + nchars = bitmapFont->num_chars; + for (i = 0, ci = bitmapFont->metrics; i < nchars; i++, ci++) { + COMPUTE_MINMAX(&ci->metrics); + if (ci->metrics.characterWidth < 0) + numneg++; + else + numpos++; + minbounds->attributes &= ci->metrics.attributes; + maxbounds->attributes |= ci->metrics.attributes; + overlap = ci->metrics.rightSideBearing - ci->metrics.characterWidth; + if (maxOverlap < overlap) + maxOverlap = overlap; + } + if (bitmapFont->bitmapExtra) { + if (numneg > numpos) + bitmapFont->bitmapExtra->info.drawDirection = RightToLeft; + else + bitmapFont->bitmapExtra->info.drawDirection = LeftToRight; + bitmapFont->bitmapExtra->info.maxOverlap = maxOverlap; + minbounds = &pFont->info.minbounds; + maxbounds = &pFont->info.maxbounds; + *minbounds = initMinMetrics; + *maxbounds = initMaxMetrics; + i = 0; + maxOverlap = MINSHORT; + for (r = pFont->info.firstRow; r <= pFont->info.lastRow; r++) { + for (c = pFont->info.firstCol; c <= pFont->info.lastCol; c++) { + ci = ACCESSENCODING(bitmapFont->encoding, i); + if (ci) { + COMPUTE_MINMAX(&ci->metrics); + if (ci->metrics.characterWidth < 0) + numneg++; + else + numpos++; + minbounds->attributes &= ci->metrics.attributes; + maxbounds->attributes |= ci->metrics.attributes; + overlap = ci->metrics.rightSideBearing - + ci->metrics.characterWidth; + if (maxOverlap < overlap) + maxOverlap = overlap; + } + i++; + } + } + } + if (numneg > numpos) + pFont->info.drawDirection = RightToLeft; + else + pFont->info.drawDirection = LeftToRight; + pFont->info.maxOverlap = maxOverlap; +} + +void +bitmapComputeFontInkBounds(FontPtr pFont) +{ + BitmapFontPtr bitmapFont = (BitmapFontPtr) pFont->fontPrivate; + int nchars; + int r, + c; + CharInfoPtr cit; + xCharInfo *ci; + int offset; + xCharInfo *minbounds, + *maxbounds; + int i; + + if (!bitmapFont->ink_metrics) { + if (bitmapFont->bitmapExtra) { + bitmapFont->bitmapExtra->info.ink_minbounds = bitmapFont->bitmapExtra->info.minbounds; + bitmapFont->bitmapExtra->info.ink_maxbounds = bitmapFont->bitmapExtra->info.maxbounds; + } + pFont->info.ink_minbounds = pFont->info.minbounds; + pFont->info.ink_maxbounds = pFont->info.maxbounds; + } else { + if (bitmapFont->bitmapExtra) { + minbounds = &bitmapFont->bitmapExtra->info.ink_minbounds; + maxbounds = &bitmapFont->bitmapExtra->info.ink_maxbounds; + } else { + minbounds = &pFont->info.ink_minbounds; + maxbounds = &pFont->info.ink_maxbounds; + } + *minbounds = initMinMetrics; + *maxbounds = initMaxMetrics; + nchars = bitmapFont->num_chars; + for (i = 0, ci = bitmapFont->ink_metrics; i < nchars; i++, ci++) { + COMPUTE_MINMAX(ci); + minbounds->attributes &= ci->attributes; + maxbounds->attributes |= ci->attributes; + } + if (bitmapFont->bitmapExtra) { + minbounds = &pFont->info.ink_minbounds; + maxbounds = &pFont->info.ink_maxbounds; + *minbounds = initMinMetrics; + *maxbounds = initMaxMetrics; + i=0; + for (r = pFont->info.firstRow; r <= pFont->info.lastRow; r++) { + for (c = pFont->info.firstCol; c <= pFont->info.lastCol; c++) { + cit = ACCESSENCODING(bitmapFont->encoding, i); + if (cit) { + offset = cit - bitmapFont->metrics; + ci = &bitmapFont->ink_metrics[offset]; + COMPUTE_MINMAX(ci); + minbounds->attributes &= ci->attributes; + maxbounds->attributes |= ci->attributes; + } + i++; + } + } + } + } +} + +Bool +bitmapAddInkMetrics(FontPtr pFont) +{ + BitmapFontPtr bitmapFont; + int i; + + bitmapFont = (BitmapFontPtr) pFont->fontPrivate; + bitmapFont->ink_metrics = (xCharInfo *) xalloc(bitmapFont->num_chars * sizeof(xCharInfo)); + if (!bitmapFont->ink_metrics) { + fprintf(stderr, "Error: Couldn't allocate ink_metrics (%d*%ld)\n", + bitmapFont->num_chars, (unsigned long)sizeof(xCharInfo)); + return FALSE; + } + for (i = 0; i < bitmapFont->num_chars; i++) + FontCharInkMetrics(pFont, &bitmapFont->metrics[i], &bitmapFont->ink_metrics[i]); + pFont->info.inkMetrics = TRUE; + return TRUE; +} + +/* ARGSUSED */ +int +bitmapComputeWeight(FontPtr pFont) +{ + return 10; +} diff --git a/nx-X11/lib/font/bitmap/bitscale.c b/nx-X11/lib/font/bitmap/bitscale.c new file mode 100644 index 000000000..8f7247eaf --- /dev/null +++ b/nx-X11/lib/font/bitmap/bitscale.c @@ -0,0 +1,1978 @@ +/* $Xorg: bitscale.c,v 1.5 2001/02/09 02:04:02 xorgcvs Exp $ */ +/* + +Copyright 1991, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + +*/ +/* $XFree86: xc/lib/font/bitmap/bitscale.c,v 3.29tsi Exp $ */ + +/* + * Author: Keith Packard, MIT X Consortium + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +/* + * Translate monolithic #defines to modular definitions + */ + +#ifdef PCFFORMAT +#define XFONT_PCFFORMAT 1 +#endif + +#ifdef SNFFORMAT +#define XFONT_SNFFORMAT 1 +#endif + +#ifdef BDFFORMAT +#define XFONT_BDFFORMAT 1 +#endif + +#include <X11/fonts/fntfilst.h> +#include <X11/fonts/bitmap.h> +#include <X11/fonts/fontutil.h> +#ifndef FONTMODULE +#ifdef _XOPEN_SOURCE +#include <math.h> +#else +#define _XOPEN_SOURCE /* to get prototype for hypot on some systems */ +#include <math.h> +#undef _XOPEN_SOURCE +#endif +#endif + +#ifndef MAX +#define MAX(a,b) (((a)>(b)) ? a : b) +#endif + +/* Should get this from elsewhere */ +extern unsigned long serverGeneration; + +static void bitmapUnloadScalable (FontPtr pFont); +static void ScaleBitmap ( FontPtr pFont, CharInfoPtr opci, + CharInfoPtr pci, double *inv_xform, + double widthMult, double heightMult ); +static FontPtr BitmapScaleBitmaps(FontPtr pf, FontPtr opf, + double widthMult, double heightMult, + FontScalablePtr vals); +static FontPtr PrinterScaleBitmaps(FontPtr pf, FontPtr opf, + double widthMult, double heightMult, + FontScalablePtr vals); + +enum scaleType { + atom, truncate_atom, pixel_size, point_size, resolution_x, + resolution_y, average_width, scaledX, scaledY, unscaled, fontname, + raw_ascent, raw_descent, raw_pixelsize, raw_pointsize, + raw_average_width, uncomputed +}; + +typedef struct _fontProp { + char *name; + Atom atom; + enum scaleType type; +} fontProp; + +typedef FontPtr (*ScaleFunc) ( FontPtr /* pf */, + FontPtr /* opf */, + double /* widthMult */, + double /* heightMult */, + FontScalablePtr /* vals */); + +/* These next two arrays must be kept in step with the renderer array */ +ScaleFunc scale[] = +{ +#if XFONT_PCFFORMAT + BitmapScaleBitmaps, + BitmapScaleBitmaps, +#ifdef X_GZIP_FONT_COMPRESSION + BitmapScaleBitmaps, +#endif +#endif +#if XFONT_SNFFORMAT + BitmapScaleBitmaps, + BitmapScaleBitmaps, +#ifdef X_GZIP_FONT_COMPRESSION + BitmapScaleBitmaps, +#endif +#endif +#if XFONT_BDFFORMAT + BitmapScaleBitmaps, + BitmapScaleBitmaps, +#ifdef X_GZIP_FONT_COMPRESSION + BitmapScaleBitmaps, +#endif +#endif +#if XFONT_PCFFORMAT + PrinterScaleBitmaps, +#endif +}; + +static FontEntryPtr FindBestToScale ( FontPathElementPtr fpe, + FontEntryPtr entry, + FontScalablePtr vals, + FontScalablePtr best, + double *dxp, double *dyp, + double *sdxp, double *sdyp, + FontPathElementPtr *fpep ); +static FontEntryPtr FindPmfToScale ( FontPathElementPtr fpe, + FontEntryPtr entry, + FontScalablePtr vals, + FontScalablePtr best, + double *dxp, double *dyp, + double *sdxp, double *sdyp, + FontPathElementPtr *fpep ); + +typedef FontEntryPtr (*FindToScale) (FontPathElementPtr fpe, + FontEntryPtr entry, + FontScalablePtr vals, + FontScalablePtr best, + double *dxp, double *dyp, + double *sdxp, double *sdyp, + FontPathElementPtr *fpep); +FindToScale find_scale[] = +{ +#if XFONT_PCFFORMAT + FindBestToScale, + FindBestToScale, +#ifdef X_GZIP_FONT_COMPRESSION + FindBestToScale, +#endif +#endif +#if XFONT_SNFFORMAT + FindBestToScale, + FindBestToScale, +#ifdef X_GZIP_FONT_COMPRESSION + FindBestToScale, +#endif +#endif +#if XFONT_BDFFORMAT + FindBestToScale, + FindBestToScale, +#ifdef X_GZIP_FONT_COMPRESSION + FindBestToScale, +#endif +#endif +#if XFONT_PCFFORMAT + FindPmfToScale, +#endif +}; + +static unsigned long bitscaleGeneration = 0; /* initialization flag */ + +static fontProp fontNamePropTable[] = { + { "FOUNDRY", 0, atom }, + { "FAMILY_NAME", 0, atom }, + { "WEIGHT_NAME", 0, atom }, + { "SLANT", 0, atom }, + { "SETWIDTH_NAME", 0, atom }, + { "ADD_STYLE_NAME", 0, atom }, + { "PIXEL_SIZE", 0, pixel_size }, + { "POINT_SIZE", 0, point_size }, + { "RESOLUTION_X", 0, resolution_x }, + { "RESOLUTION_Y", 0, resolution_y }, + { "SPACING", 0, atom }, + { "AVERAGE_WIDTH", 0, average_width }, + { "CHARSET_REGISTRY", 0, atom }, + { "CHARSET_ENCODING", 0, truncate_atom }, + { "FONT", 0, fontname }, + { "RAW_ASCENT", 0, raw_ascent }, + { "RAW_DESCENT", 0, raw_descent }, + { "RAW_PIXEL_SIZE", 0, raw_pixelsize }, + { "RAW_POINT_SIZE", 0, raw_pointsize }, + { "RAW_AVERAGE_WIDTH", 0, raw_average_width } +}; + +#define TRANSFORM_POINT(matrix, x, y, dest) \ + ((dest)[0] = (matrix)[0] * (x) + (matrix)[2] * (y), \ + (dest)[1] = (matrix)[1] * (x) + (matrix)[3] * (y)) + +#define CHECK_EXTENT(lsb, rsb, desc, asc, data) \ + ((lsb) > (data)[0] ? (lsb) = (data)[0] : 0 , \ + (rsb) < (data)[0] ? (rsb) = (data)[0] : 0, \ + (-desc) > (data)[1] ? (desc) = -(data)[1] : 0 , \ + (asc) < (data)[1] ? (asc) = (data)[1] : 0) + +#define NPROPS (sizeof(fontNamePropTable) / sizeof(fontProp)) + +/* Warning: order of the next two tables is critically interdependent. + Location of "unscaled" properties at the end of fontPropTable[] + is important. */ + +static fontProp fontPropTable[] = { + { "MIN_SPACE", 0, scaledX }, + { "NORM_SPACE", 0, scaledX }, + { "MAX_SPACE", 0, scaledX }, + { "END_SPACE", 0, scaledX }, + { "AVG_CAPITAL_WIDTH", 0, scaledX }, + { "AVG_LOWERCASE_WIDTH", 0, scaledX }, + { "QUAD_WIDTH", 0, scaledX }, + { "FIGURE_WIDTH", 0, scaledX }, + { "SUPERSCRIPT_X", 0, scaledX }, + { "SUPERSCRIPT_Y", 0, scaledY }, + { "SUBSCRIPT_X", 0, scaledX }, + { "SUBSCRIPT_Y", 0, scaledY }, + { "SUPERSCRIPT_SIZE", 0, scaledY }, + { "SUBSCRIPT_SIZE", 0, scaledY }, + { "SMALL_CAP_SIZE", 0, scaledY }, + { "UNDERLINE_POSITION", 0, scaledY }, + { "UNDERLINE_THICKNESS", 0, scaledY }, + { "STRIKEOUT_ASCENT", 0, scaledY }, + { "STRIKEOUT_DESCENT", 0, scaledY }, + { "CAP_HEIGHT", 0, scaledY }, + { "X_HEIGHT", 0, scaledY }, + { "ITALIC_ANGLE", 0, unscaled }, + { "RELATIVE_SETWIDTH", 0, unscaled }, + { "RELATIVE_WEIGHT", 0, unscaled }, + { "WEIGHT", 0, unscaled }, + { "DESTINATION", 0, unscaled }, + { "PCL_FONT_NAME", 0, unscaled }, + { "_ADOBE_POSTSCRIPT_FONTNAME", 0, unscaled } +}; + +/* sleazy way to shut up the compiler */ +#define zerohack (enum scaleType)0 + +static fontProp rawFontPropTable[] = { + { "RAW_MIN_SPACE", 0, }, + { "RAW_NORM_SPACE", 0, }, + { "RAW_MAX_SPACE", 0, }, + { "RAW_END_SPACE", 0, }, + { "RAW_AVG_CAPITAL_WIDTH", 0, }, + { "RAW_AVG_LOWERCASE_WIDTH", 0, }, + { "RAW_QUAD_WIDTH", 0, }, + { "RAW_FIGURE_WIDTH", 0, }, + { "RAW_SUPERSCRIPT_X", 0, }, + { "RAW_SUPERSCRIPT_Y", 0, }, + { "RAW_SUBSCRIPT_X", 0, }, + { "RAW_SUBSCRIPT_Y", 0, }, + { "RAW_SUPERSCRIPT_SIZE", 0, }, + { "RAW_SUBSCRIPT_SIZE", 0, }, + { "RAW_SMALL_CAP_SIZE", 0, }, + { "RAW_UNDERLINE_POSITION", 0, }, + { "RAW_UNDERLINE_THICKNESS", 0, }, + { "RAW_STRIKEOUT_ASCENT", 0, }, + { "RAW_STRIKEOUT_DESCENT", 0, }, + { "RAW_CAP_HEIGHT", 0, }, + { "RAW_X_HEIGHT", 0, } +}; + +static void +initFontPropTable(void) +{ + int i; + fontProp *t; + + i = sizeof(fontNamePropTable) / sizeof(fontProp); + for (t = fontNamePropTable; i; i--, t++) + t->atom = MakeAtom(t->name, (unsigned) strlen(t->name), TRUE); + + i = sizeof(fontPropTable) / sizeof(fontProp); + for (t = fontPropTable; i; i--, t++) + t->atom = MakeAtom(t->name, (unsigned) strlen(t->name), TRUE); + + i = sizeof(rawFontPropTable) / sizeof(fontProp); + for (t = rawFontPropTable; i; i--, t++) + t->atom = MakeAtom(t->name, (unsigned) strlen(t->name), TRUE); +} + +#if 0 +static FontEntryPtr +GetScalableEntry (FontPathElementPtr fpe, FontNamePtr name) +{ + FontDirectoryPtr dir; + + dir = (FontDirectoryPtr) fpe->private; + return FontFileFindNameInDir (&dir->scalable, name); +} +#endif + +static double +get_matrix_horizontal_component(double *matrix) +{ + return hypot(matrix[0], matrix[1]); +} + +static double +get_matrix_vertical_component(double *matrix) +{ + return hypot(matrix[2], matrix[3]); +} + + +static Bool +ComputeScaleFactors(FontScalablePtr from, FontScalablePtr to, + double *dx, double *dy, double *sdx, double *sdy, + double *rescale_x) +{ + double srcpixelset, destpixelset, srcpixel, destpixel; + + srcpixelset = get_matrix_horizontal_component(from->pixel_matrix); + destpixelset = get_matrix_horizontal_component(to->pixel_matrix); + srcpixel = get_matrix_vertical_component(from->pixel_matrix); + destpixel = get_matrix_vertical_component(to->pixel_matrix); + + if (srcpixelset >= EPS) + { + *dx = destpixelset / srcpixelset; + *sdx = 1000.0 / srcpixelset; + } + else + *sdx = *dx = 0; + + *rescale_x = 1.0; + + /* If client specified a width, it overrides setsize; in this + context, we interpret width as applying to the font before any + rotation, even though that's not what is ultimately returned in + the width field. */ + if (from->width > 0 && to->width > 0 && fabs(*dx) > EPS) + { + double rescale = (double)to->width / (double)from->width; + + /* If the client specified a transformation matrix, the rescaling + for width does *not* override the setsize. Instead, just check + for consistency between the setsize from the matrix and the + setsize that would result from rescaling according to the width. + This assumes (perhaps naively) that the width is correctly + reported in the name. As an interesting side effect, this test + may result in choosing a different source bitmap (one that + scales consistently between the setsize *and* the width) than it + would choose if a width were not specified. Sort of a hidden + multiple-master functionality. */ + if ((to->values_supplied & PIXELSIZE_MASK) == PIXELSIZE_ARRAY || + (to->values_supplied & POINTSIZE_MASK) == POINTSIZE_ARRAY) + { + /* Reject if resulting width difference is >= 1 pixel */ + if (fabs(rescale * from->width - *dx * from->width) >= 10) + return FALSE; + } + else + { + *rescale_x = rescale/(*dx); + *dx = rescale; + } + } + + if (srcpixel >= EPS) + { + *dy = destpixel / srcpixel; + *sdy = 1000.0 / srcpixel; + } + else + *sdy = *dy = 0; + + return TRUE; +} + +/* favor enlargement over reduction because of aliasing resulting + from reduction */ +#define SCORE(m,s) \ +if (m >= 1.0) { \ + if (m == 1.0) \ + score += (16 * s); \ + else if (m == 2.0) \ + score += (4 * s); \ + else \ + score += (int)(((double)(3 * s)) / m); \ +} else { \ + score += (int)(((double)(2 * s)) * m); \ +} + +/* don't need to favor enlargement when looking for bitmap that can + be used unscalable */ +#define SCORE2(m,s) \ +if (m >= 1.0) \ + score += (int)(((double)(8 * s)) / m); \ +else \ + score += (int)(((double)(8 * s)) * m); + +static FontEntryPtr +FindBestToScale(FontPathElementPtr fpe, FontEntryPtr entry, + FontScalablePtr vals, FontScalablePtr best, + double *dxp, double *dyp, + double *sdxp, double *sdyp, + FontPathElementPtr *fpep) +{ + FontScalableRec temp; + int source, i; + int best_score, best_unscaled_score, + score; + double dx = 0.0, sdx = 0.0, dx_amount = 0.0, + dy = 0.0, sdy = 0.0, dy_amount = 0.0, + best_dx = 0.0, best_sdx = 0.0, best_dx_amount = 0.0, + best_dy = 0.0, best_sdy = 0.0, best_dy_amount = 0.0, + best_unscaled_sdx = 0.0, best_unscaled_sdy = 0.0, + rescale_x = 0.0, best_rescale_x = 0.0, + best_unscaled_rescale_x = 0.0; + FontEntryPtr zero; + FontNameRec zeroName; + char zeroChars[MAXFONTNAMELEN]; + FontDirectoryPtr dir; + FontScaledPtr scaled; + FontScalableExtraPtr extra; + FontScaledPtr best_scaled, best_unscaled; + FontPathElementPtr best_fpe = NULL, best_unscaled_fpe = NULL; + FontEntryPtr bitmap = NULL; + FontEntryPtr result; + int aliascount = 20; + FontPathElementPtr bitmap_fpe = NULL; + FontNameRec xlfdName; + + /* find the best match */ + rescale_x = 1.0; + best_scaled = 0; + best_score = 0; + best_unscaled = 0; + best_unscaled_score = -1; + best_dx_amount = best_dy_amount = HUGE_VAL; + memcpy (zeroChars, entry->name.name, entry->name.length); + zeroChars[entry->name.length] = '\0'; + zeroName.name = zeroChars; + FontParseXLFDName (zeroChars, &temp, FONT_XLFD_REPLACE_ZERO); + zeroName.length = strlen (zeroChars); + zeroName.ndashes = entry->name.ndashes; + xlfdName.name = vals->xlfdName; + xlfdName.length = strlen(xlfdName.name); + xlfdName.ndashes = FontFileCountDashes(xlfdName.name, xlfdName.length); + restart_bestscale_loop: ; + /* + * Look through all the registered bitmap sources for + * the same zero name as ours; entries along that one + * can be scaled as desired. + */ + for (source = 0; source < FontFileBitmapSources.count; source++) + { + /* There might already be a bitmap that satisfies the request + but didn't have a zero name that was found by the scalable + font matching logic. Keep track if there is. */ + if (bitmap == NULL && vals->xlfdName != NULL) + { + bitmap_fpe = FontFileBitmapSources.fpe[source]; + dir = (FontDirectoryPtr) bitmap_fpe->private; + bitmap = FontFileFindNameInDir (&dir->nonScalable, &xlfdName); + if (bitmap && bitmap->type != FONT_ENTRY_BITMAP) + { + if (bitmap->type == FONT_ENTRY_ALIAS && aliascount > 0) + { + aliascount--; + xlfdName.name = bitmap->u.alias.resolved; + xlfdName.length = strlen(xlfdName.name); + xlfdName.ndashes = FontFileCountDashes(xlfdName.name, + xlfdName.length); + bitmap = NULL; + goto restart_bestscale_loop; + } + else + bitmap = NULL; + } + } + + if (FontFileBitmapSources.fpe[source] == fpe) + zero = entry; + else + { + dir = (FontDirectoryPtr) FontFileBitmapSources.fpe[source]->private; + zero = FontFileFindNameInDir (&dir->scalable, &zeroName); + if (!zero) + continue; + } + extra = zero->u.scalable.extra; + for (i = 0; i < extra->numScaled; i++) + { + scaled = &extra->scaled[i]; + if (!scaled->bitmap) + continue; + if (!ComputeScaleFactors(&scaled->vals, vals, &dx, &dy, &sdx, &sdy, + &rescale_x)) + continue; + score = 0; + dx_amount = dx; + dy_amount = dy; + SCORE(dy_amount, 10); + SCORE(dx_amount, 1); + if ((score > best_score) || + ((score == best_score) && + ((dy_amount < best_dy_amount) || + ((dy_amount == best_dy_amount) && + (dx_amount < best_dx_amount))))) + { + best_fpe = FontFileBitmapSources.fpe[source]; + best_scaled = scaled; + best_score = score; + best_dx = dx; + best_dy = dy; + best_sdx = sdx; + best_sdy = sdy; + best_dx_amount = dx_amount; + best_dy_amount = dy_amount; + best_rescale_x = rescale_x; + } + /* Is this font a candidate for use without ugly rescaling? */ + if (fabs(dx) > EPS && fabs(dy) > EPS && + fabs(vals->pixel_matrix[0] * rescale_x - + scaled->vals.pixel_matrix[0]) < 1 && + fabs(vals->pixel_matrix[1] * rescale_x - + scaled->vals.pixel_matrix[1]) < EPS && + fabs(vals->pixel_matrix[2] - + scaled->vals.pixel_matrix[2]) < EPS && + fabs(vals->pixel_matrix[3] - + scaled->vals.pixel_matrix[3]) < 1) + { + /* Yes. The pixel sizes are close on the diagonal and + extremely close off the diagonal. */ + score = 0; + SCORE2(vals->pixel_matrix[3] / + scaled->vals.pixel_matrix[3], 10); + SCORE2(vals->pixel_matrix[0] * rescale_x / + scaled->vals.pixel_matrix[0], 1); + if (score > best_unscaled_score) + { + best_unscaled_fpe = FontFileBitmapSources.fpe[source]; + best_unscaled = scaled; + best_unscaled_sdx = sdx / dx; + best_unscaled_sdy = sdy / dy; + best_unscaled_score = score; + best_unscaled_rescale_x = rescale_x; + } + } + } + } + if (best_unscaled) + { + *best = best_unscaled->vals; + *fpep = best_unscaled_fpe; + *dxp = 1.0; + *dyp = 1.0; + *sdxp = best_unscaled_sdx; + *sdyp = best_unscaled_sdy; + rescale_x = best_unscaled_rescale_x; + result = best_unscaled->bitmap; + } + else if (best_scaled) + { + *best = best_scaled->vals; + *fpep = best_fpe; + *dxp = best_dx; + *dyp = best_dy; + *sdxp = best_sdx; + *sdyp = best_sdy; + rescale_x = best_rescale_x; + result = best_scaled->bitmap; + } + else + result = NULL; + + if (bitmap != NULL && (result == NULL || *dxp != 1.0 || *dyp != 1.0)) + { + *fpep = bitmap_fpe; + FontParseXLFDName (bitmap->name.name, best, FONT_XLFD_REPLACE_NONE); + if (ComputeScaleFactors(best, best, dxp, dyp, sdxp, sdyp, &rescale_x)) + result = bitmap; + else + result = NULL; + } + + if (result && rescale_x != 1.0) + { + /* We have rescaled horizontally due to an XLFD width field. Change + the matrix appropriately */ + vals->pixel_matrix[0] *= rescale_x; + vals->pixel_matrix[1] *= rescale_x; +#ifdef NOTDEF + /* This would force the pointsize and pixelsize fields in the + FONT property to display as matrices to more accurately + report the font being supplied. It might also break existing + applications that expect a single number in that field. */ + vals->values_supplied = + vals->values_supplied & ~(PIXELSIZE_MASK | POINTSIZE_MASK) | + PIXELSIZE_ARRAY; +#else /* NOTDEF */ + vals->values_supplied = vals->values_supplied & ~POINTSIZE_MASK; +#endif /* NOTDEF */ + /* Recompute and reround the FontScalablePtr values after + rescaling for the new width. */ + FontFileCompleteXLFD(vals, vals); + } + + return result; +} + +static FontEntryPtr +FindPmfToScale(FontPathElementPtr fpe, FontEntryPtr entry, + FontScalablePtr vals, FontScalablePtr best, + double *dxp, double *dyp, + double *sdxp, double *sdyp, + FontPathElementPtr *fpep) +{ + FontEntryPtr result = NULL; + FontScaledPtr scaled; + FontScalableExtraPtr extra; + int i; + + extra = entry->u.scalable.extra; + for (i = 0; i < extra->numScaled; i++) + { + double rescale_x; + + scaled = &extra->scaled[i]; + if (!scaled->bitmap) + continue; + if (!ComputeScaleFactors(&scaled->vals, vals, dxp, dyp, sdxp, sdyp, + &rescale_x)) + continue; + *best = scaled->vals; + *fpep = fpe; + result = scaled->bitmap; + if (rescale_x != 1.0) + { + /* We have rescaled horizontally due to an XLFD width field. Change + the matrix appropriately */ + vals->pixel_matrix[0] *= rescale_x; + vals->pixel_matrix[1] *= rescale_x; +#ifdef NOTDEF + /* This would force the pointsize and pixelsize fields in the + FONT property to display as matrices to more accurately + report the font being supplied. It might also break existing + applications that expect a single number in that field. */ + vals->values_supplied = + vals->values_supplied & ~(PIXELSIZE_MASK | POINTSIZE_MASK) | + PIXELSIZE_ARRAY; +#else /* NOTDEF */ + vals->values_supplied = vals->values_supplied & ~POINTSIZE_MASK; +#endif /* NOTDEF */ + /* Recompute and reround the FontScalablePtr values after + rescaling for the new width. */ + FontFileCompleteXLFD(vals, vals); + } + break; + } + return result; +} + +static long +doround(double x) +{ + return (x >= 0) ? (long)(x + .5) : (long)(x - .5); +} + +static int +computeProps(FontPropPtr pf, char *wasStringProp, + FontPropPtr npf, char *isStringProp, + unsigned int nprops, double xfactor, double yfactor, + double sXfactor, double sYfactor) +{ + int n; + int count; + fontProp *t; + double rawfactor = 0.0; + + for (count = 0; nprops > 0; nprops--, pf++, wasStringProp++) { + n = sizeof(fontPropTable) / sizeof(fontProp); + for (t = fontPropTable; n && (t->atom != pf->name); n--, t++); + if (!n) + continue; + + switch (t->type) { + case scaledX: + npf->value = doround(xfactor * (double)pf->value); + rawfactor = sXfactor; + break; + case scaledY: + npf->value = doround(yfactor * (double)pf->value); + rawfactor = sYfactor; + break; + case unscaled: + npf->value = pf->value; + npf->name = pf->name; + npf++; + count++; + *isStringProp++ = *wasStringProp; + break; + default: + break; + } + if (t->type != unscaled) + { + npf->name = pf->name; + npf++; + count++; + npf->value = doround(rawfactor * (double)pf->value); + npf->name = rawFontPropTable[t - fontPropTable].atom; + npf++; + count++; + *isStringProp++ = *wasStringProp; + *isStringProp++ = *wasStringProp; + } + } + return count; +} + + +static int +ComputeScaledProperties(FontInfoPtr sourceFontInfo, /* the font to be scaled */ + char *name, /* name of resulting font */ + FontScalablePtr vals, + double dx, double dy, /* scale factors in x and y */ + double sdx, double sdy, /* directions */ + long sWidth, /* 1000-pixel average width */ + FontPropPtr *pProps, /* returns properties; + preallocated */ + char **pIsStringProp) /* return booleans; + preallocated */ +{ + int n; + char *ptr1 = NULL, *ptr2 = NULL; + char *ptr3; + FontPropPtr fp; + fontProp *fpt; + char *isStringProp; + int nProps; + + if (bitscaleGeneration != serverGeneration) { + initFontPropTable(); + bitscaleGeneration = serverGeneration; + } + nProps = NPROPS + 1 + sizeof(fontPropTable) / sizeof(fontProp) + + sizeof(rawFontPropTable) / sizeof(fontProp); + fp = (FontPropPtr) xalloc(sizeof(FontPropRec) * nProps); + *pProps = fp; + if (!fp) { + fprintf(stderr, "Error: Couldn't allocate font properties (%ld*%d)\n", + (unsigned long)sizeof(FontPropRec), nProps); + return 1; + } + isStringProp = (char *) xalloc (nProps); + *pIsStringProp = isStringProp; + if (!isStringProp) + { + fprintf(stderr, "Error: Couldn't allocate isStringProp (%d)\n", nProps); + xfree (fp); + return 1; + } + ptr2 = name; + for (fpt = fontNamePropTable, n = NPROPS; + n; + fp++, fpt++, n--, isStringProp++) + { + + if (*ptr2) + { + ptr1 = ptr2 + 1; + if (!(ptr2 = strchr(ptr1, '-'))) ptr2 = strchr(ptr1, '\0'); + } + + *isStringProp = 0; + switch (fpt->type) { + case atom: + fp->value = MakeAtom(ptr1, ptr2 - ptr1, TRUE); + *isStringProp = 1; + break; + case truncate_atom: + for (ptr3 = ptr1; *ptr3; ptr3++) + if (*ptr3 == '[') + break; + if (!*ptr3) ptr3 = ptr2; + fp->value = MakeAtom(ptr1, ptr3 - ptr1, TRUE); + *isStringProp = 1; + break; + case pixel_size: + fp->value = doround(vals->pixel_matrix[3]); + break; + case point_size: + fp->value = doround(vals->point_matrix[3] * 10.0); + break; + case resolution_x: + fp->value = vals->x; + break; + case resolution_y: + fp->value = vals->y; + break; + case average_width: + fp->value = vals->width; + break; + case fontname: + fp->value = MakeAtom(name, strlen(name), TRUE); + *isStringProp = 1; + break; + case raw_ascent: + fp->value = sourceFontInfo->fontAscent * sdy; + break; + case raw_descent: + fp->value = sourceFontInfo->fontDescent * sdy; + break; + case raw_pointsize: + fp->value = (long)(72270.0 / (double)vals->y + .5); + break; + case raw_pixelsize: + fp->value = 1000; + break; + case raw_average_width: + fp->value = sWidth; + break; + default: + break; + } + fp->name = fpt->atom; + } + n = NPROPS; + n += computeProps(sourceFontInfo->props, sourceFontInfo->isStringProp, + fp, isStringProp, sourceFontInfo->nprops, dx, dy, + sdx, sdy); + return n; +} + + +static int +compute_xform_matrix(FontScalablePtr vals, double dx, double dy, + double *xform, double *inv_xform, + double *xmult, double *ymult) +{ + double det; + double pixel = get_matrix_vertical_component(vals->pixel_matrix); + double pixelset = get_matrix_horizontal_component(vals->pixel_matrix); + + if (pixel < EPS || pixelset < EPS) return 0; + + /* Initialize the transformation matrix to the scaling factors */ + xform[0] = dx / pixelset; + xform[1] = xform[2] = 0.0; + xform[3] = dy / pixel; + +/* Inline matrix multiply -- somewhat ugly to minimize register usage */ +#define MULTIPLY_XFORM(a,b,c,d) \ +{ \ + register double aa = (a), bb = (b), cc = (c), dd = (d); \ + register double temp; \ + temp = aa * xform[0] + cc * xform[1]; \ + aa = aa * xform[2] + cc * xform[3]; \ + xform[1] = bb * xform[0] + dd * xform[1]; \ + xform[3] = bb * xform[2] + dd * xform[3]; \ + xform[0] = temp; \ + xform[2] = aa; \ +} + + /* Rescale the transformation matrix for size of source font */ + MULTIPLY_XFORM(vals->pixel_matrix[0], + vals->pixel_matrix[1], + vals->pixel_matrix[2], + vals->pixel_matrix[3]); + + *xmult = xform[0]; + *ymult = xform[3]; + + + if (inv_xform == NULL) return 1; + + /* Compute the determinant for use in inverting the matrix. */ + det = xform[0] * xform[3] - xform[1] * xform[2]; + + /* If the determinant is tiny or zero, give up */ + if (fabs(det) < EPS) return 0; + + /* Compute the inverse */ + inv_xform[0] = xform[3] / det; + inv_xform[1] = -xform[1] / det; + inv_xform[2] = -xform[2] / det; + inv_xform[3] = xform[0] / det; + + return 1; +} + +/* + * ScaleFont + * returns a pointer to the new scaled font, or NULL (due to AllocError). + */ +static FontPtr +ScaleFont(FontPtr opf, /* originating font */ + double widthMult, /* glyphs width scale factor */ + double heightMult, /* glyphs height scale factor */ + double sWidthMult, /* scalable glyphs width scale factor */ + double sHeightMult, /* scalable glyphs height scale factor */ + FontScalablePtr vals, + double *newWidthMult, /* return: X component of glyphs width + scale factor */ + double *newHeightMult, /* return: Y component of glyphs height + scale factor */ + long *sWidth) /* return: average 1000-pixel width */ +{ + FontPtr pf; + FontInfoPtr pfi, + opfi; + BitmapFontPtr bitmapFont, + obitmapFont; + CharInfoPtr pci, + opci; + int nchars = 0; /* how many characters in the font */ + int i; + int firstCol, lastCol, firstRow, lastRow; + double xform[4], inv_xform[4]; + double xmult, ymult; + int totalwidth = 0, totalchars = 0; +#define OLDINDEX(i) (((i)/(lastCol - firstCol + 1) + \ + firstRow - opf->info.firstRow) * \ + (opf->info.lastCol - opf->info.firstCol + 1) + \ + (i)%(lastCol - firstCol + 1) + \ + firstCol - opf->info.firstCol) + + *sWidth = 0; + + opfi = &opf->info; + obitmapFont = (BitmapFontPtr) opf->fontPrivate; + + bitmapFont = 0; + if (!(pf = CreateFontRec())) { + fprintf(stderr, "Error: Couldn't allocate FontRec (%ld)\n", + (unsigned long)sizeof(FontRec)); + goto bail; + } + pf->refcnt = 0; + pf->bit = opf->bit; + pf->byte = opf->byte; + pf->glyph = opf->glyph; + pf->scan = opf->scan; + + pf->get_glyphs = bitmapGetGlyphs; + pf->get_metrics = bitmapGetMetrics; + pf->unload_font = bitmapUnloadScalable; + pf->unload_glyphs = NULL; + + pfi = &pf->info; + *pfi = *opfi; + /* If charset subsetting specified in vals, determine what our range + needs to be for the output font */ + if (vals->nranges) + { + int i; + + pfi->allExist = 0; + firstCol = 255; + lastCol = 0; + firstRow = 255; + lastRow = 0; + + for (i = 0; i < vals->nranges; i++) + { + if (vals->ranges[i].min_char_high != vals->ranges[i].max_char_high) + { + firstCol = opfi->firstCol; + lastCol = opfi->lastCol; + } + if (firstCol > vals->ranges[i].min_char_low) + firstCol = vals->ranges[i].min_char_low; + if (lastCol < vals->ranges[i].max_char_low) + lastCol = vals->ranges[i].max_char_low; + if (firstRow > vals->ranges[i].min_char_high) + firstRow = vals->ranges[i].min_char_high; + if (lastRow < vals->ranges[i].max_char_high) + lastRow = vals->ranges[i].max_char_high; + } + + if (firstCol > lastCol || firstRow > lastRow) + goto bail; + + if (firstCol < opfi->firstCol) + firstCol = opfi->firstCol; + if (lastCol > opfi->lastCol) + lastCol = opfi->lastCol; + if (firstRow < opfi->firstRow) + firstRow = opfi->firstRow; + if (lastRow > opfi->lastRow) + lastRow = opfi->lastRow; + } + else + { + firstCol = opfi->firstCol; + lastCol = opfi->lastCol; + firstRow = opfi->firstRow; + lastRow = opfi->lastRow; + } + + bitmapFont = (BitmapFontPtr) xalloc(sizeof(BitmapFontRec)); + if (!bitmapFont) { + fprintf(stderr, "Error: Couldn't allocate bitmapFont (%ld)\n", + (unsigned long)sizeof(BitmapFontRec)); + goto bail; + } + nchars = (lastRow - firstRow + 1) * (lastCol - firstCol + 1); + pfi->firstRow = firstRow; + pfi->lastRow = lastRow; + pfi->firstCol = firstCol; + pfi->lastCol = lastCol; + pf->fontPrivate = (pointer) bitmapFont; + bitmapFont->version_num = obitmapFont->version_num; + bitmapFont->num_chars = nchars; + bitmapFont->num_tables = obitmapFont->num_tables; + bitmapFont->metrics = 0; + bitmapFont->ink_metrics = 0; + bitmapFont->bitmaps = 0; + bitmapFont->encoding = 0; + bitmapFont->bitmapExtra = 0; + bitmapFont->pDefault = 0; + bitmapFont->metrics = (CharInfoPtr) xalloc(nchars * sizeof(CharInfoRec)); + if (!bitmapFont->metrics) { + fprintf(stderr, "Error: Couldn't allocate metrics (%d*%ld)\n", + nchars, (unsigned long)sizeof(CharInfoRec)); + goto bail; + } + bitmapFont->encoding = + (CharInfoPtr **) xcalloc(NUM_SEGMENTS(nchars), + sizeof(CharInfoPtr*)); + if (!bitmapFont->encoding) { + fprintf(stderr, "Error: Couldn't allocate encoding (%d*%ld)\n", + nchars, (unsigned long)sizeof(CharInfoPtr)); + goto bail; + } + +#undef MAXSHORT +#define MAXSHORT 32767 +#undef MINSHORT +#define MINSHORT -32768 + + pfi->anamorphic = FALSE; + if (heightMult != widthMult) + pfi->anamorphic = TRUE; + pfi->cachable = TRUE; + + if (!compute_xform_matrix(vals, widthMult, heightMult, xform, + inv_xform, &xmult, &ymult)) + goto bail; + + pfi->fontAscent = opfi->fontAscent * ymult; + pfi->fontDescent = opfi->fontDescent * ymult; + + pfi->minbounds.leftSideBearing = MAXSHORT; + pfi->minbounds.rightSideBearing = MAXSHORT; + pfi->minbounds.ascent = MAXSHORT; + pfi->minbounds.descent = MAXSHORT; + pfi->minbounds.characterWidth = MAXSHORT; + pfi->minbounds.attributes = MAXSHORT; + + pfi->maxbounds.leftSideBearing = MINSHORT; + pfi->maxbounds.rightSideBearing = MINSHORT; + pfi->maxbounds.ascent = MINSHORT; + pfi->maxbounds.descent = MINSHORT; + pfi->maxbounds.characterWidth = MINSHORT; + pfi->maxbounds.attributes = MINSHORT; + + /* Compute the transformation and inverse transformation matrices. + Can fail if the determinant is zero. */ + + pci = bitmapFont->metrics; + for (i = 0; i < nchars; i++) + { + if ((opci = ACCESSENCODING(obitmapFont->encoding,OLDINDEX(i)))) + { + double newlsb, newrsb, newdesc, newasc, point[2]; + +#define minchar(p) ((p).min_char_low + ((p).min_char_high << 8)) +#define maxchar(p) ((p).max_char_low + ((p).max_char_high << 8)) + + if (vals->nranges) + { + int row = i / (lastCol - firstCol + 1) + firstRow; + int col = i % (lastCol - firstCol + 1) + firstCol; + int ch = (row << 8) + col; + int j; + for (j = 0; j < vals->nranges; j++) + if (ch >= minchar(vals->ranges[j]) && + ch <= maxchar(vals->ranges[j])) + break; + if (j == vals->nranges) + { + continue; + } + } + + if (opci->metrics.leftSideBearing == 0 && + opci->metrics.rightSideBearing == 0 && + opci->metrics.ascent == 0 && + opci->metrics.descent == 0 && + opci->metrics.characterWidth == 0) + { + continue; + } + + if(!bitmapFont->encoding[SEGMENT_MAJOR(i)]) { + bitmapFont->encoding[SEGMENT_MAJOR(i)]= + (CharInfoPtr*)xcalloc(BITMAP_FONT_SEGMENT_SIZE, + sizeof(CharInfoPtr)); + if(!bitmapFont->encoding[SEGMENT_MAJOR(i)]) + goto bail; + } + ACCESSENCODINGL(bitmapFont->encoding, i) = pci; + + /* Compute new extents for this glyph */ + TRANSFORM_POINT(xform, + opci->metrics.leftSideBearing, + -opci->metrics.descent, + point); + newlsb = point[0]; + newrsb = newlsb; + newdesc = -point[1]; + newasc = -newdesc; + TRANSFORM_POINT(xform, + opci->metrics.leftSideBearing, + opci->metrics.ascent, + point); + CHECK_EXTENT(newlsb, newrsb, newdesc, newasc, point); + TRANSFORM_POINT(xform, + opci->metrics.rightSideBearing, + -opci->metrics.descent, + point); + CHECK_EXTENT(newlsb, newrsb, newdesc, newasc, point); + TRANSFORM_POINT(xform, + opci->metrics.rightSideBearing, + opci->metrics.ascent, + point); + CHECK_EXTENT(newlsb, newrsb, newdesc, newasc, point); + + pci->metrics.leftSideBearing = (int)floor(newlsb); + pci->metrics.rightSideBearing = (int)floor(newrsb + .5); + pci->metrics.descent = (int)ceil(newdesc); + pci->metrics.ascent = (int)floor(newasc + .5); + /* Accumulate total width of characters before transformation, + to ascertain predominant direction of font. */ + totalwidth += opci->metrics.characterWidth; + pci->metrics.characterWidth = + doround((double)opci->metrics.characterWidth * xmult); + pci->metrics.attributes = + doround((double)opci->metrics.characterWidth * sWidthMult); + if (!pci->metrics.characterWidth) + { + /* Since transformation may shrink width, height, and + escapement to zero, make sure existing characters + are not mistaken for undefined characters. */ + + if (pci->metrics.rightSideBearing == + pci->metrics.leftSideBearing) + pci->metrics.rightSideBearing++; + if (pci->metrics.ascent == -pci->metrics.descent) + pci->metrics.ascent++; + } + + pci++; + } + } + + + /* + * For each character, set the per-character metrics, scale the glyph, and + * check per-font minbounds and maxbounds character information. + */ + + pci = bitmapFont->metrics; + for (i = 0; i < nchars; i++) + { + if ((pci = ACCESSENCODING(bitmapFont->encoding,i)) && + (opci = ACCESSENCODING(obitmapFont->encoding,OLDINDEX(i)))) + { + totalchars++; + *sWidth += abs((int)(INT16)pci->metrics.attributes); +#define MINMAX(field) \ + if (pfi->minbounds.field > pci->metrics.field) \ + pfi->minbounds.field = pci->metrics.field; \ + if (pfi->maxbounds.field < pci->metrics.field) \ + pfi->maxbounds.field = pci->metrics.field + + MINMAX(leftSideBearing); + MINMAX(rightSideBearing); + MINMAX(ascent); + MINMAX(descent); + MINMAX(characterWidth); + + /* Hack: Cast attributes into a signed quantity. Tread lightly + for now and don't go changing the global Xproto.h file */ + if ((INT16)pfi->minbounds.attributes > + (INT16)pci->metrics.attributes) + pfi->minbounds.attributes = pci->metrics.attributes; + if ((INT16)pfi->maxbounds.attributes < + (INT16)pci->metrics.attributes) + pfi->maxbounds.attributes = pci->metrics.attributes; +#undef MINMAX + } + } + pfi->ink_minbounds = pfi->minbounds; + pfi->ink_maxbounds = pfi->maxbounds; + if (totalchars) + { + *sWidth = (*sWidth * 10 + totalchars / 2) / totalchars; + if (totalwidth < 0) + { + /* Dominant direction is R->L */ + *sWidth = -*sWidth; + } + + if (pfi->minbounds.characterWidth == pfi->maxbounds.characterWidth) + vals->width = pfi->minbounds.characterWidth * 10; + else + vals->width = doround((double)*sWidth * vals->pixel_matrix[0] / + 1000.0); + } + else + { + vals->width = 0; + *sWidth = 0; + } + FontComputeInfoAccelerators (pfi); + + if (pfi->defaultCh != (unsigned short) NO_SUCH_CHAR) { + unsigned int r, + c, + cols; + + r = pfi->defaultCh >> 8; + c = pfi->defaultCh & 0xFF; + if (pfi->firstRow <= r && r <= pfi->lastRow && + pfi->firstCol <= c && c <= pfi->lastCol) { + cols = pfi->lastCol - pfi->firstCol + 1; + r = r - pfi->firstRow; + c = c - pfi->firstCol; + bitmapFont->pDefault = + ACCESSENCODING(bitmapFont->encoding, r * cols + c); + } + } + + *newWidthMult = xmult; + *newHeightMult = ymult; + return pf; +bail: + if (pf) + xfree(pf); + if (bitmapFont) { + xfree(bitmapFont->metrics); + xfree(bitmapFont->ink_metrics); + xfree(bitmapFont->bitmaps); + if(bitmapFont->encoding) + for(i=0; i<NUM_SEGMENTS(nchars); i++) + xfree(bitmapFont->encoding[i]); + xfree(bitmapFont->encoding); + } + return NULL; +} + +static void +ScaleBitmap(FontPtr pFont, CharInfoPtr opci, CharInfoPtr pci, + double *inv_xform, double widthMult, double heightMult) +{ + register char *bitmap, /* The bits */ + *newBitmap; + register int bpr, /* Padding information */ + newBpr; + int width, /* Extents information */ + height, + newWidth, + newHeight; + register int row, /* Loop variables */ + col; + INT32 deltaX, /* Increments for resampling loop */ + deltaY; + INT32 xValue, /* Subscripts for resampling loop */ + yValue; + double point[2]; + unsigned char *char_grayscale = 0; + INT32 *diffusion_workspace = NULL, *thisrow = NULL, + *nextrow = NULL, pixmult = 0; + int box_x = 0, box_y = 0; + + static unsigned char masklsb[] = + { 0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80 }; + static unsigned char maskmsb[] = + { 0x80, 0x40, 0x20, 0x10, 0x8, 0x4, 0x2, 0x1 }; + unsigned char *mask = (pFont->bit == LSBFirst ? masklsb : maskmsb); + + + bitmap = opci->bits; + newBitmap = pci->bits; + width = GLYPHWIDTHPIXELS(opci); + height = GLYPHHEIGHTPIXELS(opci); + newWidth = GLYPHWIDTHPIXELS(pci); + newHeight = GLYPHHEIGHTPIXELS(pci); + if (!newWidth || !newHeight || !width || !height) + return; + + bpr = BYTES_PER_ROW(width, pFont->glyph); + newBpr = BYTES_PER_ROW(newWidth, pFont->glyph); + + if (widthMult > 0.0 && heightMult > 0.0 && + (widthMult < 1.0 || heightMult < 1.0)) + { + /* We are reducing in one or both dimensions. In an attempt to + reduce aliasing, we'll antialias by passing the original + glyph through a low-pass box filter (which results in a + grayscale image), then use error diffusion to create bitonal + output in the resampling loop. */ + + /* First compute the sizes of the box filter */ + widthMult = ceil(1.0 / widthMult); + heightMult = ceil(1.0 / heightMult); + box_x = width / 2; + box_y = height / 2; + if (widthMult < (double)box_x) box_x = (int)widthMult; + if (heightMult < (double)box_y) box_y = (int)heightMult; + /* The pixmult value (below) is used to darken the image before + we perform error diffusion: a necessary concession to the + fact that it's very difficult to generate readable halftoned + glyphs. The degree of darkening is proportional to the size + of the blurring filter, hence inversely proportional to the + darkness of the lightest gray that results from antialiasing. + The result is that characters that exercise this logic (those + generated by reducing from a larger source font) tend to err + on the side of being too bold instead of being too light to + be readable. */ + pixmult = box_x * box_y * 192; + + if (box_x > 1 || box_y > 1) + { + /* Looks like we need to anti-alias. Create a workspace to + contain the grayscale character plus an additional row and + column for scratch */ + char_grayscale = + (unsigned char *)xalloc((width + 1) * (height + 1)); + if (char_grayscale) + { + diffusion_workspace = + (INT32 *)xalloc((newWidth + 2) * 2 * sizeof(int)); + if (!diffusion_workspace) + { + fprintf(stderr, "Warning: Couldn't allocate diffusion" + " workspace (%ld)\n", + (newWidth + 2) * 2 * (unsigned long)sizeof(int)); + xfree(char_grayscale); + char_grayscale = (unsigned char *)0; + } + /* Initialize our error diffusion workspace for later use */ + bzero((char *)diffusion_workspace + sizeof(INT32), + (newWidth + 3) * sizeof(int)); + thisrow = diffusion_workspace + 1; + nextrow = diffusion_workspace + newWidth + 3; + } else { + fprintf(stderr, "Warning: Couldn't allocate character grayscale (%d)\n", (width + 1) * (height + 1)); + } + } + } + + if (char_grayscale) + { + /* We will be doing antialiasing. First copy the bitmap into + our buffer, mapping input range [0,1] to output range + [0,255]. */ + register unsigned char *srcptr, *dstptr; + srcptr = (unsigned char *)bitmap; + dstptr = char_grayscale; + for (row = 0; row < height; row++) + { + for (col = 0; col < width; col++) + *dstptr++ = (srcptr[col >> 3] & mask[col & 0x7]) ? 255 : 0; + srcptr += bpr; /* On to next row of source */ + dstptr++; /* Skip scratch column in dest */ + } + if (box_x > 1) + { + /* Our box filter has a width > 1... let's filter the rows */ + + int right_width = box_x / 2; + int left_width = box_x - right_width - 1; + + for (row = 0; row < height; row++) + { + int sum = 0; + int left_size = 0, right_size = 0; + + srcptr = char_grayscale + (width + 1) * row; + dstptr = char_grayscale + (width + 1) * height; /* scratch */ + + /* We've computed the shape of our full box filter. Now + compute the right-hand part of the moving sum */ + for (right_size = 0; right_size < right_width; right_size++) + sum += srcptr[right_size]; + + /* Now start moving the sum, growing the box filter, and + dropping averages into our scratch buffer */ + for (left_size = 0; left_size < left_width; left_size++) + { + sum += srcptr[right_width]; + *dstptr++ = sum / (left_size + right_width + 1); + srcptr++; + } + + /* The box filter has reached full width... continue + computation of moving average until the right side + hits the wall. */ + for (col = left_size; col + right_size < width; col++) + { + sum += srcptr[right_width]; + *dstptr++ = sum / box_x; + sum -= srcptr[-left_width]; + srcptr++; + } + + /* Collapse the right side of the box filter */ + for (; right_size > 0; right_size--) + { + *dstptr++ = sum / (left_width + right_size); + sum -= srcptr[-left_width]; + srcptr++; + } + + /* Done with the row... copy dest back over source */ + memmove(char_grayscale + (width + 1) * row, + char_grayscale + (width + 1) * height, + width); + } + } + if (box_y > 1) + { + /* Our box filter has a height > 1... let's filter the columns */ + + int bottom_height = box_y / 2; + int top_height = box_y - bottom_height - 1; + + for (col = 0; col < width; col++) + { + int sum = 0; + int top_size = 0, bottom_size = 0; + + srcptr = char_grayscale + col; + dstptr = char_grayscale + width; /* scratch */ + + /* We've computed the shape of our full box filter. Now + compute the bottom part of the moving sum */ + for (bottom_size = 0; + bottom_size < bottom_height; + bottom_size++) + sum += srcptr[bottom_size * (width + 1)]; + + /* Now start moving the sum, growing the box filter, and + dropping averages into our scratch buffer */ + for (top_size = 0; top_size < top_height; top_size++) + { + sum += srcptr[bottom_height * (width + 1)]; + *dstptr = sum / (top_size + bottom_height + 1); + dstptr += width + 1; + srcptr += width + 1; + } + + /* The box filter has reached full height... continue + computation of moving average until the bottom + hits the wall. */ + for (row = top_size; row + bottom_size < height; row++) + { + sum += srcptr[bottom_height * (width + 1)]; + *dstptr = sum / box_y; + dstptr += width + 1; + sum -= srcptr[-top_height * (width + 1)]; + srcptr += width + 1; + } + + /* Collapse the bottom of the box filter */ + for (; bottom_size > 0; bottom_size--) + { + *dstptr = sum / (top_height + bottom_size); + dstptr += width + 1; + sum -= srcptr[-top_height * (width + 1)]; + srcptr += width + 1; + } + + /* Done with the column... copy dest back over source */ + + dstptr = char_grayscale + col; + srcptr = char_grayscale + width; /* scratch */ + for (row = 0; row < height; row++) + { + *dstptr = *srcptr; + dstptr += width + 1; + srcptr += width + 1; + } + } + } + + /* Increase the grayvalue to increase ink a bit */ + srcptr = char_grayscale; + for (row = 0; row < height; row++) + { + for (col = 0; col < width; col++) + { + register int pixvalue = (int)*srcptr * pixmult / 256; + if (pixvalue > 255) pixvalue = 255; + *srcptr = pixvalue; + srcptr++; + } + srcptr++; + } + } + + /* Compute the increment values for the resampling loop */ + TRANSFORM_POINT(inv_xform, 1, 0, point); + deltaX = (INT32)(point[0] * 65536.0); + deltaY = (INT32)(-point[1] * 65536.0); + + /* Resampling loop: resamples original glyph for generation of new + glyph in transformed coordinate system. */ + + for (row = 0; row < newHeight; row++) + { + /* Compute inverse transformation for start of this row */ + TRANSFORM_POINT(inv_xform, + (double)(pci->metrics.leftSideBearing) + .5, + (double)(pci->metrics.ascent - row) - .5, + point); + + /* Adjust for coordinate system to get resampling point */ + point[0] -= opci->metrics.leftSideBearing; + point[1] = opci->metrics.ascent - point[1]; + + /* Convert to integer coordinates */ + xValue = (INT32)(point[0] * 65536.0); + yValue = (INT32)(point[1] * 65536.0); + + if (char_grayscale) + { + INT32 *temp; + for (col = 0; col < newWidth; col++) + { + register int x = xValue >> 16, y = yValue >> 16; + int pixvalue, error; + + pixvalue = ((x >= 0 && x < width && y >= 0 && y < height) ? + char_grayscale[x + y * (width + 1)] : 0) + + thisrow[col] / 16; + if (pixvalue > 255) pixvalue = 255; + else if (pixvalue < 0) pixvalue = 0; + + /* Choose the bit value and set resulting error value */ + if (pixvalue >= 128) + { + newBitmap[(col >> 3) + row * newBpr] |= mask[col & 0x7]; + error = pixvalue - 255; + } + else + error = -pixvalue; + + /* Diffuse the error */ + thisrow[col + 1] += error * 7; + nextrow[col - 1] += error * 3; + nextrow[col] += error * 5; + nextrow[col + 1] = error; + + xValue += deltaX; + yValue += deltaY; + } + + /* Add in error values that fell off either end */ + nextrow[0] += nextrow[-1]; + nextrow[newWidth - 2] += thisrow[newWidth]; + nextrow[newWidth - 1] += nextrow[newWidth]; + nextrow[newWidth] = 0; + + temp = nextrow; + nextrow = thisrow; + thisrow = temp; + nextrow[-1] = nextrow[0] = 0; + } + else + { + for (col = 0; col < newWidth; col++) + { + register int x = xValue >> 16, y = yValue >> 16; + + if (x >= 0 && x < width && y >= 0 && y < height) + { + /* Use point-sampling for rescaling. */ + + if (bitmap[(x >> 3) + y * bpr] & mask[x & 0x7]) + newBitmap[(col >> 3) + row * newBpr] |= mask[col & 0x7]; + } + + xValue += deltaX; + yValue += deltaY; + } + } + } + + + if (char_grayscale) + { + xfree(char_grayscale); + xfree(diffusion_workspace); + } +} + +static FontPtr +BitmapScaleBitmaps(FontPtr pf, /* scaled font */ + FontPtr opf, /* originating font */ + double widthMult, /* glyphs width scale factor */ + double heightMult, /* glyphs height scale factor */ + FontScalablePtr vals) +{ + register int i; + int nchars = 0; + char *glyphBytes; + BitmapFontPtr bitmapFont, + obitmapFont; + CharInfoPtr pci, + opci; + FontInfoPtr pfi; + int glyph; + unsigned bytestoalloc = 0; + int firstCol, lastCol, firstRow, lastRow; + + double xform[4], inv_xform[4]; + double xmult, ymult; + + bitmapFont = (BitmapFontPtr) pf->fontPrivate; + obitmapFont = (BitmapFontPtr) opf->fontPrivate; + + if (!compute_xform_matrix(vals, widthMult, heightMult, xform, + inv_xform, &xmult, &ymult)) + goto bail; + + pfi = &pf->info; + firstCol = pfi->firstCol; + lastCol = pfi->lastCol; + firstRow = pfi->firstRow; + lastRow = pfi->lastRow; + + nchars = (lastRow - firstRow + 1) * (lastCol - firstCol + 1); + glyph = pf->glyph; + for (i = 0; i < nchars; i++) + { + if ((pci = ACCESSENCODING(bitmapFont->encoding, i))) + bytestoalloc += BYTES_FOR_GLYPH(pci, glyph); + } + + /* Do we add the font malloc stuff for VALUE ADDED ? */ + /* Will need to remember to free in the Unload routine */ + + + bitmapFont->bitmaps = (char *) xalloc(bytestoalloc); + if (!bitmapFont->bitmaps) { + fprintf(stderr, "Error: Couldn't allocate bitmaps (%d)\n", bytestoalloc); + goto bail; + } + bzero(bitmapFont->bitmaps, bytestoalloc); + + glyphBytes = bitmapFont->bitmaps; + for (i = 0; i < nchars; i++) + { + if ((pci = ACCESSENCODING(bitmapFont->encoding, i)) && + (opci = ACCESSENCODING(obitmapFont->encoding, OLDINDEX(i)))) + { + pci->bits = glyphBytes; + ScaleBitmap (pf, opci, pci, inv_xform, + widthMult, heightMult); + glyphBytes += BYTES_FOR_GLYPH(pci, glyph); + } + } + return pf; + +bail: + if (pf) + xfree(pf); + if (bitmapFont) { + xfree(bitmapFont->metrics); + xfree(bitmapFont->ink_metrics); + xfree(bitmapFont->bitmaps); + if(bitmapFont->encoding) + for(i=0; i<NUM_SEGMENTS(nchars); i++) + xfree(bitmapFont->encoding[i]); + xfree(bitmapFont->encoding); + } + return NULL; +} + +static FontPtr +PrinterScaleBitmaps(FontPtr pf, /* scaled font */ + FontPtr opf, /* originating font */ + double widthMult, /* glyphs width scale factor */ + double heightMult, /* glyphs height scale factor */ + FontScalablePtr vals) +{ + register int i; + int nchars = 0; + char *glyphBytes; + BitmapFontPtr bitmapFont, + obitmapFont; + CharInfoPtr pci; + FontInfoPtr pfi; + int glyph; + unsigned bytestoalloc = 0; + int firstCol, lastCol, firstRow, lastRow; + + double xform[4], inv_xform[4]; + double xmult, ymult; + + bitmapFont = (BitmapFontPtr) pf->fontPrivate; + obitmapFont = (BitmapFontPtr) opf->fontPrivate; + + if (!compute_xform_matrix(vals, widthMult, heightMult, xform, + inv_xform, &xmult, &ymult)) + goto bail; + + pfi = &pf->info; + firstCol = pfi->firstCol; + lastCol = pfi->lastCol; + firstRow = pfi->firstRow; + lastRow = pfi->lastRow; + + nchars = (lastRow - firstRow + 1) * (lastCol - firstCol + 1); + glyph = pf->glyph; + for (i = 0; i < nchars; i++) + { + if ((pci = ACCESSENCODING(bitmapFont->encoding, i))) + bytestoalloc = MAX(bytestoalloc,BYTES_FOR_GLYPH(pci, glyph)); + } + + /* Do we add the font malloc stuff for VALUE ADDED ? */ + /* Will need to remember to free in the Unload routine */ + + + bitmapFont->bitmaps = (char *) xalloc(bytestoalloc); + if (!bitmapFont->bitmaps) { + fprintf(stderr, "Error: Couldn't allocate bitmaps (%d)\n", bytestoalloc); + goto bail; + } + bzero(bitmapFont->bitmaps, bytestoalloc); + + glyphBytes = bitmapFont->bitmaps; + for (i = 0; i < nchars; i++) + { + if ((pci = ACCESSENCODING(bitmapFont->encoding, i)) && + (ACCESSENCODING(obitmapFont->encoding, OLDINDEX(i)))) + { + pci->bits = glyphBytes; + } + } + return pf; + +bail: + if (pf) + xfree(pf); + if (bitmapFont) { + xfree(bitmapFont->metrics); + xfree(bitmapFont->ink_metrics); + xfree(bitmapFont->bitmaps); + if(bitmapFont->encoding) + for(i=0; i<NUM_SEGMENTS(nchars); i++) + xfree(bitmapFont->encoding[i]); + xfree(bitmapFont->encoding); + } + return NULL; +} + +#ifdef NOTDEF +/* + * exported interfaces + */ + +FontFileLoadName(FontFileDirPtr *dirs, int ndirs, char *name, FontPtr *pfont, + fsBitmapFormat format, fsBitmapFormatMask fmask) +{ + FontFileNamePtr fname; + char full_name[1024]; + int ret = BadFontName; + int i; + + i = 0; + while (i < ndirs) { + if (fname = FontFileFindNameInDir(dirs[i], name)) { + if (!fname->alias) { + if (!fname->font) { + strcpy(full_name, dirs[i]->dir); + strcat(full_name, fname->file); + ret = FontFileLoad(pfont, full_name, format, fmask); + if (ret == Successful) { + fname->font = *pfont; + (*pfont)->fpePrivate = (pointer) fname; + } + return ret; + } + *pfont = fname->font; + return Successful; + } + name = fname->file; + i = 0; + } else + i++; + } + return BadFontName; +} +#endif + +/* ARGSUSED */ +int +BitmapOpenScalable (FontPathElementPtr fpe, + FontPtr *pFont, + int flags, + FontEntryPtr entry, + char *fileName, /* unused */ + FontScalablePtr vals, + fsBitmapFormat format, + fsBitmapFormatMask fmask, + FontPtr non_cachable_font) /* We don't do licensing */ +{ + FontScalableRec best; + FontPtr font = NullFont; + double dx, sdx, + dy, sdy, + savedX, savedY; + FontPropPtr props; + char *isStringProp; + int propCount; + int status; + long sWidth; + + FontEntryPtr scaleFrom; + FontPathElementPtr scaleFPE; + FontPtr sourceFont; + char fontName[MAXFONTNAMELEN]; + + /* Can't deal with mix-endian fonts yet */ + +#ifdef NOTDEF /* XXX need better test */ + if ((format & BitmapFormatByteOrderMask) != + (format & BitmapFormatBitOrderMask)) + return NullFontFileName; +#endif + + /* Reject outrageously small font sizes to keep the math from + blowing up. */ + if (get_matrix_vertical_component(vals->pixel_matrix) < 1.0 || + get_matrix_horizontal_component(vals->pixel_matrix) < 1.0) + return BadFontName; + + scaleFrom = (*find_scale[BitmapGetRenderIndex(entry->u.bitmap.renderer)]) + (fpe, entry, vals, &best, &dx, &dy, &sdx, &sdy, &scaleFPE); + + if (!scaleFrom) + return BadFontName; + + status = FontFileOpenBitmap(scaleFPE, &sourceFont, LoadAll, scaleFrom, + format, fmask); + + if (status != Successful) + return BadFontName; + + if (!vals->width) + vals->width = best.width * dx; + + /* Compute the scaled font */ + + savedX = dx; + savedY = dy; + font = ScaleFont(sourceFont, dx, dy, sdx, sdy, vals, &dx, &dy, &sWidth); + if (font) + font = (*scale[ BitmapGetRenderIndex(entry->u.bitmap.renderer) ]) + (font, sourceFont, savedX, savedY, vals); + + if (!font) + { + if (!sourceFont->refcnt) + FontFileCloseFont((FontPathElementPtr) 0, sourceFont); + return AllocError; + } + + /* Prepare font properties for the new font */ + + strcpy (fontName, scaleFrom->name.name); + FontParseXLFDName (fontName, vals, FONT_XLFD_REPLACE_VALUE); + + propCount = ComputeScaledProperties(&sourceFont->info, fontName, vals, + dx, dy, sdx, sdy, sWidth, &props, + &isStringProp); + + if (!sourceFont->refcnt) + FontFileCloseFont((FontPathElementPtr) 0, sourceFont); + + if (propCount && (!props || !isStringProp)) + { + font->info.nprops = 0; + font->info.props = (FontPropPtr)0; + font->info.isStringProp = (char *)0; + bitmapUnloadScalable(font); + return AllocError; + } + + font->info.props = props; + font->info.nprops = propCount; + font->info.isStringProp = isStringProp; + + *pFont = font; + return Successful; +} + +int +BitmapGetInfoScalable (FontPathElementPtr fpe, + FontInfoPtr pFontInfo, + FontEntryPtr entry, + FontNamePtr fontName, + char *fileName, + FontScalablePtr vals) +{ + FontPtr pfont; + int flags = 0; + long format = 0; /* It doesn't matter what format for just info */ + long fmask = 0; + int ret; + + ret = BitmapOpenScalable(fpe, &pfont, flags, entry, fileName, vals, + format, fmask, NULL); + if (ret != Successful) + return ret; + *pFontInfo = pfont->info; + + pfont->info.nprops = 0; + pfont->info.props = NULL; + pfont->info.isStringProp = NULL; + + (*pfont->unload_font)(pfont); + return Successful; +} + +static void +bitmapUnloadScalable (FontPtr pFont) +{ + BitmapFontPtr bitmapFont; + FontInfoPtr pfi; + int i, nencoding; + + bitmapFont = (BitmapFontPtr) pFont->fontPrivate; + pfi = &pFont->info; + xfree (pfi->props); + xfree (pfi->isStringProp); + if(bitmapFont->encoding) { + nencoding = (pFont->info.lastCol - pFont->info.firstCol + 1) * + (pFont->info.lastRow - pFont->info.firstRow + 1); + for(i=0; i<NUM_SEGMENTS(nencoding); i++) + xfree(bitmapFont->encoding[i]); + } + xfree (bitmapFont->encoding); + xfree (bitmapFont->bitmaps); + xfree (bitmapFont->ink_metrics); + xfree (bitmapFont->metrics); + xfree (pFont->fontPrivate); + DestroyFontRec (pFont); +} diff --git a/nx-X11/lib/font/bitmap/fontink.c b/nx-X11/lib/font/bitmap/fontink.c new file mode 100644 index 000000000..a9606f039 --- /dev/null +++ b/nx-X11/lib/font/bitmap/fontink.c @@ -0,0 +1,219 @@ +/* $Xorg: fontink.c,v 1.4 2001/02/09 02:04:02 xorgcvs Exp $ */ + +/* + +Copyright 1990, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + +*/ +/* $XFree86: xc/lib/font/bitmap/fontink.c,v 1.6 2001/01/17 19:43:27 dawes Exp $ */ + +/* + * Author: Keith Packard, MIT X Consortium + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <X11/fonts/fntfilst.h> +#include <X11/fonts/bitmap.h> +#include <X11/fonts/bdfint.h> + +static unsigned char ink_mask_msb[8] = { + 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, +}; + +static unsigned char ink_mask_lsb[8] = { + 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, +}; + +void +FontCharInkMetrics(FontPtr pFont, CharInfoPtr pCI, xCharInfo *pInk) +{ + int leftBearing, + ascent, + descent; + register int vpos, + hpos, + bpos = 0; + int bitmapByteWidth, + bitmapByteWidthPadded; + int bitmapBitWidth; + int span; + register unsigned char *p; + unsigned char *ink_mask = 0; + register int bmax; + register unsigned char charbits; + + if (pFont->bit == MSBFirst) + ink_mask = ink_mask_msb; + else if (pFont->bit == LSBFirst) + ink_mask = ink_mask_lsb; + pInk->characterWidth = pCI->metrics.characterWidth; + pInk->attributes = pCI->metrics.attributes; + + leftBearing = pCI->metrics.leftSideBearing; + ascent = pCI->metrics.ascent; + descent = pCI->metrics.descent; + bitmapBitWidth = GLYPHWIDTHPIXELS(pCI); + bitmapByteWidth = GLYPHWIDTHBYTES(pCI); + bitmapByteWidthPadded = BYTES_PER_ROW(bitmapBitWidth, pFont->glyph); + span = bitmapByteWidthPadded - bitmapByteWidth; + + p = (unsigned char *) pCI->bits; + for (vpos = descent + ascent; --vpos >= 0;) { + for (hpos = bitmapByteWidth; --hpos >= 0;) { + if (*p++ != 0) + goto found_ascent; + } + p += span; + } + /* + * special case -- font with no bits gets all zeros + */ + pInk->leftSideBearing = leftBearing; + pInk->rightSideBearing = leftBearing; + pInk->ascent = 0; + pInk->descent = 0; + return; +found_ascent: + pInk->ascent = vpos - descent + 1; + + p = ((unsigned char *) pCI->bits) + bitmapByteWidthPadded * + (descent + ascent - 1) + bitmapByteWidth; + + for (vpos = descent + ascent; --vpos >= 0;) { + for (hpos = bitmapByteWidth; --hpos >= 0;) { + if (*--p != 0) + goto found_descent; + } + p -= span; + } +found_descent: + pInk->descent = vpos - ascent + 1; + + bmax = 8; + for (hpos = 0; hpos < bitmapByteWidth; hpos++) { + charbits = 0; + p = (unsigned char *) pCI->bits + hpos; + for (vpos = descent + ascent; --vpos >= 0; p += bitmapByteWidthPadded) + charbits |= *p; + if (charbits) { + if (hpos == bitmapByteWidth - 1) + bmax = bitmapBitWidth - (hpos << 3); + p = ink_mask; + for (bpos = bmax; --bpos >= 0;) { + if (charbits & *p++) + goto found_left; + } + } + } +found_left: + pInk->leftSideBearing = leftBearing + (hpos << 3) + bmax - bpos - 1; + + bmax = bitmapBitWidth - ((bitmapByteWidth - 1) << 3); + for (hpos = bitmapByteWidth; --hpos >= 0;) { + charbits = 0; + p = (unsigned char *) pCI->bits + hpos; + for (vpos = descent + ascent; --vpos >= 0; p += bitmapByteWidthPadded) + charbits |= *p; + if (charbits) { + p = ink_mask + bmax; + for (bpos = bmax; --bpos >= 0;) { + if (charbits & *--p) + goto found_right; + } + } + bmax = 8; + } +found_right: + pInk->rightSideBearing = leftBearing + (hpos << 3) + bpos + 1; +} + +#define ISBITONMSB(x, line) ((line)[(x)/8] & (1 << (7-((x)%8)))) +#define SETBITMSB(x, line) ((line)[(x)/8] |= (1 << (7-((x)%8)))) +#define ISBITONLSB(x, line) ((line)[(x)/8] & (1 << ((x)%8))) +#define SETBITLSB(x, line) ((line)[(x)/8] |= (1 << ((x)%8))) + +#define Min(a,b) ((a)<(b)?(a):(b)) +#define Max(a,b) ((a)>(b)?(a):(b)) + +void +FontCharReshape(FontPtr pFont, CharInfoPtr pSrc, CharInfoPtr pDst) +{ + int x, + y; + unsigned char *in_line, + *out_line; + unsigned char *oldglyph, + *newglyph; + int inwidth; + int outwidth, + outheight; + int out_bytes, + in_bytes; + int y_min, + y_max, + x_min, + x_max; + + newglyph = (unsigned char *) pDst->bits; + outwidth = pDst->metrics.rightSideBearing - pDst->metrics.leftSideBearing; + outheight = pDst->metrics.descent + pDst->metrics.ascent; + out_bytes = BYTES_PER_ROW(outwidth, pFont->glyph); + + oldglyph = (unsigned char *) pSrc->bits; + inwidth = pSrc->metrics.rightSideBearing - pSrc->metrics.leftSideBearing; + in_bytes = BYTES_PER_ROW(inwidth, pFont->glyph); + + bzero(newglyph, out_bytes * outheight); + in_line = oldglyph; + out_line = newglyph; + y_min = Max(-pSrc->metrics.ascent, -pDst->metrics.ascent); + y_max = Min(pSrc->metrics.descent, pDst->metrics.descent); + x_min = Max(pSrc->metrics.leftSideBearing, pDst->metrics.leftSideBearing); + x_max = Min(pSrc->metrics.rightSideBearing, pDst->metrics.rightSideBearing); + in_line += (y_min + pSrc->metrics.ascent) * in_bytes; + out_line += (y_min + pDst->metrics.ascent) * out_bytes; + if (pFont->bit == MSBFirst) { + for (y = y_min; y < y_max; y++) { + for (x = x_min; x < x_max; x++) { + if (ISBITONMSB(x - pSrc->metrics.leftSideBearing, in_line)) + SETBITMSB(x - pDst->metrics.leftSideBearing, out_line); + } + in_line += in_bytes; + out_line += out_bytes; + } + } else { + for (y = y_min; y < y_max; y++) { + for (x = x_min; x < x_max; x++) { + if (ISBITONLSB(x - pSrc->metrics.leftSideBearing, in_line)) + SETBITLSB(x - pDst->metrics.leftSideBearing, out_line); + } + in_line += in_bytes; + out_line += out_bytes; + } + } +} diff --git a/nx-X11/lib/font/bitmap/module/Imakefile b/nx-X11/lib/font/bitmap/module/Imakefile new file mode 100644 index 000000000..29a49c644 --- /dev/null +++ b/nx-X11/lib/font/bitmap/module/Imakefile @@ -0,0 +1,45 @@ +XCOMM $XFree86: xc/lib/font/bitmap/module/Imakefile,v 1.5 1999/12/03 19:17:18 eich Exp $ + +#define IHaveModules +#include <Server.tmpl> + + INCLUDES = -I$(FONTINCSRC) -I../../include -I$(SERVERSRC)/include \ + -I$(XINCLUDESRC) -I../ + HEADERS = + DEFINES = -DFONTMODULE -DBDFFORMAT -DSNFFORMAT -DPCFFORMAT + +#ifdef FontFormatDefines + FORMAT_DEFS = FontFormatDefines +#endif +#if GzipFontCompression + GZIP_DEFS = -DX_GZIP_FONT_COMPRESSION +#endif + + SRCS = bdfread.c bdfutils.c bitmap.c bitmaputil.c bitscale.c \ + bitmapfunc.c pcfread.c pcfwrite.c snfread.c \ + fontink.c bitmapmod.c + + OBJS = bdfread.o bdfutils.o bitmap.o bitmaputil.o bitscale.o \ + bitmapfunc.o pcfread.o pcfwrite.o snfread.o \ + fontink.o bitmapmod.o + +SpecialCObjectRule(bitmapfunc,$(ICONFIGFILES),$(GZIP_DEFS)) + +LinkSourceFile(bdfread.c,..) +LinkSourceFile(bdfutils.c,..) +LinkSourceFile(bitmap.c,..) +LinkSourceFile(bitmaputil.c,..) +LinkSourceFile(bitscale.c,..) +LinkSourceFile(bitmapfunc.c,..) +LinkSourceFile(pcfread.c,..) +LinkSourceFile(pcfwrite.c,..) +LinkSourceFile(snfread.c,..) +LinkSourceFile(fontink.c,..) + +ModuleObjectRule() +LibraryModuleTarget(bitmap,$(OBJS)) +InstallLibraryModule(bitmap,$(MODULEDIR),fonts) + +DependTarget() + +InstallDriverSDKLibraryModule(bitmap,$(DRIVERSDKMODULEDIR),fonts) diff --git a/nx-X11/lib/font/bitmap/module/bitmapmod.c b/nx-X11/lib/font/bitmap/module/bitmapmod.c new file mode 100644 index 000000000..0ae9ff7ad --- /dev/null +++ b/nx-X11/lib/font/bitmap/module/bitmapmod.c @@ -0,0 +1,76 @@ +/* + * Copyright (C) 1998 The XFree86 Project, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of the XFree86 Project shall + * not be used in advertising or otherwise to promote the sale, use or other + * dealings in this Software without prior written authorization from the + * XFree86 Project. + */ +/* $XFree86: xc/lib/font/bitmap/module/bitmapmod.c,v 1.7 1999/01/26 05:53:47 dawes Exp $ */ + +#ifdef HAVE_XORG_CONFIG_H +#include <xorg-config.h> +#endif + +#include <X11/Xdefs.h> + +#include <X11/fonts/fontmod.h> +#include "xf86Module.h" + +static MODULESETUPPROTO(bitmapSetup); + + /* + * This is the module data function that is accessed when loading + * libbitmap as a module. + */ + +static XF86ModuleVersionInfo VersRec = +{ + "bitmap", + MODULEVENDORSTRING, + MODINFOSTRING1, + MODINFOSTRING2, + XORG_VERSION_CURRENT, + 1, 0, 0, + ABI_CLASS_FONT, /* Font module */ + ABI_FONT_VERSION, + MOD_CLASS_FONT, + {0,0,0,0} /* signature, to be patched into the file by a tool */ +}; + +XF86ModuleData bitmapModuleData = { &VersRec, bitmapSetup, NULL }; + +extern void BitmapRegisterFontFileFunctions(void); + +FontModule bitmapModule = { + BitmapRegisterFontFileFunctions, + "Bitmap", + NULL +}; + +static pointer +bitmapSetup(pointer mod, pointer opts, int *errmaj, int *errmin) +{ + bitmapModule.module = mod; + LoadFont(&bitmapModule); + + /* Need a non-NULL return */ + return (pointer)1; +} diff --git a/nx-X11/lib/font/bitmap/pcf.h b/nx-X11/lib/font/bitmap/pcf.h new file mode 100644 index 000000000..33b0ceff1 --- /dev/null +++ b/nx-X11/lib/font/bitmap/pcf.h @@ -0,0 +1,100 @@ +/* $Xorg: pcf.h,v 1.4 2001/02/09 02:04:02 xorgcvs Exp $ */ + +/* + +Copyright 1991, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + +*/ +/* $XFree86: xc/lib/font/bitmap/pcf.h,v 1.4 2001/12/14 19:56:47 dawes Exp $ */ + +/* + * Author: Keith Packard, MIT X Consortium + */ + +#ifndef _PCF_H_ +#define _PCF_H_ + +/* + * Information used to read/write PCF fonts + */ + +typedef struct _PCFTable { + CARD32 type; + CARD32 format; + CARD32 size; + CARD32 offset; +} PCFTableRec, *PCFTablePtr; + +#define PCF_FILE_VERSION (('p'<<24)|('c'<<16)|('f'<<8)|1) +#define PCF_FORMAT_MASK 0xffffff00 + +#define PCF_DEFAULT_FORMAT 0x00000000 +#define PCF_INKBOUNDS 0x00000200 +#define PCF_ACCEL_W_INKBOUNDS 0x00000100 +#define PCF_COMPRESSED_METRICS 0x00000100 + +#define PCF_FORMAT_MATCH(a,b) (((a)&PCF_FORMAT_MASK) == ((b)&PCF_FORMAT_MASK)) + +#define PCF_GLYPH_PAD_MASK (3<<0) +#define PCF_BYTE_MASK (1<<2) +#define PCF_BIT_MASK (1<<3) +#define PCF_SCAN_UNIT_MASK (3<<4) + +#define PCF_BYTE_ORDER(f) (((f) & PCF_BYTE_MASK)?MSBFirst:LSBFirst) +#define PCF_BIT_ORDER(f) (((f) & PCF_BIT_MASK)?MSBFirst:LSBFirst) +#define PCF_GLYPH_PAD_INDEX(f) ((f) & PCF_GLYPH_PAD_MASK) +#define PCF_GLYPH_PAD(f) (1<<PCF_GLYPH_PAD_INDEX(f)) +#define PCF_SCAN_UNIT_INDEX(f) (((f) & PCF_SCAN_UNIT_MASK) >> 4) +#define PCF_SCAN_UNIT(f) (1<<PCF_SCAN_UNIT_INDEX(f)) +#define PCF_FORMAT_BITS(f) ((f) & (PCF_GLYPH_PAD_MASK|PCF_BYTE_MASK|PCF_BIT_MASK|PCF_SCAN_UNIT_MASK)) + +#define PCF_SIZE_TO_INDEX(s) ((s) == 4 ? 2 : (s) == 2 ? 1 : 0) +#define PCF_INDEX_TO_SIZE(b) (1<<b) + +#define PCF_FORMAT(bit,byte,glyph,scan) (\ + (PCF_SIZE_TO_INDEX(scan) << 4) | \ + (((bit) == MSBFirst ? 1 : 0) << 3) | \ + (((byte) == MSBFirst ? 1 : 0) << 2) | \ + (PCF_SIZE_TO_INDEX(glyph) << 0)) + +#define PCF_PROPERTIES (1<<0) +#define PCF_ACCELERATORS (1<<1) +#define PCF_METRICS (1<<2) +#define PCF_BITMAPS (1<<3) +#define PCF_INK_METRICS (1<<4) +#define PCF_BDF_ENCODINGS (1<<5) +#define PCF_SWIDTHS (1<<6) +#define PCF_GLYPH_NAMES (1<<7) +#define PCF_BDF_ACCELERATORS (1<<8) + +extern int pcfReadFont ( FontPtr pFont, FontFilePtr file, + int bit, int byte, int glyph, int scan ); +extern int pcfReadFontInfo ( FontInfoPtr pFontInfo, FontFilePtr file ); +extern int pmfReadFont ( FontPtr pFont, FontFilePtr file, + int bit, int byte, int glyph, int scan ); +extern int pcfWriteFont ( FontPtr pFont, FontFilePtr file ); +extern void pcfError ( const char *, ... ); + +#endif /* _PCF_H_ */ diff --git a/nx-X11/lib/font/bitmap/pcfread.c b/nx-X11/lib/font/bitmap/pcfread.c new file mode 100644 index 000000000..dd76868bf --- /dev/null +++ b/nx-X11/lib/font/bitmap/pcfread.c @@ -0,0 +1,991 @@ +/* $Xorg: pcfread.c,v 1.5 2001/02/09 02:04:02 xorgcvs Exp $ */ +/* + +Copyright 1990, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + +*/ +/* $XFree86: xc/lib/font/bitmap/pcfread.c,v 1.21 2003/11/17 22:20:22 dawes Exp $ */ + +/* + * Author: Keith Packard, MIT X Consortium + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <X11/fonts/fntfilst.h> +#include <X11/fonts/bitmap.h> +#include <X11/fonts/pcf.h> + +#ifndef MAX +#define MAX(a,b) (((a)>(b)) ? a : b) +#endif + +#include <stdarg.h> + +void +pcfError(const char* message, ...) +{ + va_list args; + + va_start(args, message); + + fprintf(stderr, "PCF Error: "); + vfprintf(stderr, message, args); + va_end(args); +} + +/* Read PCF font files */ + +static void pcfUnloadFont ( FontPtr pFont ); +static int position; + + +#define IS_EOF(file) ((file)->eof == BUFFILEEOF) + +#define FONT_FILE_GETC_ERR(f) (tmp = FontFileGetc(f), BAIL_ON_EOF) + +static int +pcfGetLSB32(FontFilePtr file) +{ + int c; + + c = FontFileGetc(file); + c |= FontFileGetc(file) << 8; + c |= FontFileGetc(file) << 16; + c |= FontFileGetc(file) << 24; + position += 4; + return c; +} + +static int +pcfGetINT32(FontFilePtr file, CARD32 format) +{ + int c; + + if (PCF_BYTE_ORDER(format) == MSBFirst) { + c = FontFileGetc(file) << 24; + c |= FontFileGetc(file) << 16; + c |= FontFileGetc(file) << 8; + c |= FontFileGetc(file); + } else { + c = FontFileGetc(file); + c |= FontFileGetc(file) << 8; + c |= FontFileGetc(file) << 16; + c |= FontFileGetc(file) << 24; + } + position += 4; + return c; +} + +static int +pcfGetINT16(FontFilePtr file, CARD32 format) +{ + int c; + + if (PCF_BYTE_ORDER(format) == MSBFirst) { + c = FontFileGetc(file) << 8; + c |= FontFileGetc(file); + } else { + c = FontFileGetc(file); + c |= FontFileGetc(file) << 8; + } + position += 2; + return c; +} + +#define pcfGetINT8(file, format) (position++, FontFileGetc(file)) + +static PCFTablePtr +pcfReadTOC(FontFilePtr file, int *countp) +{ + CARD32 version; + PCFTablePtr tables; + int count; + int i; + + position = 0; + version = pcfGetLSB32(file); + if (version != PCF_FILE_VERSION) + return (PCFTablePtr) NULL; + count = pcfGetLSB32(file); + if (IS_EOF(file)) return (PCFTablePtr) NULL; + tables = (PCFTablePtr) xalloc(count * sizeof(PCFTableRec)); + if (!tables) { + pcfError("pcfReadTOC(): Couldn't allocate tables (%d*%d)\n", count, sizeof(PCFTableRec)); + return (PCFTablePtr) NULL; + } + for (i = 0; i < count; i++) { + tables[i].type = pcfGetLSB32(file); + tables[i].format = pcfGetLSB32(file); + tables[i].size = pcfGetLSB32(file); + tables[i].offset = pcfGetLSB32(file); + if (IS_EOF(file)) goto Bail; + } + + *countp = count; + return tables; + + Bail: + xfree(tables); + return (PCFTablePtr) NULL; +} + +/* + * PCF supports two formats for metrics, both the regular + * jumbo size, and 'lite' metrics, which are useful + * for most fonts which have even vaguely reasonable + * metrics + */ + +static Bool +pcfGetMetric(FontFilePtr file, CARD32 format, xCharInfo *metric) +{ + metric->leftSideBearing = pcfGetINT16(file, format); + metric->rightSideBearing = pcfGetINT16(file, format); + metric->characterWidth = pcfGetINT16(file, format); + metric->ascent = pcfGetINT16(file, format); + metric->descent = pcfGetINT16(file, format); + metric->attributes = pcfGetINT16(file, format); + if (IS_EOF(file)) return FALSE; + + return TRUE; +} + +static Bool +pcfGetCompressedMetric(FontFilePtr file, CARD32 format, xCharInfo *metric) +{ + metric->leftSideBearing = pcfGetINT8(file, format) - 0x80; + metric->rightSideBearing = pcfGetINT8(file, format) - 0x80; + metric->characterWidth = pcfGetINT8(file, format) - 0x80; + metric->ascent = pcfGetINT8(file, format) - 0x80; + metric->descent = pcfGetINT8(file, format) - 0x80; + metric->attributes = 0; + if (IS_EOF(file)) return FALSE; + + return TRUE; +} + +/* + * Position the file to the begining of the specified table + * in the font file + */ +static Bool +pcfSeekToType(FontFilePtr file, PCFTablePtr tables, int ntables, + CARD32 type, CARD32 *formatp, CARD32 *sizep) +{ + int i; + + for (i = 0; i < ntables; i++) + if (tables[i].type == type) { + if (position > tables[i].offset) + return FALSE; + if (!FontFileSkip(file, tables[i].offset - position)) + return FALSE; + position = tables[i].offset; + *sizep = tables[i].size; + *formatp = tables[i].format; + return TRUE; + } + return FALSE; +} + +static Bool +pcfHasType (PCFTablePtr tables, int ntables, CARD32 type) +{ + int i; + + for (i = 0; i < ntables; i++) + if (tables[i].type == type) + return TRUE; + return FALSE; +} + +/* + * pcfGetProperties + * + * Reads the font properties from the font file, filling in the FontInfo rec + * supplied. Used by by both ReadFont and ReadFontInfo routines. + */ + +static Bool +pcfGetProperties(FontInfoPtr pFontInfo, FontFilePtr file, + PCFTablePtr tables, int ntables) +{ + FontPropPtr props = 0; + int nprops; + char *isStringProp = 0; + CARD32 format; + int i; + CARD32 size; + int string_size; + char *strings; + + /* font properties */ + + if (!pcfSeekToType(file, tables, ntables, PCF_PROPERTIES, &format, &size)) + goto Bail; + format = pcfGetLSB32(file); + if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT)) + goto Bail; + nprops = pcfGetINT32(file, format); + if (IS_EOF(file)) goto Bail; + props = (FontPropPtr) xalloc(nprops * sizeof(FontPropRec)); + if (!props) { + pcfError("pcfGetProperties(): Couldn't allocate props (%d*%d)\n", nprops, sizeof(FontPropRec)); + goto Bail; + } + isStringProp = (char *) xalloc(nprops * sizeof(char)); + if (!isStringProp) { + pcfError("pcfGetProperties(): Couldn't allocate isStringProp (%d*%d)\n", nprops, sizeof(char)); + goto Bail; + } + for (i = 0; i < nprops; i++) { + props[i].name = pcfGetINT32(file, format); + isStringProp[i] = pcfGetINT8(file, format); + props[i].value = pcfGetINT32(file, format); + if (IS_EOF(file)) goto Bail; + } + /* pad the property array */ + /* + * clever here - nprops is the same as the number of odd-units read, as + * only isStringProp are odd length + */ + if (nprops & 3) + { + i = 4 - (nprops & 3); + (void)FontFileSkip(file, i); + position += i; + } + if (IS_EOF(file)) goto Bail; + string_size = pcfGetINT32(file, format); + if (IS_EOF(file)) goto Bail; + strings = (char *) xalloc(string_size); + if (!strings) { + pcfError("pcfGetProperties(): Couldn't allocate strings (%d)\n", string_size); + goto Bail; + } + FontFileRead(file, strings, string_size); + if (IS_EOF(file)) goto Bail; + position += string_size; + for (i = 0; i < nprops; i++) { + props[i].name = MakeAtom(strings + props[i].name, + strlen(strings + props[i].name), TRUE); + if (isStringProp[i]) { + props[i].value = MakeAtom(strings + props[i].value, + strlen(strings + props[i].value), TRUE); + } + } + xfree(strings); + pFontInfo->isStringProp = isStringProp; + pFontInfo->props = props; + pFontInfo->nprops = nprops; + return TRUE; +Bail: + xfree(isStringProp); + xfree(props); + return FALSE; +} + + +/* + * pcfReadAccel + * + * Fill in the accelerator information from the font file; used + * to read both BDF_ACCELERATORS and old style ACCELERATORS + */ + +static Bool +pcfGetAccel(FontInfoPtr pFontInfo, FontFilePtr file, + PCFTablePtr tables, int ntables, CARD32 type) +{ + CARD32 format; + CARD32 size; + + if (!pcfSeekToType(file, tables, ntables, type, &format, &size) || + IS_EOF(file)) + goto Bail; + format = pcfGetLSB32(file); + if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT) && + !PCF_FORMAT_MATCH(format, PCF_ACCEL_W_INKBOUNDS)) + { + goto Bail; + } + pFontInfo->noOverlap = pcfGetINT8(file, format); + pFontInfo->constantMetrics = pcfGetINT8(file, format); + pFontInfo->terminalFont = pcfGetINT8(file, format); + pFontInfo->constantWidth = pcfGetINT8(file, format); + pFontInfo->inkInside = pcfGetINT8(file, format); + pFontInfo->inkMetrics = pcfGetINT8(file, format); + pFontInfo->drawDirection = pcfGetINT8(file, format); + pFontInfo->anamorphic = FALSE; + pFontInfo->cachable = TRUE; + /* natural alignment */ pcfGetINT8(file, format); + pFontInfo->fontAscent = pcfGetINT32(file, format); + pFontInfo->fontDescent = pcfGetINT32(file, format); + pFontInfo->maxOverlap = pcfGetINT32(file, format); + if (IS_EOF(file)) goto Bail; + if (!pcfGetMetric(file, format, &pFontInfo->minbounds)) + goto Bail; + if (!pcfGetMetric(file, format, &pFontInfo->maxbounds)) + goto Bail; + if (PCF_FORMAT_MATCH(format, PCF_ACCEL_W_INKBOUNDS)) { + if (!pcfGetMetric(file, format, &pFontInfo->ink_minbounds)) + goto Bail; + if (!pcfGetMetric(file, format, &pFontInfo->ink_maxbounds)) + goto Bail; + } else { + pFontInfo->ink_minbounds = pFontInfo->minbounds; + pFontInfo->ink_maxbounds = pFontInfo->maxbounds; + } + return TRUE; +Bail: + return FALSE; +} + +int +pcfReadFont(FontPtr pFont, FontFilePtr file, + int bit, int byte, int glyph, int scan) +{ + CARD32 format; + CARD32 size; + BitmapFontPtr bitmapFont = 0; + int i; + PCFTablePtr tables = 0; + int ntables; + int nmetrics; + int nbitmaps; + int sizebitmaps; + int nink_metrics; + CharInfoPtr metrics = 0; + xCharInfo *ink_metrics = 0; + char *bitmaps = 0; + CharInfoPtr **encoding = 0; + int nencoding = 0; + int encodingOffset; + CARD32 bitmapSizes[GLYPHPADOPTIONS]; + CARD32 *offsets = 0; + Bool hasBDFAccelerators; + + pFont->info.nprops = 0; + pFont->info.props = 0; + if (!(tables = pcfReadTOC(file, &ntables))) + goto Bail; + + /* properties */ + + if (!pcfGetProperties(&pFont->info, file, tables, ntables)) + goto Bail; + + /* Use the old accelerators if no BDF accelerators are in the file */ + + hasBDFAccelerators = pcfHasType (tables, ntables, PCF_BDF_ACCELERATORS); + if (!hasBDFAccelerators) + if (!pcfGetAccel (&pFont->info, file, tables, ntables, PCF_ACCELERATORS)) + goto Bail; + + /* metrics */ + + if (!pcfSeekToType(file, tables, ntables, PCF_METRICS, &format, &size)) { + goto Bail; + } + format = pcfGetLSB32(file); + if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT) && + !PCF_FORMAT_MATCH(format, PCF_COMPRESSED_METRICS)) { + goto Bail; + } + if (PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT)) + nmetrics = pcfGetINT32(file, format); + else + nmetrics = pcfGetINT16(file, format); + if (IS_EOF(file)) goto Bail; + metrics = (CharInfoPtr) xalloc(nmetrics * sizeof(CharInfoRec)); + if (!metrics) { + pcfError("pcfReadFont(): Couldn't allocate metrics (%d*%d)\n", nmetrics, sizeof(CharInfoRec)); + goto Bail; + } + for (i = 0; i < nmetrics; i++) + if (PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT)) { + if (!pcfGetMetric(file, format, &(metrics + i)->metrics)) + goto Bail; + } else { + if (!pcfGetCompressedMetric(file, format, &(metrics + i)->metrics)) + goto Bail; + } + + /* bitmaps */ + + if (!pcfSeekToType(file, tables, ntables, PCF_BITMAPS, &format, &size)) + goto Bail; + format = pcfGetLSB32(file); + if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT)) + goto Bail; + + nbitmaps = pcfGetINT32(file, format); + if (nbitmaps != nmetrics || IS_EOF(file)) + goto Bail; + + offsets = (CARD32 *) xalloc(nbitmaps * sizeof(CARD32)); + if (!offsets) { + pcfError("pcfReadFont(): Couldn't allocate offsets (%d*%d)\n", nbitmaps, sizeof(CARD32)); + goto Bail; + } + for (i = 0; i < nbitmaps; i++) { + offsets[i] = pcfGetINT32(file, format); + if (IS_EOF(file)) goto Bail; + } + + for (i = 0; i < GLYPHPADOPTIONS; i++) { + bitmapSizes[i] = pcfGetINT32(file, format); + if (IS_EOF(file)) goto Bail; + } + + sizebitmaps = bitmapSizes[PCF_GLYPH_PAD_INDEX(format)]; + /* guard against completely empty font */ + bitmaps = xalloc(sizebitmaps ? sizebitmaps : 1); + if (!bitmaps) { + pcfError("pcfReadFont(): Couldn't allocate bitmaps (%d)\n", sizebitmaps ? sizebitmaps : 1); + goto Bail; + } + FontFileRead(file, bitmaps, sizebitmaps); + if (IS_EOF(file)) goto Bail; + position += sizebitmaps; + + if (PCF_BIT_ORDER(format) != bit) + BitOrderInvert((unsigned char *)bitmaps, sizebitmaps); + if ((PCF_BYTE_ORDER(format) == PCF_BIT_ORDER(format)) != (bit == byte)) { + switch (bit == byte ? PCF_SCAN_UNIT(format) : scan) { + case 1: + break; + case 2: + TwoByteSwap((unsigned char *)bitmaps, sizebitmaps); + break; + case 4: + FourByteSwap((unsigned char *)bitmaps, sizebitmaps); + break; + } + } + if (PCF_GLYPH_PAD(format) != glyph) { + char *padbitmaps; + int sizepadbitmaps; + int old, + new; + xCharInfo *metric; + + sizepadbitmaps = bitmapSizes[PCF_SIZE_TO_INDEX(glyph)]; + padbitmaps = (char *) xalloc(sizepadbitmaps); + if (!padbitmaps) { + pcfError("pcfReadFont(): Couldn't allocate padbitmaps (%d)\n", sizepadbitmaps); + goto Bail; + } + new = 0; + for (i = 0; i < nbitmaps; i++) { + old = offsets[i]; + metric = &metrics[i].metrics; + offsets[i] = new; + new += RepadBitmap(bitmaps + old, padbitmaps + new, + PCF_GLYPH_PAD(format), glyph, + metric->rightSideBearing - metric->leftSideBearing, + metric->ascent + metric->descent); + } + xfree(bitmaps); + bitmaps = padbitmaps; + } + for (i = 0; i < nbitmaps; i++) + metrics[i].bits = bitmaps + offsets[i]; + + xfree(offsets); + offsets = NULL; + + /* ink metrics ? */ + + ink_metrics = NULL; + if (pcfSeekToType(file, tables, ntables, PCF_INK_METRICS, &format, &size)) { + format = pcfGetLSB32(file); + if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT) && + !PCF_FORMAT_MATCH(format, PCF_COMPRESSED_METRICS)) { + goto Bail; + } + if (PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT)) + nink_metrics = pcfGetINT32(file, format); + else + nink_metrics = pcfGetINT16(file, format); + if (IS_EOF(file)) goto Bail; + if (nink_metrics != nmetrics) + goto Bail; + ink_metrics = (xCharInfo *) xalloc(nink_metrics * sizeof(xCharInfo)); + if (!ink_metrics) { + pcfError("pcfReadFont(): Couldn't allocate ink_metrics (%d*%d)\n", nink_metrics, sizeof(xCharInfo)); + goto Bail; + } + for (i = 0; i < nink_metrics; i++) + if (PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT)) { + if (!pcfGetMetric(file, format, ink_metrics + i)) + goto Bail; + } else { + if (!pcfGetCompressedMetric(file, format, ink_metrics + i)) + goto Bail; + } + } + + /* encoding */ + + if (!pcfSeekToType(file, tables, ntables, PCF_BDF_ENCODINGS, &format, &size)) + goto Bail; + format = pcfGetLSB32(file); + if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT)) + goto Bail; + + pFont->info.firstCol = pcfGetINT16(file, format); + pFont->info.lastCol = pcfGetINT16(file, format); + pFont->info.firstRow = pcfGetINT16(file, format); + pFont->info.lastRow = pcfGetINT16(file, format); + pFont->info.defaultCh = pcfGetINT16(file, format); + if (IS_EOF(file)) goto Bail; + + nencoding = (pFont->info.lastCol - pFont->info.firstCol + 1) * + (pFont->info.lastRow - pFont->info.firstRow + 1); + + encoding = (CharInfoPtr **) xcalloc(NUM_SEGMENTS(nencoding), + sizeof(CharInfoPtr*)); + if (!encoding) { + pcfError("pcfReadFont(): Couldn't allocate encoding (%d*%d)\n", nencoding, sizeof(CharInfoPtr)); + goto Bail; + } + + pFont->info.allExist = TRUE; + for (i = 0; i < nencoding; i++) { + encodingOffset = pcfGetINT16(file, format); + if (IS_EOF(file)) goto Bail; + if (encodingOffset == 0xFFFF) { + pFont->info.allExist = FALSE; + } else { + if(!encoding[SEGMENT_MAJOR(i)]) { + encoding[SEGMENT_MAJOR(i)]= + (CharInfoPtr*)xcalloc(BITMAP_FONT_SEGMENT_SIZE, + sizeof(CharInfoPtr)); + if(!encoding[SEGMENT_MAJOR(i)]) + goto Bail; + } + ACCESSENCODINGL(encoding, i) = metrics + encodingOffset; + } + } + + /* BDF style accelerators (i.e. bounds based on encoded glyphs) */ + + if (hasBDFAccelerators) + if (!pcfGetAccel (&pFont->info, file, tables, ntables, PCF_BDF_ACCELERATORS)) + goto Bail; + + bitmapFont = (BitmapFontPtr) xalloc(sizeof *bitmapFont); + if (!bitmapFont) { + pcfError("pcfReadFont(): Couldn't allocate bitmapFont (%d)\n", sizeof *bitmapFont); + goto Bail; + } + + bitmapFont->version_num = PCF_FILE_VERSION; + bitmapFont->num_chars = nmetrics; + bitmapFont->num_tables = ntables; + bitmapFont->metrics = metrics; + bitmapFont->ink_metrics = ink_metrics; + bitmapFont->bitmaps = bitmaps; + bitmapFont->encoding = encoding; + bitmapFont->pDefault = (CharInfoPtr) 0; + if (pFont->info.defaultCh != (unsigned short) NO_SUCH_CHAR) { + unsigned int r, + c, + cols; + + r = pFont->info.defaultCh >> 8; + c = pFont->info.defaultCh & 0xFF; + if (pFont->info.firstRow <= r && r <= pFont->info.lastRow && + pFont->info.firstCol <= c && c <= pFont->info.lastCol) { + cols = pFont->info.lastCol - pFont->info.firstCol + 1; + r = r - pFont->info.firstRow; + c = c - pFont->info.firstCol; + bitmapFont->pDefault = ACCESSENCODING(encoding, r * cols + c); + } + } + bitmapFont->bitmapExtra = (BitmapExtraPtr) 0; + pFont->fontPrivate = (pointer) bitmapFont; + pFont->get_glyphs = bitmapGetGlyphs; + pFont->get_metrics = bitmapGetMetrics; + pFont->unload_font = pcfUnloadFont; + pFont->unload_glyphs = NULL; + pFont->bit = bit; + pFont->byte = byte; + pFont->glyph = glyph; + pFont->scan = scan; + xfree(tables); + return Successful; +Bail: + xfree(ink_metrics); + if(encoding) { + for(i=0; i<NUM_SEGMENTS(nencoding); i++) + xfree(encoding[i]); + } + xfree(encoding); + xfree(bitmaps); + xfree(metrics); + xfree(pFont->info.props); + pFont->info.nprops = 0; + pFont->info.props = 0; + xfree (pFont->info.isStringProp); + xfree(bitmapFont); + xfree(tables); + xfree(offsets); + return AllocError; +} + +int +pcfReadFontInfo(FontInfoPtr pFontInfo, FontFilePtr file) +{ + PCFTablePtr tables; + int ntables; + CARD32 format; + CARD32 size; + int nencoding; + Bool hasBDFAccelerators; + + pFontInfo->isStringProp = NULL; + pFontInfo->props = NULL; + pFontInfo->nprops = 0; + + if (!(tables = pcfReadTOC(file, &ntables))) + goto Bail; + + /* properties */ + + if (!pcfGetProperties(pFontInfo, file, tables, ntables)) + goto Bail; + + /* Use the old accelerators if no BDF accelerators are in the file */ + + hasBDFAccelerators = pcfHasType (tables, ntables, PCF_BDF_ACCELERATORS); + if (!hasBDFAccelerators) + if (!pcfGetAccel (pFontInfo, file, tables, ntables, PCF_ACCELERATORS)) + goto Bail; + + /* encoding */ + + if (!pcfSeekToType(file, tables, ntables, PCF_BDF_ENCODINGS, &format, &size)) + goto Bail; + format = pcfGetLSB32(file); + if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT)) + goto Bail; + + pFontInfo->firstCol = pcfGetINT16(file, format); + pFontInfo->lastCol = pcfGetINT16(file, format); + pFontInfo->firstRow = pcfGetINT16(file, format); + pFontInfo->lastRow = pcfGetINT16(file, format); + pFontInfo->defaultCh = pcfGetINT16(file, format); + if (IS_EOF(file)) goto Bail; + + nencoding = (pFontInfo->lastCol - pFontInfo->firstCol + 1) * + (pFontInfo->lastRow - pFontInfo->firstRow + 1); + + pFontInfo->allExist = TRUE; + while (nencoding--) { + if (pcfGetINT16(file, format) == 0xFFFF) + pFontInfo->allExist = FALSE; + if (IS_EOF(file)) goto Bail; + } + if (IS_EOF(file)) goto Bail; + + /* BDF style accelerators (i.e. bounds based on encoded glyphs) */ + + if (hasBDFAccelerators) + if (!pcfGetAccel (pFontInfo, file, tables, ntables, PCF_BDF_ACCELERATORS)) + goto Bail; + + xfree(tables); + return Successful; +Bail: + pFontInfo->nprops = 0; + xfree (pFontInfo->props); + xfree (pFontInfo->isStringProp); + xfree(tables); + return AllocError; +} + +static void +pcfUnloadFont(FontPtr pFont) +{ + BitmapFontPtr bitmapFont; + int i,nencoding; + + bitmapFont = (BitmapFontPtr) pFont->fontPrivate; + xfree(bitmapFont->ink_metrics); + if(bitmapFont->encoding) { + nencoding = (pFont->info.lastCol - pFont->info.firstCol + 1) * + (pFont->info.lastRow - pFont->info.firstRow + 1); + for(i=0; i<NUM_SEGMENTS(nencoding); i++) + xfree(bitmapFont->encoding[i]); + } + xfree(bitmapFont->encoding); + xfree(bitmapFont->bitmaps); + xfree(bitmapFont->metrics); + xfree(pFont->info.isStringProp); + xfree(pFont->info.props); + xfree(bitmapFont); + DestroyFontRec(pFont); +} + +int +pmfReadFont(FontPtr pFont, FontFilePtr file, + int bit, int byte, int glyph, int scan) +{ + CARD32 format; + CARD32 size; + BitmapFontPtr bitmapFont = 0; + int i; + PCFTablePtr tables = 0; + int ntables; + int nmetrics; + int sizebitmaps; + int nink_metrics; + CharInfoPtr metrics = 0; + xCharInfo *ink_metrics = 0; + char *bitmaps = 0; + CharInfoPtr **encoding = 0; + int nencoding = 0; + int encodingOffset; + Bool hasBDFAccelerators; + CharInfoPtr pci; + + pFont->info.nprops = 0; + pFont->info.props = 0; + + if (!(tables = pcfReadTOC(file, &ntables))) + goto Bail; + + /* properties */ + + if (!pcfGetProperties(&pFont->info, file, tables, ntables)) + goto Bail; + + /* Use the old accelerators if no BDF accelerators are in the file */ + + hasBDFAccelerators = pcfHasType (tables, ntables, PCF_BDF_ACCELERATORS); + if (!hasBDFAccelerators) + if (!pcfGetAccel (&pFont->info, file, tables, ntables, PCF_ACCELERATORS)) + goto Bail; + + /* metrics */ + + if (!pcfSeekToType(file, tables, ntables, PCF_METRICS, &format, &size)) { + goto Bail; + } + format = pcfGetLSB32(file); + if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT) && + !PCF_FORMAT_MATCH(format, PCF_COMPRESSED_METRICS)) { + goto Bail; + } + if (PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT)) + nmetrics = pcfGetINT32(file, format); + else + nmetrics = pcfGetINT16(file, format); + if (IS_EOF(file)) goto Bail; + metrics = (CharInfoPtr) xalloc(nmetrics * sizeof(CharInfoRec)); + if (!metrics) { + pcfError("pmfReadFont(): Couldn't allocate metrics (%d*%d)\n", nmetrics, sizeof(CharInfoRec)); + goto Bail; + } + for (i = 0; i < nmetrics; i++) + if (PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT)) { + if (!pcfGetMetric(file, format, &(metrics + i)->metrics)) + goto Bail; + } else { + if (!pcfGetCompressedMetric(file, format, &(metrics + i)->metrics)) + goto Bail; + } + + /* Set the bitmaps to all point to the same zero filled array + * that is the size of the largest bitmap. + */ + + pci = metrics; + sizebitmaps = 0; + for (i = 0; i < nmetrics; i++) + { + sizebitmaps = MAX(sizebitmaps,BYTES_FOR_GLYPH(pci, glyph)); + pci++; + } + +#ifdef FONTMODULE + sizebitmaps = 1024; /* Default - we xalloc the size anyway */ +#else + sizebitmaps = BUFSIZ; +#endif + /* guard against completely empty font */ + bitmaps = (char *) xalloc(sizebitmaps); + if (!bitmaps) { + pcfError("pmfReadFont(): Couldn't allocate bitmaps (%d)\n", sizebitmaps); + goto Bail; + } + + memset(bitmaps,0,sizebitmaps); + for (i = 0; i < nmetrics; i++) + metrics[i].bits = bitmaps; + + /* ink metrics ? */ + + ink_metrics = NULL; + if (pcfSeekToType(file, tables, ntables, PCF_INK_METRICS, &format, &size)) { + format = pcfGetLSB32(file); + if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT) && + !PCF_FORMAT_MATCH(format, PCF_COMPRESSED_METRICS)) { + goto Bail; + } + if (PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT)) + nink_metrics = pcfGetINT32(file, format); + else + nink_metrics = pcfGetINT16(file, format); + if (nink_metrics != nmetrics) + goto Bail; + if (IS_EOF(file)) goto Bail; + ink_metrics = (xCharInfo *) xalloc(nink_metrics * sizeof(xCharInfo)); + if (!ink_metrics) { + pcfError("pmfReadFont(): Couldn't allocate ink_metrics (%d*%d)\n", nink_metrics, sizeof(xCharInfo)); + goto Bail; + } + for (i = 0; i < nink_metrics; i++) + if (PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT)) { + if (!pcfGetMetric(file, format, ink_metrics + i)) + goto Bail; + } else { + if (!pcfGetCompressedMetric(file, format, ink_metrics + i)) + goto Bail; + } + } + + /* encoding */ + + if (!pcfSeekToType(file, tables, ntables, PCF_BDF_ENCODINGS, &format, &size)) + goto Bail; + format = pcfGetLSB32(file); + if (!PCF_FORMAT_MATCH(format, PCF_DEFAULT_FORMAT)) + goto Bail; + + pFont->info.firstCol = pcfGetINT16(file, format); + pFont->info.lastCol = pcfGetINT16(file, format); + pFont->info.firstRow = pcfGetINT16(file, format); + pFont->info.lastRow = pcfGetINT16(file, format); + pFont->info.defaultCh = pcfGetINT16(file, format); + if (IS_EOF(file)) goto Bail; + + nencoding = (pFont->info.lastCol - pFont->info.firstCol + 1) * + (pFont->info.lastRow - pFont->info.firstRow + 1); + + encoding = (CharInfoPtr **) xcalloc(NUM_SEGMENTS(nencoding), + sizeof(CharInfoPtr*)); + if (!encoding) { + pcfError("pmfReadFont(): Couldn't allocate encoding (%d*%d)\n", nencoding, sizeof(CharInfoPtr)); + goto Bail; + } + pFont->info.allExist = TRUE; + for (i = 0; i < nencoding; i++) { + encodingOffset = pcfGetINT16(file, format); + if (IS_EOF(file)) goto Bail; + if (encodingOffset == 0xFFFF) { + pFont->info.allExist = FALSE; + } else { + if(!encoding[SEGMENT_MAJOR(i)]) { + encoding[SEGMENT_MAJOR(i)]= + (CharInfoPtr*)xcalloc(BITMAP_FONT_SEGMENT_SIZE, + sizeof(CharInfoPtr)); + if(!encoding[SEGMENT_MAJOR(i)]) + goto Bail; + } + ACCESSENCODINGL(encoding, i) = metrics + encodingOffset; + } + } + if (IS_EOF(file)) goto Bail; + + /* BDF style accelerators (i.e. bounds based on encoded glyphs) */ + + if (hasBDFAccelerators) + if (!pcfGetAccel (&pFont->info, file, tables, ntables, PCF_BDF_ACCELERATORS)) + goto Bail; + + bitmapFont = (BitmapFontPtr) xalloc(sizeof *bitmapFont); + if (!bitmapFont) { + pcfError("pmfReadFont(): Couldn't allocate bitmapFont (%d)\n", sizeof *bitmapFont); + goto Bail; + } + + bitmapFont->version_num = PCF_FILE_VERSION; + bitmapFont->num_chars = nmetrics; + bitmapFont->num_tables = ntables; + bitmapFont->metrics = metrics; + bitmapFont->ink_metrics = ink_metrics; + bitmapFont->bitmaps = bitmaps; + bitmapFont->encoding = encoding; + bitmapFont->pDefault = (CharInfoPtr) 0; + if (pFont->info.defaultCh != (unsigned short) NO_SUCH_CHAR) { + unsigned int r, + c, + cols; + + r = pFont->info.defaultCh >> 8; + c = pFont->info.defaultCh & 0xFF; + if (pFont->info.firstRow <= r && r <= pFont->info.lastRow && + pFont->info.firstCol <= c && c <= pFont->info.lastCol) { + cols = pFont->info.lastCol - pFont->info.firstCol + 1; + r = r - pFont->info.firstRow; + c = c - pFont->info.firstCol; + bitmapFont->pDefault = ACCESSENCODING(encoding, r * cols + c); + } + } + bitmapFont->bitmapExtra = (BitmapExtraPtr) 0; + pFont->fontPrivate = (pointer) bitmapFont; + pFont->get_glyphs = bitmapGetGlyphs; + pFont->get_metrics = bitmapGetMetrics; + pFont->unload_font = pcfUnloadFont; + pFont->unload_glyphs = NULL; + pFont->bit = bit; + pFont->byte = byte; + pFont->glyph = glyph; + pFont->scan = scan; + xfree(tables); + return Successful; +Bail: + xfree(ink_metrics); + if(encoding) { + for(i=0; i<NUM_SEGMENTS(nencoding); i++) + xfree(encoding[i]); + } + xfree(encoding); + xfree(bitmaps); + xfree(metrics); + xfree(pFont->info.props); + pFont->info.nprops = 0; + pFont->info.props = 0; + xfree (pFont->info.isStringProp); + xfree(bitmapFont); + xfree(tables); + return AllocError; +} diff --git a/nx-X11/lib/font/bitmap/pcfwrite.c b/nx-X11/lib/font/bitmap/pcfwrite.c new file mode 100644 index 000000000..8d5e9425f --- /dev/null +++ b/nx-X11/lib/font/bitmap/pcfwrite.c @@ -0,0 +1,468 @@ +/* $Xorg: pcfwrite.c,v 1.5 2001/02/09 02:04:02 xorgcvs Exp $ */ +/* + +Copyright 1990, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + +*/ +/* $XFree86: xc/lib/font/bitmap/pcfwrite.c,v 1.11 2003/11/17 22:20:22 dawes Exp $ */ + +/* + * Author: Keith Packard, MIT X Consortium + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <X11/fonts/fntfilst.h> +#include <X11/fonts/bitmap.h> +#include <X11/fonts/pcf.h> + +/* Write PCF font files */ + +static CARD32 current_position; + +static int +pcfWrite(FontFilePtr file, char *b, int c) +{ + current_position += c; + return FontFileWrite(file, b, c); +} + +static int +pcfPutLSB32(FontFilePtr file, int c) +{ + current_position += 4; + (void) FontFilePutc(c, file); + (void) FontFilePutc(c >> 8, file); + (void) FontFilePutc(c >> 16, file); + return FontFilePutc(c >> 24, file); +} + +static int +pcfPutINT32(FontFilePtr file, CARD32 format, int c) +{ + current_position += 4; + if (PCF_BYTE_ORDER(format) == MSBFirst) { + (void) FontFilePutc(c >> 24, file); + (void) FontFilePutc(c >> 16, file); + (void) FontFilePutc(c >> 8, file); + return FontFilePutc(c, file); + } else { + (void) FontFilePutc(c, file); + (void) FontFilePutc(c >> 8, file); + (void) FontFilePutc(c >> 16, file); + return FontFilePutc(c >> 24, file); + } +} + +static int +pcfPutINT16(FontFilePtr file, CARD32 format, int c) +{ + current_position += 2; + if (PCF_BYTE_ORDER(format) == MSBFirst) { + (void) FontFilePutc(c >> 8, file); + return FontFilePutc(c, file); + } else { + (void) FontFilePutc(c, file); + return FontFilePutc(c >> 8, file); + } +} + +/*ARGSUSED*/ +static int +pcfPutINT8(FontFilePtr file, CARD32 format, int c) +{ + current_position += 1; + return FontFilePutc(c, file); +} + +static void +pcfWriteTOC(FontFilePtr file, PCFTablePtr table, int count) +{ + CARD32 version; + int i; + + version = PCF_FILE_VERSION; + pcfPutLSB32(file, version); + pcfPutLSB32(file, count); + for (i = 0; i < count; i++) { + pcfPutLSB32(file, table->type); + pcfPutLSB32(file, table->format); + pcfPutLSB32(file, table->size); + pcfPutLSB32(file, table->offset); + table++; + } +} + +static void +pcfPutCompressedMetric(FontFilePtr file, CARD32 format, xCharInfo *metric) +{ + pcfPutINT8(file, format, metric->leftSideBearing + 0x80); + pcfPutINT8(file, format, metric->rightSideBearing + 0x80); + pcfPutINT8(file, format, metric->characterWidth + 0x80); + pcfPutINT8(file, format, metric->ascent + 0x80); + pcfPutINT8(file, format, metric->descent + 0x80); +} + +static void +pcfPutMetric(FontFilePtr file, CARD32 format, xCharInfo *metric) +{ + pcfPutINT16(file, format, metric->leftSideBearing); + pcfPutINT16(file, format, metric->rightSideBearing); + pcfPutINT16(file, format, metric->characterWidth); + pcfPutINT16(file, format, metric->ascent); + pcfPutINT16(file, format, metric->descent); + pcfPutINT16(file, format, metric->attributes); +} + +static void +pcfPutBitmap(FontFilePtr file, CARD32 format, CharInfoPtr pCI) +{ + int count; + unsigned char *bits; + + count = BYTES_FOR_GLYPH(pCI, PCF_GLYPH_PAD(format)); + bits = (unsigned char *) pCI->bits; + current_position += count; + while (count--) + FontFilePutc(*bits++, file); +} + +static void +pcfPutAccel(FontFilePtr file, CARD32 format, FontInfoPtr pFontInfo) +{ + pcfPutINT8(file, format, pFontInfo->noOverlap); + pcfPutINT8(file, format, pFontInfo->constantMetrics); + pcfPutINT8(file, format, pFontInfo->terminalFont); + pcfPutINT8(file, format, pFontInfo->constantWidth); + pcfPutINT8(file, format, pFontInfo->inkInside); + pcfPutINT8(file, format, pFontInfo->inkMetrics); + pcfPutINT8(file, format, pFontInfo->drawDirection); + pcfPutINT8(file, format, 0); + pcfPutINT32(file, format, pFontInfo->fontAscent); + pcfPutINT32(file, format, pFontInfo->fontDescent); + pcfPutINT32(file, format, pFontInfo->maxOverlap); + pcfPutMetric(file, format, &pFontInfo->minbounds); + pcfPutMetric(file, format, &pFontInfo->maxbounds); + if (PCF_FORMAT_MATCH(format, PCF_ACCEL_W_INKBOUNDS)) { + pcfPutMetric(file, format, &pFontInfo->ink_minbounds); + pcfPutMetric(file, format, &pFontInfo->ink_maxbounds); + } +} + +#define S32 4 +#define S16 2 +#define S8 1 + +#define Pad(s) (RoundUp(s) - (s)) +#define RoundUp(s) (((s) + 3) & ~3) + +#define Compressable(i) (-128 <= (i) && (i) <= 127) + +#define CanCompressMetric(m) (Compressable((m)->leftSideBearing) && \ + Compressable((m)->rightSideBearing) && \ + Compressable((m)->characterWidth) && \ + Compressable((m)->ascent) && \ + Compressable((m)->descent) && \ + (m)->attributes == 0) + +#define CanCompressMetrics(min,max) (CanCompressMetric(min) && CanCompressMetric(max)) + +static char * +pcfNameForAtom(Atom a) +{ + return NameForAtom(a); +} + +int +pcfWriteFont(FontPtr pFont, FontFilePtr file) +{ + PCFTableRec tables[32], + *table; + CARD32 mask, + bit; + int ntables; + int size; + CARD32 format; + int i; + int cur_table; + int prop_string_size; + int glyph_string_size; + xCharInfo *minbounds, + *maxbounds; + xCharInfo *ink_minbounds, + *ink_maxbounds; + BitmapFontPtr bitmapFont; + int nencodings = 0; + int header_size; + FontPropPtr offsetProps; + int prop_pad = 0; + char *atom_name; + int glyph; + CARD32 offset; + + bitmapFont = (BitmapFontPtr) pFont->fontPrivate; + if (bitmapFont->bitmapExtra) { + minbounds = &bitmapFont->bitmapExtra->info.minbounds; + maxbounds = &bitmapFont->bitmapExtra->info.maxbounds; + ink_minbounds = &bitmapFont->bitmapExtra->info.ink_minbounds; + ink_maxbounds = &bitmapFont->bitmapExtra->info.ink_maxbounds; + } else { + minbounds = &pFont->info.minbounds; + maxbounds = &pFont->info.maxbounds; + ink_minbounds = &pFont->info.ink_minbounds; + ink_maxbounds = &pFont->info.ink_maxbounds; + } + offsetProps = (FontPropPtr) xalloc(pFont->info.nprops * sizeof(FontPropRec)); + if (!offsetProps) { + pcfError("pcfWriteFont(): Couldn't allocate offsetProps (%d*%d)", pFont->info.nprops, sizeof(FontPropRec)); + return AllocError; + } + prop_string_size = 0; + for (i = 0; i < pFont->info.nprops; i++) { + offsetProps[i].name = prop_string_size; + prop_string_size += strlen(pcfNameForAtom(pFont->info.props[i].name)) + 1; + if (pFont->info.isStringProp[i]) { + offsetProps[i].value = prop_string_size; + prop_string_size += strlen(pcfNameForAtom(pFont->info.props[i].value)) + 1; + } else + offsetProps[i].value = pFont->info.props[i].value; + } + format = PCF_FORMAT(pFont->bit, pFont->byte, pFont->glyph, pFont->scan); + mask = 0xFFFFFFF; + ntables = 0; + table = tables; + while (mask) { + bit = lowbit(mask); + mask &= ~bit; + table->type = bit; + switch (bit) { + case PCF_PROPERTIES: + table->format = PCF_DEFAULT_FORMAT | format; + size = S32 + S32 + (S32 + S8 + S32) * pFont->info.nprops; + prop_pad = Pad(size); + table->size = RoundUp(size) + S32 + + RoundUp(prop_string_size); + table++; + break; + case PCF_ACCELERATORS: + if (bitmapFont->bitmapExtra->info.inkMetrics) + table->format = PCF_ACCEL_W_INKBOUNDS | format; + else + table->format = PCF_DEFAULT_FORMAT | format; + table->size = 100; + table++; + break; + case PCF_METRICS: + if (CanCompressMetrics(minbounds, maxbounds)) { + table->format = PCF_COMPRESSED_METRICS | format; + size = S32 + S16 + bitmapFont->num_chars * (5 * S8); + table->size = RoundUp(size); + } else { + table->format = PCF_DEFAULT_FORMAT | format; + table->size = S32 + S32 + bitmapFont->num_chars * (6 * S16); + } + table++; + break; + case PCF_BITMAPS: + table->format = PCF_DEFAULT_FORMAT | format; + size = S32 + S32 + bitmapFont->num_chars * S32 + + GLYPHPADOPTIONS * S32 + + bitmapFont->bitmapExtra->bitmapsSizes[PCF_GLYPH_PAD_INDEX(format)]; + table->size = RoundUp(size); + table++; + break; + case PCF_INK_METRICS: + if (bitmapFont->ink_metrics) { + if (CanCompressMetrics(ink_minbounds, ink_maxbounds)) { + table->format = PCF_COMPRESSED_METRICS | format; + size = S32 + S16 + bitmapFont->num_chars * (5 * S8); + table->size = RoundUp(size); + } else { + table->format = PCF_DEFAULT_FORMAT | format; + table->size = S32 + S32 + bitmapFont->num_chars * (6 * S16); + } + table++; + } + break; + case PCF_BDF_ENCODINGS: + table->format = PCF_DEFAULT_FORMAT | format; + nencodings = (pFont->info.lastRow - pFont->info.firstRow + 1) * + (pFont->info.lastCol - pFont->info.firstCol + 1); + size = S32 + 5 * S16 + nencodings * S16; + table->size = RoundUp(size); + table++; + break; + case PCF_SWIDTHS: + table->format = PCF_DEFAULT_FORMAT | format; + table->size = S32 + S32 + bitmapFont->num_chars * S32; + table++; + break; + case PCF_GLYPH_NAMES: + table->format = PCF_DEFAULT_FORMAT | format; + glyph_string_size = 0; + for (i = 0; i < bitmapFont->num_chars; i++) + glyph_string_size += strlen(pcfNameForAtom(bitmapFont->bitmapExtra->glyphNames[i])) + 1; + table->size = S32 + S32 + bitmapFont->num_chars * S32 + + S32 + RoundUp(glyph_string_size); + table++; + break; + case PCF_BDF_ACCELERATORS: + if (pFont->info.inkMetrics) + table->format = PCF_ACCEL_W_INKBOUNDS | format; + else + table->format = PCF_DEFAULT_FORMAT | format; + table->size = 100; + table++; + break; + } + } + ntables = table - tables; + offset = 0; + header_size = S32 + S32 + ntables * (4 * S32); + offset = header_size; + for (cur_table = 0, table = tables; + cur_table < ntables; + cur_table++, table++) { + table->offset = offset; + offset += table->size; + } + current_position = 0; + pcfWriteTOC(file, tables, ntables); + for (cur_table = 0, table = tables; + cur_table < ntables; + cur_table++, table++) { + if (current_position > table->offset) { + printf("can't go backwards... %d > %d\n", + (int)current_position, (int)table->offset); + xfree(offsetProps); + return BadFontName; + } + while (current_position < table->offset) + pcfPutINT8(file, format, '\0'); + pcfPutLSB32(file, table->format); + switch (table->type) { + case PCF_PROPERTIES: + pcfPutINT32(file, format, pFont->info.nprops); + for (i = 0; i < pFont->info.nprops; i++) { + pcfPutINT32(file, format, offsetProps[i].name); + pcfPutINT8(file, format, pFont->info.isStringProp[i]); + pcfPutINT32(file, format, offsetProps[i].value); + } + for (i = 0; i < prop_pad; i++) + pcfPutINT8(file, format, 0); + pcfPutINT32(file, format, prop_string_size); + for (i = 0; i < pFont->info.nprops; i++) { + atom_name = pcfNameForAtom(pFont->info.props[i].name); + pcfWrite(file, atom_name, strlen(atom_name) + 1); + if (pFont->info.isStringProp[i]) { + atom_name = pcfNameForAtom(pFont->info.props[i].value); + pcfWrite(file, atom_name, strlen(atom_name) + 1); + } + } + break; + case PCF_ACCELERATORS: + pcfPutAccel(file, table->format, &bitmapFont->bitmapExtra->info); + break; + case PCF_METRICS: + if (PCF_FORMAT_MATCH(table->format, PCF_COMPRESSED_METRICS)) { + pcfPutINT16(file, format, bitmapFont->num_chars); + for (i = 0; i < bitmapFont->num_chars; i++) + pcfPutCompressedMetric(file, format, &bitmapFont->metrics[i].metrics); + } else { + pcfPutINT32(file, format, bitmapFont->num_chars); + for (i = 0; i < bitmapFont->num_chars; i++) + pcfPutMetric(file, format, &bitmapFont->metrics[i].metrics); + } + break; + case PCF_BITMAPS: + pcfPutINT32(file, format, bitmapFont->num_chars); + glyph = PCF_GLYPH_PAD(format); + offset = 0; + for (i = 0; i < bitmapFont->num_chars; i++) { + pcfPutINT32(file, format, offset); + offset += BYTES_FOR_GLYPH(&bitmapFont->metrics[i], glyph); + } + for (i = 0; i < GLYPHPADOPTIONS; i++) { + pcfPutINT32(file, format, + bitmapFont->bitmapExtra->bitmapsSizes[i]); + } + for (i = 0; i < bitmapFont->num_chars; i++) + pcfPutBitmap(file, format, &bitmapFont->metrics[i]); + break; + case PCF_INK_METRICS: + if (PCF_FORMAT_MATCH(table->format, PCF_COMPRESSED_METRICS)) { + pcfPutINT16(file, format, bitmapFont->num_chars); + for (i = 0; i < bitmapFont->num_chars; i++) + pcfPutCompressedMetric(file, format, &bitmapFont->ink_metrics[i]); + } else { + pcfPutINT32(file, format, bitmapFont->num_chars); + for (i = 0; i < bitmapFont->num_chars; i++) + pcfPutMetric(file, format, &bitmapFont->ink_metrics[i]); + } + break; + case PCF_BDF_ENCODINGS: + pcfPutINT16(file, format, pFont->info.firstCol); + pcfPutINT16(file, format, pFont->info.lastCol); + pcfPutINT16(file, format, pFont->info.firstRow); + pcfPutINT16(file, format, pFont->info.lastRow); + pcfPutINT16(file, format, pFont->info.defaultCh); + for (i = 0; i < nencodings; i++) { + if (ACCESSENCODING(bitmapFont->encoding,i)) + pcfPutINT16(file, format, + ACCESSENCODING(bitmapFont->encoding, i) - + bitmapFont->metrics); + else + pcfPutINT16(file, format, 0xFFFF); + } + break; + case PCF_SWIDTHS: + pcfPutINT32(file, format, bitmapFont->num_chars); + for (i = 0; i < bitmapFont->num_chars; i++) + pcfPutINT32(file, format, bitmapFont->bitmapExtra->sWidths[i]); + break; + case PCF_GLYPH_NAMES: + pcfPutINT32(file, format, bitmapFont->num_chars); + offset = 0; + for (i = 0; i < bitmapFont->num_chars; i++) { + pcfPutINT32(file, format, offset); + offset += strlen(pcfNameForAtom(bitmapFont->bitmapExtra->glyphNames[i])) + 1; + } + pcfPutINT32(file, format, offset); + for (i = 0; i < bitmapFont->num_chars; i++) { + atom_name = pcfNameForAtom(bitmapFont->bitmapExtra->glyphNames[i]); + pcfWrite(file, atom_name, strlen(atom_name) + 1); + } + break; + case PCF_BDF_ACCELERATORS: + pcfPutAccel(file, table->format, &pFont->info); + break; + } + } + + xfree(offsetProps); + return Successful; +} diff --git a/nx-X11/lib/font/bitmap/snfread.c b/nx-X11/lib/font/bitmap/snfread.c new file mode 100644 index 000000000..01b6bf382 --- /dev/null +++ b/nx-X11/lib/font/bitmap/snfread.c @@ -0,0 +1,514 @@ +/* $Xorg: snfread.c,v 1.5 2001/02/09 02:04:02 xorgcvs Exp $ */ +/************************************************************************ +Copyright 1989 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +************************************************************************/ + +/* + +Copyright 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + +*/ +/* $XFree86: xc/lib/font/bitmap/snfread.c,v 1.12 2003/11/17 22:20:22 dawes Exp $ */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#ifndef FONTMODULE +#include <ctype.h> +#endif + +#include <X11/fonts/fntfilst.h> +#include <X11/fonts/bitmap.h> +#include "snfstr.h" + +#include <stdarg.h> + +void +snfError(const char* message, ...) +{ + va_list args; + + va_start(args, message); + + fprintf(stderr, "SNF Error: "); + vfprintf(stderr, message, args); + va_end(args); +} + +static void snfUnloadFont(FontPtr pFont); + +static int +snfReadCharInfo(FontFilePtr file, CharInfoPtr charInfo, char *base) +{ + snfCharInfoRec snfCharInfo; + +#define Width(m) ((m).rightSideBearing - (m).leftSideBearing) +#define Height(m) ((m).ascent + (m).descent) + + if (FontFileRead(file, (char *) &snfCharInfo, sizeof snfCharInfo) != + sizeof(snfCharInfo)) { + return BadFontName; + } + charInfo->metrics = snfCharInfo.metrics; + if (snfCharInfo.exists) + charInfo->bits = base + snfCharInfo.byteOffset; + else + charInfo->bits = 0; + return Successful; +} + +static int +snfReadxCharInfo(FontFilePtr file, xCharInfo *charInfo) +{ + snfCharInfoRec snfCharInfo; + + if (FontFileRead(file, (char *) &snfCharInfo, sizeof snfCharInfo) != + sizeof(snfCharInfo)) { + return BadFontName; + } + *charInfo = snfCharInfo.metrics; + return Successful; +} + +static void +snfCopyInfo(snfFontInfoPtr snfInfo, FontInfoPtr pFontInfo) +{ + pFontInfo->firstCol = snfInfo->firstCol; + pFontInfo->lastCol = snfInfo->lastCol; + pFontInfo->firstRow = snfInfo->firstRow; + pFontInfo->lastRow = snfInfo->lastRow; + pFontInfo->defaultCh = snfInfo->chDefault; + pFontInfo->noOverlap = snfInfo->noOverlap; + pFontInfo->terminalFont = snfInfo->terminalFont; + pFontInfo->constantMetrics = snfInfo->constantMetrics; + pFontInfo->constantWidth = snfInfo->constantWidth; + pFontInfo->inkInside = snfInfo->inkInside; + pFontInfo->inkMetrics = snfInfo->inkMetrics; + pFontInfo->allExist = snfInfo->allExist; + pFontInfo->drawDirection = snfInfo->drawDirection; + pFontInfo->anamorphic = FALSE; + pFontInfo->cachable = TRUE; + pFontInfo->maxOverlap = 0; + pFontInfo->minbounds = snfInfo->minbounds.metrics; + pFontInfo->maxbounds = snfInfo->maxbounds.metrics; + pFontInfo->fontAscent = snfInfo->fontAscent; + pFontInfo->fontDescent = snfInfo->fontDescent; + pFontInfo->nprops = snfInfo->nProps; +} + +static int +snfReadProps(snfFontInfoPtr snfInfo, FontInfoPtr pFontInfo, FontFilePtr file) +{ + char *strings; + FontPropPtr pfp; + snfFontPropPtr psnfp; + char *propspace; + int bytestoalloc; + int i; + + bytestoalloc = snfInfo->nProps * sizeof(snfFontPropRec) + + BYTESOFSTRINGINFO(snfInfo); + propspace = (char *) xalloc(bytestoalloc); + if (!propspace) { + snfError("snfReadProps(): Couldn't allocate propspace (%d)\n", bytestoalloc); + return AllocError; + } + + if (FontFileRead(file, propspace, bytestoalloc) != bytestoalloc) { + xfree(propspace); + return BadFontName; + } + psnfp = (snfFontPropPtr) propspace; + + strings = propspace + BYTESOFPROPINFO(snfInfo); + + for (i = 0, pfp = pFontInfo->props; i < snfInfo->nProps; i++, pfp++, psnfp++) { + pfp->name = MakeAtom(&strings[psnfp->name], + (unsigned) strlen(&strings[psnfp->name]), 1); + pFontInfo->isStringProp[i] = psnfp->indirect; + if (psnfp->indirect) + pfp->value = (INT32) MakeAtom(&strings[psnfp->value], + (unsigned) strlen(&strings[psnfp->value]), 1); + else + pfp->value = psnfp->value; + } + + xfree(propspace); + return Successful; +} + +static int +snfReadHeader(snfFontInfoPtr snfInfo, FontFilePtr file) +{ + if (FontFileRead(file, (char *) snfInfo, sizeof *snfInfo) != sizeof *snfInfo) + return BadFontName; + + if (snfInfo->version1 != FONT_FILE_VERSION || + snfInfo->version2 != FONT_FILE_VERSION) + return BadFontName; + return Successful; +} + +static int snf_set; +static int snf_bit, snf_byte, snf_glyph, snf_scan; + +void +SnfSetFormat (int bit, int byte, int glyph, int scan) +{ + snf_bit = bit; + snf_byte = byte; + snf_glyph = glyph; + snf_scan = scan; + snf_set = 1; +} + +static void +SnfGetFormat (int *bit, int *byte, int *glyph, int *scan) +{ + if (!snf_set) + FontDefaultFormat (&snf_bit, &snf_byte, &snf_glyph, &snf_scan); + *bit = snf_bit; + *byte = snf_byte; + *glyph = snf_glyph; + *scan = snf_scan; +} + +int +snfReadFont(FontPtr pFont, FontFilePtr file, + int bit, int byte, int glyph, int scan) +{ + snfFontInfoRec fi; + unsigned bytestoalloc; + int i, j; + char *fontspace; + BitmapFontPtr bitmapFont; + int num_chars; + int bitmapsSize; + int ret; + int metrics_off; + int encoding_off; + int props_off; + int isStringProp_off; + int ink_off; + char *bitmaps; + int def_bit, def_byte, def_glyph, def_scan; + + ret = snfReadHeader(&fi, file); + if (ret != Successful) + return ret; + + SnfGetFormat (&def_bit, &def_byte, &def_glyph, &def_scan); + + /* + * we'll allocate one chunk of memory and split it among the various parts + * of the font: + * + * BitmapFontRec CharInfoRec's Glyphs Encoding DIX Properties Ink CharInfoRec's + * + * If the glyphpad is not the same as the font file, then the glyphs + * are allocated separately, to be later realloc'ed when we know + * how big to make them. + */ + + bitmapsSize = BYTESOFGLYPHINFO(&fi); + num_chars = n2dChars(&fi); + bytestoalloc = sizeof(BitmapFontRec); /* bitmapFont */ + metrics_off = bytestoalloc; + bytestoalloc += num_chars * sizeof(CharInfoRec); /* metrics */ + encoding_off = bytestoalloc; + bytestoalloc += NUM_SEGMENTS(num_chars) * sizeof(CharInfoPtr**); + /* encoding */ + props_off = bytestoalloc; + bytestoalloc += fi.nProps * sizeof(FontPropRec); /* props */ + isStringProp_off = bytestoalloc; + bytestoalloc += fi.nProps * sizeof(char); /* isStringProp */ + bytestoalloc = (bytestoalloc + 3) & ~3; + ink_off = bytestoalloc; + if (fi.inkMetrics) + bytestoalloc += num_chars * sizeof(xCharInfo); /* ink_metrics */ + + fontspace = (char *) xalloc(bytestoalloc); + if (!fontspace) { + snfError("snfReadFont(): Couldn't allocate fontspace (%d)\n", bytestoalloc); + return AllocError; + } + bitmaps = (char *) xalloc (bitmapsSize); + if (!bitmaps) + { + snfError("snfReadFont(): Couldn't allocate bitmaps (%d)\n", bitmapsSize); + xfree (fontspace); + return AllocError; + } + /* + * now fix up pointers + */ + + bitmapFont = (BitmapFontPtr) fontspace; + bitmapFont->num_chars = num_chars; + bitmapFont->metrics = (CharInfoPtr) (fontspace + metrics_off); + bitmapFont->encoding = (CharInfoPtr **) (fontspace + encoding_off); + bitmapFont->bitmaps = bitmaps; + bitmapFont->pDefault = NULL; + bitmapFont->bitmapExtra = NULL; + pFont->info.props = (FontPropPtr) (fontspace + props_off); + pFont->info.isStringProp = (char *) (fontspace + isStringProp_off); + if (fi.inkMetrics) + bitmapFont->ink_metrics = (xCharInfo *) (fontspace + ink_off); + else + bitmapFont->ink_metrics = 0; + + /* + * read the CharInfo + */ + + ret = Successful; + memset(bitmapFont->encoding, 0, + NUM_SEGMENTS(num_chars)*sizeof(CharInfoPtr*)); + for (i = 0; ret == Successful && i < num_chars; i++) { + ret = snfReadCharInfo(file, &bitmapFont->metrics[i], bitmaps); + if (bitmapFont->metrics[i].bits) { + if (!bitmapFont->encoding[SEGMENT_MAJOR(i)]) { + bitmapFont->encoding[SEGMENT_MAJOR(i)]= + (CharInfoPtr*)xcalloc(BITMAP_FONT_SEGMENT_SIZE, + sizeof(CharInfoPtr)); + if (!bitmapFont->encoding[SEGMENT_MAJOR(i)]) { + ret = AllocError; + break; + } + } + ACCESSENCODINGL(bitmapFont->encoding,i) = &bitmapFont->metrics[i]; + } + } + + if (ret != Successful) { + xfree(bitmaps); + if(bitmapFont->encoding) { + for(j=0; j<SEGMENT_MAJOR(i); j++) + xfree(bitmapFont->encoding[i]); + } + xfree(fontspace); + return ret; + } + /* + * read the glyphs + */ + + if (FontFileRead(file, bitmaps, bitmapsSize) != bitmapsSize) { + xfree(bitmaps); + xfree(fontspace); + return BadFontName; + } + + if (def_bit != bit) + BitOrderInvert((unsigned char *)bitmaps, bitmapsSize); + if ((def_byte == def_bit) != (bit == byte)) { + switch (bit == byte ? def_scan : scan) { + case 1: + break; + case 2: + TwoByteSwap((unsigned char *)bitmaps, bitmapsSize); + break; + case 4: + FourByteSwap((unsigned char *)bitmaps, bitmapsSize); + break; + } + } + if (def_glyph != glyph) { + char *padbitmaps; + int sizepadbitmaps; + int sizechar; + CharInfoPtr metric; + + sizepadbitmaps = 0; + metric = bitmapFont->metrics; + for (i = 0; i < num_chars; i++) + { + if (metric->bits) + sizepadbitmaps += BYTES_FOR_GLYPH(metric,glyph); + metric++; + } + padbitmaps = (char *) xalloc(sizepadbitmaps); + if (!padbitmaps) { + snfError("snfReadFont(): Couldn't allocate padbitmaps (%d)\n", sizepadbitmaps); + xfree (bitmaps); + xfree (fontspace); + return AllocError; + } + metric = bitmapFont->metrics; + bitmapFont->bitmaps = padbitmaps; + for (i = 0; i < num_chars; i++) { + sizechar = RepadBitmap(metric->bits, padbitmaps, + def_glyph, glyph, + metric->metrics.rightSideBearing - + metric->metrics.leftSideBearing, + metric->metrics.ascent + metric->metrics.descent); + metric->bits = padbitmaps; + padbitmaps += sizechar; + metric++; + } + xfree(bitmaps); + } + + /* now read and atom'ize properties */ + + ret = snfReadProps(&fi, &pFont->info, file); + if (ret != Successful) { + xfree(fontspace); + return ret; + } + snfCopyInfo(&fi, &pFont->info); + + /* finally, read the ink metrics if the exist */ + + if (fi.inkMetrics) { + ret = Successful; + ret = snfReadxCharInfo(file, &pFont->info.ink_minbounds); + ret = snfReadxCharInfo(file, &pFont->info.ink_maxbounds); + for (i = 0; ret == Successful && i < num_chars; i++) + ret = snfReadxCharInfo(file, &bitmapFont->ink_metrics[i]); + if (ret != Successful) { + xfree(fontspace); + return ret; + } + } else { + pFont->info.ink_minbounds = pFont->info.minbounds; + pFont->info.ink_maxbounds = pFont->info.maxbounds; + } + + if (pFont->info.defaultCh != (unsigned short) NO_SUCH_CHAR) { + unsigned int r, + c, + cols; + + r = pFont->info.defaultCh >> 8; + c = pFont->info.defaultCh & 0xFF; + if (pFont->info.firstRow <= r && r <= pFont->info.lastRow && + pFont->info.firstCol <= c && c <= pFont->info.lastCol) { + cols = pFont->info.lastCol - pFont->info.firstCol + 1; + r = r - pFont->info.firstRow; + c = c - pFont->info.firstCol; + bitmapFont->pDefault = &bitmapFont->metrics[r * cols + c]; + } + } + bitmapFont->bitmapExtra = (BitmapExtraPtr) 0; + pFont->fontPrivate = (pointer) bitmapFont; + pFont->get_glyphs = bitmapGetGlyphs; + pFont->get_metrics = bitmapGetMetrics; + pFont->unload_font = snfUnloadFont; + pFont->unload_glyphs = NULL; + pFont->bit = bit; + pFont->byte = byte; + pFont->glyph = glyph; + pFont->scan = scan; + return Successful; +} + +int +snfReadFontInfo(FontInfoPtr pFontInfo, FontFilePtr file) +{ + int ret; + snfFontInfoRec fi; + int bytestoskip; + int num_chars; + + ret = snfReadHeader(&fi, file); + if (ret != Successful) + return ret; + snfCopyInfo(&fi, pFontInfo); + + pFontInfo->props = (FontPropPtr) xalloc(fi.nProps * sizeof(FontPropRec)); + if (!pFontInfo->props) { + snfError("snfReadFontInfo(): Couldn't allocate props (%d*%d)\n", fi.nProps, sizeof(FontPropRec)); + return AllocError; + } + pFontInfo->isStringProp = (char *) xalloc(fi.nProps * sizeof(char)); + if (!pFontInfo->isStringProp) { + snfError("snfReadFontInfo(): Couldn't allocate isStringProp (%d*%d)\n", fi.nProps, sizeof(char)); + xfree(pFontInfo->props); + return AllocError; + } + num_chars = n2dChars(&fi); + bytestoskip = num_chars * sizeof(snfCharInfoRec); /* charinfos */ + bytestoskip += BYTESOFGLYPHINFO(&fi); + (void)FontFileSkip(file, bytestoskip); + + ret = snfReadProps(&fi, pFontInfo, file); + if (ret != Successful) { + xfree(pFontInfo->props); + xfree(pFontInfo->isStringProp); + return ret; + } + if (fi.inkMetrics) { + ret = snfReadxCharInfo(file, &pFontInfo->ink_minbounds); + if (ret != Successful) { + xfree(pFontInfo->props); + xfree(pFontInfo->isStringProp); + return ret; + } + ret = snfReadxCharInfo(file, &pFontInfo->ink_maxbounds); + if (ret != Successful) { + xfree(pFontInfo->props); + xfree(pFontInfo->isStringProp); + return ret; + } + } else { + pFontInfo->ink_minbounds = pFontInfo->minbounds; + pFontInfo->ink_maxbounds = pFontInfo->maxbounds; + } + return Successful; + +} + +static void +snfUnloadFont(FontPtr pFont) +{ + BitmapFontPtr bitmapFont; + + bitmapFont = (BitmapFontPtr) pFont->fontPrivate; + xfree (bitmapFont->bitmaps); + xfree (bitmapFont); + DestroyFontRec (pFont); +} + diff --git a/nx-X11/lib/font/bitmap/snfstr.h b/nx-X11/lib/font/bitmap/snfstr.h new file mode 100644 index 000000000..8158089bf --- /dev/null +++ b/nx-X11/lib/font/bitmap/snfstr.h @@ -0,0 +1,185 @@ +/* $Xorg: snfstr.h,v 1.4 2001/02/09 02:04:02 xorgcvs Exp $ */ +/*********************************************************** +Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +/* + +Copyright 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + +*/ +/* $XFree86: xc/lib/font/bitmap/snfstr.h,v 1.5 2001/12/14 19:56:47 dawes Exp $ */ + +#ifndef SNFSTR_H +#define SNFSTR_H 1 + +#include <X11/fonts/fntfilio.h> + +/*- + * This file describes the Server Natural Font format. + * SNF fonts are both CPU-dependent and frame buffer bit order dependent. + * This file is used by: + * 1) the server, to hold font information read out of font files. + * 2) font converters + * + * Each font file contains the following + * data structures, with no padding in-between. + * + * 1) The XFONTINFO structure + * hand-padded to a two-short boundary. + * maxbounds.byteoffset is the total number of bytes in the + * glpyh array + * maxbounds.bitOffset is thetotal width of the unpadded font + * + * 2) The XCHARINFO array + * indexed directly with character codes, both on disk + * and in memory. + * + * 3) Character glyphs + * padded in the server-natural way, and + * ordered in the device-natural way. + * End of glyphs padded to 32-bit boundary. + * + * 4) nProps font properties + * + * 5) a sequence of null-terminated strings, for font properties + */ + +#define FONT_FILE_VERSION 4 + +typedef struct _snfFontProp { + CARD32 name; /* offset of string */ + INT32 value; /* number or offset of string */ + Bool indirect; /* value is a string offset */ +} snfFontPropRec; + +/* + * the following macro definitions describe a font file image in memory + */ +#define ADDRCharInfoRec( pfi) \ + ((snfCharInfoRec *) &(pfi)[1]) + +#define ADDRCHARGLYPHS( pfi) \ + (((char *) &(pfi)[1]) + BYTESOFCHARINFO(pfi)) + +/* + * pad out glyphs to a CARD32 boundary + */ +#define ADDRXFONTPROPS( pfi) \ + ((snfFontPropRec *) ((char *)ADDRCHARGLYPHS( pfi) + BYTESOFGLYPHINFO(pfi))) + +#define ADDRSTRINGTAB( pfi) \ + ((char *)ADDRXFONTPROPS( pfi) + BYTESOFPROPINFO(pfi)) + +#define n2dChars(pfi) (((pfi)->lastRow - (pfi)->firstRow + 1) * \ + ((pfi)->lastCol - (pfi)->firstCol + 1)) +#define BYTESOFFONTINFO(pfi) (sizeof(snfFontInfoRec)) +#define BYTESOFCHARINFO(pfi) (sizeof(snfCharInfoRec) * n2dChars(pfi)) +#define BYTESOFPROPINFO(pfi) (sizeof(snfFontPropRec) * (pfi)->nProps) +#define BYTESOFSTRINGINFO(pfi) ((pfi)->lenStrings) +#define BYTESOFGLYPHINFO(pfi) (((pfi)->maxbounds.byteOffset+3) & ~0x3) +#define BYTESOFINKINFO(pfi) (sizeof(snfCharInfoRec) * n2dChars(pfi)) + +typedef struct _snfFontProp *snfFontPropPtr; +typedef struct _snfCharInfo *snfCharInfoPtr; +typedef struct _snfFontInfo *snfFontInfoPtr; + +typedef struct _snfCharInfo { + xCharInfo metrics; /* info preformatted for Queries */ + unsigned byteOffset:24; /* byte offset of the raster from pGlyphs */ + unsigned exists:1; /* true iff glyph exists for this char */ + unsigned pad:7; /* must be zero for now */ +} snfCharInfoRec; + +typedef struct _snfFontInfo { + unsigned int version1; /* version stamp */ + unsigned int allExist; + unsigned int drawDirection; + unsigned int noOverlap; /* true if: + * max(rightSideBearing-characterWidth) <= + * minbounds->metrics.leftSideBearing */ + unsigned int constantMetrics; + unsigned int terminalFont; /* Should be deprecated! true if: constant + * metrics && leftSideBearing == 0 && + * rightSideBearing == characterWidth && + * ascent == fontAscent && descent == + * fontDescent */ + unsigned int linear:1; /* true if firstRow == lastRow */ + unsigned int constantWidth:1; /* true if + * minbounds->metrics.characterWidth + * == + * maxbounds->metrics.characterWidth */ + unsigned int inkInside:1; /* true if for all defined glyphs: + * leftSideBearing >= 0 && rightSideBearing <= + * characterWidth && -fontDescent <= ascent <= + * fontAscent && -fontAscent <= descent <= + * fontDescent */ + unsigned int inkMetrics:1; /* ink metrics != bitmap metrics */ + /* used with terminalFont */ + /* see font's pInk{CI,Min,Max} */ + unsigned int padding:28; + unsigned int firstCol; + unsigned int lastCol; + unsigned int firstRow; + unsigned int lastRow; + unsigned int nProps; + unsigned int lenStrings; /* length in bytes of string table */ + unsigned int chDefault; /* default character */ + int fontDescent; /* minimum for quality typography */ + int fontAscent; /* minimum for quality typography */ + snfCharInfoRec minbounds; /* MIN of glyph metrics over all chars */ + snfCharInfoRec maxbounds; /* MAX of glyph metrics over all chars */ + unsigned int pixDepth; /* intensity bits per pixel */ + unsigned int glyphSets; /* number of sets of glyphs, for sub-pixel + * positioning */ + unsigned int version2; /* version stamp double-check */ +} snfFontInfoRec; + +extern void SnfSetFormat ( int bit, int byte, int glyph, int scan ); +extern int snfReadFont ( FontPtr pFont, FontFilePtr file, + int bit, int byte, int glyph, int scan ); +extern int snfReadFontInfo ( FontInfoPtr pFontInfo, FontFilePtr file ); +extern void snfError( const char* message, ... ); + +#endif /* SNFSTR_H */ diff --git a/nx-X11/lib/font/builtins/Imakefile b/nx-X11/lib/font/builtins/Imakefile new file mode 100644 index 000000000..f70434865 --- /dev/null +++ b/nx-X11/lib/font/builtins/Imakefile @@ -0,0 +1,17 @@ +XCOMM $XFree86: xc/lib/font/builtins/Imakefile,v 1.2 1999/11/19 14:59:08 hohndel Exp $ +XCOMM +XCOMM +XCOMM $XConsortium: Imakefile /main/14 1996/11/03 19:58:41 kaleb $ +#include <Server.tmpl> + + INCLUDES = -I$(FONTINCSRC) -I../include -I$(SERVERSRC)/include + HEADERS = + + SRCS = dir.c file.c fonts.c fpe.c render.c + OBJS = dir.o file.o fonts.o fpe.o render.o + +SubdirLibraryRule($(OBJS)) +NormalLibraryObjectRule() +NormalLintTarget($(SRCS)) + +DependTarget() diff --git a/nx-X11/lib/font/builtins/buildfont b/nx-X11/lib/font/builtins/buildfont new file mode 100644 index 000000000..aa4602ff8 --- /dev/null +++ b/nx-X11/lib/font/builtins/buildfont @@ -0,0 +1,14 @@ +#!/bin/sh +# +# Convert a bdf file into C-code suitable for inclusion in +# builtin fonts +# +FONT=$1 +NAME=$2 +echo 'static const char file_'$NAME'[] = {' +bdftopcf -p1 -u1 $1 | + compress -b 12 | + od -b -v -w8 | + sed 's/^[0-9]*\( *\)/\1\1\1\1/' | + sed 's/\([0-9][0-9]*\)/'"'"'\\\1'"'"',/g' +echo '};' diff --git a/nx-X11/lib/font/builtins/builtin.h b/nx-X11/lib/font/builtins/builtin.h new file mode 100644 index 000000000..ea98407eb --- /dev/null +++ b/nx-X11/lib/font/builtins/builtin.h @@ -0,0 +1,60 @@ +/* + * Id: builtin.h,v 1.2 1999/11/02 06:16:47 keithp Exp $ + * + * Copyright 1999 SuSE, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of SuSE not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. SuSE makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE + * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Keith Packard, SuSE, Inc. + */ +/* $XFree86: xc/lib/font/builtins/builtin.h,v 1.3 1999/12/30 02:29:49 robin Exp $ */ + +#include <X11/Xdefs.h> +#include <X11/fonts/font.h> +#include <X11/fonts/fontxlfd.h> +#include <X11/fonts/fntfil.h> +#include <X11/fonts/fntfilio.h> +#include <X11/fonts/fntfilst.h> + +typedef struct _BuiltinFile { + const char *name; + int len; + const char *bits; +} BuiltinFileRec, *BuiltinFilePtr; + +typedef struct _BuiltinDir { + char *file_name; + char *font_name; +} BuiltinDirRec, *BuiltinDirPtr; + +typedef struct _BuiltinAlias { + char *alias_name; + char *font_name; +} BuiltinAliasRec, *BuiltinAliasPtr; + +extern const BuiltinFileRec builtin_files[]; +extern const int builtin_files_count; + +extern const BuiltinDirRec builtin_dir[]; +extern const int builtin_dir_count; + +extern const BuiltinAliasRec builtin_alias[]; +extern const int builtin_alias_count; + +extern FontFilePtr BuiltinFileOpen (); +extern int BuiltinFileClose (); diff --git a/nx-X11/lib/font/builtins/dir.c b/nx-X11/lib/font/builtins/dir.c new file mode 100644 index 000000000..fb2f82c41 --- /dev/null +++ b/nx-X11/lib/font/builtins/dir.c @@ -0,0 +1,64 @@ +/* + * Id: dir.c,v 1.2 1999/11/02 06:16:47 keithp Exp $ + * + * Copyright 1999 SuSE, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of SuSE not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. SuSE makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE + * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Keith Packard, SuSE, Inc. + */ +/* $XFree86: xc/lib/font/builtins/dir.c,v 1.3 1999/12/30 02:29:49 robin Exp $ */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include "builtin.h" + +int +BuiltinReadDirectory (directory, pdir) + char *directory; + FontDirectoryPtr *pdir; +{ + FontDirectoryPtr dir; + int i; + + dir = FontFileMakeDir ("", builtin_dir_count); + for (i = 0; i < builtin_dir_count; i++) + { + if (!FontFileAddFontFile (dir, + (char *) builtin_dir[i].font_name, + (char *) builtin_dir[i].file_name)) + { + FontFileFreeDir (dir); + return BadFontPath; + } + } + for (i = 0; i < builtin_alias_count; i++) + { + if (!FontFileAddFontAlias (dir, + (char *) builtin_alias[i].alias_name, + (char *) builtin_alias[i].font_name)) + { + FontFileFreeDir (dir); + return BadFontPath; + } + } + FontFileSortDir (dir); + *pdir = dir; + return Successful; +} diff --git a/nx-X11/lib/font/builtins/file.c b/nx-X11/lib/font/builtins/file.c new file mode 100644 index 000000000..024c35343 --- /dev/null +++ b/nx-X11/lib/font/builtins/file.c @@ -0,0 +1,139 @@ +/* + * Id: file.c,v 1.2 1999/11/02 06:16:47 keithp Exp $ + * + * Copyright 1999 SuSE, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of SuSE not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. SuSE makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE + * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Keith Packard, SuSE, Inc. + */ +/* $XFree86: xc/lib/font/builtins/file.c,v 1.3 1999/12/30 02:29:49 robin Exp $ */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include "builtin.h" + +typedef struct _BuiltinIO { + int offset; + BuiltinFilePtr file; +} BuiltinIORec, *BuiltinIOPtr; + +static int +BuiltinFill (f) + BufFilePtr f; +{ + int left, len; + BuiltinIOPtr io = ((BuiltinIOPtr) f->private); + + left = io->file->len - io->offset; + if (left <= 0) + { + f->left = 0; + return BUFFILEEOF; + } + len = BUFFILESIZE; + if (len > left) + len = left; + bcopy (io->file->bits + io->offset, f->buffer, len); + io->offset += len; + f->left = len - 1; + f->bufp = f->buffer + 1; + return f->buffer[0]; +} + +static int +BuiltinSkip (f, count) + BufFilePtr f; + int count; +{ + BuiltinIOPtr io = ((BuiltinIOPtr) f->private); + int curoff; + int fileoff; + int todo; + int left; + + curoff = f->bufp - f->buffer; + fileoff = curoff + f->left; + if (curoff + count <= fileoff) { + f->bufp += count; + f->left -= count; + } else { + todo = count - (fileoff - curoff); + io->offset += todo; + if (io->offset > io->file->len) + io->offset = io->file->len; + if (io->offset < 0) + io->offset = 0; + f->left = 0; + } + return count; +} + +static int +BuiltinClose (f, doClose) + BufFilePtr f; +{ + BuiltinIOPtr io = ((BuiltinIOPtr) f->private); + + xfree (io); + return 1; +} + + +FontFilePtr +BuiltinFileOpen (name) + char *name; +{ + int i; + BuiltinIOPtr io; + BufFilePtr raw, cooked; + + if (*name == '/') name++; + for (i = 0; i < builtin_files_count; i++) + if (!strcmp (name, builtin_files[i].name)) + break; + if (i == builtin_files_count) + return NULL; + io = (BuiltinIOPtr) xalloc (sizeof (BuiltinIORec)); + if (!io) + return NULL; + io->offset = 0; + io->file = (void *) &builtin_files[i]; + raw = BufFileCreate ((char *) io, BuiltinFill, 0, BuiltinSkip, BuiltinClose); + if (!raw) + { + xfree (io); + return NULL; + } + if (cooked = BufFilePushCompressed (raw)) + raw = cooked; + else + { + raw->left += raw->bufp - raw->buffer; + raw->bufp = raw->buffer; + } + return (FontFilePtr) raw; +} + +int +BuiltinFileClose (f) + FontFilePtr f; +{ + return BufFileClose ((BufFilePtr) f, TRUE); +} diff --git a/nx-X11/lib/font/builtins/fonts.c b/nx-X11/lib/font/builtins/fonts.c new file mode 100644 index 000000000..30c762f7f --- /dev/null +++ b/nx-X11/lib/font/builtins/fonts.c @@ -0,0 +1,2438 @@ +/* + * Id: fonts.c,v 1.2 1999/11/02 06:16:47 keithp Exp $ + * + * Copyright 1999 SuSE, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of SuSE not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. SuSE makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE + * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Keith Packard, SuSE, Inc. + */ +/* $XFree86: xc/lib/font/builtins/fonts.c,v 1.3 1999/12/30 02:29:49 robin Exp $ */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include "builtin.h" + +static const char file_6x13[] = { + '\037', '\235', '\214', '\001', '\314', '\214', '\201', '\223', + '\000', '\200', '\301', '\000', '\006', '\023', '\032', '\244', + '\042', '\300', '\040', '\246', '\204', '\015', '\023', '\042', + '\004', '\100', '\046', '\041', '\273', '\210', '\004', '\024', + '\116', '\104', '\223', '\021', '\000', '\224', '\001', '\006', + '\021', '\050', '\114', '\210', '\317', '\201', '\101', '\134', + '\007', '\014', '\102', '\320', '\150', '\220', '\243', '\101', + '\130', '\026', '\014', '\202', '\030', '\251', '\062', '\042', + '\206', '\015', '\006', '\201', '\320', '\004', '\200', '\010', + '\044', '\000', '\024', '\035', '\014', '\002', '\332', '\211', + '\104', '\044', '\000', '\130', '\063', '\017', '\112', '\064', + '\130', '\321', '\040', '\076', '\024', '\064', '\053', '\354', + '\014', '\040', '\041', '\341', '\004', '\211', '\070', '\145', + '\112', '\144', '\221', '\120', '\206', '\104', '\037', '\011', + '\213', '\110', '\134', '\222', '\260', '\211', '\304', '\055', + '\011', '\323', '\110', '\304', '\223', '\060', '\217', '\302', + '\006', '\011', '\011', '\051', '\144', '\153', '\360', '\221', + '\102', '\262', '\006', '\071', '\335', '\115', '\230', '\112', + '\142', '\254', '\204', '\263', '\024', '\362', '\110', '\030', + '\114', '\242', '\264', '\204', '\332', '\044', '\256', '\113', + '\330', '\116', '\342', '\275', '\204', '\035', '\046', '\006', + '\020', '\061', '\121', '\314', '\104', '\000', '\012', '\322', + '\136', '\136', '\223', '\220', '\316', '\345', '\005', '\011', + '\373', '\134', '\066', '\100', '\023', '\321', '\104', '\043', + '\117', '\234', '\120', '\161', '\022', '\244', '\111', '\221', + '\057', '\122', '\212', '\034', '\111', '\062', '\205', '\212', + '\224', '\054', '\006', '\121', '\127', '\161', '\102', '\344', + '\066', '\200', '\046', '\151', '\346', '\214', '\001', '\140', + '\244', '\165', '\022', '\046', '\131', '\276', '\260', '\166', + '\115', '\074', '\015', '\236', '\062', '\025', '\257', '\024', + '\111', '\162', '\004', '\011', '\025', '\345', '\255', '\305', + '\066', '\201', '\236', '\246', '\116', '\033', '\000', '\123', + '\230', '\004', '\121', '\015', '\100', '\012', '\370', '\042', + '\124', '\256', '\044', '\041', '\102', '\005', '\011', '\166', + '\346', '\123', '\312', '\264', '\111', '\063', '\344', '\215', + '\033', '\062', '\145', '\334', '\314', '\201', '\016', '\040', + '\010', '\021', '\042', '\137', '\324', '\226', '\005', '\023', + '\257', '\055', '\047', '\226', '\107', '\111', '\140', '\121', + '\004', '\023', '\001', '\046', '\241', '\205', '\130', '\120', + '\074', '\221', '\204', '\152', '\015', '\076', '\130', '\136', + '\021', '\123', '\074', '\301', '\104', '\025', '\124', '\044', + '\221', '\332', '\027', '\130', '\134', '\230', '\341', '\206', + '\035', '\176', '\210', '\333', '\024', '\120', '\004', '\061', + '\304', '\204', '\107', '\000', '\060', '\104', '\177', '\126', + '\024', '\041', '\105', '\020', '\107', '\274', '\246', '\036', + '\173', '\110', '\270', '\210', '\104', '\020', '\122', '\114', + '\201', '\036', '\154', '\262', '\321', '\146', '\033', '\156', + '\264', '\075', '\201', '\003', '\016', '\065', '\344', '\240', + '\043', '\217', '\076', '\136', '\127', '\204', '\023', '\103', + '\074', '\101', '\004', '\213', '\000', '\304', '\340', '\342', + '\023', '\120', '\144', '\041', '\005', '\165', '\326', '\171', + '\124', '\207', '\030', '\154', '\244', '\061', '\006', '\010', + '\144', '\274', '\321', '\106', '\030', '\151', '\270', '\001', + '\202', '\031', '\366', '\321', '\341', '\002', '\010', '\040', + '\114', '\201', '\106', '\030', '\162', '\224', '\001', '\102', + '\030', '\367', '\201', '\220', '\237', '\032', '\157', '\344', + '\341', '\002', '\161', '\251', '\121', '\001', '\100', '\013', + '\300', '\011', '\327', '\202', '\021', '\316', '\101', '\107', + '\050', '\167', '\336', '\265', '\040', '\105', '\013', '\361', + '\315', '\127', '\337', '\175', '\371', '\355', '\107', '\106', + '\013', '\055', '\304', '\060', '\103', '\246', '\062', '\300', + '\320', '\302', '\015', '\065', '\174', '\032', '\352', '\020', + '\055', '\330', '\340', '\151', '\221', '\107', '\046', '\231', + '\051', '\000', '\322', '\161', '\051', '\150', '\154', '\043', + '\162', '\350', '\241', '\023', '\000', '\140', '\361', '\005', + '\022', '\323', '\125', '\047', '\150', '\024', '\125', '\370', + '\367', '\305', '\215', '\355', '\051', '\005', '\100', '\000', + '\304', '\026', '\153', '\020', '\150', '\006', '\105', '\264', + '\023', '\151', '\244', '\201', '\246', '\254', '\101', '\314', + '\002', '\340', '\354', '\262', '\044', '\375', '\223', '\054', + '\000', '\321', '\116', '\273', '\323', '\266', '\334', '\116', + '\145', '\020', '\070', '\000', '\000', '\142', '\210', '\041', + '\213', '\010', '\042', '\056', '\271', '\346', '\216', '\133', + '\356', '\271', '\353', '\252', '\233', '\056', '\272', '\354', + '\276', '\333', '\056', '\274', '\356', '\306', '\153', '\157', + '\275', '\370', '\322', '\253', '\357', '\274', '\374', '\312', + '\353', '\357', '\275', '\373', '\376', '\233', '\157', '\277', + '\000', '\023', '\074', '\260', '\300', '\001', '\027', '\214', + '\260', '\301', '\011', '\037', '\254', '\360', '\303', '\016', + '\107', '\334', '\360', '\304', '\014', '\127', '\274', '\360', + '\305', '\020', '\123', '\214', '\261', '\304', '\026', '\147', + '\334', '\061', '\307', '\033', '\153', '\354', '\161', '\310', + '\037', '\213', '\014', '\362', '\310', '\050', '\237', '\254', + '\262', '\311', '\054', '\227', '\354', '\062', '\311', '\060', + '\247', '\334', '\162', '\314', '\053', '\277', '\054', '\263', + '\315', '\065', '\323', '\074', '\363', '\315', '\072', '\343', + '\274', '\163', '\316', '\074', '\007', '\015', '\364', '\320', + '\077', '\027', '\355', '\363', '\321', '\376', '\322', '\004', + '\056', '\115', '\160', '\031', '\244', '\101', '\102', '\047', + '\044', '\104', '\103', '\102', '\101', '\044', '\104', '\253', + '\101', '\150', '\265', '\224', '\120', '\035', '\011', '\011', + '\222', '\220', '\135', '\171', '\361', '\225', '\220', '\055', + '\011', '\015', '\223', '\020', '\064', '\011', '\165', '\223', + '\220', '\072', '\011', '\075', '\146', '\020', '\001', '\023', + '\105', '\060', '\221', '\007', '\023', '\255', '\060', '\021', + '\016', '\023', '\025', '\061', '\221', '\024', '\023', '\175', + '\061', '\021', '\033', '\023', '\345', '\061', '\221', '\041', + '\023', '\115', '\062', '\021', '\050', '\023', '\265', '\062', + '\221', '\056', '\023', '\035', '\063', '\021', '\065', '\023', + '\205', '\063', '\221', '\073', '\023', '\355', '\063', '\021', + '\002', '\021', '\125', '\020', '\221', '\010', '\021', '\275', + '\020', '\021', '\017', '\021', '\045', '\021', '\221', '\025', + '\021', '\215', '\021', '\021', '\034', '\021', '\365', '\021', + '\221', '\042', '\021', '\135', '\022', '\021', '\051', '\021', + '\305', '\022', '\221', '\057', '\021', '\055', '\023', '\021', + '\066', '\021', '\225', '\023', '\221', '\074', '\021', '\375', + '\023', '\021', '\003', '\076', '\145', '\340', '\223', '\011', + '\076', '\315', '\340', '\023', '\020', '\076', '\065', '\341', + '\223', '\026', '\076', '\235', '\341', '\023', '\035', '\076', + '\005', '\342', '\223', '\043', '\076', '\155', '\342', '\023', + '\052', '\076', '\325', '\342', '\223', '\060', '\076', '\075', + '\343', '\023', '\067', '\076', '\245', '\343', '\223', '\075', + '\076', '\015', '\320', '\021', '\004', '\035', '\165', '\320', + '\221', '\012', '\035', '\335', '\320', '\021', '\021', '\035', + '\105', '\321', '\221', '\027', '\035', '\255', '\321', '\021', + '\036', '\035', '\025', '\322', '\221', '\044', '\035', '\175', + '\322', '\021', '\053', '\035', '\311', '\105', '\107', '\214', + '\321', '\221', '\151', '\164', '\004', '\034', '\035', '\151', + '\107', '\107', '\364', '\321', '\221', '\003', '\024', '\300', + '\040', '\024', '\170', '\040', '\000', '\102', '\040', '\101', + '\027', '\110', '\160', '\007', '\022', '\104', '\202', '\004', + '\253', '\040', '\101', '\061', '\110', '\360', '\015', '\022', + '\344', '\203', '\004', '\023', '\041', '\101', '\113', '\110', + '\160', '\024', '\022', '\204', '\205', '\004', '\173', '\041', + '\101', '\145', '\110', '\360', '\032', '\022', '\044', '\207', + '\004', '\343', '\041', '\101', '\177', '\110', '\160', '\001', + '\244', '\001', '\000', '\006', '\162', '\130', '\202', '\034', + '\312', '\040', '\207', '\077', '\310', '\041', '\023', '\162', + '\230', '\205', '\034', '\232', '\041', '\207', '\163', '\310', + '\041', '\040', '\162', '\330', '\210', '\034', '\152', '\042', + '\207', '\247', '\310', '\041', '\055', '\162', '\030', '\214', + '\034', '\072', '\043', '\207', '\333', '\310', '\041', '\072', + '\162', '\130', '\217', '\034', '\012', '\040', '\045', '\000', + '\170', '\000', '\030', '\071', '\000', '\306', '\024', '\200', + '\321', '\006', '\140', '\034', '\002', '\030', '\241', '\000', + '\306', '\056', '\200', '\121', '\015', '\140', '\274', '\003', + '\030', '\011', '\001', '\306', '\110', '\200', '\321', '\023', + '\140', '\134', '\005', '\030', '\121', '\142', '\220', '\142', + '\200', '\121', '\032', '\140', '\374', '\006', '\030', '\331', + '\001', '\306', '\174', '\200', '\321', '\000', '\106', '\231', + '\200', '\121', '\100', '\140', '\224', '\026', '\030', '\105', + '\007', '\106', '\071', '\202', '\121', '\250', '\140', '\224', + '\060', '\030', '\305', '\015', '\106', '\331', '\203', '\121', + '\020', '\141', '\224', '\112', '\030', '\105', '\024', '\106', + '\171', '\205', '\121', '\170', '\141', '\224', '\144', '\030', + '\305', '\032', '\106', '\031', '\207', '\121', '\340', '\141', + '\224', '\176', '\030', '\105', '\001', '\005', '\001', '\300', + '\005', '\142', '\111', '\202', '\130', '\306', '\040', '\226', + '\076', '\210', '\345', '\022', '\142', '\211', '\205', '\130', + '\226', '\041', '\226', '\162', '\210', '\345', '\037', '\142', + '\311', '\210', '\130', '\146', '\042', '\226', '\246', '\210', + '\345', '\054', '\142', '\011', '\214', '\130', '\066', '\043', + '\226', '\332', '\210', '\345', '\071', '\142', '\111', '\217', + '\130', '\006', '\040', '\063', '\000', '\160', '\000', '\066', + '\067', '\200', '\115', '\024', '\140', '\263', '\006', '\330', + '\024', '\002', '\066', '\237', '\200', '\115', '\056', '\140', + '\063', '\015', '\330', '\264', '\003', '\066', '\007', '\201', + '\115', '\110', '\140', '\263', '\023', '\330', '\124', '\005', + '\066', '\157', '\201', '\115', '\142', '\140', '\063', '\032', + '\330', '\364', '\006', '\066', '\327', '\201', '\115', '\174', + '\140', '\263', '\000', '\310', '\222', '\000', '\262', '\076', + '\200', '\054', '\026', '\040', '\053', '\007', '\310', '\062', + '\002', '\262', '\246', '\200', '\054', '\060', '\040', '\013', + '\030', '\061', '\011', '\127', '\013', '\022', '\222', '\065', + '\000', '\170', '\340', '\242', '\030', '\315', '\250', '\007', + '\150', '\102', '\000', '\007', '\174', '\300', '\001', '\035', + '\061', '\210', '\012', '\052', '\060', '\322', '\222', '\222', + '\364', '\244', '\012', '\051', '\100', '\001', '\034', '\130', + '\000', '\220', '\022', '\040', '\244', '\000', '\070', '\100', + '\000', '\006', '\020', '\200', '\007', '\010', '\300', '\000', + '\002', '\170', '\226', '\003', '\210', '\345', '\000', '\007', + '\110', '\100', '\233', '\125', '\221', '\010', '\261', '\016', + '\340', '\200', '\233', '\346', '\024', '\132', '\011', '\110', + '\100', '\016', '\271', '\365', '\322', '\017', '\274', '\024', + '\000', '\037', '\240', '\111', '\004', '\046', '\120', '\201', + '\014', '\104', '\040', '\247', '\002', '\330', '\150', '\102', + '\042', '\020', '\001', '\005', '\144', '\304', '\251', '\057', + '\015', '\253', '\130', '\301', '\330', '\255', '\003', '\210', + '\025', '\246', '\011', '\341', '\301', '\131', '\327', '\112', + '\200', '\301', '\050', '\204', '\255', '\077', '\070', '\153', + '\102', '\176', '\320', '\055', '\205', '\320', '\265', '\256', + '\006', '\271', '\053', '\136', '\365', '\132', '\127', '\272', + '\262', '\125', '\255', '\154', '\035', '\153', '\140', '\305', + '\312', '\327', '\155', '\305', '\165', '\260', '\201', '\115', + '\010', '\004', '\020', '\100', '\000', '\001', '\020', '\000', + '\001', '\020', '\210', '\252', '\106', '\034', '\313', '\130', + '\001', '\004', '\100', '\262', '\043', '\371', '\200', '\002', + '\066', '\013', '\313', '\235', '\104', '\226', '\000', '\037', + '\270', '\214', '\101', '\030', '\040', '\201', '\234', '\036', + '\040', '\247', '\022', '\150', '\332', '\266', '\320', '\212', + '\327', '\267', '\255', '\025', '\000', '\060', '\345', '\154', + '\135', '\067', '\253', '\131', '\315', '\142', '\063', '\041', + '\004', '\360', '\200', '\112', '\035', '\100', '\001', '\012', + '\074', '\000', '\246', '\022', '\250', '\200', '\002', '\052', + '\253', '\200', '\012', '\304', '\062', '\131', '\052', '\025', + '\100', '\001', '\062', '\220', '\200', '\210', '\046', '\204', + '\001', '\215', '\355', '\026', '\143', '\033', '\233', '\323', + '\227', '\032', '\045', '\131', '\326', '\105', '\300', '\164', + '\237', '\005', '\333', '\012', '\174', '\364', '\003', '\025', + '\140', '\055', '\154', '\101', '\373', '\124', '\274', '\102', + '\227', '\273', '\006', '\301', '\054', '\136', '\073', '\032', + '\122', '\010', '\054', '\266', '\262', '\226', '\025', '\055', + '\001', '\024', '\300', '\325', '\372', '\172', '\365', '\255', + '\006', '\050', '\300', '\131', '\325', '\353', '\000', '\256', + '\056', '\266', '\261', '\227', '\125', '\310', '\007', '\376', + '\353', '\000', '\367', '\106', '\300', '\044', '\011', '\321', + '\056', '\003', '\066', '\233', '\200', '\017', '\150', '\127', + '\300', '\304', '\152', '\300', '\004', '\014', '\214', '\140', + '\203', '\364', '\227', '\130', '\017', '\250', '\157', '\205', + '\241', '\372', '\336', '\227', '\142', '\125', '\041', '\375', + '\345', '\152', '\210', '\017', '\014', '\342', '\372', '\172', + '\200', '\302', '\034', '\005', '\351', '\333', '\124', '\374', + '\126', '\026', '\237', '\127', '\261', '\225', '\015', '\000', + '\145', '\127', '\102', '\023', '\311', '\252', '\367', '\040', + '\063', '\216', '\161', '\211', '\043', '\360', '\337', '\214', + '\300', '\064', '\304', '\031', '\250', '\100', '\005', '\032', + '\020', '\000', '\255', '\276', '\215', '\276', '\134', '\375', + '\100', '\175', '\025', '\362', '\000', '\011', '\070', '\331', + '\247', '\116', '\176', '\100', '\211', '\213', '\105', '\054', + '\022', '\047', '\244', '\311', '\116', '\316', '\262', '\004', + '\244', '\234', '\220', '\320', '\142', '\270', '\130', '\352', + '\365', '\162', '\115', '\251', '\074', '\145', '\142', '\131', + '\325', '\312', '\006', '\251', '\157', '\004', '\224', '\274', + '\344', '\204', '\270', '\364', '\254', '\033', '\346', '\200', + '\166', '\347', '\214', '\000', '\245', '\052', '\204', '\253', + '\011', '\050', '\300', '\000', '\012', '\220', '\000', '\256', + '\152', '\204', '\312', '\140', '\276', '\163', '\004', '\066', + '\040', '\144', '\065', '\337', '\171', '\002', '\124', '\255', + '\352', '\231', '\167', '\254', '\146', '\064', '\207', '\261', + '\276', '\017', '\040', '\263', '\233', '\033', '\035', '\201', + '\012', '\024', '\370', '\312', '\220', '\346', '\263', '\237', + '\047', '\315', '\123', '\024', '\167', '\071', '\261', '\133', + '\245', '\264', '\243', '\325', '\314', '\331', '\362', '\246', + '\271', '\276', '\102', '\256', '\300', '\006', '\042', '\040', + '\350', '\315', '\316', '\027', '\311', '\255', '\366', '\252', + '\130', '\005', '\334', '\341', '\234', '\006', '\330', '\315', + '\130', '\315', '\365', '\206', '\211', '\125', '\135', '\355', + '\272', '\027', '\304', '\164', '\236', '\363', '\206', '\347', + '\313', '\352', '\326', '\146', '\366', '\271', '\220', '\155', + '\155', '\201', '\075', '\300', '\125', '\043', '\017', '\013', + '\303', '\152', '\346', '\362', '\110', '\056', '\034', '\000', + '\107', '\273', '\027', '\002', '\314', '\066', '\361', '\116', + '\372', '\033', '\132', '\107', '\223', '\066', '\247', '\066', + '\375', '\060', '\115', '\106', '\174', '\142', '\053', '\027', + '\113', '\302', '\206', '\176', '\053', '\266', '\304', '\272', + '\141', '\000', '\210', '\204', '\001', '\164', '\116', '\152', + '\016', '\213', '\225', '\347', '\075', '\367', '\131', '\041', + '\006', '\140', '\153', '\273', '\217', '\225', '\352', '\012', + '\024', '\173', '\044', '\350', '\156', '\363', '\264', '\325', + '\274', '\357', '\107', '\163', '\065', '\322', '\304', '\032', + '\111', '\266', '\043', '\160', '\342', '\137', '\277', '\145', + '\002', '\222', '\036', '\070', '\042', '\035', '\015', '\000', + '\160', '\143', '\125', '\002', '\014', '\330', '\211', '\232', + '\063', '\340', '\134', '\101', '\167', '\365', '\276', '\122', + '\255', '\264', '\220', '\157', '\173', '\147', '\131', '\323', + '\127', '\343', '\134', '\345', '\070', '\004', '\050', '\356', + '\140', '\000', '\253', '\027', '\003', '\141', '\065', '\337', + '\113', '\061', '\360', '\126', '\120', '\033', '\104', '\346', + '\004', '\200', '\371', '\113', '\175', '\142', '\220', '\340', + '\036', '\327', '\330', '\100', '\127', '\067', '\133', '\133', + '\134', '\001', '\225', '\132', '\032', '\255', '\337', '\376', + '\042', '\152', '\125', '\273', '\125', '\155', '\052', '\240', + '\277', '\043', '\341', '\052', '\155', '\311', '\013', '\323', + '\131', '\317', '\172', '\264', '\245', '\045', '\055', '\306', + '\041', '\200', '\161', '\205', '\144', '\205', '\133', '\375', + '\125', '\365', '\004', '\010', '\115', '\361', '\145', '\063', + '\034', '\252', '\333', '\242', '\200', '\002', '\124', '\252', + '\000', '\012', '\160', '\153', '\300', '\064', '\336', '\326', + '\215', '\055', '\034', '\201', '\013', '\154', '\140', '\003', + '\166', '\147', '\271', '\171', '\235', '\234', '\161', '\246', + '\122', '\035', '\355', '\020', '\321', '\357', '\027', '\267', + '\245', '\134', '\307', '\362', '\174', '\044', '\214', '\005', + '\372', '\306', '\057', '\160', '\031', '\017', '\134', '\340', + '\361', '\027', '\260', '\100', '\157', '\335', '\276', '\223', + '\276', '\003', '\075', '\361', '\002', '\030', '\200', '\151', + '\271', '\245', '\365', '\214', '\073', '\173', '\044', '\005', + '\150', '\273', '\332', '\045', '\230', '\054', '\315', '\177', + '\021', '\002', '\030', '\240', '\000', '\007', '\342', '\236', + '\171', '\323', '\042', '\200', '\002', '\213', '\345', '\100', + '\340', '\035', '\133', '\000', '\011', '\244', '\176', '\365', + '\102', '\007', '\260', '\210', '\161', '\053', '\022', '\142', + '\257', '\171', '\323', '\356', '\366', '\061', '\222', '\331', + '\374', '\334', '\252', '\370', '\236', '\370', '\020', '\314', + '\314', '\361', '\201', '\277', '\131', '\330', '\016', '\037', + '\370', '\363', '\175', '\351', '\363', '\377', '\015', '\000', + '\015', '\250', '\264', '\000', '\015', '\140', '\151', '\120', + '\070', '\115', '\345', '\003', '\107', '\367', '\261', '\120', + '\375', '\362', '\255', '\203', '\037', '\376', '\061', '\217', + '\337', '\000', '\005', '\361', '\062', '\302', '\061', '\333', + '\174', '\365', '\023', '\013', '\263', '\340', '\007', '\153', + '\130', '\061', '\233', '\170', '\371', '\067', '\265', '\370', + '\120', '\335', '\157', '\102', '\332', '\257', '\377', '\053', + '\147', '\371', '\002', '\131', '\046', '\155', '\152', '\007', + '\000', '\134', '\105', '\125', '\213', '\366', '\066', '\042', + '\061', '\142', '\273', '\027', '\022', '\031', '\241', '\200', + '\150', '\106', '\132', '\331', '\324', '\150', '\025', '\066', + '\200', '\016', '\130', '\141', '\315', '\127', '\201', '\032', + '\347', '\125', '\047', '\247', '\130', '\016', '\220', '\001', + '\101', '\046', '\144', '\210', '\266', '\123', '\010', '\110', + '\200', '\022', '\230', '\140', '\031', '\101', '\151', '\025', + '\006', '\201', '\050', '\270', '\177', '\231', '\261', '\202', + '\014', '\110', '\202', '\262', '\146', '\152', '\303', '\222', + '\141', '\007', '\147', '\054', '\073', '\106', '\203', '\023', + '\100', '\144', '\043', '\230', '\115', '\330', '\026', '\001', + '\034', '\147', '\202', '\026', '\326', '\203', '\077', '\210', + '\165', '\101', '\310', '\154', '\103', '\010', '\000', '\003', + '\310', '\203', '\106', '\350', '\134', '\315', '\247', '\204', + '\076', '\350', '\134', '\244', '\225', '\161', '\146', '\167', + '\204', '\040', '\106', '\001', '\016', '\120', '\000', '\302', + '\265', '\155', '\162', '\123', '\155', '\040', '\325', '\020', + '\340', '\027', '\201', '\335', '\126', '\141', '\211', '\007', + '\206', '\134', '\210', '\177', '\144', '\210', '\146', '\115', + '\310', '\155', '\145', '\270', '\203', '\371', '\066', '\177', + '\100', '\270', '\156', '\156', '\110', '\204', '\160', '\170', + '\177', '\006', '\321', '\204', '\155', '\110', '\207', '\230', + '\101', '\000', '\210', '\244', '\200', '\023', '\210', '\115', + '\001', '\007', '\175', '\106', '\301', '\207', '\157', '\050', + '\210', '\162', '\110', '\210', '\110', '\210', '\115', '\206', + '\230', '\206', '\004', '\067', '\022', '\117', '\025', '\125', + '\062', '\310', '\201', '\037', '\070', '\001', '\042', '\010', + '\133', '\106', '\321', '\150', '\106', '\066', '\206', '\226', + '\150', '\206', '\231', '\130', '\207', '\330', '\264', '\211', + '\344', '\107', '\202', '\117', '\270', '\162', '\025', '\026', + '\141', '\023', '\120', '\200', '\104', '\206', '\020', '\115', + '\130', '\137', '\052', '\107', '\142', '\023', '\001', '\056', + '\201', '\120', '\010', '\206', '\240', '\010', '\201', '\000', + '\010', '\260', '\150', '\010', '\177', '\160', '\056', '\212', + '\140', '\056', '\204', '\140', '\010', '\207', '\240', '\213', + '\274', '\150', '\056', '\260', '\330', '\213', '\200', '\260', + '\213', '\302', '\270', '\213', '\211', '\260', '\007', '\264', + '\310', '\213', '\200', '\220', '\214', '\302', '\030', '\214', + '\346', '\062', '\010', '\344', '\322', '\007', '\200', '\000', + '\215', '\204', '\040', '\010', '\202', '\060', '\056', '\325', + '\170', '\215', '\321', '\010', '\060', '\210', '\220', '\007', + '\347', '\142', '\010', '\310', '\210', '\215', '\322', '\070', + '\056', '\202', '\160', '\213', '\343', '\002', '\010', '\201', + '\240', '\215', '\353', '\002', '\215', '\374', '\062', '\216', + '\206', '\220', '\215', '\354', '\010', '\214', '\206', '\200', + '\010', '\313', '\010', '\213', '\364', '\230', '\214', '\206', + '\120', '\217', '\343', '\162', '\213', '\260', '\230', '\010', + '\200', '\040', '\010', '\320', '\070', '\010', '\176', '\260', + '\214', '\371', '\370', '\217', '\320', '\350', '\217', '\201', + '\140', '\214', '\172', '\220', '\214', '\210', '\300', '\217', + '\206', '\340', '\217', '\311', '\010', '\221', '\375', '\370', + '\007', '\011', '\371', '\220', '\172', '\120', '\221', '\010', + '\151', '\214', '\372', '\330', '\220', '\314', '\350', '\007', + '\025', '\051', '\010', '\263', '\010', '\213', '\205', '\300', + '\007', '\037', '\031', '\222', '\017', '\251', '\217', '\022', + '\171', '\222', '\021', '\211', '\222', '\054', '\271', '\222', + '\056', '\331', '\217', '\055', '\011', '\223', '\025', '\171', + '\010', '\201', '\060', '\223', '\046', '\231', '\222', '\206', + '\060', '\220', '\060', '\371', '\222', '\052', '\271', '\223', + '\076', '\331', '\223', '\100', '\231', '\222', '\102', '\311', + '\222', '\030', '\031', '\223', '\101', '\151', '\224', '\103', + '\311', '\223', '\211', '\160', '\223', '\110', '\331', '\224', + '\112', '\331', '\224', '\105', '\271', '\222', '\121', '\331', + '\217', '\013', '\011', '\213', '\350', '\050', '\010', '\124', + '\211', '\217', '\106', '\131', '\220', '\077', '\311', '\225', + '\100', '\151', '\010', '\362', '\230', '\221', '\363', '\270', + '\214', '\273', '\210', '\010', '\141', '\211', '\216', '\032', + '\251', '\225', '\152', '\131', '\213', '\372', '\010', '\226', + '\370', '\050', '\217', '\136', '\351', '\225', '\367', '\310', + '\226', '\153', '\171', '\216', '\165', '\351', '\226', '\164', + '\011', '\223', '\000', '\171', '\224', '\021', '\271', '\220', + '\342', '\262', '\214', '\004', '\271', '\214', '\173', '\051', + '\224', '\016', '\231', '\222', '\207', '\120', '\230', '\006', + '\171', '\222', '\257', '\030', '\213', '\050', '\211', '\007', + '\311', '\250', '\010', '\205', '\251', '\223', '\274', '\350', + '\220', '\205', '\040', '\231', '\043', '\371', '\230', '\205', + '\211', '\007', '\213', '\171', '\214', '\014', '\171', '\213', + '\320', '\250', '\010', '\310', '\370', '\231', '\173', '\040', + '\010', '\273', '\250', '\010', '\216', '\131', '\213', '\114', + '\111', '\232', '\206', '\060', '\222', '\252', '\371', '\217', + '\323', '\030', '\213', '\173', '\260', '\231', '\322', '\030', + '\214', '\016', '\251', '\010', '\372', '\150', '\233', '\217', + '\151', '\224', '\270', '\011', '\213', '\273', '\311', '\230', + '\271', '\371', '\233', '\274', '\211', '\224', '\362', '\330', + '\233', '\304', '\171', '\233', '\306', '\011', '\234', '\276', + '\031', '\234', '\074', '\131', '\234', '\310', '\311', '\234', + '\312', '\131', '\213', '\265', '\151', '\222', '\316', '\231', + '\234', '\324', '\331', '\233', '\051', '\211', '\010', '\322', + '\171', '\234', '\317', '\131', '\235', '\332', '\151', '\227', + '\265', '\070', '\234', '\335', '\071', '\235', '\342', '\031', + '\236', '\344', '\331', '\234', '\345', '\151', '\217', '\016', + '\111', '\223', '\346', '\271', '\236', '\274', '\051', '\217', + '\146', '\371', '\230', '\136', '\263', '\023', '\326', '\262', + '\055', '\010', '\321', '\020', '\040', '\221', '\021', '\017', + '\104', '\032', '\051', '\041', '\022', '\005', '\221', '\031', + '\240', '\221', '\161', '\160', '\141', '\022', '\122', '\266', + '\022', '\254', '\126', '\025', '\127', '\341', '\166', '\122', + '\021', '\023', '\027', '\240', '\103', '\000', '\220', '\001', + '\325', '\007', '\000', '\070', '\041', '\173', '\101', '\261', + '\121', '\121', '\065', '\023', '\041', '\000', '\000', '\042', + '\000', '\000', '\043', '\000', '\000', '\044', '\000', '\000', + '\045', '\000', '\000', '\046', '\000', '\000', '\121', '\003', + '\025', '\051', '\000', '\000', '\052', '\000', '\000', '\053', + '\000', '\000', '\134', '\061', '\121', '\177', '\362', '\002', + '\000', '\000', '\003', '\125', '\002', '\000', '\136', '\061', + '\003', '\000', '\060', '\065', '\065', '\000', '\000', '\066', + '\000', '\000', '\067', '\000', '\000', '\070', '\000', '\000', + '\112', '\242', '\003', '\000', '\260', '\003', '\000', '\060', + '\030', '\075', '\000', '\000', '\140', '\101', '\127', '\072', + '\121', '\065', '\102', '\340', '\042', '\000', '\100', '\004', + '\000', '\040', '\026', '\106', '\000', '\000', '\055', '\222', + '\043', '\111', '\000', '\000', '\112', '\000', '\000', '\144', + '\301', '\004', '\277', '\001', '\000', '\264', '\362', '\004', + '\036', '\001', '\000', '\121', '\120', '\036', '\340', '\001', + '\000', '\202', '\122', '\005', '\000', '\140', '\005', '\254', + '\122', '\053', '\000', '\200', '\033', '\132', '\000', '\000', + '\150', '\301', '\005', '\000', '\320', '\005', '\000', '\340', + '\005', '\000', '\360', '\005', '\000', '\000', '\006', '\000', + '\020', '\006', '\000', '\040', '\006', '\000', '\060', '\034', + '\025', '\121', '\006', '\000', '\140', '\006', '\000', '\160', + '\006', '\000', '\200', '\006', '\000', '\240', '\026', '\152', + '\000', '\000', '\234', '\301', '\006', '\000', '\360', '\035', + '\156', '\000', '\000', '\157', '\000', '\000', '\160', '\000', + '\000', '\161', '\000', '\000', '\162', '\000', '\000', '\163', + '\000', '\000', '\164', '\000', '\000', '\134', '\143', '\007', + '\000', '\160', '\007', '\000', '\300', '\026', '\156', '\241', + '\007', '\000', '\260', '\007', '\000', '\300', '\007', '\000', + '\320', '\007', '\000', '\340', '\007', '\000', '\360', '\007', + '\000', '\360', '\017', '\260', '\032', '\253', '\262', '\072', + '\253', '\264', '\132', '\253', '\266', '\172', '\253', '\270', + '\172', '\253', '\103', '\021', '\010', '\000', '\340', '\065', + '\203', '\000', '\000', '\162', '\121', '\010', '\000', '\140', + '\010', '\000', '\160', '\010', '\074', '\001', '\000', '\211', + '\000', '\000', '\212', '\000', '\000', '\213', '\000', '\000', + '\214', '\000', '\000', '\215', '\000', '\000', '\216', '\000', + '\000', '\166', '\001', '\011', '\000', '\020', '\011', '\000', + '\040', '\011', '\000', '\060', '\011', '\000', '\100', '\011', + '\000', '\120', '\011', '\000', '\140', '\011', '\000', '\160', + '\011', '\000', '\360', '\020', '\231', '\000', '\000', '\232', + '\000', '\000', '\233', '\000', '\000', '\172', '\321', '\011', + '\000', '\340', '\011', '\000', '\360', '\011', '\000', '\000', + '\012', '\000', '\020', '\012', '\000', '\040', '\012', '\000', + '\060', '\012', '\000', '\100', '\012', '\000', '\120', '\012', + '\000', '\140', '\012', '\000', '\160', '\012', '\000', '\200', + '\012', '\000', '\320', '\027', '\252', '\000', '\000', '\253', + '\000', '\000', '\254', '\000', '\000', '\255', '\000', '\000', + '\256', '\000', '\000', '\257', '\160', '\024', '\000', '\360', + '\027', '\262', '\000', '\000', '\201', '\101', '\013', '\000', + '\120', '\013', '\000', '\100', '\066', '\267', '\000', '\000', + '\270', '\000', '\000', '\271', '\000', '\000', '\272', '\000', + '\000', '\273', '\000', '\000', '\274', '\000', '\000', '\275', + '\000', '\000', '\276', '\000', '\000', '\277', '\000', '\000', + '\300', '\000', '\000', '\205', '\041', '\014', '\000', '\140', + '\066', '\304', '\000', '\000', '\305', '\000', '\000', '\306', + '\000', '\000', '\307', '\000', '\000', '\310', '\000', '\000', + '\311', '\000', '\000', '\312', '\000', '\000', '\313', '\000', + '\000', '\314', '\000', '\000', '\315', '\000', '\000', '\316', + '\000', '\000', '\317', '\000', '\000', '\150', '\023', '\015', + '\000', '\160', '\030', '\323', '\000', '\000', '\324', '\000', + '\000', '\325', '\000', '\000', '\326', '\000', '\000', '\327', + '\000', '\000', '\330', '\000', '\000', '\331', '\000', '\000', + '\211', '\261', '\015', '\000', '\300', '\015', '\000', '\240', + '\066', '\336', '\000', '\000', '\337', '\260', '\023', '\113', + '\143', '\264', '\023', '\321', '\014', '\153', '\333', '\266', + '\006', '\301', '\266', '\157', '\353', '\266', '\152', '\033', + '\267', '\164', '\073', '\267', '\166', '\013', '\267', '\167', + '\053', '\267', '\170', '\273', '\267', '\172', '\333', '\267', + '\165', '\313', '\267', '\177', '\353', '\267', '\171', '\033', + '\270', '\204', '\073', '\270', '\206', '\013', '\270', '\207', + '\053', '\270', '\210', '\273', '\270', '\212', '\333', '\270', + '\205', '\313', '\270', '\217', '\353', '\270', '\211', '\033', + '\271', '\224', '\073', '\271', '\226', '\013', '\271', '\227', + '\053', '\271', '\230', '\273', '\271', '\232', '\333', '\271', + '\225', '\313', '\271', '\237', '\353', '\271', '\231', '\033', + '\272', '\244', '\073', '\272', '\246', '\013', '\272', '\247', + '\053', '\272', '\250', '\273', '\272', '\252', '\333', '\272', + '\245', '\313', '\272', '\257', '\353', '\272', '\251', '\033', + '\273', '\264', '\073', '\273', '\266', '\213', '\272', '\012', + '\221', '\266', '\012', '\161', '\134', '\101', '\005', '\241', + '\011', '\321', '\241', '\006', '\061', '\121', '\006', '\221', + '\243', '\171', '\225', '\020', '\071', '\142', '\020', '\141', + '\152', '\020', '\155', '\152', '\020', '\303', '\141', '\020', + '\214', '\152', '\020', '\134', '\143', '\020', '\254', '\152', + '\020', '\306', '\152', '\020', '\326', '\152', '\020', '\347', + '\152', '\020', '\370', '\152', '\020', '\011', '\153', '\020', + '\030', '\153', '\020', '\051', '\153', '\020', '\071', '\153', + '\020', '\113', '\153', '\020', '\133', '\153', '\020', '\341', + '\260', '\066', '\011', '\061', '\017', '\011', '\301', '\017', + '\011', '\121', '\000', '\023', '\061', '\211', '\214', '\047', + '\023', '\023', '\141', '\002', '\023', '\321', '\002', '\023', + '\141', '\003', '\023', '\021', '\004', '\023', '\201', '\004', + '\023', '\001', '\005', '\023', '\241', '\005', '\023', '\121', + '\006', '\023', '\361', '\006', '\023', '\241', '\007', '\023', + '\061', '\010', '\023', '\141', '\032', '\006', '\341', '\010', + '\023', '\121', '\011', '\023', '\301', '\011', '\023', '\041', + '\012', '\023', '\161', '\012', '\023', '\261', '\012', '\023', + '\361', '\012', '\023', '\121', '\013', '\213', '\063', '\021', + '\277', '\060', '\021', '\303', '\060', '\021', '\311', '\060', + '\021', '\317', '\360', '\070', '\023', '\241', '\015', '\023', + '\101', '\016', '\023', '\221', '\016', '\023', '\361', '\016', + '\023', '\161', '\017', '\227', '\021', '\021', '\232', '\147', + '\020', '\005', '\020', '\021', '\247', '\145', '\020', '\011', + '\020', '\021', '\013', '\020', '\021', '\015', '\020', '\021', + '\066', '\225', '\146', '\021', '\061', '\001', '\231', '\023', + '\021', '\027', '\020', '\021', '\031', '\020', '\021', '\033', + '\020', '\021', '\035', '\020', '\021', '\037', '\020', '\021', + '\041', '\020', '\021', '\043', '\020', '\021', '\045', '\020', + '\021', '\047', '\020', '\021', '\051', '\020', '\021', '\053', + '\020', '\021', '\055', '\320', '\071', '\021', '\021', '\003', + '\021', '\061', '\003', '\021', '\121', '\003', '\021', '\161', + '\003', '\021', '\041', '\004', '\021', '\301', '\004', '\021', + '\221', '\005', '\021', '\121', '\006', '\247', '\023', '\021', + '\172', '\020', '\021', '\174', '\020', '\021', '\176', '\020', + '\021', '\200', '\020', '\021', '\202', '\020', '\021', '\204', + '\020', '\021', '\206', '\020', '\021', '\210', '\260', '\072', + '\021', '\301', '\010', '\021', '\341', '\010', '\021', '\001', + '\011', '\021', '\041', '\011', '\021', '\101', '\011', '\021', + '\141', '\011', '\021', '\201', '\011', '\021', '\241', '\011', + '\021', '\301', '\011', '\021', '\341', '\011', '\021', '\001', + '\012', '\021', '\041', '\012', '\257', '\023', '\021', '\246', + '\020', '\021', '\250', '\020', '\021', '\252', '\020', '\021', + '\254', '\020', '\021', '\256', '\020', '\021', '\270', '\020', + '\021', '\274', '\020', '\021', '\307', '\020', '\021', '\322', + '\020', '\021', '\333', '\020', '\021', '\340', '\220', '\073', + '\021', '\241', '\016', '\021', '\361', '\016', '\021', '\101', + '\017', '\021', '\221', '\017', '\021', '\341', '\017', '\062', + '\354', '\023', '\010', '\340', '\023', '\015', '\340', '\023', + '\022', '\340', '\023', '\027', '\340', '\023', '\034', '\340', + '\023', '\041', '\060', '\074', '\076', '\261', '\002', '\076', + '\001', '\003', '\076', '\121', '\003', '\076', '\241', '\003', + '\076', '\361', '\003', '\076', '\101', '\004', '\076', '\221', + '\004', '\076', '\341', '\004', '\076', '\061', '\005', '\076', + '\201', '\005', '\076', '\321', '\005', '\076', '\041', '\006', + '\315', '\343', '\023', '\154', '\340', '\023', '\161', '\340', + '\023', '\166', '\340', '\023', '\173', '\340', '\023', '\200', + '\340', '\023', '\205', '\340', '\023', '\212', '\340', '\023', + '\217', '\340', '\023', '\224', '\340', '\023', '\231', '\340', + '\023', '\236', '\340', '\023', '\243', '\160', '\075', '\076', + '\321', '\012', '\076', '\041', '\013', '\076', '\161', '\013', + '\076', '\301', '\013', '\076', '\021', '\014', '\076', '\141', + '\014', '\076', '\261', '\014', '\076', '\001', '\015', '\076', + '\121', '\015', '\076', '\241', '\015', '\076', '\361', '\015', + '\076', '\101', '\016', '\341', '\343', '\023', '\356', '\340', + '\023', '\363', '\340', '\023', '\370', '\340', '\023', '\375', + '\340', '\023', '\216', '\145', '\020', '\146', '\065', '\132', + '\035', '\021', '\001', '\035', '\141', '\001', '\035', '\261', + '\001', '\035', '\001', '\002', '\035', '\121', '\002', '\353', + '\323', '\021', '\057', '\320', '\021', '\064', '\320', '\021', + '\071', '\320', '\021', '\076', '\320', '\021', '\103', '\320', + '\021', '\110', '\320', '\021', '\115', '\320', '\021', '\122', + '\320', '\021', '\127', '\320', '\021', '\134', '\320', '\021', + '\141', '\320', '\021', '\146', '\120', '\077', '\035', '\001', + '\007', '\035', '\121', '\007', '\035', '\241', '\007', '\035', + '\361', '\007', '\035', '\101', '\010', '\035', '\221', '\010', + '\035', '\341', '\010', '\035', '\061', '\011', '\035', '\201', + '\011', '\035', '\321', '\011', '\035', '\041', '\012', '\035', + '\161', '\012', '\377', '\323', '\021', '\261', '\320', '\021', + '\266', '\320', '\021', '\273', '\340', '\323', '\302', '\221', + '\006', '\151', '\000', '\003', '\146', '\235', '\247', '\143', + '\135', '\326', '\060', '\140', '\045', '\141', '\220', '\326', + '\146', '\355', '\025', '\155', '\075', '\006', '\144', '\155', + '\326', '\064', '\032', '\327', '\163', '\015', '\003', '\123', + '\143', '\327', '\152', '\175', '\243', '\172', '\155', '\326', + '\071', '\332', '\327', '\060', '\260', '\243', '\175', '\035', + '\003', '\060', '\072', '\330', '\154', '\355', '\326', '\061', + '\000', '\327', '\210', '\135', '\327', '\210', '\235', '\327', + '\210', '\315', '\327', '\210', '\375', '\327', '\210', '\055', + '\330', '\156', '\335', '\051', '\150', '\055', '\327', '\145', + '\055', '\003', '\207', '\215', '\331', '\060', '\040', '\003', + '\212', '\315', '\331', '\062', '\300', '\330', '\240', '\355', + '\330', '\240', '\015', '\331', '\240', '\055', '\331', '\240', + '\115', '\331', '\234', '\075', '\003', '\205', '\355', '\326', + '\063', '\260', '\331', '\163', '\075', '\003', '\237', '\035', + '\333', '\242', '\035', '\333', '\244', '\035', '\333', '\246', + '\035', '\333', '\250', '\035', '\333', '\073', '\072', '\007', + '\160', '\020', '\006', '\143', '\000', '\250', '\145', '\200', + '\007', '\143', '\300', '\006', '\141', '\360', '\035', '\161', + '\120', '\007', '\157', '\100', '\007', '\320', '\001', '\046', + '\000', '\340', '\006', '\336', '\041', '\006', '\145', '\040', + '\007', '\163', '\220', '\006', '\147', '\360', '\250', '\145', + '\302', '\006', '\306', '\175', '\251', '\160', '\060', '\335', + '\301', '\355', '\006', '\233', '\172', '\334', '\335', '\115', + '\335', '\170', '\122', '\021', '\311', '\275', '\334', '\323', + '\155', '\335', '\150', '\260', '\251', '\277', '\135', '\047', + '\156', '\300', '\006', '\145', '\140', '\006', '\354', '\115', + '\047', '\371', '\041', '\007', '\352', '\035', '\336', '\163', + '\300', '\334', '\366', '\075', '\007', '\234', '\001', '\007', + '\154', '\120', '\007', '\231', '\072', '\006', '\146', '\162', + '\046', '\205', '\232', '\007', '\160', '\200', '\006', '\371', + '\041', '\251', '\351', '\375', '\006', '\025', '\061', '\007', + '\306', '\075', '\007', '\206', '\252', '\007', '\323', '\035', + '\251', '\366', '\001', '\250', '\164', '\160', '\007', '\221', + '\112', '\007', '\150', '\120', '\047', '\200', '\312', '\046', + '\165', '\160', '\251', '\146', '\220', '\006', '\166', '\000', + '\250', '\325', '\315', '\026', '\373', '\061', '\342', '\217', + '\132', '\006', '\367', '\375', '\334', '\151', '\002', '\250', + '\002', '\316', '\006', '\366', '\201', '\251', '\362', '\041', + '\046', '\157', '\000', '\343', '\217', '\012', '\337', '\163', + '\220', '\251', '\145', '\220', '\334', '\141', '\300', '\250', + '\147', '\120', '\047', '\141', '\240', '\337', '\224', '\132', + '\007', '\145', '\220', '\337', '\151', '\020', '\343', '\101', + '\336', '\037', '\000', '\260', '\244', '\057', '\342', '\244', + '\120', '\052', '\245', '\000', '\100', '\245', '\126', '\212', + '\245', '\000', '\240', '\245', '\146', '\321', '\245', '\137', + '\032', '\246', '\346', '\061', '\005', '\144', '\012', '\000', + '\146', '\212', '\246', '\127', '\240', '\246', '\154', '\272', + '\247', '\162', '\020', '\006', '\153', '\120', '\006', '\164', + '\000', '\337', '\362', '\275', '\247', '\300', '\275', '\006', + '\016', '\336', '\326', '\206', '\052', '\006', '\145', '\076', + '\006', '\147', '\116', '\007', '\366', '\175', '\006', '\353', + '\175', '\331', '\144', '\055', '\327', '\162', '\060', '\006', + '\336', '\301', '\251', '\224', '\102', '\335', '\002', '\136', + '\047', '\103', '\216', '\336', '\152', '\036', '\336', '\173', + '\332', '\247', '\024', '\001', '\000', '\035', '\076', '\250', + '\205', '\172', '\250', '\000', '\220', '\250', '\213', '\332', + '\250', '\317', '\015', '\251', '\222', '\112', '\251', '\226', + '\212', '\251', '\232', '\312', '\251', '\000', '\340', '\251', + '\240', '\052', '\252', '\000', '\100', '\252', '\162', '\016', + '\334', '\145', '\160', '\350', '\154', '\176', '\251', '\243', + '\036', '\334', '\167', '\236', '\347', '\172', '\115', '\007', + '\151', '\300', '\006', '\370', '\241', '\347', '\151', '\020', + '\003', '\067', '\260', '\243', '\146', '\035', '\006', '\060', + '\172', '\353', '\126', '\162', '\353', '\136', '\161', '\353', + '\064', '\172', '\353', '\123', '\163', '\353', '\067', '\172', + '\353', '\071', '\172', '\353', '\266', '\016', '\003', '\141', + '\320', '\243', '\267', '\256', '\044', '\267', '\256', '\247', + '\267', '\316', '\247', '\267', '\076', '\034', '\267', '\136', + '\021', '\267', '\016', '\250', '\267', '\056', '\250', '\146', + '\055', '\006', '\271', '\016', '\003', '\142', '\260', '\353', + '\334', '\336', '\353', '\334', '\376', '\353', '\334', '\036', + '\354', '\334', '\076', '\354', '\334', '\136', '\354', '\334', + '\176', '\354', '\142', '\240', '\354', '\334', '\316', '\354', + '\334', '\356', '\354', '\334', '\016', '\355', '\334', '\056', + '\355', '\334', '\116', '\355', '\334', '\156', '\355', '\334', + '\216', '\355', '\060', '\060', '\006', '\333', '\076', '\006', + '\336', '\076', '\006', '\340', '\076', '\006', '\342', '\076', + '\006', '\344', '\076', '\006', '\346', '\076', '\006', '\350', + '\076', '\006', '\307', '\076', '\006', '\354', '\076', '\006', + '\356', '\076', '\006', '\360', '\076', '\006', '\362', '\076', + '\006', '\364', '\076', '\006', '\366', '\036', '\334', '\057', + '\272', '\357', '\372', '\116', '\006', '\333', '\116', '\006', + '\336', '\116', '\006', '\340', '\116', '\006', '\342', '\116', + '\006', '\344', '\116', '\006', '\346', '\116', '\006', '\350', + '\116', '\006', '\307', '\116', '\006', '\354', '\116', '\006', + '\356', '\116', '\006', '\360', '\116', '\006', '\362', '\116', + '\006', '\364', '\116', '\006', '\366', '\036', '\353', '\146', + '\115', '\006', '\372', '\136', '\006', '\333', '\136', '\006', + '\336', '\136', '\006', '\340', '\136', '\006', '\342', '\136', + '\006', '\344', '\136', '\006', '\346', '\136', '\006', '\350', + '\136', '\006', '\307', '\136', '\006', '\354', '\136', '\006', + '\356', '\136', '\006', '\360', '\136', '\006', '\362', '\136', + '\006', '\364', '\316', '\037', '\146', '\135', '\006', '\370', + '\036', '\337', '\031', '\157', '\006', '\333', '\156', '\006', + '\336', '\156', '\006', '\340', '\156', '\006', '\342', '\156', + '\006', '\344', '\156', '\006', '\346', '\156', '\006', '\350', + '\156', '\006', '\307', '\156', '\006', '\354', '\156', '\006', + '\356', '\156', '\006', '\360', '\156', '\006', '\362', '\056', + '\020', '\133', '\157', '\357', '\146', '\200', '\357', '\146', + '\040', '\250', '\302', '\002', '\150', '\023', '\201', '\054', + '\025', '\307', '\055', '\331', '\362', '\367', '\370', '\206', + '\055', '\322', '\042', '\370', '\043', '\261', '\124', '\370', + '\060', '\237', '\015', '\021', '\370', '\312', '\002', + +}; + +static const char file_cursor[] = { + '\037', '\235', '\214', '\001', '\314', '\214', '\201', '\203', + '\000', '\200', '\301', '\000', '\006', '\023', '\032', '\044', + '\227', '\020', '\121', '\102', '\001', '\012', '\023', '\222', + '\111', '\310', '\006', '\041', '\000', '\002', '\012', '\055', + '\042', '\030', '\140', '\020', '\232', '\306', '\210', '\006', + '\151', '\114', '\060', '\210', '\015', '\043', '\000', '\020', + '\040', '\001', '\020', '\261', '\310', '\000', '\203', '\101', + '\040', '\051', '\341', '\100', '\004', '\000', '\045', '\203', + '\101', '\100', '\051', '\321', '\045', '\060', '\010', '\154', + '\103', '\102', '\213', '\012', '\047', '\032', '\104', '\125', + '\002', '\344', '\116', '\220', '\001', '\024', '\044', '\124', + '\241', '\320', '\206', '\305', '\032', '\077', '\165', '\044', + '\014', '\242', '\120', '\251', '\101', '\044', '\012', '\327', + '\044', '\234', '\242', '\320', '\111', '\102', '\060', '\135', + '\023', '\266', '\121', '\370', '\257', '\354', '\077', '\073', + '\012', '\033', '\200', '\014', '\224', '\160', '\310', '\023', + '\050', '\131', '\244', '\044', '\071', '\202', '\204', '\012', + '\000', '\052', '\150', '\312', '\314', '\051', '\003', '\102', + '\304', '\031', '\066', '\171', '\340', '\240', '\231', '\043', + '\002', '\104', '\030', '\071', '\174', '\353', '\270', '\051', + '\343', '\146', '\114', '\235', '\066', '\142', '\312', '\040', + '\236', '\010', '\345', '\111', '\022', '\047', '\124', '\276', + '\114', '\111', '\242', '\245', '\010', '\000', '\043', '\117', + '\060', '\003', '\160', '\054', '\147', '\316', '\033', '\071', + '\000', '\256', '\024', '\231', '\133', '\027', '\200', '\224', + '\042', '\123', '\236', '\060', '\251', '\102', '\045', '\111', + '\150', '\327', '\260', '\145', '\323', '\266', '\355', '\344', + '\013', '\026', '\334', '\261', '\147', '\327', '\016', '\375', + '\045', '\013', '\000', '\054', '\137', '\220', '\254', '\246', + '\153', '\067', '\112', '\225', '\040', '\104', '\276', '\134', + '\111', '\102', '\204', '\012', '\326', '\224', '\330', '\041', + '\044', '\214', '\220', '\320', '\354', '\277', '\170', '\377', + '\014', '\052', '\055', '\233', '\021', '\200', '\166', '\356', + '\017', '\314', '\143', '\137', '\317', '\276', '\275', '\173', + '\244', '\006', '\065', '\001', '\320', '\203', '\050', '\222', + '\041', '\104', '\171', '\022', '\105', '\072', '\224', '\150', + '\116', '\240', '\110', '\200', '\070', '\042', '\207', '\040', + '\221', '\004', '\362', '\110', '\037', '\205', '\104', '\222', + '\110', '\040', '\174', '\030', '\022', '\211', '\042', '\202', + '\040', '\250', '\040', '\203', '\016', '\102', '\070', '\140', + '\044', '\203', '\024', '\162', '\041', '\041', '\205', '\350', + '\161', '\210', '\175', '\370', '\325', '\307', '\137', '\200', + '\221', '\064', '\022', '\310', '\037', '\217', '\104', '\342', + '\210', '\040', '\376', '\225', '\030', '\310', '\205', '\053', + '\172', '\350', '\142', '\036', '\365', '\255', '\230', '\307', + '\207', '\013', '\342', '\121', '\037', '\204', '\170', '\174', + '\210', '\010', '\042', '\072', '\106', '\362', '\143', '\203', + '\000', '\072', '\262', '\307', '\207', '\006', '\336', '\270', + '\337', '\041', '\101', '\376', '\110', '\037', '\206', '\215', + '\350', '\241', '\337', '\040', '\215', '\320', '\250', '\340', + '\041', '\371', '\135', '\231', '\345', '\041', '\370', '\351', + '\307', '\337', '\226', '\135', '\356', '\027', '\046', '\227', + '\133', '\046', '\142', '\045', '\231', '\136', '\046', '\262', + '\107', '\202', '\205', '\164', '\350', '\240', '\041', '\206', + '\350', '\341', '\140', '\041', '\130', '\176', '\170', '\337', + '\232', '\113', '\312', '\051', '\044', '\042', '\162', '\374', + '\007', '\310', '\043', '\175', '\002', '\010', '\111', '\240', + '\177', '\022', '\372', '\210', '\236', '\164', '\052', '\171', + '\337', '\223', '\367', '\225', '\251', '\344', '\041', '\114', + '\326', '\367', '\343', '\205', '\202', '\064', '\162', '\041', + '\225', '\176', '\070', '\042', '\150', '\246', '\202', '\322', + '\341', '\047', '\044', '\236', '\012', '\372', '\147', '\221', + '\200', '\100', '\122', '\340', '\241', '\372', '\041', '\022', + '\147', '\252', '\206', '\064', '\011', '\244', '\244', '\370', + '\331', '\371', '\352', '\176', '\211', '\000', '\122', '\137', + '\200', '\177', '\350', '\147', '\040', '\211', '\206', '\034', + '\202', '\242', '\230', '\200', '\050', '\262', '\344', '\037', + '\213', '\354', '\351', '\152', '\217', '\173', '\006', '\073', + '\041', '\261', '\017', '\012', '\162', '\307', '\177', '\013', + '\332', '\101', '\240', '\205', '\004', '\026', '\262', '\310', + '\205', '\326', '\036', '\353', '\043', '\042', '\174', '\024', + '\033', '\110', '\043', '\174', '\060', '\162', '\252', '\035', + '\377', '\075', '\022', '\110', '\035', '\004', '\232', '\153', + '\045', '\043', '\204', '\144', '\311', '\056', '\221', '\155', + '\036', '\151', '\237', '\041', '\174', '\044', '\310', '\345', + '\036', '\016', '\376', '\230', '\207', '\237', '\216', '\340', + '\101', '\240', '\201', '\055', '\366', '\172', '\041', '\227', + '\317', '\056', '\051', '\255', '\261', '\260', '\042', '\353', + '\144', '\175', '\215', '\246', '\251', '\347', '\037', '\375', + '\336', '\012', '\111', '\037', '\204', '\104', '\362', '\010', + '\040', '\365', '\132', '\034', '\210', '\225', '\203', '\264', + '\133', '\037', '\207', '\201', '\230', '\332', '\161', '\251', + '\221', '\160', '\030', '\007', '\040', '\030', '\022', '\022', + '\307', '\177', '\034', '\122', '\034', '\311', '\037', '\220', + '\144', '\134', '\252', '\313', '\134', '\146', '\314', '\245', + '\035', '\011', '\226', '\132', '\107', '\316', '\220', '\074', + '\032', '\351', '\236', '\172', '\010', '\313', '\137', '\320', + '\264', '\336', '\101', '\240', '\040', '\216', '\034', '\214', + '\364', '\231', '\146', '\246', '\151', '\145', '\257', '\133', + '\036', '\342', '\041', '\044', '\120', '\043', '\002', '\011', + '\227', '\044', '\342', '\232', '\342', '\256', '\232', '\152', + '\175', '\152', '\213', '\001', '\136', '\150', '\240', '\214', + '\001', '\132', '\231', '\344', '\207', '\301', '\006', '\031', + '\310', '\042', '\056', '\227', '\052', '\063', '\044', '\312', + '\006', '\313', '\354', '\332', '\112', '\012', '\302', '\110', + '\220', '\110', '\027', '\034', '\354', '\301', '\153', '\257', + '\174', '\245', '\337', '\211', '\034', '\102', '\261', '\042', + '\220', '\326', '\253', '\310', '\217', '\012', '\311', '\007', + '\022', '\007', '\011', '\361', '\220', '\320', '\157', '\006', + '\341', '\221', '\220', '\040', '\011', '\051', '\016', '\000', + '\051', '\011', '\361', '\222', '\020', '\063', '\011', '\171', + '\223', '\220', '\076', '\011', '\151', '\140', '\221', '\123', + '\006', '\131', '\141', '\221', '\034', '\026', '\111', '\142', + '\221', '\053', '\026', '\071', '\143', '\221', '\070', '\026', + '\351', '\143', '\221', '\006', '\063', '\351', '\060', '\223', + '\025', '\063', '\331', '\061', '\223', '\044', '\063', '\311', + '\062', '\223', '\064', '\063', '\311', '\063', '\223', '\004', + '\034', '\001', '\040', '\103', '\361', '\120', '\024', '\017', + '\107', '\361', '\216', '\024', '\317', '\112', '\361', '\312', + '\024', '\257', '\116', '\361', '\010', '\230', '\204', '\202', + '\111', '\074', '\230', '\104', '\205', '\111', '\154', '\230', + '\204', '\210', '\111', '\244', '\230', '\104', '\214', '\111', + '\342', '\230', '\044', '\100', '\001', '\006', '\201', '\200', + '\076', '\000', '\076', '\254', '\157', '\305', '\372', '\162', + '\254', '\357', '\310', '\372', '\256', '\254', '\257', '\314', + '\372', '\352', '\254', '\217', '\200', '\001', '\006', '\241', + '\300', '\077', '\000', '\110', '\370', '\037', '\032', '\376', + '\207', '\210', '\377', '\241', '\342', '\177', '\304', '\370', + '\037', '\071', '\376', '\007', '\200', '\003', '\030', '\204', + '\003', '\016', '\004', '\000', '\017', '\042', '\310', '\205', + '\010', '\342', '\041', '\202', '\230', '\210', '\240', '\051', + '\042', '\150', '\214', '\010', '\202', '\043', '\202', '\376', + '\210', '\240', '\006', '\012', '\002', '\000', '\035', '\220', + '\120', '\013', '\044', '\324', '\003', '\011', '\035', '\101', + '\102', '\123', '\220', '\120', '\027', '\044', '\224', '\006', + '\011', '\345', '\101', '\102', '\011', '\034', '\105', '\006', + '\107', '\221', '\302', '\121', '\334', '\160', '\024', '\107', + '\034', '\305', '\025', '\107', '\161', '\306', '\121', '\334', + '\161', '\024', '\007', '\130', '\105', '\004', '\126', '\321', + '\201', '\125', '\260', '\140', '\025', '\074', '\130', '\305', + '\020', '\126', '\061', '\205', '\125', '\200', '\141', '\025', + '\157', '\130', '\105', '\037', '\126', '\321', '\300', '\002', + '\014', '\242', '\203', '\055', '\002', '\100', '\013', '\136', + '\264', '\203', '\027', '\055', '\341', '\105', '\130', '\170', + '\021', '\032', '\136', '\374', '\206', '\027', '\377', '\341', + '\305', '\006', '\060', '\300', '\040', '\037', '\170', '\043', + '\000', '\132', '\040', '\307', '\037', '\310', '\261', '\011', + '\162', '\374', '\202', '\034', '\335', '\040', '\107', '\107', + '\310', '\261', '\023', '\162', '\334', '\205', '\034', '\267', + '\041', '\307', '\175', '\310', '\361', '\002', '\152', '\001', + '\300', '\015', '\022', '\171', '\205', '\104', '\336', '\041', + '\221', '\227', '\110', '\344', '\055', '\022', '\171', '\215', + '\104', '\336', '\043', '\221', '\021', '\160', '\200', '\101', + '\132', '\240', '\111', '\000', '\034', '\241', '\223', '\145', + '\350', '\144', '\040', '\072', '\031', '\212', '\116', '\366', + '\242', '\223', '\335', '\350', '\144', '\076', '\072', '\231', + '\201', '\364', '\000', '\240', '\006', '\256', '\254', '\202', + '\053', '\323', '\340', '\312', '\100', '\270', '\062', '\022', + '\256', '\214', '\205', '\053', '\213', '\341', '\312', '\156', + '\270', '\062', '\037', '\256', '\314', '\200', '\166', '\346', + '\070', '\314', '\042', '\014', '\263', '\014', '\303', '\054', + '\304', '\060', '\047', '\061', '\314', '\131', '\014', '\323', + '\005', '\334', '\001', '\000', '\027', '\104', '\140', '\020', + '\134', '\020', '\301', '\040', '\007', '\300', '\301', '\003', + '\170', '\360', '\001', '\037', '\370', '\340', '\003', '\374', + '\170', '\000', '\076', '\016', '\000', '\217', '\001', '\224', + '\163', '\234', '\341', '\374', '\146', '\067', '\267', '\231', + '\315', '\007', '\300', '\343', '\003', '\370', '\370', '\001', + '\077', '\376', '\340', '\017', '\177', '\374', '\201', '\037', + '\077', '\300', '\307', '\007', '\340', '\341', '\116', '\161', + '\202', '\363', '\007', '\366', '\244', '\247', '\074', '\341', + '\351', '\116', '\000', '\300', '\100', '\202', '\000', '\370', + '\000', '\060', '\366', '\371', '\200', '\160', '\002', '\343', + '\000', '\037', '\134', '\036', '\016', '\006', '\300', '\201', + '\000', '\070', '\040', '\000', '\016', '\234', '\011', '\070', + '\000', '\200', '\017', '\000', '\370', '\003', '\020', '\177', + '\000', '\307', '\037', '\342', '\211', '\117', '\176', '\174', + '\000', '\034', '\014', '\305', '\307', '\003', '\370', '\160', + '\000', '\037', '\034', '\340', '\003', '\002', '\320', '\044', + '\106', '\302', '\363', '\017', '\014', '\330', '\024', '\003', + '\132', '\340', '\001', '\006', '\376', '\061', '\000', '\236', + '\372', '\264', '\247', '\003', '\220', '\234', '\344', '\374', + '\021', '\000', '\242', '\022', '\225', '\037', '\000', '\220', + '\034', '\006', '\170', '\240', '\205', '\233', '\356', '\024', + '\000', '\377', '\070', '\350', '\120', '\213', '\112', '\125', + '\241', '\102', '\025', '\250', '\077', '\345', '\051', '\116', + '\300', '\061', '\200', '\010', '\030', '\200', '\074', '\056', + '\301', '\210', '\000', '\170', '\272', '\321', '\162', '\346', + '\343', '\000', '\336', '\061', '\313', '\007', '\376', '\201', + '\326', '\001', '\034', '\201', '\003', '\104', '\040', '\100', + '\134', '\343', '\372', '\217', '\017', '\024', '\201', '\002', + '\167', '\315', '\053', '\005', '\352', '\072', '\127', '\271', + '\022', '\340', '\255', '\337', '\350', '\103', '\140', '\003', + '\313', '\215', '\016', '\374', '\343', '\017', '\207', '\075', + '\354', '\140', '\373', '\220', '\130', '\304', '\376', '\241', + '\260', '\213', '\015', '\054', '\107', '\070', '\062', '\002', + '\004', '\214', '\200', '\000', '\043', '\020', '\300', '\010', + '\002', '\060', '\212', '\321', '\000', '\140', '\034', '\017', + '\230', '\054', '\000', '\070', '\362', '\217', '\037', '\224', + '\066', '\075', '\351', '\171', '\007', '\014', '\336', '\201', + '\203', '\167', '\160', '\340', '\035', '\016', '\170', '\307', + '\001', '\336', '\061', '\200', '\167', '\374', '\300', '\266', + '\266', '\115', '\117', '\132', '\315', '\142', '\120', '\203', + '\022', '\040', '\006', '\010', '\210', '\001', '\004', '\142', + '\000', '\202', '\030', '\000', '\041', '\006', '\200', '\210', + '\001', '\077', '\142', '\320', '\333', '\203', '\302', '\240', + '\264', '\245', '\005', '\000', '\074', '\244', '\313', '\200', + '\173', '\160', '\340', '\036', '\070', '\270', '\007', '\034', + '\356', '\001', '\216', '\173', '\000', '\343', '\036', '\374', + '\000', '\257', '\170', '\245', '\273', '\333', '\262', '\300', + '\344', '\274', '\000', '\100', '\057', '\114', '\342', '\212', + '\004', '\001', '\100', '\041', '\000', '\033', '\205', '\211', + '\101', '\352', '\132', '\127', '\140', '\004', '\300', '\276', + '\370', '\275', '\257', '\176', '\231', '\221', '\201', '\302', + '\252', '\024', '\036', '\020', '\035', '\200', '\175', '\033', + '\333', '\130', '\140', '\000', '\300', '\300', '\010', '\076', + '\260', '\202', '\023', '\014', '\335', '\037', '\000', '\103', + '\300', '\020', '\176', '\260', '\204', '\043', '\334', '\323', + '\362', '\036', '\026', '\041', '\375', '\370', '\103', '\001', + '\200', '\120', '\217', '\057', '\124', '\000', '\012', '\325', + '\270', '\002', '\155', '\252', '\120', '\205', '\152', '\124', + '\241', '\002', '\124', '\250', '\307', '\025', '\012', '\000', + '\205', '\176', '\174', '\041', '\000', '\100', '\110', '\254', + '\205', '\147', '\114', '\143', '\357', '\070', '\067', '\251', + '\070', '\106', '\052', '\122', '\215', '\032', '\200', '\031', + '\014', '\040', '\006', '\002', '\270', '\361', '\215', '\247', + '\073', '\135', '\174', '\004', '\300', '\310', '\374', '\030', + '\100', '\222', '\103', '\030', '\302', '\177', '\074', '\300', + '\311', '\116', '\276', '\207', '\003', '\210', '\054', '\335', + '\052', '\203', '\343', '\310', '\007', '\010', '\247', '\007', + '\074', '\340', '\000', '\010', '\342', '\040', '\233', '\140', + '\306', '\101', '\227', '\267', '\034', '\316', '\161', '\136', + '\371', '\203', '\372', '\304', '\247', '\075', '\355', '\071', + '\120', '\175', '\272', '\031', '\236', '\362', '\134', '\363', + '\075', '\363', '\171', '\322', '\054', '\077', '\300', '\034', + '\031', '\230', '\300', '\014', '\222', '\101', '\202', '\074', + '\220', '\040', '\002', '\042', '\030', '\107', '\014', '\374', + '\361', '\001', '\145', '\120', '\300', '\320', '\206', '\126', + '\107', '\005', '\226', '\101', '\203', '\155', '\066', '\230', + '\320', '\367', '\310', '\301', '\066', '\356', '\320', '\216', + '\066', '\364', '\343', '\015', '\371', '\060', '\303', '\074', + '\346', '\120', '\332', '\165', '\324', '\300', '\323', '\236', + '\336', '\307', '\015', '\326', '\121', '\207', '\147', '\360', + '\241', '\261', '\052', '\045', '\000', '\004', '\014', '\000', + '\006', '\005', '\140', '\101', '\036', '\107', '\030', '\000', + '\020', '\144', '\055', '\000', '\040', '\324', '\132', '\023', + '\130', '\260', '\102', '\025', '\256', '\121', '\205', '\055', + '\144', '\241', '\326', '\265', '\306', '\247', '\112', '\115', + '\352', '\217', '\177', '\024', '\333', '\302', '\305', '\076', + '\166', '\171', '\213', '\215', '\117', '\040', '\300', '\370', + '\331', '\316', '\216', '\166', '\000', '\020', '\153', '\020', + '\304', '\112', '\373', '\332', '\317', '\346', '\252', '\266', + '\007', '\260', '\155', '\032', '\157', '\373', '\333', '\334', + '\036', '\200', '\020', '\102', '\120', '\204', '\050', '\050', + '\041', '\005', '\124', '\250', '\000', '\032', '\026', '\000', + '\205', '\002', '\374', '\302', '\037', '\316', '\176', '\167', + '\273', '\327', '\235', '\356', '\163', '\227', '\173', '\334', + '\146', '\230', '\101', '\033', '\266', '\261', '\207', '\067', + '\330', '\341', '\006', '\154', '\330', '\300', '\027', '\372', + '\001', '\120', '\234', '\000', '\164', '\340', '\001', '\377', + '\167', '\277', '\367', '\235', '\157', '\234', '\070', '\034', + '\000', '\017', '\177', '\070', '\142', '\043', '\016', '\361', + '\212', '\077', '\074', '\277', '\030', '\327', '\357', '\156', + '\063', '\316', '\361', '\147', '\203', '\141', '\000', '\355', + '\106', '\102', '\002', '\210', '\020', '\201', '\161', '\377', + '\341', '\017', '\325', '\376', '\303', '\270', '\111', '\056', + '\362', '\166', '\177', '\334', '\331', '\134', '\005', '\260', + '\112', '\013', '\353', '\214', '\034', '\034', '\043', '\016', + '\145', '\101', '\154', '\131', '\156', '\136', '\163', '\377', + '\272', '\063', '\300', '\366', '\235', '\052', '\121', '\263', + '\012', '\124', '\036', '\113', '\316', '\310', '\114', '\106', + '\353', '\223', '\227', '\016', '\345', '\245', '\047', '\335', + '\310', '\116', '\016', '\000', '\002', '\244', '\116', '\165', + '\004', '\204', '\301', '\352', '\123', '\317', '\172', '\325', + '\241', '\154', '\332', '\256', '\207', '\371', '\034', '\071', + '\000', '\273', '\330', '\163', '\020', '\346', '\006', '\227', + '\126', '\252', '\000', '\100', '\252', '\055', '\172', '\074', + '\000', '\041', '\367', '\326', '\307', '\153', '\107', '\252', + '\344', '\016', '\132', '\344', '\000', '\054', '\131', '\351', + '\115', '\247', '\162', '\323', '\235', '\034', '\302', '\044', + '\033', '\171', '\272', '\351', '\355', '\255', '\343', '\024', + '\312', '\320', '\160', '\002', '\342', '\000', '\100', '\070', + '\000', '\010', '\006', '\000', '\201', '\001', '\114', '\235', + '\000', '\001', '\200', '\210', '\105', '\300', '\042', '\071', + '\077', '\000', '\342', '\007', '\050', '\325', '\247', '\077', + '\036', '\260', '\371', '\017', '\002', '\030', '\027', '\003', + '\340', '\304', '\000', '\034', '\021', '\200', '\103', '\004', + '\200', '\043', '\026', '\201', '\311', '\101', '\007', '\277', + '\120', '\000', '\150', '\262', '\001', '\200', '\040', '\000', + '\020', '\010', '\200', '\022', '\355', '\024', '\104', '\254', + '\000', '\230', '\074', '\216', '\175', '\160', '\171', '\224', + '\242', '\024', '\020', '\017', '\000', '\306', '\003', '\300', + '\141', '\000', '\231', '\340', '\000', '\000', '\214', '\323', + '\244', '\003', '\111', '\373', '\200', '\110', '\040', '\040', + '\023', '\011', '\150', '\300', '\002', '\016', '\340', '\200', + '\253', '\137', '\235', '\372', '\322', '\207', '\276', '\363', + '\271', '\136', '\332', '\171', '\314', '\100', '\324', '\077', + '\370', '\301', '\067', '\174', '\360', '\216', '\036', '\224', + '\177', '\374', '\341', '\027', '\265', '\367', '\033', '\034', + '\217', '\001', '\354', '\343', '\245', '\014', '\110', '\000', + '\002', '\154', '\362', '\003', '\220', '\324', '\337', '\004', + '\004', '\040', '\001', '\003', '\174', '\200', '\217', '\033', + '\300', '\143', '\004', '\343', '\160', '\000', '\367', '\360', + '\144', '\153', '\025', '\176', '\070', '\020', '\125', '\064', + '\065', '\137', '\120', '\305', '\000', '\376', '\300', '\001', + '\374', '\300', '\017', '\377', '\200', '\017', '\377', '\000', + '\017', '\357', '\000', '\016', '\307', '\140', '\140', '\127', + '\126', '\116', '\006', '\106', '\014', '\010', '\140', '\014', + '\073', '\325', '\165', '\036', '\310', '\201', '\006', '\126', + '\116', '\127', '\206', '\140', '\002', '\006', '\121', '\344', + '\364', '\000', '\350', '\160', '\001', '\334', '\260', '\003', + '\026', '\326', '\202', '\053', '\310', '\117', '\037', '\064', + '\141', '\000', '\340', '\001', '\256', '\027', '\000', '\314', + '\220', '\017', '\015', '\340', '\144', '\177', '\300', '\000', + '\166', '\144', '\000', '\214', '\043', '\116', '\007', '\240', + '\035', '\104', '\250', '\036', '\222', '\003', '\000', '\365', + '\367', '\003', '\025', '\346', '\035', '\135', '\147', '\166', + '\000', '\105', '\120', '\307', '\167', '\174', '\072', '\226', + '\166', '\000', '\060', '\165', '\023', '\040', '\000', '\053', + '\066', '\001', '\004', '\060', '\015', '\005', '\360', '\001', + '\074', '\340', '\200', '\020', '\100', '\016', '\141', '\010', + '\011', '\364', '\000', '\011', '\344', '\000', '\011', '\004', + '\200', '\010', '\010', '\100', '\010', '\020', '\300', '\007', + '\340', '\004', '\000', '\373', '\020', '\000', '\367', '\320', + '\123', '\002', '\050', '\200', '\246', '\245', '\163', '\341', + '\005', '\017', '\367', '\000', '\017', '\023', '\270', '\207', + '\347', '\060', '\154', '\037', '\340', '\206', '\000', '\340', + '\022', '\036', '\160', '\170', '\017', '\226', '\201', '\003', + '\060', '\116', '\372', '\100', '\207', '\375', '\100', '\116', + '\346', '\024', '\000', '\051', '\000', '\000', '\043', '\000', + '\000', '\026', '\000', '\000', '\162', '\304', '\070', '\012', + '\065', '\174', '\216', '\070', '\116', '\233', '\267', '\167', + '\117', '\326', '\126', '\377', '\060', '\155', '\110', '\130', + '\203', '\036', '\025', '\000', '\221', '\347', '\007', '\004', + '\200', '\000', '\010', '\100', '\020', '\252', '\010', '\007', + '\024', '\200', '\000', '\042', '\000', '\003', '\101', '\000', + '\014', '\040', '\000', '\004', '\022', '\000', '\010', '\005', + '\201', '\076', '\002', '\060', '\164', '\164', '\310', '\167', + '\360', '\004', '\116', '\160', '\066', '\117', '\022', '\010', + '\017', '\041', '\345', '\140', '\037', '\000', '\174', '\015', + '\004', '\000', '\002', '\340', '\206', '\306', '\020', '\003', + '\203', '\000', '\006', '\320', '\006', '\155', '\003', '\000', + '\006', '\006', '\000', '\003', '\055', '\201', '\001', '\014', + '\000', '\003', '\254', '\046', '\140', '\001', '\340', '\206', + '\376', '\360', '\003', '\067', '\367', '\214', '\323', '\070', + '\215', '\103', '\020', '\006', '\207', '\000', '\007', '\016', + '\200', '\003', '\034', '\300', '\001', '\142', '\006', '\140', + '\134', '\065', '\140', '\377', '\260', '\012', '\252', '\120', + '\142', '\362', '\130', '\000', '\150', '\004', '\012', '\366', + '\270', '\000', '\370', '\170', '\217', '\371', '\010', '\012', + '\364', '\070', '\217', '\325', '\120', '\143', '\002', '\131', + '\143', '\204', '\026', '\116', '\371', '\160', '\002', '\336', + '\007', '\166', '\317', '\300', '\003', '\015', '\266', '\220', + '\140', '\347', '\175', '\007', '\031', '\116', '\005', '\011', + '\120', '\364', '\244', '\163', '\003', '\231', '\126', '\162', + '\206', '\117', '\247', '\167', '\000', '\017', '\360', '\001', + '\077', '\200', '\130', '\037', '\260', '\001', '\061', '\000', + '\003', '\140', '\360', '\161', '\311', '\230', '\036', '\037', + '\060', '\212', '\050', '\107', '\123', '\001', '\360', '\123', + '\050', '\167', '\017', '\000', '\060', '\017', '\000', '\160', + '\146', '\367', '\065', '\132', '\066', '\071', '\010', '\000', + '\060', '\004', '\222', '\010', '\000', '\043', '\261', '\017', + '\077', '\060', '\022', '\223', '\250', '\223', '\070', '\051', + '\132', '\250', '\005', '\000', '\241', '\365', '\010', '\003', + '\360', '\014', '\001', '\360', '\016', '\120', '\225', '\126', + '\114', '\251', '\224', '\110', '\031', '\132', '\105', '\051', + '\132', '\124', '\151', '\223', '\077', '\125', '\225', '\125', + '\131', '\224', '\132', '\151', '\224', '\120', '\305', '\164', + '\113', '\267', '\225', '\133', '\171', '\137', '\376', '\360', + '\156', '\277', '\040', '\002', '\242', '\040', '\012', '\252', + '\200', '\226', '\152', '\251', '\012', '\146', '\071', '\226', + '\156', '\111', '\226', '\157', '\051', '\226', '\167', '\110', + '\140', '\216', '\105', '\227', '\166', '\131', '\227', '\002', + '\205', '\225', '\066', '\131', '\225', '\077', '\005', '\226', + '\134', '\271', '\225', '\236', '\350', '\144', '\173', '\071', + '\230', '\130', '\371', '\123', '\177', '\171', '\230', '\140', + '\031', '\230', '\301', '\027', '\000', '\170', '\360', '\000', + '\316', '\306', '\026', '\302', '\020', '\016', '\044', '\040', + '\015', '\270', '\340', '\000', '\240', '\040', '\000', '\040', + '\120', '\153', '\001', '\220', '\231', '\150', '\050', '\162', + '\050', '\240', '\000', '\036', '\300', '\115', '\374', '\200', + '\116', '\015', '\365', '\001', '\303', '\020', '\004', '\347', + '\060', '\016', '\314', '\366', '\015', '\052', '\365', '\101', + '\061', '\167', '\000', '\200', '\350', '\007', '\341', '\367', + '\215', '\104', '\005', '\014', '\157', '\151', '\226', '\052', + '\240', '\012', '\271', '\271', '\233', '\154', '\051', '\012', + '\157', '\371', '\233', '\144', '\051', '\227', '\167', '\071', + '\234', '\170', '\111', '\227', '\337', '\270', '\121', '\007', + '\005', '\026', '\006', '\106', '\150', '\233', '\331', '\014', + '\154', '\340', '\234', '\316', '\031', '\000', '\320', '\110', + '\215', '\070', '\200', '\001', '\006', '\220', '\201', '\214', + '\151', '\145', '\036', '\125', '\200', '\002', '\311', '\017', + '\357', '\060', '\116', '\044', '\150', '\121', '\000', '\300', + '\035', '\314', '\045', '\005', '\000', '\340', '\005', '\000', + '\100', '\010', '\000', '\340', '\020', '\123', '\007', '\001', + '\001', '\000', '\003', '\230', '\131', '\153', '\004', '\160', + '\170', '\311', '\310', '\077', '\004', '\120', '\177', '\053', + '\351', '\121', '\151', '\147', '\167', '\107', '\146', '\116', + '\346', '\204', '\202', '\340', '\020', '\174', '\307', '\230', + '\222', '\051', '\151', '\203', '\034', '\200', '\210', '\343', + '\304', '\014', '\014', '\240', '\240', '\340', '\311', '\155', + '\001', '\020', '\016', '\041', '\020', '\016', '\141', '\040', + '\014', '\020', '\300', '\001', '\016', '\160', '\145', '\370', + '\160', '\004', '\053', '\265', '\231', '\347', '\144', '\147', + '\204', '\126', '\220', '\102', '\030', '\017', '\203', '\020', + '\017', '\343', '\060', '\017', '\363', '\360', '\016', '\071', + '\260', '\145', '\127', '\346', '\017', '\307', '\120', '\026', + '\053', '\345', '\166', '\007', '\365', '\123', '\060', '\132', + '\145', '\124', '\066', '\135', '\212', '\131', '\243', '\125', + '\306', '\007', '\372', '\171', '\014', '\001', '\060', '\010', + '\245', '\027', '\000', '\306', '\000', '\137', '\070', '\166', + '\174', '\050', '\000', '\000', '\105', '\352', '\016', '\000', + '\300', '\006', '\000', '\160', '\174', '\332', '\321', '\121', + '\374', '\120', '\124', '\164', '\370', '\010', '\007', '\360', + '\011', '\007', '\340', '\015', '\131', '\226', '\210', '\107', + '\306', '\121', '\373', '\351', '\017', '\112', '\226', '\245', + '\160', '\000', '\161', '\300', '\000', '\016', '\360', '\200', + '\017', '\374', '\120', '\154', '\370', '\200', '\015', '\214', + '\300', '\000', '\006', '\300', '\077', '\003', '\000', '\010', + '\020', '\026', '\163', '\211', '\250', '\144', '\003', '\300', + '\245', '\077', '\205', '\017', '\003', '\300', '\013', '\003', + '\300', '\003', '\003', '\140', '\203', '\066', '\050', '\107', + '\316', '\005', '\004', '\060', '\000', '\010', '\007', '\305', + '\134', '\062', '\360', '\017', '\067', '\140', '\074', '\000', + '\200', '\134', '\060', '\000', '\250', '\315', '\105', '\243', + '\300', '\000', '\017', '\300', '\020', '\017', '\200', '\040', + '\223', '\367', '\260', '\133', '\000', '\160', '\017', '\223', + '\032', '\251', '\217', '\112', '\243', '\204', '\111', '\230', + '\206', '\251', '\227', '\104', '\211', '\230', '\177', '\251', + '\230', '\242', '\252', '\225', '\142', '\111', '\226', '\146', + '\231', '\226', '\252', '\252', '\226', '\155', '\011', '\227', + '\256', '\072', '\226', '\302', '\131', '\234', '\262', '\112', + '\234', '\215', '\365', '\215', '\245', '\025', '\000', '\042', + '\200', '\253', '\270', '\372', '\017', '\043', '\000', '\150', + '\276', '\052', '\002', '\200', '\026', '\017', '\077', '\020', + '\001', '\040', '\100', '\254', '\304', '\012', '\135', '\151', + '\165', '\000', '\356', '\360', '\017', '\357', '\300', '\254', + '\314', '\172', '\007', '\356', '\000', '\255', '\225', '\072', + '\255', '\377', '\160', '\007', '\340', '\260', '\133', '\017', + '\007', '\012', '\001', '\240', '\255', '\260', '\020', '\000', + '\260', '\060', '\000', '\240', '\007', '\172', '\274', '\160', + '\000', '\343', '\352', '\013', '\007', '\340', '\013', '\035', + '\271', '\174', '\015', '\144', '\210', '\301', '\067', '\174', + '\303', '\267', '\117', '\360', '\032', '\117', '\044', '\045', + '\117', '\306', '\126', '\026', '\037', '\020', '\102', '\024', + '\220', '\257', '\372', '\272', '\257', '\024', '\360', '\007', + '\076', '\300', '\001', '\010', '\240', '\243', '\002', '\013', + '\000', '\003', '\133', '\260', '\004', '\173', '\260', '\241', + '\030', '\212', '\376', '\160', '\260', '\114', '\132', '\205', + '\010', '\320', '\022', '\337', '\370', '\000', '\170', '\360', + '\215', '\055', '\241', '\212', '\330', '\270', '\216', '\266', + '\212', '\227', '\337', '\270', '\216', '\330', '\130', '\020', + '\157', '\144', '\117', '\351', '\141', '\117', '\157', '\124', + '\020', '\007', '\045', '\205', '\365', '\132', '\026', '\314', + '\366', '\017', '\307', '\167', '\120', '\125', '\070', '\210', + '\321', '\205', '\007', '\321', '\345', '\022', '\036', '\213', + '\174', '\320', '\145', '\221', '\210', '\125', '\177', '\214', + '\303', '\000', '\010', '\300', '\001', '\076', '\360', '\007', + '\374', '\372', '\263', '\332', '\161', '\174', '\072', '\272', + '\260', '\011', '\333', '\215', '\007', '\153', '\260', '\110', + '\173', '\260', '\073', '\333', '\263', '\077', '\333', '\257', + '\377', '\212', '\000', '\102', '\253', '\237', '\105', '\233', + '\264', '\072', '\132', '\264', '\013', '\253', '\243', '\307', + '\167', '\021', '\256', '\227', '\120', '\200', '\260', '\007', + '\240', '\260', '\007', '\220', '\260', '\007', '\210', '\040', + '\266', '\144', '\073', '\266', '\214', '\260', '\007', '\106', + '\362', '\013', '\173', '\200', '\001', '\334', '\321', '\247', + '\310', '\307', '\076', '\000', '\260', '\222', '\140', '\360', + '\017', '\160', '\360', '\017', '\060', '\173', '\267', '\166', + '\373', '\017', '\247', '\346', '\007', '\211', '\345', '\007', + '\177', '\000', '\003', '\176', '\040', '\101', '\341', '\201', + '\020', '\204', '\013', '\000', '\355', '\027', '\001', '\002', + '\360', '\253', '\020', '\040', '\002', '\377', '\007', '\000', + '\044', '\140', '\244', '\006', '\005', '\014', '\246', '\205', + '\125', '\003', '\340', '\100', '\003', '\170', '\271', '\357', + '\000', '\255', '\322', '\372', '\016', '\024', '\310', '\207', + '\034', '\005', '\014', '\377', '\000', '\272', '\240', '\233', + '\212', '\325', '\123', '\075', '\020', '\040', '\000', '\247', + '\033', '\016', '\341', '\200', '\147', '\343', '\064', '\116', + '\170', '\246', '\272', '\247', '\173', '\272', '\245', '\113', + '\000', '\251', '\150', '\000', '\330', '\250', '\263', '\004', + '\140', '\235', '\042', '\152', '\242', '\366', '\260', '\003', + '\341', '\304', '\017', '\007', '\140', '\017', '\037', '\140', + '\242', '\042', '\212', '\001', '\002', '\140', '\235', '\014', + '\240', '\246', '\056', '\141', '\000', '\070', '\301', '\002', + '\006', '\340', '\011', '\224', '\150', '\000', '\365', '\027', + '\002', '\000', '\160', '\002', '\000', '\120', '\024', '\326', + '\213', '\275', '\325', '\013', '\000', '\324', '\113', '\275', + '\365', '\147', '\211', '\030', '\320', '\000', '\174', '\040', + '\276', '\015', '\340', '\007', '\073', '\010', '\125', '\350', + '\233', '\200', '\352', '\233', '\276', '\350', '\213', '\023', + '\330', '\226', '\231', '\360', '\053', '\000', '\234', '\300', + '\001', '\323', '\270', '\216', '\235', '\231', '\000', '\044', + '\040', '\001', '\371', '\332', '\022', '\252', '\206', '\023', + '\371', '\365', '\161', '\037', '\247', '\215', '\070', '\340', + '\001', '\237', '\300', '\007', '\334', '\026', '\210', '\363', + '\313', '\137', '\371', '\146', '\003', '\066', '\020', '\232', + '\351', '\150', '\137', '\000', '\046', '\146', '\055', '\121', + '\215', '\317', '\130', '\216', '\317', '\130', '\215', '\055', + '\321', '\216', '\007', '\140', '\137', '\257', '\251', '\122', + '\074', '\300', '\145', '\070', '\160', '\216', '\303', '\020', + '\016', '\143', '\060', '\016', '\043', '\174', '\216', '\351', + '\370', '\301', '\255', '\051', '\153', '\201', '\247', '\136', + '\201', '\127', '\127', '\056', '\354', '\302', '\035', '\227', + '\137', '\164', '\071', '\303', '\372', '\305', '\021', '\351', + '\341', '\003', '\372', '\231', '\144', '\145', '\246', '\245', + '\060', '\360', '\236', '\230', '\111', '\173', '\005', '\241', + '\035', '\040', '\340', '\100', '\051', '\211', '\162', '\106', + '\225', '\145', '\362', '\224', '\117', '\371', '\364', '\237', + '\360', '\160', '\241', '\007', '\212', '\003', '\340', '\360', + '\245', '\033', '\005', '\272', '\135', '\127', '\225', '\240', + '\065', '\006', '\000', '\320', '\131', '\233', '\225', '\131', + '\227', '\125', '\131', '\242', '\145', '\141', '\251', '\165', + '\133', '\144', '\114', '\133', '\262', '\005', '\133', '\256', + '\305', '\132', '\252', '\125', '\224', '\015', '\326', '\250', + '\060', '\260', '\134', '\311', '\165', '\134', '\305', '\065', + '\134', '\301', '\365', '\133', '\315', '\145', '\141', '\322', + '\025', '\136', '\172', '\354', '\135', '\334', '\245', '\135', + '\330', '\145', '\135', '\367', '\120', '\135', '\064', '\112', + '\137', '\051', '\031', '\170', '\033', '\365', '\136', '\355', + '\025', '\127', '\061', '\334', '\302', '\120', '\045', '\253', + '\034', '\374', '\237', '\063', '\327', '\001', '\374', '\145', + '\303', '\003', '\326', '\165', '\011', '\166', '\311', '\013', + '\246', '\140', '\026', '\066', '\141', '\234', '\114', '\141', + '\017', '\126', '\020', '\074', '\373', '\007', '\167', '\340', + '\257', '\000', '\333', '\005', '\153', '\220', '\004', '\101', + '\220', '\312', '\121', '\170', '\260', '\104', '\333', '\222', + '\256', '\174', '\265', '\000', '\240', '\013', '\120', '\345', + '\312', '\241', '\170', '\015', '\001', '\140', '\313', '\074', + '\172', '\225', '\235', '\252', '\227', '\212', '\351', '\227', + '\176', '\371', '\075', '\040', '\240', '\000', '\311', '\040', + '\003', '\362', '\220', '\000', '\114', '\140', '\000', '\103', + '\200', '\001', '\213', '\174', '\136', '\317', '\206', '\023', + '\350', '\140', '\007', '\373', '\360', '\015', '\004', '\167', + '\154', '\246', '\365', '\017', '\317', '\220', '\007', '\063', + '\274', '\301', '\332', '\374', '\120', '\156', '\372', '\251', + '\273', '\354', '\251', '\136', '\051', '\230', '\276', '\214', + '\230', '\255', '\013', '\233', '\166', '\146', '\010', '\030', + '\060', '\010', '\060', '\020', '\010', '\340', '\020', '\014', + '\341', '\340', '\316', '\041', '\000', '\016', '\023', '\240', + '\215', '\030', '\120', '\146', '\346', '\114', '\232', '\277', + '\313', '\171', '\334', '\051', '\220', '\117', '\230', '\317', + '\341', '\164', '\007', '\000', '\253', '\212', '\002', '\075', + '\320', '\034', '\160', '\007', '\357', '\100', '\313', '\106', + '\273', '\312', '\012', '\275', '\244', '\014', '\035', '\265', + '\105', '\173', '\320', '\051', '\221', '\011', '\021', '\001', + '\004', '\216', '\160', '\020', '\312', '\150', '\223', '\030', + '\201', '\076', '\374', '\343', '\100', '\005', '\261', '\023', + '\112', '\261', '\105', '\157', '\244', '\026', '\232', '\224', + '\036', '\347', '\001', '\000', '\022', '\300', '\223', '\000', + '\100', '\001', '\000', '\120', '\001', '\224', '\010', '\000', + '\027', '\060', '\210', '\000', '\140', '\023', '\032', '\000', + '\000', '\076', '\301', '\070', '\035', '\100', '\212', '\051', + '\211', '\022', '\324', '\113', '\115', '\223', '\370', '\270', + '\105', '\141', '\002', '\333', '\133', '\244', '\221', '\310', + '\024', '\053', '\000', '\000', '\054', '\060', '\107', '\000', + '\340', '\002', '\000', '\360', '\002', '\275', '\105', '\250', + '\000', '\060', '\003', '\000', '\100', '\003', '\257', '\004', + '\000', '\066', '\240', '\110', '\014', '\235', '\003', '\045', + '\004', '\000', '\073', '\200', '\120', '\075', '\000', '\267', + '\365', '\007', '\023', '\124', '\041', '\004', '\071', '\251', + '\022', '\000', '\340', '\031', '\106', '\340', '\111', '\000', + '\004', '\000', '\111', '\000', '\000', '\112', '\000', '\000', + '\113', '\000', '\000', '\114', '\000', '\000', '\115', '\000', + '\000', '\136', '\361', '\004', '\064', '\001', '\000', '\121', + '\340', '\032', '\000', '\300', '\025', '\166', '\121', '\005', + '\000', '\140', '\005', '\251', '\161', '\034', '\000', '\140', + '\034', '\132', '\000', '\000', '\133', '\040', '\115', '\000', + '\320', '\005', '\347', '\011', '\000', '\137', '\000', '\000', + '\140', '\021', '\006', '\000', '\040', '\006', '\236', '\065', + '\021', '\145', '\000', '\000', '\146', '\000', '\000', '\147', + '\000', '\000', '\150', '\000', '\000', '\151', '\000', '\000', + '\152', '\000', '\000', '\132', '\241', '\244', '\143', '\341', + '\006', '\000', '\360', '\006', '\000', '\360', '\245', '\161', + '\000', '\000', '\250', '\061', '\007', '\000', '\100', '\007', + '\000', '\120', '\007', '\000', '\200', '\026', '\167', '\200', + '\143', '\171', '\060', '\037', '\000', '\260', '\007', '\007', + '\333', '\007', '\000', '\020', '\270', '\050', '\207', '\023', + '\154', '\101', '\071', '\070', '\251', '\236', '\205', '\000', + '\000', '\206', '\000', '\000', '\207', '\260', '\236', '\000', + '\220', '\010', '\000', '\240', '\010', '\000', '\260', '\010', + '\000', '\300', '\010', '\000', '\320', '\010', '\000', '\120', + '\321', '\217', '\000', '\000', '\220', '\000', '\000', '\221', + '\000', '\000', '\222', '\000', '\000', '\223', '\000', '\000', + '\224', '\000', '\000', '\225', '\000', '\000', '\226', '\000', + '\000', '\227', '\000', '\000', '\230', '\000', '\000', '\022', + '\015', '\022', '\226', '\103', '\002', '\063', '\301', '\336', + '\006', '\341', '\336', '\216', '\333', '\336', '\362', '\375', + '\336', '\363', '\035', '\337', '\364', '\175', '\337', '\366', + '\235', '\337', '\360', '\275', '\337', '\365', '\315', '\337', + '\370', '\355', '\337', '\372', '\335', '\337', '\002', '\376', + '\337', '\003', '\036', '\340', '\004', '\176', '\340', '\006', + '\236', '\340', '\000', '\276', '\340', '\005', '\316', '\340', + '\010', '\356', '\340', '\012', '\336', '\340', '\022', '\376', + '\340', '\023', '\036', '\341', '\024', '\176', '\341', '\026', + '\236', '\341', '\020', '\276', '\341', '\025', '\316', '\341', + '\030', '\356', '\341', '\032', '\336', '\341', '\042', '\376', + '\341', '\043', '\236', '\340', '\004', '\060', '\023', '\047', + '\116', '\342', '\052', '\036', '\342', '\053', '\016', '\342', + '\102', '\140', '\021', '\057', '\256', '\336', '\051', '\161', + '\024', '\056', '\235', '\020', '\067', '\335', '\077', '\011', + '\201', '\325', '\006', '\141', '\327', '\006', '\201', '\236', + '\006', '\201', '\032', '\006', '\061', '\333', '\006', '\301', + '\026', '\006', '\301', '\334', '\006', '\161', '\336', '\006', + '\261', '\012', '\011', '\061', '\014', '\011', '\161', '\015', + '\011', '\001', '\170', '\124', '\150', '\020', '\015', '\140', + '\021', '\030', '\140', '\021', '\050', '\140', '\021', '\063', + '\140', '\021', '\103', '\140', '\021', '\116', '\140', '\021', + '\136', '\140', '\021', '\145', '\140', '\021', '\161', '\140', + '\021', '\167', '\140', '\021', '\202', '\140', '\021', '\215', + '\140', '\021', '\235', '\140', '\021', '\243', '\260', '\072', + '\026', '\301', '\013', '\026', '\241', '\224', '\006', '\221', + '\015', '\026', '\201', '\016', '\026', '\141', '\017', '\026', + '\221', '\000', '\063', '\321', '\000', '\063', '\141', '\001', + '\063', '\321', '\001', '\063', '\221', '\002', '\063', '\141', + '\003', '\063', '\321', '\136', '\006', '\101', '\005', '\063', + '\121', '\006', '\063', '\021', '\007', '\063', '\041', '\010', + '\063', '\321', '\010', '\063', '\321', '\011', '\063', '\141', + '\012', '\063', '\101', '\013', '\063', '\241', '\013', '\063', + '\121', '\014', '\063', '\321', '\014', '\063', '\241', '\015', + '\032', '\065', '\023', '\353', '\060', '\023', '\361', '\060', + '\023', '\374', '\060', '\023', '\002', '\120', '\074', '\015', + '\120', '\074', '\023', '\120', '\074', '\036', '\120', '\074', + '\043', '\120', '\074', '\055', '\120', '\074', '\023', '\165', + '\025', '\305', '\023', '\005', '\305', '\363', '\005', '\305', + '\223', '\006', '\305', '\203', '\007', '\305', '\023', '\010', + '\305', '\203', '\224', '\361', '\121', '\074', '\252', '\120', + '\074', '\263', '\120', '\074', '\301', '\000', '\075', '\305', + '\203', '\015', '\305', '\303', '\015', '\305', '\123', '\016', + '\305', '\043', '\017', '\305', '\103', '\273', '\342', '\141', + '\022', '\025', '\140', '\022', '\034', '\140', '\075', '\046', + '\361', '\002', '\046', '\261', '\003', '\046', '\061', '\173', + '\006', '\241', '\004', '\046', '\221', '\005', '\046', '\321', + '\006', '\046', '\161', '\007', '\046', '\141', '\010', '\046', + '\021', '\011', '\046', '\021', '\012', '\046', '\261', '\012', + '\046', '\241', '\013', '\046', '\141', '\014', '\046', '\161', + '\015', '\046', '\001', '\016', '\046', '\341', '\016', '\046', + '\161', '\017', '\046', '\121', '\000', '\353', '\063', '\001', + '\353', '\143', '\002', '\353', '\203', '\003', '\353', '\363', + '\004', '\353', '\323', '\005', '\353', '\003', '\007', '\353', + '\243', '\141', '\006', '\061', '\011', '\353', '\363', '\011', + '\353', '\003', '\013', '\353', '\043', '\014', '\353', '\223', + '\015', '\353', '\023', '\016', '\353', '\343', '\016', '\353', + '\123', '\017', '\353', '\023', '\000', '\377', '\263', '\077', + '\006', '\101', '\001', '\377', '\323', '\001', '\377', '\263', + '\002', '\377', '\243', '\215', '\134', '\364', '\077', '\101', + '\360', '\077', '\115', '\360', '\077', '\124', '\360', '\077', + '\324', '\150', '\020', '\157', '\360', '\077', '\203', '\360', + '\077', '\223', '\140', '\100', '\377', '\223', '\013', '\377', + '\363', '\014', '\377', '\203', '\015', '\377', '\143', '\016', + '\377', '\343', '\016', '\377', '\263', '\017', '\014', '\024', + '\101', '\012', '\020', '\101', '\023', '\020', '\101', '\041', + '\020', '\101', '\052', '\020', '\101', '\137', '\146', '\020', + '\101', '\020', '\101', '\117', '\020', '\101', '\125', '\020', + '\101', '\140', '\020', '\101', '\146', '\020', '\101', '\161', + '\020', '\101', '\310', '\101', '\032', '\246', '\201', '\032', + '\133', '\137', '\007', '\245', '\161', '\032', '\137', '\320', + '\006', '\141', '\060', '\007', '\132', '\161', '\030', '\162', + '\360', '\006', '\263', '\215', '\366', '\152', '\077', '\366', + '\145', '\257', '\025', '\142', '\120', '\366', '\145', '\100', + '\006', '\137', '\300', '\366', '\167', '\360', '\005', '\144', + '\240', '\366', '\244', '\035', '\367', '\173', '\101', '\367', + '\166', '\217', '\367', '\172', '\357', '\366', '\146', '\037', + '\331', '\162', '\357', '\367', '\162', '\220', '\366', '\167', + '\137', '\007', '\137', '\312', '\367', '\163', '\137', '\367', + '\207', '\337', '\366', '\212', '\057', '\370', '\160', '\377', + '\006', '\141', '\340', '\332', '\142', '\100', '\371', '\164', + '\040', '\371', '\221', '\375', '\006', '\147', '\360', '\006', + '\163', '\220', '\006', '\164', '\120', '\333', '\227', '\337', + '\371', '\237', '\037', '\372', '\232', '\177', '\371', '\164', + '\100', '\007', '\157', '\320', '\006', '\137', '\300', '\006', + '\145', '\140', '\006', '\231', '\077', '\006', '\247', '\261', + '\030', '\250', '\201', '\372', '\252', '\317', '\372', '\256', + '\017', '\373', '\137', '\040', '\373', '\162', '\100', '\373', + '\247', '\377', '\006', '\251', '\277', '\372', '\137', '\040', + '\007', '\151', '\160', '\006', '\150', '\020', '\373', '\263', + '\057', '\031', '\233', '\037', '\374', '\254', '\117', '\374', + '\306', '\217', '\374', '\275', '\057', '\031', '\277', '\317', + '\374', '\137', '\360', '\371', '\144', '\120', '\331', '\266', + '\057', '\374', '\326', '\137', '\006', '\323', '\177', '\373', + '\137', '\100', '\007', '\145', '\200', '\375', '\300', '\357', + '\375', '\340', '\317', '\375', '\144', '\077', '\370', '\227', + '\217', '\007', '\325', '\017', '\007', '\151', '\040', '\007', + '\141', '\240', '\244', '\351', '\277', '\376', '\355', '\377', + '\376', '\232', '\077', '\006', '\214', '\001', '\376', '\162', + '\360', '\005', '\160', '\100', '\007', '\250', '\141', '\377', + '\156', '\200', '\377', '\372', '\317', '\377', '\365', '\337', + '\376', '\143', '\340', '\372', '\243', '\321', '\376', '\143', + '\340', '\372', '\365', '\317', '\006', '\157', '\060', '\006', + '\132', '\061', '\006', '\154', '\360', '\006', '\143', '\260', + '\006', '\365', '\377', '\006', '\146', '\140', '\006', '\341', + '\077', '\366', '\165', '\220', '\331', '\262', '\157', '\006', + '\146', '\020', '\376', '\143', '\137', '\007', '\147', '\120', + '\377', '\151', '\077', '\007', '\254', '\075', '\006', '\151', + '\077', '\007', '\163', '\120', '\377', '\151', '\077', '\007', + '\163', '\060', '\374', '\145', '\140', '\007', '\222', '\261', + '\027', '\243', '\221', '\366', '\163', '\060', '\007', '\303', + '\137', '\006', '\166', '\040', '\031', '\173', '\121', '\377', + '\151', '\077', '\007', '\163', '\200', '\006', '\141', '\320', + '\376', '\243', '\221', '\366', '\163', '\060', '\007', '\150', + '\020', '\006', '\355', '\257', '\371', '\144', '\220', '\006', + '\141', '\320', '\006', '\157', '\340', '\006', '\164', '\077', + '\006', '\151', '\077', '\007', '\254', '\115', '\006', '\151', + '\020', '\006', '\155', '\360', '\006', '\156', '\100', '\367', + '\143', '\220', '\366', '\163', '\060', '\007', '\232', '\237', + '\367', '\256', '\235', '\367', '\231', '\177', '\376', '\132', + '\221', '\367', '\164', '\220', '\376', '\000', '\220', '\367', + '\164', '\020', '\377', '\347', '\257', '\025', '\171', '\137', + '\007', '\142', '\340', '\372', '\216', '\217', '\370', '\000', + '\220', '\367', '\165', '\040', '\006', '\256', '\357', '\370', + '\210', '\257', '\371', '\144', '\340', '\376', '\272', '\317', + '\006', '\207', '\161', '\006', '\225', '\115', '\006', '\356', + '\257', '\373', '\154', '\160', '\030', '\147', '\140', '\376', + '\157', '\017', '\000', '\144', '\340', '\376', '\272', '\077', + '\007', '\144', '\317', '\006', '\112', '\112', '\006', '\356', + '\257', '\373', '\163', '\100', '\366', '\154', '\300', '\006', + '\232', '\117', '\006', '\356', '\017', '\007', '\215', '\237', + '\376', '\000', '\100', '\006', '\356', '\017', '\007', '\215', + '\037', '\377', '\347', '\257', '\025', '\145', '\200', '\007', + '\143', '\200', '\006', '\141', '\340', '\006', '\147', '\120', + '\331', '\145', '\200', '\007', '\143', '\200', '\006', '\141', + '\340', '\006', '\147', '\140', '\376', '\157', '\157', '\331', + '\256', '\017', '\366', '\226', '\355', '\372', '\140', '\257', + '\371', '\235', '\057', '\006', '\142', '\340', '\372', '\250', + '\321', '\371', '\142', '\040', '\006', '\256', '\237', '\377', + '\347', '\257', '\025', '\147', '\360', '\030', '\142', '\120', + '\333', '\147', '\360', '\030', '\142', '\220', '\007', '\232', + '\217', '\006', '\141', '\340', '\006', '\144', '\300', '\134', + '\150', '\020', '\006', '\156', '\100', '\006', '\061', '\240', + '\371', '\150', '\020', '\006', '\156', '\100', '\006', '\062', + '\240', '\331', '\141', '\340', '\006', '\144', '\040', '\003', + '\232', '\237', '\027', '\207', '\341', '\332', '\171', '\161', + '\030', '\231', '\177', '\376', '\132', '\221', '\006', '\262', + '\117', '\332', '\151', '\040', '\373', '\156', '\240', '\371', + '\355', '\377', '\006', '\156', '\260', '\373', '\151', '\077', + '\007', '\254', '\335', '\376', '\157', '\340', '\006', '\273', + '\237', '\366', '\163', '\060', '\007', '\232', '\237', '\373', + '\231', '\277', '\377', '\250', '\221', '\373', '\231', '\277', + '\377', '\371', '\177', '\376', '\241', '\375', '\372', '\231', + '\277', '\375', '\111', '\372', '\372', '\231', '\277', '\375', + '\232', '\237', '\373', '\231', '\137', '\376', '\111', '\372', + '\372', '\231', '\137', '\376', '\232', '\237', '\373', '\164', + '\040', '\006', '\165', '\020', '\374', '\244', '\235', '\373', + '\164', '\040', '\006', '\165', '\020', '\374', '\156', '\240', + '\371', '\154', '\300', '\006', '\165', '\357', '\006', '\177', + '\121', '\331', '\154', '\300', '\006', '\165', '\357', '\006', + '\177', '\141', '\376', '\157', '\237', '\244', '\371', '\037', + '\006', '\156', '\360', '\027', '\225', '\315', '\006', '\371', + '\037', '\006', '\156', '\360', '\027', '\346', '\377', '\366', + '\000', '\100', '\366', '\244', '\115', '\366', '\156', '\240', + '\371', '\155', '\220', '\006', '\144', '\100', '\006', '\256', + '\057', '\006', '\165', '\020', '\374', '\244', '\335', '\006', + '\151', '\100', '\006', '\144', '\340', '\372', '\142', '\120', + '\007', '\301', '\357', '\006', '\232', '\337', '\006', '\157', + '\120', '\007', '\173', '\001', '\000', '\155', '\360', '\006', + '\165', '\260', '\027', '\232', '\017', '\007', '\214', '\061', + '\006', '\151', '\240', '\244', '\160', '\300', '\030', '\143', + '\220', '\006', '\154', '\240', '\371', '\354', '\357', '\376', + '\340', '\177', '\332', '\363', '\017', '\376', '\232', '\017', + '\007', '\154', '\120', '\007', '\254', '\015', '\007', '\154', + '\120', '\007', '\163', '\240', '\371', '\161', '\120', '\007', + '\172', '\101', '\007', '\151', '\360', '\006', '\156', '\340', + '\370', '\210', '\017', '\000', '\161', '\120', '\007', '\172', + '\101', '\007', '\151', '\360', '\006', '\156', '\340', '\370', + '\210', '\257', '\371', '\316', '\177', '\374', '\372', '\317', + '\377', '\252', '\135', '\374', '\307', '\257', '\377', '\374', + '\257', '\371', '\316', '\177', '\374', '\325', '\237', '\006', + '\327', '\257', '\332', '\305', '\177', '\374', '\325', '\237', + '\006', '\327', '\257', '\371', '\316', '\177', '\374', '\337', + '\037', '\376', '\252', '\135', '\374', '\307', '\377', '\375', + '\341', '\257', '\371', '\316', '\177', '\374', '\142', '\120', + '\007', '\301', '\117', '\332', '\316', '\177', '\374', '\142', + '\120', '\007', '\301', '\357', '\006', '\232', '\057', '\007', + '\164', '\300', '\006', '\255', '\317', '\371', '\246', '\055', + '\007', '\164', '\300', '\006', '\255', '\317', '\371', '\157', + '\240', '\371', '\163', '\020', '\006', '\151', '\300', '\006', + '\227', '\137', '\371', '\000', '\060', '\007', '\141', '\220', + '\006', '\154', '\160', '\371', '\225', '\257', '\371', '\163', + '\040', '\006', '\200', '\177', '\007', '\156', '\340', '\370', + '\210', '\017', '\000', '\163', '\040', '\006', '\200', '\177', + '\007', '\156', '\340', '\370', '\210', '\257', '\371', '\163', + '\040', '\006', '\137', '\200', '\006', '\200', '\137', '\007', + '\142', '\340', '\372', '\216', '\217', '\370', '\000', '\060', + '\007', '\142', '\360', '\005', '\150', '\000', '\370', '\165', + '\040', '\006', '\256', '\357', '\370', '\210', '\257', '\371', + '\163', '\040', '\006', '\255', '\377', '\372', '\231', '\157', + '\367', '\000', '\060', '\007', '\142', '\320', '\372', '\257', + '\237', '\371', '\177', '\177', '\376', '\132', '\061', '\007', + '\142', '\060', '\374', '\305', '\177', '\374', '\216', '\217', + '\370', '\000', '\060', '\007', '\142', '\060', '\374', '\305', + '\177', '\374', '\216', '\217', '\370', '\232', '\077', '\007', + '\142', '\360', '\005', '\221', '\157', '\367', '\000', '\060', + '\007', '\142', '\360', '\005', '\221', '\377', '\367', '\347', + '\257', '\025', '\163', '\040', '\006', '\137', '\140', '\007', + '\200', '\137', '\007', '\142', '\340', '\372', '\216', '\217', + '\370', '\000', '\060', '\007', '\142', '\360', '\005', '\166', + '\000', '\370', '\165', '\040', '\006', '\256', '\357', '\370', + '\210', '\257', '\371', '\163', '\200', '\006', '\165', '\220', + '\372', '\256', '\017', '\000', '\163', '\200', '\006', '\165', + '\220', '\372', '\256', '\257', '\371', '\237', '\257', '\007', + '\151', '\340', '\006', '\231', '\375', '\371', '\172', '\220', + '\006', '\156', '\160', '\006', '\232', '\077', '\007', '\354', + '\177', '\375', '\253', '\315', '\376', '\327', '\237', '\377', + '\347', '\257', '\025', '\163', '\000', '\007', '\356', '\237', + '\007', '\143', '\020', '\006', '\244', '\075', '\007', '\160', + '\340', '\376', '\171', '\060', '\006', '\141', '\340', '\006', + '\232', '\077', '\007', '\164', '\160', '\030', '\000', '\060', + '\007', '\164', '\160', '\030', '\232', '\117', '\007', '\207', + '\161', '\006', '\145', '\340', '\332', '\164', '\160', '\030', + '\147', '\120', '\006', '\231', '\177', '\376', '\132', '\101', + '\007', '\143', '\220', '\366', '\163', '\300', '\332', '\164', + '\060', '\006', '\151', '\077', '\007', '\163', '\240', '\371', + '\252', '\017', '\007', '\255', '\377', '\372', '\231', '\157', + '\367', '\255', '\375', '\006', '\160', '\320', '\372', '\257', + '\237', '\371', '\177', '\177', '\376', '\132', '\241', '\372', + '\160', '\320', '\372', '\257', '\017', '\375', '\264', '\337', + '\332', '\157', '\000', '\007', '\255', '\377', '\372', '\320', + '\357', '\373', '\347', '\257', '\025', '\252', '\017', '\007', + '\303', '\137', '\374', '\307', '\277', '\373', '\311', '\217', + '\032', '\252', '\017', '\007', '\303', '\137', '\374', '\307', + '\277', '\373', '\311', '\237', '\377', '\347', '\257', '\025', + '\252', '\017', '\007', '\325', '\237', '\006', '\327', '\337', + '\332', '\157', '\000', '\007', '\325', '\237', '\006', '\327', + '\257', '\371', '\252', '\017', '\007', '\337', '\037', '\376', + '\255', '\375', '\006', '\160', '\360', '\375', '\341', '\257', + '\371', '\374', '\137', '\006', '\132', '\301', '\377', '\145', + '\260', '\006', '\232', '\137', '\007', '\154', '\120', '\367', + '\156', '\360', '\027', '\225', '\135', '\007', '\154', '\120', + '\367', '\156', '\360', '\027', '\346', '\377', '\366', '\257', + '\015', '\031', '\210', '\301', '\006', '\154', '\000', '\331', + '\217', '\041', '\006', '\210', '\301', '\006', '\154', '\020', + '\006', '\232', '\017', '\366', '\165', '\357', '\006', '\177', + '\121', '\331', '\140', '\137', '\367', '\156', '\360', '\027', + '\346', '\377', '\366', '\000', '\160', '\007', '\225', '\077', + '\006', '\233', '\175', '\007', '\225', '\077', '\006', '\150', + '\240', '\371', '\170', '\200', '\377', '\143', '\201', '\007', + '\370', '\317', '\372', '\347', '\257', '\025', '\357', '\141', + '\020', '\303', '\064', '\236', '\335', '\141', '\026', '\340', + '\041', '\036', '\115', '\131', '\036', '\045', '\115', '\322', + '\011', '\001', + +}; + +static const char file_5x7[] = { + '\037', '\235', '\214', '\001', '\314', '\214', '\201', '\203', + '\000', '\200', '\301', '\000', '\006', '\023', '\032', '\244', + '\043', '\300', '\040', '\242', '\204', '\015', '\025', '\032', + '\044', '\223', '\220', '\137', '\104', '\002', '\012', '\021', + '\002', '\100', '\203', '\021', '\000', '\230', '\001', '\006', + '\013', '\112', '\004', '\200', '\053', '\201', '\101', '\144', + '\007', '\014', '\202', '\030', '\011', '\000', '\102', '\104', + '\100', '\021', '\014', '\002', '\141', '\211', '\010', '\044', + '\000', '\110', '\023', '\014', '\002', '\142', '\111', '\316', + '\200', '\101', '\014', '\027', '\022', '\152', '\124', '\110', + '\321', '\040', '\277', '\016', '\043', '\203', '\216', '\014', + '\040', '\041', '\141', '\316', '\203', '\033', '\022', '\256', + '\074', '\310', '\042', '\241', '\014', '\241', '\076', '\022', + '\026', '\021', '\272', '\044', '\141', '\023', '\241', '\133', + '\022', '\212', '\021', '\032', '\047', '\241', '\034', '\205', + '\051', '\015', '\366', '\121', '\150', '\044', '\341', '\303', + '\204', '\135', '\015', '\126', '\122', '\030', '\027', '\200', + '\050', '\241', '\252', '\022', '\262', '\122', '\170', '\325', + '\240', '\056', '\241', '\313', '\022', '\116', '\023', '\112', + '\056', '\241', '\071', '\226', '\000', '\362', '\145', '\114', + '\130', '\100', '\143', '\200', '\007', '\032', '\147', '\070', + '\306', '\241', '\361', '\315', '\120', '\005', '\011', '\355', + '\014', '\075', '\223', '\060', '\320', '\120', '\237', '\006', + '\025', '\015', '\055', '\240', '\260', '\222', '\106', '\043', + '\117', '\234', '\120', '\161', '\022', '\244', '\111', '\221', + '\057', '\122', '\212', '\034', '\111', '\062', '\205', '\212', + '\224', '\054', '\006', '\121', '\127', '\161', '\102', '\344', + '\066', '\200', '\046', '\151', '\346', '\214', '\001', '\140', + '\244', '\165', '\022', '\046', '\131', '\276', '\260', '\166', + '\115', '\074', '\015', '\236', '\062', '\024', '\257', '\024', + '\111', '\162', '\004', '\011', '\025', '\345', '\255', '\267', + '\066', '\201', '\236', '\246', '\116', '\033', '\000', '\123', + '\230', '\004', '\121', '\015', '\100', '\012', '\370', '\042', + '\124', '\256', '\044', '\041', '\102', '\005', '\011', '\166', + '\346', '\116', '\336', '\310', '\151', '\023', '\206', '\015', + '\200', '\040', '\104', '\210', '\174', '\251', '\235', '\205', + '\311', '\353', '\345', '\133', '\001', '\000', '\105', '\022', + '\130', '\024', '\301', '\304', '\176', '\111', '\150', '\261', + '\025', '\024', '\117', '\044', '\241', '\032', '\202', '\012', + '\226', '\127', '\304', '\024', '\117', '\060', '\121', '\005', + '\025', '\111', '\244', '\366', '\005', '\026', '\022', '\122', + '\150', '\041', '\206', '\032', '\342', '\066', '\005', '\024', + '\101', '\014', '\341', '\340', '\021', '\000', '\014', '\161', + '\237', '\025', '\105', '\110', '\021', '\304', '\021', '\257', + '\251', '\307', '\036', '\022', '\051', '\042', '\021', '\204', + '\024', '\123', '\240', '\007', '\233', '\154', '\264', '\331', + '\206', '\033', '\155', '\117', '\340', '\200', '\103', '\015', + '\071', '\324', '\170', '\143', '\216', '\327', '\025', '\341', + '\304', '\020', '\117', '\020', '\161', '\042', '\000', '\061', + '\000', '\260', '\033', '\021', '\055', '\062', '\341', '\340', + '\153', '\014', '\116', '\221', '\004', '\210', '\116', '\000', + '\100', '\145', '\155', '\016', '\006', '\301', '\145', '\212', + '\117', '\100', '\221', '\205', '\024', '\324', '\131', '\227', + '\342', '\033', '\160', '\344', '\041', '\107', '\032', '\147', + '\240', '\101', '\007', '\010', '\061', '\344', '\220', '\103', + '\014', '\054', '\320', '\151', '\047', '\016', '\040', '\120', + '\201', '\106', '\031', '\040', '\074', '\001', '\107', '\031', + '\156', '\200', '\160', '\204', '\034', '\157', '\324', '\001', + '\007', '\161', '\251', '\121', '\001', '\100', '\013', '\300', + '\011', '\327', '\202', '\021', '\316', '\101', '\007', '\051', + '\167', '\336', '\265', '\040', '\105', '\013', '\361', '\315', + '\127', '\137', '\013', '\055', '\334', '\020', '\052', '\014', + '\241', '\326', '\120', '\152', '\013', '\103', '\264', '\120', + '\003', '\251', '\100', '\012', '\111', '\144', '\013', '\121', + '\112', '\227', '\246', '\243', '\261', '\171', '\170', '\141', + '\206', '\135', '\142', '\361', '\005', '\022', '\323', '\125', + '\347', '\150', '\024', '\125', '\340', '\367', '\205', '\214', + '\355', '\041', '\046', '\224', '\102', '\240', '\001', '\060', + '\324', '\120', '\006', '\221', '\106', '\232', '\117', '\314', + '\002', '\340', '\323', '\263', '\312', '\032', '\153', '\355', + '\265', '\330', '\146', '\133', '\055', '\000', '\340', '\000', + '\000', '\110', '\041', '\205', '\030', '\022', '\310', '\267', + '\341', '\216', '\013', '\256', '\270', '\344', '\242', '\173', + '\256', '\271', '\345', '\246', '\313', '\256', '\272', '\355', + '\256', '\353', '\356', '\274', '\362', '\326', '\033', '\357', + '\275', '\350', '\032', '\202', '\357', '\273', '\374', '\322', + '\333', '\256', '\276', '\360', '\006', '\334', '\257', '\275', + '\002', '\373', '\133', '\060', '\301', '\003', '\357', '\153', + '\160', '\302', '\007', '\053', '\214', '\360', '\302', '\020', + '\077', '\054', '\261', '\303', '\024', '\067', '\154', '\061', + '\303', '\030', '\107', '\134', '\161', '\306', '\023', '\137', + '\254', '\261', '\307', '\035', '\163', '\274', '\361', '\307', + '\042', '\203', '\074', '\162', '\310', '\044', '\247', '\374', + '\060', '\300', '\045', '\267', '\234', '\062', '\313', '\052', + '\237', '\054', '\263', '\311', '\064', '\273', '\214', '\362', + '\315', '\063', '\333', '\234', '\163', '\314', '\065', '\363', + '\254', '\163', '\317', '\070', '\003', '\275', '\163', '\320', + '\077', '\027', '\355', '\363', '\321', '\104', '\043', '\075', + '\164', '\271', '\043', '\165', '\073', '\122', '\132', '\000', + '\070', '\220', '\120', '\005', '\011', '\161', '\220', '\320', + '\010', '\011', '\251', '\220', '\120', '\224', '\006', '\341', + '\220', '\320', '\017', '\011', '\265', '\145', '\320', '\127', + '\006', '\071', '\152', '\120', '\130', '\006', '\215', '\145', + '\120', '\032', '\011', '\055', '\152', '\320', '\035', '\011', + '\371', '\221', '\120', '\041', '\011', '\061', '\222', '\320', + '\044', '\011', '\151', '\222', '\120', '\050', '\011', '\241', + '\222', '\320', '\053', '\011', '\331', '\222', '\120', '\057', + '\011', '\021', '\223', '\120', '\140', '\006', '\111', '\223', + '\120', '\066', '\011', '\071', '\015', '\300', '\071', '\011', + '\271', '\223', '\120', '\075', '\025', '\045', '\064', '\200', + '\106', '\012', '\150', '\024', '\201', '\106', '\030', '\150', + '\364', '\201', '\106', '\046', '\150', '\324', '\202', '\106', + '\064', '\150', '\264', '\203', '\106', '\102', '\150', '\224', + '\204', '\106', '\120', '\150', '\164', '\205', '\106', '\136', + '\150', '\124', '\206', '\106', '\154', '\150', '\064', '\207', + '\106', '\172', '\150', '\344', '\231', '\103', '\032', '\075', + '\242', '\221', '\045', '\032', '\165', '\242', '\021', '\051', + '\032', '\255', '\242', '\221', '\054', '\032', '\345', '\242', + '\021', '\060', '\032', '\035', '\243', '\221', '\063', '\032', + '\125', '\243', '\021', '\067', '\032', '\215', '\243', '\221', + '\072', '\032', '\305', '\243', '\021', '\076', '\032', '\375', + '\243', '\221', '\001', '\021', '\065', '\020', '\021', '\005', + '\021', '\155', '\020', '\221', '\010', '\021', '\245', '\020', + '\021', '\014', '\021', '\335', '\020', '\221', '\017', '\021', + '\025', '\021', '\021', '\023', '\021', '\115', '\021', '\221', + '\026', '\021', '\205', '\021', '\021', '\032', '\021', '\275', + '\021', '\221', '\035', '\021', '\351', '\103', '\104', '\010', + '\021', '\221', '\105', '\104', '\104', '\022', '\021', '\311', + '\104', '\104', '\100', '\021', '\221', '\123', '\104', '\304', + '\025', '\021', '\251', '\105', '\104', '\170', '\021', '\221', + '\141', '\104', '\104', '\031', '\021', '\211', '\106', '\104', + '\260', '\021', '\221', '\157', '\104', '\304', '\034', '\021', + '\151', '\107', '\104', '\350', '\021', '\221', '\175', '\104', + '\104', '\000', '\066', '\111', '\200', '\115', '\040', '\140', + '\223', '\013', '\330', '\304', '\003', '\066', '\051', '\201', + '\115', '\130', '\140', '\223', '\031', '\330', '\104', '\007', + '\066', '\011', '\202', '\115', '\220', '\140', '\223', '\047', + '\330', '\304', '\012', '\066', '\351', '\202', '\115', '\310', + '\140', '\223', '\065', '\330', '\104', '\016', '\066', '\311', + '\203', '\115', '\000', '\141', '\223', '\103', '\330', '\304', + '\021', '\066', '\251', '\204', '\115', '\070', '\141', '\223', + '\121', '\330', '\104', '\025', '\066', '\211', '\205', '\115', + '\160', '\141', '\223', '\137', '\330', '\304', '\030', '\066', + '\151', '\206', '\115', '\250', '\141', '\223', '\155', '\330', + '\104', '\034', '\066', '\111', '\207', '\115', '\340', '\141', + '\223', '\173', '\330', '\304', '\037', '\066', '\051', '\100', + '\107', '\030', '\320', '\221', '\011', '\164', '\104', '\003', + '\035', '\011', '\101', '\107', '\120', '\320', '\221', '\027', + '\164', '\304', '\006', '\035', '\351', '\101', '\107', '\210', + '\320', '\221', '\045', '\164', '\104', '\012', '\035', '\311', + '\102', '\107', '\300', '\320', '\221', '\063', '\164', '\304', + '\015', '\035', '\251', '\103', '\107', '\370', '\320', '\221', + '\101', '\164', '\104', '\021', '\035', '\211', '\104', '\107', + '\060', '\321', '\221', '\117', '\164', '\304', '\024', '\035', + '\151', '\105', '\107', '\150', '\321', '\221', '\135', '\164', + '\104', '\030', '\035', '\111', '\106', '\107', '\240', '\321', + '\221', '\153', '\164', '\304', '\033', '\035', '\051', '\107', + '\107', '\330', '\321', '\221', '\171', '\164', '\104', '\037', + '\035', '\011', '\000', '\151', '\000', '\200', '\200', '\135', + '\076', '\140', '\227', '\026', '\330', '\145', '\007', '\166', + '\111', '\202', '\135', '\256', '\140', '\227', '\062', '\330', + '\145', '\016', '\166', '\011', '\204', '\135', '\036', '\141', + '\227', '\116', '\330', '\145', '\025', '\166', '\311', '\205', + '\135', '\216', '\141', '\227', '\152', '\330', '\145', '\034', + '\166', '\211', '\207', '\135', '\376', '\141', '\227', '\206', + '\330', '\145', '\043', '\166', '\111', '\211', '\135', '\156', + '\142', '\227', '\242', '\330', '\145', '\052', '\166', '\011', + '\213', '\135', '\336', '\142', '\227', '\276', '\330', '\145', + '\061', '\166', '\311', '\214', '\135', '\116', '\143', '\227', + '\332', '\330', '\145', '\070', '\166', '\211', '\216', '\135', + '\276', '\143', '\227', '\366', '\330', '\145', '\077', '\166', + '\111', '\000', '\320', '\054', '\000', '\064', '\022', '\000', + '\115', '\006', '\100', '\003', '\002', '\320', '\000', '\201', + '\001', '\072', '\301', '\300', '\326', '\014', '\362', '\200', + '\212', '\132', '\324', '\040', '\004', '\160', '\300', '\007', + '\034', '\200', '\021', '\005', '\024', '\300', '\243', '\036', + '\005', '\100', '\001', '\016', '\120', '\200', '\002', '\160', + '\224', '\000', '\227', '\033', '\100', '\003', '\010', '\100', + '\307', '\224', '\032', '\100', '\001', '\057', '\015', '\100', + '\000', '\006', '\100', '\107', '\072', '\022', '\100', '\001', + '\035', '\301', '\050', '\107', '\243', '\146', '\220', '\004', + '\054', '\240', '\001', '\011', '\040', '\000', '\113', '\113', + '\132', '\000', '\001', '\234', '\124', '\250', '\004', '\200', + '\132', '\102', '\016', '\200', '\324', '\252', '\041', '\025', + '\251', '\126', '\303', '\250', '\120', '\077', '\320', '\324', + '\017', '\260', '\304', '\252', '\043', '\301', '\252', '\104', + '\264', '\252', '\020', '\253', '\102', '\365', '\251', '\102', + '\145', '\052', '\130', '\271', '\152', '\020', '\252', '\202', + '\365', '\251', '\010', '\040', '\200', '\000', '\010', '\200', + '\000', '\251', '\255', '\065', '\255', '\106', '\115', '\210', + '\003', '\024', '\100', '\327', '\220', '\160', '\324', '\001', + '\021', '\141', '\200', '\000', '\016', '\040', '\200', '\006', + '\050', '\044', '\247', '\054', '\171', '\052', '\000', '\072', + '\132', '\127', '\205', '\050', '\340', '\003', '\207', '\305', + '\114', '\324', '\114', '\112', '\001', '\251', '\005', '\040', + '\250', '\002', '\110', '\200', '\110', '\004', '\120', '\324', + '\217', '\112', '\113', '\000', '\314', '\122', '\253', '\000', + '\066', '\213', '\221', '\265', '\042', '\065', '\042', '\105', + '\345', '\053', '\101', '\011', '\140', '\126', '\211', '\200', + '\157', '\050', '\017', '\140', '\211', '\001', '\100', '\003', + '\127', '\215', '\120', '\226', '\250', '\015', '\101', '\341', + '\146', '\367', '\052', '\055', '\311', '\252', '\065', '\265', + '\017', '\100', '\200', '\001', '\020', '\220', '\000', '\237', + '\024', '\264', '\000', '\017', '\020', '\052', '\000', '\040', + '\163', '\000', '\336', '\372', '\304', '\000', '\001', '\070', + '\100', '\002', '\172', '\073', '\334', '\264', '\152', '\266', + '\266', '\006', '\130', '\356', '\161', '\227', '\353', '\000', + '\335', '\032', '\144', '\265', '\322', '\002', '\015', '\166', + '\117', '\073', '\130', '\314', '\256', '\065', '\041', '\270', + '\025', '\312', '\132', '\061', '\013', '\000', '\312', '\252', + '\265', '\274', '\265', '\155', '\100', '\003', '\002', '\060', + '\335', '\004', '\074', '\140', '\271', '\000', '\120', '\256', + '\162', '\023', '\220', '\222', '\350', '\312', '\224', '\271', + '\363', '\135', '\156', '\112', '\210', '\053', '\123', '\334', + '\046', '\127', '\246', '\010', '\261', '\057', '\120', '\245', + '\266', '\334', '\367', '\302', '\227', '\257', '\263', '\115', + '\011', '\002', '\026', '\154', '\134', '\000', '\044', '\240', + '\000', '\003', '\030', '\100', '\001', '\114', '\002', '\340', + '\376', '\072', '\270', '\242', '\313', '\065', '\211', '\117', + '\177', '\012', '\324', '\332', '\146', '\330', '\047', '\363', + '\075', '\200', '\114', '\075', '\354', '\323', '\335', '\206', + '\170', '\302', '\265', '\135', '\053', '\176', '\147', '\273', + '\131', '\007', '\147', '\230', '\271', '\057', '\306', '\156', + '\206', '\061', '\354', '\342', '\325', '\302', '\027', '\266', + '\055', '\316', '\255', '\132', '\037', '\023', '\337', '\012', + '\247', '\045', '\000', '\157', '\065', '\210', '\130', '\303', + '\132', '\336', '\135', '\042', '\046', '\265', '\003', '\370', + '\256', '\104', '\034', '\220', '\200', '\006', '\140', '\106', + '\246', '\041', '\116', '\010', '\162', '\331', '\313', '\313', + '\266', '\122', '\127', '\312', '\015', '\030', '\200', '\157', + '\025', '\260', '\327', '\026', '\033', '\204', '\311', '\310', + '\165', '\000', '\224', '\063', '\214', '\336', '\044', '\323', + '\026', '\043', '\110', '\055', '\252', '\114', '\041', '\214', + '\142', '\063', '\157', '\026', '\152', '\300', '\205', '\257', + '\220', '\311', '\174', '\135', '\351', '\056', '\125', '\277', + '\032', '\141', '\162', '\002', '\252', '\073', '\347', '\021', + '\177', '\231', '\246', '\051', '\171', '\363', '\146', '\041', + '\332', '\323', '\053', '\067', '\253', '\244', '\021', '\161', + '\161', '\105', '\023', '\322', '\333', '\350', '\062', '\072', + '\001', '\070', '\215', '\110', '\160', '\005', '\220', '\132', + '\265', '\232', '\271', '\263', '\054', '\156', '\010', '\220', + '\301', '\107', '\336', '\220', '\152', '\353', '\257', '\203', + '\155', '\352', '\140', '\035', '\120', '\322', '\235', '\352', + '\225', '\257', '\176', '\005', '\100', '\004', '\346', '\352', + '\200', '\230', '\040', '\032', '\301', '\122', '\015', '\065', + '\000', '\364', '\372', '\122', '\006', '\350', '\126', '\261', + '\012', '\151', '\165', '\005', '\046', '\120', '\201', '\125', + '\033', '\240', '\000', '\311', '\112', '\210', '\004', '\022', + '\320', '\024', '\360', '\212', '\104', '\041', '\251', '\375', + '\162', '\004', '\056', '\060', '\201', '\011', '\254', '\072', + '\331', '\177', '\305', '\351', '\137', '\111', '\073', '\125', + '\151', '\251', '\065', '\131', '\253', '\055', '\150', '\102', + '\316', '\073', '\222', '\014', '\213', '\330', '\001', '\013', + '\130', '\000', '\135', '\025', '\213', '\135', '\304', '\250', + '\265', '\240', '\031', '\205', '\110', '\121', '\273', '\075', + '\354', '\203', '\334', '\227', '\001', '\325', '\005', '\160', + '\003', '\322', '\312', '\200', '\010', '\013', '\140', '\001', + '\360', '\106', '\100', '\154', '\165', '\331', '\220', '\350', + '\272', '\027', '\276', '\376', '\066', '\260', '\207', '\005', + '\036', '\160', '\200', '\027', '\330', '\340', '\377', '\066', + '\011', '\251', '\033', '\100', '\122', '\277', '\332', '\367', + '\261', '\340', '\343', '\057', '\217', '\045', '\356', '\137', + '\021', '\117', '\374', '\277', '\074', '\106', '\360', '\233', + '\343', '\313', '\342', '\224', '\150', '\234', '\266', '\037', + '\367', '\270', '\002', '\304', '\255', '\200', '\224', '\000', + '\225', '\303', '\046', '\361', '\267', '\235', '\125', '\316', + '\134', '\226', '\267', '\167', '\345', '\061', '\146', '\264', + '\215', '\243', '\246', '\336', '\160', '\247', '\344', '\305', + '\060', '\216', '\071', '\316', '\175', '\262', '\163', '\221', + '\042', '\272', '\305', '\311', '\245', '\357', '\210', '\243', + '\253', '\334', '\005', '\064', '\146', '\255', '\114', '\166', + '\162', '\167', '\223', '\216', '\231', '\233', '\062', '\035', + '\000', '\036', '\175', '\072', '\146', '\236', '\276', '\332', + '\247', '\177', '\271', '\001', '\046', '\225', '\262', '\114', + '\071', '\135', '\320', '\054', '\373', '\126', '\000', '\006', + '\360', '\172', '\221', '\303', '\256', '\145', '\221', '\112', + '\113', '\354', '\100', '\066', '\163', '\240', '\147', '\272', + '\161', '\312', '\252', '\335', '\354', '\157', '\027', '\000', + '\003', '\374', '\355', '\023', '\217', '\346', '\267', '\274', + '\005', '\265', '\363', '\265', '\127', '\356', '\341', '\272', + '\003', '\333', '\316', '\317', '\262', '\263', '\264', '\206', + '\073', '\370', '\253', '\057', '\040', '\320', '\004', '\310', + '\260', '\324', '\324', '\252', '\370', '\301', '\067', '\036', + '\063', '\215', '\147', '\074', '\244', '\317', '\033', '\164', + '\241', '\103', '\176', '\362', '\211', '\116', '\310', '\077', + '\214', '\205', '\220', '\206', '\200', '\004', '\043', '\324', + '\122', '\260', '\203', '\241', '\016', '\200', '\005', '\314', + '\032', '\000', '\176', '\225', '\132', '\152', '\041', '\240', + '\152', '\000', '\064', '\045', '\047', '\024', '\000', '\000', + '\325', '\054', '\000', '\200', '\240', '\110', '\064', '\003', + '\000', '\320', '\000', '\000', '\242', '\142', '\065', '\244', + '\170', '\000', '\000', '\126', '\135', '\111', '\010', '\000', + '\040', '\002', '\000', '\140', '\215', '\004', '\000', '\050', + '\001', '\000', '\114', '\000', '\200', '\023', '\000', '\000', + '\005', '\000', '\110', '\001', '\000', '\264', '\266', '\002', + '\000', '\124', '\245', '\005', '\000', '\160', '\001', '\000', + '\136', '\000', '\000', '\030', '\100', '\011', '\000', '\127', + '\231', '\001', '\000', '\150', '\000', '\200', '\032', '\000', + '\300', '\006', '\000', '\270', '\001', '\000', '\274', '\126', + '\044', '\035', '\000', '\140', '\007', '\000', '\340', '\001', + '\000', '\172', '\000', '\200', '\254', '\200', '\155', '\046', + '\101', '\000', '\200', '\020', '\122', '\344', '\045', '\000', + '\154', '\245', '\055', '\050', '\102', '\043', '\111', '\000', + '\000', '\112', '\000', '\000', '\135', '\301', '\004', '\277', + '\001', '\000', '\135', '\362', '\004', '\002', '\002', '\000', + '\121', '\120', '\036', '\340', '\001', '\000', '\216', '\122', + '\005', '\000', '\140', '\005', '\000', '\160', '\005', '\000', + '\300', '\041', '\270', '\241', '\005', '\000', '\020', '\026', + '\134', '\000', '\000', '\135', '\000', '\000', '\136', '\000', + '\000', '\137', '\340', '\021', '\000', '\020', '\006', '\000', + '\060', '\026', '\303', '\101', '\021', '\145', '\000', '\000', + '\146', '\000', '\000', '\234', '\201', '\006', '\000', '\300', + '\066', '\152', '\000', '\000', '\153', '\000', '\000', '\366', + '\361', '\035', '\156', '\000', '\000', '\157', '\000', '\000', + '\213', '\122', '\026', '\147', '\061', '\007', '\000', '\100', + '\007', '\000', '\120', '\007', '\000', '\140', '\007', '\000', + '\000', '\067', '\170', '\000', '\000', '\171', '\000', '\000', + '\172', '\000', '\000', '\173', '\000', '\000', '\174', '\000', + '\000', '\153', '\041', '\067', '\177', '\000', '\000', '\377', + '\220', '\205', '\132', '\270', '\205', '\134', '\330', '\205', + '\136', '\370', '\205', '\140', '\030', '\206', '\140', '\270', + '\023', '\201', '\000', '\000', '\202', '\000', '\000', '\203', + '\000', '\000', '\204', '\000', '\000', '\164', '\143', '\010', + '\000', '\160', '\010', '\000', '\360', '\020', '\211', '\000', + '\000', '\212', '\000', '\000', '\213', '\000', '\000', '\166', + '\323', '\010', '\000', '\340', '\010', '\000', '\360', '\010', + '\067', '\001', '\000', '\221', '\000', '\000', '\222', '\000', + '\000', '\170', '\103', '\011', '\000', '\060', '\027', '\226', + '\000', '\000', '\227', '\000', '\000', '\230', '\000', '\000', + '\231', '\000', '\000', '\172', '\263', '\011', '\000', '\300', + '\011', '\000', '\320', '\011', '\000', '\340', '\011', '\000', + '\360', '\011', '\000', '\000', '\012', '\000', '\300', '\067', + '\167', '\061', '\012', '\000', '\100', '\012', '\000', '\120', + '\012', '\000', '\140', '\012', '\000', '\160', '\012', '\000', + '\340', '\067', '\251', '\000', '\000', '\171', '\261', '\012', + '\000', '\260', '\027', '\255', '\000', '\000', '\256', '\000', + '\000', '\200', '\003', '\013', '\000', '\020', '\013', '\000', + '\040', '\013', '\000', '\060', '\013', '\000', '\100', '\013', + '\000', '\120', '\013', '\000', '\040', '\070', '\267', '\100', + '\022', '\000', '\220', '\013', '\000', '\360', '\027', '\273', + '\000', '\000', '\274', '\000', '\000', '\204', '\343', '\013', + '\000', '\360', '\013', '\000', '\000', '\014', '\000', '\020', + '\014', '\000', '\040', '\014', '\000', '\060', '\014', '\000', + '\140', '\070', '\305', '\000', '\000', '\306', '\000', '\000', + '\307', '\000', '\000', '\310', '\000', '\000', '\311', '\000', + '\000', '\312', '\000', '\000', '\201', '\301', '\014', '\000', + '\320', '\014', '\000', '\340', '\014', '\000', '\360', '\014', + '\000', '\000', '\015', '\000', '\020', '\015', '\000', '\240', + '\070', '\203', '\101', '\015', '\000', '\120', '\015', '\000', + '\140', '\015', '\000', '\160', '\015', '\000', '\200', '\015', + '\000', '\300', '\070', '\332', '\000', '\000', '\333', '\000', + '\000', '\334', '\000', '\000', '\335', '\000', '\000', '\336', + '\000', '\000', '\337', '\300', '\022', '\216', '\003', '\101', + '\006', '\341', '\220', '\262', '\370', '\100', '\022', '\371', + '\220', '\023', '\031', '\221', '\024', '\171', '\221', '\026', + '\231', '\221', '\020', '\271', '\221', '\025', '\311', '\221', + '\030', '\351', '\221', '\032', '\331', '\221', '\042', '\371', + '\221', '\043', '\031', '\222', '\044', '\171', '\222', '\046', + '\231', '\222', '\040', '\271', '\222', '\045', '\311', '\222', + '\050', '\351', '\222', '\052', '\331', '\222', '\062', '\371', + '\222', '\063', '\031', '\223', '\064', '\171', '\223', '\066', + '\231', '\223', '\060', '\271', '\223', '\065', '\311', '\223', + '\070', '\351', '\223', '\072', '\331', '\223', '\102', '\371', + '\223', '\103', '\031', '\224', '\104', '\171', '\224', '\106', + '\231', '\224', '\100', '\271', '\224', '\105', '\311', '\224', + '\110', '\351', '\224', '\112', '\331', '\224', '\122', '\371', + '\224', '\123', '\031', '\225', '\124', '\171', '\225', '\126', + '\231', '\225', '\012', '\341', '\070', '\012', '\141', '\144', + '\270', '\006', '\155', '\261', '\147', '\020', '\270', '\147', + '\020', '\277', '\147', '\020', '\130', '\143', '\020', '\320', + '\147', '\020', '\330', '\147', '\020', '\175', '\221', '\176', + '\011', '\041', '\177', '\006', '\221', '\177', '\271', '\001', + '\027', '\011', '\001', '\005', '\011', '\101', '\201', '\006', + '\301', '\201', '\006', '\121', '\202', '\023', '\221', '\020', + '\154', '\143', '\020', '\073', '\150', '\020', '\102', '\150', + '\020', '\113', '\250', '\026', '\011', '\161', '\206', '\006', + '\001', '\207', '\006', '\141', '\067', '\006', '\021', '\210', + '\006', '\221', '\210', '\006', '\041', '\211', '\006', '\301', + '\211', '\006', '\101', '\212', '\006', '\201', '\212', '\006', + '\261', '\212', '\006', '\341', '\212', '\006', '\021', '\213', + '\006', '\001', '\070', '\006', '\201', '\213', '\006', '\301', + '\213', '\006', '\001', '\214', '\006', '\061', '\214', '\006', + '\141', '\214', '\006', '\221', '\214', '\006', '\101', '\070', + '\006', '\001', '\215', '\006', '\101', '\215', '\006', '\201', + '\215', '\006', '\261', '\215', '\006', '\361', '\215', '\006', + '\061', '\216', '\006', '\201', '\070', '\351', '\230', '\020', + '\356', '\150', '\020', '\362', '\150', '\020', '\203', '\141', + '\020', '\370', '\150', '\020', '\374', '\150', '\020', '\214', + '\143', '\020', '\003', '\151', '\020', '\007', '\151', '\020', + '\013', '\151', '\020', '\341', '\220', '\020', '\343', '\220', + '\020', '\345', '\220', '\020', '\220', '\143', '\020', '\351', + '\220', '\020', '\353', '\220', '\020', '\355', '\220', '\020', + '\357', '\220', '\020', '\361', '\220', '\020', '\363', '\060', + '\071', '\011', '\161', '\017', '\011', '\241', '\030', '\006', + '\261', '\017', '\011', '\321', '\017', '\232', '\047', '\024', + '\032', '\161', '\071', '\315', '\242', '\021', '\042', '\326', + '\123', '\032', '\261', '\000', '\032', '\261', '\136', '\024', + '\245', '\071', '\032', '\061', '\001', '\032', '\121', '\001', + '\032', '\161', '\001', '\032', '\221', '\001', '\032', '\261', + '\001', '\032', '\321', '\001', '\236', '\243', '\021', '\041', + '\240', '\021', '\043', '\240', '\021', '\045', '\240', '\021', + '\047', '\240', '\021', '\051', '\240', '\021', '\053', '\040', + '\072', '\032', '\361', '\002', '\032', '\021', '\003', '\221', + '\241', '\021', '\065', '\240', '\021', '\067', '\240', '\021', + '\071', '\140', '\072', '\032', '\321', '\003', '\032', '\361', + '\003', '\032', '\021', '\004', '\032', '\061', '\004', '\032', + '\121', '\004', '\032', '\161', '\004', '\252', '\243', '\021', + '\113', '\240', '\021', '\115', '\240', '\021', '\117', '\240', + '\021', '\121', '\240', '\021', '\123', '\240', '\021', '\125', + '\340', '\072', '\032', '\221', '\005', '\032', '\261', '\005', + '\032', '\321', '\005', '\032', '\361', '\005', '\032', '\021', + '\006', '\032', '\161', '\006', '\264', '\243', '\021', '\161', + '\240', '\021', '\232', '\141', '\020', '\173', '\240', '\021', + '\200', '\240', '\021', '\205', '\240', '\021', '\242', '\141', + '\020', '\276', '\143', '\020', '\224', '\240', '\021', '\231', + '\240', '\021', '\236', '\240', '\021', '\243', '\240', '\021', + '\250', '\240', '\021', '\255', '\160', '\074', '\032', '\161', + '\013', '\032', '\301', '\013', '\032', '\021', '\014', '\032', + '\141', '\014', '\032', '\261', '\014', '\032', '\001', '\015', + '\321', '\243', '\021', '\332', '\240', '\021', '\337', '\240', + '\021', '\344', '\240', '\021', '\351', '\240', '\021', '\356', + '\240', '\021', '\363', '\260', '\075', '\032', '\321', '\017', + '\256', '\025', '\021', '\174', '\365', '\145', '\021', '\061', + '\001', '\021', '\201', '\001', '\021', '\321', '\001', '\347', + '\023', '\021', '\047', '\020', '\021', '\054', '\020', '\021', + '\061', '\020', '\021', '\070', '\020', '\021', '\075', '\020', + '\021', '\102', '\020', '\021', '\107', '\060', '\077', '\021', + '\021', '\005', '\021', '\141', '\005', '\021', '\261', '\005', + '\021', '\001', '\006', '\021', '\121', '\006', '\021', '\301', + '\006', '\021', '\021', '\007', '\377', '\023', '\021', '\173', + '\360', '\022', '\021', '\121', '\010', '\021', '\241', '\010', + '\021', '\021', '\011', '\021', '\141', '\011', '\021', '\261', + '\011', '\013', '\024', '\021', '\245', '\020', '\021', '\252', + '\020', '\021', '\257', '\020', '\021', '\267', '\060', '\101', + '\021', '\021', '\014', '\021', '\141', '\014', '\021', '\261', + '\014', '\021', '\001', '\015', '\021', '\121', '\015', '\021', + '\241', '\015', '\021', '\041', '\016', '\021', '\161', '\016', + '\021', '\301', '\016', '\021', '\021', '\017', '\021', '\141', + '\017', '\045', '\224', '\150', '\161', '\144', '\023', '\012', + '\140', '\023', '\017', '\140', '\023', '\024', '\140', '\023', + '\031', '\360', '\102', '\066', '\061', '\002', '\066', '\201', + '\002', '\066', '\321', '\002', '\066', '\041', '\003', '\066', + '\161', '\003', '\066', '\301', '\003', '\071', '\144', '\023', + '\106', '\140', '\023', '\113', '\140', '\023', '\120', '\140', + '\023', '\125', '\140', '\023', '\103', '\000', '\003', '\370', + '\232', '\042', '\370', '\032', '\045', '\367', '\012', '\003', + '\127', '\321', '\257', '\342', '\327', '\257', '\344', '\327', + '\257', '\346', '\327', '\257', '\350', '\327', '\257', '\352', + '\167', '\257', '\061', '\340', '\175', '\012', '\313', '\257', + '\060', '\020', '\003', '\377', '\372', '\260', '\001', '\373', + '\260', '\003', '\373', '\260', '\005', '\373', '\260', '\007', + '\373', '\260', '\011', '\353', '\257', '\014', '\353', '\257', + '\016', '\053', '\003', '\021', '\053', '\003', '\023', '\053', + '\003', '\025', '\053', '\003', '\027', '\053', '\003', '\031', + '\053', '\003', '\033', '\073', '\003', '\035', '\073', '\003', + '\016', '\073', '\003', '\021', '\073', '\003', '\023', '\073', + '\003', '\025', '\073', '\003', '\027', '\073', '\003', '\031', + '\073', '\003', '\033', '\113', '\003', '\336', '\067', '\174', + '\305', '\167', '\174', '\311', '\267', '\174', '\315', '\367', + '\174', '\321', '\067', '\175', '\000', '\120', '\175', '\327', + '\227', '\175', '\333', '\327', '\175', '\337', '\027', '\176', + '\343', '\127', '\176', '\347', '\347', '\226', '\354', '\007', + '\000', '\356', '\007', '\177', '\362', '\107', '\177', '\366', + '\007', '\000', '\370', '\247', '\177', '\374', '\107', '\004', + '\376', '\107', '\034', '\000', '\020', '\200', '\000', '\060', + '\200', '\005', '\170', '\200', '\011', '\270', '\200', '\015', + '\370', '\200', '\346', '\061', '\005', '\022', '\050', '\045', + '\025', '\170', '\201', '\031', '\010', '\000', '\033', '\330', + '\201', '\000', '\360', '\201', '\041', '\070', '\202', '\045', + '\010', '\006', '\047', '\230', '\202', '\000', '\260', '\202', + '\000', '\320', '\202', '\057', '\030', '\203', '\063', '\010', + '\000', '\065', '\170', '\203', '\071', '\010', '\000', '\073', + '\330', '\203', '\077', '\010', '\000', '\101', '\070', '\204', + '\105', '\170', '\204', '\111', '\010', '\000', '\113', '\330', + '\204', '\117', '\030', '\205', '\123', '\130', '\205', '\372', + '\307', '\006', '\141', '\340', '\006', '\067', '\070', '\004', + '\061', '\140', '\003', '\014', '\373', '\271', '\374', '\372', + '\271', '\377', '\372', '\271', '\001', '\373', '\271', '\003', + '\373', '\271', '\005', '\373', '\271', '\007', '\373', '\271', + '\011', '\373', '\271', '\136', '\343', '\271', '\066', '\120', + '\044', '\236', '\173', '\003', '\241', '\173', '\003', '\243', + '\173', '\003', '\245', '\173', '\003', '\247', '\173', '\003', + '\251', '\173', '\003', '\253', '\173', '\003', '\255', '\173', + '\003', '\257', '\173', '\003', '\261', '\033', '\003', '\067', + '\100', '\273', '\061', '\200', '\003', '\241', '\213', '\003', + '\243', '\213', '\003', '\245', '\213', '\003', '\247', '\213', + '\003', '\251', '\073', '\044', '\051', '\262', '\274', '\255', + '\213', '\003', '\257', '\053', '\044', '\327', '\213', '\003', + '\312', '\233', '\003', '\241', '\173', '\047', '\367', '\161', + '\006', '\162', '\020', '\006', '\166', '\320', '\202', '\236', + '\233', '\003', '\247', '\233', '\003', '\251', '\233', '\003', + '\253', '\233', '\003', '\255', '\233', '\003', '\257', '\233', + '\003', '\307', '\153', '\047', '\376', '\107', '\276', '\346', + '\213', '\276', '\062', '\360', '\260', '\051', '\262', '\277', + '\377', '\272', '\277', '\001', '\273', '\277', '\003', '\273', + '\277', '\005', '\273', '\277', '\007', '\273', '\277', '\011', + '\273', '\277', '\261', '\273', '\277', '\105', '\362', '\004', + '\370', '\173', '\276', '\375', '\033', '\003', '\374', '\052', + '\003', '\020', '\033', '\301', '\001', '\034', '\003', '\003', + '\034', '\003', '\005', '\374', '\271', '\122', '\362', '\300', + '\372', '\273', '\274', '\021', '\114', '\273', '\040', '\313', + '\260', '\040', '\073', '\301', '\040', '\333', '\277', '\042', + '\173', '\202', '\055', '\340', '\301', '\050', '\134', '\300', + '\050', '\213', '\302', '\011', '\054', '\003', '\013', '\054', + '\003', '\042', '\314', '\262', '\375', '\353', '\262', '\177', + '\273', '\302', '\345', '\013', '\301', '\103', '\040', '\262', + '\001', '\114', '\263', '\067', '\134', '\300', '\070', '\173', + '\303', '\011', '\074', '\003', '\013', '\074', '\003', '\042', + '\314', '\263', '\375', '\113', '\003', '\023', '\114', '\003', + '\377', '\113', '\003', '\001', '\114', '\003', '\003', '\114', + '\003', '\005', '\114', '\003', '\007', '\114', '\003', '\011', + '\114', '\003', '\013', '\114', '\003', '\042', '\274', '\052', + '\375', '\133', '\003', '\023', '\134', '\003', '\377', '\133', + '\003', '\001', '\134', '\003', '\003', '\134', '\003', '\346', + '\147', '\055', '\314', '\222', '\054', '\313', '\042', '\021', + '\316', '\062', '\170', '\321', '\062', '\055', '\160', '\234', + '\020', + +}; + +static const char file_5x8[] = { + '\037', '\235', '\214', '\001', '\314', '\214', '\201', '\223', + '\000', '\200', '\301', '\000', '\006', '\023', '\032', '\144', + '\042', '\300', '\040', '\246', '\204', '\015', '\023', '\042', + '\004', '\100', '\046', '\041', '\271', '\210', '\004', '\024', + '\116', '\104', '\024', '\021', '\311', '\000', '\203', '\010', + '\024', '\046', '\304', '\140', '\300', '\040', '\264', '\002', + '\006', '\041', '\150', '\064', '\310', '\321', '\040', '\272', + '\005', '\006', '\101', '\210', '\114', '\071', '\021', '\216', + '\003', '\203', '\100', '\146', '\002', '\100', '\020', '\021', + '\320', '\003', '\203', '\200', '\164', '\322', '\371', '\010', + '\000', '\121', '\004', '\211', '\110', '\051', '\046', '\344', + '\107', '\141', '\146', '\005', '\235', '\001', '\044', '\044', + '\234', '\040', '\161', '\103', '\102', '\231', '\007', '\131', + '\044', '\224', '\041', '\321', '\107', '\302', '\042', '\022', + '\227', '\044', '\154', '\042', '\161', '\113', '\102', '\061', + '\022', '\343', '\044', '\224', '\243', '\060', '\244', '\301', + '\076', '\012', '\241', '\044', '\104', '\244', '\120', '\254', + '\301', '\112', '\165', '\023', '\212', '\222', '\250', '\052', + '\041', '\053', '\205', '\134', '\015', '\352', '\222', '\270', + '\054', '\341', '\065', '\211', '\350', '\022', '\262', '\223', + '\150', '\157', '\344', '\304', '\000', '\035', '\046', '\152', + '\231', '\010', '\100', '\101', '\302', '\060', '\224', '\317', + '\044', '\144', '\103', '\371', '\100', '\302', '\072', '\224', + '\121', '\212', '\004', '\064', '\321', '\310', '\023', '\047', + '\124', '\234', '\004', '\151', '\122', '\344', '\213', '\224', + '\042', '\107', '\222', '\114', '\241', '\042', '\045', '\213', + '\101', '\323', '\125', '\234', '\020', '\251', '\015', '\240', + '\111', '\232', '\071', '\143', '\000', '\030', '\131', '\235', + '\204', '\111', '\226', '\057', '\252', '\131', '\013', '\117', + '\203', '\247', '\114', '\305', '\053', '\105', '\222', '\034', + '\101', '\102', '\005', '\371', '\152', '\260', '\115', '\234', + '\247', '\251', '\323', '\006', '\300', '\024', '\046', '\101', + '\120', '\003', '\220', '\342', '\275', '\010', '\225', '\053', + '\111', '\210', '\120', '\101', '\142', '\135', '\271', '\223', + '\067', '\162', '\332', '\204', '\141', '\003', '\040', '\010', + '\021', '\042', '\137', '\146', '\147', '\141', '\322', '\072', + '\071', '\130', '\000', '\120', '\044', '\201', '\105', '\021', + '\114', '\344', '\227', '\204', '\026', '\140', '\101', '\361', + '\104', '\022', '\250', '\031', '\210', '\340', '\170', '\105', + '\114', '\361', '\004', '\023', '\125', '\120', '\221', '\304', + '\151', '\137', '\140', '\001', '\241', '\204', '\024', '\132', + '\210', '\241', '\155', '\123', '\100', '\021', '\304', '\020', + '\014', '\036', '\001', '\300', '\020', '\365', '\131', '\121', + '\204', '\024', '\101', '\034', '\321', '\032', '\172', '\352', + '\041', '\161', '\042', '\022', '\101', '\110', '\061', '\205', + '\171', '\256', '\301', '\046', '\033', '\155', '\266', '\311', + '\366', '\204', '\015', '\064', '\330', '\340', '\102', '\014', + '\071', '\344', '\020', '\303', '\214', '\065', '\336', '\130', + '\135', '\021', '\116', '\014', '\361', '\004', '\021', '\045', + '\002', '\220', '\204', '\024', '\126', '\234', '\370', '\004', + '\024', '\131', '\110', '\041', '\035', '\165', '\047', '\276', + '\001', '\107', '\036', '\162', '\244', '\161', '\006', '\032', + '\164', '\200', '\100', '\044', '\016', '\071', '\200', '\040', + '\106', '\036', '\040', '\014', '\361', '\306', '\031', '\156', + '\244', '\101', '\107', '\032', '\157', '\270', '\321', '\046', + '\174', '\160', '\270', '\040', '\334', '\151', '\124', '\000', + '\320', '\202', '\157', '\300', '\265', '\140', '\004', '\163', + '\316', '\375', '\251', '\035', '\167', '\055', '\110', '\321', + '\302', '\173', '\361', '\315', '\327', '\102', '\013', '\070', + '\100', '\012', '\103', '\013', '\067', '\324', '\100', '\251', + '\245', '\103', '\264', '\120', '\303', '\244', '\076', '\002', + '\051', '\044', '\221', '\106', '\266', '\060', '\145', '\225', + '\320', '\155', '\331', '\347', '\153', '\034', '\126', '\170', + '\241', '\023', '\000', '\140', '\361', '\005', '\022', '\321', + '\115', '\327', '\147', '\024', '\125', '\330', '\367', '\005', + '\214', '\353', '\035', '\164', '\120', '\000', '\274', '\362', + '\152', '\220', '\147', '\272', '\352', '\004', '\000', '\112', + '\050', '\171', '\106', '\231', '\101', '\304', '\002', '\140', + '\254', '\116', '\242', '\001', '\260', '\317', '\077', '\006', + '\065', '\224', '\354', '\262', '\302', '\126', '\153', '\355', + '\112', '\000', '\004', '\005', '\110', '\041', '\205', '\034', + '\022', '\310', '\266', '\335', '\176', '\313', '\255', '\267', + '\340', '\222', '\073', '\256', '\270', '\341', '\226', '\213', + '\256', '\271', '\351', '\236', '\253', '\356', '\273', '\356', + '\306', '\333', '\356', '\274', '\354', '\326', '\273', '\356', + '\275', '\360', '\322', '\213', '\257', '\274', '\366', '\346', + '\333', '\057', '\277', '\373', '\352', '\353', '\157', '\300', + '\377', '\012', '\014', '\360', '\300', '\010', '\037', '\254', + '\260', '\301', '\014', '\027', '\354', '\060', '\301', '\020', + '\047', '\334', '\160', '\304', '\013', '\077', '\054', '\261', + '\305', '\025', '\123', '\074', '\361', '\305', '\032', '\143', + '\274', '\161', '\306', '\034', '\207', '\014', '\362', '\310', + '\037', '\227', '\354', '\261', '\275', '\063', '\005', '\065', + '\223', '\133', '\000', '\250', '\144', '\020', '\006', '\127', + '\045', '\204', '\102', '\102', '\060', '\044', '\204', '\103', + '\102', '\071', '\031', '\044', '\243', '\101', '\162', '\031', + '\244', '\241', '\101', '\140', '\044', '\204', '\106', '\102', + '\160', '\044', '\204', '\107', '\102', '\052', '\027', '\225', + '\020', '\044', '\011', '\075', '\144', '\020', '\050', '\011', + '\241', '\222', '\020', '\054', '\011', '\341', '\222', '\020', + '\060', '\011', '\041', '\223', '\020', '\064', '\011', '\141', + '\223', '\020', '\070', '\011', '\045', '\146', '\020', '\074', + '\011', '\341', '\203', '\055', '\002', '\023', '\101', '\060', + '\021', '\006', '\023', '\201', '\060', '\021', '\012', '\023', + '\301', '\060', '\021', '\016', '\023', '\001', '\061', '\021', + '\022', '\023', '\101', '\061', '\021', '\026', '\023', '\201', + '\061', '\021', '\032', '\065', '\115', '\204', '\307', '\104', + '\244', '\261', '\064', '\021', '\044', '\023', '\141', '\062', + '\021', '\050', '\023', '\241', '\062', '\021', '\054', '\023', + '\341', '\062', '\021', '\060', '\023', '\041', '\063', '\021', + '\064', '\023', '\141', '\063', '\021', '\070', '\023', '\241', + '\063', '\021', '\074', '\023', '\341', '\103', '\131', '\104', + '\074', '\245', '\024', '\021', '\006', '\021', '\201', '\020', + '\021', '\012', '\021', '\301', '\020', '\021', '\016', '\021', + '\001', '\321', '\121', '\104', '\120', '\104', '\204', '\105', + '\104', '\140', '\104', '\204', '\106', '\104', '\160', '\104', + '\204', '\107', '\117', '\021', '\265', '\004', '\000', '\044', + '\021', '\141', '\022', '\021', '\050', '\021', '\241', '\022', + '\021', '\054', '\021', '\341', '\022', '\021', '\060', '\021', + '\041', '\023', '\021', '\064', '\021', '\141', '\023', '\021', + '\070', '\021', '\241', '\023', '\021', '\074', '\021', '\341', + '\023', '\021', '\000', '\104', '\041', '\100', '\024', '\004', + '\104', '\141', '\100', '\024', '\010', '\104', '\241', '\100', + '\024', '\014', '\104', '\341', '\100', '\024', '\020', '\104', + '\171', '\304', '\063', '\121', '\130', '\020', '\005', '\006', + '\121', '\150', '\020', '\005', '\007', '\121', '\170', '\020', + '\005', '\010', '\121', '\210', '\040', '\012', '\044', '\210', + '\202', '\011', '\242', '\200', '\202', '\050', '\250', '\040', + '\012', '\054', '\210', '\202', '\013', '\242', '\000', '\203', + '\050', '\310', '\040', '\012', '\064', '\210', '\202', '\015', + '\242', '\200', '\203', '\050', '\350', '\040', '\012', '\074', + '\210', '\202', '\017', '\242', '\000', '\040', '\043', '\040', + '\111', '\210', '\313', '\000', '\200', '\225', '\152', '\021', + '\300', '\001', '\037', '\160', '\000', '\010', '\001', '\100', + '\001', '\005', '\264', '\360', '\205', '\012', '\120', '\200', + '\003', '\142', '\310', '\001', '\004', '\040', '\340', '\000', + '\001', '\030', '\100', '\007', '\012', '\300', '\000', '\002', + '\020', '\300', '\000', '\001', '\050', '\011', '\003', '\050', + '\060', '\304', '\136', '\035', '\200', '\003', '\004', '\350', + '\341', '\007', '\025', '\260', '\102', '\203', '\234', '\060', + '\043', '\067', '\001', '\100', '\002', '\026', '\320', '\200', + '\004', '\370', '\220', '\000', '\034', '\050', '\200', '\026', + '\005', '\120', '\103', '\033', '\136', '\021', '\130', '\042', + '\071', '\300', '\025', '\127', '\210', '\304', '\061', '\372', + '\220', '\003', '\012', '\271', '\342', '\007', '\306', '\010', + '\200', '\017', '\010', '\313', '\215', '\072', '\201', '\343', + '\114', '\344', '\050', '\022', '\070', '\136', '\261', '\214', + '\146', '\024', '\243', '\031', '\011', '\100', '\307', '\204', + '\254', '\161', '\217', '\146', '\334', '\011', '\001', '\004', + '\100', '\000', '\004', '\104', '\221', '\220', '\010', '\030', + '\144', '\024', '\077', '\020', '\303', '\030', '\046', '\004', + '\001', '\153', '\374', '\300', '\367', '\030', '\040', '\201', + '\003', '\010', '\100', '\002', '\015', '\110', '\343', '\265', + '\234', '\170', '\305', '\017', '\032', '\244', '\221', '\012', + '\211', '\041', '\043', '\031', '\151', '\231', '\023', '\026', + '\300', '\001', '\024', '\120', '\141', '\264', '\230', '\250', + '\000', '\267', '\020', '\040', '\206', '\257', '\164', '\241', + '\101', '\172', '\370', '\075', '\220', '\134', '\221', '\145', + '\204', '\364', '\341', '\367', '\044', '\300', '\000', '\017', + '\120', '\062', '\041', '\076', '\374', '\343', '\114', '\150', + '\051', '\022', '\017', '\350', '\344', '\211', '\051', '\201', + '\100', '\042', '\005', '\200', '\221', '\106', '\062', '\321', + '\211', '\006', '\270', '\142', '\024', '\051', '\011', '\001', + '\006', '\010', '\300', '\230', '\000', '\240', '\044', '\002', + '\040', '\300', '\113', '\220', '\060', '\100', '\001', '\036', + '\260', '\241', '\101', '\074', '\040', '\000', '\007', '\160', + '\223', '\001', '\263', '\024', '\200', '\002', '\054', '\320', + '\115', '\000', '\170', '\100', '\231', '\211', '\004', '\041', + '\045', '\051', '\331', '\116', '\112', '\152', '\200', '\002', + '\325', '\234', '\045', '\072', '\031', '\200', '\116', '\175', + '\146', '\163', '\220', '\266', '\144', '\146', '\041', '\023', + '\162', '\223', '\050', '\106', '\253', '\220', '\313', '\164', + '\142', '\053', '\063', '\222', '\021', '\112', '\146', '\240', + '\002', '\025', '\110', '\200', '\000', '\366', '\051', '\001', + '\011', '\170', '\240', '\242', '\006', '\161', '\200', '\004', + '\064', '\272', '\321', '\131', '\112', '\200', '\231', '\355', + '\344', '\150', '\105', '\243', '\110', '\116', '\007', '\060', + '\023', '\233', '\045', '\145', '\146', '\104', '\050', '\051', + '\000', '\015', '\264', '\263', '\242', '\027', '\305', '\050', + '\000', '\124', '\050', '\115', '\203', '\160', '\000', '\002', + '\070', '\175', '\251', '\002', '\014', '\020', '\103', '\251', + '\000', '\100', '\245', '\314', '\214', '\242', '\105', '\143', + '\352', '\123', '\011', '\130', '\300', '\003', '\032', '\160', + '\251', '\107', '\053', '\032', '\322', '\221', '\062', '\163', + '\251', '\026', '\320', '\000', '\003', '\124', '\302', '\121', + '\007', '\050', '\065', '\233', '\022', '\050', '\144', '\073', + '\377', '\330', '\111', '\000', '\060', '\265', '\242', '\375', + '\374', '\052', '\077', '\015', '\302', '\124', '\017', '\134', + '\224', '\254', '\274', '\244', '\247', '\101', '\042', '\020', + '\001', '\046', '\372', '\160', '\234', '\312', '\034', '\044', + '\066', '\115', '\252', '\322', '\103', '\042', '\022', '\247', + '\031', '\265', '\241', '\015', '\243', '\030', '\313', '\153', + '\031', '\323', '\000', '\204', '\324', '\011', '\005', '\222', + '\332', '\224', '\237', '\226', '\163', '\244', '\012', '\261', + '\346', '\104', '\223', '\071', '\330', '\173', '\046', '\226', + '\234', '\375', '\104', '\000', '\005', '\236', '\330', '\104', + '\112', '\336', '\024', '\235', '\101', '\145', '\252', '\023', + '\001', '\020', '\315', '\023', '\206', '\120', '\257', '\317', + '\004', '\051', '\107', '\015', '\322', '\131', '\037', '\032', + '\264', '\062', '\020', '\075', '\012', '\101', '\065', '\233', + '\020', '\172', '\366', '\063', '\243', '\033', '\175', '\252', + '\115', '\045', '\160', '\323', '\021', '\256', '\123', '\266', + '\031', '\065', '\200', '\041', '\071', '\251', '\102', '\012', + '\260', '\314', '\253', '\025', '\105', '\143', '\102', '\032', + '\331', '\304', '\010', '\100', '\364', '\264', '\151', '\365', + '\051', '\132', '\071', '\320', '\116', '\167', '\046', '\322', + '\230', '\030', '\050', '\244', '\156', '\011', '\000', '\263', + '\017', '\006', '\162', '\272', '\321', '\105', '\100', '\111', + '\130', '\150', '\231', '\115', '\002', '\200', '\160', '\331', + '\332', '\026', '\040', '\306', '\313', '\055', '\103', '\374', + '\041', '\020', '\345', '\015', '\004', '\172', '\115', '\246', + '\136', '\102', '\024', '\302', '\020', '\175', '\010', '\204', + '\173', '\315', '\213', '\260', '\101', '\164', '\253', '\017', + '\200', '\260', '\057', '\041', '\002', '\041', '\010', '\156', + '\355', '\267', '\277', '\367', '\315', '\227', '\041', '\366', + '\000', '\256', '\102', '\360', '\001', '\134', '\204', '\300', + '\057', '\267', '\006', '\341', '\007', '\160', '\011', '\342', + '\017', '\000', '\046', '\227', '\175', '\353', '\245', '\340', + '\102', '\374', '\167', '\302', '\355', '\175', '\057', '\040', + '\344', '\253', '\141', '\160', '\321', '\267', '\274', '\177', + '\360', '\060', '\040', '\004', '\241', '\137', '\374', '\212', + '\167', '\304', '\366', '\065', '\304', '\206', '\347', '\133', + '\341', '\103', '\220', '\267', '\133', '\053', '\176', '\357', + '\171', '\307', '\025', '\143', '\370', '\012', '\142', '\276', + '\347', '\115', '\361', '\214', '\145', '\354', '\341', '\363', + '\272', '\167', '\020', '\033', '\136', '\260', '\037', '\070', + '\014', '\344', '\365', '\252', '\230', '\303', '\107', '\236', + '\157', '\220', '\065', '\154', '\344', '\045', '\037', '\271', + '\274', '\116', '\216', '\162', '\223', '\233', '\174', '\143', + '\031', '\043', '\271', '\306', '\061', '\056', '\304', '\220', + '\225', '\174', '\145', '\165', '\115', '\031', '\312', '\137', + '\146', '\062', '\230', '\307', '\054', '\146', '\046', '\163', + '\231', '\314', '\111', '\056', '\363', '\223', '\325', '\054', + '\345', '\364', '\206', '\131', '\305', '\042', '\176', '\163', + '\233', '\073', '\214', '\146', '\054', '\117', '\231', '\313', + '\054', '\136', '\357', '\206', '\003', '\221', '\342', '\370', + '\372', '\127', '\312', '\356', '\045', '\304', '\234', '\005', + '\035', '\346', '\375', '\336', '\331', '\314', '\357', '\125', + '\057', '\230', '\225', '\214', '\340', '\045', '\023', '\372', + '\317', '\353', '\065', '\264', '\177', '\025', '\155', '\341', + '\030', '\077', '\272', '\314', '\204', '\016', '\364', '\213', + '\057', '\315', '\151', '\112', '\137', '\332', '\305', '\044', + '\056', '\263', '\213', '\215', '\174', '\340', '\023', '\013', + '\353', '\017', '\325', '\102', '\110', '\103', '\076', '\222', + '\021', '\224', '\224', '\304', '\063', '\041', '\051', '\210', + '\145', '\140', '\202', '\316', '\114', '\336', '\344', '\047', + '\052', '\071', '\212', '\124', '\250', '\322', '\224', '\247', + '\130', '\000', '\000', '\027', '\000', '\000', '\314', '\062', + '\000', '\000', '\015', '\000', '\300', '\052', '\150', '\354', + '\200', '\073', '\333', '\110', '\102', '\000', '\204', '\000', + '\000', '\042', '\000', '\300', '\010', '\000', '\100', '\002', + '\000', '\224', '\000', '\000', '\046', '\000', '\300', '\011', + '\000', '\060', '\263', '\024', '\000', '\100', '\005', '\000', + '\130', '\001', '\000', '\264', '\322', '\002', '\000', '\350', + '\351', '\005', '\000', '\250', '\331', '\221', '\270', '\062', + '\003', '\000', '\320', '\000', '\000', '\065', '\000', '\200', + '\015', '\000', '\160', '\003', '\000', '\334', '\054', '\007', + '\000', '\320', '\001', '\000', '\166', '\000', '\000', '\036', + '\000', '\240', '\007', '\000', '\360', '\312', '\017', '\000', + '\220', '\223', '\040', '\000', '\100', '\010', '\047', '\002', + '\000', '\021', '\000', '\000', '\026', '\043', '\000', '\300', + '\104', '\062', '\112', '\002', '\000', '\224', '\000', '\000', + '\261', '\060', '\241', '\067', '\000', '\140', '\325', '\023', + '\000', '\004', '\200', '\050', '\214', '\307', '\073', '\000', + '\350', '\123', '\025', '\000', '\100', '\252', '\126', '\001', + '\300', '\066', '\132', '\000', '\200', '\131', '\270', '\000', + '\200', '\056', '\000', '\300', '\013', '\000', '\370', '\002', + '\000', '\202', '\026', '\006', '\000', '\240', '\045', '\070', + '\025', '\051', '\003', '\000', '\314', '\000', '\000', '\315', + '\014', '\055', '\015', '\000', '\120', '\003', '\000', '\326', + '\000', '\000', '\372', '\164', '\307', '\015', '\000', '\170', + '\003', '\000', '\212', '\246', '\026', '\266', '\314', '\001', + '\000', '\164', '\000', '\100', '\035', '\000', '\140', '\007', + '\000', '\334', '\001', '\000', '\107', '\313', '\003', '\000', + '\364', '\000', '\200', '\075', '\000', '\200', '\017', '\000', + '\200', '\213', '\037', '\000', '\200', '\352', '\224', '\045', + '\345', '\273', '\147', '\247', '\214', '\332', '\323', '\316', + '\366', '\140', '\241', '\335', '\355', '\153', '\207', '\173', + '\333', '\337', '\116', '\367', '\270', '\327', '\175', '\356', + '\166', '\317', '\073', '\336', '\367', '\056', '\367', '\276', + '\337', '\335', '\357', '\172', '\007', '\074', '\337', '\377', + '\116', '\370', '\300', '\027', '\176', '\360', '\206', '\117', + '\074', '\342', '\027', '\057', '\370', '\306', '\037', '\336', + '\361', '\212', '\207', '\074', '\343', '\037', '\117', '\371', + '\310', '\127', '\176', '\362', '\206', '\127', '\110', '\322', + '\024', '\322', '\254', '\356', '\002', '\340', '\047', '\006', + '\051', '\054', '\000', '\210', '\075', '\316', '\204', '\114', + '\333', '\040', '\063', '\063', '\110', '\271', '\015', '\022', + '\030', '\172', '\047', '\304', '\337', '\006', '\061', '\370', + '\155', '\022', '\142', '\027', '\216', '\033', '\144', '\344', + '\006', '\111', '\271', '\101', '\144', '\156', '\220', '\212', + '\030', '\004', '\350', '\006', '\101', '\272', '\101', '\236', + '\156', '\220', '\243', '\275', '\045', '\041', '\202', '\110', + '\310', '\041', '\022', '\302', '\210', '\204', '\104', '\042', + '\041', '\226', '\110', '\310', '\046', '\022', '\002', '\065', + '\203', '\224', '\042', '\041', '\247', '\110', '\110', '\052', + '\022', '\262', '\212', '\204', '\264', '\042', '\041', '\257', + '\110', '\110', '\054', '\022', '\062', '\213', '\204', '\324', + '\042', '\041', '\267', '\110', '\110', '\056', '\022', '\262', + '\213', '\204', '\364', '\042', '\041', '\277', '\110', '\110', + '\060', '\022', '\062', '\214', '\204', '\024', '\043', '\041', + '\307', '\110', '\110', '\062', '\022', '\122', '\030', '\203', + '\064', '\043', '\041', '\317', '\220', '\020', '\321', '\220', + '\020', '\323', '\220', '\020', '\325', '\140', '\030', '\011', + '\221', '\015', '\011', '\261', '\015', '\011', '\321', '\015', + '\011', '\361', '\015', '\011', '\021', '\016', '\011', '\061', + '\016', '\011', '\121', '\016', '\011', '\161', '\016', '\011', + '\221', '\016', '\011', '\261', '\016', '\011', '\321', '\016', + '\011', '\361', '\016', '\011', '\021', '\017', '\011', '\061', + '\017', '\011', '\121', '\017', '\011', '\161', '\017', '\011', + '\221', '\017', '\011', '\261', '\017', '\011', '\321', '\017', + '\011', '\001', '\055', '\273', '\142', '\020', '\003', '\060', + '\021', '\005', '\060', '\021', '\070', '\144', '\020', '\011', + '\060', '\021', '\013', '\060', '\021', '\015', '\060', '\021', + '\017', '\060', '\021', '\021', '\060', '\021', '\023', '\060', + '\021', '\025', '\060', '\021', '\027', '\060', '\021', '\031', + '\060', '\021', '\033', '\060', '\021', '\221', '\141', '\020', + '\037', '\060', '\021', '\041', '\060', '\021', '\043', '\060', + '\021', '\045', '\060', '\021', '\047', '\060', '\021', '\051', + '\060', '\021', '\053', '\060', '\021', '\055', '\060', '\021', + '\057', '\060', '\021', '\061', '\060', '\021', '\063', '\060', + '\021', '\065', '\060', '\021', '\067', '\060', '\021', '\071', + '\060', '\021', '\073', '\060', '\021', '\075', '\060', '\021', + '\077', '\060', '\021', '\101', '\060', '\021', '\103', '\060', + '\021', '\105', '\060', '\021', '\107', '\060', '\021', '\111', + '\060', '\021', '\113', '\060', '\021', '\115', '\060', '\021', + '\117', '\060', '\021', '\121', '\060', '\021', '\123', '\060', + '\021', '\125', '\060', '\021', '\127', '\060', '\021', '\131', + '\060', '\021', '\133', '\060', '\021', '\135', '\060', '\021', + '\137', '\060', '\021', '\230', '\141', '\020', '\146', '\040', + '\207', '\060', '\120', '\211', '\047', '\122', '\211', '\107', + '\062', '\004', '\225', '\310', '\025', '\232', '\010', '\003', + '\355', '\326', '\211', '\357', '\326', '\211', '\361', '\326', + '\211', '\363', '\326', '\211', '\365', '\246', '\211', '\061', + '\120', '\063', '\250', '\230', '\211', '\060', '\020', '\003', + '\234', '\330', '\212', '\237', '\330', '\212', '\241', '\330', + '\212', '\243', '\330', '\212', '\245', '\330', '\212', '\247', + '\010', '\003', '\062', '\240', '\212', '\272', '\310', '\212', + '\062', '\360', '\212', '\062', '\020', '\213', '\062', '\060', + '\213', '\062', '\120', '\213', '\062', '\160', '\213', '\062', + '\220', '\213', '\063', '\300', '\213', '\063', '\300', '\212', + '\063', '\360', '\212', '\063', '\020', '\213', '\063', '\060', + '\213', '\063', '\120', '\213', '\063', '\160', '\213', '\063', + '\220', '\213', '\064', '\120', '\063', '\317', '\026', '\155', + '\323', '\126', '\155', '\327', '\226', '\155', '\333', '\326', + '\155', '\337', '\026', '\156', '\343', '\346', '\047', '\346', + '\006', '\000', '\350', '\246', '\156', '\000', '\300', '\156', + '\356', '\006', '\157', '\362', '\346', '\172', '\367', '\226', + '\157', '\373', '\326', '\157', '\377', '\026', '\160', '\000', + '\060', '\160', '\005', '\167', '\160', '\011', '\267', '\160', + '\015', '\367', '\160', '\000', '\020', '\161', '\023', '\127', + '\161', '\000', '\160', '\161', '\144', '\241', '\161', '\034', + '\347', '\161', '\344', '\061', '\005', '\041', '\007', '\000', + '\043', '\127', '\162', '\032', '\202', '\162', '\052', '\007', + '\000', '\054', '\347', '\162', '\060', '\047', '\163', '\064', + '\147', '\163', '\000', '\200', '\163', '\000', '\240', '\163', + '\074', '\347', '\163', '\000', '\000', '\164', '\102', '\107', + '\164', '\106', '\007', '\000', '\110', '\247', '\164', '\114', + '\007', '\000', '\116', '\007', '\165', '\122', '\107', '\165', + '\126', '\207', '\165', '\000', '\240', '\165', '\134', '\347', + '\165', '\140', '\047', '\166', '\047', '\022', '\003', '\067', + '\120', '\157', '\111', '\321', '\053', '\275', '\362', '\053', + '\147', '\067', '\023', '\323', '\102', '\167', '\310', '\062', + '\054', '\312', '\042', '\224', '\011', '\321', '\054', '\317', + '\022', '\055', '\104', '\131', '\054', '\164', '\007', + +}; + +static char name_6x13[] = "-misc-fixed-medium-r-semicondensed--13-120-75-75-c-60-iso8859-1"; +static char name_cursor[] = "cursor"; +static char name_5x7[] = "-misc-fixed-medium-r-normal--7-70-75-75-c-50-iso8859-1"; +static char name_5x8[] = "-misc-fixed-medium-r-normal--8-80-75-75-c-50-iso646.1991-irv"; + +const BuiltinFileRec builtin_files[] = { +"6x13.builtin", sizeof file_6x13, file_6x13, +"cursor.builtin", sizeof file_cursor, file_cursor, +"5x7.builtin", sizeof file_5x7, file_5x7, +"5x8.builtin", sizeof file_5x8, file_5x8, +}; + +const int builtin_files_count = sizeof (builtin_files) / sizeof (builtin_files[0]); + +const BuiltinDirRec builtin_dir[] = { +"6x13.builtin", name_6x13, +"cursor.builtin", name_cursor, +"5x7.builtin", name_5x7, +"5x8.builtin", name_5x8, +}; + +const int builtin_dir_count = sizeof (builtin_dir) / sizeof (builtin_dir[0]); + +static char alias_fixed[] = "fixed"; +static char alias_6x13[] = "6x13"; +static char alias_6x13_100[] = "-misc-fixed-medium-r-semicondensed--13-100-100-100-c-60-iso8859-1"; +static char alias_5x7[] = "5x7"; +static char alias_5x7_100[] = "-misc-fixed-medium-r-normal--7-50-100-100-c-50-iso8859-1"; +static char alias_5x8[] = "5x8"; +static char alias_5x8_75[] = "-misc-fixed-medium-r-normal--8-80-75-75-c-50-iso8859-1"; +static char alias_5x8_100[] = "-misc-fixed-medium-r-normal--8-60-100-100-c-50-iso8859-1"; + +const BuiltinAliasRec builtin_alias[] = { +alias_fixed, name_6x13, +alias_6x13, name_6x13, +alias_6x13_100, name_6x13, +alias_5x7, name_5x7, +alias_5x7_100, name_5x7, +alias_5x8, name_5x8, +alias_5x8_75, name_5x8, +alias_5x8_100, name_5x8, +}; + +const int builtin_alias_count = sizeof (builtin_alias) / sizeof (builtin_alias[0]); diff --git a/nx-X11/lib/font/builtins/fpe.c b/nx-X11/lib/font/builtins/fpe.c new file mode 100644 index 000000000..7f78fabbd --- /dev/null +++ b/nx-X11/lib/font/builtins/fpe.c @@ -0,0 +1,98 @@ +/* $XdotOrg: xc/lib/font/builtins/fpe.c,v 1.5 2005/07/30 18:56:32 alanc Exp $ */ +/* + * Id: fpe.c,v 1.2 1999/11/02 06:16:48 keithp Exp $ + * + * Copyright 1999 SuSE, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of SuSE not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. SuSE makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE + * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Keith Packard, SuSE, Inc. + */ +/* $XFree86: xc/lib/font/builtins/fpe.c,v 1.3 1999/12/30 02:29:51 robin Exp $ */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <X11/fonts/fntfilst.h> + +static int font_file_type; + +const char builtin_fonts[] = "built-ins"; + +int +BuiltinNameCheck (name) + char *name; +{ + return (strcmp (name, builtin_fonts) == 0); +} + +int +BuiltinInitFPE (fpe) + FontPathElementPtr fpe; +{ + int status; + FontDirectoryPtr dir; + + status = BuiltinReadDirectory (fpe->name, &dir); + + if (status == Successful) + fpe->private = (pointer) dir; + return status; +} + +/* ARGSUSED */ +int +BuiltinResetFPE (fpe) + FontPathElementPtr fpe; +{ + FontDirectoryPtr dir; + + dir = (FontDirectoryPtr) fpe->private; + /* builtins can't change! */ + return Successful; +} + +int +BuiltinFreeFPE (fpe) + FontPathElementPtr fpe; +{ + FontFileFreeDir ((FontDirectoryPtr) fpe->private); + return Successful; +} + +void +BuiltinRegisterFpeFunctions(void) +{ + BuiltinRegisterFontFileFunctions (); + + font_file_type = RegisterFPEFunctions(BuiltinNameCheck, + BuiltinInitFPE, + BuiltinFreeFPE, + BuiltinResetFPE, + FontFileOpenFont, + FontFileCloseFont, + FontFileListFonts, + FontFileStartListFontsWithInfo, + FontFileListNextFontWithInfo, + (WakeupFpeFunc) 0, + (ClientDiedFunc) 0, + (LoadGlyphsFunc) 0, + (StartLaFunc) 0, + (NextLaFunc) 0, + (SetPathFunc) 0); +} diff --git a/nx-X11/lib/font/builtins/render.c b/nx-X11/lib/font/builtins/render.c new file mode 100644 index 000000000..520d873f4 --- /dev/null +++ b/nx-X11/lib/font/builtins/render.c @@ -0,0 +1,114 @@ +/* $XdotOrg: xc/lib/font/builtins/render.c,v 1.5 2005/07/30 18:56:32 alanc Exp $ */ +/* + * Id: render.c,v 1.2 1999/11/02 06:16:48 keithp Exp $ + * + * Copyright 1999 SuSE, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of SuSE not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. SuSE makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE + * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Keith Packard, SuSE, Inc. + */ +/* $XFree86: xc/lib/font/builtins/render.c,v 1.3 1999/12/30 02:29:51 robin Exp $ */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <X11/fonts/fntfilst.h> +#include "builtin.h" + +BuiltinOpenBitmap (fpe, ppFont, flags, entry, fileName, format, fmask) + FontPathElementPtr fpe; + FontPtr *ppFont; + int flags; + FontEntryPtr entry; + char *fileName; + fsBitmapFormat format; + fsBitmapFormatMask fmask; +{ + FontFilePtr file; + FontPtr pFont; + int i; + int ret; + int bit, + byte, + glyph, + scan, + image; + + file = BuiltinFileOpen (fileName); + if (!file) + return BadFontName; + pFont = (FontPtr) xalloc(sizeof(FontRec)); + if (!pFont) { + BuiltinFileClose (file); + return AllocError; + } + /* set up default values */ + FontDefaultFormat(&bit, &byte, &glyph, &scan); + /* get any changes made from above */ + ret = CheckFSFormat(format, fmask, &bit, &byte, &scan, &glyph, &image); + + /* Fill in font record. Data format filled in by reader. */ + pFont->refcnt = 0; + pFont->maxPrivate = -1; + pFont->devPrivates = (pointer *) 0; + + ret = pcfReadFont (pFont, file, bit, byte, glyph, scan); + + BuiltinFileClose (file); + if (ret != Successful) + xfree(pFont); + else + *ppFont = pFont; + return ret; +} + +BuiltinGetInfoBitmap (fpe, pFontInfo, entry, fileName) + FontPathElementPtr fpe; + FontInfoPtr pFontInfo; + FontEntryPtr entry; + char *fileName; +{ + FontFilePtr file; + int i; + int ret; + FontRendererPtr renderer; + + file = BuiltinFileOpen (fileName); + if (!file) + return BadFontName; + ret = pcfReadFontInfo (pFontInfo, file); + BuiltinFileClose (file); + return ret; +} + +static FontRendererRec renderers[] = { + ".builtin", 8, + BuiltinOpenBitmap, 0, BuiltinGetInfoBitmap, 0, 0 +}; + +#define numRenderers (sizeof renderers / sizeof renderers[0]) + +void +BuiltinRegisterFontFileFunctions(void) +{ + int i; + for (i = 0; i < numRenderers; i++) + FontFileRegisterRenderer ((FontRendererRec *) &renderers[i]); +} + diff --git a/nx-X11/lib/font/fc/Imakefile b/nx-X11/lib/font/fc/Imakefile new file mode 100644 index 000000000..d51151348 --- /dev/null +++ b/nx-X11/lib/font/fc/Imakefile @@ -0,0 +1,31 @@ +XCOMM $Xorg: Imakefile,v 1.3 2000/08/17 19:46:36 cpqbld Exp $ +XCOMM +XCOMM Make file for font handling routines +XCOMM +XCOMM $XFree86: xc/lib/font/fc/Imakefile,v 1.4 1999/12/13 02:52:50 robin Exp $ +#include <Server.tmpl> + + INCLUDES = -I$(FONTINCSRC) -I../include $(TRANS_INCLUDES) + HEADERS = + SRCS = fsconvert.c fserve.c fsio.c transport.c + OBJS = fsconvert.o fserve.o fsio.o transport.o + CONN_DEFINES = $(CONNECTION_FLAGS) -DFONT_t -DTRANS_CLIENT -DTRANS_SERVER -DTRANS_REOPEN +#if HasBSD44Sockets + SOCK_DEFINES = -DBSD44SOCKETS +#endif + DEFINES = $(SIGNAL_DEFINES) $(CONN_DEFINES) $(SOCK_DEFINES) + + +#define DoNormalLib NormalLibFont +#define DoSharedLib SharedLibFont +#define DoDebugLib DebugLibFont +#define DoProfileLib ProfileLibFont +#include <Library.tmpl> +LibraryObjectRule() + +SubdirLibraryRule($(OBJS)) +LinkSourceFile(transport.c,$(TRANSCOMMSRC)) + +NormalLintTarget($(SRCS)) + +DependTarget() diff --git a/nx-X11/lib/font/fc/fsconvert.c b/nx-X11/lib/font/fc/fsconvert.c new file mode 100644 index 000000000..9ff54f58f --- /dev/null +++ b/nx-X11/lib/font/fc/fsconvert.c @@ -0,0 +1,760 @@ +/* $Xorg: fsconvert.c,v 1.3 2000/08/17 19:46:36 cpqbld Exp $ */ +/* + * Copyright 1990 Network Computing Devices + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Network Computing Devices not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. Network Computing Devices + * makes no representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * NETWORK COMPUTING DEVICES DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, + * IN NO EVENT SHALL NETWORK COMPUTING DEVICES BE LIABLE FOR ANY SPECIAL, + * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE + * OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Dave Lemke, Network Computing Devices, Inc + */ +/* $XFree86: xc/lib/font/fc/fsconvert.c,v 1.14 2003/08/30 18:06:29 dawes Exp $ */ +/* + * FS data conversion + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <X11/X.h> +#include <X11/Xtrans/Xtrans.h> +#include <X11/Xpoll.h> +#include <X11/fonts/FS.h> +#include <X11/fonts/FSproto.h> +#include <X11/fonts/fontmisc.h> +#include <X11/fonts/fontstruct.h> +#include "fservestr.h" +#include <X11/fonts/fontutil.h> +#include "fslibos.h" + +extern char _fs_glyph_undefined; +extern char _fs_glyph_requested; +extern char _fs_glyph_zero_length; + + +/* + * converts data from font server form to X server form + */ + +void +_fs_convert_char_info(fsXCharInfo *src, xCharInfo *dst) +{ + dst->ascent = src->ascent; + dst->descent = src->descent; + dst->leftSideBearing = src->left; + dst->rightSideBearing = src->right; + dst->characterWidth = src->width; + dst->attributes = src->attributes; +} + +void +_fs_init_fontinfo(FSFpePtr conn, FontInfoPtr pfi) +{ + if (conn->fsMajorVersion == 1) { + unsigned short n; + n = pfi->firstCol; + pfi->firstCol = pfi->firstRow; + pfi->firstRow = n; + n = pfi->lastCol; + pfi->lastCol = pfi->lastRow; + pfi->lastRow = n; + pfi->defaultCh = ((pfi->defaultCh >> 8) & 0xff) + + ((pfi->defaultCh & 0xff) << 8); + } + + if (FontCouldBeTerminal (pfi)) + { + pfi->terminalFont = TRUE; + pfi->minbounds.ascent = pfi->fontAscent; + pfi->minbounds.descent = pfi->fontDescent; + pfi->minbounds.leftSideBearing = 0; + pfi->minbounds.rightSideBearing = pfi->minbounds.characterWidth; + pfi->maxbounds = pfi->minbounds; + } + + FontComputeInfoAccelerators (pfi); +} + +int +_fs_convert_props(fsPropInfo *pi, fsPropOffset *po, pointer pd, + FontInfoPtr pfi) +{ + FontPropPtr dprop; + int i, + nprops; + char *is_str; + fsPropOffset local_off; + char *off_adr; + char *pdc = pd; + +/* stolen from server/include/resource.h */ +#define BAD_RESOURCE 0xe0000000 + + nprops = pfi->nprops = pi->num_offsets; + + if (nprops < 0 + || nprops > SIZE_MAX/(sizeof(FontPropRec) + sizeof(char))) + return -1; + + dprop = (FontPropPtr) xalloc(sizeof(FontPropRec) * nprops + + sizeof (char) * nprops); + if (!dprop) + return -1; + + is_str = (char *) (dprop + nprops); + pfi->props = dprop; + pfi->isStringProp = is_str; + + off_adr = (char *)po; + for (i = 0; i < nprops; i++, dprop++, is_str++) + { + memcpy(&local_off, off_adr, SIZEOF(fsPropOffset)); + dprop->name = MakeAtom(&pdc[local_off.name.position], + local_off.name.length, 1); + if (local_off.type != PropTypeString) { + *is_str = FALSE; + dprop->value = local_off.value.position; + } else { + *is_str = TRUE; + dprop->value = (INT32) MakeAtom(&pdc[local_off.value.position], + local_off.value.length, 1); + if (dprop->value == BAD_RESOURCE) + { + xfree (pfi->props); + pfi->nprops = 0; + pfi->props = 0; + pfi->isStringProp = 0; + return -1; + } + } + off_adr += SIZEOF(fsPropOffset); + } + + return nprops; +} + +void +_fs_free_props (FontInfoPtr pfi) +{ + if (pfi->props) + { + xfree (pfi->props); + pfi->nprops = 0; + pfi->props = 0; + } +} + +int +_fs_convert_lfwi_reply(FSFpePtr conn, FontInfoPtr pfi, + fsListFontsWithXInfoReply *fsrep, + fsPropInfo *pi, fsPropOffset *po, pointer pd) +{ + fsUnpack_XFontInfoHeader(fsrep, pfi); + _fs_init_fontinfo(conn, pfi); + + if (_fs_convert_props(pi, po, pd, pfi) == -1) + return AllocError; + + return Successful; +} + + +#define ENCODING_UNDEFINED(enc) \ + ((enc)->bits == &_fs_glyph_undefined ? \ + TRUE : \ + (access_done = access_done && (enc)->bits != &_fs_glyph_requested, \ + FALSE)) + +#define GLYPH_UNDEFINED(loc) ENCODING_UNDEFINED(encoding + (loc)) + +/* + * figures out what glyphs to request + * + * Includes logic to attempt to reduce number of round trips to the font + * server: when a glyph is requested, fs_build_range() requests a + * 16-glyph range of glyphs that contains the requested glyph. This is + * predicated on the belief that using a glyph increases the chances + * that nearby glyphs will be used: a good assumption for phonetic + * alphabets, but a questionable one for ideographic/pictographic ones. + */ +/* ARGSUSED */ +int +fs_build_range(FontPtr pfont, Bool range_flag, unsigned int count, + int item_size, unsigned char *data, int *nranges, + fsRange **ranges) +{ + FSFontDataPtr fsd = (FSFontDataPtr) (pfont->fpePrivate); + FSFontPtr fsfont = (FSFontPtr) (pfont->fontPrivate); + register CharInfoPtr encoding = fsfont->encoding; + FontInfoPtr pfi = &(pfont->info); + fsRange range; + int access_done = TRUE; + int err; + register unsigned long firstrow, lastrow, firstcol, lastcol; + register unsigned long row; + register unsigned long col; + register unsigned long loc; + + if (!fsd->glyphs_to_get) + return AccessDone; + + firstrow = pfi->firstRow; + lastrow = pfi->lastRow; + firstcol = pfi->firstCol; + lastcol = pfi->lastCol; + + /* Make sure we have default char */ + if (fsfont->pDefault && ENCODING_UNDEFINED(fsfont->pDefault)) + { + loc = fsfont->pDefault - encoding; + row = loc / (lastcol - firstcol + 1) + firstrow; + col = loc % (lastcol - firstcol + 1) + firstcol; + + range.min_char_low = range.max_char_low = col; + range.min_char_high = range.max_char_high = row; + + if ((err = add_range(&range, nranges, ranges, FALSE)) != + Successful) return err; + encoding[loc].bits = &_fs_glyph_requested; + access_done = FALSE; + } + + if (!range_flag && item_size == 1) + { + if (firstrow != 0) return AccessDone; + while (count--) + { + col = *data++; + if (col >= firstcol && col <= lastcol && + GLYPH_UNDEFINED(col - firstcol)) + { + int col1, col2; + col1 = col & 0xf0; + col2 = col1 + 15; + if (col1 < firstcol) col1 = firstcol; + if (col2 > lastcol) col2 = lastcol; + /* Collect a 16-glyph neighborhood containing the requested + glyph... should in most cases reduce the number of round + trips to the font server. */ + for (col = col1; col <= col2; col++) + { + if (!GLYPH_UNDEFINED(col - firstcol)) continue; + range.min_char_low = range.max_char_low = col; + range.min_char_high = range.max_char_high = 0; + if ((err = add_range(&range, nranges, ranges, FALSE)) != + Successful) return err; + encoding[col - firstcol].bits = &_fs_glyph_requested; + access_done = FALSE; + } + } + } + } + else + { + fsRange fullrange[1]; + + if (range_flag && count == 0) + { + count = 2; + data = (unsigned char *)fullrange; + fullrange[0].min_char_high = firstrow; + fullrange[0].min_char_low = firstcol; + fullrange[0].max_char_high = lastrow; + fullrange[0].max_char_low = lastcol; + } + + while (count--) + { + int row1, col1, row2, col2; + row1 = row2 = *data++; + col1 = col2 = *data++; + if (range_flag) + { + if (count) + { + row2 = *data++; + col2 = *data++; + count--; + } + else + { + row2 = lastrow; + col2 = lastcol; + } + if (row1 < firstrow) row1 = firstrow; + if (row2 > lastrow) row2 = lastrow; + if (col1 < firstcol) col1 = firstcol; + if (col2 > lastcol) col2 = lastcol; + } + else + { + if (row1 < firstrow || row1 > lastrow || + col1 < firstcol || col1 > lastcol) + continue; + } + for (row = row1; row <= row2; row++) + { + expand_glyph_range: ; + loc = (row - firstrow) * (lastcol + 1 - firstcol) + + (col1 - firstcol); + for (col = col1; col <= col2; col++, loc++) + { + if (GLYPH_UNDEFINED(loc)) + { + if (row1 == row2 && + (((col1 & 0xf) && col1 > firstcol) || + (col2 & 0xf) != 0xf) && (col2 < lastcol)) + { + /* If we're loading from a single row, expand + range of glyphs loaded to a multiple of + a 16-glyph range -- attempt to reduce number + of round trips to the font server. */ + col1 &= 0xf0; + col2 = (col2 & 0xf0) + 15; + if (col1 < firstcol) col1 = firstcol; + if (col2 > lastcol) col2 = lastcol; + goto expand_glyph_range; + } + range.min_char_low = range.max_char_low = col; + range.min_char_high = range.max_char_high = row; + if ((err = add_range(&range, nranges, ranges, FALSE)) != + Successful) return err; + encoding[loc].bits = &_fs_glyph_requested; + access_done = FALSE; + } + } + } + } + } + + return access_done ? + AccessDone : + Successful; +} + +#undef GLYPH_UNDEFINED +#undef ENCODING_UNDEFINED + + +/* _fs_clean_aborted_loadglyphs(): Undoes the changes to the encoding array + performed by fs_build_range(); for use if the associated LoadGlyphs + requests needs to be cancelled. */ + +void +_fs_clean_aborted_loadglyphs(FontPtr pfont, int num_expected_ranges, + fsRange *expected_ranges) +{ + register FSFontPtr fsfont; + register int i; + + fsfont = (FSFontPtr) pfont->fontPrivate; + if (fsfont->encoding) + { + fsRange full_range[1]; + if (!num_expected_ranges) + { + full_range[0].min_char_low = pfont->info.firstCol; + full_range[0].min_char_high = pfont->info.firstRow; + full_range[0].max_char_low = pfont->info.lastCol; + full_range[0].max_char_high = pfont->info.lastRow; + num_expected_ranges = 1; + expected_ranges = full_range; + } + + for (i = 0; i < num_expected_ranges; i++) + { + int row, col; + for (row = expected_ranges[i].min_char_high; + row <= expected_ranges[i].max_char_high; + row++) + { + register CharInfoPtr encoding = fsfont->encoding + + ((row - pfont->info.firstRow) * + (pfont->info.lastCol - + pfont->info.firstCol + 1) + + expected_ranges[i].min_char_low - + pfont->info.firstCol); + for (col = expected_ranges[i].min_char_low; + col <= expected_ranges[i].max_char_low; + encoding++, col++) + { + if (encoding->bits == &_fs_glyph_requested) + encoding->bits = &_fs_glyph_undefined; + } + } + } + } +} + + +/* + * figures out what extents to request + * this is where lots of extra + * smarts wants to live + */ +/* ARGSUSED */ +int +_fs_check_extents(FontPtr pfont, Mask flags, int nranges, fsRange *range, + FSBlockDataPtr blockrec) +{ +/* XXX -- either fill in the requested info if we have it somewhere + * and return AccessDone, or else return Successful + */ + return Successful; +} + +/* + * figures out what glyphs to request + * this is where lots of extra + * smarts wants to live + */ +/* ARGSUSED */ +int +_fs_check_bitmaps(FontPtr pfont, fsBitmapFormat format, + Mask flags, int nranges, fsRange *range, + FSBlockDataPtr blockrec) +{ +/* XXX -- either fill in the requested info if we have it somewhere + * and return AccessDone, or else return Successful + */ + return Successful; +} + +int +_fs_get_glyphs(FontPtr pFont, unsigned long count, unsigned char *chars, + FontEncoding charEncoding, + unsigned long *glyphCount, /* RETURN */ + CharInfoPtr *glyphs) /* RETURN */ +{ + FSFontPtr fsdata; + unsigned int firstCol; + register unsigned int numCols; + unsigned int firstRow; + unsigned int numRows; + CharInfoPtr *glyphsBase; + register unsigned int c; + register CharInfoPtr pci; + unsigned int r; + CharInfoPtr encoding; + CharInfoPtr pDefault; + FSFontDataPtr fsd = (FSFontDataPtr) pFont->fpePrivate; + int err = Successful; + + fsdata = (FSFontPtr) pFont->fontPrivate; + encoding = fsdata->encoding; + pDefault = fsdata->pDefault; + firstCol = pFont->info.firstCol; + numCols = pFont->info.lastCol - firstCol + 1; + glyphsBase = glyphs; + + /* In this age of glyph caching, any glyphs gotten through this + procedure should already be loaded. If they are not, we are + dealing with someone (perhaps a ddx driver optimizing a font) + that doesn't understand the finer points of glyph caching. The + CHECK_ENCODING macro checks for this condition... if found, it + calls fs_load_all_glyphs(), which corrects it. Since the caller + of this code will not know how to handle a return value of + Suspended, the fs_load_all_glyphs() procedure will block and + freeze the server until the load operation is done. Moral: the + glyphCachingMode flag really must indicate the capabilities of + the ddx drivers. */ + +#define CHECK_ENCODING(cnum) \ + ( pci = encoding + (cnum), \ + fsd->glyphs_to_get ? \ + ( pci->bits == &_fs_glyph_undefined || pci->bits == &_fs_glyph_requested ? \ + ((err = fs_load_all_glyphs(pFont)), pci) : \ + pci ) : \ + pci ) + + switch (charEncoding) { + + case Linear8Bit: + case TwoD8Bit: + if (pFont->info.firstRow > 0) + break; + if (pFont->info.allExist && pDefault) { + while (err == Successful && count--) { + c = (*chars++) - firstCol; + if (c < numCols) + *glyphs++ = CHECK_ENCODING(c); + else + *glyphs++ = pDefault; + } + } else { + while (err == Successful && count--) { + c = (*chars++) - firstCol; + if (c < numCols && CHECK_ENCODING(c)->bits) + *glyphs++ = pci; + else if (pDefault) + *glyphs++ = pDefault; + } + } + break; + case Linear16Bit: + if (pFont->info.allExist && pDefault) { + while (err == Successful && count--) { + c = *chars++ << 8; + c = (c | *chars++) - firstCol; + if (c < numCols) + *glyphs++ = CHECK_ENCODING(c); + else + *glyphs++ = pDefault; + } + } else { + while (err == Successful && count--) { + c = *chars++ << 8; + c = (c | *chars++) - firstCol; + if (c < numCols && CHECK_ENCODING(c)->bits) + *glyphs++ = pci; + else if (pDefault) + *glyphs++ = pDefault; + } + } + break; + + case TwoD16Bit: + firstRow = pFont->info.firstRow; + numRows = pFont->info.lastRow - firstRow + 1; + while (err == Successful && count--) { + r = (*chars++) - firstRow; + c = (*chars++) - firstCol; + if (r < numRows && c < numCols && + CHECK_ENCODING(r * numCols + c)->bits) + *glyphs++ = pci; + else if (pDefault) + *glyphs++ = pDefault; + } + break; + } + *glyphCount = glyphs - glyphsBase; + return err; +} + + +static int +_fs_get_metrics(FontPtr pFont, unsigned long count, unsigned char *chars, + FontEncoding charEncoding, + unsigned long *glyphCount, /* RETURN */ + xCharInfo **glyphs) /* RETURN */ +{ + FSFontPtr fsdata; + unsigned int firstCol; + register unsigned int numCols; + unsigned int firstRow; + unsigned int numRows; + xCharInfo **glyphsBase; + register unsigned int c; + unsigned int r; + CharInfoPtr encoding; + CharInfoPtr pDefault; + + fsdata = (FSFontPtr) pFont->fontPrivate; + encoding = fsdata->inkMetrics; + pDefault = fsdata->pDefault; + /* convert default bitmap metric to default ink metric */ + if (pDefault) + pDefault = encoding + (pDefault - fsdata->encoding); + firstCol = pFont->info.firstCol; + numCols = pFont->info.lastCol - firstCol + 1; + glyphsBase = glyphs; + + + /* XXX - this should be much smarter */ + /* make sure the glyphs are there */ + switch (charEncoding) { + + case Linear8Bit: + case TwoD8Bit: + if (pFont->info.firstRow > 0) + break; + if (pFont->info.allExist && pDefault) { + while (count--) { + c = (*chars++) - firstCol; + if (c < numCols) + *glyphs++ = (xCharInfo *)&encoding[c]; + else + *glyphs++ = (xCharInfo *)pDefault; + } + } else { + while (count--) { + c = (*chars++) - firstCol; + if (c < numCols) + *glyphs++ = (xCharInfo *)(encoding + c); + else if (pDefault) + *glyphs++ = (xCharInfo *)pDefault; + } + } + break; + case Linear16Bit: + if (pFont->info.allExist && pDefault) { + while (count--) { + c = *chars++ << 8; + c = (c | *chars++) - firstCol; + if (c < numCols) + *glyphs++ = (xCharInfo *)(encoding + c); + else + *glyphs++ = (xCharInfo *)pDefault; + } + } else { + while (count--) { + c = *chars++ << 8; + c = (c | *chars++) - firstCol; + if (c < numCols) + *glyphs++ = (xCharInfo *)(encoding + c); + else if (pDefault) + *glyphs++ = (xCharInfo *)pDefault; + } + } + break; + + case TwoD16Bit: + firstRow = pFont->info.firstRow; + numRows = pFont->info.lastRow - firstRow + 1; + while (count--) { + r = (*chars++) - firstRow; + c = (*chars++) - firstCol; + if (r < numRows && c < numCols) + *glyphs++ = (xCharInfo *)(encoding + (r * numCols + c)); + else if (pDefault) + *glyphs++ = (xCharInfo *)pDefault; + } + break; + } + *glyphCount = glyphs - glyphsBase; + return Successful; +} + + +void +_fs_unload_font(FontPtr pfont) +{ + FSFontPtr fsdata = (FSFontPtr) pfont->fontPrivate; + FSFontDataPtr fsd = (FSFontDataPtr) pfont->fpePrivate; + CharInfoPtr encoding = fsdata->encoding; + FSGlyphPtr glyphs; + + /* + * fsdata points at FSFontRec, FSFontDataRec and name + */ + if (encoding) + xfree(encoding); + + while ((glyphs = fsdata->glyphs)) + { + fsdata->glyphs = glyphs->next; + xfree (glyphs); + } + + /* XXX we may get called after the resource DB has been cleaned out */ + if (find_old_font(fsd->fontid)) + DeleteFontClientID (fsd->fontid); + + _fs_free_props (&pfont->info); + + xfree(fsdata); + + DestroyFontRec(pfont); +} + +FontPtr +fs_create_font (FontPathElementPtr fpe, + char *name, + int namelen, + fsBitmapFormat format, + fsBitmapFormatMask fmask) +{ + FontPtr pfont; + FSFontPtr fsfont; + FSFontDataPtr fsd; + int bit, byte, scan, glyph; + + pfont = CreateFontRec (); + if (!pfont) + return 0; + fsfont = (FSFontPtr) xalloc (sizeof (FSFontRec) + + sizeof (FSFontDataRec) + + namelen + 1); + if (!fsfont) + { + DestroyFontRec (pfont); + return 0; + } + fsd = (FSFontDataPtr) (fsfont + 1); + bzero((char *) fsfont, sizeof(FSFontRec)); + bzero((char *) fsd, sizeof(FSFontDataRec)); + + pfont->fpe = fpe; + pfont->fontPrivate = (pointer) fsfont; + pfont->fpePrivate = (pointer) fsd; + + /* These font components will be needed in packGlyphs */ + CheckFSFormat(format, BitmapFormatMaskBit | + BitmapFormatMaskByte | + BitmapFormatMaskScanLineUnit | + BitmapFormatMaskScanLinePad, + &bit, + &byte, + &scan, + &glyph, + NULL); + pfont->format = format; + pfont->bit = bit; + pfont->byte = byte; + pfont->scan = scan; + pfont->glyph = glyph; + + pfont->info.nprops = 0; + pfont->info.props = 0; + pfont->info.isStringProp = 0; + + /* set font function pointers */ + pfont->get_glyphs = _fs_get_glyphs; + pfont->get_metrics = _fs_get_metrics; + pfont->unload_font = _fs_unload_font; + pfont->unload_glyphs = NULL; + + /* set the FPE private information */ + fsd->format = format; + fsd->fmask = fmask; + fsd->name = (char *) (fsd + 1); + memcpy (fsd->name, name, namelen); + fsd->name[namelen] = '\0'; + fsd->fontid = GetNewFontClientID (); + + /* save the ID */ + if (!StoreFontClientFont(pfont, fsd->fontid)) + { + xfree (fsfont); + DestroyFontRec (pfont); + return 0; + } + + return pfont; +} + +pointer +fs_alloc_glyphs (FontPtr pFont, int size) +{ + FSGlyphPtr glyphs; + FSFontPtr fsfont = (FSFontPtr) pFont->fontPrivate; + + glyphs = xalloc (sizeof (FSGlyphRec) + size); + glyphs->next = fsfont->glyphs; + fsfont->glyphs = glyphs; + return (pointer) (glyphs + 1); +} diff --git a/nx-X11/lib/font/fc/fserve.c b/nx-X11/lib/font/fc/fserve.c new file mode 100644 index 000000000..bac0b8ee6 --- /dev/null +++ b/nx-X11/lib/font/fc/fserve.c @@ -0,0 +1,3262 @@ +/* $XdotOrg: xc/lib/font/fc/fserve.c,v 1.8 2005/07/09 06:36:12 keithp Exp $ */ +/* $Xorg: fserve.c,v 1.4 2001/02/09 02:04:02 xorgcvs Exp $ */ +/* + +Copyright 1990, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ +/* $XFree86: xc/lib/font/fc/fserve.c,v 3.26tsi Exp $ */ + +/* + * Copyright 1990 Network Computing Devices + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the names of Network Computing Devices, or Digital + * not be used in advertising or publicity pertaining to distribution + * of the software without specific, written prior permission. + * + * NETWORK COMPUTING DEVICES, AND DIGITAL AND DISCLAIM ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES, + * OR DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF + * THIS SOFTWARE. + * + * Author: Dave Lemke, Network Computing Devices, Inc + */ +/* + * font server specific font access + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#ifdef WIN32 +#define _WILLWINSOCK_ +#endif +#define FONT_t +#define TRANS_CLIENT +#include "X11/Xtrans/Xtrans.h" +#include "X11/Xpoll.h" +#include <X11/fonts/FS.h> +#include <X11/fonts/FSproto.h> +#include <X11/X.h> +#include <X11/Xos.h> +#include <X11/fonts/fontmisc.h> +#include <X11/fonts/fontstruct.h> +#include "fservestr.h" +#include <X11/fonts/fontutil.h> +#include <errno.h> + +#include <time.h> +#define Time_t time_t + +#ifdef NCD +#include <ncd/nvram.h> +#endif + +#include <stddef.h> + +#ifndef MIN +#define MIN(a,b) ((a)<(b)?(a):(b)) +#endif +#define TimeCmp(a,c,b) ((int) ((a) - (b)) c 0) + +#define NONZEROMETRICS(pci) ((pci)->leftSideBearing || \ + (pci)->rightSideBearing || \ + (pci)->ascent || \ + (pci)->descent || \ + (pci)->characterWidth) + +extern void ErrorF(const char *f, ...); + +static int fs_read_glyphs ( FontPathElementPtr fpe, FSBlockDataPtr blockrec ); +static int fs_read_list ( FontPathElementPtr fpe, FSBlockDataPtr blockrec ); +static int fs_read_list_info ( FontPathElementPtr fpe, + FSBlockDataPtr blockrec ); + +extern fd_set _fs_fd_mask; + +static void fs_block_handler ( pointer data, OSTimePtr wt, + pointer LastSelectMask ); +static int fs_wakeup ( FontPathElementPtr fpe, unsigned long *mask ); + +/* + * List of all FPEs + */ +static FSFpePtr fs_fpes; +/* + * Union of all FPE blockStates + */ +static CARD32 fs_blockState; + +static int _fs_restart_connection ( FSFpePtr conn ); +static void fs_send_query_bitmaps ( FontPathElementPtr fpe, + FSBlockDataPtr blockrec ); +static int fs_send_close_font ( FontPathElementPtr fpe, Font id ); +static void fs_client_died ( pointer client, FontPathElementPtr fpe ); +static void _fs_client_access ( FSFpePtr conn, pointer client, Bool sync ); +static void _fs_client_resolution ( FSFpePtr conn ); +static fsGenericReply *fs_get_reply (FSFpePtr conn, int *error); +static int fs_await_reply (FSFpePtr conn); +static void _fs_do_blocked (FSFpePtr conn); +static void fs_cleanup_bfont (FSBlockedFontPtr bfont); + +char _fs_glyph_undefined; +char _fs_glyph_requested; +char _fs_glyph_zero_length; + +static int generationCount; + +int FontServerRequestTimeout = 30 * 1000; + +static void +_fs_close_server (FSFpePtr conn); + +static FSFpePtr +_fs_init_conn (char *servername); + +static int +_fs_wait_connect (FSFpePtr conn); + +static int +_fs_send_init_packets (FSFpePtr conn); + +static void +_fs_check_reconnect (FSFpePtr conn); + +static void +_fs_start_reconnect (FSFpePtr conn); + +static void +_fs_free_conn (FSFpePtr conn); + +static int +fs_free_fpe(FontPathElementPtr fpe); + +/* + * Font server access + * + * the basic idea for the non-blocking access is to have the function + * called multiple times until the actual data is returned, instead + * of ClientBlocked. + * + * the first call to the function will cause the request to be sent to + * the font server, and a block record to be stored in the fpe's list + * of outstanding requests. the FS block handler also sticks the + * proper set of fd's into the select mask. when data is ready to be + * read in, the FS wakup handler will be hit. this will read the + * data off the wire into the proper block record, and then signal the + * client that caused the block so that it can restart. it will then + * call the access function again, which will realize that the data has + * arrived and return it. + */ + + +#ifdef DEBUG +static void +_fs_add_req_log(FSFpePtr conn, int opcode) +{ + conn->current_seq++; + fprintf (stderr, "\t\tRequest: %5d Opcode: %2d\n", + conn->current_seq, opcode); + conn->reqbuffer[conn->reqindex].opcode = opcode; + conn->reqbuffer[conn->reqindex].sequence = conn->current_seq; + conn->reqindex++; + if (conn->reqindex == REQUEST_LOG_SIZE) + conn->reqindex = 0; +} + +static void +_fs_add_rep_log (FSFpePtr conn, fsGenericReply *rep) +{ + int i; + + for (i = 0; i < REQUEST_LOG_SIZE; i++) + if (conn->reqbuffer[i].sequence == rep->sequenceNumber) + break; + if (i == REQUEST_LOG_SIZE) + fprintf (stderr, "\t\t\t\t\tReply: %5d Opcode: unknown\n", + rep->sequenceNumber); + else + fprintf (stderr, "\t\t\t\t\tReply: %5d Opcode: %d\n", + rep->sequenceNumber, + conn->reqbuffer[i].opcode); +} +#else +#define _fs_add_req_log(conn,op) ((conn)->current_seq++) +#define _fs_add_rep_log(conn,rep) +#endif + +static Bool +fs_name_check(char *name) +{ +#ifdef __UNIXOS2__ + /* OS/2 uses D:/usr/X11R6/.... as fontfile pathnames, so check that + * there is not only a protocol/ prefix, but also that the first chars + * are not a drive letter + */ + if (name && isalpha(*name) && name[1] == ':') + return FALSE; +#endif + /* Just make sure there is a protocol/ prefix */ + return (name && *name != '/' && strchr(name, '/')); +} + +static void +_fs_client_resolution(FSFpePtr conn) +{ + fsSetResolutionReq srreq; + int num_res; + FontResolutionPtr res; + + res = GetClientResolutions(&num_res); + + if (num_res) { + srreq.reqType = FS_SetResolution; + srreq.num_resolutions = num_res; + srreq.length = (SIZEOF(fsSetResolutionReq) + + (num_res * SIZEOF(fsResolution)) + 3) >> 2; + + _fs_add_req_log(conn, FS_SetResolution); + if (_fs_write(conn, (char *) &srreq, SIZEOF(fsSetResolutionReq)) != -1) + (void)_fs_write_pad(conn, (char *) res, + (num_res * SIZEOF(fsResolution))); + } +} + +/* + * close font server and remove any state associated with + * this connection - this includes any client records. + */ + +static void +fs_close_conn(FSFpePtr conn) +{ + FSClientPtr client, nclient; + + _fs_close_server (conn); + + for (client = conn->clients; client; client = nclient) + { + nclient = client->next; + xfree (client); + } + conn->clients = NULL; +} + +/* + * the wakeup handlers have to be set when the FPE is open, and not + * removed until it is freed, in order to handle unexpected data, like + * events + */ +/* ARGSUSED */ +static int +fs_init_fpe(FontPathElementPtr fpe) +{ + FSFpePtr conn; + char *name; + int err; + int ret; + + /* open font server */ + /* create FS specific fpe info */ + name = fpe->name; + + /* hack for old style names */ + if (*name == ':') + name++; /* skip ':' */ + + conn = _fs_init_conn (name); + if (!conn) + err = AllocError; + else + { + err = init_fs_handlers (fpe, fs_block_handler); + if (err != Successful) + { + _fs_free_conn (conn); + err = AllocError; + } + else + { + fpe->private = conn; + conn->next = fs_fpes; + fs_fpes = conn; + ret = _fs_wait_connect (conn); + if (ret != FSIO_READY) + { + fs_free_fpe (fpe); + err = BadFontPath; + } + else + err = Successful; + } + } + + if (err == Successful) + { +#ifdef NCD + if (configData.ExtendedFontDiags) + printf("Connected to font server \"%s\"\n", name); +#endif +#ifdef DEBUG + fprintf (stderr, "connected to FS \"%s\"\n", name); +#endif + } + else + { +#ifdef DEBUG + fprintf(stderr, "failed to connect to FS \"%s\" %d\n", name, err); +#endif +#ifdef NCD + if (configData.ExtendedFontDiags) + printf("Failed to connect to font server \"%s\"\n", name); +#endif + ; + } + return err; +} + +static int +fs_reset_fpe(FontPathElementPtr fpe) +{ + (void) _fs_send_init_packets((FSFpePtr) fpe->private); + return Successful; +} + +/* + * this shouldn't be called till all refs to the FPE are gone + */ + +static int +fs_free_fpe(FontPathElementPtr fpe) +{ + FSFpePtr conn = (FSFpePtr) fpe->private, *prev; + + /* unhook from chain of all font servers */ + for (prev = &fs_fpes; *prev; prev = &(*prev)->next) + { + if (*prev == conn) + { + *prev = conn->next; + break; + } + } + _fs_unmark_block (conn, conn->blockState); + fs_close_conn(conn); + remove_fs_handlers(fpe, fs_block_handler, fs_fpes == 0); + _fs_free_conn (conn); + fpe->private = (pointer) 0; + +#ifdef NCD + if (configData.ExtendedFontDiags) + printf("Disconnected from font server \"%s\"\n", fpe->name); +#endif +#ifdef DEBUG + fprintf (stderr, "disconnect from FS \"%s\"\n", fpe->name); +#endif + + return Successful; +} + +static FSBlockDataPtr +fs_new_block_rec(FontPathElementPtr fpe, pointer client, int type) +{ + FSBlockDataPtr blockrec, + *prev; + FSFpePtr conn = (FSFpePtr) fpe->private; + int size; + + switch (type) { + case FS_OPEN_FONT: + size = sizeof(FSBlockedFontRec); + break; + case FS_LOAD_GLYPHS: + size = sizeof(FSBlockedGlyphRec); + break; + case FS_LIST_FONTS: + size = sizeof(FSBlockedListRec); + break; + case FS_LIST_WITH_INFO: + size = sizeof(FSBlockedListInfoRec); + break; + default: + size = 0; + break; + } + blockrec = (FSBlockDataPtr) xalloc(sizeof(FSBlockDataRec) + size); + if (!blockrec) + return (FSBlockDataPtr) 0; + blockrec->data = (pointer) (blockrec + 1); + blockrec->client = client; + blockrec->sequenceNumber = -1; + blockrec->errcode = StillWorking; + blockrec->type = type; + blockrec->depending = 0; + blockrec->next = (FSBlockDataPtr) 0; + + /* stick it on the end of the list (since its expected last) */ + for (prev = &conn->blockedRequests; *prev; prev = &(*prev)->next) + ; + *prev = blockrec; + + return blockrec; +} + +static void +_fs_set_pending_reply (FSFpePtr conn) +{ + FSBlockDataPtr blockrec; + + for (blockrec = conn->blockedRequests; blockrec; blockrec = blockrec->next) + if (blockrec->errcode == StillWorking) + break; + if (blockrec) + { + conn->blockedReplyTime = GetTimeInMillis () + FontServerRequestTimeout; + _fs_mark_block (conn, FS_PENDING_REPLY); + } + else + _fs_unmark_block (conn, FS_PENDING_REPLY); +} + +static void +_fs_remove_block_rec(FSFpePtr conn, FSBlockDataPtr blockrec) +{ + FSBlockDataPtr *prev; + + for (prev = &conn->blockedRequests; *prev; prev = &(*prev)->next) + if (*prev == blockrec) + { + *prev = blockrec->next; + break; + } + if (blockrec->type == FS_LOAD_GLYPHS) + { + FSBlockedGlyphPtr bglyph = (FSBlockedGlyphPtr)blockrec->data; + if (bglyph->num_expected_ranges) + xfree(bglyph->expected_ranges); + } + xfree(blockrec); + _fs_set_pending_reply (conn); +} + +static void +_fs_signal_clients_depending(FSClientsDependingPtr *clients_depending) +{ + FSClientsDependingPtr p; + + while ((p = *clients_depending)) + { + *clients_depending = p->next; + ClientSignal(p->client); + xfree(p); + } +} + +static int +_fs_add_clients_depending(FSClientsDependingPtr *clients_depending, pointer client) +{ + FSClientsDependingPtr new, cd; + + for (; (cd = *clients_depending); + clients_depending = &(*clients_depending)->next) + { + if (cd->client == client) + return Suspended; + } + + new = (FSClientsDependingPtr)xalloc (sizeof (FSClientsDependingRec)); + if (!new) + return BadAlloc; + + new->client = client; + new->next = 0; + *clients_depending = new; + return Suspended; +} + +/* + * When a request is aborted due to a font server failure, + * signal any depending clients to restart their dependant + * requests + */ +static void +_fs_clean_aborted_blockrec(FSFpePtr conn, FSBlockDataPtr blockrec) +{ + switch(blockrec->type) { + case FS_OPEN_FONT: { + FSBlockedFontPtr bfont = (FSBlockedFontPtr)blockrec->data; + + fs_cleanup_bfont (bfont); + _fs_signal_clients_depending(&bfont->clients_depending); + break; + } + case FS_LOAD_GLYPHS: { + FSBlockedGlyphPtr bglyph = (FSBlockedGlyphPtr)blockrec->data; + + _fs_clean_aborted_loadglyphs(bglyph->pfont, + bglyph->num_expected_ranges, + bglyph->expected_ranges); + _fs_signal_clients_depending(&bglyph->clients_depending); + break; + } + case FS_LIST_FONTS: + break; + case FS_LIST_WITH_INFO: { + FSBlockedListInfoPtr binfo; + binfo = (FSBlockedListInfoPtr) blockrec->data; + if (binfo->status == FS_LFWI_REPLY) + FD_SET(conn->fs_fd, &_fs_fd_mask); + _fs_free_props (&binfo->info); + } + default: + break; + } +} + +static void +fs_abort_blockrec(FSFpePtr conn, FSBlockDataPtr blockrec) +{ + _fs_clean_aborted_blockrec (conn, blockrec); + _fs_remove_block_rec (conn, blockrec); +} + +/* + * Tell the font server we've failed to complete an open and + * then unload the partially created font + */ +static void +fs_cleanup_bfont (FSBlockedFontPtr bfont) +{ + FSFontDataRec *fsd; + + if (bfont->pfont) + { + fsd = (FSFontDataRec *) bfont->pfont->fpePrivate; + + /* make sure the FS knows we choked on it */ + fs_send_close_font(bfont->pfont->fpe, bfont->fontid); + + /* + * Either unload the font if it's being opened for + * the first time, or smash the generation field to + * mark this font as an orphan + */ + if (!(bfont->flags & FontReopen)) + { + if (bfont->freeFont) + (*bfont->pfont->unload_font) (bfont->pfont); +#ifdef DEBUG + else + fprintf (stderr, "Not freeing other font in cleanup_bfont\n"); +#endif + bfont->pfont = 0; + } + else + fsd->generation = -1; + } +} + +/* + * Check to see if a complete reply is waiting + */ +static fsGenericReply * +fs_get_reply (FSFpePtr conn, int *error) +{ + char *buf; + fsGenericReply *rep; + int ret; + + /* block if the connection is down or paused in lfwi */ + if (conn->fs_fd == -1 || !FD_ISSET (conn->fs_fd, &_fs_fd_mask)) + { + *error = FSIO_BLOCK; + return 0; + } + + ret = _fs_start_read (conn, sizeof (fsGenericReply), &buf); + if (ret != FSIO_READY) + { + *error = FSIO_BLOCK; + return 0; + } + + rep = (fsGenericReply *) buf; + + ret = _fs_start_read (conn, rep->length << 2, &buf); + if (ret != FSIO_READY) + { + *error = FSIO_BLOCK; + return 0; + } + + *error = FSIO_READY; + + return (fsGenericReply *) buf; +} + +static Bool +fs_reply_ready (FSFpePtr conn) +{ + fsGenericReply *rep; + + if (conn->fs_fd == -1 || !FD_ISSET (conn->fs_fd, &_fs_fd_mask)) + return FALSE; + if (fs_data_read (conn) < sizeof (fsGenericReply)) + return FALSE; + rep = (fsGenericReply *) (conn->inBuf.buf + conn->inBuf.remove); + if (fs_data_read (conn) < rep->length << 2) + return FALSE; + return TRUE; +} + +static void +_fs_pending_reply (FSFpePtr conn) +{ + if (!(conn->blockState & FS_PENDING_REPLY)) + { + _fs_mark_block (conn, FS_PENDING_REPLY); + conn->blockedReplyTime = GetTimeInMillis () + FontServerRequestTimeout; + } +} + +static void +_fs_prepare_for_reply (FSFpePtr conn) +{ + _fs_pending_reply (conn); + _fs_flush (conn); +} + +/* + * Block (for a while) awaiting a complete reply + */ +static int +fs_await_reply (FSFpePtr conn) +{ + int ret; + + if (conn->blockState & FS_COMPLETE_REPLY) + return FSIO_READY; + + while (!fs_get_reply (conn, &ret)) + { + if (ret != FSIO_BLOCK) + return ret; + if (_fs_wait_for_readable (conn, FontServerRequestTimeout) != FSIO_READY) + { + _fs_connection_died (conn); + return FSIO_ERROR; + } + } + return FSIO_READY; +} + +/* + * Process the reply to an OpenBitmapFont request + */ +static int +fs_read_open_font(FontPathElementPtr fpe, FSBlockDataPtr blockrec) +{ + FSFpePtr conn = (FSFpePtr) fpe->private; + FSBlockedFontPtr bfont = (FSBlockedFontPtr) blockrec->data; + fsOpenBitmapFontReply *rep; + FSBlockDataPtr blockOrig; + FSBlockedFontPtr origBfont; + int ret; + + rep = (fsOpenBitmapFontReply *) fs_get_reply (conn, &ret); + if (!rep || rep->type == FS_Error) + { + if (ret == FSIO_BLOCK) + return StillWorking; + if (rep) + _fs_done_read (conn, rep->length << 2); + fs_cleanup_bfont (bfont); + return BadFontName; + } + + /* If we're not reopening a font and FS detected a duplicate font + open request, replace our reference to the new font with a + reference to an existing font (possibly one not finished + opening). If this is a reopen, keep the new font reference... + it's got the metrics and extents we read when the font was opened + before. This also gives us the freedom to easily close the font + if we we decide (in fs_read_query_info()) that we don't like what + we got. */ + + if (rep->otherid && !(bfont->flags & FontReopen)) + { + fs_cleanup_bfont (bfont); + + /* Find old font if we're completely done getting it from server. */ + bfont->pfont = find_old_font(rep->otherid); + bfont->freeFont = FALSE; + bfont->fontid = rep->otherid; + bfont->state = FS_DONE_REPLY; + /* + * look for a blocked request to open the same font + */ + for (blockOrig = conn->blockedRequests; + blockOrig; + blockOrig = blockOrig->next) + { + if (blockOrig != blockrec && blockOrig->type == FS_OPEN_FONT) + { + origBfont = (FSBlockedFontPtr) blockOrig->data; + if (origBfont->fontid == rep->otherid) + { + blockrec->depending = blockOrig->depending; + blockOrig->depending = blockrec; + bfont->state = FS_DEPENDING; + bfont->pfont = origBfont->pfont; + break; + } + } + } + if (bfont->pfont == NULL) + { + /* XXX - something nasty happened */ + ret = BadFontName; + } + else + ret = AccessDone; + } + else + { + bfont->pfont->info.cachable = rep->cachable != 0; + bfont->state = FS_INFO_REPLY; + /* + * Reset the blockrec for the next reply + */ + blockrec->sequenceNumber = bfont->queryInfoSequence; + conn->blockedReplyTime = GetTimeInMillis () + FontServerRequestTimeout; + ret = StillWorking; + } + _fs_done_read (conn, rep->length << 2); + return ret; +} + +static Bool +fs_fonts_match (FontInfoPtr pInfo1, FontInfoPtr pInfo2) +{ + int i; + + if (pInfo1->firstCol != pInfo2->firstCol || + pInfo1->lastCol != pInfo2->lastCol || + pInfo1->firstRow != pInfo2->firstRow || + pInfo1->lastRow != pInfo2->lastRow || + pInfo1->defaultCh != pInfo2->defaultCh || + pInfo1->noOverlap != pInfo2->noOverlap || + pInfo1->terminalFont != pInfo2->terminalFont || + pInfo1->constantMetrics != pInfo2->constantMetrics || + pInfo1->constantWidth != pInfo2->constantWidth || + pInfo1->inkInside != pInfo2->inkInside || + pInfo1->inkMetrics != pInfo2->inkMetrics || + pInfo1->allExist != pInfo2->allExist || + pInfo1->drawDirection != pInfo2->drawDirection || + pInfo1->cachable != pInfo2->cachable || + pInfo1->anamorphic != pInfo2->anamorphic || + pInfo1->maxOverlap != pInfo2->maxOverlap || + pInfo1->fontAscent != pInfo2->fontAscent || + pInfo1->fontDescent != pInfo2->fontDescent || + pInfo1->nprops != pInfo2->nprops) + return FALSE; + +#define MATCH(xci1, xci2) \ + (((xci1).leftSideBearing == (xci2).leftSideBearing) && \ + ((xci1).rightSideBearing == (xci2).rightSideBearing) && \ + ((xci1).characterWidth == (xci2).characterWidth) && \ + ((xci1).ascent == (xci2).ascent) && \ + ((xci1).descent == (xci2).descent) && \ + ((xci1).attributes == (xci2).attributes)) + + if (!MATCH(pInfo1->maxbounds, pInfo2->maxbounds) || + !MATCH(pInfo1->minbounds, pInfo2->minbounds) || + !MATCH(pInfo1->ink_maxbounds, pInfo2->ink_maxbounds) || + !MATCH(pInfo1->ink_minbounds, pInfo2->ink_minbounds)) + return FALSE; + +#undef MATCH + + for (i = 0; i < pInfo1->nprops; i++) + if (pInfo1->isStringProp[i] != + pInfo2->isStringProp[i] || + pInfo1->props[i].name != + pInfo2->props[i].name || + pInfo1->props[i].value != + pInfo2->props[i].value) + { + return FALSE; + } + return TRUE; +} + +static int +fs_read_query_info(FontPathElementPtr fpe, FSBlockDataPtr blockrec) +{ + FSBlockedFontPtr bfont = (FSBlockedFontPtr) blockrec->data; + FSFpePtr conn = (FSFpePtr) fpe->private; + fsQueryXInfoReply *rep; + char *buf; + fsPropInfo *pi; + fsPropOffset *po; + pointer pd; + FontInfoPtr pInfo; + FontInfoRec tempInfo; + int err; + int ret; + + rep = (fsQueryXInfoReply *) fs_get_reply (conn, &ret); + if (!rep || rep->type == FS_Error) + { + if (ret == FSIO_BLOCK) + return StillWorking; + if (rep) + _fs_done_read (conn, rep->length << 2); + fs_cleanup_bfont (bfont); + return BadFontName; + } + + /* If this is a reopen, accumulate the query info into a dummy + font and compare to our original data. */ + if (bfont->flags & FontReopen) + pInfo = &tempInfo; + else + pInfo = &bfont->pfont->info; + + buf = (char *) rep; + buf += SIZEOF(fsQueryXInfoReply); + + /* move the data over */ + fsUnpack_XFontInfoHeader(rep, pInfo); + + /* compute accelerators */ + _fs_init_fontinfo(conn, pInfo); + + /* Compute offsets into the reply */ + pi = (fsPropInfo *) buf; + buf += SIZEOF (fsPropInfo); + + po = (fsPropOffset *) buf; + buf += pi->num_offsets * SIZEOF(fsPropOffset); + + pd = (pointer) buf; + buf += pi->data_len; + + /* convert the properties and step over the reply */ + ret = _fs_convert_props(pi, po, pd, pInfo); + _fs_done_read (conn, rep->length << 2); + + if (ret == -1) + { + fs_cleanup_bfont (bfont); + return AllocError; + } + + if (bfont->flags & FontReopen) + { + /* We're reopening a font that we lost because of a downed + connection. In the interest of avoiding corruption from + opening a different font than the old one (we already have + its metrics, extents, and probably some of its glyphs), + verify that the metrics and properties all match. */ + + if (fs_fonts_match (pInfo, &bfont->pfont->info)) + { + err = Successful; + bfont->state = FS_DONE_REPLY; + } + else + { + fs_cleanup_bfont (bfont); + err = BadFontName; + } + _fs_free_props (pInfo); + + return err; + } + + /* + * Ask for terminal format fonts if possible + */ + if (bfont->pfont->info.terminalFont) + bfont->format = ((bfont->format & ~ (BitmapFormatImageRectMask)) | + BitmapFormatImageRectMax); + + /* + * Figure out if the whole font should get loaded right now. + */ + if (glyphCachingMode == CACHING_OFF || + (glyphCachingMode == CACHE_16_BIT_GLYPHS + && !bfont->pfont->info.lastRow)) + { + bfont->flags |= FontLoadAll; + } + + /* + * Ready to send the query bitmaps; the terminal font bit has + * been computed and glyphCaching has been considered + */ + if (bfont->flags & FontLoadBitmaps) + { + fs_send_query_bitmaps (fpe, blockrec); + _fs_flush (conn); + } + + bfont->state = FS_EXTENT_REPLY; + + /* + * Reset the blockrec for the next reply + */ + blockrec->sequenceNumber = bfont->queryExtentsSequence; + conn->blockedReplyTime = GetTimeInMillis () + FontServerRequestTimeout; + + return StillWorking; +} + +static int +fs_read_extent_info(FontPathElementPtr fpe, FSBlockDataPtr blockrec) +{ + FSFpePtr conn = (FSFpePtr) fpe->private; + FSBlockedFontPtr bfont = (FSBlockedFontPtr) blockrec->data; + FSFontDataPtr fsd = (FSFontDataPtr) bfont->pfont->fpePrivate; + FSFontPtr fsfont = (FSFontPtr) bfont->pfont->fontPrivate; + fsQueryXExtents16Reply *rep; + char *buf; + int i; + int numExtents; + int numInfos; + int ret; + Bool haveInk = FALSE; /* need separate ink metrics? */ + CharInfoPtr ci, pCI; + char *fsci; + fsXCharInfo fscilocal; + FontInfoRec *fi = &bfont->pfont->info; + + rep = (fsQueryXExtents16Reply *) fs_get_reply (conn, &ret); + if (!rep || rep->type == FS_Error) + { + if (ret == FSIO_BLOCK) + return StillWorking; + if (rep) + _fs_done_read (conn, rep->length << 2); + fs_cleanup_bfont (bfont); + return BadFontName; + } + + /* move the data over */ + /* need separate inkMetrics for fixed font server protocol version */ + numExtents = rep->num_extents; + numInfos = numExtents; + if (bfont->pfont->info.terminalFont && conn->fsMajorVersion > 1) + { + numInfos *= 2; + haveInk = TRUE; + } + ci = pCI = (CharInfoPtr) xalloc(sizeof(CharInfoRec) * numInfos); + + if (!pCI) + { + _fs_done_read (conn, rep->length << 2); + fs_cleanup_bfont(bfont); + return AllocError; + } + fsfont->encoding = pCI; + if (haveInk) + fsfont->inkMetrics = pCI + numExtents; + else + fsfont->inkMetrics = pCI; + + buf = (char *) rep; + buf += SIZEOF (fsQueryXExtents16Reply); + fsci = buf; + + fsd->glyphs_to_get = 0; + ci = fsfont->inkMetrics; + for (i = 0; i < numExtents; i++) + { + memcpy(&fscilocal, fsci, SIZEOF(fsXCharInfo)); /* align it */ + _fs_convert_char_info(&fscilocal, &ci->metrics); + /* Bounds check. */ + if (ci->metrics.ascent > fi->maxbounds.ascent) + { + ErrorF("fserve: warning: %s %s ascent (%d) > maxascent (%d)\n", + fpe->name, fsd->name, + ci->metrics.ascent, fi->maxbounds.ascent); + ci->metrics.ascent = fi->maxbounds.ascent; + } + if (ci->metrics.descent > fi->maxbounds.descent) + { + ErrorF("fserve: warning: %s %s descent (%d) > maxdescent (%d)\n", + fpe->name, fsd->name, + ci->metrics.descent, fi->maxbounds.descent); + ci->metrics.descent = fi->maxbounds.descent; + } + fsci = fsci + SIZEOF(fsXCharInfo); + /* Initialize the bits field for later glyph-caching use */ + if (NONZEROMETRICS(&ci->metrics)) + { + if (!haveInk && + (ci->metrics.leftSideBearing == ci->metrics.rightSideBearing || + ci->metrics.ascent == -ci->metrics.descent)) + pCI[i].bits = &_fs_glyph_zero_length; + else + { + pCI[i].bits = &_fs_glyph_undefined; + fsd->glyphs_to_get++; + } + } + else + pCI[i].bits = (char *)0; + ci++; + } + + /* Done with reply */ + _fs_done_read (conn, rep->length << 2); + + /* build bitmap metrics, ImageRectMax style */ + if (haveInk) + { + CharInfoPtr ii; + + ci = fsfont->encoding; + ii = fsfont->inkMetrics; + for (i = 0; i < numExtents; i++, ci++, ii++) + { + if (NONZEROMETRICS(&ii->metrics)) + { + ci->metrics.leftSideBearing = FONT_MIN_LEFT(fi); + ci->metrics.rightSideBearing = FONT_MAX_RIGHT(fi); + ci->metrics.ascent = FONT_MAX_ASCENT(fi); + ci->metrics.descent = FONT_MAX_DESCENT(fi); + ci->metrics.characterWidth = FONT_MAX_WIDTH(fi); + ci->metrics.attributes = ii->metrics.attributes; + } + else + { + ci->metrics = ii->metrics; + } + /* Bounds check. */ + if (ci->metrics.ascent > fi->maxbounds.ascent) + { + ErrorF("fserve: warning: %s %s ascent (%d) " + "> maxascent (%d)\n", + fpe->name, fsd->name, + ci->metrics.ascent, fi->maxbounds.ascent); + ci->metrics.ascent = fi->maxbounds.ascent; + } + if (ci->metrics.descent > fi->maxbounds.descent) + { + ErrorF("fserve: warning: %s %s descent (%d) " + "> maxdescent (%d)\n", + fpe->name, fsd->name, + ci->metrics.descent, fi->maxbounds.descent); + ci->metrics.descent = fi->maxbounds.descent; + } + } + } + { + unsigned int r, c, numCols, firstCol; + + firstCol = bfont->pfont->info.firstCol; + numCols = bfont->pfont->info.lastCol - firstCol + 1; + c = bfont->pfont->info.defaultCh; + fsfont->pDefault = 0; + if (bfont->pfont->info.lastRow) + { + r = c >> 8; + r -= bfont->pfont->info.firstRow; + c &= 0xff; + c -= firstCol; + if (r < bfont->pfont->info.lastRow-bfont->pfont->info.firstRow+1 && + c < numCols) + fsfont->pDefault = &pCI[r * numCols + c]; + } + else + { + c -= firstCol; + if (c < numCols) + fsfont->pDefault = &pCI[c]; + } + } + bfont->state = FS_GLYPHS_REPLY; + + if (bfont->flags & FontLoadBitmaps) + { + /* + * Reset the blockrec for the next reply + */ + blockrec->sequenceNumber = bfont->queryBitmapsSequence; + conn->blockedReplyTime = GetTimeInMillis () + FontServerRequestTimeout; + return StillWorking; + } + return Successful; +} + +#ifdef DEBUG +static char *fs_open_states[] = { + "OPEN_REPLY ", + "INFO_REPLY ", + "EXTENT_REPLY", + "GLYPHS_REPLY", + "DONE_REPLY ", + "DEPENDING ", +}; +#endif + +static int +fs_do_open_font(FontPathElementPtr fpe, FSBlockDataPtr blockrec) +{ + FSBlockedFontPtr bfont = (FSBlockedFontPtr) blockrec->data; + int err; + +#ifdef DEBUG + fprintf (stderr, "fs_do_open_font state %s %s\n", + fs_open_states[bfont->state], + ((FSFontDataPtr) (bfont->pfont->fpePrivate))->name); +#endif + err = BadFontName; + switch (bfont->state) { + case FS_OPEN_REPLY: + err = fs_read_open_font(fpe, blockrec); + if (err != StillWorking) { /* already loaded, or error */ + /* if font's already loaded, massage error code */ + switch (bfont->state) { + case FS_DONE_REPLY: + err = Successful; + break; + case FS_DEPENDING: + err = StillWorking; + break; + } + } + break; + case FS_INFO_REPLY: + err = fs_read_query_info(fpe, blockrec); + break; + case FS_EXTENT_REPLY: + err = fs_read_extent_info(fpe, blockrec); + break; + case FS_GLYPHS_REPLY: + if (bfont->flags & FontLoadBitmaps) + err = fs_read_glyphs(fpe, blockrec); + break; + case FS_DEPENDING: /* can't happen */ + default: + break; + } +#ifdef DEBUG + fprintf (stderr, "fs_do_open_font err %d\n", err); +#endif + if (err != StillWorking) + { + bfont->state = FS_DONE_REPLY; /* for _fs_load_glyphs() */ + while ((blockrec = blockrec->depending)) + { + bfont = (FSBlockedFontPtr) blockrec->data; + bfont->state = FS_DONE_REPLY; /* for _fs_load_glyphs() */ + } + } + return err; +} + +void +_fs_mark_block (FSFpePtr conn, CARD32 mask) +{ + conn->blockState |= mask; + fs_blockState |= mask; +} + +void +_fs_unmark_block (FSFpePtr conn, CARD32 mask) +{ + FSFpePtr c; + + if (conn->blockState & mask) + { + conn->blockState &= ~mask; + fs_blockState = 0; + for (c = fs_fpes; c; c = c->next) + fs_blockState |= c->blockState; + } +} + +/* ARGSUSED */ +static void +fs_block_handler(pointer data, OSTimePtr wt, pointer LastSelectMask) +{ + static struct timeval block_timeout; + CARD32 now, earliest, wakeup; + int soonest; + FSFpePtr conn; + + XFD_ORSET((fd_set *)LastSelectMask, (fd_set *)LastSelectMask, + &_fs_fd_mask); + /* + * Flush all pending output + */ + if (fs_blockState & FS_PENDING_WRITE) + for (conn = fs_fpes; conn; conn = conn->next) + if (conn->blockState & FS_PENDING_WRITE) + _fs_flush (conn); + /* + * Check for any fpe with a complete reply, set sleep time to zero + */ + if (fs_blockState & FS_COMPLETE_REPLY) + { + block_timeout.tv_sec = 0; + block_timeout.tv_usec = 0; + if (*wt == NULL) + *wt = &block_timeout; + else + **wt = block_timeout; + } + /* + * Walk through fpe list computing sleep time + */ + else if (fs_blockState & (FS_BROKEN_WRITE| + FS_BROKEN_CONNECTION| + FS_PENDING_REPLY| + FS_RECONNECTING)) + { + now = GetTimeInMillis (); + earliest = now + 10000000; + for (conn = fs_fpes; conn; conn = conn->next) + { + if (conn->blockState & FS_RECONNECTING) + { + wakeup = conn->blockedConnectTime; + if (TimeCmp (wakeup, <, earliest)) + earliest = wakeup; + } + if (conn->blockState & FS_BROKEN_CONNECTION) + { + wakeup = conn->brokenConnectionTime; + if (TimeCmp (wakeup, <, earliest)) + earliest = wakeup; + } + if (conn->blockState & FS_BROKEN_WRITE) + { + wakeup = conn->brokenWriteTime; + if (TimeCmp (wakeup, <, earliest)) + earliest = wakeup; + } + if (conn->blockState & FS_PENDING_REPLY) + { + wakeup = conn->blockedReplyTime; + if (TimeCmp (wakeup, <, earliest)) + earliest = wakeup; + } + } + soonest = earliest - now; + if (soonest < 0) + soonest = 0; + block_timeout.tv_sec = soonest / 1000; + block_timeout.tv_usec = (soonest % 1000) * 1000; + if (*wt == NULL) + *wt = &block_timeout; + else if (soonest < (*wt)->tv_sec * 1000 + (*wt)->tv_usec / 1000) + **wt = block_timeout; + } +} + +static void +fs_handle_unexpected(FSFpePtr conn, fsGenericReply *rep) +{ + if (rep->type == FS_Event && rep->data1 == KeepAlive) + { + fsNoopReq req; + + /* ping it back */ + req.reqType = FS_Noop; + req.length = SIZEOF(fsNoopReq) >> 2; + _fs_add_req_log(conn, FS_Noop); + _fs_write(conn, (char *) &req, SIZEOF(fsNoopReq)); + } + /* this should suck up unexpected replies and events */ + _fs_done_read (conn, rep->length << 2); +} + +static void +fs_read_reply (FontPathElementPtr fpe, pointer client) +{ + FSFpePtr conn = (FSFpePtr) fpe->private; + FSBlockDataPtr blockrec; + int ret; + int err; + fsGenericReply *rep; + + if ((rep = fs_get_reply (conn, &ret))) + { + _fs_add_rep_log (conn, rep); + for (blockrec = conn->blockedRequests; + blockrec; + blockrec = blockrec->next) + { + if (blockrec->sequenceNumber == rep->sequenceNumber) + break; + } + err = Successful; + if (!blockrec) + { + fs_handle_unexpected(conn, rep); + } + else + { + /* + * go read it, and if we're done, + * wake up the appropriate client + */ + switch (blockrec->type) { + case FS_OPEN_FONT: + blockrec->errcode = fs_do_open_font(fpe, blockrec); + break; + case FS_LOAD_GLYPHS: + blockrec->errcode = fs_read_glyphs(fpe, blockrec); + break; + case FS_LIST_FONTS: + blockrec->errcode = fs_read_list(fpe, blockrec); + break; + case FS_LIST_WITH_INFO: + blockrec->errcode = fs_read_list_info(fpe, blockrec); + break; + default: + break; + } + err = blockrec->errcode; + if (err != StillWorking) + { + while (blockrec) + { + blockrec->errcode = err; + if (client != blockrec->client) + ClientSignal(blockrec->client); + blockrec = blockrec->depending; + } + _fs_unmark_block (conn, FS_PENDING_REPLY); + } + } + if (fs_reply_ready (conn)) + _fs_mark_block (conn, FS_COMPLETE_REPLY); + else + _fs_unmark_block (conn, FS_COMPLETE_REPLY); + } +} + +static int +fs_wakeup(FontPathElementPtr fpe, unsigned long *mask) +{ + fd_set *LastSelectMask = (fd_set *) mask; + FSFpePtr conn = (FSFpePtr) fpe->private; + + /* + * Don't continue if the fd is -1 (which will be true when the + * font server terminates + */ + if ((conn->blockState & FS_RECONNECTING)) + _fs_check_reconnect (conn); + else if ((conn->blockState & FS_COMPLETE_REPLY) || + (conn->fs_fd != -1 && FD_ISSET(conn->fs_fd, LastSelectMask))) + fs_read_reply (fpe, 0); + if (conn->blockState & (FS_PENDING_REPLY|FS_BROKEN_CONNECTION|FS_BROKEN_WRITE)) + _fs_do_blocked (conn); +#ifdef DEBUG + { + FSBlockDataPtr blockrec; + FSBlockedFontPtr bfont; + FSBlockedListPtr blist; + static CARD32 lastState; + static FSBlockDataPtr lastBlock; + + if (conn->blockState || conn->blockedRequests || lastState || lastBlock) + { + fprintf (stderr, " Block State 0x%x\n", (int) conn->blockState); + lastState = conn->blockState; + lastBlock = conn->blockedRequests; + } + for (blockrec = conn->blockedRequests; blockrec; blockrec = blockrec->next) + { + switch (blockrec->type) { + case FS_OPEN_FONT: + bfont = (FSBlockedFontPtr) blockrec->data; + fprintf (stderr, " Blocked font errcode %d sequence %d state %s %s\n", + blockrec->errcode, + blockrec->sequenceNumber, + fs_open_states[bfont->state], + bfont->pfont ? + ((FSFontDataPtr) (bfont->pfont->fpePrivate))->name : + "<freed>"); + break; + case FS_LIST_FONTS: + blist = (FSBlockedListPtr) blockrec->data; + fprintf (stderr, " Blocked list errcode %d sequence %d\n", + blockrec->errcode, blockrec->sequenceNumber); + break; + default: + fprintf (stderr, " Blocked type %d errcode %d sequence %d\n", + blockrec->type, + blockrec->errcode, + blockrec->sequenceNumber); + break; + } + } + } +#endif + return FALSE; +} + +/* + * Notice a dead connection and prepare for reconnect + */ + +void +_fs_connection_died(FSFpePtr conn) +{ + if (conn->blockState & FS_BROKEN_CONNECTION) + return; + fs_close_conn(conn); + conn->brokenConnectionTime = GetTimeInMillis (); + _fs_mark_block (conn, FS_BROKEN_CONNECTION); + _fs_unmark_block (conn, FS_BROKEN_WRITE|FS_PENDING_WRITE|FS_RECONNECTING); +} + +/* + * Signal clients that the connection has come back up + */ +static int +_fs_restart_connection(FSFpePtr conn) +{ + FSBlockDataPtr block; + + _fs_unmark_block (conn, FS_GIVE_UP); + while ((block = (FSBlockDataPtr) conn->blockedRequests)) + { + if (block->errcode == StillWorking) + { + ClientSignal(block->client); + fs_abort_blockrec(conn, block); + } + } + return TRUE; +} + +/* + * Declare this font server connection useless + */ +static void +_fs_giveup (FSFpePtr conn) +{ + FSBlockDataPtr block; + + if (conn->blockState & FS_GIVE_UP) + return; +#ifdef DEBUG + fprintf (stderr, "give up on FS \"%s\"\n", conn->servername); +#endif + _fs_mark_block (conn, FS_GIVE_UP); + while ((block = (FSBlockDataPtr) conn->blockedRequests)) + { + if (block->errcode == StillWorking) + { + ClientSignal (block->client); + fs_abort_blockrec (conn, block); + } + } + if (conn->fs_fd >= 0) + _fs_connection_died (conn); +} + +static void +_fs_do_blocked (FSFpePtr conn) +{ + CARD32 now; + + now = GetTimeInMillis (); + if ((conn->blockState & FS_PENDING_REPLY) && + TimeCmp (conn->blockedReplyTime, <=, now)) + { + _fs_giveup (conn); + } + else + { + if (conn->blockState & FS_BROKEN_CONNECTION) + { + /* Try to reconnect broken connections */ + if (TimeCmp (conn->brokenConnectionTime, <=, now)) + _fs_start_reconnect (conn); + } + else if (conn->blockState & FS_BROKEN_WRITE) + { + /* Try to flush blocked connections */ + if (TimeCmp (conn->brokenWriteTime, <=, now)) + _fs_flush (conn); + } + } +} + +/* + * sends the actual request out + */ +/* ARGSUSED */ +static int +fs_send_open_font(pointer client, FontPathElementPtr fpe, Mask flags, + char *name, int namelen, + fsBitmapFormat format, fsBitmapFormatMask fmask, + XID id, FontPtr *ppfont) +{ + FSFpePtr conn = (FSFpePtr) fpe->private; + FontPtr font; + FSBlockDataPtr blockrec = NULL; + FSBlockedFontPtr bfont; + FSFontDataPtr fsd; + fsOpenBitmapFontReq openreq; + fsQueryXInfoReq inforeq; + fsQueryXExtents16Req extreq; + int err; + unsigned char buf[1024]; + + if (conn->blockState & FS_GIVE_UP) + return BadFontName; + + if (namelen <= 0 || namelen > sizeof (buf) - 1) + return BadFontName; + + /* + * Get the font structure put together, either by reusing + * the existing one or creating a new one + */ + if (flags & FontReopen) + { + Atom nameatom, fn = None; + int i; + + font = *ppfont; + fsd = (FSFontDataPtr)font->fpePrivate; + /* This is an attempt to reopen a font. Did the font have a + NAME property? */ + if ((nameatom = MakeAtom("FONT", 4, 0)) != None) + { + for (i = 0; i < font->info.nprops; i++) + if (font->info.props[i].name == nameatom && + font->info.isStringProp[i]) + { + fn = font->info.props[i].value; + break; + } + } + if (fn == None || !(name = NameForAtom(fn))) + { + name = fsd->name; + namelen = fsd->namelen; + } + else + namelen = strlen(name); + } + else + { + font = fs_create_font (fpe, name, namelen, format, fmask); + if (!font) + return AllocError; + + fsd = (FSFontDataPtr)font->fpePrivate; + } + + /* make a new block record, and add it to the end of the list */ + blockrec = fs_new_block_rec(font->fpe, client, FS_OPEN_FONT); + if (!blockrec) + { + if (!(flags & FontReopen)) + (*font->unload_font) (font); + return AllocError; + } + + /* + * Must check this before generating any protocol, otherwise we'll + * mess up a reconnect in progress + */ + if (conn->blockState & (FS_BROKEN_CONNECTION | FS_RECONNECTING)) + { + _fs_pending_reply (conn); + return Suspended; + } + + fsd->generation = conn->generation; + + bfont = (FSBlockedFontPtr) blockrec->data; + bfont->fontid = fsd->fontid; + bfont->pfont = font; + bfont->state = FS_OPEN_REPLY; + bfont->flags = flags; + bfont->format = fsd->format; + bfont->clients_depending = (FSClientsDependingPtr)0; + bfont->freeFont = (flags & FontReopen) == 0; + + _fs_client_access (conn, client, (flags & FontOpenSync) != 0); + _fs_client_resolution(conn); + + /* do an FS_OpenFont, FS_QueryXInfo and FS_QueryXExtents */ + buf[0] = (unsigned char) namelen; + memcpy(&buf[1], name, namelen); + openreq.reqType = FS_OpenBitmapFont; + openreq.fid = fsd->fontid; + openreq.format_hint = fsd->format; + openreq.format_mask = fsd->fmask; + openreq.length = (SIZEOF(fsOpenBitmapFontReq) + namelen + 4) >> 2; + + _fs_add_req_log(conn, FS_OpenBitmapFont); + _fs_write(conn, (char *) &openreq, SIZEOF(fsOpenBitmapFontReq)); + _fs_write_pad(conn, (char *) buf, namelen + 1); + + blockrec->sequenceNumber = conn->current_seq; + + inforeq.reqType = FS_QueryXInfo; + inforeq.id = fsd->fontid; + inforeq.length = SIZEOF(fsQueryXInfoReq) >> 2; + + bfont->queryInfoSequence = conn->current_seq + 1; + + _fs_add_req_log(conn, FS_QueryXInfo); + _fs_write(conn, (char *) &inforeq, SIZEOF(fsQueryXInfoReq)); + + if (!(bfont->flags & FontReopen)) + { + extreq.reqType = FS_QueryXExtents16; + extreq.range = fsTrue; + extreq.fid = fsd->fontid; + extreq.num_ranges = 0; + extreq.length = SIZEOF(fsQueryXExtents16Req) >> 2; + + bfont->queryExtentsSequence = conn->current_seq + 1; + + _fs_add_req_log(conn, FS_QueryXExtents16); + _fs_write(conn, (char *) &extreq, SIZEOF(fsQueryXExtents16Req)); + } + +#ifdef NCD + if (configData.ExtendedFontDiags) + { + memcpy(buf, name, MIN(256, namelen)); + buf[MIN(256, namelen)] = '\0'; + printf("Requesting font \"%s\" from font server \"%s\"\n", + buf, font->fpe->name); + } +#endif + _fs_prepare_for_reply (conn); + + err = blockrec->errcode; + if (bfont->flags & FontOpenSync) + { + while (blockrec->errcode == StillWorking) + { + if (fs_await_reply (conn) != FSIO_READY) + { + blockrec->errcode = BadFontName; + break; + } + fs_read_reply (font->fpe, client); + } + err = blockrec->errcode; + if (err == Successful) + *ppfont = bfont->pfont; + else + fs_cleanup_bfont (bfont); + bfont->freeFont = FALSE; + _fs_remove_block_rec (conn, blockrec); + } + return err == StillWorking ? Suspended : err; +} + +static void +fs_send_query_bitmaps(FontPathElementPtr fpe, FSBlockDataPtr blockrec) +{ + FSFpePtr conn = (FSFpePtr) fpe->private; + FSBlockedFontPtr bfont = (FSBlockedFontPtr) blockrec->data; + fsQueryXBitmaps16Req bitreq; + + /* send the request */ + bitreq.reqType = FS_QueryXBitmaps16; + bitreq.fid = bfont->fontid; + bitreq.format = bfont->format; + bitreq.range = TRUE; + bitreq.length = SIZEOF(fsQueryXBitmaps16Req) >> 2; + bitreq.num_ranges = 0; + + bfont->queryBitmapsSequence = conn->current_seq + 1; + + _fs_add_req_log(conn, FS_QueryXBitmaps16); + _fs_write(conn, (char *) &bitreq, SIZEOF(fsQueryXBitmaps16Req)); +} + +/* ARGSUSED */ +static int +fs_open_font(pointer client, FontPathElementPtr fpe, Mask flags, + char *name, int namelen, + fsBitmapFormat format, fsBitmapFormatMask fmask, + XID id, FontPtr *ppfont, + char **alias, FontPtr non_cachable_font) +{ + FSFpePtr conn = (FSFpePtr) fpe->private; + FSBlockDataPtr blockrec; + FSBlockedFontPtr bfont; + int err; + + /* libfont interface expects ImageRectMin glyphs */ + format = (format & ~BitmapFormatImageRectMask) | BitmapFormatImageRectMin; + + *alias = (char *) 0; + for (blockrec = conn->blockedRequests; blockrec; blockrec = blockrec->next) + { + if (blockrec->type == FS_OPEN_FONT && blockrec->client == client) + { + err = blockrec->errcode; + if (err == StillWorking) + return Suspended; + + bfont = (FSBlockedFontPtr) blockrec->data; + if (err == Successful) + *ppfont = bfont->pfont; + else + fs_cleanup_bfont (bfont); + _fs_remove_block_rec (conn, blockrec); + return err; + } + } + return fs_send_open_font(client, fpe, flags, name, namelen, format, fmask, + id, ppfont); +} + +/* ARGSUSED */ +static int +fs_send_close_font(FontPathElementPtr fpe, Font id) +{ + FSFpePtr conn = (FSFpePtr) fpe->private; + fsCloseReq req; + + if (conn->blockState & FS_GIVE_UP) + return Successful; + /* tell the font server to close the font */ + req.reqType = FS_CloseFont; + req.length = SIZEOF(fsCloseReq) >> 2; + req.id = id; + _fs_add_req_log(conn, FS_CloseFont); + _fs_write(conn, (char *) &req, SIZEOF(fsCloseReq)); + + return Successful; +} + +/* ARGSUSED */ +static void +fs_close_font(FontPathElementPtr fpe, FontPtr pfont) +{ + FSFontDataPtr fsd = (FSFontDataPtr) pfont->fpePrivate; + FSFpePtr conn = (FSFpePtr) fpe->private; + + if (conn->generation == fsd->generation) + fs_send_close_font(fpe, fsd->fontid); + +#ifdef DEBUG + { + FSBlockDataPtr blockrec; + FSBlockedFontPtr bfont; + + for (blockrec = conn->blockedRequests; blockrec; blockrec = blockrec->next) + { + if (blockrec->type == FS_OPEN_FONT) + { + bfont = (FSBlockedFontPtr) blockrec->data; + if (bfont->pfont == pfont) + fprintf (stderr, "closing font which hasn't been opened\n"); + } + } + } +#endif + (*pfont->unload_font) (pfont); +} + +static int +fs_read_glyphs(FontPathElementPtr fpe, FSBlockDataPtr blockrec) +{ + FSBlockedGlyphPtr bglyph = (FSBlockedGlyphPtr) blockrec->data; + FSBlockedFontPtr bfont = (FSBlockedFontPtr) blockrec->data; + FSFpePtr conn = (FSFpePtr) fpe->private; + FontPtr pfont = bglyph->pfont; + /* works for either blocked font + or glyph rec... pfont is at + the very beginning of both + blockrec->data structures */ + FSFontDataPtr fsd = (FSFontDataPtr) (pfont->fpePrivate); + FSFontPtr fsdata = (FSFontPtr) pfont->fontPrivate; + FontInfoPtr pfi = &pfont->info; + fsQueryXBitmaps16Reply *rep; + char *buf; + fsOffset32 *ppbits; + fsOffset32 local_off; + char *off_adr; + pointer pbitmaps; + char *bits, *allbits; +#ifdef DEBUG + char *origallbits; +#endif + int i, + err; + int nranges = 0; + int ret; + fsRange *nextrange = 0; + unsigned long minchar, maxchar; + + rep = (fsQueryXBitmaps16Reply *) fs_get_reply (conn, &ret); + if (!rep || rep->type == FS_Error) + { + if (ret == FSIO_BLOCK) + return StillWorking; + if (rep) + _fs_done_read (conn, rep->length << 2); + err = AllocError; + goto bail; + } + + buf = (char *) rep; + buf += SIZEOF (fsQueryXBitmaps16Reply); + + ppbits = (fsOffset32 *) buf; + buf += SIZEOF (fsOffset32) * (rep->num_chars); + + pbitmaps = (pointer ) buf; + + if (blockrec->type == FS_LOAD_GLYPHS) + { + nranges = bglyph->num_expected_ranges; + nextrange = bglyph->expected_ranges; + } + + /* place the incoming glyphs */ + if (nranges) + { + /* We're operating under the assumption that the ranges + requested in the LoadGlyphs call were all legal for this + font, and that individual ranges do not cover multiple + rows... fs_build_range() is designed to ensure this. */ + minchar = (nextrange->min_char_high - pfi->firstRow) * + (pfi->lastCol - pfi->firstCol + 1) + + nextrange->min_char_low - pfi->firstCol; + maxchar = (nextrange->max_char_high - pfi->firstRow) * + (pfi->lastCol - pfi->firstCol + 1) + + nextrange->max_char_low - pfi->firstCol; + nextrange++; + } + else + { + minchar = 0; + maxchar = rep->num_chars; + } + + off_adr = (char *)ppbits; + + allbits = fs_alloc_glyphs (pfont, rep->nbytes); + + if (!allbits) + { + err = AllocError; + goto bail; + } + +#ifdef DEBUG + origallbits = allbits; + fprintf (stderr, "Reading %d glyphs in %d bytes for %s\n", + (int) rep->num_chars, (int) rep->nbytes, fsd->name); +#endif + + for (i = 0; i < rep->num_chars; i++) + { + memcpy(&local_off, off_adr, SIZEOF(fsOffset32)); /* align it */ + if (blockrec->type == FS_OPEN_FONT || + fsdata->encoding[minchar].bits == &_fs_glyph_requested) + { + /* + * Broken X font server returns bits for missing characters + * when font is padded + */ + if (NONZEROMETRICS(&fsdata->encoding[minchar].metrics)) + { + if (local_off.length) + { + bits = allbits; + allbits += local_off.length; + memcpy(bits, (char *)pbitmaps + local_off.position, + local_off.length); + } + else + bits = &_fs_glyph_zero_length; + } + else + bits = 0; + if (fsdata->encoding[minchar].bits == &_fs_glyph_requested) + fsd->glyphs_to_get--; + fsdata->encoding[minchar].bits = bits; + } + if (minchar++ == maxchar) + { + if (!--nranges) break; + minchar = (nextrange->min_char_high - pfi->firstRow) * + (pfi->lastCol - pfi->firstCol + 1) + + nextrange->min_char_low - pfi->firstCol; + maxchar = (nextrange->max_char_high - pfi->firstRow) * + (pfi->lastCol - pfi->firstCol + 1) + + nextrange->max_char_low - pfi->firstCol; + nextrange++; + } + off_adr += SIZEOF(fsOffset32); + } +#ifdef DEBUG + fprintf (stderr, "Used %d bytes instead of %d\n", + (int) (allbits - origallbits), (int) rep->nbytes); +#endif + + if (blockrec->type == FS_OPEN_FONT) + { + fsd->glyphs_to_get = 0; + bfont->state = FS_DONE_REPLY; + } + err = Successful; + +bail: + _fs_done_read (conn, rep->length << 2); + return err; +} + +static int +fs_send_load_glyphs(pointer client, FontPtr pfont, + int nranges, fsRange *ranges) +{ + FontPathElementPtr fpe = pfont->fpe; + FSFpePtr conn = (FSFpePtr) fpe->private; + FSBlockedGlyphPtr blockedglyph; + fsQueryXBitmaps16Req req; + FSBlockDataPtr blockrec; + + if (conn->blockState & FS_GIVE_UP) + return BadCharRange; + + /* make a new block record, and add it to the end of the list */ + blockrec = fs_new_block_rec(fpe, client, FS_LOAD_GLYPHS); + if (!blockrec) + return AllocError; + blockedglyph = (FSBlockedGlyphPtr) blockrec->data; + blockedglyph->pfont = pfont; + blockedglyph->num_expected_ranges = nranges; + /* Assumption: it's our job to free ranges */ + blockedglyph->expected_ranges = ranges; + blockedglyph->clients_depending = (FSClientsDependingPtr)0; + + if (conn->blockState & (FS_BROKEN_CONNECTION|FS_RECONNECTING)) + { + _fs_pending_reply (conn); + return Suspended; + } + + /* send the request */ + req.reqType = FS_QueryXBitmaps16; + req.fid = ((FSFontDataPtr) pfont->fpePrivate)->fontid; + req.format = pfont->format; + if (pfont->info.terminalFont) + req.format = (req.format & ~(BitmapFormatImageRectMask)) | + BitmapFormatImageRectMax; + req.range = TRUE; + /* each range takes up 4 bytes */ + req.length = (SIZEOF(fsQueryXBitmaps16Req) >> 2) + nranges; + req.num_ranges = nranges * 2; /* protocol wants count of fsChar2bs */ + _fs_add_req_log(conn, FS_QueryXBitmaps16); + _fs_write(conn, (char *) &req, SIZEOF(fsQueryXBitmaps16Req)); + + blockrec->sequenceNumber = conn->current_seq; + + /* Send ranges to the server... pack into a char array by hand + to avoid structure-packing portability problems and to + handle swapping for version1 protocol */ + if (nranges) + { +#define RANGE_BUFFER_SIZE 64 +#define RANGE_BUFFER_SIZE_MASK 63 + int i; + char range_buffer[RANGE_BUFFER_SIZE * 4]; + char *range_buffer_p; + + range_buffer_p = range_buffer; + for (i = 0; i < nranges;) + { + if (conn->fsMajorVersion > 1) + { + *range_buffer_p++ = ranges[i].min_char_high; + *range_buffer_p++ = ranges[i].min_char_low; + *range_buffer_p++ = ranges[i].max_char_high; + *range_buffer_p++ = ranges[i].max_char_low; + } + else + { + *range_buffer_p++ = ranges[i].min_char_low; + *range_buffer_p++ = ranges[i].min_char_high; + *range_buffer_p++ = ranges[i].max_char_low; + *range_buffer_p++ = ranges[i].max_char_high; + } + + if (!(++i & RANGE_BUFFER_SIZE_MASK)) + { + _fs_write(conn, range_buffer, RANGE_BUFFER_SIZE * 4); + range_buffer_p = range_buffer; + } + } + if (i &= RANGE_BUFFER_SIZE_MASK) + _fs_write(conn, range_buffer, i * 4); + } + + _fs_prepare_for_reply (conn); + return Suspended; +} + + +extern pointer serverClient; /* This could be any number that + doesn't conflict with existing + client values. */ + +int +fs_load_all_glyphs(FontPtr pfont) +{ + int err; + FSFpePtr conn = (FSFpePtr) pfont->fpe->private; + + /* + * The purpose of this procedure is to load all glyphs in the event + * that we're dealing with someone who doesn't understand the finer + * points of glyph caching... it is called from _fs_get_glyphs() if + * the latter is called to get glyphs that have not yet been loaded. + * We assume that the caller will not know how to handle a return + * value of Suspended (usually the case for a GetGlyphs() caller), + * so this procedure hangs around, freezing the server, for the + * request to complete. This is an unpleasant kluge called to + * perform an unpleasant job that, we hope, will never be required. + */ + + while ((err = _fs_load_glyphs(serverClient, pfont, TRUE, 0, 0, NULL)) == + Suspended) + { + if (fs_await_reply (conn) != FSIO_READY) + { + /* Get rid of blockrec */ + fs_client_died(serverClient, pfont->fpe); + err = BadCharRange; + break; + } + fs_read_reply (pfont->fpe, serverClient); + } + return err; +} + + +int +_fs_load_glyphs(pointer client, FontPtr pfont, Bool range_flag, + unsigned int nchars, int item_size, unsigned char *data) +{ + FSFpePtr conn = (FSFpePtr) pfont->fpe->private; + int nranges = 0; + fsRange *ranges = NULL; + int res; + FSBlockDataPtr blockrec; + FSBlockedGlyphPtr blockedglyph; + FSClientsDependingPtr *clients_depending = NULL; + int err; + + /* see if the result is already there */ + for (blockrec = conn->blockedRequests; blockrec; blockrec = blockrec->next) + { + if (blockrec->type == FS_LOAD_GLYPHS) + { + blockedglyph = (FSBlockedGlyphPtr) blockrec->data; + if (blockedglyph->pfont == pfont) + { + /* Look for this request */ + if (blockrec->client == client) + { + err = blockrec->errcode; + if (err == StillWorking) + return Suspended; + _fs_signal_clients_depending(&blockedglyph->clients_depending); + _fs_remove_block_rec(conn, blockrec); + return err; + } + /* We've found an existing LoadGlyphs blockrec for this + font but for another client. Rather than build a + blockrec for it now (which entails some complex + maintenance), we'll add it to a queue of clients to + be signalled when the existing LoadGlyphs is + completed. */ + clients_depending = &blockedglyph->clients_depending; + break; + } + } + else if (blockrec->type == FS_OPEN_FONT) + { + FSBlockedFontPtr bfont; + bfont = (FSBlockedFontPtr) blockrec->data; + if (bfont->pfont == pfont) + { + /* + * An OpenFont is pending for this font, this must + * be from a reopen attempt, so finish the open + * attempt and retry the LoadGlyphs + */ + if (blockrec->client == client) + { + err = blockrec->errcode; + if (err == StillWorking) + return Suspended; + + _fs_signal_clients_depending(&bfont->clients_depending); + _fs_remove_block_rec(conn, blockrec); + if (err != Successful) + return err; + break; + } + /* We've found an existing OpenFont blockrec for this + font but for another client. Rather than build a + blockrec for it now (which entails some complex + maintenance), we'll add it to a queue of clients to + be signalled when the existing OpenFont is + completed. */ + if (blockrec->errcode == StillWorking) + { + clients_depending = &bfont->clients_depending; + break; + } + } + } + } + + /* + * see if the desired glyphs already exist, and return Successful if they + * do, otherwise build up character range/character string + */ + res = fs_build_range(pfont, range_flag, nchars, item_size, data, + &nranges, &ranges); + + switch (res) + { + case AccessDone: + return Successful; + + case Successful: + break; + + default: + return res; + } + + /* + * If clients_depending is not null, this request must wait for + * some prior request(s) to complete. + */ + if (clients_depending) + { + /* Since we're not ready to send the load_glyphs request yet, + clean up the damage (if any) caused by the fs_build_range() + call. */ + if (nranges) + { + _fs_clean_aborted_loadglyphs(pfont, nranges, ranges); + xfree(ranges); + } + return _fs_add_clients_depending(clients_depending, client); + } + + /* + * If fsd->generation != conn->generation, the font has been closed + * due to a lost connection. We will reopen it, which will result + * in one of three things happening: + * 1) The open will succeed and obtain the same font. Life + * is wonderful. + * 2) The open will fail. There is code above to recognize this + * and flunk the LoadGlyphs request. The client might not be + * thrilled. + * 3) Worst case: the open will succeed but the font we open will + * be different. The fs_read_query_info() procedure attempts + * to detect this by comparing the existing metrics and + * properties against those of the reopened font... if they + * don't match, we flunk the reopen, which eventually results + * in flunking the LoadGlyphs request. We could go a step + * further and compare the extents, but this should be + * sufficient. + */ + if (((FSFontDataPtr)pfont->fpePrivate)->generation != conn->generation) + { + /* Since we're not ready to send the load_glyphs request yet, + clean up the damage caused by the fs_build_range() call. */ + _fs_clean_aborted_loadglyphs(pfont, nranges, ranges); + xfree(ranges); + + /* Now try to reopen the font. */ + return fs_send_open_font(client, pfont->fpe, + (Mask)FontReopen, (char *)0, 0, + (fsBitmapFormat)0, (fsBitmapFormatMask)0, + (XID)0, &pfont); + } + + return fs_send_load_glyphs(client, pfont, nranges, ranges); +} + +static int +fs_read_list(FontPathElementPtr fpe, FSBlockDataPtr blockrec) +{ + FSFpePtr conn = (FSFpePtr) fpe->private; + FSBlockedListPtr blist = (FSBlockedListPtr) blockrec->data; + fsListFontsReply *rep; + char *data; + int length, + i, + ret; + int err; + + rep = (fsListFontsReply *) fs_get_reply (conn, &ret); + if (!rep || rep->type == FS_Error) + { + if (ret == FSIO_BLOCK) + return StillWorking; + if (rep) + _fs_done_read (conn, rep->length << 2); + return AllocError; + } + data = (char *) rep + SIZEOF (fsListFontsReply); + + err = Successful; + /* copy data into FontPathRecord */ + for (i = 0; i < rep->nFonts; i++) + { + length = *(unsigned char *)data++; + err = AddFontNamesName(blist->names, data, length); + if (err != Successful) + break; + data += length; + } + _fs_done_read (conn, rep->length << 2); + return err; +} + +static int +fs_send_list_fonts(pointer client, FontPathElementPtr fpe, char *pattern, + int patlen, int maxnames, FontNamesPtr newnames) +{ + FSFpePtr conn = (FSFpePtr) fpe->private; + FSBlockDataPtr blockrec; + FSBlockedListPtr blockedlist; + fsListFontsReq req; + + if (conn->blockState & FS_GIVE_UP) + return BadFontName; + + /* make a new block record, and add it to the end of the list */ + blockrec = fs_new_block_rec(fpe, client, FS_LIST_FONTS); + if (!blockrec) + return AllocError; + blockedlist = (FSBlockedListPtr) blockrec->data; + blockedlist->names = newnames; + + if (conn->blockState & (FS_BROKEN_CONNECTION | FS_RECONNECTING)) + { + _fs_pending_reply (conn); + return Suspended; + } + + _fs_client_access (conn, client, FALSE); + _fs_client_resolution(conn); + + /* send the request */ + req.reqType = FS_ListFonts; + req.maxNames = maxnames; + req.nbytes = patlen; + req.length = (SIZEOF(fsListFontsReq) + patlen + 3) >> 2; + _fs_add_req_log(conn, FS_ListFonts); + _fs_write(conn, (char *) &req, SIZEOF(fsListFontsReq)); + _fs_write_pad(conn, (char *) pattern, patlen); + + blockrec->sequenceNumber = conn->current_seq; + +#ifdef NCD + if (configData.ExtendedFontDiags) { + char buf[256]; + + memcpy(buf, pattern, MIN(256, patlen)); + buf[MIN(256, patlen)] = '\0'; + printf("Listing fonts on pattern \"%s\" from font server \"%s\"\n", + buf, fpe->name); + } +#endif + + _fs_prepare_for_reply (conn); + return Suspended; +} + +static int +fs_list_fonts(pointer client, FontPathElementPtr fpe, + char *pattern, int patlen, int maxnames, FontNamesPtr newnames) +{ + FSFpePtr conn = (FSFpePtr) fpe->private; + FSBlockDataPtr blockrec; + int err; + + /* see if the result is already there */ + for (blockrec = conn->blockedRequests; blockrec; blockrec = blockrec->next) + { + if (blockrec->type == FS_LIST_FONTS && blockrec->client == client) + { + err = blockrec->errcode; + if (err == StillWorking) + return Suspended; + _fs_remove_block_rec(conn, blockrec); + return err; + } + } + + /* didn't find waiting record, so send a new one */ + return fs_send_list_fonts(client, fpe, pattern, patlen, maxnames, newnames); +} + +/* + * Read a single list info reply and restart for the next reply + */ +static int +fs_read_list_info(FontPathElementPtr fpe, FSBlockDataPtr blockrec) +{ + FSBlockedListInfoPtr binfo = (FSBlockedListInfoPtr) blockrec->data; + fsListFontsWithXInfoReply *rep; + char *buf; + FSFpePtr conn = (FSFpePtr) fpe->private; + fsPropInfo *pi; + fsPropOffset *po; + pointer pd; + int ret; + int err; + + /* clean up anything from the last trip */ + _fs_free_props (&binfo->info); + + rep = (fsListFontsWithXInfoReply *) fs_get_reply (conn, &ret); + if (rep == 0) + { + if (ret == FSIO_BLOCK) + return StillWorking; + binfo->status = FS_LFWI_FINISHED; + err = AllocError; + goto done; + } + /* + * Normal termination -- the list ends with a name of length 0 + */ + if (rep->nameLength == 0) + { +#ifdef DEBUG + fprintf (stderr, "fs_read_list_info done\n"); +#endif + binfo->status = FS_LFWI_FINISHED; + err = BadFontName; + goto done; + } + + buf = (char *) rep + SIZEOF (fsListFontsWithXInfoReply); + + /* + * The original FS implementation didn't match + * the spec, version 1 was respecified to match the FS. + * Version 2 matches the original intent + */ + if (conn->fsMajorVersion <= 1) + { + memcpy (binfo->name, buf, rep->nameLength); + buf += _fs_pad_length (rep->nameLength); + } + pi = (fsPropInfo *) buf; + buf += SIZEOF (fsPropInfo); + po = (fsPropOffset *) buf; + buf += pi->num_offsets * SIZEOF (fsPropOffset); + pd = (pointer) buf; + buf += pi->data_len; + if (conn->fsMajorVersion > 1) + { + memcpy (binfo->name, buf, rep->nameLength); + buf += _fs_pad_length (rep->nameLength); + } + +#ifdef DEBUG + binfo->name[rep->nameLength] = '\0'; + fprintf (stderr, "fs_read_list_info %s\n", binfo->name); +#endif + err = _fs_convert_lfwi_reply(conn, &binfo->info, rep, pi, po, pd); + if (err != Successful) + { + binfo->status = FS_LFWI_FINISHED; + goto done; + } + binfo->namelen = rep->nameLength; + binfo->remaining = rep->nReplies; + + binfo->status = FS_LFWI_REPLY; + + /* disable this font server until we've processed this response */ + _fs_unmark_block (conn, FS_COMPLETE_REPLY); + FD_CLR(conn->fs_fd, &_fs_fd_mask); +done: + _fs_done_read (conn, rep->length << 2); + return err; +} + +/* ARGSUSED */ +static int +fs_start_list_with_info(pointer client, FontPathElementPtr fpe, + char *pattern, int len, int maxnames, pointer *pdata) +{ + FSFpePtr conn = (FSFpePtr) fpe->private; + FSBlockDataPtr blockrec; + FSBlockedListInfoPtr binfo; + fsListFontsWithXInfoReq req; + + if (conn->blockState & FS_GIVE_UP) + return BadFontName; + + /* make a new block record, and add it to the end of the list */ + blockrec = fs_new_block_rec(fpe, client, FS_LIST_WITH_INFO); + if (!blockrec) + return AllocError; + + binfo = (FSBlockedListInfoPtr) blockrec->data; + bzero((char *) binfo, sizeof(FSBlockedListInfoRec)); + binfo->status = FS_LFWI_WAITING; + + if (conn->blockState & (FS_BROKEN_CONNECTION | FS_RECONNECTING)) + { + _fs_pending_reply (conn); + return Suspended; + } + + _fs_client_access (conn, client, FALSE); + _fs_client_resolution(conn); + + /* send the request */ + req.reqType = FS_ListFontsWithXInfo; + req.maxNames = maxnames; + req.nbytes = len; + req.length = (SIZEOF(fsListFontsWithXInfoReq) + len + 3) >> 2; + _fs_add_req_log(conn, FS_ListFontsWithXInfo); + (void) _fs_write(conn, (char *) &req, SIZEOF(fsListFontsWithXInfoReq)); + (void) _fs_write_pad(conn, pattern, len); + + blockrec->sequenceNumber = conn->current_seq; + +#ifdef NCD + if (configData.ExtendedFontDiags) { + char buf[256]; + + memcpy(buf, pattern, MIN(256, len)); + buf[MIN(256, len)] = '\0'; + printf("Listing fonts with info on pattern \"%s\" from font server \"%s\"\n", + buf, fpe->name); + } +#endif + + _fs_prepare_for_reply (conn); + return Successful; +} + +/* ARGSUSED */ +static int +fs_next_list_with_info(pointer client, FontPathElementPtr fpe, + char **namep, int *namelenp, + FontInfoPtr *pFontInfo, int *numFonts, + pointer private) +{ + FSFpePtr conn = (FSFpePtr) fpe->private; + FSBlockDataPtr blockrec; + FSBlockedListInfoPtr binfo; + int err; + + /* see if the result is already there */ + for (blockrec = conn->blockedRequests; blockrec; blockrec = blockrec->next) + if (blockrec->type == FS_LIST_WITH_INFO && blockrec->client == client) + break; + + if (!blockrec) + { + /* The only good reason for not finding a blockrec would be if + disconnect/reconnect to the font server wiped it out and the + code that called us didn't do the right thing to create + another one. Under those circumstances, we need to return an + error to prevent that code from attempting to interpret the + information we don't return. */ + return BadFontName; + } + + binfo = (FSBlockedListInfoPtr) blockrec->data; + + if (binfo->status == FS_LFWI_WAITING) + return Suspended; + + *namep = binfo->name; + *namelenp = binfo->namelen; + *pFontInfo = &binfo->info; + *numFonts = binfo->remaining; + + /* Restart reply processing from this font server */ + FD_SET(conn->fs_fd, &_fs_fd_mask); + if (fs_reply_ready (conn)) + _fs_mark_block (conn, FS_COMPLETE_REPLY); + + err = blockrec->errcode; + switch (binfo->status) { + case FS_LFWI_FINISHED: + _fs_remove_block_rec(conn, blockrec); + break; + case FS_LFWI_REPLY: + binfo->status = FS_LFWI_WAITING; + blockrec->errcode = StillWorking; + conn->blockedReplyTime = GetTimeInMillis () + FontServerRequestTimeout; + _fs_mark_block (conn, FS_PENDING_REPLY); + break; + } + + return err; +} + +/* + * Called when client exits + */ + +static void +fs_client_died(pointer client, FontPathElementPtr fpe) +{ + FSFpePtr conn = (FSFpePtr) fpe->private; + FSBlockDataPtr blockrec, + depending; + FSClientPtr *prev, cur; + fsFreeACReq freeac; + + for (prev = &conn->clients; (cur = *prev); prev = &cur->next) + { + if (cur->client == client) { + freeac.reqType = FS_FreeAC; + freeac.id = cur->acid; + freeac.length = sizeof (fsFreeACReq) >> 2; + _fs_add_req_log(conn, FS_FreeAC); + _fs_write (conn, (char *) &freeac, sizeof (fsFreeACReq)); + *prev = cur->next; + xfree (cur); + break; + } + } + /* find a pending requests */ + for (blockrec = conn->blockedRequests; blockrec; blockrec = blockrec->next) + if (blockrec->client == client) + break; + + if (!blockrec) + return; + + /* replace the client pointers in this block rec with the chained one */ + if ((depending = blockrec->depending)) + { + blockrec->client = depending->client; + blockrec->depending = depending->depending; + blockrec = depending; + } + fs_abort_blockrec(conn, blockrec); +} + +static void +_fs_client_access (FSFpePtr conn, pointer client, Bool sync) +{ + FSClientPtr *prev, cur; + fsCreateACReq crac; + fsSetAuthorizationReq setac; + char *authorizations; + int authlen; + Bool new_cur = FALSE; + +#ifdef DEBUG + if (conn->blockState & (FS_RECONNECTING|FS_BROKEN_CONNECTION)) + { + fprintf (stderr, "Sending requests without a connection\n"); + } +#endif + for (prev = &conn->clients; (cur = *prev); prev = &cur->next) + { + if (cur->client == client) + { + if (prev != &conn->clients) + { + *prev = cur->next; + cur->next = conn->clients; + conn->clients = cur; + } + break; + } + } + if (!cur) + { + cur = (FSClientPtr) xalloc (sizeof (FSClientRec)); + if (!cur) + return; + cur->client = client; + cur->next = conn->clients; + conn->clients = cur; + cur->acid = GetNewFontClientID (); + new_cur = TRUE; + } + if (new_cur || cur->auth_generation != client_auth_generation(client)) + { + if (!new_cur) + { + fsFreeACReq freeac; + freeac.reqType = FS_FreeAC; + freeac.id = cur->acid; + freeac.length = sizeof (fsFreeACReq) >> 2; + _fs_add_req_log(conn, FS_FreeAC); + _fs_write (conn, (char *) &freeac, sizeof (fsFreeACReq)); + } + crac.reqType = FS_CreateAC; + crac.num_auths = set_font_authorizations(&authorizations, &authlen, + client); + authlen = crac.num_auths ? (authlen + 3) & ~0x3 : 0; + crac.length = (sizeof (fsCreateACReq) + authlen) >> 2; + crac.acid = cur->acid; + _fs_add_req_log(conn, FS_CreateAC); + _fs_write(conn, (char *) &crac, sizeof (fsCreateACReq)); + _fs_write(conn, authorizations, authlen); + /* ignore reply; we don't even care about it */ + conn->curacid = 0; + cur->auth_generation = client_auth_generation(client); + } + if (conn->curacid != cur->acid) + { + setac.reqType = FS_SetAuthorization; + setac.length = sizeof (fsSetAuthorizationReq) >> 2; + setac.id = cur->acid; + _fs_add_req_log(conn, FS_SetAuthorization); + _fs_write(conn, (char *) &setac, sizeof (fsSetAuthorizationReq)); + conn->curacid = cur->acid; + } +} + +/* + * Poll a pending connect + */ + +static int +_fs_check_connect (FSFpePtr conn) +{ + int ret; + + ret = _fs_poll_connect (conn->trans_conn, 0); + switch (ret) { + case FSIO_READY: + conn->fs_fd = _FontTransGetConnectionNumber (conn->trans_conn); + FD_SET (conn->fs_fd, &_fs_fd_mask); + break; + case FSIO_BLOCK: + break; + } + return ret; +} + +/* + * Return an FSIO status while waiting for the completed connection + * reply to arrive + */ + +static fsConnSetup * +_fs_get_conn_setup (FSFpePtr conn, int *error, int *setup_len) +{ + int ret; + char *data; + int headlen; + int len; + fsConnSetup *setup; + fsConnSetupAccept *accept; + + ret = _fs_start_read (conn, SIZEOF (fsConnSetup), &data); + if (ret != FSIO_READY) + { + *error = ret; + return 0; + } + + setup = (fsConnSetup *) data; + if (setup->major_version > FS_PROTOCOL) + { + *error = FSIO_ERROR; + return 0; + } + + headlen = (SIZEOF (fsConnSetup) + + (setup->alternate_len << 2) + + (setup->auth_len << 2)); + /* On anything but Success, no extra data is sent */ + if (setup->status != AuthSuccess) + { + len = headlen; + } + else + { + ret = _fs_start_read (conn, headlen + SIZEOF (fsConnSetupAccept), &data); + if (ret != FSIO_READY) + { + *error = ret; + return 0; + } + setup = (fsConnSetup *) data; + accept = (fsConnSetupAccept *) (data + headlen); + len = headlen + (accept->length << 2); + } + ret = _fs_start_read (conn, len, &data); + if (ret != FSIO_READY) + { + *error = ret; + return 0; + } + *setup_len = len; + return (fsConnSetup *) data; +} + +static int +_fs_send_conn_client_prefix (FSFpePtr conn) +{ + fsConnClientPrefix req; + int endian; + int ret; + + /* send setup prefix */ + endian = 1; + if (*(char *) &endian) + req.byteOrder = 'l'; + else + req.byteOrder = 'B'; + + req.major_version = FS_PROTOCOL; + req.minor_version = FS_PROTOCOL_MINOR; + +/* XXX add some auth info here */ + req.num_auths = 0; + req.auth_len = 0; + ret = _fs_write (conn, (char *) &req, SIZEOF (fsConnClientPrefix)); + if (ret != FSIO_READY) + return FSIO_ERROR; + conn->blockedConnectTime = GetTimeInMillis () + FontServerRequestTimeout; + return ret; +} + +static int +_fs_recv_conn_setup (FSFpePtr conn) +{ + int ret; + fsConnSetup *setup; + FSFpeAltPtr alts; + int i, alt_len; + int setup_len; + char *alt_save, *alt_names; + + setup = _fs_get_conn_setup (conn, &ret, &setup_len); + if (!setup) + return ret; + conn->current_seq = 0; + conn->fsMajorVersion = setup->major_version; + /* + * Create an alternate list from the initial server, but + * don't chain looking for alternates. + */ + if (conn->alternate == 0) + { + /* + * free any existing alternates list, allowing the list to + * be updated + */ + if (conn->alts) + { + xfree (conn->alts); + conn->alts = 0; + conn->numAlts = 0; + } + if (setup->num_alternates) + { + alts = (FSFpeAltPtr) xalloc (setup->num_alternates * + sizeof (FSFpeAltRec) + + (setup->alternate_len << 2)); + if (alts) + { + alt_names = (char *) (setup + 1); + alt_save = (char *) (alts + setup->num_alternates); + for (i = 0; i < setup->num_alternates; i++) + { + alts[i].subset = alt_names[0]; + alt_len = alt_names[1]; + alts[i].name = alt_save; + memcpy (alt_save, alt_names + 2, alt_len); + alt_save[alt_len] = '\0'; + alt_save += alt_len + 1; + alt_names += _fs_pad_length (alt_len + 2); + } + conn->numAlts = setup->num_alternates; + conn->alts = alts; + } + } + } + _fs_done_read (conn, setup_len); + if (setup->status != AuthSuccess) + return FSIO_ERROR; + return FSIO_READY; +} + +static int +_fs_open_server (FSFpePtr conn) +{ + int ret; + char *servername; + + if (conn->alternate == 0) + servername = conn->servername; + else + servername = conn->alts[conn->alternate-1].name; + conn->trans_conn = _fs_connect (servername, &ret); + conn->blockedConnectTime = GetTimeInMillis () + FS_RECONNECT_WAIT; + return ret; +} + +static char * +_fs_catalog_name (char *servername) +{ + char *sp; + + sp = strchr (servername, '/'); + if (!sp) + return 0; + return strrchr (sp + 1, '/'); +} + +static int +_fs_send_init_packets (FSFpePtr conn) +{ + fsSetResolutionReq srreq; + fsSetCataloguesReq screq; + int num_cats, + clen; + char *catalogues; + char *cat; + char len; + char *end; + int num_res; + FontResolutionPtr res; + +#define CATALOGUE_SEP '+' + + res = GetClientResolutions(&num_res); + if (num_res) + { + srreq.reqType = FS_SetResolution; + srreq.num_resolutions = num_res; + srreq.length = (SIZEOF(fsSetResolutionReq) + + (num_res * SIZEOF(fsResolution)) + 3) >> 2; + + _fs_add_req_log(conn, FS_SetResolution); + if (_fs_write(conn, (char *) &srreq, SIZEOF(fsSetResolutionReq)) != FSIO_READY) + return FSIO_ERROR; + if (_fs_write_pad(conn, (char *) res, (num_res * SIZEOF(fsResolution))) != FSIO_READY) + return FSIO_ERROR; + } + + catalogues = 0; + if (conn->alternate != 0) + catalogues = _fs_catalog_name (conn->alts[conn->alternate-1].name); + if (!catalogues) + catalogues = _fs_catalog_name (conn->servername); + + if (!catalogues) + { + conn->has_catalogues = FALSE; + return FSIO_READY; + } + conn->has_catalogues = TRUE; + + /* turn cats into counted list */ + catalogues++; + + cat = catalogues; + num_cats = 0; + clen = 0; + while (*cat) + { + num_cats++; + end = strchr(cat, CATALOGUE_SEP); + if (!end) + end = cat + strlen (cat); + clen += (end - cat) + 1; /* length byte + string */ + cat = end; + } + + screq.reqType = FS_SetCatalogues; + screq.num_catalogues = num_cats; + screq.length = (SIZEOF(fsSetCataloguesReq) + clen + 3) >> 2; + + _fs_add_req_log(conn, FS_SetCatalogues); + if (_fs_write(conn, (char *) &screq, SIZEOF(fsSetCataloguesReq)) != FSIO_READY) + return FSIO_ERROR; + + while (*cat) + { + num_cats++; + end = strchr(cat, CATALOGUE_SEP); + if (!end) + end = cat + strlen (cat); + len = end - cat; + if (_fs_write (conn, &len, 1) != FSIO_READY) + return FSIO_ERROR; + if (_fs_write (conn, cat, (int) len) != FSIO_READY) + return FSIO_ERROR; + cat = end; + } + + if (_fs_write (conn, "....", _fs_pad_length (clen) - clen) != FSIO_READY) + return FSIO_ERROR; + + return FSIO_READY; +} + +static int +_fs_send_cat_sync (FSFpePtr conn) +{ + fsListCataloguesReq lcreq; + + /* + * now sync up with the font server, to see if an error was generated + * by a bogus catalogue + */ + lcreq.reqType = FS_ListCatalogues; + lcreq.length = (SIZEOF(fsListCataloguesReq)) >> 2; + lcreq.maxNames = 0; + lcreq.nbytes = 0; + _fs_add_req_log(conn, FS_SetCatalogues); + if (_fs_write(conn, (char *) &lcreq, SIZEOF(fsListCataloguesReq)) != FSIO_READY) + return FSIO_ERROR; + conn->blockedConnectTime = GetTimeInMillis () + FontServerRequestTimeout; + return FSIO_READY; +} + +static int +_fs_recv_cat_sync (FSFpePtr conn) +{ + fsGenericReply *reply; + fsError *error; + int err; + int ret; + + reply = fs_get_reply (conn, &err); + if (!reply) + return err; + + ret = FSIO_READY; + if (reply->type == FS_Error) + { + error = (fsError *) reply; + if (error->major_opcode == FS_SetCatalogues) + ret = FSIO_ERROR; + } + _fs_done_read (conn, reply->length << 2); + return ret; +} + +static void +_fs_close_server (FSFpePtr conn) +{ + _fs_unmark_block (conn, FS_PENDING_WRITE|FS_BROKEN_WRITE|FS_COMPLETE_REPLY|FS_BROKEN_CONNECTION); + if (conn->trans_conn) + { + _FontTransClose (conn->trans_conn); + conn->trans_conn = 0; + _fs_io_reinit (conn); + } + if (conn->fs_fd >= 0) + { + FD_CLR (conn->fs_fd, &_fs_fd_mask); + conn->fs_fd = -1; + } + conn->fs_conn_state = FS_CONN_UNCONNECTED; +} + +static int +_fs_do_setup_connection (FSFpePtr conn) +{ + int ret; + + do + { +#ifdef DEBUG + fprintf (stderr, "fs_do_setup_connection state %d\n", conn->fs_conn_state); +#endif + switch (conn->fs_conn_state) { + case FS_CONN_UNCONNECTED: + ret = _fs_open_server (conn); + if (ret == FSIO_BLOCK) + conn->fs_conn_state = FS_CONN_CONNECTING; + break; + case FS_CONN_CONNECTING: + ret = _fs_check_connect (conn); + break; + case FS_CONN_CONNECTED: + ret = _fs_send_conn_client_prefix (conn); + break; + case FS_CONN_SENT_PREFIX: + ret = _fs_recv_conn_setup (conn); + break; + case FS_CONN_RECV_INIT: + ret = _fs_send_init_packets (conn); + if (conn->has_catalogues) + ret = _fs_send_cat_sync (conn); + break; + case FS_CONN_SENT_CAT: + if (conn->has_catalogues) + ret = _fs_recv_cat_sync (conn); + else + ret = FSIO_READY; + break; + default: + ret = FSIO_READY; + break; + } + switch (ret) { + case FSIO_READY: + if (conn->fs_conn_state < FS_CONN_RUNNING) + conn->fs_conn_state++; + break; + case FSIO_BLOCK: + if (TimeCmp (GetTimeInMillis (), <, conn->blockedConnectTime)) + break; + ret = FSIO_ERROR; + /* fall through... */ + case FSIO_ERROR: + _fs_close_server (conn); + /* + * Try the next alternate + */ + if (conn->alternate < conn->numAlts) + { + conn->alternate++; + ret = FSIO_READY; + } + else + conn->alternate = 0; + break; + } + } while (conn->fs_conn_state != FS_CONN_RUNNING && ret == FSIO_READY); + if (ret == FSIO_READY) + conn->generation = ++generationCount; + return ret; +} + +static int +_fs_wait_connect (FSFpePtr conn) +{ + int ret; + + for (;;) + { + ret = _fs_do_setup_connection (conn); + if (ret != FSIO_BLOCK) + break; + if (conn->fs_conn_state <= FS_CONN_CONNECTING) + ret = _fs_poll_connect (conn->trans_conn, 1000); + else + ret = _fs_wait_for_readable (conn, 1000); + if (ret == FSIO_ERROR) + break; + } + return ret; +} + +/* + * Poll a connection in the process of reconnecting + */ +static void +_fs_check_reconnect (FSFpePtr conn) +{ + int ret; + + ret = _fs_do_setup_connection (conn); + switch (ret) { + case FSIO_READY: + _fs_unmark_block (conn, FS_RECONNECTING|FS_GIVE_UP); + _fs_restart_connection (conn); + break; + case FSIO_BLOCK: + break; + case FSIO_ERROR: + conn->brokenConnectionTime = GetTimeInMillis () + FS_RECONNECT_POLL; + break; + } +} + +/* + * Start the reconnection process + */ +static void +_fs_start_reconnect (FSFpePtr conn) +{ + if (conn->blockState & FS_RECONNECTING) + return; + conn->alternate = 0; + _fs_mark_block (conn, FS_RECONNECTING); + _fs_unmark_block (conn, FS_BROKEN_CONNECTION); + _fs_check_reconnect (conn); +} + + +static FSFpePtr +_fs_init_conn (char *servername) +{ + FSFpePtr conn; + + conn = xalloc (sizeof (FSFpeRec) + strlen (servername) + 1); + if (!conn) + return 0; + memset (conn, '\0', sizeof (FSFpeRec)); + if (!_fs_io_init (conn)) + { + xfree (conn); + return 0; + } + conn->servername = (char *) (conn + 1); + conn->fs_conn_state = FS_CONN_UNCONNECTED; + conn->fs_fd = -1; + strcpy (conn->servername, servername); + return conn; +} + +static void +_fs_free_conn (FSFpePtr conn) +{ + _fs_close_server (conn); + _fs_io_fini (conn); + if (conn->alts) + xfree (conn->alts); + xfree (conn); +} + +/* + * called at server init time + */ + +void +fs_register_fpe_functions(void) +{ + RegisterFPEFunctions(fs_name_check, + fs_init_fpe, + fs_free_fpe, + fs_reset_fpe, + fs_open_font, + fs_close_font, + fs_list_fonts, + fs_start_list_with_info, + fs_next_list_with_info, + fs_wakeup, + fs_client_died, + _fs_load_glyphs, + NULL, + NULL, + NULL); +} + +static int +check_fs_open_font(pointer client, FontPathElementPtr fpe, Mask flags, + char *name, int namelen, + fsBitmapFormat format, fsBitmapFormatMask fmask, + XID id, FontPtr *ppfont, + char **alias, FontPtr non_cachable_font) +{ + if (XpClientIsBitmapClient(client)) + return (fs_open_font(client, fpe, flags, name, namelen, format, + fmask, id, ppfont, alias, non_cachable_font) ); + return BadFontName; +} + +static int +check_fs_list_fonts(pointer client, FontPathElementPtr fpe, + char *pattern, int patlen, int maxnames, + FontNamesPtr newnames) +{ + if (XpClientIsBitmapClient(client)) + return (fs_list_fonts(client, fpe, pattern, patlen, maxnames, + newnames)); + return BadFontName; +} + +static int +check_fs_start_list_with_info(pointer client, FontPathElementPtr fpe, + char *pattern, int len, int maxnames, + pointer *pdata) +{ + if (XpClientIsBitmapClient(client)) + return (fs_start_list_with_info(client, fpe, pattern, len, maxnames, + pdata)); + return BadFontName; +} + +static int +check_fs_next_list_with_info(pointer client, FontPathElementPtr fpe, + char **namep, int *namelenp, + FontInfoPtr *pFontInfo, int *numFonts, + pointer private) +{ + if (XpClientIsBitmapClient(client)) + return (fs_next_list_with_info(client, fpe, namep, namelenp, pFontInfo, + numFonts,private)); + return BadFontName; +} + +void +check_fs_register_fpe_functions(void) +{ + RegisterFPEFunctions(fs_name_check, + fs_init_fpe, + fs_free_fpe, + fs_reset_fpe, + check_fs_open_font, + fs_close_font, + check_fs_list_fonts, + check_fs_start_list_with_info, + check_fs_next_list_with_info, + fs_wakeup, + fs_client_died, + _fs_load_glyphs, + NULL, + NULL, + NULL); +} diff --git a/nx-X11/lib/font/fc/fserve.h b/nx-X11/lib/font/fc/fserve.h new file mode 100644 index 000000000..3254f40fa --- /dev/null +++ b/nx-X11/lib/font/fc/fserve.h @@ -0,0 +1,96 @@ +/* $Xorg: fserve.h,v 1.3 2000/08/17 19:46:36 cpqbld Exp $ */ +/* + * Copyright 1990 Network Computing Devices + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Network Computing Devices not be + * used in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. Network Computing + * Devices makes no representations about the suitability of this software + * for any purpose. It is provided "as is" without express or implied + * warranty. + * + * NETWORK COMPUTING DEVICES DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, + * IN NO EVENT SHALL NETWORK COMPUTING DEVICES BE LIABLE FOR ANY SPECIAL, + * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE + * OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Dave Lemke, Network Computing Devices, Inc + * + */ +/* $XFree86: xc/lib/font/fc/fserve.h,v 1.4 2001/01/17 19:43:29 dawes Exp $ */ + +#ifndef _FSERVE_H_ +#define _FSERVE_H_ +/* + * font server data structures + */ + +/* types of block records */ +#define FS_OPEN_FONT 1 +#define FS_LOAD_GLYPHS 2 +#define FS_LIST_FONTS 3 +#define FS_LIST_WITH_INFO 4 + +/* states of OpenFont */ +#define FS_OPEN_REPLY 0 +#define FS_INFO_REPLY 1 +#define FS_EXTENT_REPLY 2 +#define FS_GLYPHS_REPLY 3 +#define FS_DONE_REPLY 4 +#define FS_DEPENDING 5 + +/* status of ListFontsWithInfo */ +#define FS_LFWI_WAITING 0 +#define FS_LFWI_REPLY 1 +#define FS_LFWI_FINISHED 2 + +/* states of connection */ +#define FS_CONN_CLOSED 0 +#define FS_CONN_CONNECTING 1 +#define FS_CONN_READ_HEADER 2 +#define FS_CONN_READ_DATA 3 + +#define AccessDone 0x400 + +typedef struct _fs_font_data *FSFontDataPtr; +typedef struct _fs_blocked_font *FSBlockedFontPtr; +typedef struct _fs_blocked_glyphs *FSBlockedGlyphPtr; +typedef struct _fs_blocked_list *FSBlockedListPtr; +typedef struct _fs_blocked_list_info *FSBlockedListInfoPtr; +typedef struct _fs_block_data *FSBlockDataPtr; +typedef struct _fs_font_table *FSFontTablePtr; +typedef struct _fs_fpe_data *FSFpePtr; + +typedef struct _fs_blocked_bitmaps *FSBlockedBitmapPtr; +typedef struct _fs_blocked_extents *FSBlockedExtentPtr; + +extern void _fs_convert_char_info ( fsXCharInfo *src, xCharInfo *dst ); +extern void _fs_free_props (FontInfoPtr pfi); +extern FontPtr fs_create_font (FontPathElementPtr fpe, + char *name, + int namelen, + fsBitmapFormat format, + fsBitmapFormatMask fmask); + +extern int fs_load_all_glyphs ( FontPtr pfont ); +extern int _fs_load_glyphs ( pointer client, FontPtr pfont, Bool range_flag, + unsigned int nchars, int item_size, + unsigned char *data ); + +/* + * These should be declared elsewhere, but I'm concerned that moving them + * would cause problems building other pieces + */ +extern FontPtr find_old_font (Font id); +extern int set_font_authorizations (char **a, int *len, pointer client); +extern long GetTimeInMillis (void); + + +#endif /* _FSERVE_H_ */ diff --git a/nx-X11/lib/font/fc/fservestr.h b/nx-X11/lib/font/fc/fservestr.h new file mode 100644 index 000000000..0e4166642 --- /dev/null +++ b/nx-X11/lib/font/fc/fservestr.h @@ -0,0 +1,211 @@ +/* $Xorg: fservestr.h,v 1.3 2000/08/17 19:46:36 cpqbld Exp $ */ +/* + * Copyright 1990 Network Computing Devices + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Network Computing Devices not be + * used in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. Network Computing + * Devices makes no representations about the suitability of this software + * for any purpose. It is provided "as is" without express or implied + * warranty. + * + * NETWORK COMPUTING DEVICES DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, + * IN NO EVENT SHALL NETWORK COMPUTING DEVICES BE LIABLE FOR ANY SPECIAL, + * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE + * OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Dave Lemke, Network Computing Devices, Inc + */ +/* $XFree86: xc/lib/font/fc/fservestr.h,v 3.3 2001/01/17 19:43:29 dawes Exp $ */ + +#ifndef _FSERVESTR_H_ +#define _FSERVESTR_H_ + +#include "fserve.h" +#include "fsio.h" + +/* + * font server data structures + */ +/* + * font server private storage + */ + +typedef struct _fs_glyph { + struct _fs_glyph *next; +} FSGlyphRec, *FSGlyphPtr; + +typedef struct _fs_font { + CharInfoPtr pDefault; + CharInfoPtr encoding; + CharInfoPtr inkMetrics; + FSGlyphPtr glyphs; +} FSFontRec, *FSFontPtr; + +/* FS special data for the font */ +typedef struct _fs_font_data { + long fontid; + int generation; /* FS generation when opened */ + unsigned long glyphs_to_get; /* # glyphs remaining to be gotten */ + + /* Following data needed in case font needs to be reopened. */ + int namelen; + char *name; + fsBitmapFormat format; + fsBitmapFormatMask fmask; +} FSFontDataRec; + +typedef struct fs_clients_depending { + pointer client; + struct fs_clients_depending *next; +} FSClientsDependingRec, *FSClientsDependingPtr; + +/* OpenFont specific data for blocked request */ +typedef struct _fs_blocked_font { + FontPtr pfont; /* must be first for fs_read_glyphs */ + long fontid; + int state; /* how many of the replies have landed */ + int flags; + Bool freeFont; /* free this font on failure */ + CARD16 queryInfoSequence; + CARD16 queryExtentsSequence; + CARD16 queryBitmapsSequence; + fsBitmapFormat format; + FSClientsDependingPtr clients_depending; +} FSBlockedFontRec; + +/* LoadGlyphs data for blocked request */ +typedef struct _fs_blocked_glyphs { + FontPtr pfont; /* must be first for fs_read_glyphs */ + int num_expected_ranges; + fsRange *expected_ranges; + FSClientsDependingPtr clients_depending; +} FSBlockedGlyphRec; + +/* LoadExtents data for blocked request */ +typedef struct _fs_blocked_extents { + FontPtr pfont; + fsRange *expected_ranges; + int nranges; + unsigned long nextents; + fsXCharInfo *extents; +} FSBlockedExtentRec; + +/* LoadBitmaps data for blocked request */ +typedef struct _fs_blocked_bitmaps { + FontPtr pfont; + fsRange *expected_ranges; + int nranges; + unsigned long size; + unsigned long nglyphs; + fsOffset32 *offsets; + pointer gdata; +} FSBlockedBitmapRec; + +/* state for blocked ListFonts */ +typedef struct _fs_blocked_list { + FontNamesPtr names; +} FSBlockedListRec; + +/* state for blocked ListFontsWithInfo */ +typedef struct _fs_blocked_list_info { + int status; + int namelen; + FontInfoRec info; + char name[256]; + int remaining; +} FSBlockedListInfoRec; + +/* state for blocked request */ +typedef struct _fs_block_data { + int type; /* Open Font, LoadGlyphs, ListFonts, + * ListWithInfo */ + pointer client; /* who wants it */ + CARD16 sequenceNumber; /* expected */ + pointer data; /* type specific data */ + int errcode; /* Suspended, et al. */ + struct _fs_block_data *depending; /* clients depending on this one */ + struct _fs_block_data *next; +} FSBlockDataRec; + +/* state for reconnected to dead font server */ +typedef struct _fs_reconnect { + int i; +} FSReconnectRec, *FSReconnectPtr; + + +#if !defined(UNIXCPP) || defined(ANSICPP) +#define fsCat(x,y) x##_##y +#else +#define fsCat(x,y) x/**/_/**/y +#endif + + +/* copy XCharInfo parts of a protocol reply into a xCharInfo */ + +#define fsUnpack_XCharInfo(packet, structure) \ + (structure)->leftSideBearing = fsCat(packet,left); \ + (structure)->rightSideBearing = fsCat(packet,right); \ + (structure)->characterWidth = fsCat(packet,width); \ + (structure)->ascent = fsCat(packet,ascent); \ + (structure)->descent = fsCat(packet,descent); \ + (structure)->attributes = fsCat(packet,attributes) + + +/* copy XFontInfoHeader parts of a protocol reply into a FontInfoRec */ + +#define fsUnpack_XFontInfoHeader(packet, structure) \ + (structure)->allExist = ((packet)->font_header_flags & FontInfoAllCharsExist) != 0; \ + (structure)->drawDirection = \ + ((packet)->font_header_draw_direction == LeftToRightDrawDirection) ? \ + LeftToRight : RightToLeft; \ + (structure)->inkInside = ((packet)->font_header_flags & FontInfoInkInside) != 0; \ + \ + (structure)->firstRow = (packet)->font_hdr_char_range_min_char_high; \ + (structure)->firstCol = (packet)->font_hdr_char_range_min_char_low; \ + (structure)->lastRow = (packet)->font_hdr_char_range_max_char_high; \ + (structure)->lastCol = (packet)->font_hdr_char_range_max_char_low; \ + (structure)->defaultCh = (packet)->font_header_default_char_low \ + + ((packet)->font_header_default_char_high << 8); \ + \ + (structure)->fontDescent = (packet)->font_header_font_descent; \ + (structure)->fontAscent = (packet)->font_header_font_ascent; \ + \ + fsUnpack_XCharInfo((packet)->font_header_min_bounds, &(structure)->minbounds); \ + fsUnpack_XCharInfo((packet)->font_header_min_bounds, &(structure)->ink_minbounds); \ + fsUnpack_XCharInfo((packet)->font_header_max_bounds, &(structure)->maxbounds); \ + fsUnpack_XCharInfo((packet)->font_header_max_bounds, &(structure)->ink_maxbounds) + +extern void _fs_init_fontinfo ( FSFpePtr conn, FontInfoPtr pfi ); +extern int _fs_convert_props ( fsPropInfo *pi, fsPropOffset *po, pointer pd, + FontInfoPtr pfi ); +extern int _fs_convert_lfwi_reply ( FSFpePtr conn, FontInfoPtr pfi, + fsListFontsWithXInfoReply *fsrep, + fsPropInfo *pi, fsPropOffset *po, + pointer pd ); +extern int fs_build_range ( FontPtr pfont, Bool range_flag, + unsigned int count, int item_size, + unsigned char *data, int *nranges, + fsRange **ranges ); +extern void _fs_clean_aborted_loadglyphs ( FontPtr pfont, + int num_expected_ranges, + fsRange *expected_ranges ); +extern int _fs_check_extents ( FontPtr pfont, Mask flags, int nranges, + fsRange *range, FSBlockDataPtr blockrec ); +extern int _fs_check_bitmaps ( FontPtr pfont, fsBitmapFormat format, + Mask flags, int nranges, fsRange *range, + FSBlockDataPtr blockrec ); +extern int _fs_get_glyphs ( FontPtr pFont, unsigned long count, + unsigned char *chars, FontEncoding charEncoding, + unsigned long *glyphCount, CharInfoPtr *glyphs ); +extern void _fs_unload_font ( FontPtr pfont ); +extern void _fs_init_font ( FontPtr pfont ); +extern pointer fs_alloc_glyphs (FontPtr pFont, int size); +#endif /* _FSERVESTR_H_ */ diff --git a/nx-X11/lib/font/fc/fsio.c b/nx-X11/lib/font/fc/fsio.c new file mode 100644 index 000000000..fbfb9dfed --- /dev/null +++ b/nx-X11/lib/font/fc/fsio.c @@ -0,0 +1,516 @@ +/* $Xorg: fsio.c,v 1.3 2000/08/17 19:46:36 cpqbld Exp $ */ +/* + * Copyright 1990 Network Computing Devices + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Network Computing Devices not be + * used in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. Network Computing + * Devices makes no representations about the suitability of this software + * for any purpose. It is provided "as is" without express or implied + * warranty. + * + * NETWORK COMPUTING DEVICES DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, + * IN NO EVENT SHALL NETWORK COMPUTING DEVICES BE LIABLE FOR ANY SPECIAL, + * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE + * OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Dave Lemke, Network Computing Devices, Inc + */ +/* $XFree86: xc/lib/font/fc/fsio.c,v 3.16tsi Exp $ */ +/* + * font server i/o routines + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#ifdef WIN32 +#define _WILLWINSOCK_ +#include "X11/Xwindows.h" +#endif + +#define FONT_t +#define TRANS_CLIENT +#include "X11/Xtrans/Xtrans.h" +#include "X11/Xpoll.h" +#include <X11/fonts/FS.h> +#include <X11/fonts/FSproto.h> +#include <X11/fonts/fontmisc.h> +#include <X11/fonts/fontstruct.h> +#include "fservestr.h" + +#include <stdio.h> +#include <signal.h> +#include <sys/types.h> +#if !defined(WIN32) +#ifndef Lynx +#include <sys/socket.h> +#else +#include <socket.h> +#endif +#endif +#include <errno.h> +#ifdef WIN32 +#define EWOULDBLOCK WSAEWOULDBLOCK +#undef EINTR +#define EINTR WSAEINTR +#endif + +#ifdef __UNIXOS2__ +#define select(n,r,w,x,t) os2PseudoSelect(n,r,w,x,t) +#endif + + +static int padlength[4] = {0, 3, 2, 1}; +fd_set _fs_fd_mask; + +static int +_fs_resize (FSBufPtr buf, long size); + +static void +_fs_downsize (FSBufPtr buf, long size); + +int +_fs_poll_connect (XtransConnInfo trans_conn, int timeout) +{ + fd_set w_mask; + struct timeval tv; + int fs_fd = _FontTransGetConnectionNumber (trans_conn); + int ret; + + do + { + tv.tv_usec = 0; + tv.tv_sec = timeout; + FD_ZERO (&w_mask); + FD_SET (fs_fd, &w_mask); + ret = Select (fs_fd + 1, NULL, &w_mask, NULL, &tv); + } while (ret < 0 && ECHECK(EINTR)); + if (ret == 0) + return FSIO_BLOCK; + if (ret < 0) + return FSIO_ERROR; + return FSIO_READY; +} + +XtransConnInfo +_fs_connect(char *servername, int *err) +{ + XtransConnInfo trans_conn; /* transport connection object */ + int ret; + int i = 0; + int retries = 5; + + /* + * Open the network connection. + */ + if( (trans_conn=_FontTransOpenCOTSClient(servername)) == NULL ) + { + *err = FSIO_ERROR; + return 0; + } + + /* + * Set the connection non-blocking since we use select() to block. + */ + + _FontTransSetOption(trans_conn, TRANS_NONBLOCKING, 1); + + do { + if (i == TRANS_TRY_CONNECT_AGAIN) + sleep(1); + i = _FontTransConnect(trans_conn,servername); + } while ((i == TRANS_TRY_CONNECT_AGAIN) && (retries-- > 0)); + + if (i < 0) + { + if (i == TRANS_IN_PROGRESS) + ret = FSIO_BLOCK; + else + ret = FSIO_ERROR; + } + else + ret = FSIO_READY; + + if (ret == FSIO_ERROR) + { + _FontTransClose(trans_conn); + trans_conn = 0; + } + + *err = ret; + return trans_conn; +} + +int +_fs_fill (FSFpePtr conn) +{ + long avail; + long bytes_read; + Bool waited = FALSE; + + if (_fs_flush (conn) < 0) + return FSIO_ERROR; + /* + * Don't go overboard here; stop reading when we've + * got enough to satisfy the pending request + */ + while ((conn->inNeed - (conn->inBuf.insert - conn->inBuf.remove)) > 0) + { + avail = conn->inBuf.size - conn->inBuf.insert; + /* + * For SVR4 with a unix-domain connection, ETEST() after selecting + * readable means the server has died. To do this here, we look for + * two consecutive reads returning ETEST(). + */ + ESET (0); + bytes_read =_FontTransRead(conn->trans_conn, + conn->inBuf.buf + conn->inBuf.insert, + avail); + if (bytes_read > 0) { + conn->inBuf.insert += bytes_read; + waited = FALSE; + } + else + { + if (bytes_read == 0 || ETEST ()) + { + if (!waited) + { + waited = TRUE; + if (_fs_wait_for_readable (conn, 0) == FSIO_BLOCK) + return FSIO_BLOCK; + continue; + } + } + _fs_connection_died (conn); + return FSIO_ERROR; + } + } + return FSIO_READY; +} + +/* + * Make space and return whether data have already arrived + */ + +int +_fs_start_read (FSFpePtr conn, long size, char **buf) +{ + int ret; + + conn->inNeed = size; + if (fs_inqueued(conn) < size) + { + if (_fs_resize (&conn->inBuf, size) != FSIO_READY) + { + _fs_connection_died (conn); + return FSIO_ERROR; + } + ret = _fs_fill (conn); + if (ret == FSIO_ERROR) + return ret; + if (ret == FSIO_BLOCK || fs_inqueued(conn) < size) + return FSIO_BLOCK; + } + if (buf) + *buf = conn->inBuf.buf + conn->inBuf.remove; + return FSIO_READY; +} + +void +_fs_done_read (FSFpePtr conn, long size) +{ + if (conn->inBuf.insert - conn->inBuf.remove < size) + { +#ifdef DEBUG + fprintf (stderr, "_fs_done_read skipping to many bytes\n"); +#endif + return; + } + conn->inBuf.remove += size; + conn->inNeed -= size; + _fs_downsize (&conn->inBuf, FS_BUF_MAX); +} + +long +_fs_pad_length (long len) +{ + return len + padlength[len&3]; +} + +int +_fs_flush (FSFpePtr conn) +{ + long bytes_written; + long remain; + + /* XXX - hack. The right fix is to remember that the font server + has gone away when we first discovered it. */ + if (conn->fs_fd < 0) + return FSIO_ERROR; + + while ((remain = conn->outBuf.insert - conn->outBuf.remove) > 0) + { + bytes_written = _FontTransWrite(conn->trans_conn, + conn->outBuf.buf + conn->outBuf.remove, + (int) remain); + if (bytes_written > 0) + { + conn->outBuf.remove += bytes_written; + } + else + { + if (bytes_written == 0 || ETEST ()) + { + conn->brokenWriteTime = GetTimeInMillis () + FS_FLUSH_POLL; + _fs_mark_block (conn, FS_BROKEN_WRITE); + break; + } + if (!ECHECK (EINTR)) + { + _fs_connection_died (conn); + return FSIO_ERROR; + } + } + } + if (conn->outBuf.remove == conn->outBuf.insert) + { + _fs_unmark_block (conn, FS_BROKEN_WRITE|FS_PENDING_WRITE); + if (conn->outBuf.size > FS_BUF_INC) + conn->outBuf.buf = xrealloc (conn->outBuf.buf, FS_BUF_INC); + conn->outBuf.remove = conn->outBuf.insert = 0; + } + return FSIO_READY; +} + +static int +_fs_resize (FSBufPtr buf, long size) +{ + char *new; + long new_size; + + if (buf->remove) + { + if (buf->remove != buf->insert) + { + memmove (buf->buf, + buf->buf + buf->remove, + buf->insert - buf->remove); + } + buf->insert -= buf->remove; + buf->remove = 0; + } + if (buf->size - buf->remove < size) + { + new_size = ((buf->remove + size + FS_BUF_INC) / FS_BUF_INC) * FS_BUF_INC; + new = xrealloc (buf->buf, new_size); + if (!new) + return FSIO_ERROR; + buf->buf = new; + buf->size = new_size; + } + return FSIO_READY; +} + +static void +_fs_downsize (FSBufPtr buf, long size) +{ + if (buf->insert == buf->remove) + { + buf->insert = buf->remove = 0; + if (buf->size > size) + { + buf->buf = xrealloc (buf->buf, size); + buf->size = size; + } + } +} + +void +_fs_io_reinit (FSFpePtr conn) +{ + conn->outBuf.insert = conn->outBuf.remove = 0; + _fs_downsize (&conn->outBuf, FS_BUF_INC); + conn->inBuf.insert = conn->inBuf.remove = 0; + _fs_downsize (&conn->inBuf, FS_BUF_MAX); +} + +Bool +_fs_io_init (FSFpePtr conn) +{ + conn->outBuf.insert = conn->outBuf.remove = 0; + conn->outBuf.buf = xalloc (FS_BUF_INC); + if (!conn->outBuf.buf) + return FALSE; + conn->outBuf.size = FS_BUF_INC; + + conn->inBuf.insert = conn->inBuf.remove = 0; + conn->inBuf.buf = xalloc (FS_BUF_INC); + if (!conn->inBuf.buf) + { + xfree (conn->outBuf.buf); + conn->outBuf.buf = 0; + return FALSE; + } + conn->inBuf.size = FS_BUF_INC; + + return TRUE; +} + +void +_fs_io_fini (FSFpePtr conn) +{ + if (conn->outBuf.buf) + xfree (conn->outBuf.buf); + if (conn->inBuf.buf) + xfree (conn->inBuf.buf); +} + +static int +_fs_do_write(FSFpePtr conn, char *data, long len, long size) +{ + if (size == 0) { +#ifdef DEBUG + fprintf(stderr, "tried to write 0 bytes \n"); +#endif + return FSIO_READY; + } + + if (conn->fs_fd == -1) + return FSIO_ERROR; + + while (conn->outBuf.insert + size > conn->outBuf.size) + { + if (_fs_flush (conn) < 0) + return FSIO_ERROR; + if (_fs_resize (&conn->outBuf, size) < 0) + { + _fs_connection_died (conn); + return FSIO_ERROR; + } + } + memcpy (conn->outBuf.buf + conn->outBuf.insert, data, len); + conn->outBuf.insert += size; + _fs_mark_block (conn, FS_PENDING_WRITE); + return FSIO_READY; +} + +/* + * Write the indicated bytes + */ +int +_fs_write (FSFpePtr conn, char *data, long len) +{ + return _fs_do_write (conn, data, len, len); +} + +/* + * Write the indicated bytes adding any appropriate pad + */ +int +_fs_write_pad(FSFpePtr conn, char *data, long len) +{ + return _fs_do_write (conn, data, len, len + padlength[len & 3]); +} + +/* + * returns the amount of data waiting to be read + */ +int +_fs_data_ready(FSFpePtr conn) +{ + BytesReadable_t readable; + + if (_FontTransBytesReadable(conn->trans_conn, &readable) < 0) + return -1; + return readable; +} + +int +_fs_wait_for_readable(FSFpePtr conn, int ms) +{ + fd_set r_mask; + fd_set e_mask; + int result; + struct timeval tv; + + for (;;) { + if (conn->fs_fd < 0) + return FSIO_ERROR; + FD_ZERO(&r_mask); + FD_ZERO(&e_mask); + tv.tv_sec = ms / 1000; + tv.tv_usec = (ms % 1000) * 1000; + FD_SET(conn->fs_fd, &r_mask); + FD_SET(conn->fs_fd, &e_mask); + result = Select(conn->fs_fd + 1, &r_mask, NULL, &e_mask, &tv); + if (result < 0) + { + if (ECHECK(EINTR) || ECHECK(EAGAIN)) + continue; + else + return FSIO_ERROR; + } + if (result == 0) + return FSIO_BLOCK; + if (FD_ISSET(conn->fs_fd, &r_mask)) + return FSIO_READY; + return FSIO_ERROR; + } +} + +int +_fs_set_bit(fd_set *mask, int fd) +{ + FD_SET(fd, mask); + return fd; +} + +int +_fs_is_bit_set(fd_set *mask, int fd) +{ + return FD_ISSET(fd, mask); +} + +void +_fs_bit_clear(fd_set *mask, int fd) +{ + FD_CLR(fd, mask); +} + +int +_fs_any_bit_set(fd_set *mask) +{ + return XFD_ANYSET(mask); +} + +void +_fs_or_bits(fd_set *dst, fd_set *m1, fd_set *m2) +{ +#ifdef WIN32 + int i; + if (dst != m1) { + for (i = m1->fd_count; --i >= 0; ) { + if (!FD_ISSET(m1->fd_array[i], dst)) + FD_SET(m1->fd_array[i], dst); + } + } + if (dst != m2) { + for (i = m2->fd_count; --i >= 0; ) { + if (!FD_ISSET(m2->fd_array[i], dst)) + FD_SET(m2->fd_array[i], dst); + } + } +#else + XFD_ORSET(dst, m1, m2); +#endif +} diff --git a/nx-X11/lib/font/fc/fsio.h b/nx-X11/lib/font/fc/fsio.h new file mode 100644 index 000000000..224143601 --- /dev/null +++ b/nx-X11/lib/font/fc/fsio.h @@ -0,0 +1,187 @@ +/* $Xorg: fsio.h,v 1.3 2000/08/17 19:46:36 cpqbld Exp $ */ +/* + * Copyright 1990 Network Computing Devices + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Network Computing Devices not be + * used in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. Network Computing + * Devices makes no representations about the suitability of this software + * for any purpose. It is provided "as is" without express or implied + * warranty. + * + * NETWORK COMPUTING DEVICES DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, + * IN NO EVENT SHALL NETWORK COMPUTING DEVICES BE LIABLE FOR ANY SPECIAL, + * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE + * OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Dave Lemke, Network Computing Devices, Inc + */ +/* $XFree86: xc/lib/font/fc/fsio.h,v 1.5 1999/12/30 02:39:06 robin Exp $ */ + +#ifndef _FSIO_H_ +#define _FSIO_H_ + +#undef DEBUG +#define REQUEST_LOG_SIZE 100 + +typedef struct _fs_fpe_alternate { + char *name; + Bool subset; +} FSFpeAltRec, *FSFpeAltPtr; + + +/* Per client access contexts */ +typedef struct _fs_client_data { + pointer client; + struct _fs_client_data *next; + XID acid; + int auth_generation; +} FSClientRec, *FSClientPtr; + +#define FS_RECONNECT_POLL 1000 +#define FS_RECONNECT_WAIT 5000 +#define FS_GIVEUP_WAIT 20000 +#define FS_REQUEST_TIMEOUT 20000 +#define FS_OPEN_TIMEOUT 30000 +#define FS_REOPEN_TIMEOUT 10000 +#define FS_FLUSH_POLL 1000 + +typedef struct _fs_buf { + char *buf; /* data */ + long size; /* sizeof data */ + long insert; /* where to insert new data */ + long remove; /* where to remove old data */ +} FSBufRec, *FSBufPtr; + +#define FS_BUF_INC 1024 +#define FS_BUF_MAX 32768 + +#define FS_PENDING_WRITE 0x01 /* some write data is queued */ +#define FS_BROKEN_WRITE 0x02 /* writes are broken */ +#define FS_BROKEN_CONNECTION 0x04 /* connection is broken */ +#define FS_PENDING_REPLY 0x08 /* waiting for a reply */ +#define FS_GIVE_UP 0x10 /* font server declared useless */ +#define FS_COMPLETE_REPLY 0x20 /* complete reply ready */ +#define FS_RECONNECTING 0x40 + +#define FS_CONN_UNCONNECTED 0 +#define FS_CONN_CONNECTING 1 +#define FS_CONN_CONNECTED 2 +#define FS_CONN_SENT_PREFIX 3 +#define FS_CONN_RECV_INIT 4 +#define FS_CONN_SENT_CAT 5 +#define FS_CONN_RUNNING 6 + +/* FS specific font FontPathElement data */ +typedef struct _fs_fpe_data { + FSFpePtr next; /* list of all active fs fpes */ + int fs_fd; /* < 0 when not running */ + int fs_conn_state; /* connection state */ + int current_seq; + char *servername; + Bool has_catalogues; + + int generation; + int numAlts; + int alternate; /* which alternate is in use +1 */ + int fsMajorVersion; /* font server major version number */ + FSFpeAltPtr alts; + + FSClientPtr clients; + XID curacid; +#ifdef DEBUG + int reqindex; + struct { + int opcode; + int sequence; + } reqbuffer[REQUEST_LOG_SIZE]; +#endif + FSBufRec outBuf; /* request queue */ + FSBufRec inBuf; /* reply queue */ + long inNeed; /* amount needed for reply */ + + CARD32 blockState; + CARD32 blockedReplyTime; /* time to abort blocked read */ + CARD32 brokenWriteTime; /* time to retry broken write */ + CARD32 blockedConnectTime; /* time to abort blocked connect */ + CARD32 brokenConnectionTime; /* time to retry broken connection */ + + FSBlockDataPtr blockedRequests; + + struct _XtransConnInfo *trans_conn; /* transport connection object */ +} FSFpeRec; + +#define fs_outspace(conn) ((conn)->outBuf.size - (conn)->outBuf.insert) +#define fs_outqueued(conn) ((conn)->outBuf.insert - (conn)->outBuf.remove) +#define fs_inqueued(conn) ((conn)->inBuf.insert - (conn)->inBuf.remove) +#define fs_needsflush(conn) (fs_outqueued(conn) != 0) +#define fs_needsfill(conn) (fs_inqueued(conn) < (conn)->inNeed) +#define fs_needsconnect(conn) ((conn)->fs_fd < 0) +#define fs_data_read(conn) ((conn)->inBuf.insert - (conn)->inBuf.remove) + +#define FSIO_READY 1 +#define FSIO_BLOCK 0 +#define FSIO_ERROR -1 + +extern Bool _fs_reopen_server ( FSFpePtr conn ); +extern int _fs_write ( FSFpePtr conn, char *data, long size ); +extern int _fs_write_pad ( FSFpePtr conn, char *data, long len ); +extern int _fs_data_ready ( FSFpePtr conn ); +extern int _fs_wait_for_readable ( FSFpePtr conn, int ms ); +extern int _fs_set_bit ( fd_set * mask, int fd ); +extern int _fs_is_bit_set ( fd_set * mask, int fd ); +extern void _fs_bit_clear ( fd_set * mask, int fd ); +extern int _fs_any_bit_set ( fd_set * mask ); +extern void _fs_or_bits ( fd_set * dst, fd_set * m1, fd_set * m2 ); +extern long _fs_pad_length (long len); + +extern void _fs_connection_died ( FSFpePtr conn ); + +extern int _fs_fill (FSFpePtr conn); +extern int _fs_flush (FSFpePtr conn); +extern void _fs_mark_block (FSFpePtr conn, CARD32 mask); +extern void _fs_unmark_block (FSFpePtr conn, CARD32 mask); +extern void _fs_done_read (FSFpePtr conn, long size); +extern void _fs_io_reinit (FSFpePtr conn); +extern int _fs_start_read (FSFpePtr conn, long size, char **buf); +extern Bool _fs_io_init (FSFpePtr conn); +extern void _fs_io_fini (FSFpePtr conn); +extern int _fs_poll_connect (XtransConnInfo trans_conn, int timeout); +extern XtransConnInfo _fs_connect(char *servername, int *ret); + +/* check for both EAGAIN and EWOULDBLOCK, because some supposedly POSIX + * systems are broken and return EWOULDBLOCK when they should return EAGAIN + */ +#ifdef WIN32 +#define ETEST() (WSAGetLastError() == WSAEWOULDBLOCK) +#else +#if defined(EAGAIN) && defined(EWOULDBLOCK) +#define ETEST() (errno == EAGAIN || errno == EWOULDBLOCK) +#else +#ifdef EAGAIN +#define ETEST() (errno == EAGAIN) +#else +#define ETEST() (errno == EWOULDBLOCK) +#endif +#endif +#endif +#ifdef WIN32 +#define ECHECK(err) (WSAGetLastError() == err) +#define ESET(val) WSASetLastError(val) +#else +#ifdef ISC +#define ECHECK(err) ((errno == err) || ETEST()) +#else +#define ECHECK(err) (errno == err) +#endif +#define ESET(val) errno = val +#endif + +#endif /* _FSIO_H_ */ diff --git a/nx-X11/lib/font/fc/fsio.h.NX.reference b/nx-X11/lib/font/fc/fsio.h.NX.reference new file mode 100644 index 000000000..f79a17b90 --- /dev/null +++ b/nx-X11/lib/font/fc/fsio.h.NX.reference @@ -0,0 +1,191 @@ +/* $Xorg: fsio.h,v 1.3 2000/08/17 19:46:36 cpqbld Exp $ */ +/* + * Copyright 1990 Network Computing Devices + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Network Computing Devices not be + * used in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. Network Computing + * Devices makes no representations about the suitability of this software + * for any purpose. It is provided "as is" without express or implied + * warranty. + * + * NETWORK COMPUTING DEVICES DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, + * IN NO EVENT SHALL NETWORK COMPUTING DEVICES BE LIABLE FOR ANY SPECIAL, + * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE + * OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Dave Lemke, Network Computing Devices, Inc + */ +/* $XFree86: xc/lib/font/fc/fsio.h,v 1.6 2001/01/17 19:43:29 dawes Exp $ */ + +#ifndef _FSIO_H_ +#define _FSIO_H_ + +#undef DEBUG +#define REQUEST_LOG_SIZE 100 + +typedef struct _fs_fpe_alternate { + char *name; + Bool subset; +} FSFpeAltRec, *FSFpeAltPtr; + + +/* Per client access contexts */ +typedef struct _fs_client_data { + pointer client; + struct _fs_client_data *next; + XID acid; + int auth_generation; +} FSClientRec, *FSClientPtr; + +#define FS_RECONNECT_POLL 1000 +#ifdef __CYGWIN__ +#define FS_RECONNECT_WAIT 800 +#else +#define FS_RECONNECT_WAIT 5000 +#endif +#define FS_GIVEUP_WAIT 20000 +#define FS_REQUEST_TIMEOUT 20000 +#define FS_OPEN_TIMEOUT 30000 +#define FS_REOPEN_TIMEOUT 10000 +#define FS_FLUSH_POLL 1000 + +typedef struct _fs_buf { + char *buf; /* data */ + long size; /* sizeof data */ + long insert; /* where to insert new data */ + long remove; /* where to remove old data */ +} FSBufRec, *FSBufPtr; + +#define FS_BUF_INC 1024 +#define FS_BUF_MAX 32768 + +#define FS_PENDING_WRITE 0x01 /* some write data is queued */ +#define FS_BROKEN_WRITE 0x02 /* writes are broken */ +#define FS_BROKEN_CONNECTION 0x04 /* connection is broken */ +#define FS_PENDING_REPLY 0x08 /* waiting for a reply */ +#define FS_GIVE_UP 0x10 /* font server declared useless */ +#define FS_COMPLETE_REPLY 0x20 /* complete reply ready */ +#define FS_RECONNECTING 0x40 + +#define FS_CONN_UNCONNECTED 0 +#define FS_CONN_CONNECTING 1 +#define FS_CONN_CONNECTED 2 +#define FS_CONN_SENT_PREFIX 3 +#define FS_CONN_RECV_INIT 4 +#define FS_CONN_SENT_CAT 5 +#define FS_CONN_RUNNING 6 + +/* FS specific font FontPathElement data */ +typedef struct _fs_fpe_data { + FSFpePtr next; /* list of all active fs fpes */ + int fs_fd; /* < 0 when not running */ + int fs_conn_state; /* connection state */ + int current_seq; + char *servername; + Bool has_catalogues; + + int generation; + int numAlts; + int alternate; /* which alternate is in use +1 */ + int fsMajorVersion; /* font server major version number */ + FSFpeAltPtr alts; + + FSClientPtr clients; + XID curacid; +#ifdef DEBUG + int reqindex; + struct { + int opcode; + int sequence; + } reqbuffer[REQUEST_LOG_SIZE]; +#endif + FSBufRec outBuf; /* request queue */ + FSBufRec inBuf; /* reply queue */ + long inNeed; /* amount needed for reply */ + + CARD32 blockState; + CARD32 blockedReplyTime; /* time to abort blocked read */ + CARD32 brokenWriteTime; /* time to retry broken write */ + CARD32 blockedConnectTime; /* time to abort blocked connect */ + CARD32 brokenConnectionTime; /* time to retry broken connection */ + + FSBlockDataPtr blockedRequests; + + struct _XtransConnInfo *trans_conn; /* transport connection object */ +} FSFpeRec; + +#define fs_outspace(conn) ((conn)->outBuf.size - (conn)->outBuf.insert) +#define fs_outqueued(conn) ((conn)->outBuf.insert - (conn)->outBuf.remove) +#define fs_inqueued(conn) ((conn)->inBuf.insert - (conn)->inBuf.remove) +#define fs_needsflush(conn) (fs_outqueued(conn) != 0) +#define fs_needsfill(conn) (fs_inqueued(conn) < (conn)->inNeed) +#define fs_needsconnect(conn) ((conn)->fs_fd < 0) +#define fs_data_read(conn) ((conn)->inBuf.insert - (conn)->inBuf.remove) + +#define FSIO_READY 1 +#define FSIO_BLOCK 0 +#define FSIO_ERROR -1 + +extern Bool _fs_reopen_server ( FSFpePtr conn ); +extern int _fs_write ( FSFpePtr conn, char *data, long size ); +extern int _fs_write_pad ( FSFpePtr conn, char *data, long len ); +extern int _fs_data_ready ( FSFpePtr conn ); +extern int _fs_wait_for_readable ( FSFpePtr conn, int ms ); +extern int _fs_set_bit ( fd_set * mask, int fd ); +extern int _fs_is_bit_set ( fd_set * mask, int fd ); +extern void _fs_bit_clear ( fd_set * mask, int fd ); +extern int _fs_any_bit_set ( fd_set * mask ); +extern void _fs_or_bits ( fd_set * dst, fd_set * m1, fd_set * m2 ); +extern long _fs_pad_length (long len); + +extern void _fs_connection_died ( FSFpePtr conn ); + +extern int _fs_fill (FSFpePtr conn); +extern int _fs_flush (FSFpePtr conn); +extern void _fs_mark_block (FSFpePtr conn, CARD32 mask); +extern void _fs_unmark_block (FSFpePtr conn, CARD32 mask); +extern void _fs_done_read (FSFpePtr conn, long size); +extern void _fs_io_reinit (FSFpePtr conn); +extern int _fs_start_read (FSFpePtr conn, long size, char **buf); +extern Bool _fs_io_init (FSFpePtr conn); +extern void _fs_io_fini (FSFpePtr conn); +extern int _fs_poll_connect (XtransConnInfo trans_conn, int timeout); +extern XtransConnInfo _fs_connect(char *servername, int *ret); + +/* check for both EAGAIN and EWOULDBLOCK, because some supposedly POSIX + * systems are broken and return EWOULDBLOCK when they should return EAGAIN + */ +#ifdef WIN32 +#define ETEST() (WSAGetLastError() == WSAEWOULDBLOCK) +#else +#if defined(EAGAIN) && defined(EWOULDBLOCK) +#define ETEST() (errno == EAGAIN || errno == EWOULDBLOCK) +#else +#ifdef EAGAIN +#define ETEST() (errno == EAGAIN) +#else +#define ETEST() (errno == EWOULDBLOCK) +#endif +#endif +#endif +#ifdef WIN32 +#define ECHECK(err) (WSAGetLastError() == err) +#define ESET(val) WSASetLastError(val) +#else +#ifdef ISC +#define ECHECK(err) ((errno == err) || ETEST()) +#else +#define ECHECK(err) (errno == err) +#endif +#define ESET(val) errno = val +#endif + +#endif /* _FSIO_H_ */ diff --git a/nx-X11/lib/font/fc/fsio.h.XF86.reference b/nx-X11/lib/font/fc/fsio.h.XF86.reference new file mode 100644 index 000000000..974ef4a91 --- /dev/null +++ b/nx-X11/lib/font/fc/fsio.h.XF86.reference @@ -0,0 +1,187 @@ +/* $Xorg: fsio.h,v 1.3 2000/08/17 19:46:36 cpqbld Exp $ */ +/* + * Copyright 1990 Network Computing Devices + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Network Computing Devices not be + * used in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. Network Computing + * Devices makes no representations about the suitability of this software + * for any purpose. It is provided "as is" without express or implied + * warranty. + * + * NETWORK COMPUTING DEVICES DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, + * IN NO EVENT SHALL NETWORK COMPUTING DEVICES BE LIABLE FOR ANY SPECIAL, + * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE + * OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Dave Lemke, Network Computing Devices, Inc + */ +/* $XFree86: xc/lib/font/fc/fsio.h,v 1.6 2001/01/17 19:43:29 dawes Exp $ */ + +#ifndef _FSIO_H_ +#define _FSIO_H_ + +#undef DEBUG +#define REQUEST_LOG_SIZE 100 + +typedef struct _fs_fpe_alternate { + char *name; + Bool subset; +} FSFpeAltRec, *FSFpeAltPtr; + + +/* Per client access contexts */ +typedef struct _fs_client_data { + pointer client; + struct _fs_client_data *next; + XID acid; + int auth_generation; +} FSClientRec, *FSClientPtr; + +#define FS_RECONNECT_POLL 1000 +#define FS_RECONNECT_WAIT 5000 +#define FS_GIVEUP_WAIT 20000 +#define FS_REQUEST_TIMEOUT 20000 +#define FS_OPEN_TIMEOUT 30000 +#define FS_REOPEN_TIMEOUT 10000 +#define FS_FLUSH_POLL 1000 + +typedef struct _fs_buf { + char *buf; /* data */ + long size; /* sizeof data */ + long insert; /* where to insert new data */ + long remove; /* where to remove old data */ +} FSBufRec, *FSBufPtr; + +#define FS_BUF_INC 1024 +#define FS_BUF_MAX 32768 + +#define FS_PENDING_WRITE 0x01 /* some write data is queued */ +#define FS_BROKEN_WRITE 0x02 /* writes are broken */ +#define FS_BROKEN_CONNECTION 0x04 /* connection is broken */ +#define FS_PENDING_REPLY 0x08 /* waiting for a reply */ +#define FS_GIVE_UP 0x10 /* font server declared useless */ +#define FS_COMPLETE_REPLY 0x20 /* complete reply ready */ +#define FS_RECONNECTING 0x40 + +#define FS_CONN_UNCONNECTED 0 +#define FS_CONN_CONNECTING 1 +#define FS_CONN_CONNECTED 2 +#define FS_CONN_SENT_PREFIX 3 +#define FS_CONN_RECV_INIT 4 +#define FS_CONN_SENT_CAT 5 +#define FS_CONN_RUNNING 6 + +/* FS specific font FontPathElement data */ +typedef struct _fs_fpe_data { + FSFpePtr next; /* list of all active fs fpes */ + int fs_fd; /* < 0 when not running */ + int fs_conn_state; /* connection state */ + int current_seq; + char *servername; + Bool has_catalogues; + + int generation; + int numAlts; + int alternate; /* which alternate is in use +1 */ + int fsMajorVersion; /* font server major version number */ + FSFpeAltPtr alts; + + FSClientPtr clients; + XID curacid; +#ifdef DEBUG + int reqindex; + struct { + int opcode; + int sequence; + } reqbuffer[REQUEST_LOG_SIZE]; +#endif + FSBufRec outBuf; /* request queue */ + FSBufRec inBuf; /* reply queue */ + long inNeed; /* amount needed for reply */ + + CARD32 blockState; + CARD32 blockedReplyTime; /* time to abort blocked read */ + CARD32 brokenWriteTime; /* time to retry broken write */ + CARD32 blockedConnectTime; /* time to abort blocked connect */ + CARD32 brokenConnectionTime; /* time to retry broken connection */ + + FSBlockDataPtr blockedRequests; + + struct _XtransConnInfo *trans_conn; /* transport connection object */ +} FSFpeRec; + +#define fs_outspace(conn) ((conn)->outBuf.size - (conn)->outBuf.insert) +#define fs_outqueued(conn) ((conn)->outBuf.insert - (conn)->outBuf.remove) +#define fs_inqueued(conn) ((conn)->inBuf.insert - (conn)->inBuf.remove) +#define fs_needsflush(conn) (fs_outqueued(conn) != 0) +#define fs_needsfill(conn) (fs_inqueued(conn) < (conn)->inNeed) +#define fs_needsconnect(conn) ((conn)->fs_fd < 0) +#define fs_data_read(conn) ((conn)->inBuf.insert - (conn)->inBuf.remove) + +#define FSIO_READY 1 +#define FSIO_BLOCK 0 +#define FSIO_ERROR -1 + +extern Bool _fs_reopen_server ( FSFpePtr conn ); +extern int _fs_write ( FSFpePtr conn, char *data, long size ); +extern int _fs_write_pad ( FSFpePtr conn, char *data, long len ); +extern int _fs_data_ready ( FSFpePtr conn ); +extern int _fs_wait_for_readable ( FSFpePtr conn, int ms ); +extern int _fs_set_bit ( fd_set * mask, int fd ); +extern int _fs_is_bit_set ( fd_set * mask, int fd ); +extern void _fs_bit_clear ( fd_set * mask, int fd ); +extern int _fs_any_bit_set ( fd_set * mask ); +extern void _fs_or_bits ( fd_set * dst, fd_set * m1, fd_set * m2 ); +extern long _fs_pad_length (long len); + +extern void _fs_connection_died ( FSFpePtr conn ); + +extern int _fs_fill (FSFpePtr conn); +extern int _fs_flush (FSFpePtr conn); +extern void _fs_mark_block (FSFpePtr conn, CARD32 mask); +extern void _fs_unmark_block (FSFpePtr conn, CARD32 mask); +extern void _fs_done_read (FSFpePtr conn, long size); +extern void _fs_io_reinit (FSFpePtr conn); +extern int _fs_start_read (FSFpePtr conn, long size, char **buf); +extern Bool _fs_io_init (FSFpePtr conn); +extern void _fs_io_fini (FSFpePtr conn); +extern int _fs_poll_connect (XtransConnInfo trans_conn, int timeout); +extern XtransConnInfo _fs_connect(char *servername, int *ret); + +/* check for both EAGAIN and EWOULDBLOCK, because some supposedly POSIX + * systems are broken and return EWOULDBLOCK when they should return EAGAIN + */ +#ifdef WIN32 +#define ETEST() (WSAGetLastError() == WSAEWOULDBLOCK) +#else +#if defined(EAGAIN) && defined(EWOULDBLOCK) +#define ETEST() (errno == EAGAIN || errno == EWOULDBLOCK) +#else +#ifdef EAGAIN +#define ETEST() (errno == EAGAIN) +#else +#define ETEST() (errno == EWOULDBLOCK) +#endif +#endif +#endif +#ifdef WIN32 +#define ECHECK(err) (WSAGetLastError() == err) +#define ESET(val) WSASetLastError(val) +#else +#ifdef ISC +#define ECHECK(err) ((errno == err) || ETEST()) +#else +#define ECHECK(err) (errno == err) +#endif +#define ESET(val) errno = val +#endif + +#endif /* _FSIO_H_ */ diff --git a/nx-X11/lib/font/fc/fslibos.h b/nx-X11/lib/font/fc/fslibos.h new file mode 100644 index 000000000..acc1f16dc --- /dev/null +++ b/nx-X11/lib/font/fc/fslibos.h @@ -0,0 +1,220 @@ +/* $Xorg: fslibos.h,v 1.4 2001/02/09 02:04:03 xorgcvs Exp $ */ +/* + * Copyright 1990 Network Computing Devices; + * Portions Copyright 1987 by Digital Equipment Corporation + */ + +/* + +Copyright 1987, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + +*/ +/* $XFree86: xc/lib/font/fc/fslibos.h,v 3.8 2003/08/29 18:01:14 herrb Exp $ */ + +/* + * FSlib networking & os include file + */ + +#include <X11/Xtrans/Xtrans.h> + +#ifndef WIN32 + +/* + * makedepend screws up on #undef OPEN_MAX, so we define a new symbol + */ + +#ifndef FONT_OPEN_MAX + +#ifndef X_NOT_POSIX +# ifdef _POSIX_SOURCE +# include <limits.h> +# else +# define _POSIX_SOURCE +# include <limits.h> +# undef _POSIX_SOURCE +# endif +#endif +#ifndef SIZE_MAX +# ifdef ULONG_MAX +# define SIZE_MAX ULONG_MAX +# else +# define SIZE_MAX UINT_MAX +# endif +#endif +#ifndef OPEN_MAX +#if defined(SVR4) || defined(__UNIXOS2__) +#define OPEN_MAX 256 +#else +#include <sys/param.h> +#ifndef OPEN_MAX +#ifdef __OSF1__ +#define OPEN_MAX 256 +#else +#ifdef NOFILE +#define OPEN_MAX NOFILE +#else +#define OPEN_MAX NOFILES_MAX +#endif +#endif +#endif +#endif +#endif + +#if OPEN_MAX > 256 +#define FONT_OPEN_MAX 256 +#else +#define FONT_OPEN_MAX OPEN_MAX +#endif + +#endif /* FONT_OPEN_MAX */ + +#ifdef WORD64 +#define NMSKBITS 64 +#else +#define NMSKBITS 32 +#endif + +#define MSKCNT ((FONT_OPEN_MAX + NMSKBITS - 1) / NMSKBITS) + +typedef unsigned long FdSet[MSKCNT]; +typedef FdSet FdSetPtr; + +#if (MSKCNT==1) +#define BITMASK(i) (1 << (i)) +#define MASKIDX(i) 0 +#endif + +#if (MSKCNT>1) +#define BITMASK(i) (1 << ((i) & (NMSKBITS - 1))) +#define MASKIDX(i) ((i) / NMSKBITS) +#endif + +#define MASKWORD(buf, i) buf[MASKIDX(i)] +#define BITSET(buf, i) MASKWORD(buf, i) |= BITMASK(i) +#define BITCLEAR(buf, i) MASKWORD(buf, i) &= ~BITMASK(i) +#define GETBIT(buf, i) (MASKWORD(buf, i) & BITMASK(i)) + +#if (MSKCNT==1) +#define COPYBITS(src, dst) dst[0] = src[0] +#define CLEARBITS(buf) buf[0] = 0 +#define MASKANDSETBITS(dst, b1, b2) dst[0] = (b1[0] & b2[0]) +#define ORBITS(dst, b1, b2) dst[0] = (b1[0] | b2[0]) +#define UNSETBITS(dst, b1) (dst[0] &= ~b1[0]) +#define ANYSET(src) (src[0]) +#endif + +#if (MSKCNT==2) +#define COPYBITS(src, dst) { dst[0] = src[0]; dst[1] = src[1]; } +#define CLEARBITS(buf) { buf[0] = 0; buf[1] = 0; } +#define MASKANDSETBITS(dst, b1, b2) {\ + dst[0] = (b1[0] & b2[0]);\ + dst[1] = (b1[1] & b2[1]); } +#define ORBITS(dst, b1, b2) {\ + dst[0] = (b1[0] | b2[0]);\ + dst[1] = (b1[1] | b2[1]); } +#define UNSETBITS(dst, b1) {\ + dst[0] &= ~b1[0]; \ + dst[1] &= ~b1[1]; } +#define ANYSET(src) (src[0] || src[1]) +#endif + +#if (MSKCNT==3) +#define COPYBITS(src, dst) { dst[0] = src[0]; dst[1] = src[1]; \ + dst[2] = src[2]; } +#define CLEARBITS(buf) { buf[0] = 0; buf[1] = 0; buf[2] = 0; } +#define MASKANDSETBITS(dst, b1, b2) {\ + dst[0] = (b1[0] & b2[0]);\ + dst[1] = (b1[1] & b2[1]);\ + dst[2] = (b1[2] & b2[2]); } +#define ORBITS(dst, b1, b2) {\ + dst[0] = (b1[0] | b2[0]);\ + dst[1] = (b1[1] | b2[1]);\ + dst[2] = (b1[2] | b2[2]); } +#define UNSETBITS(dst, b1) {\ + dst[0] &= ~b1[0]; \ + dst[1] &= ~b1[1]; \ + dst[2] &= ~b1[2]; } +#define ANYSET(src) (src[0] || src[1] || src[2]) +#endif + +#if (MSKCNT==4) +#define COPYBITS(src, dst) dst[0] = src[0]; dst[1] = src[1]; \ + dst[2] = src[2]; dst[3] = src[3] +#define CLEARBITS(buf) buf[0] = 0; buf[1] = 0; buf[2] = 0; buf[3] = 0 +#define MASKANDSETBITS(dst, b1, b2) \ + dst[0] = (b1[0] & b2[0]);\ + dst[1] = (b1[1] & b2[1]);\ + dst[2] = (b1[2] & b2[2]);\ + dst[3] = (b1[3] & b2[3]) +#define ORBITS(dst, b1, b2) \ + dst[0] = (b1[0] | b2[0]);\ + dst[1] = (b1[1] | b2[1]);\ + dst[2] = (b1[2] | b2[2]);\ + dst[3] = (b1[3] | b2[3]) +#define UNSETBITS(dst, b1) \ + dst[0] &= ~b1[0]; \ + dst[1] &= ~b1[1]; \ + dst[2] &= ~b1[2]; \ + dst[3] &= ~b1[3] +#define ANYSET(src) (src[0] || src[1] || src[2] || src[3]) +#endif + +#if (MSKCNT>4) +#define COPYBITS(src, dst) memmove((caddr_t) dst, (caddr_t) src,\ + MSKCNT*sizeof(long)) +#define CLEARBITS(buf) bzero((caddr_t) buf, MSKCNT*sizeof(long)) +#define MASKANDSETBITS(dst, b1, b2) \ + { int cri; \ + for (cri=MSKCNT; --cri>=0; ) \ + dst[cri] = (b1[cri] & b2[cri]); } +#define ORBITS(dst, b1, b2) \ + { int cri; \ + for (cri=MSKCNT; --cri>=0; ) \ + dst[cri] = (b1[cri] | b2[cri]); } +#define UNSETBITS(dst, b1) \ + { int cri; \ + for (cri=MSKCNT; --cri>=0; ) \ + dst[cri] &= ~b1[cri]; } +#if (MSKCNT==8) +#define ANYSET(src) (src[0] || src[1] || src[2] || src[3] || \ + src[4] || src[5] || src[6] || src[7]) +#endif +#endif + +#else /* not WIN32 */ + +#include <X11/Xwinsock.h> +#include <X11/Xw32defs.h> + +typedef fd_set FdSet; +typedef FdSet *FdSetPtr; + +#define CLEARBITS(set) FD_ZERO(&set) +#define BITSET(set,s) FD_SET(s,&set) +#define BITCLEAR(set,s) FD_CLR(s,&set) +#define GETBIT(set,s) FD_ISSET(s,&set) +#define ANYSET(set) set->fd_count + +#endif diff --git a/nx-X11/lib/font/fontcache/Imakefile b/nx-X11/lib/font/fontcache/Imakefile new file mode 100644 index 000000000..1c8526d6c --- /dev/null +++ b/nx-X11/lib/font/fontcache/Imakefile @@ -0,0 +1,29 @@ +XCOMM Id: Imakefile,v 1.2 1999/01/31 13:02:46 akiyama Exp $ + + + +XCOMM $XFree86$ + +#include <Server.tmpl> + +#if BuildFontCache +FONTCACHE_DEFINES = FontCacheExtensionDefines +#endif + INCLUDES = -I. -I$(FONTINCSRC) -I../include + HEADERS = + SRCS = fontcache.c + OBJS = fontcache.o + +#define DoNormalLib NormalLibFont +#define DoSharedLib SharedLibFont +#define DoDebugLib DebugLibFont +#define DoProfileLib ProfileLibFont +#include <Library.tmpl> +LibraryObjectRule() + +SpecialCLibObjectRule(fontcache,$(ICONFIGFILES),$(FONTCACHE_DEFINES)) + +SubdirLibraryRule($(OBJS)) +NormalLintTarget($(SRCS)) + +DependTarget() diff --git a/nx-X11/lib/font/fontcache/fcqueue.h b/nx-X11/lib/font/fontcache/fcqueue.h new file mode 100644 index 000000000..58ba6dfa1 --- /dev/null +++ b/nx-X11/lib/font/fontcache/fcqueue.h @@ -0,0 +1,133 @@ +/* + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)queue.h 8.5 (Berkeley) 8/20/94 + * $_Id_: queue.h,v 1.10.2.4 1998/05/12 16:35:25 bde Exp $ + * + * ---------------------------------------------------------------------- + * + * Note: + * This header file derived from FreeBSD-2.2.7 + * /usr/include/sys/queue.h, modified for X-TrueType Server by + * Shunsuke Akiyama <akiyama@jp.FreeBSD.org>. + * + * Id: fcqueue.h,v 1.1 1999/01/06 13:36:42 akiyama Exp $ + */ + +#ifndef _FCQUEUE_H_ +#define _FCQUEUE_H_ + +/* + * Tail queue definitions. + */ +#define TAILQ_HEAD(name, type) \ +struct name { \ + struct type *tqh_first; /* first element */ \ + struct type **tqh_last; /* addr of last next element */ \ +} + +#define TAILQ_HEAD_INITIALIZER(head) \ + { NULL, &(head).tqh_first } + +#define TAILQ_ENTRY(type) \ +struct { \ + struct type *tqe_next; /* next element */ \ + struct type **tqe_prev; /* address of previous next element */ \ +} + +/* + * Tail queue functions. + */ +#define TAILQ_EMPTY(head) ((head)->tqh_first == NULL) + +#define TAILQ_FOREACH(var, head, field) \ + for (var = TAILQ_FIRST(head); var; var = TAILQ_NEXT(var, field)) + +#define TAILQ_FIRST(head) ((head)->tqh_first) + +#define TAILQ_LAST(head, headname) \ + (*(((struct headname *)((head)->tqh_last))->tqh_last)) + +#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next) + +#define TAILQ_PREV(elm, headname, field) \ + (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last)) + +#define TAILQ_INIT(head) do { \ + (head)->tqh_first = NULL; \ + (head)->tqh_last = &(head)->tqh_first; \ +} while (0) + +#define TAILQ_INSERT_HEAD(head, elm, field) do { \ + if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \ + (head)->tqh_first->field.tqe_prev = \ + &(elm)->field.tqe_next; \ + else \ + (head)->tqh_last = &(elm)->field.tqe_next; \ + (head)->tqh_first = (elm); \ + (elm)->field.tqe_prev = &(head)->tqh_first; \ +} while (0) + +#define TAILQ_INSERT_TAIL(head, elm, field) do { \ + (elm)->field.tqe_next = NULL; \ + (elm)->field.tqe_prev = (head)->tqh_last; \ + *(head)->tqh_last = (elm); \ + (head)->tqh_last = &(elm)->field.tqe_next; \ +} while (0) + +#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \ + if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\ + (elm)->field.tqe_next->field.tqe_prev = \ + &(elm)->field.tqe_next; \ + else \ + (head)->tqh_last = &(elm)->field.tqe_next; \ + (listelm)->field.tqe_next = (elm); \ + (elm)->field.tqe_prev = &(listelm)->field.tqe_next; \ +} while (0) + +#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \ + (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \ + (elm)->field.tqe_next = (listelm); \ + *(listelm)->field.tqe_prev = (elm); \ + (listelm)->field.tqe_prev = &(elm)->field.tqe_next; \ +} while (0) + +#define TAILQ_REMOVE(head, elm, field) do { \ + if (((elm)->field.tqe_next) != NULL) \ + (elm)->field.tqe_next->field.tqe_prev = \ + (elm)->field.tqe_prev; \ + else \ + (head)->tqh_last = (elm)->field.tqe_prev; \ + *(elm)->field.tqe_prev = (elm)->field.tqe_next; \ +} while (0) + +#endif /* _FCQUEUE_H_ */ diff --git a/nx-X11/lib/font/fontcache/fontcache.c b/nx-X11/lib/font/fontcache/fontcache.c new file mode 100644 index 000000000..40cfd63c2 --- /dev/null +++ b/nx-X11/lib/font/fontcache/fontcache.c @@ -0,0 +1,1022 @@ +/*- + * Copyright (c) 1998-1999 Shunsuke Akiyama <akiyama@jp.FreeBSD.org>. + * All rights reserved. + * Copyright (c) 1998-1999 X-TrueType Server Project, All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * Id: fontcache.c,v 1.19 1999/01/31 13:06:00 akiyama Exp $ + */ +/* $XFree86: xc/lib/font/fontcache/fontcache.c,v 1.4 2001/04/05 17:42:28 dawes Exp $ */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "fontcache.h" + +#define LOW_MARK 0 +#define HI_MARK 1 + +#define PURGE_ENTRY 1 +#define PURGE_BITMAP 2 + +typedef struct { + long hiMark; /* Cache hi water mark */ + long lowMark; /* Cache low water mark */ + long allocated; /* Cache allocated size */ + long used; /* Cache used size */ +} FontCacheSize_t; + +static int CacheInitialized = 0; + +static TAILQ_HEAD(FcInUseQueue, cache_entry) InUseQueueHead, *InUseQueue; +static TAILQ_HEAD(FcFreeQueue, cache_entry) FreeQueueHead, *FreeQueue; +static FCBCB FreeBitmapHead, *FreeBitmap; + +static long CacheHiMark; +static long CacheLowMark; +static int CacheBalance; +static FontCacheSize_t HashSize; +static FontCacheSize_t AllocSize; +static int NeedPurgeCache; +static FontCacheStatistics CacheStatistics; + +static void fc_assign_cache(void); +static int fc_assign_entry(void); +static void fc_flush_cache(void); +static int fc_get_bitmap_area(FontCacheEntryPtr, int); +static void fc_free_bitmap_area(FontCacheBitmapPtr); +static int fc_check_size(int); +static void fc_purge_cache(void); +static void fc_purge_bitmap(void); +static void fc_flush_cache_bitmap(void); +static void fc_flush_cache_inuse(void); +static void fc_flush_cache_free(void); +static void fc_purge_cache_entry(void); +static void fc_purge_cache_entry_pool(void); +static void fc_purge_bitmap_pool(void); + + +/* + * FontCacheInitialize() + * + * Initialize cache work area. + */ + +int +FontCacheInitialize() +{ +#ifdef FONTCACHE + int i; + + if (!CacheInitialized) { + /* + * first time initialization + */ +#if defined(HASH_DEBUG) || defined(DEBUG) + fprintf(stderr, "FontCacheInitialize: initializing cache\n"); +#endif + InUseQueue = &InUseQueueHead; + TAILQ_INIT(InUseQueue); + + FreeQueue = &FreeQueueHead; + TAILQ_INIT(FreeQueue); + + FreeBitmap = &FreeBitmapHead; + FreeBitmap->index = 0; + for (i = 0; i < FC_MEM_HASH_SIZE; i++) { + TAILQ_INIT(&FreeBitmap->head[i]); + } + + CacheHiMark = FC_DEFAULT_CACHE_SIZE * 1024; /* temporary */ + CacheLowMark = (CacheHiMark / 4) * 3; + CacheBalance = FC_CACHE_BALANCE; + + NeedPurgeCache = 0; + + HashSize.allocated = HashSize.used = 0; + AllocSize.allocated = AllocSize.used = 0; + fc_assign_cache(); + fc_assign_entry(); +#if defined(DEBUG) + fprintf(stderr, "FontCacheInitialize: hi=%ld, lo=%ld, bal=%d\n", + CacheHiMark, CacheLowMark, CacheBalance); +#endif + + CacheInitialized = 1; + } else { + /* + * second time or later case. + * flush and reassign cache. + */ +#if defined(HASH_DEBUG) || defined(DEBUG) + fprintf(stderr, "FontCacheInitialize: initializing cache, again\n"); +#endif + } + + memset(&CacheStatistics, 0, sizeof (CacheStatistics)); +#endif /* FONTCACHE */ + + return 0; /* make lint happy */ +} + +/* + * FontCacheChangeSettings() + * + * Change cache size and reinitialize work areas. + * + * Returns 0, if memory allocation failed. Otherwise 1. + */ + +int +FontCacheChangeSettings(FontCacheSettingsPtr cs) +{ + int result; + + if (!CacheInitialized) { + FontCacheInitialize(); + if (!CacheInitialized) + return 0; + } + +#if defined(HASH_DEBUG) || defined(DEBUG) +fprintf(stderr, + "FontCahceChangeSettings: hi-mark=%ld, low-mark=%ld, balance=%ld\n", + cs->himark, cs->lowmark, cs->balance); +#endif + + fc_flush_cache(); + + CacheHiMark = cs->himark; + CacheLowMark = cs->lowmark; + CacheBalance = cs->balance; + + fc_assign_cache(); + result = fc_assign_entry(); + + return result; +} + +/* + * FontCacheGetSettings() + * + * Get current cache control parameters. + */ + +void +FontCacheGetSettings(FontCacheSettingsPtr cs) +{ + if (!CacheInitialized) { + FontCacheInitialize(); + if (!CacheInitialized) + return; + } + + cs->himark = CacheHiMark; + cs->lowmark = CacheLowMark; + cs->balance = CacheBalance; +} + +/* + * FontCacheGetStatistics() + * + * Get current cache statistics. + */ + +void +FontCacheGetStatistics(FontCacheStatisticsPtr cs) +{ + if (!CacheInitialized) { + FontCacheInitialize(); + if (!CacheInitialized) + return; + } + + CacheStatistics.purge_stat = NeedPurgeCache; + CacheStatistics.balance = CacheBalance; + CacheStatistics.f.usage = HashSize.used; + CacheStatistics.v.usage = AllocSize.used; + + memcpy(cs, &CacheStatistics, sizeof (CacheStatistics)); +} + +/* + * FontCacheOpenCache() + * + * Allocate font cache control block and initialize it. + * + * Returns pointer to font cache control block. Or returns NULL when + * detected illegal parameter or memory allocation failed. + */ + +FCCBPtr +FontCacheOpenCache(void *arg) +{ + int linesize; + FCCBPtr this; + int size = 0, mask = 0; + int i; + + static int sizes[] = { 16, 32, 64, 128, 0 }; + + if (!CacheInitialized) { + FontCacheInitialize(); + if (!CacheInitialized) + return NULL; + } + + linesize = (long)arg; +#if defined(HASH_DEBUG) || defined(DEBUG) +fprintf(stderr, "FontCacheOpenCache: line size=%d\n", linesize); +#endif + + for (i = 0; sizes[i] != 0; i++) { + if (sizes[i] == linesize) { + size = linesize; + mask = linesize - 1; + break; + } + } + if (sizes[i] == 0) { + return NULL; + } + + this = (FCCBPtr) malloc(sizeof (FCCB)); + if (this != NULL) { + memset(this, 0, sizeof (FCCB)); + this->head = (FontCacheHeadPtr) malloc(sizeof (FontCacheHead) * size); + if (this->head == NULL) { + free(this); + this = NULL; + } else { + this->size = size; + this->mask = mask; + for (i = 0; i < size; i++) { + TAILQ_INIT(&this->head[i]); + } + } + } + + return this; +} + +/* + * FontCacheCloseCache() + * + * Release font cache control block and all it's related entries. + */ + +void +FontCacheCloseCache(FCCBPtr this) +{ + FontCacheEntryPtr entry, next; + int i; + int size; + + if (!CacheInitialized) { + return; + } + + size = this->size; + for (i = 0; i < size; i++) { + entry = TAILQ_FIRST(&this->head[i]); + while (entry != NULL) { + /* remove entry from in-use queue, here */ + TAILQ_REMOVE(InUseQueue, entry, c_lru); + + /* remove entry from the hash */ + if (entry->bitmapsize > FC_SMALL_BITMAP_SIZE + && entry->charInfo.bits != NULL) { + fc_free_bitmap_area(entry->bmp); + } + entry->charInfo.bits = NULL; + entry->bitmapsize = 0; + + next = TAILQ_NEXT(entry, c_hash); + TAILQ_INSERT_HEAD(FreeQueue, entry, c_lru); + HashSize.used -= sizeof (FontCacheEntry); + entry = next; + } + } + + free(this->head); + free(this); +} + +/* + * FontCacheGetEntry() + * + * Allocate font cache entry and initialize it. + */ + +FontCacheEntryPtr +FontCacheGetEntry() +{ + FontCacheEntryPtr entry; + FontCacheEntryPtr p; + long size; + + /* scan in-use queue and purge if required */ + fc_purge_cache(); + + /* allocate hash entry */ + if (TAILQ_EMPTY(FreeQueue)) { + size = sizeof (FontCacheEntry); + p = (FontCacheEntryPtr) malloc(size); + if (p != NULL) { + TAILQ_INSERT_HEAD(FreeQueue, p, c_lru); + HashSize.allocated += size; +#if defined(HASH_DEBUG) || defined(DEBUG) +fprintf(stderr, "FontCachegetEntry: allocated new entry\n"); +#endif + } + } + + if (!TAILQ_EMPTY(FreeQueue)) { + entry = TAILQ_FIRST(FreeQueue); + TAILQ_REMOVE(FreeQueue, entry, c_lru); + memset(entry, 0, sizeof (FontCacheEntry)); + } else { + entry = NULL; + } + + return entry; +} + +/* + * FontCacheGetBitmap() + * + * Allocate font glyph bitmap area. + * + * Note: + * Allocated area should be cleared. + */ + +int +FontCacheGetBitmap(FontCacheEntryPtr entry, int size) +{ + int oldsize; + int result; + + /* XXX */ + if ((AllocSize.used > AllocSize.hiMark - size) && + (size > FC_SMALL_BITMAP_SIZE)) { + fc_purge_bitmap(); + } + + if (size < 0) /* wrong size */ + return 0; + + result = 0; + oldsize = entry->bitmapsize; + if (size <= FC_SMALL_BITMAP_SIZE) { + /* use coresponding bitmap area */ + if (oldsize > FC_SMALL_BITMAP_SIZE) { + /* We don't need allocated area anymore */ + fc_free_bitmap_area(entry->bmp); + } + entry->bitmapsize = size; + if (size > 0) { + entry->charInfo.bits = entry->bitmap; + memset(entry->charInfo.bits, 0, size); + } else + entry->charInfo.bits = NULL; + + result = 1; + } else { + /* need extra bitmap area */ + if (entry->charInfo.bits == NULL) { + /* no any extra bitmap area */ + if (fc_get_bitmap_area(entry, size)) { + entry->bitmapsize = size; + memset(entry->charInfo.bits, 0, size); + if (fc_check_size(HI_MARK)) { + fc_purge_cache(); + } + result = 1; + } + } else { + /* we already have extra bitmap area */ + if (oldsize == size) { + /* same size, reuse it */ + memset(entry->charInfo.bits, 0, size); + result = 1; + } else { + /* different size */ + fc_free_bitmap_area(entry->bmp); + if (fc_get_bitmap_area(entry, size)) { + entry->bitmapsize = size; + memset(entry->charInfo.bits, 0, size); + if (fc_check_size(HI_MARK)) { + fc_purge_cache(); + } + result = 1; + } + } + } + } + + return result; +} + +/* + * FontCacheSearchEntry() + * + * Search an entry matched with the key from the hash. + */ + +int +FontCacheSearchEntry(FCCBPtr this, int key, FontCacheEntryPtr *value) +{ + FontCacheHeadPtr head; + FontCacheEntryPtr entry; + int index; + + index = key & this->mask; + head = &this->head[index]; + + TAILQ_FOREACH(entry, head, c_hash) { + if (entry->key == key) { + /* found, change position */ + CacheStatistics.f.hits++; + + TAILQ_REMOVE(InUseQueue, entry, c_lru); + TAILQ_INSERT_HEAD(InUseQueue, entry, c_lru); + + TAILQ_REMOVE(head, entry, c_hash); + TAILQ_INSERT_HEAD(head, entry, c_hash); + + /* purge least recentrly used cache entirs */ + fc_purge_cache(); + + *value = entry; + return 1; + } + } + + /* purge least recentrly used cache entirs */ + fc_purge_cache(); + + /* not found */ + CacheStatistics.f.misshits++; + *value = NULL; + return 0; +} + +/* + * FontCacheInsertEntry() + * + * Insert an entry into the cache pool. + */ + +int +FontCacheInsertEntry(FCCBPtr this, int key, FontCacheEntryPtr entry) +{ + FontCacheHeadPtr head; + int index; + + index = key & this->mask; + head = &this->head[index]; + + entry->key = key; + entry->c_head = head; + TAILQ_INSERT_HEAD(head, entry, c_hash); + + /* insert entry into in-use queue */ + TAILQ_INSERT_HEAD(InUseQueue, entry, c_lru); + + /* adjust cache in-use size */ + HashSize.used += sizeof (FontCacheEntry); + if (fc_check_size(HI_MARK)) { + fc_purge_cache(); + } + + return 1; +} + +/* + * fc_assign_cache() + * + * Assign cache size considered with cache balance rate. + */ + +static void +fc_assign_cache() +{ + HashSize.hiMark = (CacheHiMark * CacheBalance) / 100; + HashSize.lowMark = (CacheLowMark * CacheBalance) / 100; + + AllocSize.hiMark = (CacheHiMark * (100 - CacheBalance)) / 100; + AllocSize.lowMark = (CacheLowMark * (100 - CacheBalance)) / 100; +} + +/* + * fc_assign_entry() + * + * Assign cache entry into free queue. + * + * Returns 0, when memory allocation failed. Otherwise 1. + */ + +static int +fc_assign_entry() +{ + FontCacheEntryPtr entry; + long used; + int result = 1; + + used = 0; + while ((used + sizeof (FontCacheEntry)) < HashSize.hiMark) { + entry = (FontCacheEntryPtr) malloc(sizeof (FontCacheEntry)); + if (entry == NULL) { + fprintf(stderr, "fc_assign_entry: can't allocate memory.\n"); + result = 0; + break; + } + TAILQ_INSERT_HEAD(FreeQueue, entry, c_lru); + used += sizeof (FontCacheEntry); + HashSize.allocated += sizeof (FontCacheEntry); + } + + return result; +} + +/* + * fc_get_bitmap_area() + * + * Search allocated memory area from free bitmap hash pool. If there + * is no entry, then allocate new bitmap area. + * + * Returns 0, when memory allocation failed, otherwise 1. And some + * sort of cache entry structure members were updated. + */ + +static int +fc_get_bitmap_area(FontCacheEntryPtr this, int size) +{ + FontCacheBitmapHeadPtr head; + FontCacheBitmapPtr bitmap; + int index; + int result = 0; + + index = size & FC_MEM_HASH_MASK; + head = &FreeBitmap->head[index]; + TAILQ_FOREACH(bitmap, head, b_hash) { + if (bitmap->key == size) { + TAILQ_REMOVE(head, bitmap, b_hash); + this->bmp = bitmap; + this->charInfo.bits = (char *) (bitmap + 1); + bitmap->b_entry = this; + result = 1; + CacheStatistics.v.hits++; + AllocSize.used += (size + sizeof (FontCacheBitmap)); +#if defined(HASH_DEBUG) || defined(DEBUG) +fprintf(stderr, "fc_get_bitmap_area: bitmap entry found in pool\n"); +#endif + break; + } + } + + if (result == 0) { + CacheStatistics.v.misshits++; + bitmap = (FontCacheBitmapPtr) malloc(size + sizeof (FontCacheBitmap)); + if (bitmap != NULL) { + bitmap->b_entry = this; + bitmap->size = size + sizeof (FontCacheBitmap); + bitmap->key = size; + this->bmp = bitmap; + this->charInfo.bits = (char *) (bitmap + 1); + AllocSize.allocated += (size + sizeof (FontCacheBitmap)); + AllocSize.used += (size + sizeof (FontCacheBitmap)); + result = 1; +#if defined(HASH_DEBUG) || defined(DEBUG) +fprintf(stderr, "fc_get_bitmap_area: bitmap entry allocated\n"); +#endif + } else { + this->bmp = NULL; + this->charInfo.bits = NULL; + } + } + + return result; +} + +/* + * fc_free_bitmap_area() + * + * Release allocated bitmap area into free hash pool. + */ + +static void +fc_free_bitmap_area(FontCacheBitmapPtr this) +{ + FontCacheBitmapHeadPtr head; + FontCacheEntryPtr entry; + int index; + +#if defined(HASH_DEBUG) || defined(DEBUG) +fprintf(stderr, "fc_free_bitmap_area: bitmap entry returns into pool\n"); +#endif + + index = this->key & FC_MEM_HASH_MASK; + head = &FreeBitmap->head[index]; + TAILQ_INSERT_HEAD(head, this, b_hash); + + AllocSize.used -= this->size; + + entry = this->b_entry; + entry->bmp = NULL; + entry->bitmapsize = 0; +} + +/* + * fc_flush_cache_bitmap() + * + * Flush all allocated bitmap area from the free hash pool. + */ + +static void +fc_flush_cache_bitmap() +{ + FontCacheBitmapHeadPtr head; + FontCacheBitmapPtr bitmap; + int i; + + for (i = 0; i < FC_MEM_HASH_SIZE; i++) { + head = &FreeBitmap->head[i]; + while (!TAILQ_EMPTY(head)) { + bitmap = TAILQ_FIRST(head); + TAILQ_REMOVE(head, bitmap, b_hash); + + AllocSize.allocated -= bitmap->size; + free(bitmap); + } + } +} + +/* + * fc_flush_cache_inuse() + * + * Release all in-use cache entries. + */ + +static void +fc_flush_cache_inuse() +{ + FontCacheEntryPtr entry; + FontCacheHeadPtr head; + + while (!TAILQ_EMPTY(InUseQueue)) { + /* remove this entry from in-use queue */ + entry = TAILQ_FIRST(InUseQueue); + TAILQ_REMOVE(InUseQueue, entry, c_lru); + + /* remove this entry from hash */ + head = entry->c_head; + TAILQ_REMOVE(head, entry, c_hash); + + /* release bitmap area */ + if (entry->bitmapsize > FC_SMALL_BITMAP_SIZE + && entry->charInfo.bits != NULL) { + fc_free_bitmap_area(entry->bmp); + } + entry->charInfo.bits = NULL; + entry->bitmapsize = 0; + + /* release font-specific private area */ + if ( entry->vfuncs && entry->vfuncs->f_private_dispose ) + (*entry->vfuncs->f_private_dispose)(entry->f_private); + entry->f_private = NULL; + entry->vfuncs = NULL; + + /* add this entry to free queue */ + TAILQ_INSERT_HEAD(FreeQueue, entry, c_lru); + + /* adjust size */ + HashSize.used -= sizeof (FontCacheEntry); + } +} + +/* + * fc_flush_cache_free() + * + * Flush all free cache entries from the free cache queue. + */ + +static void +fc_flush_cache_free() +{ + FontCacheEntryPtr entry; + + /* release entire entries of the free queue */ + while (!TAILQ_EMPTY(FreeQueue)) { + entry = TAILQ_FIRST(FreeQueue); + TAILQ_REMOVE(FreeQueue, entry, c_lru); + free(entry); + HashSize.allocated -= sizeof (FontCacheEntry); + } +} + +/* + * fc_flush_cache() + * + * Flush all cache entries and allocated bitmap area from the pool. + */ + +static void +fc_flush_cache() +{ + fc_flush_cache_inuse(); + fc_flush_cache_bitmap(); + fc_flush_cache_free(); + + memset(&CacheStatistics, 0, sizeof (CacheStatistics)); +} + +/* + * fc_check_size() + * + * Check cache size, then return it's result. + */ + +static int +fc_check_size(int mark) +{ + int result = 0; + + if (mark == LOW_MARK) { + if (HashSize.used > HashSize.lowMark) { + result |= PURGE_ENTRY; + } + if (AllocSize.used > AllocSize.lowMark) { + result |= PURGE_BITMAP; + } + } else { + if (HashSize.used > HashSize.hiMark) { + result |= PURGE_ENTRY; + } + if (AllocSize.used > AllocSize.hiMark) { + result |= PURGE_BITMAP; + } + } + + return result; +} + +/* + * fc_purge_cache_entry() + * + * Purge least recently used cache entry. + */ + +static void +fc_purge_cache_entry() +{ + FontCacheHeadPtr head; + FontCacheEntryPtr entry; + int i; + + for (i = 0; i < FC_PURGE_PER_SCAN; i++) { + /* get least recently used entry */ + entry = TAILQ_LAST(InUseQueue, FcInUseQueue); + +#if defined(HASH_DEBUG) || defined(DEBUG) +fprintf(stderr, "fc_purge_cache_entry: purged: %p, %d\n", + entry, entry->key); +#endif + + /* remove this entry from in-use queue */ + TAILQ_REMOVE(InUseQueue, entry, c_lru); + + /* remove this entry from the hash */ + head = entry->c_head; + TAILQ_REMOVE(head, entry, c_hash); + + /* release bitmap area */ + if (entry->bitmapsize > FC_SMALL_BITMAP_SIZE + && entry->charInfo.bits != NULL) { + fc_free_bitmap_area(entry->bmp); + CacheStatistics.v.purged++; + } + entry->charInfo.bits = NULL; + entry->bitmapsize = 0; + + /* release font-specific private area */ + if ( entry->vfuncs && entry->vfuncs->f_private_dispose ) + (*entry->vfuncs->f_private_dispose)(entry->f_private); + entry->f_private = NULL; + entry->vfuncs = NULL; + + /* add this entry to free queue */ + TAILQ_INSERT_HEAD(FreeQueue, entry, c_lru); + + HashSize.used -= sizeof (FontCacheEntry); + CacheStatistics.f.purged++; + } +} + +/* + * fc_purge_cache_entry_pool() + * + * Purge free cache entries, to adjust cache size. + */ + +static void +fc_purge_cache_entry_pool() +{ + FontCacheEntryPtr entry; + + while (!TAILQ_EMPTY(FreeQueue)) { + entry = TAILQ_LAST(FreeQueue, FcFreeQueue); + TAILQ_REMOVE(FreeQueue, entry, c_lru); +#if defined(HASH_DEBUG) || defined(DEBUG) +fprintf(stderr, "fc_purge_cache_entry_pool: purged from free queue: %p\n", + entry); +#endif + HashSize.allocated -= sizeof (FontCacheEntry); + free(entry); + if (HashSize.allocated <= HashSize.hiMark) { + break; + } + } +} + +/* + * fc_purge_bitmap() + * + * Purge least recently used allocated bitmap area. + */ + +static void +fc_purge_bitmap() +{ + FontCacheEntryPtr entry, first; + int purged = 0; + + /* release used entry, if required */ + first = TAILQ_FIRST(InUseQueue); + if (first != NULL) { + entry = TAILQ_LAST(InUseQueue, FcInUseQueue); + while (purged < FC_PURGE_PER_SCAN) { + if (entry->bmp != NULL) { +#if defined(HASH_DEBUG) || defined(DEBUG) +fprintf(stderr, "fc_purge_bitmap: purged from live queue: %p, %d(%d)\n", + entry->bmp, entry->bmp->key, entry->bmp->size); +#endif + fc_free_bitmap_area(entry->bmp); + entry->charInfo.bits = NULL; + CacheStatistics.v.purged++; + purged++; + } + if (entry == first) { + break; + } + entry = TAILQ_PREV(entry, FcInUseQueue, c_lru); + } + } +} + +/* + * fc_purge_bitmap_pool() + * + * Purge free bitmap area from pool, to adjust cache size. + */ + +static void +fc_purge_bitmap_pool() +{ + int this, stop, quit; + FontCacheBitmapHeadPtr head; + FontCacheBitmapPtr bitmap; + + /* release free bitmap entry */ + this = FreeBitmap->index; + stop = this; + quit = 0; + + do { + head = &FreeBitmap->head[this]; + while (!TAILQ_EMPTY(head)) { + bitmap = TAILQ_LAST(head, fcmem_head); + TAILQ_REMOVE(head, bitmap, b_hash); +#if defined(HASH_DEBUG) || defined(DEBUG) +fprintf(stderr, "fc_purge_bitmap_pool: purged from pool: %p, %d(%d)\n", + bitmap, bitmap->key, bitmap->size); +#endif + AllocSize.allocated -= bitmap->size; + free(bitmap); + if (AllocSize.allocated <= AllocSize.hiMark) { + quit = 1; + break; + } + } + this++; + this &= FC_MEM_HASH_MASK; + } while (this != stop && quit == 0); + + FreeBitmap->index++; + FreeBitmap->index &= FC_MEM_HASH_MASK; +} + +/* + * fc_purge_cache() + * + * Purge font cache, if required. + */ + +static void +fc_purge_cache() +{ + int strategy; + + if (NeedPurgeCache) { + strategy = fc_check_size(LOW_MARK); + switch (strategy) { + case PURGE_ENTRY : + CacheStatistics.purge_runs++; + fc_purge_cache_entry(); + break; + case PURGE_BITMAP : + CacheStatistics.purge_runs++; + fc_purge_bitmap(); + break; + case (PURGE_ENTRY | PURGE_BITMAP) : + CacheStatistics.purge_runs++; + fc_purge_cache_entry(); + fc_purge_bitmap(); + break; + default : + NeedPurgeCache = 0; + break; + } + } else { + strategy = fc_check_size(HI_MARK); + switch (strategy) { + case PURGE_ENTRY : + if ((CacheBalance + FC_BALANCE_DIFFS) <= FC_BALANCE_HI) { + CacheBalance += FC_BALANCE_DIFFS; +#if defined(HASH_DEBUG) || defined(DEBUG) +fprintf(stderr, "fc_purge_cache: cache balance changed to %d\n", CacheBalance); +#endif + fc_assign_cache(); + fc_purge_bitmap_pool(); + } else { + CacheStatistics.purge_runs++; + NeedPurgeCache = 1; + while (fc_check_size(HI_MARK) & PURGE_ENTRY) { + fc_purge_cache_entry(); + } + } + break; + case PURGE_BITMAP : + if ((CacheBalance - FC_BALANCE_DIFFS) >= FC_BALANCE_LOW) { + CacheBalance -= FC_BALANCE_DIFFS; +#if defined(HASH_DEBUG) || defined(DEBUG) +fprintf(stderr, "fc_purge_cache: cache balance changed to %d\n", CacheBalance); +#endif + fc_assign_cache(); + fc_purge_cache_entry_pool(); + } else { + CacheStatistics.purge_runs++; + NeedPurgeCache = 1; + while (fc_check_size(HI_MARK) & PURGE_BITMAP) { + fc_purge_bitmap(); + } + } + break; + case (PURGE_ENTRY | PURGE_BITMAP) : + CacheStatistics.purge_runs++; + NeedPurgeCache = 1; + while (fc_check_size(HI_MARK)) { + fc_purge_cache_entry(); + fc_purge_bitmap(); + } + break; + default : + break; + } + } +} diff --git a/nx-X11/lib/font/fontcache/fontcache.h b/nx-X11/lib/font/fontcache/fontcache.h new file mode 100644 index 000000000..c95de25eb --- /dev/null +++ b/nx-X11/lib/font/fontcache/fontcache.h @@ -0,0 +1,121 @@ +/*- + * Copyright (c) 1998-1999 Shunsuke Akiyama <akiyama@jp.FreeBSD.org>. + * All rights reserved. + * Copyright (c) 1998-1999 X-TrueType Server Project, All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * Id: fontcache.h,v 1.12 1999/01/09 06:24:30 akiyama Exp $ + */ +/* $XFree86: xc/lib/font/fontcache/fontcache.h,v 1.6 2002/11/08 00:46:27 alanh Exp $ */ + +#ifndef _FONTCACHE_H_ +#define _FONTCACHE_H_ + +#include <X11/fonts/fontmisc.h> +#include <X11/fonts/fontstruct.h> +#include "fcqueue.h" +#define _FONTCACHE_SERVER_ +#include <X11/extensions/fontcacheP.h> + +/* constant declarations */ + +#ifndef FC_DEFAULT_CACHE_SIZE +#define FC_DEFAULT_CACHE_SIZE 5120 /* in KB */ +#endif + +#define FC_CACHE_BALANCE 70 /* in percentage */ +#define FC_BALANCE_LOW 10 /* in percentage */ +#define FC_BALANCE_HI 90 /* in percentage */ +#define FC_BALANCE_DIFFS 5 /* in percentage */ + +#define FC_SMALL_BITMAP_SIZE 128 + +#define FC_MEM_HASH_SIZE 256 +#define FC_MEM_HASH_MASK (FC_MEM_HASH_SIZE - 1) + +#define FC_PURGE_PER_SCAN 2 + +/* data type declarations */ + +struct cache_entry; +struct fcbitmap; + +TAILQ_HEAD(fchash_head, cache_entry); +TAILQ_HEAD(fcmem_head, fcbitmap); + +struct fcbitmap { + TAILQ_ENTRY(fcbitmap) b_hash; + struct cache_entry *b_entry; + int size; + int key; +}; + +struct fc_entry_vfuncs { + void (*f_private_dispose)(void *f_private); +}; + +struct cache_entry { + TAILQ_ENTRY(cache_entry) c_hash; /* Hash chain. */ + TAILQ_ENTRY(cache_entry) c_lru; /* Font cache LRU list chain. */ + struct fchash_head *c_head; /* Pointer to head. */ + int key; /* hash key */ + CharInfoRec charInfo; /* CharInfo record */ + struct fcbitmap *bmp; + void *f_private; /* Font-specific private data */ + struct fc_entry_vfuncs *vfuncs; /* virtual function table */ + int bitmapsize; /* Bitmap size */ + char bitmap[FC_SMALL_BITMAP_SIZE]; /* Small bitmap data area */ +}; + +struct fchash { + int size; + int mask; + struct fchash_head *head; +}; + +struct fcmemhash { + int index; + struct fcmem_head head[FC_MEM_HASH_SIZE]; +}; + +typedef struct fcbitmap FontCacheBitmap, *FontCacheBitmapPtr; +typedef struct cache_entry FontCacheEntry, *FontCacheEntryPtr; +typedef struct fchash_head FontCacheHead, *FontCacheHeadPtr; +typedef struct fcmem_head FontCacheBitmapHead, *FontCacheBitmapHeadPtr; +typedef struct fchash FCCB, *FCCBPtr; +typedef struct fcmemhash FCBCB, *FCBCBPtr; + +/* Function prototypes */ + +int FontCacheInitialize(void); +FCCBPtr FontCacheOpenCache(void * /* arg */); +void FontCacheCloseCache(FCCBPtr /* this */); +FontCacheEntryPtr FontCacheGetEntry(void); +int FontCacheSearchEntry(FCCBPtr /* this */, int /* key */, + FontCacheEntryPtr * /* value */); +int FontCacheInsertEntry(FCCBPtr /* this */, int /* key */, + FontCacheEntryPtr /* entry */); +int FontCacheGetBitmap(FontCacheEntryPtr /* entry */, + int /* size */); + +#endif /* _FONTCACHE_H_ */ diff --git a/nx-X11/lib/font/fontfile/Imakefile b/nx-X11/lib/font/fontfile/Imakefile new file mode 100644 index 000000000..fa075a951 --- /dev/null +++ b/nx-X11/lib/font/fontfile/Imakefile @@ -0,0 +1,81 @@ +XCOMM $Xorg: Imakefile,v 1.3 2000/08/17 19:46:36 cpqbld Exp $ + + + + +XCOMM $XFree86: xc/lib/font/fontfile/Imakefile,v 3.20 2001/11/03 23:03:00 dawes Exp $ + +#include <Server.tmpl> + +#if BuildServer && DoLoadableServer +#define IHaveSubdirs +#define NoLibSubdirs +SUBDIRS = module +#endif + + INCLUDES = -I$(FONTINCSRC) -I../include -I$(SERVERSRC)/include \ + -I$(INCLUDESRC) + HEADERS = +#ifdef FontFormatDefines +FORMAT_DEFS = FontFormatDefines +#endif + +#if BuildSpeedo +SPEEDO_DEFINES = -DBUILD_SPEEDO +#endif +#if BuildType1 +TYPE1_DEFINES = -DBUILD_TYPE1 +#endif +#if BuildCID +CID_DEFINES = -DBUILD_CID +#endif +#if BuildFreeType +FREETYPE_DEFINES = -DBUILD_FREETYPE +#endif + +#if FontencCompatibility + COMPAT_SRC = fontencc.c + COMPAT_OBJ = fontencc.o +#endif + +#if GzipFontCompression + GUNZIP_SRC = gunzip.c + GUNZIP_OBJ = gunzip.o + GZIP_DEFS = -DX_GZIP_FONT_COMPRESSION +#endif + +FONTENCDEFS = -DFONT_ENCODINGS_DIRECTORY=\"$(ENCODINGSDIR)/encodings.dir\" + + DEFINES = StrcasecmpDefines \ + $(SPEEDO_DEFINES) $(TYPE1_DEFINES) $(CID_DEFINES) \ + $(FREETYPE_DEFINES) $(FONTENCDEFS) \ + $(GZIP_DEFS) + + SRCS = dirfile.c fontdir.c fontfile.c fileio.c fontscale.c \ + defaults.c bitsource.c register.c renderers.c bufio.c \ + decompress.c filewr.c printerfont.c ffcheck.c \ + fontenc.c encparse.c $(COMPAT_SRC) $(GUNZIP_SRC) + OBJS = dirfile.o fontdir.o fontfile.o fileio.o fontscale.o \ + defaults.o bitsource.o register.o renderers.o bufio.o \ + decompress.o filewr.o printerfont.o ffcheck.o \ + fontenc.o encparse.o $(COMPAT_OBJ) $(GUNZIP_OBJ) + +#define DoNormalLib NormalLibFont +#define DoSharedLib SharedLibFont +#define DoDebugLib DebugLibFont +#define DoProfileLib ProfileLibFont +#include <Library.tmpl> +LibraryObjectRule() + +SpecialCLibObjectRule(fileio,$(ICONFIGFILES),$(GZIP_DEFS)) + +SubdirLibraryRule($(OBJS)) +NormalLintTarget($(SRCS)) + +#if BuildServer && DoLoadableServer +MakeSubdirs($(SUBDIRS)) +DependSubdirs($(SUBDIRS)) +#endif + +DependTarget() + diff --git a/nx-X11/lib/font/fontfile/bitsource.c b/nx-X11/lib/font/fontfile/bitsource.c new file mode 100644 index 000000000..ae27de8fe --- /dev/null +++ b/nx-X11/lib/font/fontfile/bitsource.c @@ -0,0 +1,174 @@ +/* $Xorg: bitsource.c,v 1.4 2001/02/09 02:04:03 xorgcvs Exp $ */ + +/* + +Copyright 1991, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ +/* $XFree86: xc/lib/font/fontfile/bitsource.c,v 1.3 2001/01/17 19:43:29 dawes Exp $ */ + +/* + * Author: Keith Packard, MIT X Consortium + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <X11/fonts/fntfilst.h> + +BitmapSourcesRec FontFileBitmapSources; + +Bool +FontFileRegisterBitmapSource (FontPathElementPtr fpe) +{ + FontPathElementPtr *new; + int i; + int newsize; + + for (i = 0; i < FontFileBitmapSources.count; i++) + if (FontFileBitmapSources.fpe[i] == fpe) + return TRUE; + if (FontFileBitmapSources.count == FontFileBitmapSources.size) + { + newsize = FontFileBitmapSources.size + 4; + new = (FontPathElementPtr *) xrealloc (FontFileBitmapSources.fpe, newsize * sizeof *new); + if (!new) + return FALSE; + FontFileBitmapSources.size = newsize; + FontFileBitmapSources.fpe = new; + } + FontFileBitmapSources.fpe[FontFileBitmapSources.count++] = fpe; + return TRUE; +} + +void +FontFileUnregisterBitmapSource (FontPathElementPtr fpe) +{ + int i; + + for (i = 0; i < FontFileBitmapSources.count; i++) + if (FontFileBitmapSources.fpe[i] == fpe) + { + FontFileBitmapSources.count--; + if (FontFileBitmapSources.count == 0) + { + FontFileBitmapSources.size = 0; + xfree (FontFileBitmapSources.fpe); + FontFileBitmapSources.fpe = 0; + } + else + { + for (; i < FontFileBitmapSources.count; i++) + FontFileBitmapSources.fpe[i] = FontFileBitmapSources.fpe[i+1]; + } + break; + } +} + +/* + * Our set_path_hook: unregister all bitmap sources. + * This is necessary because already open fonts will keep their FPEs + * allocated, but they may not be on the new font path. + * The bitmap sources in the new path will be registered by the init_func. + */ +void +FontFileEmptyBitmapSource(void) +{ + if (FontFileBitmapSources.count == 0) + return; + + FontFileBitmapSources.count = 0; + FontFileBitmapSources.size = 0; + xfree (FontFileBitmapSources.fpe); + FontFileBitmapSources.fpe = 0; +} + +int +FontFileMatchBitmapSource (FontPathElementPtr fpe, + FontPtr *pFont, + int flags, + FontEntryPtr entry, + FontNamePtr zeroPat, + FontScalablePtr vals, + fsBitmapFormat format, + fsBitmapFormatMask fmask, + Bool noSpecificSize) +{ + int source; + FontEntryPtr zero; + FontBitmapEntryPtr bitmap; + int ret; + FontDirectoryPtr dir; + FontScaledPtr scaled; + + /* + * Look through all the registered bitmap sources for + * the same zero name as ours; entries along that one + * can be scaled as desired. + */ + ret = BadFontName; + for (source = 0; source < FontFileBitmapSources.count; source++) + { + if (FontFileBitmapSources.fpe[source] == fpe) + continue; + dir = (FontDirectoryPtr) FontFileBitmapSources.fpe[source]->private; + zero = FontFileFindNameInDir (&dir->scalable, zeroPat); + if (!zero) + continue; + scaled = FontFileFindScaledInstance (zero, vals, noSpecificSize); + if (scaled) + { + if (scaled->pFont) + { + *pFont = scaled->pFont; + (*pFont)->fpe = FontFileBitmapSources.fpe[source]; + ret = Successful; + } + else if (scaled->bitmap) + { + entry = scaled->bitmap; + bitmap = &entry->u.bitmap; + if (bitmap->pFont) + { + *pFont = bitmap->pFont; + (*pFont)->fpe = FontFileBitmapSources.fpe[source]; + ret = Successful; + } + else + { + ret = FontFileOpenBitmap ( + FontFileBitmapSources.fpe[source], + pFont, flags, entry, format, fmask); + if (ret == Successful && *pFont) + (*pFont)->fpe = FontFileBitmapSources.fpe[source]; + } + } + else /* "cannot" happen */ + { + ret = BadFontName; + } + break; + } + } + return ret; +} diff --git a/nx-X11/lib/font/fontfile/bufio.c b/nx-X11/lib/font/fontfile/bufio.c new file mode 100644 index 000000000..43c6a13a7 --- /dev/null +++ b/nx-X11/lib/font/fontfile/bufio.c @@ -0,0 +1,212 @@ +/* $Xorg: bufio.c,v 1.4 2001/02/09 02:04:03 xorgcvs Exp $ */ + +/* + +Copyright 1991, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + +*/ +/* $XFree86: xc/lib/font/fontfile/bufio.c,v 3.9 2001/12/14 19:56:50 dawes Exp $ */ + +/* + * Author: Keith Packard, MIT X Consortium + */ + + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <X11/Xos.h> +#include <X11/fonts/fontmisc.h> +#include <X11/fonts/bufio.h> +#include <errno.h> + +BufFilePtr +BufFileCreate (char *private, + int (*input)(BufFilePtr), + int (*output)(int, BufFilePtr), + int (*skip)(BufFilePtr, int), + int (*close)(BufFilePtr, int)) +{ + BufFilePtr f; + + f = (BufFilePtr) xalloc (sizeof *f); + if (!f) + return 0; + f->private = private; + f->bufp = f->buffer; + f->left = 0; + f->input = input; + f->output = output; + f->skip = skip; + f->eof = 0; + f->close = close; + return f; +} + +#define FileDes(f) ((int)(long) (f)->private) + +static int +BufFileRawFill (BufFilePtr f) +{ + int left; + + left = read (FileDes(f), (char *)f->buffer, BUFFILESIZE); + if (left <= 0) { + f->left = 0; + return BUFFILEEOF; + } + f->left = left - 1; + f->bufp = f->buffer + 1; + return f->buffer[0]; +} + +static int +BufFileRawSkip (BufFilePtr f, int count) +{ + int curoff; + int fileoff; + int todo; + + curoff = f->bufp - f->buffer; + fileoff = curoff + f->left; + if (curoff + count <= fileoff) { + f->bufp += count; + f->left -= count; + } else { + todo = count - (fileoff - curoff); + if (lseek (FileDes(f), todo, 1) == -1) { + if (errno != ESPIPE) + return BUFFILEEOF; + while (todo) { + curoff = BUFFILESIZE; + if (curoff > todo) + curoff = todo; + fileoff = read (FileDes(f), (char *)f->buffer, curoff); + if (fileoff <= 0) + return BUFFILEEOF; + todo -= fileoff; + } + } + f->left = 0; + } + return count; +} + +static int +BufFileRawClose (BufFilePtr f, int doClose) +{ + if (doClose) + close (FileDes (f)); + return 1; +} + +BufFilePtr +BufFileOpenRead (int fd) +{ +#if defined(__UNIXOS2__) || defined (WIN32) + /* hv: I'd bet WIN32 has the same effect here */ + setmode(fd,O_BINARY); +#endif + return BufFileCreate ((char *)(long) fd, BufFileRawFill, 0, BufFileRawSkip, BufFileRawClose); +} + +static int +BufFileRawFlush (int c, BufFilePtr f) +{ + int cnt; + + if (c != BUFFILEEOF) + *f->bufp++ = c; + cnt = f->bufp - f->buffer; + f->bufp = f->buffer; + f->left = BUFFILESIZE; + if (write (FileDes(f), (char *)f->buffer, cnt) != cnt) + return BUFFILEEOF; + return c; +} + +BufFilePtr +BufFileOpenWrite (int fd) +{ + BufFilePtr f; + +#if defined(__UNIXOS2__) || defined(WIN32) + /* hv: I'd bet WIN32 has the same effect here */ + setmode(fd,O_BINARY); +#endif + f = BufFileCreate ((char *)(long) fd, 0, BufFileRawFlush, 0, BufFileFlush); + f->bufp = f->buffer; + f->left = BUFFILESIZE; + return f; +} + +int +BufFileRead (BufFilePtr f, char *b, int n) +{ + int c, cnt; + cnt = n; + while (cnt--) { + c = BufFileGet (f); + if (c == BUFFILEEOF) + break; + *b++ = c; + } + return n - cnt - 1; +} + +int +BufFileWrite (BufFilePtr f, char *b, int n) +{ + int cnt; + cnt = n; + while (cnt--) { + if (BufFilePut (*b++, f) == BUFFILEEOF) + return BUFFILEEOF; + } + return n; +} + +int +BufFileFlush (BufFilePtr f, int doClose) +{ + if (f->bufp != f->buffer) + return (*f->output) (BUFFILEEOF, f); + return 0; +} + +int +BufFileClose (BufFilePtr f, int doClose) +{ + int ret; + ret = (*f->close) (f, doClose); + xfree (f); + return ret; +} + +void +BufFileFree (BufFilePtr f) +{ + xfree (f); +} diff --git a/nx-X11/lib/font/fontfile/decompress.c b/nx-X11/lib/font/fontfile/decompress.c new file mode 100644 index 000000000..a4c546871 --- /dev/null +++ b/nx-X11/lib/font/fontfile/decompress.c @@ -0,0 +1,410 @@ +/* $Xorg: decompress.c,v 1.4 2001/02/09 02:04:03 xorgcvs Exp $ */ +/* + * Copyright 1985, 1986 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * James A. Woods, derived from original work by Spencer Thomas + * and Joseph Orost. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the University of California, Berkeley. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +/* + +Copyright 1993, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ +/* $XFree86: xc/lib/font/fontfile/decompress.c,v 1.4 2001/01/17 19:43:29 dawes Exp $ */ +/* + * decompress - cat a compressed file + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <X11/fonts/fontmisc.h> +#include <X11/fonts/bufio.h> + +#define BITS 16 + +/* + * a code_int must be able to hold 2**BITS values of type int, and also -1 + */ +#if BITS > 15 +typedef long int code_int; +#else +typedef int code_int; +#endif + +typedef long int count_int; + +#ifdef NO_UCHAR + typedef char char_type; +#else + typedef unsigned char char_type; +#endif /* UCHAR */ + +static char_type magic_header[] = { "\037\235" }; /* 1F 9D */ + +/* Defines for third byte of header */ +#define BIT_MASK 0x1f +#define BLOCK_MASK 0x80 +/* Masks 0x40 and 0x20 are free. I think 0x20 should mean that there is + a fourth header byte (for expansion). +*/ + +#define INIT_BITS 9 /* initial number of bits/code */ + +#ifdef COMPATIBLE /* But wrong! */ +# define MAXCODE(n_bits) (1 << (n_bits) - 1) +#else +# define MAXCODE(n_bits) ((1 << (n_bits)) - 1) +#endif /* COMPATIBLE */ + +/* + * the next two codes should not be changed lightly, as they must not + * lie within the contiguous general code space. + */ +#define FIRST 257 /* first free entry */ +#define CLEAR 256 /* table clear output code */ + +#define STACK_SIZE 8192 + +typedef struct _compressedFILE { + BufFilePtr file; + + char_type *stackp; + code_int oldcode; + char_type finchar; + + int block_compress; + int maxbits; + code_int maxcode, maxmaxcode; + + code_int free_ent; + int clear_flg; + int n_bits; + + /* bit buffer */ + int offset, size; + char_type buf[BITS]; + + char_type de_stack[STACK_SIZE]; + char_type *tab_suffix; + unsigned short *tab_prefix; +} CompressedFile; + + +static int hsize_table[] = { + 5003, /* 12 bits - 80% occupancy */ + 9001, /* 13 bits - 91% occupancy */ + 18013, /* 14 bits - 91% occupancy */ + 35023, /* 15 bits - 94% occupancy */ + 69001 /* 16 bits - 95% occupancy */ +}; + +static int BufCompressedClose ( BufFilePtr f, int doClose ); +static int BufCompressedFill ( BufFilePtr f ); +static code_int getcode ( CompressedFile *file ); +static int BufCompressedSkip ( BufFilePtr f, int bytes ); + +BufFilePtr +BufFilePushCompressed (BufFilePtr f) +{ + int code; + int maxbits; + int hsize; + CompressedFile *file; + int extra; + + if ((BufFileGet(f) != (magic_header[0] & 0xFF)) || + (BufFileGet(f) != (magic_header[1] & 0xFF))) + { + return 0; + } + code = BufFileGet (f); + if (code == BUFFILEEOF) return 0; + + maxbits = code & BIT_MASK; + if (maxbits > BITS || maxbits < 12) + return 0; + hsize = hsize_table[maxbits - 12]; + extra = (1 << maxbits) * sizeof (char_type) + + hsize * sizeof (unsigned short); + file = (CompressedFile *) xalloc (sizeof (CompressedFile) + extra); + if (!file) + return 0; + file->file = f; + file->maxbits = maxbits; + file->block_compress = code & BLOCK_MASK; + file->maxmaxcode = 1 << file->maxbits; + file->tab_suffix = (char_type *) &file[1]; + file->tab_prefix = (unsigned short *) (file->tab_suffix + file->maxmaxcode); + /* + * As above, initialize the first 256 entries in the table. + */ + file->maxcode = MAXCODE(file->n_bits = INIT_BITS); + for ( code = 255; code >= 0; code-- ) { + file->tab_prefix[code] = 0; + file->tab_suffix[code] = (char_type) code; + } + file->free_ent = ((file->block_compress) ? FIRST : 256 ); + file->clear_flg = 0; + file->offset = 0; + file->size = 0; + file->stackp = file->de_stack; + bzero(file->buf, BITS); + file->finchar = file->oldcode = getcode (file); + if (file->oldcode != -1) + *file->stackp++ = file->finchar; + return BufFileCreate ((char *) file, + BufCompressedFill, + 0, + BufCompressedSkip, + BufCompressedClose); +} + +static int +BufCompressedClose (BufFilePtr f, int doClose) +{ + CompressedFile *file; + BufFilePtr raw; + + file = (CompressedFile *) f->private; + raw = file->file; + xfree (file); + BufFileClose (raw, doClose); + return 1; +} + +static int +BufCompressedFill (BufFilePtr f) +{ + CompressedFile *file; + register char_type *stackp, *de_stack; + register char_type finchar; + register code_int code, oldcode, incode; + BufChar *buf, *bufend; + + file = (CompressedFile *) f->private; + + buf = f->buffer; + bufend = buf + BUFFILESIZE; + stackp = file->stackp; + de_stack = file->de_stack; + finchar = file->finchar; + oldcode = file->oldcode; + while (buf < bufend) { + while (stackp > de_stack && buf < bufend) + *buf++ = *--stackp; + + if (buf == bufend) + break; + + if (oldcode == -1) + break; + + code = getcode (file); + if (code == -1) + break; + + if ( (code == CLEAR) && file->block_compress ) { + for ( code = 255; code >= 0; code-- ) + file->tab_prefix[code] = 0; + file->clear_flg = 1; + file->free_ent = FIRST - 1; + if ( (code = getcode (file)) == -1 ) /* O, untimely death! */ + break; + } + incode = code; + /* + * Special case for KwKwK string. + */ + if ( code >= file->free_ent ) { + *stackp++ = finchar; + code = oldcode; + } + + /* + * Generate output characters in reverse order + */ + while ( code >= 256 ) + { + *stackp++ = file->tab_suffix[code]; + code = file->tab_prefix[code]; + } + finchar = file->tab_suffix[code]; + *stackp++ = finchar; + + /* + * Generate the new entry. + */ + if ( (code=file->free_ent) < file->maxmaxcode ) { + file->tab_prefix[code] = (unsigned short)oldcode; + file->tab_suffix[code] = finchar; + file->free_ent = code+1; + } + /* + * Remember previous code. + */ + oldcode = incode; + } + file->oldcode = oldcode; + file->stackp = stackp; + file->finchar = finchar; + if (buf == f->buffer) { + f->left = 0; + return BUFFILEEOF; + } + f->bufp = f->buffer + 1; + f->left = (buf - f->buffer) - 1; + return f->buffer[0]; +} + +/***************************************************************** + * TAG( getcode ) + * + * Read one code from the standard input. If BUFFILEEOF, return -1. + * Inputs: + * stdin + * Outputs: + * code or -1 is returned. + */ + +static char_type rmask[9] = {0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff}; + +static code_int +getcode(CompressedFile *file) +{ + register code_int code; + register int r_off, bits; + register char_type *bp = file->buf; + register BufFilePtr raw; + + if ( file->clear_flg > 0 || file->offset >= file->size || + file->free_ent > file->maxcode ) + { + /* + * If the next entry will be too big for the current code + * size, then we must increase the size. This implies reading + * a new buffer full, too. + */ + if ( file->free_ent > file->maxcode ) { + file->n_bits++; + if ( file->n_bits == file->maxbits ) + file->maxcode = file->maxmaxcode; /* won't get any bigger now */ + else + file->maxcode = MAXCODE(file->n_bits); + } + if ( file->clear_flg > 0) { + file->maxcode = MAXCODE (file->n_bits = INIT_BITS); + file->clear_flg = 0; + } + bits = file->n_bits; + raw = file->file; + while (bits > 0 && (code = BufFileGet (raw)) != BUFFILEEOF) + { + *bp++ = code; + --bits; + } + bp = file->buf; + if (bits == file->n_bits) + return -1; /* end of file */ + file->size = file->n_bits - bits; + file->offset = 0; + /* Round size down to integral number of codes */ + file->size = (file->size << 3) - (file->n_bits - 1); + } + r_off = file->offset; + bits = file->n_bits; + /* + * Get to the first byte. + */ + bp += (r_off >> 3); + r_off &= 7; + /* Get first part (low order bits) */ +#ifdef NO_UCHAR + code = ((*bp++ >> r_off) & rmask[8 - r_off]) & 0xff; +#else + code = (*bp++ >> r_off); +#endif /* NO_UCHAR */ + bits -= (8 - r_off); + r_off = 8 - r_off; /* now, offset into code word */ + /* Get any 8 bit parts in the middle (<=1 for up to 16 bits). */ + if ( bits >= 8 ) { +#ifdef NO_UCHAR + code |= (*bp++ & 0xff) << r_off; +#else + code |= *bp++ << r_off; +#endif /* NO_UCHAR */ + r_off += 8; + bits -= 8; + } + /* high order bits. */ + code |= (*bp & rmask[bits]) << r_off; + file->offset += file->n_bits; + + return code; +} + +static int +BufCompressedSkip (BufFilePtr f, int bytes) +{ + int c; + while (bytes--) + { + c = BufFileGet(f); + if (c == BUFFILEEOF) + return BUFFILEEOF; + } + return 0; +} + +#ifdef TEST +int +main (int argc, char *argv[]) +{ + BufFilePtr inputraw, input, output; + int c; + + inputraw = BufFileOpenRead (0); + input = BufFilePushCompressed (inputraw); + output = BufFileOpenWrite (1); + while ((c = BufFileGet (input)) != BUFFILEEOF) + BufFilePut (c, output); + BufFileClose (input, FALSE); + BufFileClose (output, FALSE); + return 0; +} +#endif diff --git a/nx-X11/lib/font/fontfile/defaults.c b/nx-X11/lib/font/fontfile/defaults.c new file mode 100644 index 000000000..7f20cab67 --- /dev/null +++ b/nx-X11/lib/font/fontfile/defaults.c @@ -0,0 +1,77 @@ +/* $Xorg: defaults.c,v 1.4 2001/02/09 02:04:03 xorgcvs Exp $ */ + +/* + +Copyright 1990, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ +/* $XFree86: xc/lib/font/fontfile/defaults.c,v 1.7 2001/01/17 19:43:29 dawes Exp $ */ + +/* + * Author: Keith Packard, MIT X Consortium + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <X11/X.h> +#include <X11/Xproto.h> + +#ifndef DEFAULT_BIT_ORDER +#ifdef BITMAP_BIT_ORDER +#define DEFAULT_BIT_ORDER BITMAP_BIT_ORDER +#else +#define DEFAULT_BIT_ORDER MSBFirst +#endif +#endif + +#ifndef DEFAULT_BYTE_ORDER +#ifdef IMAGE_BYTE_ORDER +#define DEFAULT_BYTE_ORDER IMAGE_BYTE_ORDER +#else +#define DEFAULT_BYTE_ORDER MSBFirst +#endif +#endif + +#ifndef DEFAULT_GLYPH_PAD +#ifdef GLYPHPADBYTES +#define DEFAULT_GLYPH_PAD GLYPHPADBYTES +#else +#define DEFAULT_GLYPH_PAD 4 +#endif +#endif + +#ifndef DEFAULT_SCAN_UNIT +#define DEFAULT_SCAN_UNIT 1 +#endif + +#include <X11/fonts/fntfilst.h> + +void +FontDefaultFormat (int *bit, int *byte, int *glyph, int *scan) +{ + *bit = DEFAULT_BIT_ORDER; + *byte = DEFAULT_BYTE_ORDER; + *glyph = DEFAULT_GLYPH_PAD; + *scan = DEFAULT_SCAN_UNIT; +} diff --git a/nx-X11/lib/font/fontfile/dirfile.c b/nx-X11/lib/font/fontfile/dirfile.c new file mode 100644 index 000000000..f390391bc --- /dev/null +++ b/nx-X11/lib/font/fontfile/dirfile.c @@ -0,0 +1,491 @@ +/* $Xorg: dirfile.c,v 1.4 2001/02/09 02:04:03 xorgcvs Exp $ */ + +/* + +Copyright 1991, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ +/* $XFree86: xc/lib/font/fontfile/dirfile.c,v 3.17 2004/02/08 01:52:27 dawes Exp $ */ + +/* + * Author: Keith Packard, MIT X Consortium + */ + +/* + * dirfile.c + * + * Read fonts.dir and fonts.alias files + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <X11/fonts/fntfilst.h> +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <errno.h> + +static Bool AddFileNameAliases ( FontDirectoryPtr dir ); +static int ReadFontAlias ( char *directory, Bool isFile, + FontDirectoryPtr *pdir ); +static int lexAlias ( FILE *file, char **lexToken ); +static int lexc ( FILE *file ); + +int +FontFileReadDirectory (char *directory, FontDirectoryPtr *pdir) +{ + char file_name[MAXFONTFILENAMELEN]; + char font_name[MAXFONTNAMELEN]; + char dir_file[MAXFONTFILENAMELEN]; + char dir_path[MAXFONTFILENAMELEN]; + char *ptr; + FILE *file; + int count, + i, + status; + struct stat statb; + static char format[24] = ""; + + FontDirectoryPtr dir = NullFontDirectory; + + if (strlen(directory) + 1 + sizeof(FontDirFile) > sizeof(dir_file)) + return BadFontPath; + + /* Check for font directory attributes */ +#if !defined(__UNIXOS2__) && !defined(WIN32) + if ((ptr = strchr(directory, ':'))) { +#else + /* OS/2 and WIN32 path might start with a drive letter, don't clip this */ + if ((ptr = strchr(directory+2, ':'))) { +#endif + strncpy(dir_path, directory, ptr - directory); + dir_path[ptr - directory] = '\0'; + } else { + strcpy(dir_path, directory); + } + strcpy(dir_file, dir_path); + if (dir_file[strlen(dir_file) - 1] != '/') + strcat(dir_file, "/"); + strcat(dir_file, FontDirFile); + file = fopen(dir_file, "rt"); + if (file) { + Bool found_font = FALSE; + +#ifndef WIN32 + if (fstat (fileno(file), &statb) == -1) +#else + if (stat (dir_file, &statb) == -1) +#endif + { + fclose(file); + return BadFontPath; + } + count = fscanf(file, "%d\n", &i); + if ((count == EOF) || (count != 1)) { + fclose(file); + return BadFontPath; + } + dir = FontFileMakeDir(directory, i); + if (dir == NULL) { + fclose(file); + return BadFontPath; + } + dir->dir_mtime = statb.st_mtime; + if (format[0] == '\0') + sprintf(format, "%%%ds %%%d[^\n]\n", + MAXFONTFILENAMELEN-1, MAXFONTNAMELEN-1); + + while ((count = fscanf(file, format, file_name, font_name)) != EOF) { +#if defined(__UNIXOS2__) || defined(WIN32) + /* strip any existing trailing CR */ + for (i=0; i<strlen(font_name); i++) { + if (font_name[i]=='\r') font_name[i] = '\0'; + } +#endif + if (count != 2) { + FontFileFreeDir (dir); + fclose(file); + return BadFontPath; + } + if (FontFileAddFontFile (dir, font_name, file_name)) + found_font = TRUE; + } + if (!found_font) { + FontFileFreeDir (dir); + fclose(file); + return BadFontPath; + } + fclose(file); + + } else if (errno != ENOENT) { + return BadFontPath; + } + status = ReadFontAlias(dir_path, FALSE, &dir); + if (status != Successful) { + if (dir) + FontFileFreeDir (dir); + return status; + } + if (!dir) + return BadFontPath; + + FontFileSortDir(dir); + + *pdir = dir; + return Successful; +} + +Bool +FontFileDirectoryChanged(FontDirectoryPtr dir) +{ + char dir_file[MAXFONTFILENAMELEN]; + struct stat statb; + + if (strlen(dir->directory) + sizeof(FontDirFile) > sizeof(dir_file)) + return FALSE; + + strcpy (dir_file, dir->directory); + strcat (dir_file, FontDirFile); + if (stat (dir_file, &statb) == -1) + { + if (errno != ENOENT || dir->dir_mtime != 0) + return TRUE; + return FALSE; /* doesn't exist and never did: no change */ + } + if (dir->dir_mtime != statb.st_mtime) + return TRUE; + strcpy (dir_file, dir->directory); + strcat (dir_file, FontAliasFile); + if (stat (dir_file, &statb) == -1) + { + if (errno != ENOENT || dir->alias_mtime != 0) + return TRUE; + return FALSE; /* doesn't exist and never did: no change */ + } + if (dir->alias_mtime != statb.st_mtime) + return TRUE; + return FALSE; +} + +/* + * Make each of the file names an automatic alias for each of the files. + */ + +static Bool +AddFileNameAliases(FontDirectoryPtr dir) +{ + int i; + char copy[MAXFONTFILENAMELEN]; + char *fileName; + FontTablePtr table; + FontRendererPtr renderer; + int len; + FontNameRec name; + + table = &dir->nonScalable; + for (i = 0; i < table->used; i++) { + if (table->entries[i].type != FONT_ENTRY_BITMAP) + continue; + fileName = table->entries[i].u.bitmap.fileName; + renderer = FontFileMatchRenderer (fileName); + if (!renderer) + continue; + + len = strlen (fileName) - renderer->fileSuffixLen; + if (len >= sizeof(copy)) + continue; + CopyISOLatin1Lowered (copy, fileName, len); + copy[len] = '\0'; + name.name = copy; + name.length = len; + name.ndashes = FontFileCountDashes (copy, len); + + if (!FontFileFindNameInDir(table, &name)) { + if (!FontFileAddFontAlias (dir, copy, table->entries[i].name.name)) + return FALSE; + } + } + return TRUE; +} + +/* + * parse the font.alias file. Format is: + * + * alias font-name + * + * To imbed white-space in an alias name, enclose it like "font name" + * in double quotes. \ escapes and character, so + * "font name \"With Double Quotes\" \\ and \\ back-slashes" + * works just fine. + * + * A line beginning with a ! denotes a newline-terminated comment. + */ + +/* + * token types + */ + +#define NAME 0 +#define NEWLINE 1 +#define DONE 2 +#define EALLOC 3 + +static int +ReadFontAlias(char *directory, Bool isFile, FontDirectoryPtr *pdir) +{ + char alias[MAXFONTNAMELEN]; + char font_name[MAXFONTNAMELEN]; + char alias_file[MAXFONTFILENAMELEN]; + FILE *file; + FontDirectoryPtr dir; + int token; + char *lexToken; + int status = Successful; + struct stat statb; + + if (strlen(directory) >= sizeof(alias_file)) + return BadFontPath; + dir = *pdir; + strcpy(alias_file, directory); + if (!isFile) { + if (strlen(directory) + 1 + sizeof(FontAliasFile) > sizeof(alias_file)) + return BadFontPath; + if (directory[strlen(directory) - 1] != '/') + strcat(alias_file, "/"); + strcat(alias_file, FontAliasFile); + } + file = fopen(alias_file, "rt"); + if (!file) + return ((errno == ENOENT) ? Successful : BadFontPath); + if (!dir) + *pdir = dir = FontFileMakeDir(directory, 10); + if (!dir) + { + fclose (file); + return AllocError; + } +#ifndef WIN32 + if (fstat (fileno (file), &statb) == -1) +#else + if (stat (alias_file, &statb) == -1) +#endif + { + fclose (file); + return BadFontPath; + } + dir->alias_mtime = statb.st_mtime; + while (status == Successful) { + token = lexAlias(file, &lexToken); + switch (token) { + case NEWLINE: + break; + case DONE: + fclose(file); + return Successful; + case EALLOC: + status = AllocError; + break; + case NAME: + if (strlen(lexToken) >= sizeof(alias)) { + status = BadFontPath; + break; + } + strcpy(alias, lexToken); + token = lexAlias(file, &lexToken); + switch (token) { + case NEWLINE: + if (strcmp(alias, "FILE_NAMES_ALIASES")) + status = BadFontPath; + else if (!AddFileNameAliases(dir)) + status = AllocError; + break; + case DONE: + status = BadFontPath; + break; + case EALLOC: + status = AllocError; + break; + case NAME: + if (strlen(lexToken) >= sizeof(font_name)) { + status = BadFontPath; + break; + } + CopyISOLatin1Lowered(alias, alias, strlen(alias)); + CopyISOLatin1Lowered(font_name, lexToken, strlen(lexToken)); + if (!FontFileAddFontAlias (dir, alias, font_name)) + status = AllocError; + break; + } + } + } + fclose(file); + return status; +} + +#define QUOTE 0 +#define WHITE 1 +#define NORMAL 2 +#define END 3 +#define NL 4 +#define BANG 5 + +static int charClass; + +static int +lexAlias(FILE *file, char **lexToken) +{ + int c; + char *t; + enum state { + Begin, Normal, Quoted, Comment + } state; + int count; + + static char *tokenBuf = (char *) NULL; + static int tokenSize = 0; + + t = tokenBuf; + count = 0; + state = Begin; + for (;;) { + if (count == tokenSize) { + int nsize; + char *nbuf; + + nsize = tokenSize ? (tokenSize << 1) : 64; + nbuf = (char *) xrealloc(tokenBuf, nsize); + if (!nbuf) + return EALLOC; + tokenBuf = nbuf; + tokenSize = nsize; + t = tokenBuf + count; + } + c = lexc(file); + switch (charClass) { + case QUOTE: + switch (state) { + case Begin: + case Normal: + state = Quoted; + break; + case Quoted: + state = Normal; + break; + case Comment: + break; + } + break; + case WHITE: + switch (state) { + case Begin: + case Comment: + continue; + case Normal: + *t = '\0'; + *lexToken = tokenBuf; + return NAME; + case Quoted: + break; + } + /* fall through */ + case NORMAL: + switch (state) { + case Begin: + state = Normal; + break; + case Comment: + continue; + default: + break; + } + *t++ = c; + ++count; + break; + case END: + case NL: + switch (state) { + case Begin: + case Comment: + *lexToken = (char *) NULL; + return charClass == END ? DONE : NEWLINE; + default: + *t = '\0'; + *lexToken = tokenBuf; + ungetc(c, file); + return NAME; + } + break; + case BANG: + switch (state) { + case Begin: + state = Comment; + break; + case Comment: + break; + default: + *t++ = c; + ++count; + } + break; + } + } +} + +static int +lexc(FILE *file) +{ + int c; + + c = getc(file); + switch (c) { + case EOF: + charClass = END; + break; + case '\\': + c = getc(file); + if (c == EOF) + charClass = END; + else + charClass = NORMAL; + break; + case '"': + charClass = QUOTE; + break; + case ' ': + case '\t': + charClass = WHITE; + break; + case '\r': + case '\n': + charClass = NL; + break; + case '!': + charClass = BANG; + break; + default: + charClass = NORMAL; + break; + } + return c; +} diff --git a/nx-X11/lib/font/fontfile/encparse.c b/nx-X11/lib/font/fontfile/encparse.c new file mode 100644 index 000000000..285f5a17d --- /dev/null +++ b/nx-X11/lib/font/fontfile/encparse.c @@ -0,0 +1,963 @@ +/* +Copyright (c) 1998-2001 by Juliusz Chroboczek + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +/* $XFree86: xc/lib/font/fontfile/encparse.c,v 1.20tsi Exp $ */ + +/* Parser for encoding files */ + +/* This code assumes that we are using ASCII. We don't use the ctype + functions, as they depend on the current locale. On the other + hand, we do use strcasecmp, but only on strings that we've checked + to be pure ASCII. Bloody ``Code Set Independence''. */ + +#include <string.h> +#include <stdio.h> + +#if defined(__SCO__) || defined(__UNIXWARE__) +#include <strings.h> +#endif + +#ifndef FONTENC_NO_LIBFONT + +#include <X11/fonts/fntfilio.h> +#include <X11/fonts/fntfilst.h> + +#else + +#include <stdlib.h> +#define xalloc(n) malloc(n) +#define xrealloc(p, n) realloc(p, n) +#define xfree(p) free(p) + +#include "zlib.h" +typedef gzFile FontFilePtr; +#define FontFileGetc(f) gzgetc(f) +#define FontFileOpen(filename) gzopen(filename, "rb") +#define FontFileClose(f) gzclose(f) + +#define MAXFONTFILENAMELEN 1024 +#define MAXFONTNAMELEN 1024 + +#endif + +#include <X11/fonts/fontenc.h> +#include "fontencI.h" + +#define MAXALIASES 20 + +#define EOF_TOKEN -1 +#define ERROR_TOKEN -2 +#define EOL_TOKEN 0 +#define NUMBER_TOKEN 1 +#define KEYWORD_TOKEN 2 + +#define EOF_LINE -1 +#define ERROR_LINE -2 +#define STARTENCODING_LINE 1 +#define STARTMAPPING_LINE 2 +#define ENDMAPPING_LINE 3 +#define CODE_LINE 4 +#define CODE_RANGE_LINE 5 +#define CODE_UNDEFINE_LINE 6 +#define NAME_LINE 7 +#define SIZE_LINE 8 +#define ALIAS_LINE 9 +#define FIRSTINDEX_LINE 10 + +/* Return from lexer */ +#define MAXKEYWORDLEN 100 + +static long number_value; +static char keyword_value[MAXKEYWORDLEN+1]; + +static long value1, value2, value3; + +/* Lexer code */ + +/* Skip to the beginning of new line */ +static void +skipEndOfLine(FontFilePtr f, int c) +{ + if(c == 0) + c = FontFileGetc(f); + + for(;;) + if(c <= 0 || c == '\n') + return; + else + c = FontFileGetc(f); +} + +/* Get a number; we're at the first digit. */ +static unsigned +getnum(FontFilePtr f, int c, int *cp) +{ + unsigned n = 0; + int base = 10; + + /* look for `0' or `0x' prefix */ + if(c == '0') { + c = FontFileGetc(f); + base = 8; + if(c == 'x' || c == 'X') { + base = 16; + c = FontFileGetc(f); + } + } + + /* accumulate digits */ + for(;;) { + if ('0' <= c && c <= '9') { + n *= base; n += c - '0'; + } else if('a' <= c && c <= 'f') { + n *= base; n += c - 'a' + 10; + } else if('A' <=c && c <= 'F') { + n *= base; n += c - 'A' + 10; + } else + break; + c = FontFileGetc(f); + } + + *cp = c; return n; +} + +/* Skip to beginning of new line; return 1 if only whitespace was found. */ +static int +endOfLine(FontFilePtr f, int c) +{ + if(c == 0) + c = FontFileGetc(f); + + for(;;) { + if(c <= 0 || c == '\n') + return 1; + else if(c == '#') { + skipEndOfLine(f,c); + return 1; + } + else if(c == ' ' || c == '\t') { + skipEndOfLine(f,c); + return 0; + } + c = FontFileGetc(f); + } +} + +/* Get a token; we're at first char */ +static int +gettoken(FontFilePtr f, int c, int *cp) +{ + char *p; + + if(c <= 0) + c = FontFileGetc(f); + + if(c <= 0) { + return EOF_TOKEN; + } + + while(c == ' ' || c == '\t') + c = FontFileGetc(f); + + if(c=='\n') { + return EOL_TOKEN; + } else if(c == '#') { + skipEndOfLine(f,c); + return EOL_TOKEN; + } else if(c >= '0' && c <= '9') { + number_value = getnum(f,c,cp); + return NUMBER_TOKEN; + } else if((c >= 'A' && c <= 'Z') || + (c >= 'a' && c <= 'z') || + c == '/' || c == '_' || c == '-' || c == '.') { + p = keyword_value; + *p++ = c; + while(p-keyword_value < MAXKEYWORDLEN) { + c = FontFileGetc(f); + if(c <= ' ' || c > '~' || c == '#') + break; + *p++ = c; + } + *cp = c; + *p = '\0'; + return KEYWORD_TOKEN; + } else { + *cp = c; + return ERROR_TOKEN; + } +} + +/* Parse a line. + * Always skips to the beginning of a new line, even if an error occurs */ +static int +getnextline(FontFilePtr f) +{ + int c, token; + c = FontFileGetc(f); + if(c <= 0) + return EOF_LINE; + + again: + token=gettoken(f,c,&c); + + switch(token) { + case EOF_TOKEN: + return EOF_LINE; + case EOL_TOKEN: + /* empty line */ + c = FontFileGetc(f); + goto again; + case NUMBER_TOKEN: + value1 = number_value; + token = gettoken(f,c,&c); + switch(token) { + case NUMBER_TOKEN: + value2 = number_value; + token = gettoken(f,c,&c); + switch(token) { + case NUMBER_TOKEN: + value3 = number_value; + return CODE_RANGE_LINE; + case EOL_TOKEN: + return CODE_LINE; + default: + skipEndOfLine(f,c); + return ERROR_LINE; + } + case KEYWORD_TOKEN: + if(!endOfLine(f,c)) + return ERROR_LINE; + else + return NAME_LINE; + default: + skipEndOfLine(f,c); + return ERROR_LINE; + } + case KEYWORD_TOKEN: + if(!strcasecmp(keyword_value, "STARTENCODING")) { + token = gettoken(f,c,&c); + if(token == KEYWORD_TOKEN) { + if(endOfLine(f,c)) + return STARTENCODING_LINE; + else + return ERROR_LINE; + } else { + skipEndOfLine(f,c); + return ERROR_LINE; + } + } else if(!strcasecmp(keyword_value, "ALIAS")) { + token = gettoken(f,c,&c); + if(token == KEYWORD_TOKEN) { + if(endOfLine(f,c)) + return ALIAS_LINE; + else + return ERROR_LINE; + } else { + skipEndOfLine(f,c); + return ERROR_LINE; + } + } else if(!strcasecmp(keyword_value, "SIZE")) { + token = gettoken(f,c,&c); + if(token == NUMBER_TOKEN) { + value1 = number_value; + token = gettoken(f,c,&c); + switch(token) { + case NUMBER_TOKEN: + value2 = number_value; + return SIZE_LINE; + case EOL_TOKEN: + value2=0; + return SIZE_LINE; + default: + skipEndOfLine(f,c); + return ERROR_LINE; + } + } else { + skipEndOfLine(f,c); + return ERROR_LINE; + } + } else if(!strcasecmp(keyword_value, "FIRSTINDEX")) { + token = gettoken(f,c,&c); + if(token == NUMBER_TOKEN) { + value1 = number_value; + token = gettoken(f,c,&c); + switch(token) { + case NUMBER_TOKEN: + value2 = number_value; + return FIRSTINDEX_LINE; + case EOL_TOKEN: + value2 = 0; + return FIRSTINDEX_LINE; + default: + skipEndOfLine(f,c); + return ERROR_LINE; + } + } else { + skipEndOfLine(f,c); + return ERROR_LINE; + } + } else if(!strcasecmp(keyword_value, "STARTMAPPING")) { + keyword_value[0] = 0; + value1 = 0; value1 = 0; + /* first a keyword */ + token = gettoken(f,c,&c); + if(token != KEYWORD_TOKEN) { + skipEndOfLine(f, c); + return ERROR_LINE; + } + + /* optional first integer */ + token = gettoken(f,c,&c); + if(token == NUMBER_TOKEN) { + value1 = number_value; + } else if(token == EOL_TOKEN) { + return STARTMAPPING_LINE; + } else { + skipEndOfLine(f, c); + return ERROR_LINE; + } + + /* optional second integer */ + token = gettoken(f,c,&c); + if(token == NUMBER_TOKEN) { + value2 = number_value; + } else if(token == EOL_TOKEN) { + return STARTMAPPING_LINE; + } else { + skipEndOfLine(f, c); + return ERROR_LINE; + } + + if(!endOfLine(f,c)) + return ERROR_LINE; + else { + return STARTMAPPING_LINE; + } + } else if(!strcasecmp(keyword_value, "UNDEFINE")) { + /* first integer */ + token = gettoken(f,c,&c); + if(token != NUMBER_TOKEN) { + skipEndOfLine(f,c); + return ERROR_LINE; + } + value1 = number_value; + /* optional second integer */ + token = gettoken(f,c,&c); + if(token == EOL_TOKEN) { + value2 = value1; + return CODE_UNDEFINE_LINE; + } else if(token == NUMBER_TOKEN) { + value2 = number_value; + if(endOfLine(f,c)) { + return CODE_UNDEFINE_LINE; + } else + return ERROR_LINE; + } else { + skipEndOfLine(f,c); + return ERROR_LINE; + } + } else if(!strcasecmp(keyword_value, "ENDENCODING")) { + if(endOfLine(f,c)) + return EOF_LINE; + else + return ERROR_LINE; + } else if(!strcasecmp(keyword_value, "ENDMAPPING")) { + if(endOfLine(f,c)) + return ENDMAPPING_LINE; + else + return ERROR_LINE; + } else { + skipEndOfLine(f,c); + return ERROR_LINE; + } + default: + return ERROR_LINE; + } +} + +static void +install_mapping(FontEncPtr encoding, FontMapPtr mapping) +{ + FontMapPtr m; + + if(encoding->mappings == NULL) + encoding->mappings = mapping; + else { + m = encoding->mappings; + while(m->next != NULL) + m = m->next; + m->next = mapping; + } + mapping->next = NULL; + mapping->encoding = encoding; +} + +static int +setCode(unsigned from, unsigned to, unsigned row_size, + unsigned *first, unsigned *last, + unsigned *encsize, unsigned short **enc) +{ + unsigned index, i; + unsigned short *newenc; + + if(from>0xFFFF) + return 0; /* success */ + + if(row_size==0) + index=from; + else { + if((value1 & 0xFF) >= row_size) + return 0; /* ignore out of range mappings */ + index = (from>>8) * row_size + (from&0xFF); + } + + /* Optimize away useless identity mappings. This is only expected + to be useful with linear encodings. */ + if(index == to && (index < *first || index > *last)) + return 0; + if(*encsize == 0) { + *encsize = (index < 256) ? 256 : 0x10000; + *enc = (unsigned short*)xalloc((*encsize) * sizeof(unsigned short)); + if(*enc == NULL) { + *encsize = 0; + return 1; + } + } else if(*encsize <= index) { + *encsize = 0x10000; + if((newenc = (unsigned short*)xrealloc(enc, *encsize))==NULL) + return 1; + *enc = newenc; + } + if(*first > *last) { + *first = *last = index; + } + if(index < *first) { + for(i = index; i < *first; i++) + (*enc)[i] = i; + *first = index; + } + if(index > *last) { + for(i = *last + 1; i <= index; i++) + (*enc)[i] = i; + *last = index; + } + (*enc)[index] = to; + return 0; +} + +/* Parser. If headerOnly is true, we're only interested in the + data contained in the encoding file's header. */ + +/* As font encodings are currently never freed, the allocations done + by this function are mostly its private business. Note, however, + that FontEncIdentify needs to free the header fields -- so if you + change this function, you may need to change FontEncIdentify. */ + +/* I want a garbage collector. */ + +static FontEncPtr +parseEncodingFile(FontFilePtr f, int headerOnly) +{ + int line; + + unsigned short *enc=NULL; + char **nam = NULL, **newnam; + unsigned i, first = 0xFFFF, last=0, encsize=0, namsize=0; + FontEncPtr encoding = NULL; + FontMapPtr mapping = NULL; + FontEncSimpleMapPtr sm; + FontEncSimpleNamePtr sn; + char *aliases[MAXALIASES]; + int numaliases=0; + +#if 0 + /* GCC complains about unused labels. Please fix GCC rather than + obfuscating my code. */ + no_encoding: +#endif + line = getnextline(f); + switch(line) { + case EOF_LINE: + goto error; + case STARTENCODING_LINE: + encoding = (FontEncPtr)xalloc(sizeof(FontEncRec)); + if(encoding == NULL) + goto error; + encoding->name = (char*)xalloc(strlen(keyword_value)+1); + if(encoding->name == NULL) + goto error; + strcpy(encoding->name, keyword_value); + encoding->size = 256; + encoding->row_size = 0; + encoding->mappings = NULL; + encoding->next = NULL; + encoding->first = encoding->first_col=0; + goto no_mapping; + default: + goto error; + } + + no_mapping: + line = getnextline(f); + switch(line) { + case EOF_LINE: goto done; + case ALIAS_LINE: + if(numaliases < MAXALIASES) { + aliases[numaliases] = (char*)xalloc(strlen(keyword_value)+1); + if(aliases[numaliases] == NULL) + goto error; + strcpy(aliases[numaliases], keyword_value); + numaliases++; + } + goto no_mapping; + case SIZE_LINE: + encoding->size = value1; + encoding->row_size = value2; + goto no_mapping; + case FIRSTINDEX_LINE: + encoding->first = value1; + encoding->first_col = value2; + goto no_mapping; + case STARTMAPPING_LINE: + if(headerOnly) + goto done; + if(!strcasecmp(keyword_value, "unicode")) { + mapping = (FontMapPtr)xalloc(sizeof(FontMapRec)); + if(mapping == NULL) + goto error; + mapping->type = FONT_ENCODING_UNICODE; + mapping->pid = 0; + mapping->eid = 0; + mapping->recode = 0; + mapping->name = 0; + mapping->client_data = 0; + mapping->next = 0; + goto mapping; + } else if(!strcasecmp(keyword_value, "cmap")) { + mapping = (FontMapPtr)xalloc(sizeof(FontMapRec)); + if(mapping == NULL) + goto error; + mapping->type = FONT_ENCODING_TRUETYPE; + mapping->pid = value1; + mapping->eid = value2; + mapping->recode = 0; + mapping->name = 0; + mapping->client_data = 0; + mapping->next = 0; + goto mapping; + } else if(!strcasecmp(keyword_value, "postscript")) { + mapping = (FontMapPtr)xalloc(sizeof(FontMapRec)); + if(mapping == NULL) + goto error; + mapping->type = FONT_ENCODING_POSTSCRIPT; + mapping->pid = 0; + mapping->eid = 0; + mapping->recode = 0; + mapping->name = 0; + mapping->client_data = 0; + mapping->next = 0; + goto string_mapping; + } else { /* unknown mapping type -- ignore */ + goto skipmapping; + } + /* NOTREACHED */ + goto error; + default: goto no_mapping; /* ignore unknown lines */ + } + + skipmapping: + line = getnextline(f); + switch(line) { + case ENDMAPPING_LINE: + goto no_mapping; + case EOF_LINE: + goto error; + default: + goto skipmapping; + } + + mapping: + line = getnextline(f); + switch(line) { + case EOF_LINE: goto error; + case ENDMAPPING_LINE: + mapping->recode = FontEncSimpleRecode; + mapping->name = FontEncUndefinedName; + mapping->client_data = sm = + (FontEncSimpleMapPtr)xalloc(sizeof(FontEncSimpleMapRec)); + if(sm == NULL) + goto error; + sm->row_size = encoding->row_size; + if(first <= last) { + sm->first = first; + sm->len=last-first+1; + sm->map = + (unsigned short*)xalloc(sm->len * sizeof(unsigned short)); + if(sm->map == NULL) { + xfree(sm); + mapping->client_data = sm = NULL; + goto error; + } + } else { + sm->first = 0; + sm->len = 0; + sm->map = 0; + } + for(i=0; i < sm->len; i++) + sm -> map[i] = enc[first+i]; + install_mapping(encoding, mapping); + mapping = 0; + first = 0xFFFF; last=0; + goto no_mapping; + + case CODE_LINE: + if(setCode(value1, value2, encoding->row_size, + &first, &last, &encsize, &enc)) + goto error; + goto mapping; + + case CODE_RANGE_LINE: + if(value1 > 0x10000) + value1 = 0x10000; + if(value2 > 0x10000) + value2 = 0x10000; + if(value2 < value1) + goto mapping; + /* Do the last value first to avoid having to realloc() */ + if(setCode(value2, value3+(value2-value1), encoding->row_size, + &first, &last, &encsize, &enc)) + goto error; + for(i=value1; i<value2; i++) { + if(setCode(i, value3+(i-value1), encoding->row_size, + &first, &last, &encsize, &enc)) + goto error; + } + goto mapping; + + case CODE_UNDEFINE_LINE: + if(value1 > 0x10000) + value1 = 0x10000; + if(value2 > 0x10000) + value2 = 0x10000; + if(value2 < value1) + goto mapping; + /* Do the last value first to avoid having to realloc() */ + if(setCode(value2, 0, encoding->row_size, + &first, &last, &encsize, &enc)) + goto error; + for(i = value1; i < value2; i++) { + if(setCode(i, 0, encoding->row_size, + &first, &last, &encsize, &enc)) + goto error; + } + goto mapping; + + default: goto mapping; /* ignore unknown lines */ + } + + string_mapping: + line = getnextline(f); + switch(line) { + case EOF_LINE: goto error; + case ENDMAPPING_LINE: + mapping->recode = FontEncUndefinedRecode; + mapping->name = FontEncSimpleName; + mapping->client_data = sn = + (FontEncSimpleNamePtr)xalloc(sizeof(FontEncSimpleNameRec)); + if(sn == NULL) + goto error; + if(first > last) { + xfree(sn); + mapping->client_data = sn = NULL; + goto error; + } + sn->first = first; + sn->len = last - first + 1; + sn->map = (char**)xalloc(sn->len*sizeof(char*)); + if(sn->map == NULL) { + xfree(sn); + mapping->client_data = sn = NULL; + goto error; + } + for(i = 0; i < sn->len; i++) + sn->map[i] = nam[first+i]; + install_mapping(encoding,mapping); + mapping = 0; + first = 0xFFFF; last=0; + goto no_mapping; + case NAME_LINE: + if(value1 >= 0x10000) goto string_mapping; + if(namsize == 0) { + namsize = (value1) < 256 ? 256 : 0x10000; + nam = (char**)xalloc(namsize * sizeof(char*)); + if(nam == NULL) { + namsize=0; + goto error; + } + } else if(namsize <= value1) { + namsize = 0x10000; + if((newnam = (char**)xrealloc(nam, namsize)) == NULL) + goto error; + nam = newnam; + } + if(first > last) { + first = last = value1; + } + if(value1 < first) { + for(i = value1; i < first; i++) + nam[i] = NULL; + first = value1; + } + if(value1 > last) { + for(i=last+1; i <= value1; i++) + nam[i]=NULL; + last = value1; + } + nam[value1] = (char*)xalloc(strlen(keyword_value)+1); + if(nam[value1] == NULL) { + goto error; + } + strcpy(nam[value1], keyword_value); + goto string_mapping; + + default: goto string_mapping; /* ignore unknown lines */ + } + + done: + if(encsize) xfree(enc); encsize=0; enc = NULL; + if(namsize) xfree(nam); namsize=0; nam = NULL; /* don't free entries! */ + + encoding->aliases=NULL; + if(numaliases) { + encoding->aliases = (char**)xalloc((numaliases+1)*sizeof(char*)); + if(encoding->aliases == NULL) + goto error; + for(i=0; i<numaliases; i++) + encoding->aliases[i] = aliases[i]; + encoding->aliases[numaliases]=NULL; + } + + return encoding; + +error: + if(encsize) xfree(enc); encsize=0; + if(namsize) { + for(i = first; i <= last; i++) + if(nam[i]) + xfree(nam[i]); + xfree(nam); + namsize = 0; + } + if(mapping) { + if(mapping->client_data) xfree(mapping->client_data); + xfree(mapping); + } + if(encoding) { + if(encoding->name) xfree(encoding->name); + for(mapping = encoding->mappings; mapping; mapping = mapping->next) { + if(mapping->client_data) xfree(mapping->client_data); + xfree(mapping); + } + xfree(encoding); + } + for(i = 0; i < numaliases; i++) + xfree(aliases[i]); + /* We don't need to free sn and sm as they handled locally in the body.*/ + return 0; +} + +char* +FontEncDirectory() +{ + static char* dir = NULL; + + if(dir == NULL) { + char *c = getenv("FONT_ENCODINGS_DIRECTORY"); + if(c) { + dir = malloc(strlen(c) + 1); + if(!dir) + return NULL; + strcpy(dir, c); + } else { + dir = FONT_ENCODINGS_DIRECTORY; + } + } + return dir; +} + +static void +parseFontFileName(const char *fontFileName, char *buf, char *dir) +{ + const char *p; + char *q, *lastslash; + + for(p = fontFileName, q = dir, lastslash = NULL; *p; p++, q++) { + *q = *p; + if(*p == '/') + lastslash = q+1; + } + + if(!lastslash) + lastslash = dir; + + *lastslash = '\0'; + + if(buf && strlen(dir) + 14 < MAXFONTFILENAMELEN) { + strcpy(buf, dir); + strcat(buf, "encodings.dir"); + } +} + +static FontEncPtr +FontEncReallyReallyLoad(const char *charset, + const char *dirname, const char *dir) +{ + FontFilePtr f; + FILE *file; + FontEncPtr encoding; + char file_name[MAXFONTFILENAMELEN], encoding_name[MAXFONTNAMELEN], + buf[MAXFONTFILENAMELEN]; + int count, n; + static char format[24] = ""; + + /* As we don't really expect to open encodings that often, we don't + take the trouble of caching encodings directories. */ + + if((file = fopen(dirname, "r")) == NULL) { + return NULL; + } + + count = fscanf(file, "%d\n", &n); + if(count == EOF || count != 1) { + fclose(file); + return NULL; + } + + encoding = NULL; + if (!format[0]) { + sprintf(format, "%%%ds %%%d[^\n]\n", (int)sizeof(encoding_name) - 1, + (int)sizeof(file_name) - 1); + } + for(;;) { + count = fscanf(file, format, encoding_name, file_name); + if(count == EOF) + break; + if(count != 2) + break; + + if(!strcasecmp(encoding_name, charset)) { + /* Found it */ + if(file_name[0] != '/') { + if(strlen(dir) + strlen(file_name) >= MAXFONTFILENAMELEN) + return NULL; + strcpy(buf, dir); + strcat(buf, file_name); + } else { + strcpy(buf , file_name); + } + + f = FontFileOpen(buf); + if(f == NULL) { + return NULL; + } + encoding = parseEncodingFile(f, 0); + FontFileClose(f); + break; + } + } + + fclose(file); + + return encoding; +} + +/* Parser ntrypoint -- used by FontEncLoad */ +FontEncPtr +FontEncReallyLoad(const char *charset, const char *fontFileName) +{ + FontEncPtr encoding; + char dir[MAXFONTFILENAMELEN], dirname[MAXFONTFILENAMELEN]; + char *d; + + if(fontFileName) { + parseFontFileName(fontFileName, dirname, dir); + encoding = FontEncReallyReallyLoad(charset, dirname, dir); + if(encoding) + return(encoding); + } + + d = FontEncDirectory(); + if(d) { + parseFontFileName(d, NULL, dir); + encoding = FontEncReallyReallyLoad(charset, d, dir); + return encoding; + } + + return NULL; +} + +/* Return a NULL-terminated array of encoding names. Note that this + * function has incestuous knowledge of the allocations done by + * parseEncodingFile. */ + +char ** +FontEncIdentify(const char *fileName) +{ + FontFilePtr f; + FontEncPtr encoding; + char **names, **name, **alias; + int numaliases; + + if((f = FontFileOpen(fileName))==NULL) { + return NULL; + } + encoding = parseEncodingFile(f, 1); + FontFileClose(f); + + if(!encoding) + return NULL; + + numaliases = 0; + if(encoding->aliases) + for(alias = encoding->aliases; *alias; alias++) + numaliases++; + + names = (char**)xalloc((numaliases+2)*sizeof(char*)); + if(names == NULL) { + if(encoding->aliases) + xfree(encoding->aliases); + xfree(encoding); + return NULL; + } + + name = names; + *(name++) = encoding->name; + if(numaliases > 0) + for(alias = encoding->aliases; *alias; alias++, name++) + *name = *alias; + + *name = 0; + xfree(encoding->aliases); + xfree(encoding); + + return names; +} diff --git a/nx-X11/lib/font/fontfile/ffcheck.c b/nx-X11/lib/font/fontfile/ffcheck.c new file mode 100644 index 000000000..9a70a17f9 --- /dev/null +++ b/nx-X11/lib/font/fontfile/ffcheck.c @@ -0,0 +1,173 @@ +/* $Xorg: ffcheck.c,v 1.4 2001/02/09 02:04:03 xorgcvs Exp $ */ + +/* + +Copyright 1991, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ +/* $XFree86: xc/lib/font/fontfile/ffcheck.c,v 1.15tsi Exp $ */ + +/* + * Author: Keith Packard, MIT X Consortium + */ +/* $NCDXorg: @(#)fontfile.c,v 1.6 1991/07/02 17:00:46 lemke Exp $ */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <X11/fonts/fntfilst.h> +#include <X11/fonts/bitmap.h> +#ifdef LOADABLEFONTS +#include <X11/fonts/fontmod.h> +#endif + +/* + * Map FPE functions to renderer functions + */ + + +/* Here we must check the client to see if it has a context attached to + * it that allows us to access the printer fonts + */ + +static int +FontFileCheckOpenFont (pointer client, FontPathElementPtr fpe, Mask flags, + char *name, int namelen, + fsBitmapFormat format, fsBitmapFormatMask fmask, + XID id, FontPtr *pFont, char **aliasName, + FontPtr non_cachable_font) +{ + if (XpClientIsBitmapClient(client)) + return (FontFileOpenFont (client, fpe, flags, name, namelen, format, + fmask, id, pFont, aliasName, non_cachable_font)); + return BadFontName; +} + +static int +FontFileCheckListFonts (pointer client, FontPathElementPtr fpe, + char *pat, int len, int max, FontNamesPtr names) +{ + if (XpClientIsBitmapClient(client)) + return FontFileListFonts (client, fpe, pat, len, max, names); + return BadFontName; +} + +static int +FontFileCheckStartListFontsWithInfo(pointer client, FontPathElementPtr fpe, + char *pat, int len, int max, + pointer *privatep) +{ + if (XpClientIsBitmapClient(client)) + return FontFileStartListFontsWithInfo(client, fpe, pat, len, + max, privatep); + return BadFontName; +} + +static int +FontFileCheckListNextFontWithInfo(pointer client, FontPathElementPtr fpe, + char **namep, int *namelenp, + FontInfoPtr *pFontInfo, + int *numFonts, pointer private) +{ + if (XpClientIsBitmapClient(client)) + return FontFileListNextFontWithInfo(client, fpe, namep, namelenp, + pFontInfo, numFonts, private); + return BadFontName; +} + +static int +FontFileCheckStartListFontsAndAliases(pointer client, FontPathElementPtr fpe, + char *pat, int len, int max, + pointer *privatep) +{ + if (XpClientIsBitmapClient(client)) + return FontFileStartListFontsAndAliases(client, fpe, pat, len, + max, privatep); + return BadFontName; +} + +static int +FontFileCheckListNextFontOrAlias(pointer client, FontPathElementPtr fpe, + char **namep, int *namelenp, + char **resolvedp, int *resolvedlenp, + pointer private) +{ + if (XpClientIsBitmapClient(client)) + return FontFileListNextFontOrAlias(client, fpe, namep, namelenp, + resolvedp, resolvedlenp, private); + return BadFontName; +} + +void +FontFileCheckRegisterFpeFunctions (void) +{ +#ifndef LOADABLEFONTS + BitmapRegisterFontFileFunctions (); + + +#ifndef CRAY +#ifdef BUILD_SPEEDO + SpeedoRegisterFontFileFunctions (); +#endif +#ifdef BUILD_TYPE1 + Type1RegisterFontFileFunctions(); +#endif +#endif +#ifdef BUILD_CID + CIDRegisterFontFileFunctions(); +#endif +#ifdef BUILD_FREETYPE + FreeTypeRegisterFontFileFunctions(); +#endif + + +#else + + { + int i; + + if (FontModuleList) { + for (i = 0; FontModuleList[i].name; i++) { + if (FontModuleList[i].initFunc) + FontModuleList[i].initFunc(); + } + } + } +#endif + + RegisterFPEFunctions(FontFileNameCheck, + FontFileInitFPE, + FontFileFreeFPE, + FontFileResetFPE, + FontFileCheckOpenFont, + FontFileCloseFont, + FontFileCheckListFonts, + FontFileCheckStartListFontsWithInfo, + FontFileCheckListNextFontWithInfo, + NULL, + NULL, + NULL, + FontFileCheckStartListFontsAndAliases, + FontFileCheckListNextFontOrAlias, + FontFileEmptyBitmapSource); +} diff --git a/nx-X11/lib/font/fontfile/fileio.c b/nx-X11/lib/font/fontfile/fileio.c new file mode 100644 index 000000000..a3f94640b --- /dev/null +++ b/nx-X11/lib/font/fontfile/fileio.c @@ -0,0 +1,90 @@ +/* $Xorg: fileio.c,v 1.4 2001/02/09 02:04:03 xorgcvs Exp $ */ + +/* + +Copyright 1991, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ +/* $XFree86: xc/lib/font/fontfile/fileio.c,v 3.9 2001/12/14 19:56:51 dawes Exp $ */ + +/* + * Author: Keith Packard, MIT X Consortium + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <X11/fonts/fntfilio.h> +#include <X11/Xos.h> +#ifndef O_BINARY +#define O_BINARY O_RDONLY +#endif + +FontFilePtr +FontFileOpen (const char *name) +{ + int fd; + int len; + BufFilePtr raw, cooked; + + fd = open (name, O_BINARY); + if (fd < 0) + return 0; + raw = BufFileOpenRead (fd); + if (!raw) + { + close (fd); + return 0; + } + len = strlen (name); +#ifndef __UNIXOS2__ + if (len > 2 && !strcmp (name + len - 2, ".Z")) { +#else + if (len > 2 && (!strcmp (name + len - 4, ".pcz") || + !strcmp (name + len - 2, ".Z"))) { +#endif + cooked = BufFilePushCompressed (raw); + if (!cooked) { + BufFileClose (raw, TRUE); + return 0; + } + raw = cooked; +#ifdef X_GZIP_FONT_COMPRESSION + } else if (len > 3 && !strcmp (name + len - 3, ".gz")) { + cooked = BufFilePushZIP (raw); + if (!cooked) { + BufFileClose (raw, TRUE); + return 0; + } + raw = cooked; +#endif + } + return (FontFilePtr) raw; +} + +int +FontFileClose (FontFilePtr f) +{ + return BufFileClose ((BufFilePtr) f, TRUE); +} + diff --git a/nx-X11/lib/font/fontfile/filewr.c b/nx-X11/lib/font/fontfile/filewr.c new file mode 100644 index 000000000..d076f166a --- /dev/null +++ b/nx-X11/lib/font/fontfile/filewr.c @@ -0,0 +1,65 @@ +/* $Xorg: filewr.c,v 1.4 2001/02/09 02:04:03 xorgcvs Exp $ */ + +/* + +Copyright 1991, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ +/* $XFree86: xc/lib/font/fontfile/filewr.c,v 3.6 2001/12/14 19:56:51 dawes Exp $ */ + +/* + * Author: Keith Packard, MIT X Consortium + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <X11/fonts/fntfilio.h> +#include <X11/Xos.h> + +FontFilePtr +FontFileOpenWrite (const char *name) +{ + int fd; + +#if defined(WIN32) || defined(__UNIXOS2__) || defined(__CYGWIN__) + fd = open (name, O_CREAT|O_TRUNC|O_RDWR|O_BINARY, 0666); +#else + fd = creat (name, 0666); +#endif + if (fd < 0) + return 0; + return (FontFilePtr) BufFileOpenWrite (fd); +} + +FontFilePtr +FontFileOpenWriteFd (int fd) +{ + return (FontFilePtr) BufFileOpenWrite (fd); +} + +FontFilePtr +FontFileOpenFd (int fd) +{ + return (FontFilePtr) BufFileOpenRead (fd); +} diff --git a/nx-X11/lib/font/fontfile/fontdir.c b/nx-X11/lib/font/fontfile/fontdir.c new file mode 100644 index 000000000..8f75d8bde --- /dev/null +++ b/nx-X11/lib/font/fontfile/fontdir.c @@ -0,0 +1,827 @@ +/* $XdotOrg: xc/lib/font/fontfile/fontdir.c,v 1.6 2005/11/14 20:40:42 ajax Exp $ */ +/* $Xorg: fontdir.c,v 1.4 2001/02/09 02:04:03 xorgcvs Exp $ */ + +/* + +Copyright 1991, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ +/* $XFree86: xc/lib/font/fontfile/fontdir.c,v 3.22 2003/07/07 16:40:11 eich Exp $ */ + +/* + * Author: Keith Packard, MIT X Consortium + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <X11/fonts/fntfilst.h> +#include <X11/keysym.h> + +#if HAVE_STDINT_H +#include <stdint.h> +#elif !defined(INT32_MAX) +#define INT32_MAX 0x7fffffff +#endif + +Bool +FontFileInitTable (FontTablePtr table, int size) +{ + if (size < 0 || (size > INT32_MAX/sizeof(FontEntryRec))) + return FALSE; + if (size) + { + table->entries = (FontEntryPtr) xalloc(sizeof(FontEntryRec) * size); + if (!table->entries) + return FALSE; + } + else + table->entries = 0; + table->used = 0; + table->size = size; + table->sorted = FALSE; + return TRUE; +} + +void +FontFileFreeEntry (FontEntryPtr entry) +{ + FontScalableExtraPtr extra; + int i; + + if (entry->name.name) + xfree(entry->name.name); + entry->name.name = NULL; + + switch (entry->type) + { + case FONT_ENTRY_SCALABLE: + xfree (entry->u.scalable.fileName); + extra = entry->u.scalable.extra; + for (i = 0; i < extra->numScaled; i++) + if (extra->scaled[i].vals.ranges) + xfree (extra->scaled[i].vals.ranges); + xfree (extra->scaled); + xfree (extra); + break; + case FONT_ENTRY_BITMAP: + xfree (entry->u.bitmap.fileName); + entry->u.bitmap.fileName = NULL; + break; + case FONT_ENTRY_ALIAS: + xfree (entry->u.alias.resolved); + entry->u.alias.resolved = NULL; + break; +#ifdef NOTYET + case FONT_ENTRY_BC: + break; +#endif + } +} + +void +FontFileFreeTable (FontTablePtr table) +{ + int i; + + for (i = 0; i < table->used; i++) + FontFileFreeEntry (&table->entries[i]); + xfree (table->entries); +} + +FontDirectoryPtr +FontFileMakeDir(char *dirName, int size) +{ + FontDirectoryPtr dir; + int dirlen; + int needslash = 0; + char *attrib; + int attriblen; + +#if !defined(__UNIXOS2__) && !defined(WIN32) + attrib = strchr(dirName, ':'); +#else + /* OS/2 uses the colon in the drive letter descriptor, skip this */ + attrib = strchr(dirName+2, ':'); +#endif + if (attrib) { + dirlen = attrib - dirName; + attriblen = strlen(attrib); + } else { + dirlen = strlen(dirName); + attriblen = 0; + } + if (dirName[dirlen - 1] != '/') +#ifdef NCD + if (dirlen) /* leave out slash for builtins */ +#endif + needslash = 1; + dir = (FontDirectoryPtr) xalloc(sizeof *dir + dirlen + needslash + 1 + + (attriblen ? attriblen + 1 : 0)); + if (!dir) + return (FontDirectoryPtr)0; + if (!FontFileInitTable (&dir->scalable, 0)) + { + xfree (dir); + return (FontDirectoryPtr)0; + } + if (!FontFileInitTable (&dir->nonScalable, size)) + { + FontFileFreeTable (&dir->scalable); + xfree (dir); + return (FontDirectoryPtr)0; + } + dir->directory = (char *) (dir + 1); + dir->dir_mtime = 0; + dir->alias_mtime = 0; + if (attriblen) + dir->attributes = dir->directory + dirlen + needslash + 1; + else + dir->attributes = NULL; + strncpy(dir->directory, dirName, dirlen); + dir->directory[dirlen] = '\0'; + if (dir->attributes) + strcpy(dir->attributes, attrib); + if (needslash) + strcat(dir->directory, "/"); + return dir; +} + +void +FontFileFreeDir (FontDirectoryPtr dir) +{ + FontFileFreeTable (&dir->scalable); + FontFileFreeTable (&dir->nonScalable); + xfree(dir); +} + +FontEntryPtr +FontFileAddEntry(FontTablePtr table, FontEntryPtr prototype) +{ + FontEntryPtr entry; + int newsize; + + /* can't add entries to a sorted table, pointers get broken! */ + if (table->sorted) + return (FontEntryPtr) 0; /* "cannot" happen */ + if (table->used == table->size) { + newsize = table->size + 100; + entry = (FontEntryPtr) xrealloc(table->entries, + newsize * sizeof(FontEntryRec)); + if (!entry) + return (FontEntryPtr)0; + table->size = newsize; + table->entries = entry; + } + entry = &table->entries[table->used]; + *entry = *prototype; + entry->name.name = (char *) xalloc(prototype->name.length + 1); + if (!entry->name.name) + return (FontEntryPtr)0; + memcpy (entry->name.name, prototype->name.name, prototype->name.length); + entry->name.name[entry->name.length] = '\0'; + table->used++; + return entry; +} + +/* + * Compare two strings just like strcmp, but preserve decimal integer + * sorting order, i.e. "2" < "10" or "iso8859-2" < "iso8859-10" < + * "iso10646-1". Strings are sorted as if sequences of digits were + * prefixed by a length indicator (i.e., does not ignore leading zeroes). + * + * Markus Kuhn <Markus.Kuhn@cl.cam.ac.uk> + */ +#define Xisdigit(c) ('\060' <= (c) && (c) <= '\071') + +static int strcmpn(const char *s1, const char *s2) +{ + int digits, predigits = 0; + const char *ss1, *ss2; + + while (1) { + if (*s1 == 0 && *s2 == 0) + return 0; + digits = Xisdigit(*s1) && Xisdigit(*s2); + if (digits && !predigits) { + ss1 = s1; + ss2 = s2; + while (Xisdigit(*ss1) && Xisdigit(*ss2)) + ss1++, ss2++; + if (!Xisdigit(*ss1) && Xisdigit(*ss2)) + return -1; + if (Xisdigit(*ss1) && !Xisdigit(*ss2)) + return 1; + } + if ((unsigned char)*s1 < (unsigned char)*s2) + return -1; + if ((unsigned char)*s1 > (unsigned char)*s2) + return 1; + predigits = digits; + s1++, s2++; + } +} + + +static int +FontFileNameCompare(const void* a, const void* b) +{ + FontEntryPtr a_name = (FontEntryPtr) a, + b_name = (FontEntryPtr) b; + + return strcmpn(a_name->name.name, b_name->name.name); +} + +void +FontFileSortTable (FontTablePtr table) +{ + if (!table->sorted) { + qsort((char *) table->entries, table->used, sizeof(FontEntryRec), + FontFileNameCompare); + table->sorted = TRUE; + } +} + +void +FontFileSortDir(FontDirectoryPtr dir) +{ + FontFileSortTable (&dir->scalable); + FontFileSortTable (&dir->nonScalable); + /* now that the table is fixed in size, swizzle the pointers */ + FontFileSwitchStringsToBitmapPointers (dir); +} + +/* + Given a Font Table, SetupWildMatch() sets up various pointers and state + information so the table can be searched for name(s) that match a given + fontname pattern -- which may contain wildcards. Under certain + circumstances, SetupWildMatch() will find the one table entry that + matches the pattern. If those circumstances do not pertain, + SetupWildMatch() returns a range within the the table that should be + searched for matching name(s). With the information established by + SetupWildMatch(), including state information in "private", the + PatternMatch() procedure is then used to test names in the range for a + match. +*/ + +#define isWild(c) ((c) == XK_asterisk || (c) == XK_question) +#define isDigit(c) (XK_0 <= (c) && (c) <= XK_9) + +static int +SetupWildMatch(FontTablePtr table, FontNamePtr pat, + int *leftp, int *rightp, int *privatep) +{ + int nDashes; + char c; + char *t; + char *firstWild; + char *firstDigit; + int first; + int center, + left, + right; + int result; + char *name; + + name = pat->name; + nDashes = pat->ndashes; + firstWild = 0; + firstDigit = 0; + t = name; + while ((c = *t++)) { + if (isWild(c)) { + if (!firstWild) + firstWild = t - 1; + } + if (isDigit(c)) { + if (!firstDigit) + firstDigit = t - 1; + } + } + left = 0; + right = table->used; + if (firstWild) + *privatep = nDashes; + else + *privatep = -1; + if (!table->sorted) { + *leftp = left; + *rightp = right; + return -1; + } else if (firstWild) { + if (firstDigit && firstDigit < firstWild) + first = firstDigit - name; + else + first = firstWild - name; + while (left < right) { + center = (left + right) / 2; + result = strncmp(name, table->entries[center].name.name, first); + if (result == 0) + break; + if (result < 0) + right = center; + else + left = center + 1; + } + *leftp = left; + *rightp = right; + return -1; + } else { + while (left < right) { + center = (left + right) / 2; + result = strcmpn(name, table->entries[center].name.name); + if (result == 0) + return center; + if (result < 0) + right = center; + else + left = center + 1; + } + *leftp = 1; + *rightp = 0; + return -1; + } +} + +static int +PatternMatch(char *pat, int patdashes, char *string, int stringdashes) +{ + char c, + t; + + if (stringdashes < patdashes) + return 0; + for (;;) { + switch (c = *pat++) { + case '*': + if (!(c = *pat++)) + return 1; + if (c == XK_minus) { + patdashes--; + for (;;) { + while ((t = *string++) != XK_minus) + if (!t) + return 0; + stringdashes--; + if (PatternMatch(pat, patdashes, string, stringdashes)) + return 1; + if (stringdashes == patdashes) + return 0; + } + } else { + for (;;) { + while ((t = *string++) != c) { + if (!t) + return 0; + if (t == XK_minus) { + if (stringdashes-- < patdashes) + return 0; + } + } + if (PatternMatch(pat, patdashes, string, stringdashes)) + return 1; + } + } + case '?': + if (*string++ == XK_minus) + stringdashes--; + break; + case '\0': + return (*string == '\0'); + case XK_minus: + if (*string++ == XK_minus) { + patdashes--; + stringdashes--; + break; + } + return 0; + default: + if (c == *string++) + break; + return 0; + } + } +} + +int +FontFileCountDashes (char *name, int namelen) +{ + int ndashes = 0; + + while (namelen--) + if (*name++ == '\055') /* avoid non ascii systems */ + ++ndashes; + return ndashes; +} + +char * +FontFileSaveString (char *s) +{ + char *n; + + n = (char *) xalloc (strlen (s) + 1); + if (!n) + return 0; + strcpy (n, s); + return n; +} + +FontEntryPtr +FontFileFindNameInScalableDir(FontTablePtr table, FontNamePtr pat, + FontScalablePtr vals) +{ + int i, + start, + stop, + res, + private; + FontNamePtr name; + + if ((i = SetupWildMatch(table, pat, &start, &stop, &private)) >= 0) + return &table->entries[i]; + for (i = start; i < stop; i++) { + name = &table->entries[i].name; + res = PatternMatch(pat->name, private, name->name, name->ndashes); + if (res > 0) + { + /* Check to see if enhancements requested are available */ + if (vals) + { + int vs = vals->values_supplied; + int cap; + + if (table->entries[i].type == FONT_ENTRY_SCALABLE) + cap = table->entries[i].u.scalable.renderer->capabilities; + else if (table->entries[i].type == FONT_ENTRY_ALIAS) + cap = ~0; /* Calling code will have to see if true */ + else + cap = 0; + if ((((vs & PIXELSIZE_MASK) == PIXELSIZE_ARRAY || + (vs & POINTSIZE_MASK) == POINTSIZE_ARRAY) && + !(cap & CAP_MATRIX)) || + ((vs & CHARSUBSET_SPECIFIED) && + !(cap & CAP_CHARSUBSETTING))) + continue; + } + return &table->entries[i]; + } + if (res < 0) + break; + } + return (FontEntryPtr)0; +} + +FontEntryPtr +FontFileFindNameInDir(FontTablePtr table, FontNamePtr pat) +{ + return FontFileFindNameInScalableDir(table, pat, (FontScalablePtr)0); +} + +int +FontFileFindNamesInScalableDir(FontTablePtr table, FontNamePtr pat, int max, + FontNamesPtr names, FontScalablePtr vals, + int alias_behavior, int *newmax) +{ + int i, + start, + stop, + res, + private; + int ret = Successful; + FontEntryPtr fname; + FontNamePtr name; + + if (max <= 0) + return Successful; + if ((i = SetupWildMatch(table, pat, &start, &stop, &private)) >= 0) { + if (alias_behavior == NORMAL_ALIAS_BEHAVIOR || + table->entries[i].type != FONT_ENTRY_ALIAS) + { + name = &table->entries[i].name; + if (newmax) *newmax = max - 1; + return AddFontNamesName(names, name->name, name->length); + } + start = i; + stop = i + 1; + } + for (i = start, fname = &table->entries[start]; i < stop; i++, fname++) { + res = PatternMatch(pat->name, private, fname->name.name, fname->name.ndashes); + if (res > 0) { + if (vals) + { + int vs = vals->values_supplied; + int cap; + + if (fname->type == FONT_ENTRY_SCALABLE) + cap = fname->u.scalable.renderer->capabilities; + else if (fname->type == FONT_ENTRY_ALIAS) + cap = ~0; /* Calling code will have to see if true */ + else + cap = 0; + if ((((vs & PIXELSIZE_MASK) == PIXELSIZE_ARRAY || + (vs & POINTSIZE_MASK) == POINTSIZE_ARRAY) && + !(cap & CAP_MATRIX)) || + ((vs & CHARSUBSET_SPECIFIED) && + !(cap & CAP_CHARSUBSETTING))) + continue; + } + + if ((alias_behavior & IGNORE_SCALABLE_ALIASES) && + fname->type == FONT_ENTRY_ALIAS) + { + FontScalableRec tmpvals; + if (FontParseXLFDName (fname->name.name, &tmpvals, + FONT_XLFD_REPLACE_NONE) && + !(tmpvals.values_supplied & SIZE_SPECIFY_MASK)) + continue; + } + + ret = AddFontNamesName(names, fname->name.name, fname->name.length); + if (ret != Successful) + goto bail; + + /* If alias_behavior is LIST_ALIASES_AND_TARGET_NAMES, mark + this entry as an alias by negating its length and follow + it by the resolved name */ + if ((alias_behavior & LIST_ALIASES_AND_TARGET_NAMES) && + fname->type == FONT_ENTRY_ALIAS) + { + names->length[names->nnames - 1] = + -names->length[names->nnames - 1]; + ret = AddFontNamesName(names, fname->u.alias.resolved, + strlen(fname->u.alias.resolved)); + if (ret != Successful) + goto bail; + } + + if (--max <= 0) + break; + } else if (res < 0) + break; + } + bail: ; + if (newmax) *newmax = max; + return ret; +} + +int +FontFileFindNamesInDir(FontTablePtr table, FontNamePtr pat, + int max, FontNamesPtr names) +{ + return FontFileFindNamesInScalableDir(table, pat, max, names, + (FontScalablePtr)0, + NORMAL_ALIAS_BEHAVIOR, (int *)0); +} + +Bool +FontFileMatchName(char *name, int length, FontNamePtr pat) +{ + /* Perform a fontfile-type name match on a single name */ + FontTableRec table; + FontEntryRec entries[1]; + + /* Dummy up a table */ + table.used = 1; + table.size = 1; + table.sorted = TRUE; + table.entries = entries; + entries[0].name.name = name; + entries[0].name.length = length; + entries[0].name.ndashes = FontFileCountDashes(name, length); + + return FontFileFindNameInDir(&table, pat) != (FontEntryPtr)0; +} + +/* + * Add a font file to a directory. This handles bitmap and + * scalable names both + */ + +Bool +FontFileAddFontFile (FontDirectoryPtr dir, char *fontName, char *fileName) +{ + FontEntryRec entry; + FontScalableRec vals, zeroVals; + FontRendererPtr renderer; + FontEntryPtr existing; + FontScalableExtraPtr extra; + FontEntryPtr bitmap = 0, scalable; + Bool isscale; + Bool scalable_xlfd; + + renderer = FontFileMatchRenderer (fileName); + if (!renderer) + return FALSE; + entry.name.length = strlen (fontName); + if (entry.name.length > MAXFONTNAMELEN) + entry.name.length = MAXFONTNAMELEN; + entry.name.name = fontName; + CopyISOLatin1Lowered (entry.name.name, fontName, entry.name.length); + entry.name.ndashes = FontFileCountDashes (entry.name.name, entry.name.length); + entry.name.name[entry.name.length] = '\0'; + /* + * Add a bitmap name if the incoming name isn't an XLFD name, or + * if it isn't a scalable name (i.e. non-zero scalable fields) + * + * If name of bitmapped font contains XLFD enhancements, do not add + * a scalable version of the name... this can lead to confusion and + * ambiguity between the font name and the field enhancements. + */ + isscale = entry.name.ndashes == 14 && + FontParseXLFDName(entry.name.name, + &vals, FONT_XLFD_REPLACE_NONE) && + (vals.values_supplied & PIXELSIZE_MASK) != PIXELSIZE_ARRAY && + (vals.values_supplied & POINTSIZE_MASK) != POINTSIZE_ARRAY && + !(vals.values_supplied & ENHANCEMENT_SPECIFY_MASK); +#define UNSCALED_ATTRIB "unscaled" + scalable_xlfd = (isscale && + (((vals.values_supplied & PIXELSIZE_MASK) == 0) || + ((vals.values_supplied & POINTSIZE_MASK) == 0))); + /* + * For scalable fonts without a scalable XFLD, check if the "unscaled" + * attribute is present. + */ + if (isscale && !scalable_xlfd && + dir->attributes && dir->attributes[0] == ':') { + char *ptr1 = dir->attributes + 1; + char *ptr2; + int length; + int uslength = strlen(UNSCALED_ATTRIB); + + do { + ptr2 = strchr(ptr1, ':'); + if (ptr2) + length = ptr2 - ptr1; + else + length = dir->attributes + strlen(dir->attributes) - ptr1; + if (length == uslength && !strncmp(ptr1, UNSCALED_ATTRIB, uslength)) + isscale = FALSE; + if (ptr2) + ptr1 = ptr2 + 1; + } while (ptr2); + } + if (!isscale || (vals.values_supplied & SIZE_SPECIFY_MASK)) + { + /* + * If the renderer doesn't support OpenBitmap, FontFileOpenFont + * will still do the right thing. + */ + entry.type = FONT_ENTRY_BITMAP; + entry.u.bitmap.renderer = renderer; + entry.u.bitmap.pFont = NullFont; + if (!(entry.u.bitmap.fileName = FontFileSaveString (fileName))) + return FALSE; + if (!(bitmap = FontFileAddEntry (&dir->nonScalable, &entry))) + { + xfree (entry.u.bitmap.fileName); + return FALSE; + } + } + /* + * Parse out scalable fields from XLFD names - a scalable name + * just gets inserted, a scaled name has more things to do. + */ + if (isscale) + { + if (vals.values_supplied & SIZE_SPECIFY_MASK) + { + bzero((char *)&zeroVals, sizeof(zeroVals)); + zeroVals.x = vals.x; + zeroVals.y = vals.y; + zeroVals.values_supplied = PIXELSIZE_SCALAR | POINTSIZE_SCALAR; + FontParseXLFDName (entry.name.name, &zeroVals, + FONT_XLFD_REPLACE_VALUE); + entry.name.length = strlen (entry.name.name); + existing = FontFileFindNameInDir (&dir->scalable, &entry.name); + if (existing) + { + if ((vals.values_supplied & POINTSIZE_MASK) == + POINTSIZE_SCALAR && + (int)(vals.point_matrix[3] * 10) == GetDefaultPointSize()) + { + existing->u.scalable.extra->defaults = vals; + + xfree (existing->u.scalable.fileName); + if (!(existing->u.scalable.fileName = FontFileSaveString (fileName))) + return FALSE; + } + if(bitmap) + { + FontFileCompleteXLFD(&vals, &vals); + FontFileAddScaledInstance (existing, &vals, NullFont, + bitmap->name.name); + return TRUE; + } + } + } + if (!(entry.u.scalable.fileName = FontFileSaveString (fileName))) + return FALSE; + extra = (FontScalableExtraPtr) xalloc (sizeof (FontScalableExtraRec)); + if (!extra) + { + xfree (entry.u.scalable.fileName); + return FALSE; + } + bzero((char *)&extra->defaults, sizeof(extra->defaults)); + if ((vals.values_supplied & POINTSIZE_MASK) == POINTSIZE_SCALAR && + (int)(vals.point_matrix[3] * 10) == GetDefaultPointSize()) + extra->defaults = vals; + else + { + FontResolutionPtr resolution; + int num; + + extra->defaults.point_matrix[0] = + extra->defaults.point_matrix[3] = + (double)GetDefaultPointSize() / 10.0; + extra->defaults.point_matrix[1] = + extra->defaults.point_matrix[2] = 0.0; + extra->defaults.values_supplied = + POINTSIZE_SCALAR | PIXELSIZE_UNDEFINED; + extra->defaults.width = -1; + if (vals.x <= 0 || vals.y <= 0) + { + resolution = GetClientResolutions (&num); + if (resolution && num > 0) + { + extra->defaults.x = resolution->x_resolution; + extra->defaults.y = resolution->y_resolution; + } + else + { + extra->defaults.x = 75; + extra->defaults.y = 75; + } + } + else + { + extra->defaults.x = vals.x; + extra->defaults.y = vals.y; + } + FontFileCompleteXLFD (&extra->defaults, &extra->defaults); + } + extra->numScaled = 0; + extra->sizeScaled = 0; + extra->scaled = 0; + extra->private = 0; + entry.type = FONT_ENTRY_SCALABLE; + entry.u.scalable.renderer = renderer; + entry.u.scalable.extra = extra; + if (!(scalable = FontFileAddEntry (&dir->scalable, &entry))) + { + xfree (extra); + xfree (entry.u.scalable.fileName); + return FALSE; + } + if (vals.values_supplied & SIZE_SPECIFY_MASK) + { + if(bitmap) + { + FontFileCompleteXLFD(&vals, &vals); + FontFileAddScaledInstance (scalable, &vals, NullFont, + bitmap->name.name); + } + } + } + return TRUE; +} + +Bool +FontFileAddFontAlias (FontDirectoryPtr dir, char *aliasName, char *fontName) +{ + FontEntryRec entry; + + entry.name.length = strlen (aliasName); + CopyISOLatin1Lowered (aliasName, aliasName, entry.name.length); + entry.name.name = aliasName; + entry.name.ndashes = FontFileCountDashes (entry.name.name, entry.name.length); + entry.type = FONT_ENTRY_ALIAS; + if (!(entry.u.alias.resolved = FontFileSaveString (fontName))) + return FALSE; + if (!FontFileAddEntry (&dir->nonScalable, &entry)) + { + xfree (entry.u.alias.resolved); + return FALSE; + } + return TRUE; +} diff --git a/nx-X11/lib/font/fontfile/fontenc.c b/nx-X11/lib/font/fontfile/fontenc.c new file mode 100644 index 000000000..e96cdde26 --- /dev/null +++ b/nx-X11/lib/font/fontfile/fontenc.c @@ -0,0 +1,952 @@ +/* +Copyright (c) 1998-2001 by Juliusz Chroboczek + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +/* $XdotOrg: xc/lib/font/fontfile/fontenc.c,v 1.5 2005/11/08 06:33:26 jkj Exp $ */ +/* $XFree86: xc/lib/font/fontfile/fontenc.c,v 1.15 2003/02/20 03:25:19 dawes Exp $ */ + +/* Backend-independent encoding code */ + +#include <string.h> + +#if defined(__SCO__) || defined(__UNIXWARE__) +#include <strings.h> +#endif + +#ifndef FONTENC_NO_LIBFONT + +#include <X11/fonts/fontmisc.h> /* defines xalloc and friends */ +#include <X11/fonts/fntfilst.h> + +#else + +#include <stdlib.h> +#define xalloc(n) malloc(n) +#define xrealloc(p, n) realloc(p, n) +#define xfree(p) free(p) +#define FALSE 0 +#define TRUE 1 +#define MAXFONTNAMELEN 1024 +#define MAXFONTFILENAMELEN 1024 + +#endif /* FONTENC_NO_FONTFILE */ + +#include <X11/fonts/fontenc.h> +#include "fontencI.h" + +/* Functions local to this file */ + +static FontEncPtr FontEncLoad(const char*, const char*); + +/* Early versions of this code only knew about hardwired encodings, + hence the following data. Now that the code knows how to load an + encoding from a file, most of these tables could go away. */ + +/* At any rate, no new hardcoded encodings will be added. */ + +static FontMapRec iso10646[]= +{ + {FONT_ENCODING_UNICODE,0,0,0,0,0,0}, + {0,0,0,0,0,0,0} +}; + +/* Notice that the Apple encodings do not have all the characters in + the corresponding ISO 8859, and therefore the table has some holes. + There's not much more we can do with fonts without a Unicode cmap + unless we are willing to combine cmaps (which we are not). */ + +static unsigned short +iso8859_1_apple_roman[]= +{ 0xCA, 0xC1, 0xA2, 0xA3, 0xDB, 0xB4, 0x00, 0xA4, + 0xAC, 0xA9, 0xBB, 0xC7, 0xC2, 0x00, 0xA8, 0xF8, + 0xA1, 0xB1, 0x00, 0x00, 0xAB, 0xB5, 0xA6, 0xE1, + 0xFC, 0x00, 0xBC, 0xC8, 0x00, 0x00, 0x00, 0xC0, + 0xCB, 0xE7, 0xE5, 0xCC, 0x80, 0x81, 0xAE, 0x82, + 0xE9, 0x83, 0xE6, 0xE8, 0xED, 0xEA, 0xEB, 0xEC, + 0x00, 0x84, 0xF1, 0xEE, 0xEF, 0xCD, 0x85, 0x00, + 0xAF, 0xF4, 0xF2, 0xF3, 0x86, 0x00, 0x00, 0xA7, + 0x88, 0x87, 0x89, 0x8B, 0x8A, 0x8C, 0xBE, 0x8D, + 0x8F, 0x8E, 0x90, 0x91, 0x93, 0x92, 0x94, 0x95, + 0x00, 0x96, 0x98, 0x97, 0x99, 0x9B, 0x9A, 0xD6, + 0xBF, 0x9D, 0x9C, 0x9E, 0x9F, 0x00, 0x00, 0xD8 }; + +/* Cannot use simple_recode because need to eliminate 0x80<=code<0xA0 */ +static unsigned +iso8859_1_to_apple_roman(unsigned isocode, void *client_data) +{ + if(isocode<=0x80) + return isocode; + else if(isocode>=0xA0) + return iso8859_1_apple_roman[isocode-0xA0]; + else + return 0; +} + +static FontMapRec iso8859_1[]= +{ + {FONT_ENCODING_TRUETYPE,2,2,0,0,0,0}, /* ISO 8859-1 */ + {FONT_ENCODING_UNICODE,0,0,0,0,0,0}, /* ISO 8859-1 coincides with Unicode*/ + {FONT_ENCODING_TRUETYPE,1,0,iso8859_1_to_apple_roman,0,0,0}, + {0,0,0,0,0,0,0} +}; + +static unsigned short iso8859_2_tophalf[]= +{ 0x00A0, 0x0104, 0x02D8, 0x0141, 0x00A4, 0x013D, 0x015A, 0x00A7, + 0x00A8, 0x0160, 0x015E, 0x0164, 0x0179, 0x00AD, 0x017D, 0x017B, + 0x00B0, 0x0105, 0x02DB, 0x0142, 0x00B4, 0x013E, 0x015B, 0x02C7, + 0x00B8, 0x0161, 0x015F, 0x0165, 0x017A, 0x02DD, 0x017E, 0x017C, + 0x0154, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x0139, 0x0106, 0x00C7, + 0x010C, 0x00C9, 0x0118, 0x00CB, 0x011A, 0x00CD, 0x00CE, 0x010E, + 0x0110, 0x0143, 0x0147, 0x00D3, 0x00D4, 0x0150, 0x00D6, 0x00D7, + 0x0158, 0x016E, 0x00DA, 0x0170, 0x00DC, 0x00DD, 0x0162, 0x00DF, + 0x0155, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x013A, 0x0107, 0x00E7, + 0x010D, 0x00E9, 0x0119, 0x00EB, 0x011B, 0x00ED, 0x00EE, 0x010F, + 0x0111, 0x0144, 0x0148, 0x00F3, 0x00F4, 0x0151, 0x00F6, 0x00F7, + 0x0159, 0x016F, 0x00FA, 0x0171, 0x00FC, 0x00FD, 0x0163, 0x02D9 }; + +static FontEncSimpleMapRec iso8859_2_to_unicode_map= +{0x60, 0, 0xA0, iso8859_2_tophalf }; + +static unsigned short iso8859_2_apple_centeuro[]= +{ 0xCA, 0x84, 0x00, 0xFC, 0x00, 0xBB, 0xE5, 0xA4, + 0xAC, 0xE1, 0x00, 0xE8, 0x8F, 0x00, 0xEB, 0xFB, + 0xA1, 0x88, 0x00, 0xB8, 0x00, 0xBC, 0xE6, 0xFF, + 0x00, 0xE4, 0x00, 0xE9, 0x90, 0x00, 0xEC, 0xFD, + 0xD9, 0xE7, 0x00, 0x00, 0x80, 0xBD, 0x8C, 0x00, + 0x89, 0x83, 0xA2, 0x00, 0x9D, 0xEA, 0x00, 0x91, + 0x00, 0xC1, 0xC5, 0xEE, 0xEF, 0xCC, 0x85, 0x00, + 0xDB, 0xF1, 0xF2, 0xF4, 0x86, 0xF8, 0x00, 0xA7, + 0xDA, 0x87, 0x00, 0x00, 0x8A, 0xBE, 0x8D, 0x00, + 0x8B, 0x8E, 0xAB, 0x00, 0x9E, 0x92, 0x00, 0x93, + 0x00, 0xC4, 0xCB, 0x97, 0x99, 0xCE, 0x9A, 0xD6, + 0xDE, 0xF3, 0x9C, 0xF5, 0x9F, 0xF9, 0x00, 0x00 }; + +static unsigned +iso8859_2_to_apple_centeuro(unsigned isocode, void *client_data) +{ + if(isocode<=0x80) + return isocode; + else if(isocode>=0xA0) + return iso8859_2_apple_centeuro[isocode-0xA0]; + else + return 0; +} + + +static FontMapRec iso8859_2[]= +{ + {FONT_ENCODING_UNICODE,0,0, + FontEncSimpleRecode,0,&iso8859_2_to_unicode_map,0}, + {FONT_ENCODING_TRUETYPE,1,29,iso8859_2_to_apple_centeuro,0,0,0}, + {0,0,0,0,0,0,0} +}; + +static unsigned short iso8859_3_tophalf[]= +{ 0x00A0, 0x0126, 0x02D8, 0x00A3, 0x00A4, 0x0000, 0x0124, 0x00A7, + 0x00A8, 0x0130, 0x015E, 0x011E, 0x0134, 0x00AD, 0x0000, 0x017B, + 0x00B0, 0x0127, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x0125, 0x00B7, + 0x00B8, 0x0131, 0x015F, 0x011F, 0x0135, 0x00BD, 0x0000, 0x017C, + 0x00C0, 0x00C1, 0x00C2, 0x0000, 0x00C4, 0x010A, 0x0108, 0x00C7, + 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF, + 0x0000, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x0120, 0x00D6, 0x00D7, + 0x011C, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x016C, 0x015C, 0x00DF, + 0x00E0, 0x00E1, 0x00E2, 0x0000, 0x00E4, 0x010B, 0x0109, 0x00E7, + 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, + 0x0000, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x0121, 0x00F6, 0x00F7, + 0x011D, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x016D, 0x015D, 0x02D9}; + +static FontEncSimpleMapRec iso8859_3_to_unicode_map= +{ 0x60, 0, 0xA0, iso8859_3_tophalf }; + +static FontMapRec iso8859_3[]= +{ + {FONT_ENCODING_UNICODE,0,0, + FontEncSimpleRecode,0,&iso8859_3_to_unicode_map,0}, + {0,0,0,0,0,0,0} +}; + + +static unsigned short iso8859_4_tophalf[]= +{ 0x00A0, 0x0104, 0x0138, 0x0156, 0x00A4, 0x0128, 0x013B, 0x00A7, + 0x00A8, 0x0160, 0x0112, 0x0122, 0x0166, 0x00AD, 0x017D, 0x00AF, + 0x00B0, 0x0105, 0x02DB, 0x0157, 0x00B4, 0x0129, 0x013C, 0x02C7, + 0x00B8, 0x0161, 0x0113, 0x0123, 0x0167, 0x014A, 0x017E, 0x014B, + 0x0100, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x012E, + 0x010C, 0x00C9, 0x0118, 0x00CB, 0x0116, 0x00CD, 0x00CE, 0x012A, + 0x0110, 0x0145, 0x014C, 0x0136, 0x00D4, 0x00D5, 0x00D6, 0x00D7, + 0x00D8, 0x0172, 0x00DA, 0x00DB, 0x00DC, 0x0168, 0x016A, 0x00DF, + 0x0101, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x012F, + 0x010D, 0x00E9, 0x0119, 0x00EB, 0x0117, 0x00ED, 0x00EE, 0x012B, + 0x0111, 0x0146, 0x014D, 0x0137, 0x00F4, 0x00F5, 0x00F6, 0x00F7, + 0x00F8, 0x0173, 0x00FA, 0x00FB, 0x00FC, 0x0169, 0x016B, 0x02D9, +}; + +static FontEncSimpleMapRec iso8859_4_to_unicode_map= +{ 0x60, 0, 0xA0, iso8859_4_tophalf }; + +static FontMapRec iso8859_4[]= +{ + {FONT_ENCODING_UNICODE,0,0,FontEncSimpleRecode,0, + &iso8859_4_to_unicode_map,0}, + {0,0,0,0,0,0,0} +}; + +static unsigned short iso8859_5_tophalf[]= +{ 0x00A0, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0406, 0x0407, + 0x0408, 0x0409, 0x040A, 0x040B, 0x040C, 0x00AD, 0x040E, 0x040F, + 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, + 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F, + 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, + 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F, + 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, + 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F, + 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, + 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F, + 0x2116, 0x0451, 0x0452, 0x0453, 0x0454, 0x0455, 0x0456, 0x0457, + 0x0458, 0x0459, 0x045A, 0x045B, 0x045C, 0x00A7, 0x045E, 0x045F}; + +static FontEncSimpleMapRec iso8859_5_to_unicode_map= +{ 0x60, 0, 0xA0, iso8859_5_tophalf }; + +static unsigned short +iso8859_5_apple_cyrillic[]= +{ 0xCA, 0xDD, 0xAB, 0xAE, 0xB8, 0xC1, 0xA7, 0xBA, + 0xB7, 0xBC, 0xBE, 0xCB, 0xCD, 0x00, 0xD8, 0xDA, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, + 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, + 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, + 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, + 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, + 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xDF, + 0xDC, 0xDE, 0xAC, 0xAF, 0xB9, 0xCF, 0xB4, 0xBB, + 0xC0, 0xBD, 0xBF, 0xCC, 0xCE, 0xA4, 0xD9, 0xDB }; + +static unsigned +iso8859_5_to_apple_cyrillic(unsigned isocode, void *client_data) +{ + if(isocode<=0x80) + return isocode; + else if(isocode>=0xA0) + return iso8859_5_apple_cyrillic[isocode-0x80]; + else return 0; +} + +static FontMapRec iso8859_5[]= +{ + {FONT_ENCODING_UNICODE,0,0,FontEncSimpleRecode,0, + &iso8859_5_to_unicode_map,0}, + {FONT_ENCODING_TRUETYPE,1,7,iso8859_5_to_apple_cyrillic,0,0,0}, + {0,0,0,0,0,0,0} +}; + +/* ISO 8859-6 seems useless for serving fonts (not enough presentation + * forms). What do Arabic-speakers use? */ + +static unsigned +iso8859_6_to_unicode(unsigned isocode, void *client_data) +{ + if(isocode<=0xA0 || isocode==0xA4 || isocode==0xAD) + return isocode; + else if(isocode==0xAC || isocode==0xBB || + (isocode>=0xBF && isocode<=0xDA) || + (isocode>=0xE0 && isocode<=0xEF) || + (isocode>=0xF0 && isocode<=0xF2)) + return isocode-0xA0+0x0600; + else + return 0; +} + +static FontMapRec iso8859_6[]= +{ + {FONT_ENCODING_UNICODE,0,0,iso8859_6_to_unicode,0,0,0}, + {0,0,0,0,0,0,0} +}; + +static unsigned +iso8859_7_to_unicode(unsigned isocode, void *client_data) +{ + if(isocode<=0xA0 || + (isocode>=0xA3 && isocode<=0xAD) || + (isocode>=0xB0 && isocode<=0xB3) || + isocode==0xB7 || isocode==0xBB || isocode==0xBD) + return isocode; + else if(isocode==0xA1) + return 0x02BD; + else if(isocode==0xA2) + return 0x02BC; + else if(isocode==0xAF) + return 0x2015; + else if(isocode>=0xB4) + return isocode-0xA0+0x0370; + else + return 0; +} + +static FontMapRec iso8859_7[]= +{ + {FONT_ENCODING_UNICODE,0,0,iso8859_7_to_unicode,0,0,0}, + {0,0,0,0,0,0,0} +}; + +static unsigned +iso8859_8_to_unicode(unsigned isocode, void *client_data) +{ + if(isocode==0xA1) + return 0; + else if(isocode<0xBF) + return isocode; + else if(isocode==0xDF) + return 0x2017; + else if(isocode>=0xE0 && isocode<=0xFA) + return isocode+0x04F0; + else + return 0; +} + +static FontMapRec iso8859_8[]= +{ + {FONT_ENCODING_UNICODE,0,0,iso8859_8_to_unicode,0,0,0}, + {0,0,0,0,0,0,0} +}; + +static unsigned +iso8859_9_to_unicode(unsigned isocode, void *client_data) +{ + switch(isocode) { + case 0xD0: return 0x011E; + case 0xDD: return 0x0130; + case 0xDE: return 0x015E; + case 0xF0: return 0x011F; + case 0xFD: return 0x0131; + case 0xFE: return 0x015F; + default: return isocode; + } +} + +static FontMapRec iso8859_9[]= +{ + {FONT_ENCODING_UNICODE,0,0,iso8859_9_to_unicode,0,0,0}, + {0,0,0,0,0,0,0} +}; + +static unsigned short iso8859_10_tophalf[]= +{ 0x00A0, 0x0104, 0x0112, 0x0122, 0x012A, 0x0128, 0x0136, 0x00A7, + 0x013B, 0x0110, 0x0160, 0x0166, 0x017D, 0x00AD, 0x016A, 0x014A, + 0x00B0, 0x0105, 0x0113, 0x0123, 0x012B, 0x0129, 0x0137, 0x00B7, + 0x013C, 0x0111, 0x0161, 0x0167, 0x017E, 0x2014, 0x016B, 0x014B, + 0x0100, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x012E, + 0x010C, 0x00C9, 0x0118, 0x00CB, 0x0116, 0x00CD, 0x00CE, 0x00CF, + 0x00D0, 0x0145, 0x014C, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x0168, + 0x00D8, 0x0172, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF, + 0x0101, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x012F, + 0x010D, 0x00E9, 0x0119, 0x00EB, 0x0117, 0x00ED, 0x00EE, 0x00EF, + 0x00F0, 0x0146, 0x014D, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x0169, + 0x00F8, 0x0173, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x0138}; + +static FontEncSimpleMapRec iso8859_10_to_unicode_map= +{ 0x60, 0, 0xA0, iso8859_10_tophalf }; + +static FontMapRec iso8859_10[]= +{ + {FONT_ENCODING_UNICODE,0,0,FontEncSimpleRecode,0, + &iso8859_10_to_unicode_map,0}, + {0,0,0,0,0,0,0} +}; + +static unsigned +iso8859_15_to_unicode(unsigned isocode, void *client_data) +{ + switch(isocode) { + case 0xA4: return 0x20AC; + case 0xA6: return 0x0160; + case 0xA8: return 0x0161; + case 0xB4: return 0x017D; + case 0xB8: return 0x017E; + case 0xBC: return 0x0152; + case 0xBD: return 0x0153; + case 0xBE: return 0x0178; + default: return isocode; + } +} + +static FontMapRec iso8859_15[]= +{ + {FONT_ENCODING_UNICODE,0,0,iso8859_15_to_unicode,0,0,0}, + {0,0,0,0,0,0,0} +}; + +static unsigned short koi8_r_tophalf[]= +{ 0x2500, 0x2502, 0x250C, 0x2510, 0x2514, 0x2518, 0x251C, 0x2524, + 0x252C, 0x2534, 0x253C, 0x2580, 0x2584, 0x2588, 0x258C, 0x2590, + 0x2591, 0x2592, 0x2593, 0x2320, 0x25A0, 0x2022, 0x221A, 0x2248, + 0x2264, 0x2265, 0x00A0, 0x2321, 0x00B0, 0x00B2, 0x00B7, 0x00F7, + 0x2550, 0x2551, 0x2552, 0x0451, 0x2553, 0x2554, 0x2555, 0x2556, + 0x2557, 0x2558, 0x2559, 0x255A, 0x255B, 0x255C, 0x255D, 0x255E, + 0x255F, 0x2560, 0x2561, 0x0401, 0x2562, 0x2563, 0x2564, 0x2565, + 0x2566, 0x2567, 0x2568, 0x2569, 0x256A, 0x256B, 0x256C, 0x00A9, + 0x044E, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433, + 0x0445, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, + 0x043F, 0x044F, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432, + 0x044C, 0x044B, 0x0437, 0x0448, 0x044D, 0x0449, 0x0447, 0x044A, + 0x042E, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413, + 0x0425, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, + 0x041F, 0x042F, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412, + 0x042C, 0x042B, 0x0417, 0x0428, 0x042D, 0x0429, 0x0427, 0x042A}; + +static FontEncSimpleMapRec koi8_r_to_unicode_map= +{ 0x80, 0, 0x80, koi8_r_tophalf }; + + +static FontMapRec koi8_r[]= +{ + {FONT_ENCODING_UNICODE,0,0,FontEncSimpleRecode,0, + &koi8_r_to_unicode_map,0}, + {0,0,0,0,0,0,0} +}; + +static unsigned +koi8_ru_to_unicode(unsigned koicode, void *client_data) +{ + switch(koicode) { + case 0x93: return 0x201C; + case 0x96: return 0x201D; + case 0x97: return 0x2014; + case 0x98: return 0x2116; + case 0x99: return 0x2122; + case 0x9B: return 0x00BB; + case 0x9C: return 0x00AE; + case 0x9D: return 0x00AB; + case 0x9F: return 0x00A4; + case 0xA4: return 0x0454; + case 0xA6: return 0x0456; + case 0xA7: return 0x0457; + case 0xAD: return 0x0491; + case 0xAE: return 0x045E; + case 0xB4: return 0x0404; + case 0xB6: return 0x0406; + case 0xB7: return 0x0407; + case 0xBD: return 0x0490; + case 0xBE: return 0x040E; + default: return FontEncSimpleRecode(koicode, &koi8_r_to_unicode_map); + } +} + +static FontMapRec koi8_ru[]= +{ + {FONT_ENCODING_UNICODE,0,0,koi8_ru_to_unicode,0,0,0}, + {0,0,0,0,0,0,0} +}; + +/* koi8-e, ISO-IR-111 or ECMA-Cyrillic */ + +static unsigned short koi8_e_A0_BF[]= +{ 0x00A0, 0x0452, 0x0453, 0x0451, 0x0454, 0x0455, 0x0456, 0x0457, + 0x0458, 0x0459, 0x045A, 0x045B, 0x045C, 0x00AD, 0x045E, 0x045F, + 0x2116, 0x0402, 0x0403, 0x0401, 0x0404, 0x0405, 0x0406, 0x0407, + 0x0408, 0x0409, 0x040A, 0x040B, 0x040C, 0x00A4, 0x040E, 0x040F }; + +static unsigned +koi8_e_to_unicode(unsigned koicode, void *client_data) +{ + if(koicode<0xA0) + return koicode; + else if(koicode<0xC0) + return koi8_e_A0_BF[koicode-0xA0]; + else + return FontEncSimpleRecode(koicode, &koi8_r_to_unicode_map); +} + +static FontMapRec koi8_e[]= +{ + {FONT_ENCODING_UNICODE,0,0,koi8_e_to_unicode,0,0,0}, + {0,0,0,0,0,0,0} +}; + +/* Koi8 unified */ + +static unsigned short koi8_uni_80_BF[]= +{ 0x2500, 0x2502, 0x250C, 0x2510, 0x2514, 0x2518, 0x251C, 0x2524, + 0x252C, 0x2534, 0x253C, 0x2580, 0x2584, 0x2588, 0x258C, 0x2590, + 0x2591, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014, + 0x00A9, 0x2122, 0x00A0, 0x00BB, 0x00AE, 0x00AB, 0x00B7, 0x00A4, + 0x00A0, 0x0452, 0x0453, 0x0451, 0x0454, 0x0455, 0x0456, 0x0457, + 0x0458, 0x0459, 0x045A, 0x045B, 0x045C, 0x0491, 0x045E, 0x045F, + 0x2116, 0x0402, 0x0403, 0x0401, 0x0404, 0x0405, 0x0406, 0x0407, + 0x0408, 0x0409, 0x040A, 0x040B, 0x040C, 0x0490, 0x040E, 0x040F }; + +static unsigned +koi8_uni_to_unicode(unsigned koicode, void *client_data) +{ + if(koicode<0x80) + return koicode; + else if(koicode<0xC0) + return koi8_uni_80_BF[koicode-0x80]; + else + return FontEncSimpleRecode(koicode, &koi8_r_to_unicode_map); +} + +static FontMapRec koi8_uni[]= +{ + {FONT_ENCODING_UNICODE,0,0,koi8_uni_to_unicode,0,0,0}, + {0,0,0,0,0,0,0} +}; + +/* Ukrainian variant of Koi8-R; see RFC 2319 */ + +static unsigned +koi8_u_to_unicode(unsigned koicode, void *client_data) +{ + switch(koicode) { + case 0xA4: return 0x0454; + case 0xA6: return 0x0456; + case 0xA7: return 0x0457; + case 0xAD: return 0x0491; + case 0xB4: return 0x0404; + case 0xB6: return 0x0406; + case 0xB7: return 0x0407; + case 0xBD: return 0x0490; + default: return FontEncSimpleRecode(koicode, &koi8_r_to_unicode_map); + } +} + +static FontMapRec koi8_u[]= +{ + {FONT_ENCODING_UNICODE,0,0,koi8_u_to_unicode,0,0,0}, + {0,0,0,0,0,0,0} +}; + +/* Microsoft Symbol, which is only meaningful for TrueType fonts, is + treated specially in ftenc.c, where we add usFirstCharIndex-0x20 to + the glyph index before applying the cmap. Lovely design. */ + +static FontMapRec microsoft_symbol[]= +{{FONT_ENCODING_TRUETYPE,3,0,0,0,0,0}, + /* You never know */ + {FONT_ENCODING_TRUETYPE,3,1,0,0,0,0}, + {0,0,0,0,0,0,0}}; + +static FontMapRec apple_roman[]= +{{FONT_ENCODING_TRUETYPE,1,0,0,0,0,0}, {0,0,0,0,0,0,0}}; + +/* The data for recodings */ + +/* For compatibility with X11R6.4. Losers. */ +static char *iso8859_15_aliases[2]={"fcd8859-15",0}; + +static FontEncRec initial_encodings[]= +{ + {"iso10646-1",0,256*256,0,iso10646,0,0,0}, /* Unicode */ + {"iso8859-1",0,256,0,iso8859_1,0,0,0}, /* Latin 1 (West European) */ + {"iso8859-2",0,256,0,iso8859_2,0,0,0}, /* Latin 2 (East European) */ + {"iso8859-3",0,256,0,iso8859_3,0,0,0}, /* Latin 3 (South European) */ + {"iso8859-4",0,256,0,iso8859_4,0,0,0}, /* Latin 4 (North European) */ + {"iso8859-5",0,256,0,iso8859_5,0,0,0}, /* Cyrillic */ + {"iso8859-6",0,256,0,iso8859_6,0,0,0}, /* Arabic */ + {"iso8859-7",0,256,0,iso8859_7,0,0,0}, /* Greek */ + {"iso8859-8",0,256,0,iso8859_8,0,0,0}, /* Hebrew */ + {"iso8859-9",0,256,0,iso8859_9,0,0,0}, /* Latin 5 (Turkish) */ + {"iso8859-10",0,256,0,iso8859_10,0,0,0}, /* Latin 6 (Nordic) */ + {"iso8859-15",iso8859_15_aliases,256,0,iso8859_15,0,0,0}, /* Latin 9 */ + {"koi8-r",0,256,0,koi8_r,0,0,0}, /* Russian */ + {"koi8-ru",0,256,0,koi8_ru,0,0,0}, /* Ukrainian */ + {"koi8-uni",0,256,0,koi8_uni,0,0,0}, /* Russian/Ukrainian/Bielorussian */ + {"koi8-e",0,256,0,koi8_e,0,0,0}, /* ``European'' */ + {"koi8-u",0,256,0,koi8_u,0,0,0}, /* Ukrainian too */ + {"microsoft-symbol",0,256,0,microsoft_symbol,0,0,0}, + {"apple-roman",0,256,0,apple_roman,0,0,0}, + {0,0,0,0,0,0,0} +}; + +static FontEncPtr font_encodings=NULL; + +static void +define_initial_encoding_info(void) +{ + FontEncPtr encoding; + FontMapPtr mapping; + + font_encodings = initial_encodings; + for(encoding = font_encodings; ; encoding++) { + encoding->next = encoding + 1; + for(mapping = encoding->mappings; ; mapping++) { + mapping->next = mapping+1; + mapping->encoding = encoding; + if(mapping->next->type == 0) { + mapping->next = NULL; + break; + } + } + if(!encoding->next->name) { + encoding->next = NULL; + break; + } + } +} + + +char* +FontEncFromXLFD(const char *name, int length) +{ + const char *p; + char *q; + static char charset[MAXFONTNAMELEN]; + int len; + + if(length > MAXFONTNAMELEN - 1) + return 0; + + if(name == NULL) + p = NULL; + else { + p = name + length - 1; + while(p > name && *p != '-') + p--; + p--; + while(p >= name && *p != '-') + p--; + if(p <= name) + p = 0; + } + + /* now p either is null or points at the '-' before the charset registry */ + + if(p == 0) + return 0; + + len = length - (p - name) - 1; + memcpy(charset, p+1, len); + charset[len] = 0; + + /* check for a subset specification */ + if((q = strchr(charset, (int)'['))) + *q = 0; + + return charset; +} + +unsigned +FontEncRecode(unsigned code, FontMapPtr mapping) +{ + FontEncPtr encoding = mapping->encoding; + if(encoding && mapping->recode) { + if(encoding->row_size == 0) { + /* linear encoding */ + if(code < encoding->first || code>=encoding->size) + return 0; + } else { + /* matrix encoding */ + int row = code/0x100, col = code&0xFF; + if(row < encoding->first || row >= encoding->size || + col < encoding->first_col || col >= encoding->row_size) + return 0; + } + return (*mapping->recode)(code, mapping->client_data); + } else + return code; +} + +char* +FontEncName(unsigned code, FontMapPtr mapping) +{ + FontEncPtr encoding = mapping->encoding; + if(encoding && mapping->name) { + if((encoding->row_size == 0 && code >= encoding->size) || + (encoding->row_size != 0 && + (code/0x100 >= encoding->size || + (code&0xFF) >= encoding->row_size))) + return 0; + return (*mapping->name)(code, mapping->client_data); + } else + return 0; +} + +FontEncPtr +FontEncFind(const char *encoding_name, const char *filename) +{ + FontEncPtr encoding; + char **alias; + + if(font_encodings == NULL) define_initial_encoding_info(); + + for(encoding = font_encodings; encoding; encoding = encoding->next) { + if(!strcasecmp(encoding->name, encoding_name)) + return encoding; + if(encoding->aliases) + for(alias=encoding->aliases; *alias; alias++) + if(!strcasecmp(*alias, encoding_name)) + return encoding; + } + + /* Unknown charset, try to load a definition file */ + return FontEncLoad(encoding_name, filename); +} + +FontMapPtr +FontMapFind(FontEncPtr encoding, int type, int pid, int eid) +{ + FontMapPtr mapping; + if(encoding == NULL) + return NULL; + + for(mapping = encoding->mappings; mapping; mapping = mapping->next) { + if(mapping->type != type) + continue; + if(pid > 0 && mapping->pid != pid) + continue; + if(eid > 0 && mapping->eid != eid) + continue; + return mapping; + } + return NULL; +} + +FontMapPtr +FontEncMapFind(const char *encoding_name, int type, int pid, int eid, + const char *filename) +{ + FontEncPtr encoding; + FontMapPtr mapping; + + encoding = FontEncFind(encoding_name, filename); + if(encoding == NULL) + return NULL; + mapping = FontMapFind(encoding, type, pid, eid); + return mapping; +} + +static FontEncPtr +FontEncLoad(const char *encoding_name, const char *filename) +{ + FontEncPtr encoding; + + encoding = FontEncReallyLoad(encoding_name, filename); + if (encoding == NULL) { + return 0; + } else { + char **alias; + int found = 0; + + /* Check whether the name is already known for this encoding */ + if(strcasecmp(encoding->name, encoding_name) == 0) { + found = 1; + } else { + if(encoding->aliases) { + for(alias=encoding->aliases; *alias; alias++) + if(!strcasecmp(*alias, encoding_name)) { + found = 1; + break; + } + } + } + + if(!found) { + /* Add a new alias. This works because we know that this + particular encoding has been allocated dynamically */ + char **new_aliases; + char *new_name; + int numaliases = 0; + + new_name = xalloc(strlen(encoding_name) + 1); + if(new_name == NULL) + return NULL; + strcpy(new_name, encoding_name); + if(encoding->aliases) { + for(alias = encoding->aliases; *alias; alias++) + numaliases++; + } + new_aliases = (char**)xalloc((numaliases+2)*sizeof(char*)); + if(new_aliases == NULL) { + xfree(new_name); + return NULL; + } + if(encoding->aliases) { + memcpy(new_aliases, encoding->aliases, numaliases*sizeof(char*)); + xfree(encoding->aliases); + } + new_aliases[numaliases] = new_name; + new_aliases[numaliases+1] = NULL; + encoding->aliases = new_aliases; + } + + /* register the new encoding */ + encoding->next=font_encodings; + font_encodings=encoding; + + return encoding; + } +} + +unsigned +FontEncSimpleRecode(unsigned code, void *client_data) +{ + FontEncSimpleMapPtr map; + unsigned index; + + map = client_data; + + if(code > 0xFFFF || (map->row_size && (code&0xFF) >= map->row_size)) + return 0; + + if(map->row_size) + index = (code&0xFF)+(code>>8)*map->row_size; + else + index = code; + + if(map->map && index>=map->first && index<map->first+map->len) + return map->map[index-map->first]; + else + return code; +} + +char * +FontEncSimpleName(unsigned code, void *client_data) +{ + FontEncSimpleNamePtr map; + + map = client_data; + if(map && code >= map->first && code<map->first+map->len) + return map->map[code-map->first]; + else + return NULL; +} + +unsigned +FontEncUndefinedRecode(unsigned code, void *client_data) +{ + return code; +} + +char * +FontEncUndefinedName(unsigned code, void *client_data) +{ + return NULL; +} + +#define FONTENC_SEGMENT_SIZE 256 +#define FONTENC_SEGMENTS 256 +#define FONTENC_INVERSE_CODES (FONTENC_SEGMENT_SIZE * FONTENC_SEGMENTS) + +static unsigned int +reverse_reverse(unsigned i, void* data) +{ + int s, j; + unsigned **map = (unsigned**)data; + + if(i >= FONTENC_INVERSE_CODES) + return 0; + + if(map == NULL) + return 0; + + s = i / FONTENC_SEGMENT_SIZE; + j = i % FONTENC_SEGMENT_SIZE; + + if(map[s] == NULL) + return 0; + else + return map[s][j]; +} + +static int +tree_set(unsigned int **map, unsigned int i, unsigned int j) +{ + int s, c; + + if(i >= FONTENC_INVERSE_CODES) + return FALSE; + + s = i / FONTENC_SEGMENT_SIZE; + c = i % FONTENC_SEGMENT_SIZE; + + if(map[s] == NULL) { + map[s] = calloc(FONTENC_SEGMENT_SIZE, sizeof(int)); + if(map[s] == NULL) + return FALSE; + } + + map[s][c] = j; + return TRUE; +} + +FontMapReversePtr +FontMapReverse(FontMapPtr mapping) +{ + FontEncPtr encoding = mapping->encoding; + FontMapReversePtr reverse = NULL; + unsigned int **map = NULL; + int i, j, k; + + if(encoding == NULL) goto bail; + + map = calloc(FONTENC_SEGMENTS, sizeof(int*)); + if(map == NULL) goto bail; + + if(encoding->row_size == 0) { + for(i = encoding->first; i < encoding->size; i++) { + k = FontEncRecode(i, mapping); + if(k != 0) + if(!tree_set(map, k, i)) + goto bail; + } + } else { + for(i = encoding->first; i < encoding->size; i++) { + for(j = encoding->first_col; j < encoding->row_size; j++) { + k = FontEncRecode(i*256 + j, mapping); + if(k != 0) + if(!tree_set(map, k, i*256+j)) + goto bail; + } + } + } + + reverse = malloc(sizeof(FontMapReverseRec)); + if(!reverse) goto bail; + + reverse->reverse = reverse_reverse; + reverse->data = map; + return reverse; + + bail: + if(map) + xfree(map); + if(reverse) + xfree(reverse); + return NULL; +} + +void +FontMapReverseFree(FontMapReversePtr delendum) +{ + unsigned int **map = (unsigned int**)delendum; + int i; + + if(map == NULL) + return; + + for(i = 0; i < FONTENC_SEGMENTS; i++) + if(map[i] != NULL) + xfree(map[i]); + + xfree(map); + return; +} diff --git a/nx-X11/lib/font/fontfile/fontencI.h b/nx-X11/lib/font/fontfile/fontencI.h new file mode 100644 index 000000000..bd35a1fbb --- /dev/null +++ b/nx-X11/lib/font/fontfile/fontencI.h @@ -0,0 +1,46 @@ +/* +Copyright (c) 1998-2001 by Juliusz Chroboczek + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +/* $XFree86: xc/lib/font/fontfile/fontencI.h,v 1.3 1999/04/25 10:01:43 dawes Exp $ */ + +/* Private types and functions for the encoding code. */ +/* Used by the files `fontenc.h' and `encparse.h' */ + +typedef struct _FontEncSimpleMap { + unsigned len; /* might be 0x10000 */ + unsigned short row_size; + unsigned short first; + unsigned short *map; +} FontEncSimpleMapRec, *FontEncSimpleMapPtr; + +typedef struct _FontEncSimpleName { + unsigned len; + unsigned short first; + char **map; +} FontEncSimpleNameRec, *FontEncSimpleNamePtr; + +unsigned FontEncSimpleRecode(unsigned, void*); +unsigned FontEncUndefinedRecode(unsigned, void*); +char *FontEncSimpleName(unsigned, void*); +char *FontEncUndefinedName(unsigned, void*); + +FontEncPtr FontEncReallyLoad(const char*, const char*); diff --git a/nx-X11/lib/font/fontfile/fontencc.c b/nx-X11/lib/font/fontfile/fontencc.c new file mode 100644 index 000000000..b54079acf --- /dev/null +++ b/nx-X11/lib/font/fontfile/fontencc.c @@ -0,0 +1,77 @@ +/* +Copyright (c) 1998-2001 by Juliusz Chroboczek + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ +/* $XFree86: xc/lib/font/fontfile/fontencc.c,v 1.1 2001/08/13 21:46:47 dawes Exp $ */ + +/* Binary compatibility code. */ + +/* This file includes code to make modules compiled for earlier + versions of the fontenc interfaces link with this one. It does + *not* provide source compatibility, as many of the data structures + now have different names. */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <X11/fonts/fontenc.h> +#include <X11/fonts/fontencc.h> + +extern void ErrorF(const char *f, ...); + +char * +font_encoding_from_xlfd(const char * name, int length) +{ + return FontEncFromXLFD(name, length); +} + +FontEncPtr +font_encoding_find(const char *encoding_name, const char *filename) +{ + return FontEncFind(encoding_name, filename); +} + +unsigned +font_encoding_recode(unsigned code, + FontEncPtr encoding, FontMapPtr mapping) +{ + if(encoding != mapping->encoding) { + ErrorF("Inconsistent mapping/encoding\n"); + return 0; + } + return FontEncRecode(code, mapping); +} + +char * +font_encoding_name(unsigned code, + FontEncPtr encoding, FontMapPtr mapping) +{ + if(encoding != mapping->encoding) { + ErrorF("Inconsistent mapping/encoding\n"); + return 0; + } + return FontEncName(code, mapping); +} + +char ** +identifyEncodingFile(const char *filename) +{ + return FontEncIdentify(filename); +} diff --git a/nx-X11/lib/font/fontfile/fontfile.c b/nx-X11/lib/font/fontfile/fontfile.c new file mode 100644 index 000000000..2356c0595 --- /dev/null +++ b/nx-X11/lib/font/fontfile/fontfile.c @@ -0,0 +1,1147 @@ +/* $XdotOrg: xc/lib/font/fontfile/fontfile.c,v 1.5 2005/07/09 06:36:13 keithp Exp $ */ +/* $Xorg: fontfile.c,v 1.4 2001/02/09 02:04:03 xorgcvs Exp $ */ + +/* + +Copyright 1991, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ +/* $XFree86: xc/lib/font/fontfile/fontfile.c,v 3.21 2003/12/02 19:50:40 dawes Exp $ */ + +/* + * Author: Keith Packard, MIT X Consortium + */ +/* $NCDXorg: @(#)fontfile.c,v 1.6 1991/07/02 17:00:46 lemke Exp $ */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <X11/fonts/fntfilst.h> +#ifdef WIN32 +#include <ctype.h> +#endif + +/* + * Map FPE functions to renderer functions + */ + +static int FontFileOpenBitmapNCF (FontPathElementPtr fpe, FontPtr *pFont, + int flags, FontEntryPtr entry, + fsBitmapFormat format, + fsBitmapFormatMask fmask, + FontPtr non_cachable_font); + +int +FontFileNameCheck (char *name) +{ +#ifndef NCD +#if defined(__UNIXOS2__) || defined(WIN32) + /* OS/2 uses D:/... as a path name for fonts, so accept this as a valid + * path if it starts with a letter and a colon. Same applies for WIN32 + */ + if (isalpha(*name) && name[1]==':') + return TRUE; +#endif + return *name == '/'; +#else + return ((strcmp(name, "built-ins") == 0) || (*name == '/')); +#endif +} + +int +FontFileInitFPE (FontPathElementPtr fpe) +{ + int status; + FontDirectoryPtr dir; + + status = FontFileReadDirectory (fpe->name, &dir); + if (status == Successful) + { + if (dir->nonScalable.used > 0) + if (!FontFileRegisterBitmapSource (fpe)) + { + FontFileFreeFPE (fpe); + return AllocError; + } + fpe->private = (pointer) dir; + } + return status; +} + +/* ARGSUSED */ +int +FontFileResetFPE (FontPathElementPtr fpe) +{ + FontDirectoryPtr dir; + + dir = (FontDirectoryPtr) fpe->private; + /* + * The reset must fail for bitmap fonts because they get cleared when + * the path is set. + */ + if (FontFileDirectoryChanged (dir)) + { + /* can't do it, so tell the caller to close and re-open */ + return FPEResetFailed; + } + else + { + if (dir->nonScalable.used > 0) + if (!FontFileRegisterBitmapSource (fpe)) + { + return FPEResetFailed; + } + return Successful; + } +} + +int +FontFileFreeFPE (FontPathElementPtr fpe) +{ + FontFileUnregisterBitmapSource (fpe); + FontFileFreeDir ((FontDirectoryPtr) fpe->private); + return Successful; +} + +static int +transfer_values_to_alias(char *entryname, int entrynamelength, + char *resolvedname, + char **aliasName, FontScalablePtr vals) +{ + static char aliasname[MAXFONTNAMELEN]; + int nameok = 1, len; + char lowerName[MAXFONTNAMELEN]; + + *aliasName = resolvedname; + if ((len = strlen(*aliasName)) <= MAXFONTNAMELEN && + (entrynamelength < MAXFONTNAMELEN) && + FontFileCountDashes (*aliasName, len) == 14) + { + FontScalableRec tmpVals; + FontScalableRec tmpVals2; + + tmpVals2 = *vals; + + /* If we're aliasing a scalable name, transfer values + from the name into the destination alias, multiplying + by matrices that appear in the alias. */ + + CopyISOLatin1Lowered (lowerName, entryname, + entrynamelength); + lowerName[entrynamelength] = '\0'; + + if (FontParseXLFDName(lowerName, &tmpVals, + FONT_XLFD_REPLACE_NONE) && + !tmpVals.values_supplied && + FontParseXLFDName(*aliasName, &tmpVals, + FONT_XLFD_REPLACE_NONE)) + { + double *matrix = 0, tempmatrix[4]; + + /* Use a matrix iff exactly one is defined */ + if ((tmpVals.values_supplied & PIXELSIZE_MASK) == + PIXELSIZE_ARRAY && + !(tmpVals.values_supplied & POINTSIZE_MASK)) + matrix = tmpVals.pixel_matrix; + else if ((tmpVals.values_supplied & POINTSIZE_MASK) == + POINTSIZE_ARRAY && + !(tmpVals.values_supplied & PIXELSIZE_MASK)) + matrix = tmpVals.point_matrix; + + /* If matrix given in the alias, compute new point + and/or pixel matrices */ + if (matrix) + { + /* Complete the XLFD name to avoid potential + gotchas */ + if (FontFileCompleteXLFD(&tmpVals2, &tmpVals2)) + { + tempmatrix[0] = + matrix[0] * tmpVals2.point_matrix[0] + + matrix[1] * tmpVals2.point_matrix[2]; + tempmatrix[1] = + matrix[0] * tmpVals2.point_matrix[1] + + matrix[1] * tmpVals2.point_matrix[3]; + tempmatrix[2] = + matrix[2] * tmpVals2.point_matrix[0] + + matrix[3] * tmpVals2.point_matrix[2]; + tempmatrix[3] = + matrix[2] * tmpVals2.point_matrix[1] + + matrix[3] * tmpVals2.point_matrix[3]; + tmpVals2.point_matrix[0] = tempmatrix[0]; + tmpVals2.point_matrix[1] = tempmatrix[1]; + tmpVals2.point_matrix[2] = tempmatrix[2]; + tmpVals2.point_matrix[3] = tempmatrix[3]; + + tempmatrix[0] = + matrix[0] * tmpVals2.pixel_matrix[0] + + matrix[1] * tmpVals2.pixel_matrix[2]; + tempmatrix[1] = + matrix[0] * tmpVals2.pixel_matrix[1] + + matrix[1] * tmpVals2.pixel_matrix[3]; + tempmatrix[2] = + matrix[2] * tmpVals2.pixel_matrix[0] + + matrix[3] * tmpVals2.pixel_matrix[2]; + tempmatrix[3] = + matrix[2] * tmpVals2.pixel_matrix[1] + + matrix[3] * tmpVals2.pixel_matrix[3]; + tmpVals2.pixel_matrix[0] = tempmatrix[0]; + tmpVals2.pixel_matrix[1] = tempmatrix[1]; + tmpVals2.pixel_matrix[2] = tempmatrix[2]; + tmpVals2.pixel_matrix[3] = tempmatrix[3]; + + tmpVals2.values_supplied = + (tmpVals2.values_supplied & + ~(PIXELSIZE_MASK | POINTSIZE_MASK)) | + PIXELSIZE_ARRAY | POINTSIZE_ARRAY; + } + else + nameok = 0; + } + + CopyISOLatin1Lowered (aliasname, *aliasName, len + 1); + if (nameok && FontParseXLFDName(aliasname, &tmpVals2, + FONT_XLFD_REPLACE_VALUE)) + /* Return a version of the aliasname that has + had the vals stuffed into it. To avoid + memory leak, this alias name lives in a + static buffer. The caller needs to be done + with this buffer before this procedure is + called again to avoid reentrancy problems. */ + *aliasName = aliasname; + } + } + return nameok; +} + +/* ARGSUSED */ +int +FontFileOpenFont (pointer client, FontPathElementPtr fpe, Mask flags, + char *name, int namelen, + fsBitmapFormat format, fsBitmapFormatMask fmask, + XID id, FontPtr *pFont, char **aliasName, + FontPtr non_cachable_font) +{ + FontDirectoryPtr dir; + char lowerName[MAXFONTNAMELEN]; + char fileName[MAXFONTFILENAMELEN*2 + 1]; + FontNameRec tmpName; + FontEntryPtr entry; + FontScalableRec vals; + FontScalableEntryPtr scalable; + FontScaledPtr scaled; + FontBitmapEntryPtr bitmap; + int ret; + Bool noSpecificSize; + int nranges; + fsRange *ranges; + + if (namelen >= MAXFONTNAMELEN) + return AllocError; + dir = (FontDirectoryPtr) fpe->private; + + /* Match non-scalable pattern */ + CopyISOLatin1Lowered (lowerName, name, namelen); + lowerName[namelen] = '\0'; + ranges = FontParseRanges(lowerName, &nranges); + tmpName.name = lowerName; + tmpName.length = namelen; + tmpName.ndashes = FontFileCountDashes (lowerName, namelen); + if (!FontParseXLFDName(lowerName, &vals, FONT_XLFD_REPLACE_NONE)) + bzero(&vals, sizeof(vals)); + if (!(entry = FontFileFindNameInDir (&dir->nonScalable, &tmpName)) && + tmpName.ndashes == 14 && + FontParseXLFDName (lowerName, &vals, FONT_XLFD_REPLACE_ZERO)) + { + tmpName.length = strlen(lowerName); + entry = FontFileFindNameInDir (&dir->nonScalable, &tmpName); + } + + if (entry) + { + switch (entry->type) { + case FONT_ENTRY_BITMAP: + bitmap = &entry->u.bitmap; + if (bitmap->pFont) + { + *pFont = bitmap->pFont; + (*pFont)->fpe = fpe; + ret = Successful; + } + else + { + ret = FontFileOpenBitmapNCF (fpe, pFont, flags, entry, format, + fmask, non_cachable_font); + if (ret == Successful && *pFont) + (*pFont)->fpe = fpe; + } + break; + case FONT_ENTRY_ALIAS: + vals.nranges = nranges; + vals.ranges = ranges; + transfer_values_to_alias(entry->name.name, entry->name.length, + entry->u.alias.resolved, aliasName, &vals); + ret = FontNameAlias; + break; +#ifdef NOTYET + case FONT_ENTRY_BC: + bc = &entry->u.bc; + entry = bc->entry; + ret = (*scalable->renderer->OpenScalable) + (fpe, pFont, flags, entry, &bc->vals, format, fmask, + non_cachable_font); + if (ret == Successful && *pFont) + (*pFont)->fpe = fpe; + break; +#endif + default: + ret = BadFontName; + } + } + else + { + ret = BadFontName; + } + + if (ret != BadFontName) + { + if (ranges) xfree(ranges); + return ret; + } + + /* Match XLFD patterns */ + CopyISOLatin1Lowered (lowerName, name, namelen); + lowerName[namelen] = '\0'; + tmpName.name = lowerName; + tmpName.length = namelen; + tmpName.ndashes = FontFileCountDashes (lowerName, namelen); + if (!FontParseXLFDName (lowerName, &vals, FONT_XLFD_REPLACE_ZERO) || + !(tmpName.length = strlen (lowerName), + entry = FontFileFindNameInScalableDir (&dir->scalable, &tmpName, + &vals))) { + CopyISOLatin1Lowered (lowerName, name, namelen); + lowerName[namelen] = '\0'; + tmpName.name = lowerName; + tmpName.length = namelen; + tmpName.ndashes = FontFileCountDashes (lowerName, namelen); + entry = FontFileFindNameInScalableDir (&dir->scalable, &tmpName, &vals); + if (entry) + { + strcpy(lowerName, entry->name.name); + tmpName.name = lowerName; + tmpName.length = entry->name.length; + tmpName.ndashes = entry->name.ndashes; + } + } + if (entry) + { + noSpecificSize = FALSE; /* TRUE breaks XLFD enhancements */ + if (entry->type == FONT_ENTRY_SCALABLE && + FontFileCompleteXLFD (&vals, &entry->u.scalable.extra->defaults)) + { + scalable = &entry->u.scalable; + if ((vals.values_supplied & PIXELSIZE_MASK) == PIXELSIZE_ARRAY || + (vals.values_supplied & POINTSIZE_MASK) == POINTSIZE_ARRAY || + (vals.values_supplied & + ~SIZE_SPECIFY_MASK & ~CHARSUBSET_SPECIFIED)) + scaled = 0; + else + scaled = FontFileFindScaledInstance (entry, &vals, + noSpecificSize); + /* + * A scaled instance can occur one of two ways: + * + * Either the font has been scaled to this + * size already, in which case scaled->pFont + * will point at that font. + * + * Or a bitmap instance in this size exists, + * which is handled as if we got a pattern + * matching the bitmap font name. + */ + if (scaled) + { + if (scaled->pFont) + { + *pFont = scaled->pFont; + (*pFont)->fpe = fpe; + ret = Successful; + } + else if (scaled->bitmap) + { + entry = scaled->bitmap; + bitmap = &entry->u.bitmap; + if (bitmap->pFont) + { + *pFont = bitmap->pFont; + (*pFont)->fpe = fpe; + ret = Successful; + } + else + { + ret = FontFileOpenBitmapNCF (fpe, pFont, flags, entry, + format, fmask, + non_cachable_font); + if (ret == Successful && *pFont) + (*pFont)->fpe = fpe; + } + } + else /* "cannot" happen */ + { + ret = BadFontName; + } + } + else + { + ret = FontFileMatchBitmapSource (fpe, pFont, flags, entry, &tmpName, &vals, format, fmask, noSpecificSize); + if (ret != Successful) + { + char origName[MAXFONTNAMELEN]; + + CopyISOLatin1Lowered (origName, name, namelen); + origName[namelen] = '\0'; + + /* Pass the original XLFD name in the vals + structure; the rasterizer is free to examine it + for hidden meanings. This information will not + be saved in the scaled-instances table. */ + + vals.xlfdName = origName; + vals.ranges = ranges; + vals.nranges = nranges; + + if (strlen(dir->directory) + strlen(scalable->fileName) >= + sizeof(fileName)) { + ret = BadFontName; + } else { + strcpy (fileName, dir->directory); + strcat (fileName, scalable->fileName); + ret = (*scalable->renderer->OpenScalable) (fpe, pFont, + flags, entry, fileName, &vals, format, fmask, + non_cachable_font); + } + + /* In case rasterizer does something bad because of + charset subsetting... */ + if (ret == Successful && + ((*pFont)->info.firstCol > (*pFont)->info.lastCol || + (*pFont)->info.firstRow > (*pFont)->info.lastRow)) + { + (*(*pFont)->unload_font)(*pFont); + ret = BadFontName; + } + /* Save the instance */ + if (ret == Successful) + { + if (FontFileAddScaledInstance (entry, &vals, + *pFont, (char *) 0)) + ranges = 0; + else + (*pFont)->fpePrivate = (pointer) 0; + (*pFont)->fpe = fpe; + } + } + } + } + } + else + ret = BadFontName; + + if (ranges) + xfree(ranges); + return ret; +} + +/* ARGSUSED */ +void +FontFileCloseFont (FontPathElementPtr fpe, FontPtr pFont) +{ + FontEntryPtr entry; + + if ((entry = (FontEntryPtr) pFont->fpePrivate)) { + switch (entry->type) { + case FONT_ENTRY_SCALABLE: + FontFileRemoveScaledInstance (entry, pFont); + break; + case FONT_ENTRY_BITMAP: + entry->u.bitmap.pFont = 0; + break; + default: + /* "cannot" happen */ + break; + } + pFont->fpePrivate = 0; + } + (*pFont->unload_font) (pFont); +} + +static int +FontFileOpenBitmapNCF (FontPathElementPtr fpe, FontPtr *pFont, + int flags, FontEntryPtr entry, + fsBitmapFormat format, fsBitmapFormatMask fmask, + FontPtr non_cachable_font) +{ + FontBitmapEntryPtr bitmap; + char fileName[MAXFONTFILENAMELEN*2+1]; + int ret; + FontDirectoryPtr dir; + + dir = (FontDirectoryPtr) fpe->private; + bitmap = &entry->u.bitmap; + if(!bitmap || !bitmap->renderer->OpenBitmap) + return BadFontName; + if (strlen(dir->directory) + strlen(bitmap->fileName) >= sizeof(fileName)) + return BadFontName; + strcpy (fileName, dir->directory); + strcat (fileName, bitmap->fileName); + ret = (*bitmap->renderer->OpenBitmap) + (fpe, pFont, flags, entry, fileName, format, fmask, + non_cachable_font); + if (ret == Successful) + { + bitmap->pFont = *pFont; + (*pFont)->fpePrivate = (pointer) entry; + } + return ret; +} + +int +FontFileOpenBitmap (FontPathElementPtr fpe, FontPtr *pFont, + int flags, FontEntryPtr entry, + fsBitmapFormat format, fsBitmapFormatMask fmask) +{ + return FontFileOpenBitmapNCF (fpe, pFont, flags, entry, format, fmask, + (FontPtr)0); +} + +static int +FontFileGetInfoBitmap (FontPathElementPtr fpe, FontInfoPtr pFontInfo, + FontEntryPtr entry) +{ + FontBitmapEntryPtr bitmap; + char fileName[MAXFONTFILENAMELEN*2+1]; + int ret; + FontDirectoryPtr dir; + + dir = (FontDirectoryPtr) fpe->private; + bitmap = &entry->u.bitmap; + if (!bitmap || !bitmap->renderer->GetInfoBitmap) + return BadFontName; + if (strlen(dir->directory) + strlen(bitmap->fileName) >= sizeof(fileName)) + return BadFontName; + strcpy (fileName, dir->directory); + strcat (fileName, bitmap->fileName); + ret = (*bitmap->renderer->GetInfoBitmap) (fpe, pFontInfo, entry, fileName); + return ret; +} + +static void +_FontFileAddScalableNames(FontNamesPtr names, FontNamesPtr scaleNames, + FontNamePtr nameptr, char *zeroChars, + FontScalablePtr vals, fsRange *ranges, + int nranges, int *max) +{ + int i; + FontScalableRec zeroVals, tmpVals; + for (i = 0; i < scaleNames->nnames; i++) + { + char nameChars[MAXFONTNAMELEN]; + if (!*max) + return; + FontParseXLFDName (scaleNames->names[i], &zeroVals, + FONT_XLFD_REPLACE_NONE); + tmpVals = *vals; + if (FontFileCompleteXLFD (&tmpVals, &zeroVals)) + { + --*max; + + strcpy (nameChars, scaleNames->names[i]); + if ((vals->values_supplied & PIXELSIZE_MASK) || + !(vals->values_supplied & PIXELSIZE_WILDCARD) || + vals->y == 0) + { + tmpVals.values_supplied = + (tmpVals.values_supplied & ~PIXELSIZE_MASK) | + (vals->values_supplied & PIXELSIZE_MASK); + tmpVals.pixel_matrix[0] = vals->pixel_matrix[0]; + tmpVals.pixel_matrix[1] = vals->pixel_matrix[1]; + tmpVals.pixel_matrix[2] = vals->pixel_matrix[2]; + tmpVals.pixel_matrix[3] = vals->pixel_matrix[3]; + } + if ((vals->values_supplied & POINTSIZE_MASK) || + !(vals->values_supplied & POINTSIZE_WILDCARD) || + vals->y == 0) + { + tmpVals.values_supplied = + (tmpVals.values_supplied & ~POINTSIZE_MASK) | + (vals->values_supplied & POINTSIZE_MASK); + tmpVals.point_matrix[0] = vals->point_matrix[0]; + tmpVals.point_matrix[1] = vals->point_matrix[1]; + tmpVals.point_matrix[2] = vals->point_matrix[2]; + tmpVals.point_matrix[3] = vals->point_matrix[3]; + } + if (vals->width <= 0) + tmpVals.width = 0; + if (vals->x == 0) + tmpVals.x = 0; + if (vals->y == 0) + tmpVals.y = 0; + tmpVals.ranges = ranges; + tmpVals.nranges = nranges; + FontParseXLFDName (nameChars, &tmpVals, + FONT_XLFD_REPLACE_VALUE); + /* If we're marking aliases with negative lengths, we + need to concoct a valid target name to follow it. + Otherwise we're done. */ + if (scaleNames->length[i] >= 0) + { + (void) AddFontNamesName (names, nameChars, + strlen (nameChars)); + /* If our original pattern matches the name from + the table and that name doesn't duplicate what + we just added, add the name from the table */ + if (strcmp(nameChars, scaleNames->names[i]) && + FontFileMatchName(scaleNames->names[i], + scaleNames->length[i], + nameptr) && + *max) + { + --*max; + (void) AddFontNamesName (names, scaleNames->names[i], + scaleNames->length[i]); + } + } + else + { + char *aliasName; + vals->ranges = ranges; + vals->nranges = nranges; + if (transfer_values_to_alias(zeroChars, + strlen(zeroChars), + scaleNames->names[++i], + &aliasName, vals)) + { + (void) AddFontNamesName (names, nameChars, + strlen (nameChars)); + names->length[names->nnames - 1] = + -names->length[names->nnames - 1]; + (void) AddFontNamesName (names, aliasName, + strlen (aliasName)); + /* If our original pattern matches the name from + the table and that name doesn't duplicate what + we just added, add the name from the table */ + if (strcmp(nameChars, scaleNames->names[i - 1]) && + FontFileMatchName(scaleNames->names[i - 1], + -scaleNames->length[i - 1], + nameptr) && + *max) + { + --*max; + (void) AddFontNamesName (names, + scaleNames->names[i - 1], + -scaleNames->length[i - 1]); + names->length[names->nnames - 1] = + -names->length[names->nnames - 1]; + (void) AddFontNamesName (names, aliasName, + strlen (aliasName)); + } + } + } + } + } +} + +/* ARGSUSED */ +static int +_FontFileListFonts (pointer client, FontPathElementPtr fpe, + char *pat, int len, int max, FontNamesPtr names, + int mark_aliases) +{ + FontDirectoryPtr dir; + char lowerChars[MAXFONTNAMELEN], zeroChars[MAXFONTNAMELEN]; + FontNameRec lowerName; + FontNameRec zeroName; + FontNamesPtr scaleNames; + FontScalableRec vals; + fsRange *ranges; + int nranges; + int result = BadFontName; + + if (len >= MAXFONTNAMELEN) + return AllocError; + dir = (FontDirectoryPtr) fpe->private; + CopyISOLatin1Lowered (lowerChars, pat, len); + lowerChars[len] = '\0'; + lowerName.name = lowerChars; + lowerName.length = len; + lowerName.ndashes = FontFileCountDashes (lowerChars, len); + + /* Match XLFD patterns */ + + strcpy (zeroChars, lowerChars); + if (lowerName.ndashes == 14 && + FontParseXLFDName (zeroChars, &vals, FONT_XLFD_REPLACE_ZERO)) + { + ranges = FontParseRanges(lowerChars, &nranges); + result = FontFileFindNamesInScalableDir (&dir->nonScalable, + &lowerName, max, names, + (FontScalablePtr)0, + (mark_aliases ? + LIST_ALIASES_AND_TARGET_NAMES : + NORMAL_ALIAS_BEHAVIOR) | + IGNORE_SCALABLE_ALIASES, + &max); + zeroName.name = zeroChars; + zeroName.length = strlen (zeroChars); + zeroName.ndashes = lowerName.ndashes; + + /* Look for scalable names and aliases, adding scaled instances of + them to the output */ + + /* Scalable names... */ + scaleNames = MakeFontNamesRecord (0); + if (!scaleNames) + { + if (ranges) xfree(ranges); + return AllocError; + } + FontFileFindNamesInScalableDir (&dir->scalable, &zeroName, max, + scaleNames, &vals, + mark_aliases ? + LIST_ALIASES_AND_TARGET_NAMES : + NORMAL_ALIAS_BEHAVIOR, (int *)0); + _FontFileAddScalableNames(names, scaleNames, &lowerName, + zeroChars, &vals, ranges, nranges, + &max); + FreeFontNames (scaleNames); + + /* Scalable aliases... */ + scaleNames = MakeFontNamesRecord (0); + if (!scaleNames) + { + if (ranges) xfree(ranges); + return AllocError; + } + FontFileFindNamesInScalableDir (&dir->nonScalable, &zeroName, + max, scaleNames, &vals, + mark_aliases ? + LIST_ALIASES_AND_TARGET_NAMES : + NORMAL_ALIAS_BEHAVIOR, (int *)0); + _FontFileAddScalableNames(names, scaleNames, &lowerName, + zeroChars, &vals, ranges, nranges, + &max); + FreeFontNames (scaleNames); + + if (ranges) xfree(ranges); + } + else + { + result = FontFileFindNamesInScalableDir (&dir->nonScalable, + &lowerName, max, names, + (FontScalablePtr)0, + mark_aliases ? + LIST_ALIASES_AND_TARGET_NAMES : + NORMAL_ALIAS_BEHAVIOR, + &max); + if (result == Successful) + result = FontFileFindNamesInScalableDir (&dir->scalable, + &lowerName, max, names, + (FontScalablePtr)0, + mark_aliases ? + LIST_ALIASES_AND_TARGET_NAMES : + NORMAL_ALIAS_BEHAVIOR, (int *)0); + } + return result; +} + +typedef struct _LFWIData { + FontNamesPtr names; + int current; +} LFWIDataRec, *LFWIDataPtr; + +int +FontFileListFonts (pointer client, FontPathElementPtr fpe, char *pat, + int len, int max, FontNamesPtr names) +{ + return _FontFileListFonts (client, fpe, pat, len, max, names, 0); +} + +int +FontFileStartListFontsWithInfo(pointer client, FontPathElementPtr fpe, + char *pat, int len, int max, + pointer *privatep) +{ + LFWIDataPtr data; + int ret; + + data = (LFWIDataPtr) xalloc (sizeof *data); + if (!data) + return AllocError; + data->names = MakeFontNamesRecord (0); + if (!data->names) + { + xfree (data); + return AllocError; + } + ret = FontFileListFonts (client, fpe, pat, len, max, data->names); + if (ret != Successful) + { + FreeFontNames (data->names); + xfree (data); + return ret; + } + data->current = 0; + *privatep = (pointer) data; + return Successful; +} + +/* ARGSUSED */ +static int +FontFileListOneFontWithInfo (pointer client, FontPathElementPtr fpe, + char **namep, int *namelenp, + FontInfoPtr *pFontInfo) +{ + FontDirectoryPtr dir; + char lowerName[MAXFONTNAMELEN]; + char fileName[MAXFONTFILENAMELEN*2 + 1]; + FontNameRec tmpName; + FontEntryPtr entry; + FontScalableRec vals; + FontScalableEntryPtr scalable; + FontScaledPtr scaled; + FontBitmapEntryPtr bitmap; + int ret; + Bool noSpecificSize; + int nranges; + fsRange *ranges; + + char *name = *namep; + int namelen = *namelenp; + + if (namelen >= MAXFONTNAMELEN) + return AllocError; + dir = (FontDirectoryPtr) fpe->private; + + /* Match non-scalable pattern */ + CopyISOLatin1Lowered (lowerName, name, namelen); + lowerName[namelen] = '\0'; + ranges = FontParseRanges(lowerName, &nranges); + tmpName.name = lowerName; + tmpName.length = namelen; + tmpName.ndashes = FontFileCountDashes (lowerName, namelen); + if (!FontParseXLFDName(lowerName, &vals, FONT_XLFD_REPLACE_NONE)) + bzero(&vals, sizeof(vals)); + if (!(entry = FontFileFindNameInDir (&dir->nonScalable, &tmpName)) && + tmpName.ndashes == 14 && + FontParseXLFDName (lowerName, &vals, FONT_XLFD_REPLACE_ZERO)) + { + tmpName.length = strlen(lowerName); + entry = FontFileFindNameInDir (&dir->nonScalable, &tmpName); + } + + if (entry) + { + switch (entry->type) { + case FONT_ENTRY_BITMAP: + bitmap = &entry->u.bitmap; + if (bitmap->pFont) + { + *pFontInfo = &bitmap->pFont->info; + ret = Successful; + } + else + { + ret = FontFileGetInfoBitmap (fpe, *pFontInfo, entry); + } + break; + case FONT_ENTRY_ALIAS: + vals.nranges = nranges; + vals.ranges = ranges; + transfer_values_to_alias(entry->name.name, entry->name.length, + entry->u.alias.resolved, namep, &vals); + *namelenp = strlen (*namep); + ret = FontNameAlias; + break; +#ifdef NOTYET + case FONT_ENTRY_BC: + /* no LFWI for this yet */ + bc = &entry->u.bc; + entry = bc->entry; + /* Make a new scaled instance */ + if (strlen(dir->directory) + strlen(scalable->fileName) >= + sizeof(fileName)) { + ret = BadFontName; + } else { + strcpy (fileName, dir->directory); + strcat (fileName, scalable->fileName); + ret = (*scalable->renderer->GetInfoScalable) + (fpe, *pFontInfo, entry, tmpName, fileName, &bc->vals); + } + break; +#endif + default: + ret = BadFontName; + } + } + else + { + ret = BadFontName; + } + + if (ret != BadFontName) + { + if (ranges) xfree(ranges); + return ret; + } + + /* Match XLFD patterns */ + CopyISOLatin1Lowered (lowerName, name, namelen); + lowerName[namelen] = '\0'; + tmpName.name = lowerName; + tmpName.length = namelen; + tmpName.ndashes = FontFileCountDashes (lowerName, namelen); + if (!FontParseXLFDName (lowerName, &vals, FONT_XLFD_REPLACE_ZERO) || + !(tmpName.length = strlen (lowerName), + entry = FontFileFindNameInScalableDir (&dir->scalable, &tmpName, + &vals))) { + CopyISOLatin1Lowered (lowerName, name, namelen); + lowerName[namelen] = '\0'; + tmpName.name = lowerName; + tmpName.length = namelen; + tmpName.ndashes = FontFileCountDashes (lowerName, namelen); + entry = FontFileFindNameInScalableDir (&dir->scalable, &tmpName, &vals); + if (entry) + { + strcpy(lowerName, entry->name.name); + tmpName.name = lowerName; + tmpName.length = entry->name.length; + tmpName.ndashes = entry->name.ndashes; + } + } + + if (entry) + { + noSpecificSize = FALSE; /* TRUE breaks XLFD enhancements */ + if (entry && entry->type == FONT_ENTRY_SCALABLE && + FontFileCompleteXLFD (&vals, &entry->u.scalable.extra->defaults)) + { + scalable = &entry->u.scalable; + scaled = FontFileFindScaledInstance (entry, &vals, noSpecificSize); + /* + * A scaled instance can occur one of two ways: + * + * Either the font has been scaled to this + * size already, in which case scaled->pFont + * will point at that font. + * + * Or a bitmap instance in this size exists, + * which is handled as if we got a pattern + * matching the bitmap font name. + */ + if (scaled) + { + if (scaled->pFont) + { + *pFontInfo = &scaled->pFont->info; + ret = Successful; + } + else if (scaled->bitmap) + { + entry = scaled->bitmap; + bitmap = &entry->u.bitmap; + if (bitmap->pFont) + { + *pFontInfo = &bitmap->pFont->info; + ret = Successful; + } + else + { + ret = FontFileGetInfoBitmap (fpe, *pFontInfo, entry); + } + } + else /* "cannot" happen */ + { + ret = BadFontName; + } + } + else + { +#ifdef NOTDEF + /* no special case yet */ + ret = FontFileMatchBitmapSource (fpe, pFont, flags, entry, &vals, format, fmask, noSpecificSize); + if (ret != Successful) +#endif + { + char origName[MAXFONTNAMELEN]; + + CopyISOLatin1Lowered (origName, name, namelen); + origName[namelen] = '\0'; + vals.xlfdName = origName; + vals.ranges = ranges; + vals.nranges = nranges; + + /* Make a new scaled instance */ + if (strlen(dir->directory) + strlen(scalable->fileName) >= + sizeof(fileName)) { + ret = BadFontName; + } else { + strcpy (fileName, dir->directory); + strcat (fileName, scalable->fileName); + ret = (*scalable->renderer->GetInfoScalable) + (fpe, *pFontInfo, entry, &tmpName, fileName, &vals); + } + if (ranges) xfree(ranges); + } + } + if (ret == Successful) return ret; + } + CopyISOLatin1Lowered (lowerName, name, namelen); + tmpName.length = namelen; + } + else + ret = BadFontName; + + if (ranges) + xfree(ranges); + return ret; +} + +int +FontFileListNextFontWithInfo(pointer client, FontPathElementPtr fpe, + char **namep, int *namelenp, + FontInfoPtr *pFontInfo, + int *numFonts, pointer private) +{ + LFWIDataPtr data = (LFWIDataPtr) private; + int ret; + char *name; + int namelen; + + if (data->current == data->names->nnames) + { + FreeFontNames (data->names); + xfree (data); + return BadFontName; + } + name = data->names->names[data->current]; + namelen = data->names->length[data->current]; + ret = FontFileListOneFontWithInfo (client, fpe, &name, &namelen, pFontInfo); + if (ret == BadFontName) + ret = AllocError; + *namep = name; + *namelenp = namelen; + ++data->current; + *numFonts = data->names->nnames - data->current; + return ret; +} + +int +FontFileStartListFontsAndAliases(pointer client, FontPathElementPtr fpe, + char *pat, int len, int max, + pointer *privatep) +{ + LFWIDataPtr data; + int ret; + + data = (LFWIDataPtr) xalloc (sizeof *data); + if (!data) + return AllocError; + data->names = MakeFontNamesRecord (0); + if (!data->names) + { + xfree (data); + return AllocError; + } + ret = _FontFileListFonts (client, fpe, pat, len, max, data->names, 1); + if (ret != Successful) + { + FreeFontNames (data->names); + xfree (data); + return ret; + } + data->current = 0; + *privatep = (pointer) data; + return Successful; +} + +int +FontFileListNextFontOrAlias(pointer client, FontPathElementPtr fpe, + char **namep, int *namelenp, char **resolvedp, + int *resolvedlenp, pointer private) +{ + LFWIDataPtr data = (LFWIDataPtr) private; + int ret; + char *name; + int namelen; + + if (data->current == data->names->nnames) + { + FreeFontNames (data->names); + xfree (data); + return BadFontName; + } + name = data->names->names[data->current]; + namelen = data->names->length[data->current]; + + /* If this is a real font name... */ + if (namelen >= 0) + { + *namep = name; + *namelenp = namelen; + ret = Successful; + } + /* Else if an alias */ + else + { + /* Tell the caller that this is an alias... let him resolve it to + see if it's valid */ + *namep = name; + *namelenp = -namelen; + *resolvedp = data->names->names[++data->current]; + *resolvedlenp = data->names->length[data->current]; + ret = FontNameAlias; + } + + ++data->current; + return ret; +} + +void +FontFileRegisterLocalFpeFunctions (void) +{ + RegisterFPEFunctions(FontFileNameCheck, + FontFileInitFPE, + FontFileFreeFPE, + FontFileResetFPE, + FontFileOpenFont, + FontFileCloseFont, + FontFileListFonts, + FontFileStartListFontsWithInfo, + FontFileListNextFontWithInfo, + NULL, + NULL, + NULL, + FontFileStartListFontsAndAliases, + FontFileListNextFontOrAlias, + FontFileEmptyBitmapSource); +} diff --git a/nx-X11/lib/font/fontfile/fontscale.c b/nx-X11/lib/font/fontfile/fontscale.c new file mode 100644 index 000000000..8e9de513d --- /dev/null +++ b/nx-X11/lib/font/fontfile/fontscale.c @@ -0,0 +1,447 @@ +/* $Xorg: fontscale.c,v 1.5 2001/02/09 02:04:03 xorgcvs Exp $ */ + +/* + +Copyright 1991, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ +/* $XFree86: xc/lib/font/fontfile/fontscale.c,v 3.9 2001/08/27 19:49:54 dawes Exp $ */ + +/* + * Author: Keith Packard, MIT X Consortium + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <X11/fonts/fntfilst.h> +#ifdef _XOPEN_SOURCE +#include <math.h> +#else +#define _XOPEN_SOURCE /* to get prototype for hypot on some systems */ +#include <math.h> +#undef _XOPEN_SOURCE +#endif + +Bool +FontFileAddScaledInstance (FontEntryPtr entry, FontScalablePtr vals, + FontPtr pFont, char *bitmapName) +{ + FontScalableEntryPtr scalable; + FontScalableExtraPtr extra; + FontScaledPtr new; + int newsize; + + scalable = &entry->u.scalable; + extra = scalable->extra; + if (extra->numScaled == extra->sizeScaled) + { + newsize = extra->sizeScaled + 4; + new = (FontScaledPtr) xrealloc (extra->scaled, + newsize * sizeof (FontScaledRec)); + if (!new) + return FALSE; + extra->sizeScaled = newsize; + extra->scaled = new; + } + new = &extra->scaled[extra->numScaled++]; + new->vals = *vals; + new->pFont = pFont; + new->bitmap = (FontEntryPtr) bitmapName; + if (pFont) + pFont->fpePrivate = (pointer) entry; + return TRUE; +} + +/* Must call this after the directory is sorted */ + +void +FontFileSwitchStringsToBitmapPointers (FontDirectoryPtr dir) +{ + int s; + int b; + int i; + FontEntryPtr scalable; + FontEntryPtr nonScalable; + FontScaledPtr scaled; + FontScalableExtraPtr extra; + + scalable = dir->scalable.entries; + nonScalable = dir->nonScalable.entries; + for (s = 0; s < dir->scalable.used; s++) + { + extra = scalable[s].u.scalable.extra; + scaled = extra->scaled; + for (i = 0; i < extra->numScaled; i++) + for (b = 0; b < dir->nonScalable.used; b++) + if (nonScalable[b].name.name == (char *) scaled[i].bitmap) + scaled[i].bitmap = &nonScalable[b]; + } +} + +void +FontFileRemoveScaledInstance (FontEntryPtr entry, FontPtr pFont) +{ + FontScalableEntryPtr scalable; + FontScalableExtraPtr extra; + int i; + + scalable = &entry->u.scalable; + extra = scalable->extra; + for (i = 0; i < extra->numScaled; i++) + { + if (extra->scaled[i].pFont == pFont) + { + if (extra->scaled[i].vals.ranges) + xfree (extra->scaled[i].vals.ranges); + extra->numScaled--; + for (; i < extra->numScaled; i++) + extra->scaled[i] = extra->scaled[i+1]; + } + } +} + +Bool +FontFileCompleteXLFD (FontScalablePtr vals, FontScalablePtr def) +{ + FontResolutionPtr res; + int num_res; + double sx, sy, temp_matrix[4]; + double pixel_setsize_adjustment = 1.0; + /* + * If two of the three vertical scale values are specified, compute the + * third. If all three are specified, make sure they are consistent + * (within a pixel) + * + * One purpose of this procedure is to complete XLFD names in a + * repeatable manner. That is, if the user partially specifies + * a name (say, pixelsize but not pointsize), the results generated + * here result in a fully specified name that will result in the + * same font. + */ + + res = GetClientResolutions(&num_res); + + if (!(vals->values_supplied & PIXELSIZE_MASK) || + !(vals->values_supplied & POINTSIZE_MASK)) + { + /* If resolution(s) unspecified and cannot be computed from + pixelsize and pointsize, get appropriate defaults. */ + + if (num_res) + { + if (vals->x <= 0) + vals->x = res->x_resolution; + if (vals->y <= 0) + vals->y = res->y_resolution; + } + + if (vals->x <= 0) + vals->x = def->x; + if (vals->y <= 0) + vals->y = def->y; + } + else + { + /* If needed, compute resolution values from the pixel and + pointsize information we were given. This problem is + overdetermined (four equations, two unknowns), but we don't + check for inconsistencies here. If they exist, they will + show up in later tests for the point and pixel sizes. */ + + if (vals->y <= 0) + { + double x = hypot(vals->pixel_matrix[1], vals->pixel_matrix[3]); + double y = hypot(vals->point_matrix[1], vals->point_matrix[3]); + if (y < EPS) return FALSE; + vals->y = (int)(x * 72.27 / y + .5); + } + if (vals->x <= 0) + { + /* If the pixelsize was given as an array, or as a scalar that + has been normalized for the pixel shape, we have enough + information to compute a separate horizontal resolution */ + + if ((vals->values_supplied & PIXELSIZE_MASK) == PIXELSIZE_ARRAY || + (vals->values_supplied & PIXELSIZE_MASK) == + PIXELSIZE_SCALAR_NORMALIZED) + { + double x = hypot(vals->pixel_matrix[0], vals->pixel_matrix[2]); + double y = hypot(vals->point_matrix[0], vals->point_matrix[2]); + if (y < EPS) return FALSE; + vals->x = (int)(x * 72.27 / y + .5); + } + else + { + /* Not enough information in the pixelsize array. Just + assume the pixels are square. */ + vals->x = vals->y; + } + } + } + + if (vals->x <= 0 || vals->y <= 0) return FALSE; + + /* If neither pixelsize nor pointsize is defined, take the pointsize + from the defaults structure we've been passed. */ + if (!(vals->values_supplied & PIXELSIZE_MASK) && + !(vals->values_supplied & POINTSIZE_MASK)) + { + if (num_res) + { + vals->point_matrix[0] = + vals->point_matrix[3] = (double)res->point_size / 10.0; + vals->point_matrix[1] = + vals->point_matrix[2] = 0; + vals->values_supplied = (vals->values_supplied & ~POINTSIZE_MASK) | + POINTSIZE_SCALAR; + } + else if (def->values_supplied & POINTSIZE_MASK) + { + vals->point_matrix[0] = def->point_matrix[0]; + vals->point_matrix[1] = def->point_matrix[1]; + vals->point_matrix[2] = def->point_matrix[2]; + vals->point_matrix[3] = def->point_matrix[3]; + vals->values_supplied = (vals->values_supplied & ~POINTSIZE_MASK) | + (def->values_supplied & POINTSIZE_MASK); + } + else return FALSE; + } + + /* At this point, at least two of the three vertical scale values + should be specified. Our job now is to compute the missing ones + and check for agreement between overspecified values */ + + /* If pixelsize was specified by a scalar, we need to fix the matrix + now that we know the resolutions. */ + if ((vals->values_supplied & PIXELSIZE_MASK) == PIXELSIZE_SCALAR) + { + /* pixel_setsize_adjustment used below to modify permissible + error in pixel/pointsize matching, since multiplying a + number rounded to integer changes the amount of the error + caused by the rounding */ + + pixel_setsize_adjustment = (double)vals->x / (double)vals->y; + vals->pixel_matrix[0] *= pixel_setsize_adjustment; + vals->values_supplied = (vals->values_supplied & ~PIXELSIZE_MASK) | + PIXELSIZE_SCALAR_NORMALIZED; + } + + sx = (double)vals->x / 72.27; + sy = (double)vals->y / 72.27; + + /* If a pointsize was specified, make sure pixelsize is consistent + to within 1 pixel, then replace pixelsize with a consistent + floating-point value. */ + + if (vals->values_supplied & POINTSIZE_MASK) + { + recompute_pixelsize: ; + temp_matrix[0] = vals->point_matrix[0] * sx; + temp_matrix[1] = vals->point_matrix[1] * sy; + temp_matrix[2] = vals->point_matrix[2] * sx; + temp_matrix[3] = vals->point_matrix[3] * sy; + if (vals->values_supplied & PIXELSIZE_MASK) + { + if (fabs(vals->pixel_matrix[0] - temp_matrix[0]) > + pixel_setsize_adjustment || + fabs(vals->pixel_matrix[1] - temp_matrix[1]) > 1 || + fabs(vals->pixel_matrix[2] - temp_matrix[2]) > 1 || + fabs(vals->pixel_matrix[3] - temp_matrix[3]) > 1) + return FALSE; + } + if ((vals->values_supplied & PIXELSIZE_MASK) == PIXELSIZE_ARRAY && + (vals->values_supplied & POINTSIZE_MASK) == POINTSIZE_SCALAR) + { + /* In the special case that pixelsize came as an array and + pointsize as a scalar, recompute the pointsize matrix + from the pixelsize matrix. */ + goto recompute_pointsize; + } + + /* Refresh pixel matrix with precise values computed from + pointsize and resolution. */ + vals->pixel_matrix[0] = temp_matrix[0]; + vals->pixel_matrix[1] = temp_matrix[1]; + vals->pixel_matrix[2] = temp_matrix[2]; + vals->pixel_matrix[3] = temp_matrix[3]; + + /* Set values_supplied for pixel to match that for point */ + vals->values_supplied = + (vals->values_supplied & ~PIXELSIZE_MASK) | + (((vals->values_supplied & POINTSIZE_MASK) == POINTSIZE_ARRAY) ? + PIXELSIZE_ARRAY : PIXELSIZE_SCALAR_NORMALIZED); + } + else + { + /* Pointsize unspecified... compute from pixel size and + resolutions */ + recompute_pointsize: ; + if (fabs(sx) < EPS || fabs(sy) < EPS) return FALSE; + vals->point_matrix[0] = vals->pixel_matrix[0] / sx; + vals->point_matrix[1] = vals->pixel_matrix[1] / sy; + vals->point_matrix[2] = vals->pixel_matrix[2] / sx; + vals->point_matrix[3] = vals->pixel_matrix[3] / sy; + + /* Set values_supplied for pixel to match that for point */ + vals->values_supplied = + (vals->values_supplied & ~POINTSIZE_MASK) | + (((vals->values_supplied & PIXELSIZE_MASK) == PIXELSIZE_ARRAY) ? + POINTSIZE_ARRAY : POINTSIZE_SCALAR); + + /* If we computed scalar pointsize from scalar pixelsize, round + pointsize to decipoints and recompute pixelsize so we end up + with a repeatable name */ + if ((vals->values_supplied & POINTSIZE_MASK) == POINTSIZE_SCALAR) + { + /* Off-diagonal elements should be zero since no matrix was + specified. */ + vals->point_matrix[0] = + (double)(int)(vals->point_matrix[0] * 10.0 + .5) / 10.0; + vals->point_matrix[3] = + (double)(int)(vals->point_matrix[3] * 10.0 + .5) / 10.0; + goto recompute_pixelsize; + } + } + + /* We've succeeded. Round everything to a few decimal places + for repeatability. */ + + vals->pixel_matrix[0] = xlfd_round_double(vals->pixel_matrix[0]); + vals->pixel_matrix[1] = xlfd_round_double(vals->pixel_matrix[1]); + vals->pixel_matrix[2] = xlfd_round_double(vals->pixel_matrix[2]); + vals->pixel_matrix[3] = xlfd_round_double(vals->pixel_matrix[3]); + vals->point_matrix[0] = xlfd_round_double(vals->point_matrix[0]); + vals->point_matrix[1] = xlfd_round_double(vals->point_matrix[1]); + vals->point_matrix[2] = xlfd_round_double(vals->point_matrix[2]); + vals->point_matrix[3] = xlfd_round_double(vals->point_matrix[3]); + + /* Fill in the deprecated fields for the benefit of rasterizers + that do not handle the matrices. */ + vals->point = vals->point_matrix[3] * 10; + vals->pixel = vals->pixel_matrix[3]; + + return TRUE; +} + +static Bool +MatchScalable (FontScalablePtr a, FontScalablePtr b) +{ + int i; + + /* Some asymmetry here: we assume that the first argument (a) is + the table entry and the second (b) the item we're trying to match + (the key). We'll consider the fonts matched if the relevant + metrics match *and* if a) the table entry doesn't have charset + subsetting or b) the table entry has identical charset subsetting + to that in the key. We could add logic to check if the table + entry has a superset of the charset required by the key, but + we'll resist the urge for now. */ + +#define EQUAL(a,b) ((a)[0] == (b)[0] && \ + (a)[1] == (b)[1] && \ + (a)[2] == (b)[2] && \ + (a)[3] == (b)[3]) + + if (!(a->x == b->x && + a->y == b->y && + (a->width == b->width || a->width == 0 || b->width == 0 || b->width == -1) && + (!(b->values_supplied & PIXELSIZE_MASK) || + ((a->values_supplied & PIXELSIZE_MASK) == + (b->values_supplied & PIXELSIZE_MASK) && + EQUAL(a->pixel_matrix, b->pixel_matrix))) && + (!(b->values_supplied & POINTSIZE_MASK) || + ((a->values_supplied & POINTSIZE_MASK) == + (b->values_supplied & POINTSIZE_MASK) && + EQUAL(a->point_matrix, b->point_matrix))) && + (a->nranges == 0 || a->nranges == b->nranges))) + return FALSE; + + for (i = 0; i < a->nranges; i++) + if (a->ranges[i].min_char_low != b->ranges[i].min_char_low || + a->ranges[i].min_char_high != b->ranges[i].min_char_high || + a->ranges[i].max_char_low != b->ranges[i].max_char_low || + a->ranges[i].max_char_high != b->ranges[i].max_char_high) + return FALSE; + + return TRUE; +} + +FontScaledPtr +FontFileFindScaledInstance (FontEntryPtr entry, FontScalablePtr vals, + int noSpecificSize) +{ + FontScalableEntryPtr scalable; + FontScalableExtraPtr extra; + FontScalablePtr mvals; + int dist, i; + int mini; + double mindist; + register double temp, sum=0.0; + +#define NORMDIFF(a, b) ( \ + temp = (a)[0] - (b)[0], \ + sum = temp * temp, \ + temp = (a)[1] - (b)[1], \ + sum += temp * temp, \ + temp = (a)[2] - (b)[2], \ + sum += temp * temp, \ + temp = (a)[3] - (b)[3], \ + sum + temp * temp ) + + scalable = &entry->u.scalable; + extra = scalable->extra; + if (noSpecificSize && extra->numScaled) + { + mini = 0; + mindist = NORMDIFF(extra->scaled[0].vals.point_matrix, + vals->point_matrix); + for (i = 1; i < extra->numScaled; i++) + { + if (extra->scaled[i].pFont && + !extra->scaled[i].pFont->info.cachable) continue; + mvals = &extra->scaled[i].vals; + dist = NORMDIFF(mvals->point_matrix, vals->point_matrix); + if (dist < mindist) + { + mindist = dist; + mini = i; + } + } + if (extra->scaled[mini].pFont && + !extra->scaled[mini].pFont->info.cachable) return 0; + return &extra->scaled[mini]; + } + else + { + /* See if we've scaled to this value yet */ + for (i = 0; i < extra->numScaled; i++) + { + if (extra->scaled[i].pFont && + !extra->scaled[i].pFont->info.cachable) continue; + if (MatchScalable (&extra->scaled[i].vals, vals)) + return &extra->scaled[i]; + } + } + return 0; +} diff --git a/nx-X11/lib/font/fontfile/gunzip.c b/nx-X11/lib/font/fontfile/gunzip.c new file mode 100644 index 000000000..8c9c317aa --- /dev/null +++ b/nx-X11/lib/font/fontfile/gunzip.c @@ -0,0 +1,227 @@ +/* $Xorg: gunzip.c,v 1.3 2000/08/17 19:46:37 cpqbld Exp $ */ +/* lib/font/fontfile/gunzip.c + written by Mark Eichin <eichin@kitten.gen.ma.us> September 1996. + intended for inclusion in X11 public releases. */ +/* $XFree86: xc/lib/font/fontfile/gunzip.c,v 1.4 2000/09/19 12:46:08 eich Exp $ */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <X11/fonts/fontmisc.h> +#include <X11/fonts/bufio.h> +#include <zlib.h> + +typedef struct _xzip_buf { + z_stream z; + int zstat; + BufChar b[BUFFILESIZE]; + BufChar b_in[BUFFILESIZE]; + BufFilePtr f; +} xzip_buf; + +static int BufZipFileClose ( BufFilePtr f, int flag ); +static int BufZipFileFill ( BufFilePtr f ); +static int BufZipFileSkip ( BufFilePtr f, int c ); +static int BufCheckZipHeader ( BufFilePtr f ); + +BufFilePtr +BufFilePushZIP (BufFilePtr f) +{ + xzip_buf *x; + + x = (xzip_buf *) xalloc (sizeof (xzip_buf)); + if (!x) return 0; + /* these are just for raw calloc/free */ + x->z.zalloc = Z_NULL; + x->z.zfree = Z_NULL; + x->z.opaque = Z_NULL; + x->f = f; + + /* force inflateInit to allocate it's own history buffer */ + x->z.next_in = Z_NULL; + x->z.next_out = Z_NULL; + x->z.avail_in = x->z.avail_out = 0; + + /* using negative windowBits sets "nowrap" mode, which turns off + zlib header checking [undocumented, for gzip compatibility only?] */ + x->zstat = inflateInit2(&(x->z), -MAX_WBITS); + if (x->zstat != Z_OK) { + xfree(x); + return 0; + } + + /* now that the history buffer is allocated, we provide the data buffer */ + x->z.next_out = x->b; + x->z.avail_out = BUFFILESIZE; + x->z.next_out = x->b_in; + x->z.avail_in = 0; + + if (BufCheckZipHeader(x->f)) { + xfree(x); + return 0; + } + + return BufFileCreate((char *)x, + BufZipFileFill, + 0, + BufZipFileSkip, + BufZipFileClose); +} + +static int +BufZipFileClose(BufFilePtr f, int flag) +{ + xzip_buf *x = (xzip_buf *)f->private; + inflateEnd (&(x->z)); + BufFileClose (x->f, flag); + xfree (x); + return 1; +} + +/* here's the real work. + -- we need to put stuff in f.buffer, update f.left and f.bufp, + then return the first byte (or BUFFILEEOF). + -- to do this, we need to get stuff into avail_in, and next_in, + and call inflate appropriately. + -- we may also need to add CRC maintenance - if inflate tells us + Z_STREAM_END, we then have 4bytes CRC and 4bytes length... + gzio.c:gzread shows most of the mechanism. + */ +static int +BufZipFileFill (BufFilePtr f) +{ + xzip_buf *x = (xzip_buf *)f->private; + + /* we only get called when left == 0... */ + /* but just in case, deal */ + if (f->left >= 0) { + f->left--; + return *(f->bufp++); + } + /* did we run out last time? */ + switch (x->zstat) { + case Z_OK: + break; + case Z_STREAM_END: + case Z_DATA_ERROR: + case Z_ERRNO: + f->left = 0; + return BUFFILEEOF; + default: + return BUFFILEEOF; + } + /* now we work to consume what we can */ + /* let zlib know what we can handle */ + x->z.next_out = x->b; + x->z.avail_out = BUFFILESIZE; + + /* and try to consume all of it */ + while (x->z.avail_out > 0) { + /* if we don't have anything to work from... */ + if (x->z.avail_in == 0) { + /* ... fill the z buf from underlying file */ + int i, c; + for (i = 0; i < sizeof(x->b_in); i++) { + c = BufFileGet(x->f); + if (c == BUFFILEEOF) break; + x->b_in[i] = c; + } + x->z.avail_in += i; + x->z.next_in = x->b_in; + } + /* so now we have some output space and some input data */ + x->zstat = inflate(&(x->z), Z_NO_FLUSH); + /* the inflation output happens in the f buffer directly... */ + if (x->zstat == Z_STREAM_END) { + /* deal with EOF, crc */ + break; + } + if (x->zstat != Z_OK) { + break; + } + } + f->bufp = x->b; + f->left = BUFFILESIZE - x->z.avail_out; + + if (f->left >= 0) { + f->left--; + return *(f->bufp++); + } else { + return BUFFILEEOF; + } +} + +/* there should be a BufCommonSkip... */ +static int +BufZipFileSkip (BufFilePtr f, int c) +{ + /* BufFileRawSkip returns the count unchanged. + BufCompressedSkip returns 0. + That means it probably never gets called... */ + int retval = c; + while(c--) { + int get = BufFileGet(f); + if (get == BUFFILEEOF) return get; + } + return retval; +} + +/* now we need to duplicate check_header */ +/* contents: + 0x1f, 0x8b -- magic number + 1 byte -- method (Z_DEFLATED) + 1 byte -- flags (mask with RESERVED -> fail) + 4 byte -- time (discard) + 1 byte -- xflags (discard) + 1 byte -- "os" code (discard) + [if flags & EXTRA_FIELD: + 2 bytes -- LSBfirst length n + n bytes -- extra data (discard)] + [if flags & ORIG_NAME: + n bytes -- null terminated name (discard)] + [if flags & COMMENT: + n bytes -- null terminated comment (discard)] + [if flags & HEAD_CRC: + 2 bytes -- crc of headers? (discard)] + */ + +/* gzip flag byte -- from gzio.c */ +#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ +#define HEAD_CRC 0x02 /* bit 1 set: header CRC present */ +#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ +#define ORIG_NAME 0x08 /* bit 3 set: original file name present */ +#define COMMENT 0x10 /* bit 4 set: file comment present */ +#define RESERVED 0xE0 /* bits 5..7: reserved */ + +#define GET(f) do {c = BufFileGet(f); if (c == BUFFILEEOF) return c;} while(0) +static int +BufCheckZipHeader(BufFilePtr f) +{ + int c, flags; + GET(f); if (c != 0x1f) return 1; /* magic 1 */ + GET(f); if (c != 0x8b) return 2; /* magic 2 */ + GET(f); if (c != Z_DEFLATED) return 3; /* method */ + GET(f); if (c & RESERVED) return 4; /* reserved flags */ + flags = c; + GET(f); GET(f); GET(f); GET(f); /* time */ + GET(f); /* xflags */ + GET(f); /* os code */ + if (flags & EXTRA_FIELD) { + int len; + GET(f); len = c; + GET(f); len += (c<<8); + while (len-- >= 0) { + GET(f); + } + } + if (flags & ORIG_NAME) { + do { GET(f); } while (c != 0); + } + if (flags & COMMENT) { + do { GET(f); } while (c != 0); + } + if (flags & HEAD_CRC) { + GET(f); GET(f); /* header crc */ + } + return 0; +} diff --git a/nx-X11/lib/font/fontfile/module/Imakefile b/nx-X11/lib/font/fontfile/module/Imakefile new file mode 100644 index 000000000..0eebe085e --- /dev/null +++ b/nx-X11/lib/font/fontfile/module/Imakefile @@ -0,0 +1,21 @@ +XCOMM $XFree86: xc/lib/font/fontfile/module/Imakefile,v 1.3 1999/06/13 13:47:35 dawes Exp $ +#include <Server.tmpl> + + INCLUDES = -I$(FONTINCSRC) -I../../include -I$(SERVERSRC)/include \ + -I$(XINCLUDESRC) + + DEFINES = -DLOADABLEFONTS + + SRCS = ffcheck.c register.c + OBJS = ffcheck.o register.o + +SubdirLibraryRule($(OBJS)) + +NormalLibraryObjectRule() +NormalLintTarget($(SRCS)) + +LinkSourceFile(ffcheck.c,..) +LinkSourceFile(register.c,..) + +DependTarget() + diff --git a/nx-X11/lib/font/fontfile/printerfont.c b/nx-X11/lib/font/fontfile/printerfont.c new file mode 100644 index 000000000..0b6c19c62 --- /dev/null +++ b/nx-X11/lib/font/fontfile/printerfont.c @@ -0,0 +1,178 @@ +/* $Xorg: printerfont.c,v 1.4 2001/02/09 02:04:03 xorgcvs Exp $ */ + +/* + +Copyright 1991, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ +/* $XFree86: xc/lib/font/fontfile/printerfont.c,v 1.5tsi Exp $ */ + +/* + * Author: Keith Packard, MIT X Consortium + */ +/* $NCDXorg: @(#)fontfile.c,v 1.6 1991/07/02 17:00:46 lemke Exp $ */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <X11/fonts/fntfilst.h> + +/* + * Map FPE functions to renderer functions + */ + +#define PRINTERPATHPREFIX "PRINTER:" + +/* STUB +int XpClientIsPrintClient(client,fpe) +pointer client; +FontPathElementPtr fpe; +{ return 1; } + */ + +static int +PrinterFontNameCheck (char *name) +{ + if (strncmp(name,PRINTERPATHPREFIX,strlen(PRINTERPATHPREFIX)) != 0) + return 0; + name += strlen(PRINTERPATHPREFIX); +#ifndef NCD + return *name == '/'; +#else + return ((strcmp(name, "built-ins") == 0) || (*name == '/')); +#endif +} + +static int +PrinterFontInitFPE (FontPathElementPtr fpe) +{ + int status; + FontDirectoryPtr dir; + char * name; + + name = fpe->name + strlen(PRINTERPATHPREFIX); + status = FontFileReadDirectory (name, &dir); + if (status == Successful) + { + if (dir->nonScalable.used > 0) + if (!FontFileRegisterBitmapSource (fpe)) + { + FontFileFreeFPE (fpe); + return AllocError; + } + fpe->private = (pointer) dir; + } + return status; +} + +/* Here we must check the client to see if it has a context attached to + * it that allows us to access the printer fonts + */ + +static int +PrinterFontOpenFont (pointer client, FontPathElementPtr fpe, Mask flags, + char *name, int namelen, + fsBitmapFormat format, fsBitmapFormatMask fmask, + XID id, FontPtr *pFont, char **aliasName, + FontPtr non_cachable_font) +{ + if (XpClientIsPrintClient(client,fpe)) + return (FontFileOpenFont (client, fpe, flags, name, namelen, format, + fmask, id, pFont, aliasName, non_cachable_font)); + return BadFontName; +} + +static int +PrinterFontListFonts (pointer client, FontPathElementPtr fpe, char *pat, + int len, int max, FontNamesPtr names) +{ + if (XpClientIsPrintClient(client,fpe)) + return FontFileListFonts (client, fpe, pat, len, max, names); + return BadFontName; +} + +static int +PrinterFontStartListFontsWithInfo(pointer client, FontPathElementPtr fpe, + char *pat, int len, int max, + pointer *privatep) +{ + if (XpClientIsPrintClient(client,fpe)) + return FontFileStartListFontsWithInfo(client, fpe, pat, len, + max, privatep); + return BadFontName; +} + +static int +PrinterFontListNextFontWithInfo(pointer client, FontPathElementPtr fpe, + char **namep, int *namelenp, + FontInfoPtr *pFontInfo, + int *numFonts, pointer private) +{ + if (XpClientIsPrintClient(client,fpe)) + return FontFileListNextFontWithInfo(client, fpe, namep, namelenp, + pFontInfo, numFonts, private); + return BadFontName; +} + +static int +PrinterFontStartListFontsAndAliases(pointer client, FontPathElementPtr fpe, + char *pat, int len, int max, + pointer *privatep) +{ + if (XpClientIsPrintClient(client,fpe)) + return FontFileStartListFontsAndAliases(client, fpe, pat, len, + max, privatep); + return BadFontName; +} + +static int +PrinterFontListNextFontOrAlias(pointer client, FontPathElementPtr fpe, + char **namep, int *namelenp, + char **resolvedp, int *resolvedlenp, + pointer private) +{ + if (XpClientIsPrintClient(client,fpe)) + return FontFileListNextFontOrAlias(client, fpe, namep, namelenp, + resolvedp, resolvedlenp, private); + return BadFontName; +} + +void +PrinterFontRegisterFpeFunctions (void) +{ + RegisterFPEFunctions(PrinterFontNameCheck, + PrinterFontInitFPE, + FontFileFreeFPE, + FontFileResetFPE, + PrinterFontOpenFont, + FontFileCloseFont, + PrinterFontListFonts, + PrinterFontStartListFontsWithInfo, + PrinterFontListNextFontWithInfo, + NULL, + NULL, + NULL, + PrinterFontStartListFontsAndAliases, + PrinterFontListNextFontOrAlias, + FontFileEmptyBitmapSource); +} diff --git a/nx-X11/lib/font/fontfile/register.c b/nx-X11/lib/font/fontfile/register.c new file mode 100644 index 000000000..cb74c7cab --- /dev/null +++ b/nx-X11/lib/font/fontfile/register.c @@ -0,0 +1,109 @@ +/* $Xorg: register.c,v 1.4 2001/02/09 02:04:03 xorgcvs Exp $ */ + +/* + +Copyright 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ +/* $XFree86: xc/lib/font/fontfile/register.c,v 1.14 2001/01/17 19:43:30 dawes Exp $ */ + +/* + * This is in a separate source file so that small programs + * such as mkfontdir that want to use the fontfile utilities don't + * end up dragging in code from all the renderers, which is not small. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#else +#define XFONT_BITMAP 1 +#endif + +#include <X11/fonts/fontmisc.h> +#include <X11/fonts/fntfilst.h> +#include <X11/fonts/bitmap.h> + +#ifdef LOADABLEFONTS +#include <X11/fonts/fontmod.h> +#endif + +/* + * Translate monolithic build symbols to modular build symbols. + * I chose to make the modular symbols 'canonical' because they + * are prefixed with XFONT_, neatly avoiding name collisions + * with other packages. + */ + +#ifndef CRAY +# ifdef BUILD_SPEEDO +# define XFONT_SPEEDO 1 +# endif +# ifdef BUILD_TYPE1 +# define XFONT_TYPE1 1 +# endif +#endif + +#ifdef BUILD_CID +# define XFONT_CID 1 +#endif +#ifdef BUILD_FREETYPE +# define XFONT_FREETYPE 1 +#endif + +void +FontFileRegisterFpeFunctions(void) +{ +#ifndef LOADABLEFONTS + +#ifdef XFONT_BITMAP + BitmapRegisterFontFileFunctions (); +#endif +#ifdef XFONT_SPEEDO + SpeedoRegisterFontFileFunctions (); +#endif +#ifdef XFONT_TYPE1 + Type1RegisterFontFileFunctions(); +#endif +#ifdef XFONT_CID + CIDRegisterFontFileFunctions(); +#endif +#ifdef XFONT_FREETYPE + FreeTypeRegisterFontFileFunctions(); +#endif + +#else + { + int i; + + if (FontModuleList) { + for (i = 0; FontModuleList[i].name; i++) { + if (FontModuleList[i].initFunc) + FontModuleList[i].initFunc(); + } + } + } +#endif + + FontFileRegisterLocalFpeFunctions (); +} + diff --git a/nx-X11/lib/font/fontfile/renderers.c b/nx-X11/lib/font/fontfile/renderers.c new file mode 100644 index 000000000..f110ba817 --- /dev/null +++ b/nx-X11/lib/font/fontfile/renderers.c @@ -0,0 +1,117 @@ +/* $Xorg: renderers.c,v 1.4 2001/02/09 02:04:03 xorgcvs Exp $ */ + +/* + +Copyright 1991, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ +/* $XFree86: xc/lib/font/fontfile/renderers.c,v 1.7 2002/12/09 17:30:00 dawes Exp $ */ + +/* + * Author: Keith Packard, MIT X Consortium + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <X11/fonts/fntfilst.h> +extern void ErrorF(const char *f, ...); + +static FontRenderersRec renderers; + +/* + * XXX Maybe should allow unregistering renders. For now, just clear the + * list at each new generation. + */ +extern unsigned long serverGeneration; +static unsigned long rendererGeneration = 0; + +Bool +FontFileRegisterRenderer (FontRendererPtr renderer) +{ + return FontFilePriorityRegisterRenderer(renderer, 0); +} + +Bool +FontFilePriorityRegisterRenderer (FontRendererPtr renderer, int priority) +{ + int i; + struct _FontRenderersElement *new; + + if (rendererGeneration != serverGeneration) { + rendererGeneration = serverGeneration; + renderers.number = 0; + if (renderers.renderers) + xfree(renderers.renderers); + renderers.renderers = NULL; + } + + for (i = 0; i < renderers.number; i++) { + if (!strcmp (renderers.renderers[i].renderer->fileSuffix, + renderer->fileSuffix)) { + if(renderers.renderers[i].priority >= priority) { + if(renderers.renderers[i].priority == priority) { + if (rendererGeneration == 1) + ErrorF("Warning: font renderer for \"%s\" " + "already registered at priority %d\n", + renderer->fileSuffix, priority); + } + return TRUE; + } else { + break; + } + } + } + + if(i >= renderers.number) { + new = xrealloc (renderers.renderers, sizeof(*new) * (i + 1)); + if (!new) + return FALSE; + renderers.renderers = new; + renderers.number = i + 1; + } + renderer->number = i; + renderers.renderers[i].renderer = renderer; + renderers.renderers[i].priority = priority; + return TRUE; +} + +FontRendererPtr +FontFileMatchRenderer (char *fileName) +{ + int i; + int fileLen; + FontRendererPtr r; + + fileLen = strlen (fileName); + for (i = 0; i < renderers.number; i++) + { + r = renderers.renderers[i].renderer; + if (fileLen >= r->fileSuffixLen && + !strcmp (fileName + fileLen - r->fileSuffixLen, r->fileSuffix)) + { + return r; + } + } + return 0; +} diff --git a/nx-X11/lib/font/include/Imakefile b/nx-X11/lib/font/include/Imakefile new file mode 100644 index 000000000..91c84e6ec --- /dev/null +++ b/nx-X11/lib/font/include/Imakefile @@ -0,0 +1,11 @@ +XCOMM $Xorg$ + HEADERS = bitmap.h bufio.h fntfil.h fntfilio.h fntfilst.h fontenc.h \ + fontencc.h fontmisc.h fontmod.h fontshow.h fontutil.h \ + fontxlfd.h +all:: + +BuildIncludes($(HEADERS),X11/fonts,../..) + +#if BuildLibraries +InstallMultipleFlags($(HEADERS),$(INCDIR)/X11/fonts,$(INSTINCFLAGS)) +#endif diff --git a/nx-X11/lib/font/include/bitmap.h b/nx-X11/lib/font/include/bitmap.h new file mode 100644 index 000000000..e60fda8eb --- /dev/null +++ b/nx-X11/lib/font/include/bitmap.h @@ -0,0 +1,116 @@ +/* $Xorg: bitmap.h,v 1.4 2001/02/09 02:04:04 xorgcvs Exp $ */ + +/* + +Copyright 1990, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + +*/ +/* $XFree86: xc/lib/font/include/bitmap.h,v 1.9 2001/01/17 19:43:31 dawes Exp $ */ + +/* + * Author: Keith Packard, MIT X Consortium + */ + +#ifndef _BITMAP_H_ +#define _BITMAP_H_ + +#include <X11/fonts/fntfilio.h> +#ifndef FONTMODULE +#include <stdio.h> /* just for NULL */ +#else +#include "xf86_ansic.h" +#endif + +/* + * Internal format used to store bitmap fonts + */ + +/* number of encoding entries in one segment */ +#define BITMAP_FONT_SEGMENT_SIZE 128 + +typedef struct _BitmapExtra { + Atom *glyphNames; + int *sWidths; + CARD32 bitmapsSizes[GLYPHPADOPTIONS]; + FontInfoRec info; +} BitmapExtraRec, *BitmapExtraPtr; + +typedef struct _BitmapFont { + unsigned version_num; + int num_chars; + int num_tables; + CharInfoPtr metrics; /* font metrics, including glyph pointers */ + xCharInfo *ink_metrics; /* ink metrics */ + char *bitmaps; /* base of bitmaps, useful only to free */ + CharInfoPtr **encoding; /* array of arrays of char info pointers */ + CharInfoPtr pDefault; /* default character */ + BitmapExtraPtr bitmapExtra; /* stuff not used by X server */ +} BitmapFontRec, *BitmapFontPtr; + +#define ACCESSENCODING(enc,i) \ +(enc[(i)/BITMAP_FONT_SEGMENT_SIZE]?\ +(enc[(i)/BITMAP_FONT_SEGMENT_SIZE][(i)%BITMAP_FONT_SEGMENT_SIZE]):\ +0) +#define ACCESSENCODINGL(enc,i) \ +(enc[(i)/BITMAP_FONT_SEGMENT_SIZE][(i)%BITMAP_FONT_SEGMENT_SIZE]) + +#define SEGMENT_MAJOR(n) ((n)/BITMAP_FONT_SEGMENT_SIZE) +#define SEGMENT_MINOR(n) ((n)%BITMAP_FONT_SEGMENT_SIZE) +#define NUM_SEGMENTS(n) \ + (((n)+BITMAP_FONT_SEGMENT_SIZE-1)/BITMAP_FONT_SEGMENT_SIZE) + +extern int bitmapGetGlyphs ( FontPtr pFont, unsigned long count, + unsigned char *chars, FontEncoding charEncoding, + unsigned long *glyphCount, CharInfoPtr *glyphs ); +extern int bitmapGetMetrics ( FontPtr pFont, unsigned long count, + unsigned char *chars, FontEncoding charEncoding, + unsigned long *glyphCount, xCharInfo **glyphs ); + +extern void bitmapComputeFontBounds ( FontPtr pFont ); +extern void bitmapComputeFontInkBounds ( FontPtr pFont ); +extern Bool bitmapAddInkMetrics ( FontPtr pFont ); +extern int bitmapComputeWeight ( FontPtr pFont ); + +extern int BitmapOpenBitmap ( FontPathElementPtr fpe, FontPtr *ppFont, + int flags, FontEntryPtr entry, char *fileName, + fsBitmapFormat format, fsBitmapFormatMask fmask, + FontPtr non_cachable_font ); +extern int BitmapGetInfoBitmap ( FontPathElementPtr fpe, + FontInfoPtr pFontInfo, FontEntryPtr entry, + char *fileName ); +extern void BitmapRegisterFontFileFunctions ( void ); +extern int BitmapGetRenderIndex ( FontRendererPtr renderer ); + +extern int BitmapOpenScalable ( FontPathElementPtr fpe, FontPtr *pFont, + int flags, FontEntryPtr entry, char *fileName, + FontScalablePtr vals, fsBitmapFormat format, + fsBitmapFormatMask fmask, + FontPtr non_cachable_font ); +extern int BitmapGetInfoScalable ( FontPathElementPtr fpe, + FontInfoPtr pFontInfo, FontEntryPtr entry, + FontNamePtr fontName, char *fileName, + FontScalablePtr vals ); + +#endif /* _BITMAP_H_ */ diff --git a/nx-X11/lib/font/include/bufio.h b/nx-X11/lib/font/include/bufio.h new file mode 100644 index 000000000..da90064a2 --- /dev/null +++ b/nx-X11/lib/font/include/bufio.h @@ -0,0 +1,92 @@ +/* $Xorg: bufio.h,v 1.4 2001/02/09 02:04:04 xorgcvs Exp $ */ + +/* + +Copyright 1993, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + +*/ +/* $XFree86: xc/lib/font/include/bufio.h,v 1.6 2001/07/31 16:44:55 alanh Exp $ */ + +#ifndef ___BUFIO_H___ +#define ___BUFIO_H___ 1 + +#include <X11/Xfuncproto.h> + +#ifdef TEST + +#define xalloc(s) malloc(s) +#define xfree(s) free(s) + +#endif + +#define BUFFILESIZE 8192 +#define BUFFILEEOF -1 + +typedef unsigned char BufChar; +typedef struct _buffile *BufFilePtr; + +typedef struct _buffile { + BufChar *bufp; + int left; + int eof; + BufChar buffer[BUFFILESIZE]; + int (*input)( BufFilePtr /* f */); + int (*output)( int /* c */, BufFilePtr /* f */); + int (*skip)( BufFilePtr /* f */, int /* count */); + int (*close)( BufFilePtr /* f */, int /* doClose */); + char *private; +} BufFileRec; + +extern BufFilePtr BufFileCreate ( + char*, + int (*)(BufFilePtr), + int (*)(int, BufFilePtr), + int (*)(BufFilePtr, int), + int (*)(BufFilePtr, int)); +extern BufFilePtr BufFileOpenRead ( int ); +extern BufFilePtr BufFileOpenWrite ( int ); +extern BufFilePtr BufFilePushCompressed ( BufFilePtr ); +#ifdef X_GZIP_FONT_COMPRESSION +extern BufFilePtr BufFilePushZIP ( BufFilePtr ); +#endif +extern int BufFileClose ( BufFilePtr, int ); +extern int BufFileFlush ( BufFilePtr, int ); +extern int BufFileRead ( BufFilePtr, char*, int ); +extern int BufFileWrite ( BufFilePtr, char*, int ); +extern void BufFileFree ( BufFilePtr ); + +#define BufFileGet(f) ((f)->left-- ? *(f)->bufp++ : ((f)->eof = (*(f)->input) (f))) +#define BufFilePut(c,f) (--(f)->left ? *(f)->bufp++ = ((unsigned char)(c)) : (*(f)->output) ((unsigned char)(c),f)) +#define BufFileSkip(f,c) ((f)->eof = (*(f)->skip) (f, c)) + +#ifndef TRUE +#define TRUE 1 +#endif +#ifndef FALSE +#define FALSE 0 +#endif + +#endif /* ___BUFIO_H___ */ + diff --git a/nx-X11/lib/font/include/fntfil.h b/nx-X11/lib/font/include/fntfil.h new file mode 100644 index 000000000..81d2cbc3d --- /dev/null +++ b/nx-X11/lib/font/include/fntfil.h @@ -0,0 +1,178 @@ +/* $Xorg: fntfil.h,v 1.4 2001/02/09 02:04:04 xorgcvs Exp $ */ + +/* + +Copyright 1991, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ +/* $XFree86: xc/lib/font/include/fntfil.h,v 1.9 2001/12/14 19:56:54 dawes Exp $ */ + +/* + * Author: Keith Packard, MIT X Consortium + */ + +#ifndef _FONTFILE_H_ +#define _FONTFILE_H_ + +#include <X11/fonts/fontxlfd.h> + +typedef struct _FontEntry *FontEntryPtr; +typedef struct _FontTable *FontTablePtr; +typedef struct _FontName *FontNamePtr; +typedef struct _FontScaled *FontScaledPtr; +typedef struct _FontScalableExtra *FontScalableExtraPtr; +typedef struct _FontScalableEntry *FontScalableEntryPtr; +typedef struct _FontScaleAliasEntry *FontScaleAliasEntryPtr; +typedef struct _FontBitmapEntry *FontBitmapEntryPtr; +typedef struct _FontAliasEntry *FontAliasEntryPtr; +typedef struct _FontBCEntry *FontBCEntryPtr; +typedef struct _FontDirectory *FontDirectoryPtr; +typedef struct _FontRenderer *FontRendererPtr; + +#define NullFontEntry ((FontEntryPtr) 0) +#define NullFontTable ((FontTablePtr) 0) +#define NullFontName ((FontNamePtr) 0) +#define NullFontScaled ((FontScaled) 0) +#define NullFontScalableExtra ((FontScalableExtra) 0) +#define NullFontscalableEntry ((FontScalableEntry) 0) +#define NullFontScaleAliasEntry ((FontScaleAliasEntry) 0) +#define NullFontBitmapEntry ((FontBitmapEntry) 0) +#define NullFontAliasEntry ((FontAliasEntry) 0) +#define NullFontBCEntry ((FontBCEntry) 0) +#define NullFontDirectory ((FontDirectoryPtr) 0) +#define NullFontRenderer ((FontRendererPtr) 0) + +#define FONT_ENTRY_SCALABLE 0 +#define FONT_ENTRY_SCALE_ALIAS 1 +#define FONT_ENTRY_BITMAP 2 +#define FONT_ENTRY_ALIAS 3 +#define FONT_ENTRY_BC 4 + +#define MAXFONTNAMELEN 1024 +#define MAXFONTFILENAMELEN 1024 + +#define FontDirFile "fonts.dir" +#define FontAliasFile "fonts.alias" +#define FontScalableFile "fonts.scale" + +extern int FontFileNameCheck ( char *name ); +extern int FontFileInitFPE ( FontPathElementPtr fpe ); +extern int FontFileResetFPE ( FontPathElementPtr fpe ); +extern int FontFileFreeFPE ( FontPathElementPtr fpe ); +extern int FontFileOpenFont ( pointer client, FontPathElementPtr fpe, + Mask flags, char *name, int namelen, + fsBitmapFormat format, fsBitmapFormatMask fmask, + XID id, FontPtr *pFont, char **aliasName, + FontPtr non_cachable_font ); +extern void FontFileCloseFont ( FontPathElementPtr fpe, FontPtr pFont ); +extern int FontFileOpenBitmap ( FontPathElementPtr fpe, FontPtr *pFont, + int flags, FontEntryPtr entry, + fsBitmapFormat format, + fsBitmapFormatMask fmask ); +extern int FontFileListFonts ( pointer client, FontPathElementPtr fpe, + char *pat, int len, int max, + FontNamesPtr names ); +extern int FontFileStartListFontsWithInfo ( pointer client, + FontPathElementPtr fpe, + char *pat, int len, int max, + pointer *privatep ); +extern int FontFileListNextFontWithInfo ( pointer client, + FontPathElementPtr fpe, + char **namep, int *namelenp, + FontInfoPtr *pFontInfo, + int *numFonts, pointer private ); +extern int FontFileStartListFontsAndAliases ( pointer client, + FontPathElementPtr fpe, + char *pat, int len, int max, + pointer *privatep ); +extern int FontFileListNextFontOrAlias ( pointer client, + FontPathElementPtr fpe, + char **namep, int *namelenp, + char **resolvedp, int *resolvedlenp, + pointer private ); +extern void FontFileRegisterLocalFpeFunctions ( void ); + + +extern FontEntryPtr FontFileAddEntry ( FontTablePtr table, + FontEntryPtr prototype ); +extern Bool FontFileAddFontAlias ( FontDirectoryPtr dir, char *aliasName, + char *fontName ); +extern Bool FontFileAddFontFile ( FontDirectoryPtr dir, char *fontName, + char *fileName ); +extern int FontFileCountDashes ( char *name, int namelen ); +extern FontEntryPtr FontFileFindNameInDir ( FontTablePtr table, + FontNamePtr pat ); +extern FontEntryPtr FontFileFindNameInScalableDir ( FontTablePtr table, + FontNamePtr pat, + FontScalablePtr vals ); +extern int FontFileFindNamesInDir ( FontTablePtr table, FontNamePtr pat, + int max, FontNamesPtr names ); +extern int FontFileFindNamesInScalableDir ( FontTablePtr table, + FontNamePtr pat, int max, + FontNamesPtr names, + FontScalablePtr vals, + int alias_behavior, int *newmax ); + +extern void FontFileFreeDir ( FontDirectoryPtr dir ); +extern void FontFileFreeEntry ( FontEntryPtr entry ); +extern void FontFileFreeTable ( FontTablePtr table ); +extern Bool FontFileInitTable ( FontTablePtr table, int size ); +extern FontDirectoryPtr FontFileMakeDir ( char *dirName, int size ); +extern Bool FontFileMatchName ( char *name, int length, FontNamePtr pat ); +extern char * FontFileSaveString ( char *s ); +extern void FontFileSortDir ( FontDirectoryPtr dir ); +extern void FontFileSortTable ( FontTablePtr table ); + +extern void FontDefaultFormat ( int *bit, int *byte, int *glyph, int *scan ); + +extern Bool FontFileRegisterRenderer ( FontRendererPtr renderer ); +extern Bool FontFilePriorityRegisterRenderer ( FontRendererPtr renderer, + int priority ); +extern FontRendererPtr FontFileMatchRenderer ( char *fileName ); + +extern Bool FontFileAddScaledInstance ( FontEntryPtr entry, + FontScalablePtr vals, FontPtr pFont, + char *bitmapName ); +extern void FontFileSwitchStringsToBitmapPointers ( FontDirectoryPtr dir ); +extern void FontFileRemoveScaledInstance ( FontEntryPtr entry, FontPtr pFont ); +extern Bool FontFileCompleteXLFD ( FontScalablePtr vals, FontScalablePtr def ); +extern FontScaledPtr FontFileFindScaledInstance ( FontEntryPtr entry, + FontScalablePtr vals, + int noSpecificSize ); + +extern Bool FontFileRegisterBitmapSource ( FontPathElementPtr fpe ); +extern void FontFileUnregisterBitmapSource ( FontPathElementPtr fpe ); +extern void FontFileEmptyBitmapSource ( void ); +extern int FontFileMatchBitmapSource ( FontPathElementPtr fpe, + FontPtr *pFont, int flags, + FontEntryPtr entry, + FontNamePtr zeroPat, + FontScalablePtr vals, + fsBitmapFormat format, + fsBitmapFormatMask fmask, + Bool noSpecificSize ); + +extern int FontFileReadDirectory ( char *directory, FontDirectoryPtr *pdir ); +extern Bool FontFileDirectoryChanged ( FontDirectoryPtr dir ); + +#endif /* _FONTFILE_H_ */ diff --git a/nx-X11/lib/font/include/fntfilio.h b/nx-X11/lib/font/include/fntfilio.h new file mode 100644 index 000000000..f8e24f390 --- /dev/null +++ b/nx-X11/lib/font/include/fntfilio.h @@ -0,0 +1,56 @@ +/* $Xorg: fntfilio.h,v 1.4 2001/02/09 02:04:04 xorgcvs Exp $ */ + +/* + +Copyright 1991, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ +/* $XFree86: xc/lib/font/include/fntfilio.h,v 1.6 2001/10/31 22:50:26 tsi Exp $ */ + +/* + * Author: Keith Packard, MIT X Consortium + */ + +#ifndef _FNTFILIO_H_ +#define _FNTFILIO_H_ + +#include <X11/fonts/bufio.h> + +typedef BufFilePtr FontFilePtr; + +#define FontFileGetc(f) BufFileGet(f) +#define FontFilePutc(c,f) BufFilePut(c,f) +#define FontFileRead(f,b,n) BufFileRead(f,b,n) +#define FontFileWrite(f,b,n) BufFileWrite(f,b,n) +#define FontFileSkip(f,n) (BufFileSkip (f, n) != BUFFILEEOF) +#define FontFileSeek(f,n) (BufFileSeek (f,n,0) != BUFFILEEOF) + +#define FontFileEOF BUFFILEEOF + +extern FontFilePtr FontFileOpen ( const char *name ); +extern int FontFileClose ( FontFilePtr f ); +extern FontFilePtr FontFileOpenWrite ( const char *name ); +extern FontFilePtr FontFileOpenWriteFd ( int fd ); +extern FontFilePtr FontFileOpenFd ( int fd ); + +#endif /* _FNTFILIO_H_ */ diff --git a/nx-X11/lib/font/include/fntfilst.h b/nx-X11/lib/font/include/fntfilst.h new file mode 100644 index 000000000..1a71eae7a --- /dev/null +++ b/nx-X11/lib/font/include/fntfilst.h @@ -0,0 +1,198 @@ +/* $Xorg: fntfilst.h,v 1.5 2001/02/09 02:04:04 xorgcvs Exp $ */ + +/* + +Copyright 1991, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ +/* $XFree86: xc/lib/font/include/fntfilst.h,v 3.8 2002/12/09 17:30:00 dawes Exp $ */ + +/* + * Author: Keith Packard, MIT X Consortium + */ + +#ifndef _FONTFILEST_H_ +#define _FONTFILEST_H_ + +#ifndef FONTMODULE +#include <X11/Xos.h> +#endif +#ifndef XP_PSTEXT +#include <X11/fonts/fontmisc.h> +#endif +#include <X11/fonts/fontstruct.h> +#include <X11/fonts/fontxlfd.h> +#include <X11/fonts/fntfil.h> + +typedef struct _FontName { + char *name; + short length; + short ndashes; +} FontNameRec; + +typedef struct _FontScaled { + FontScalableRec vals; + FontEntryPtr bitmap; + FontPtr pFont; +} FontScaledRec; + +typedef struct _FontScalableExtra { + FontScalableRec defaults; + int numScaled; + int sizeScaled; + FontScaledPtr scaled; + pointer private; +} FontScalableExtraRec; + +typedef struct _FontScalableEntry { + FontRendererPtr renderer; + char *fileName; + FontScalableExtraPtr extra; +} FontScalableEntryRec; + +/* + * This "can't" work yet - the returned alias string must be permanent, + * but this layer would need to generate the appropriate name from the + * resolved scalable + the XLFD values passed in. XXX + */ + +typedef struct _FontScaleAliasEntry { + char *resolved; +} FontScaleAliasEntryRec; + +typedef struct _FontBitmapEntry { + FontRendererPtr renderer; + char *fileName; + FontPtr pFont; +} FontBitmapEntryRec; + +typedef struct _FontAliasEntry { + char *resolved; +} FontAliasEntryRec; + +typedef struct _FontBCEntry { + FontScalableRec vals; + FontEntryPtr entry; +} FontBCEntryRec; + +typedef struct _FontEntry { + FontNameRec name; + int type; + union _FontEntryParts { + FontScalableEntryRec scalable; + FontBitmapEntryRec bitmap; + FontAliasEntryRec alias; + FontBCEntryRec bc; + } u; +} FontEntryRec; + +typedef struct _FontTable { + int used; + int size; + FontEntryPtr entries; + Bool sorted; +} FontTableRec; + +typedef struct _FontDirectory { + char *directory; + unsigned long dir_mtime; + unsigned long alias_mtime; + FontTableRec scalable; + FontTableRec nonScalable; + char *attributes; +} FontDirectoryRec; + +/* Capability bits: for definition of capabilities bitmap in the + FontRendererRec to indicate support of XLFD enhancements */ + +#define CAP_MATRIX 0x1 +#define CAP_CHARSUBSETTING 0x2 + +typedef struct _FontRenderer { + char *fileSuffix; + int fileSuffixLen; + int (*OpenBitmap)(FontPathElementPtr /* fpe */, + FontPtr * /* pFont */, + int /* flags */, + FontEntryPtr /* entry */, + char * /* fileName */, + fsBitmapFormat /* format */, + fsBitmapFormatMask /* mask */, + FontPtr /* non_cachable_font */); + int (*OpenScalable)(FontPathElementPtr /* fpe */, + FontPtr * /* pFont */, + int /* flags */, + FontEntryPtr /* entry */, + char * /* fileName */, + FontScalablePtr /* vals */, + fsBitmapFormat /* format */, + fsBitmapFormatMask /* fmask */, + FontPtr /* non_cachable_font */); + int (*GetInfoBitmap)(FontPathElementPtr /* fpe */, + FontInfoPtr /* pFontInfo */, + FontEntryPtr /* entry */, + char * /*fileName */); + int (*GetInfoScalable)(FontPathElementPtr /* fpe */, + FontInfoPtr /* pFontInfo */, + FontEntryPtr /* entry */, + FontNamePtr /* fontName */, + char * /* fileName */, + FontScalablePtr /* vals */); + int number; + int capabilities; /* Bitmap components defined above */ +} FontRendererRec; + +typedef struct _FontRenders { + int number; + struct _FontRenderersElement { + /* In order to preserve backward compatibility, the + priority field is made invisible to renderers */ + FontRendererPtr renderer; + int priority; + } *renderers; +} FontRenderersRec, *FontRenderersPtr; + +typedef struct _BitmapInstance { + FontScalableRec vals; + FontBitmapEntryPtr bitmap; +} BitmapInstanceRec, *BitmapInstancePtr; + +typedef struct _BitmapScalablePrivate { + int numInstances; + BitmapInstancePtr instances; +} BitmapScalablePrivateRec, *BitmapScalablePrivatePtr; + +typedef struct _BitmapSources { + FontPathElementPtr *fpe; + int size; + int count; +} BitmapSourcesRec, *BitmapSourcesPtr; + +extern BitmapSourcesRec FontFileBitmapSources; + +/* Defines for FontFileFindNamesInScalableDir() behavior */ +#define NORMAL_ALIAS_BEHAVIOR 0 +#define LIST_ALIASES_AND_TARGET_NAMES (1<<0) +#define IGNORE_SCALABLE_ALIASES (1<<1) + +#endif /* _FONTFILEST_H_ */ diff --git a/nx-X11/lib/font/include/fontenc.h b/nx-X11/lib/font/include/fontenc.h new file mode 100644 index 000000000..09472cfc5 --- /dev/null +++ b/nx-X11/lib/font/include/fontenc.h @@ -0,0 +1,124 @@ +/* +Copyright (c) 1998-2001 by Juliusz Chroboczek + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +/* $XFree86: xc/lib/font/include/fontenc.h,v 1.7 2000/11/14 16:54:45 dawes Exp $ */ + +/* Header for backend-independent encoding code */ + +/* An encoding is identified with a name. An encoding contains some + global encoding data, such as its size, and a set of mappings. + Mappings are identified by their type and two integers, known as + pid and eid, the interpretation of which is type dependent. */ + +#ifndef _FONTENC_H +#define _FONTENC_H + +/* Encoding types. For future extensions, clients should be prepared + to ignore unknown encoding types. */ + +/* 0 is treated specially. */ + +#define FONT_ENCODING_UNICODE 1 +#define FONT_ENCODING_TRUETYPE 2 +#define FONT_ENCODING_POSTSCRIPT 3 + +/* This structure represents a mapping, either from numeric codes from + numeric codes, or from numeric codes to strings. */ + +/* It is expected that only one of `recode' and `name' will actually + be present. However, having both fields simplifies the interface + somewhat. */ + +typedef struct _FontMap { + int type; /* the type of the mapping */ + int pid, eid; /* the identification of the mapping */ + unsigned (*recode)(unsigned, void*); /* mapping function */ + char *(*name)(unsigned, void*); /* function returning glyph names */ + void *client_data; /* second parameter of the two above */ + struct _FontMap *next; /* link to next element in list */ + /* The following was added for version 0.3 of the font interface. */ + /* It should be kept at the end to preserve binary compatibility. */ + struct _FontEnc *encoding; +} FontMapRec, *FontMapPtr; + +/* This is the structure that holds all the info for one encoding. It + consists of a charset name, its size, and a linked list of mappings + like above. */ + +typedef struct _FontEnc { + char *name; /* the name of the encoding */ + char **aliases; /* its aliases, null terminated */ + int size; /* its size, either in bytes or rows */ + int row_size; /* the size of a row, or 0 if bytes */ + FontMapPtr mappings; /* linked list of mappings */ + struct _FontEnc *next; /* link to next element */ + /* the following two were added in version 0.2 of the font interface */ + /* they should be kept at the end to preserve binary compatibility */ + int first; /* first byte or row */ + int first_col; /* first column in each row */ +} FontEncRec, *FontEncPtr; + +typedef struct _FontMapReverse { + unsigned int (*reverse)(unsigned, void*); + void *data; +} FontMapReverseRec, *FontMapReversePtr; + + +/* Function prototypes */ + +/* extract an encoding name from an XLFD name. Returns a pointer to a + *static* buffer, or NULL */ +char *FontEncFromXLFD(const char*, int); + +/* find the encoding data for a given encoding name; second parameter + is the filename of the font for which the encoding is needed. + Returns NULL on failure. */ +FontEncPtr FontEncFind(const char*, const char*); + +/* Find a given mapping for an encoding. This is only a convenience + function, as clients are allowed to scavenge the data structures + themselves (as the TrueType backend does). */ + +FontMapPtr FontMapFind(FontEncPtr, int, int, int); + +/* Do both in a single step */ +FontMapPtr FontEncMapFind(const char *, int, int, int, const char *); + +/* Recode a code. Always succeeds. */ +unsigned FontEncRecode(unsigned, FontMapPtr); + +/* Return a name for a code. Returns a string or NULL. */ +char *FontEncName(unsigned, FontMapPtr); + +/* Return a pointer to the name of the system encodings directory. */ +/* This string is static and should not be modified. */ +char* FontEncDirectory(void); + +/* Identify an encoding file. If fileName doesn't exist, or is not an + encoding file, return NULL, otherwise returns a NULL-terminated + array of strings. */ +char **FontEncIdentify(const char *fileName); + +FontMapReversePtr FontMapReverse(FontMapPtr); + +void FontMapReverseFree(FontMapReversePtr); +#endif diff --git a/nx-X11/lib/font/include/fontencc.h b/nx-X11/lib/font/include/fontencc.h new file mode 100644 index 000000000..51e0e1440 --- /dev/null +++ b/nx-X11/lib/font/include/fontencc.h @@ -0,0 +1,36 @@ +/* +Copyright (c) 1998-2001 by Juliusz Chroboczek + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ +/* $XFree86$ */ + +/* Binary compatibility entry points. */ + +/* This file includes code to make modules compiled for earlier + versions of the fontenc interfaces link with this one. It does + *not* provide source compatibility, as many of the data structures + now have different names. */ + +extern char *font_encoding_from_xlfd(const char*, int); +extern unsigned font_encoding_recode(unsigned, FontEncPtr, FontMapPtr); +extern FontEncPtr font_encoding_find(const char*, const char*); +extern char *font_encoding_name(unsigned, FontEncPtr, FontMapPtr); +extern char **identifyEncodingFile(const char *fileName); + diff --git a/nx-X11/lib/font/include/fontmisc.h b/nx-X11/lib/font/include/fontmisc.h new file mode 100644 index 000000000..b7e359068 --- /dev/null +++ b/nx-X11/lib/font/include/fontmisc.h @@ -0,0 +1,133 @@ +/* $Xorg: fontmisc.h,v 1.4 2001/02/09 02:04:04 xorgcvs Exp $ */ + +/* + +Copyright 1991, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ +/* $XFree86: xc/lib/font/include/fontmisc.h,v 3.16 2001/12/14 19:56:54 dawes Exp $ */ + +/* + * Author: Keith Packard, MIT X Consortium + */ + +#ifndef _FONTMISC_H_ +#define _FONTMISC_H_ + +#ifndef FONTMODULE +#include <X11/Xfuncs.h> +#include <stdlib.h> +#include <stdio.h> + +#ifndef X_NOT_POSIX +#include <unistd.h> +#else +extern int close(); +#endif + +#endif /* FONTMODULE */ + +#include "X11/Xdefs.h" + + +#ifndef LSBFirst +#define LSBFirst 0 +#define MSBFirst 1 +#endif + +#ifndef None +#define None 0l +#endif + +#ifndef TRUE +#define TRUE 1 +#define FALSE 0 +#endif + +extern Atom MakeAtom ( char *string, unsigned len, int makeit ); +extern int ValidAtom ( Atom atom ); +extern char *NameForAtom (Atom atom); + +#ifndef _HAVE_XALLOC_DECLS +#define _HAVE_XALLOC_DECLS +extern pointer Xalloc(unsigned long); +extern pointer Xrealloc(pointer, unsigned long); +extern void Xfree(pointer); +extern pointer Xcalloc(unsigned long); +#endif +extern int f_strcasecmp(const char *s1, const char *s2); + +#ifndef xalloc +#define xalloc(n) Xalloc ((unsigned) n) +#define xfree(p) Xfree ((pointer) p) +#define xrealloc(p,n) Xrealloc ((pointer)p,n) +#define xcalloc(n,s) Xcalloc((unsigned) n * (unsigned) s) +#endif +#define lowbit(x) ((x) & (~(x) + 1)) + +#undef assert +#define assert(x) ((void)0) + +#ifndef strcasecmp +#if defined(NEED_STRCASECMP) && !defined(FONTMODULE) +#define strcasecmp(s1,s2) f_strcasecmp(s1,s2) +#endif +#endif + +extern void +BitOrderInvert( + register unsigned char *, + register int +); + +extern void +TwoByteSwap( + register unsigned char *, + register int +); + +extern void +FourByteSwap( + register unsigned char *, + register int +); + +extern int +RepadBitmap ( + char*, + char*, + unsigned, + unsigned, + int, + int +); + +extern void CopyISOLatin1Lowered( + char * /*dest*/, + char * /*source*/, + int /*length*/ +); + +extern void register_fpe_functions(void); + +#endif /* _FONTMISC_H_ */ diff --git a/nx-X11/lib/font/include/fontmod.h b/nx-X11/lib/font/include/fontmod.h new file mode 100644 index 000000000..42d277fd4 --- /dev/null +++ b/nx-X11/lib/font/include/fontmod.h @@ -0,0 +1,16 @@ +/* $XFree86: xc/lib/font/include/fontmod.h,v 1.2 1998/07/25 06:57:09 dawes Exp $ */ + +#ifndef _FONTMOD_H_ +#define _FONTMOD_H_ + +typedef void (*InitFont)(void); + +typedef struct { + InitFont initFunc; + char * name; + pointer module; +} FontModule; + +extern FontModule *FontModuleList; + +#endif /* _FONTMOD_H_ */ diff --git a/nx-X11/lib/font/include/fontshow.h b/nx-X11/lib/font/include/fontshow.h new file mode 100644 index 000000000..5bb48fe18 --- /dev/null +++ b/nx-X11/lib/font/include/fontshow.h @@ -0,0 +1,37 @@ +/* $Xorg: fontshow.h,v 1.4 2001/02/09 02:04:04 xorgcvs Exp $ */ + +/* + +Copyright 1990, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ + +/* + * Author: Keith Packard, MIT X Consortium + */ + +#define FONT_SHOW_INFO (1<<0) +#define FONT_SHOW_PROPS (1<<1) +#define FONT_SHOW_METRICS (1<<2) +#define FONT_SHOW_GLYPHS (1<<3) +#define FONT_SHOW_ALL (FONT_SHOW_INFO|FONT_SHOW_PROPS|FONT_SHOW_GLYPHS) diff --git a/nx-X11/lib/font/include/fontutil.h b/nx-X11/lib/font/include/fontutil.h new file mode 100644 index 000000000..9a73eaa47 --- /dev/null +++ b/nx-X11/lib/font/include/fontutil.h @@ -0,0 +1,26 @@ +/* $XFree86: xc/lib/font/include/fontutil.h,v 1.1 1999/03/14 11:17:49 dawes Exp $ */ + +#ifndef _FONTUTIL_H_ +#define _FONTUTIL_H_ + +#include <X11/fonts/FSproto.h> + +extern int FontCouldBeTerminal(FontInfoPtr); +extern int CheckFSFormat(fsBitmapFormat, fsBitmapFormatMask, int *, int *, + int *, int *, int *); +extern void FontComputeInfoAccelerators(FontInfoPtr); + +extern void GetGlyphs ( FontPtr font, unsigned long count, + unsigned char *chars, FontEncoding fontEncoding, + unsigned long *glyphcount, CharInfoPtr *glyphs ); +extern void QueryGlyphExtents ( FontPtr pFont, CharInfoPtr *charinfo, + unsigned long count, ExtentInfoRec *info ); +extern Bool QueryTextExtents ( FontPtr pFont, unsigned long count, + unsigned char *chars, ExtentInfoRec *info ); +extern Bool ParseGlyphCachingMode ( char *str ); +extern void InitGlyphCaching ( void ); +extern void SetGlyphCachingMode ( int newmode ); +extern int add_range ( fsRange *newrange, int *nranges, fsRange **range, + Bool charset_subset ); + +#endif /* _FONTUTIL_H_ */ diff --git a/nx-X11/lib/font/include/fontxlfd.h b/nx-X11/lib/font/include/fontxlfd.h new file mode 100644 index 000000000..e87b93143 --- /dev/null +++ b/nx-X11/lib/font/include/fontxlfd.h @@ -0,0 +1,100 @@ +/* $Xorg: fontxlfd.h,v 1.4 2001/02/09 02:04:04 xorgcvs Exp $ */ + +/* + +Copyright 1990, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + +*/ +/* $XFree86: xc/lib/font/include/fontxlfd.h,v 1.5 2001/01/17 19:43:32 dawes Exp $ */ + +/* + * Author: Keith Packard, MIT X Consortium + */ + +#ifndef _FONTXLFD_H_ +#define _FONTXLFD_H_ + +#include <X11/fonts/FSproto.h> + +/* Constants for values_supplied bitmap */ + +#define SIZE_SPECIFY_MASK 0xf + +#define PIXELSIZE_MASK 0x3 +#define PIXELSIZE_UNDEFINED 0 +#define PIXELSIZE_SCALAR 0x1 +#define PIXELSIZE_ARRAY 0x2 +#define PIXELSIZE_SCALAR_NORMALIZED 0x3 /* Adjusted for resolution */ + +#define POINTSIZE_MASK 0xc +#define POINTSIZE_UNDEFINED 0 +#define POINTSIZE_SCALAR 0x4 +#define POINTSIZE_ARRAY 0x8 + +#define PIXELSIZE_WILDCARD 0x10 +#define POINTSIZE_WILDCARD 0x20 + +#define ENHANCEMENT_SPECIFY_MASK 0x40 + +#define CHARSUBSET_SPECIFIED 0x40 + +#define EPS 1.0e-20 +#define XLFD_NDIGITS 3 /* Round numbers in pixel and + point arrays to this many + digits for repeatability */ + +typedef struct _FontScalable { + int values_supplied; /* Bitmap identifying what advanced + capabilities or enhancements + were specified in the font name */ + double pixel_matrix[4]; + double point_matrix[4]; + + /* Pixel and point fields are deprecated in favor of the + transformation matrices. They are provided and filled in for the + benefit of rasterizers that do not handle the matrices. */ + + int pixel, + point; + + int x, + y, + width; + char *xlfdName; + int nranges; + fsRange *ranges; +} FontScalableRec, *FontScalablePtr; + + +extern double xlfd_round_double ( double x ); +extern Bool FontParseXLFDName ( char *fname, FontScalablePtr vals, int subst ); +extern fsRange *FontParseRanges ( char *name, int *nranges ); + +#define FONT_XLFD_REPLACE_NONE 0 +#define FONT_XLFD_REPLACE_STAR 1 +#define FONT_XLFD_REPLACE_ZERO 2 +#define FONT_XLFD_REPLACE_VALUE 3 + +#endif /* _FONTXLFD_H_ */ diff --git a/nx-X11/lib/font/stubs/Imakefile b/nx-X11/lib/font/stubs/Imakefile new file mode 100644 index 000000000..555bbf614 --- /dev/null +++ b/nx-X11/lib/font/stubs/Imakefile @@ -0,0 +1,25 @@ +XCOMM $XFree86: xc/lib/font/stubs/Imakefile,v 1.3 1999/12/15 01:14:35 robin Exp $ + +#include <Server.tmpl> + +INCLUDES = -I$(FONTINCSRC) -I../include -I$(XINCLUDESRC) +SRCS = cauthgen.c csignal.c delfntcid.c errorf.c fatalerror.c \ + findoldfnt.c getcres.c getdefptsize.c getnewfntcid.c gettime.c \ + initfshdl.c regfpefunc.c rmfshdl.c servclient.c setfntauth.c \ + stfntcfnt.c xpstubs.c +OBJS = cauthgen.o csignal.o delfntcid.o errorf.o fatalerror.o \ + findoldfnt.o getcres.o getdefptsize.o getnewfntcid.o gettime.o \ + initfshdl.o regfpefunc.o rmfshdl.o servclient.o setfntauth.o \ + stfntcfnt.o xpstubs.o + +#undef _LinkBuildLibrary +#define _LinkBuildLibrary(lib) LinkBuildLibrary(lib) + +NormalLibraryObjectRule() +NormalLibraryTarget(fntstubs,$(OBJS)) +LintLibraryTarget(fntstubs,$(SRCS)) +InstallLibrary(fntstubs,$(USRLIBDIR)) +NormalLintTarget($(SRCS)) +DependTarget() + +/* end of file */ diff --git a/nx-X11/lib/font/stubs/cauthgen.c b/nx-X11/lib/font/stubs/cauthgen.c new file mode 100644 index 000000000..dec438d08 --- /dev/null +++ b/nx-X11/lib/font/stubs/cauthgen.c @@ -0,0 +1,14 @@ +/* $XFree86$ */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include "stubs.h" + +int +client_auth_generation(ClientPtr client) +{ + return 0; +} + +/* end of file */ diff --git a/nx-X11/lib/font/stubs/csignal.c b/nx-X11/lib/font/stubs/csignal.c new file mode 100644 index 000000000..c957eb837 --- /dev/null +++ b/nx-X11/lib/font/stubs/csignal.c @@ -0,0 +1,14 @@ +/* $XFree86$ */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include "stubs.h" + +Bool +ClientSignal(ClientPtr client) +{ + return True; +} + +/* end of file */ diff --git a/nx-X11/lib/font/stubs/delfntcid.c b/nx-X11/lib/font/stubs/delfntcid.c new file mode 100644 index 000000000..af5c0a881 --- /dev/null +++ b/nx-X11/lib/font/stubs/delfntcid.c @@ -0,0 +1,13 @@ +/* $XFree86$ */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include "stubs.h" + +void +DeleteFontClientID(Font id) +{ +} + +/* end of file */ diff --git a/nx-X11/lib/font/stubs/errorf.c b/nx-X11/lib/font/stubs/errorf.c new file mode 100644 index 000000000..52c6042a6 --- /dev/null +++ b/nx-X11/lib/font/stubs/errorf.c @@ -0,0 +1,13 @@ +/* $XFree86: xc/lib/font/stubs/errorf.c,v 1.1 1999/01/11 05:13:19 dawes Exp $ */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include "stubs.h" + +void +ErrorF(const char *f, ...) +{ +} + +/* end of file */ diff --git a/nx-X11/lib/font/stubs/fatalerror.c b/nx-X11/lib/font/stubs/fatalerror.c new file mode 100644 index 000000000..7dff1704d --- /dev/null +++ b/nx-X11/lib/font/stubs/fatalerror.c @@ -0,0 +1,13 @@ +/* $XFree86: xc/lib/font/stubs/fatalerror.c,v 1.1 1999/01/11 05:13:19 dawes Exp $ */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include "stubs.h" + +void +FatalError(const char *f, ...) +{ +} + +/* end of file */ diff --git a/nx-X11/lib/font/stubs/findoldfnt.c b/nx-X11/lib/font/stubs/findoldfnt.c new file mode 100644 index 000000000..218ecd479 --- /dev/null +++ b/nx-X11/lib/font/stubs/findoldfnt.c @@ -0,0 +1,14 @@ +/* $XFree86$ */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include "stubs.h" + +FontPtr +find_old_font(FSID id) +{ + return (FontPtr)NULL; +} + +/* end of file */ diff --git a/nx-X11/lib/font/stubs/getcres.c b/nx-X11/lib/font/stubs/getcres.c new file mode 100644 index 000000000..da0de9174 --- /dev/null +++ b/nx-X11/lib/font/stubs/getcres.c @@ -0,0 +1,14 @@ +/* $XFree86$ */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include "stubs.h" + +FontResolutionPtr +GetClientResolutions(int *num) +{ + return (FontResolutionPtr) 0; +} + +/* end of file */ diff --git a/nx-X11/lib/font/stubs/getdefptsize.c b/nx-X11/lib/font/stubs/getdefptsize.c new file mode 100644 index 000000000..10a46c86e --- /dev/null +++ b/nx-X11/lib/font/stubs/getdefptsize.c @@ -0,0 +1,14 @@ +/* $XFree86$ */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include "stubs.h" + +int +GetDefaultPointSize(void) +{ + return 0; +} + +/* end of file */ diff --git a/nx-X11/lib/font/stubs/getnewfntcid.c b/nx-X11/lib/font/stubs/getnewfntcid.c new file mode 100644 index 000000000..5a1e9270a --- /dev/null +++ b/nx-X11/lib/font/stubs/getnewfntcid.c @@ -0,0 +1,14 @@ +/* $XFree86$ */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include "stubs.h" + +Font +GetNewFontClientID(void) +{ + return (Font)0; +} + +/* end of file */ diff --git a/nx-X11/lib/font/stubs/gettime.c b/nx-X11/lib/font/stubs/gettime.c new file mode 100644 index 000000000..60a4e3951 --- /dev/null +++ b/nx-X11/lib/font/stubs/gettime.c @@ -0,0 +1,14 @@ +/* $XFree86$ */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include "stubs.h" + +unsigned long +GetTimeInMillis (void) +{ + return 0; +} + +/* end of file */ diff --git a/nx-X11/lib/font/stubs/initfshdl.c b/nx-X11/lib/font/stubs/initfshdl.c new file mode 100644 index 000000000..15a337a29 --- /dev/null +++ b/nx-X11/lib/font/stubs/initfshdl.c @@ -0,0 +1,15 @@ +/* $XFree86: xc/lib/font/stubs/initfshdl.c,v 1.1 1999/01/11 05:13:20 dawes Exp $ */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include "stubs.h" + +int +init_fs_handlers(FontPathElementPtr fpe, + BlockHandlerProcPtr block_handler) +{ + return Successful; +} + +/* end of file */ diff --git a/nx-X11/lib/font/stubs/regfpefunc.c b/nx-X11/lib/font/stubs/regfpefunc.c new file mode 100644 index 000000000..d6fcf3be3 --- /dev/null +++ b/nx-X11/lib/font/stubs/regfpefunc.c @@ -0,0 +1,28 @@ +/* $XFree86: xc/lib/font/stubs/regfpefunc.c,v 1.1 1999/01/11 05:13:20 dawes Exp $ */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include "stubs.h" + +int +RegisterFPEFunctions(NameCheckFunc name_func, + InitFpeFunc init_func, + FreeFpeFunc free_func, + ResetFpeFunc reset_func, + OpenFontFunc open_func, + CloseFontFunc close_func, + ListFontsFunc list_func, + StartLfwiFunc start_lfwi_func, + NextLfwiFunc next_lfwi_func, + WakeupFpeFunc wakeup_func, + ClientDiedFunc client_died, + LoadGlyphsFunc load_glyphs, + StartLaFunc start_list_alias_func, + NextLaFunc next_list_alias_func, + SetPathFunc set_path_func) +{ + return 0; +} + +/* end of file */ diff --git a/nx-X11/lib/font/stubs/rmfshdl.c b/nx-X11/lib/font/stubs/rmfshdl.c new file mode 100644 index 000000000..ae0ab7863 --- /dev/null +++ b/nx-X11/lib/font/stubs/rmfshdl.c @@ -0,0 +1,15 @@ +/* $XFree86: xc/lib/font/stubs/rmfshdl.c,v 1.1 1999/01/11 05:13:21 dawes Exp $ */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include "stubs.h" + +void +remove_fs_handlers(FontPathElementPtr fpe, + BlockHandlerProcPtr blockHandler, + Bool all) +{ +} + +/* end of file */ diff --git a/nx-X11/lib/font/stubs/servclient.c b/nx-X11/lib/font/stubs/servclient.c new file mode 100644 index 000000000..25c853f87 --- /dev/null +++ b/nx-X11/lib/font/stubs/servclient.c @@ -0,0 +1,3 @@ +/* $XFree86$ */ + +void *serverClient = 0; diff --git a/nx-X11/lib/font/stubs/setfntauth.c b/nx-X11/lib/font/stubs/setfntauth.c new file mode 100644 index 000000000..843f155e5 --- /dev/null +++ b/nx-X11/lib/font/stubs/setfntauth.c @@ -0,0 +1,14 @@ +/* $XFree86$ */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include "stubs.h" + +int +set_font_authorizations(char **authorizations, int *authlen, ClientPtr client) +{ + return 0; +} + +/* end of file */ diff --git a/nx-X11/lib/font/stubs/stfntcfnt.c b/nx-X11/lib/font/stubs/stfntcfnt.c new file mode 100644 index 000000000..c062677f6 --- /dev/null +++ b/nx-X11/lib/font/stubs/stfntcfnt.c @@ -0,0 +1,14 @@ +/* $XFree86$ */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include "stubs.h" + +int +StoreFontClientFont(FontPtr pfont, Font id) +{ + return 0; +} + +/* end of file */ diff --git a/nx-X11/lib/font/stubs/stubs.h b/nx-X11/lib/font/stubs/stubs.h new file mode 100644 index 000000000..d687a77e3 --- /dev/null +++ b/nx-X11/lib/font/stubs/stubs.h @@ -0,0 +1,27 @@ +/* $XFree86: xc/lib/font/stubs/stubs.h,v 1.3 1999/12/15 01:14:36 robin Exp $ */ + +/* This directory includes dummy entry for bdftopcf and mkfontdir */ + +#include <stdio.h> +#include <X11/fonts/fntfilst.h> +#include <X11/fonts/font.h> + + +#ifndef True +#define True (-1) +#endif +#ifndef False +#define False (0) +#endif + +extern FontPtr find_old_font ( FSID id ); +extern int set_font_authorizations ( char **authorizations, + int *authlen, + ClientPtr client ); + +extern unsigned long GetTimeInMillis (void); + +extern void ErrorF(const char *format, ...); +extern void FatalError(const char *format, ...); + +/* end of file */ diff --git a/nx-X11/lib/font/stubs/xpstubs.c b/nx-X11/lib/font/stubs/xpstubs.c new file mode 100644 index 000000000..444915367 --- /dev/null +++ b/nx-X11/lib/font/stubs/xpstubs.c @@ -0,0 +1,24 @@ +/* $XFree86$ */ + +/* + stub for XpClient* functions. +*/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include "stubs.h" + +Bool +XpClientIsBitmapClient(ClientPtr client) +{ + return True; +} + +Bool +XpClientIsPrintClient(ClientPtr client, FontPathElementPtr fpe) +{ + return False; +} + +/* end of file */ diff --git a/nx-X11/lib/font/util/Imakefile b/nx-X11/lib/font/util/Imakefile new file mode 100644 index 000000000..6c318ba7f --- /dev/null +++ b/nx-X11/lib/font/util/Imakefile @@ -0,0 +1,43 @@ +XCOMM $Xorg: Imakefile,v 1.3 2000/08/17 19:46:39 cpqbld Exp $ + + + + +XCOMM $XFree86: xc/lib/font/util/Imakefile,v 1.6 2000/12/07 16:40:30 dawes Exp $ + +#include <Server.tmpl> + + INCLUDES = -I$(FONTINCSRC) -I../include + HEADERS = +#ifdef FontFormatDefines + FORMAT_DEFS = FontFormatDefines +#endif + +#if defined(SunArchitecture) && (OSMajorVersion == 5) && (OSMinorVersion <= 6) + /* Work around a problem with __ctype being a "relocation against + allocatable but non-writable section" on Solaris 2.6. Hopefully + it doesn't break anything. */ + SYS_DEFINES = -D__XPG4_CHAR_CLASS__ +#endif + + + DEFINES = StrcasecmpDefines $(SYS_DEFINES) $(INTERNALDEFINES) + + SRCS = utilbitmap.c fontnames.c fontutil.c fontxlfd.c format.c \ + fontaccel.c atom.c miscutil.c private.c patcache.c + + OBJS = utilbitmap.o fontnames.o fontutil.o fontxlfd.o format.o \ + fontaccel.o atom.o miscutil.o private.o patcache.o + +#define DoNormalLib NormalLibFont +#define DoSharedLib SharedLibFont +#define DoDebugLib DebugLibFont +#define DoProfileLib ProfileLibFont +#include <Library.tmpl> +LibraryObjectRule() + +SubdirLibraryRule($(OBJS)) +NormalLintTarget($(SRCS)) + +DependTarget() + diff --git a/nx-X11/lib/font/util/atom.c b/nx-X11/lib/font/util/atom.c new file mode 100644 index 000000000..942ea0d46 --- /dev/null +++ b/nx-X11/lib/font/util/atom.c @@ -0,0 +1,233 @@ +/* $Xorg: atom.c,v 1.5 2001/02/09 02:04:04 xorgcvs Exp $ */ + +/* + +Copyright 1990, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ +/* $XFree86: xc/lib/font/util/atom.c,v 1.9 2002/09/19 13:22:00 tsi Exp $ */ + +/* + * Author: Keith Packard, MIT X Consortium + */ + +/* lame atom replacement routines for font applications */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <X11/fonts/fontmisc.h> + +typedef struct _AtomList { + char *name; + int len; + int hash; + Atom atom; +} AtomListRec, *AtomListPtr; + +static AtomListPtr *hashTable; + +static int hashSize, hashUsed; +static int hashMask; +static int rehash; + +static AtomListPtr *reverseMap; +static int reverseMapSize; +static Atom lastAtom; + +static int +Hash(char *string, int len) +{ + int h; + + h = 0; + while (len--) + h = (h << 3) ^ *string++; + if (h < 0) + return -h; + return h; +} + +static int +ResizeHashTable (void) +{ + int newHashSize; + int newHashMask; + AtomListPtr *newHashTable; + int i; + int h; + int newRehash; + int r; + + if (hashSize == 0) + newHashSize = 1024; + else + newHashSize = hashSize * 2; + newHashTable = (AtomListPtr *) xalloc (newHashSize * sizeof (AtomListPtr)); + if (!newHashTable) { + fprintf(stderr, "ResizeHashTable(): Error: Couldn't allocate" + " newHashTable (%ld)\n", + newHashSize * (unsigned long)sizeof (AtomListPtr)); + return FALSE; + } + bzero ((char *) newHashTable, newHashSize * sizeof (AtomListPtr)); + newHashMask = newHashSize - 1; + newRehash = (newHashMask - 2); + for (i = 0; i < hashSize; i++) + { + if (hashTable[i]) + { + h = (hashTable[i]->hash) & newHashMask; + if (newHashTable[h]) + { + r = hashTable[i]->hash % newRehash | 1; + do { + h += r; + if (h >= newHashSize) + h -= newHashSize; + } while (newHashTable[h]); + } + newHashTable[h] = hashTable[i]; + } + } + xfree (hashTable); + hashTable = newHashTable; + hashSize = newHashSize; + hashMask = newHashMask; + rehash = newRehash; + return TRUE; +} + +static int +ResizeReverseMap (void) +{ + int ret = TRUE; + if (reverseMapSize == 0) + reverseMapSize = 1000; + else + reverseMapSize *= 2; + reverseMap = (AtomListPtr *) xrealloc (reverseMap, reverseMapSize * sizeof (AtomListPtr)); + if (!reverseMap) { + fprintf(stderr, "ResizeReverseMap(): Error: Couldn't reallocate" + " reverseMap (%ld)\n", + reverseMapSize * (unsigned long)sizeof(AtomListPtr)); + ret = FALSE; + } + return ret; +} + +static int +NameEqual (const char *a, const char *b, int l) +{ + while (l--) + if (*a++ != *b++) + return FALSE; + return TRUE; +} + +Atom +MakeAtom(char *string, unsigned len, int makeit) +{ + AtomListPtr a; + int hash; + int h = 0; + int r; + + hash = Hash (string, len); + if (hashTable) + { + h = hash & hashMask; + if (hashTable[h]) + { + if (hashTable[h]->hash == hash && hashTable[h]->len == len && + NameEqual (hashTable[h]->name, string, len)) + { + return hashTable[h]->atom; + } + r = (hash % rehash) | 1; + for (;;) + { + h += r; + if (h >= hashSize) + h -= hashSize; + if (!hashTable[h]) + break; + if (hashTable[h]->hash == hash && hashTable[h]->len == len && + NameEqual (hashTable[h]->name, string, len)) + { + return hashTable[h]->atom; + } + } + } + } + if (!makeit) + return None; + a = (AtomListPtr) xalloc (sizeof (AtomListRec) + len + 1); + if (a == NULL) { + fprintf(stderr, "MakeAtom(): Error: Couldn't allocate AtomListRec" + " (%ld)\n", (unsigned long)sizeof (AtomListRec) + len + 1); + return None; + } + a->name = (char *) (a + 1); + a->len = len; + strncpy (a->name, string, len); + a->name[len] = '\0'; + a->atom = ++lastAtom; + a->hash = hash; + if (hashUsed >= hashSize / 2) + { + ResizeHashTable (); + h = hash & hashMask; + if (hashTable[h]) + { + r = (hash % rehash) | 1; + do { + h += r; + if (h >= hashSize) + h -= hashSize; + } while (hashTable[h]); + } + } + hashTable[h] = a; + hashUsed++; + if (reverseMapSize <= a->atom) { + if (!ResizeReverseMap()) + return None; + } + reverseMap[a->atom] = a; + return a->atom; +} + +int +ValidAtom(Atom atom) +{ + return (atom != None) && (atom <= lastAtom); +} + +char * +NameForAtom(Atom atom) +{ + if (atom != None && atom <= lastAtom) + return reverseMap[atom]->name; + return NULL; +} diff --git a/nx-X11/lib/font/util/fontaccel.c b/nx-X11/lib/font/util/fontaccel.c new file mode 100644 index 000000000..c37f69a39 --- /dev/null +++ b/nx-X11/lib/font/util/fontaccel.c @@ -0,0 +1,107 @@ +/* $Xorg: fontaccel.c,v 1.4 2001/02/09 02:04:04 xorgcvs Exp $ */ + +/* + +Copyright 1990, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + +*/ +/* $XFree86: xc/lib/font/util/fontaccel.c,v 1.6 2001/01/17 19:43:33 dawes Exp $ */ + +/* + * Author: Keith Packard, MIT X Consortium + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <X11/fonts/fontmisc.h> +#include <X11/fonts/fontstruct.h> +#include <X11/fonts/fontutil.h> + +void +FontComputeInfoAccelerators(FontInfoPtr pFontInfo) +{ + pFontInfo->noOverlap = FALSE; + if (pFontInfo->maxOverlap <= pFontInfo->minbounds.leftSideBearing) + pFontInfo->noOverlap = TRUE; + + if ((pFontInfo->minbounds.ascent == pFontInfo->maxbounds.ascent) && + (pFontInfo->minbounds.descent == pFontInfo->maxbounds.descent) && + (pFontInfo->minbounds.leftSideBearing == + pFontInfo->maxbounds.leftSideBearing) && + (pFontInfo->minbounds.rightSideBearing == + pFontInfo->maxbounds.rightSideBearing) && + (pFontInfo->minbounds.characterWidth == + pFontInfo->maxbounds.characterWidth) && + (pFontInfo->minbounds.attributes == pFontInfo->maxbounds.attributes)) { + pFontInfo->constantMetrics = TRUE; + if ((pFontInfo->maxbounds.leftSideBearing == 0) && + (pFontInfo->maxbounds.rightSideBearing == + pFontInfo->maxbounds.characterWidth) && + (pFontInfo->maxbounds.ascent == pFontInfo->fontAscent) && + (pFontInfo->maxbounds.descent == pFontInfo->fontDescent)) + pFontInfo->terminalFont = TRUE; + else + pFontInfo->terminalFont = FALSE; + } else { + pFontInfo->constantMetrics = FALSE; + pFontInfo->terminalFont = FALSE; + } + if (pFontInfo->minbounds.characterWidth == pFontInfo->maxbounds.characterWidth) + pFontInfo->constantWidth = TRUE; + else + pFontInfo->constantWidth = FALSE; + + if ((pFontInfo->minbounds.leftSideBearing >= 0) && + (pFontInfo->maxOverlap <= 0) && + (pFontInfo->minbounds.ascent >= -pFontInfo->fontDescent) && + (pFontInfo->maxbounds.ascent <= pFontInfo->fontAscent) && + (-pFontInfo->minbounds.descent <= pFontInfo->fontAscent) && + (pFontInfo->maxbounds.descent <= pFontInfo->fontDescent)) + pFontInfo->inkInside = TRUE; + else + pFontInfo->inkInside = FALSE; +} + +int +FontCouldBeTerminal(FontInfoPtr pFontInfo) +{ + if ((pFontInfo->minbounds.leftSideBearing >= 0) && + (pFontInfo->maxbounds.rightSideBearing <= pFontInfo->maxbounds.characterWidth) && + (pFontInfo->minbounds.characterWidth == pFontInfo->maxbounds.characterWidth) && + (pFontInfo->maxbounds.ascent <= pFontInfo->fontAscent) && + (pFontInfo->maxbounds.descent <= pFontInfo->fontDescent) && + (pFontInfo->maxbounds.leftSideBearing != 0 || + pFontInfo->minbounds.rightSideBearing != pFontInfo->minbounds.characterWidth || + pFontInfo->minbounds.ascent != pFontInfo->fontAscent || + pFontInfo->minbounds.descent != pFontInfo->fontDescent)) { + /* blow off font with nothing but a SPACE */ + if (pFontInfo->maxbounds.ascent == 0 && + pFontInfo->maxbounds.descent == 0) + return FALSE; + return TRUE; + } + return FALSE; +} diff --git a/nx-X11/lib/font/util/fontnames.c b/nx-X11/lib/font/util/fontnames.c new file mode 100644 index 000000000..2d3a51752 --- /dev/null +++ b/nx-X11/lib/font/util/fontnames.c @@ -0,0 +1,123 @@ +/* $Xorg: fontnames.c,v 1.4 2001/02/09 02:04:04 xorgcvs Exp $ */ + +/* + +Copyright 1991, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + +*/ +/* $XFree86: xc/lib/font/util/fontnames.c,v 1.4 2001/01/17 19:43:33 dawes Exp $ */ + +/* + * Author: Keith Packard, MIT X Consortium + * + * @(#)fontnames.c 3.1 91/04/10 + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <X11/fonts/fontmisc.h> +#include <X11/fonts/fontstruct.h> + +void +FreeFontNames(FontNamesPtr pFN) +{ + int i; + + if (!pFN) + return; + for (i = 0; i < pFN->nnames; i++) { + xfree(pFN->names[i]); + } + xfree(pFN->names); + xfree(pFN->length); + xfree(pFN); +} + +FontNamesPtr +MakeFontNamesRecord(unsigned int size) +{ + FontNamesPtr pFN; + + pFN = (FontNamesPtr) xalloc(sizeof(FontNamesRec)); + if (pFN) { + pFN->nnames = 0; + pFN->size = size; + if (size) + { + pFN->length = (int *) xalloc(size * sizeof(int)); + pFN->names = (char **) xalloc(size * sizeof(char *)); + if (!pFN->length || !pFN->names) { + xfree(pFN->length); + xfree(pFN->names); + xfree(pFN); + pFN = (FontNamesPtr) 0; + } + } + else + { + pFN->length = 0; + pFN->names = 0; + } + } + return pFN; +} + +int +AddFontNamesName(FontNamesPtr names, char *name, int length) +{ + int index = names->nnames; + char *nelt; + + nelt = (char *) xalloc(length + 1); + if (!nelt) + return AllocError; + if (index >= names->size) { + int size = names->size << 1; + int *nlength; + char **nnames; + + if (size == 0) + size = 8; + nlength = (int *) xrealloc(names->length, size * sizeof(int)); + nnames = (char **) xrealloc(names->names, size * sizeof(char *)); + if (nlength && nnames) { + names->size = size; + names->length = nlength; + names->names = nnames; + } else { + xfree(nelt); + xfree(nlength); + xfree(nnames); + return AllocError; + } + } + names->length[index] = length; + names->names[index] = nelt; + strncpy(nelt, name, length); + nelt[length] = '\0'; + names->nnames++; + return Successful; +} diff --git a/nx-X11/lib/font/util/fontutil.c b/nx-X11/lib/font/util/fontutil.c new file mode 100644 index 000000000..05fe5c2f2 --- /dev/null +++ b/nx-X11/lib/font/util/fontutil.c @@ -0,0 +1,443 @@ +/* $Xorg: fontutil.c,v 1.4 2001/02/09 02:04:04 xorgcvs Exp $ */ + +/* + +Copyright 1991, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + +*/ +/* $XFree86: xc/lib/font/util/fontutil.c,v 3.6 2001/10/28 03:32:46 tsi Exp $ */ + +/* + * Author: Keith Packard, MIT X Consortium + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <X11/fonts/fontmisc.h> +#include <X11/fonts/fontstruct.h> +#include <X11/fonts/FSproto.h> +#include <X11/fonts/fontutil.h> + +/* Define global here... doesn't hurt the servers, and avoids + unresolved references in font clients. */ + +static int defaultGlyphCachingMode = DEFAULT_GLYPH_CACHING_MODE; +int glyphCachingMode = DEFAULT_GLYPH_CACHING_MODE; + +void +GetGlyphs(FontPtr font, + unsigned long count, + unsigned char *chars, + FontEncoding fontEncoding, + unsigned long *glyphcount, /* RETURN */ + CharInfoPtr *glyphs) /* RETURN */ +{ + (*font->get_glyphs) (font, count, chars, fontEncoding, glyphcount, glyphs); +} + +#define MIN(a,b) ((a)<(b)?(a):(b)) +#define MAX(a,b) ((a)>(b)?(a):(b)) + +void +QueryGlyphExtents(FontPtr pFont, + CharInfoPtr *charinfo, + unsigned long count, + ExtentInfoRec *info) +{ + register unsigned long i; + xCharInfo *pCI; + + info->drawDirection = pFont->info.drawDirection; + + info->fontAscent = pFont->info.fontAscent; + info->fontDescent = pFont->info.fontDescent; + + if (count != 0) { + + pCI = &((*charinfo)->metrics); charinfo++; + /* ignore nonexisting characters when calculating text extents */ + if ( !((pCI->characterWidth == 0) + && (pCI->rightSideBearing == 0) + && (pCI->leftSideBearing == 0) + && (pCI->ascent == 0) + && (pCI->descent == 0)) ) { + info->overallAscent = pCI->ascent; + info->overallDescent = pCI->descent; + info->overallLeft = pCI->leftSideBearing; + info->overallRight = pCI->rightSideBearing; + info->overallWidth = pCI->characterWidth; + } + + if (pFont->info.constantMetrics && pFont->info.noOverlap) { + info->overallWidth *= count; + info->overallRight += (info->overallWidth - + pCI->characterWidth); + } else { + for (i = 1; i < count; i++) { + pCI = &((*charinfo)->metrics); charinfo++; + /* ignore nonexisting characters when calculating extents */ + if ( !((pCI->characterWidth == 0) + && (pCI->rightSideBearing == 0) + && (pCI->leftSideBearing == 0) + && (pCI->ascent == 0) + && (pCI->descent == 0)) ) { + info->overallAscent = MAX( + info->overallAscent, + pCI->ascent); + info->overallDescent = MAX( + info->overallDescent, + pCI->descent); + info->overallLeft = MIN( + info->overallLeft, + info->overallWidth + pCI->leftSideBearing); + info->overallRight = MAX( + info->overallRight, + info->overallWidth + pCI->rightSideBearing); + /* + * yes, this order is correct; overallWidth IS incremented + * last + */ + info->overallWidth += pCI->characterWidth; + } + } + } + } else { + info->overallAscent = 0; + info->overallDescent = 0; + info->overallWidth = 0; + info->overallLeft = 0; + info->overallRight = 0; + } +} + +Bool +QueryTextExtents(FontPtr pFont, + unsigned long count, + unsigned char *chars, + ExtentInfoRec *info) +{ + xCharInfo **charinfo; + unsigned long n; + FontEncoding encoding; + int cm; + int i; + unsigned long t; + xCharInfo *defaultChar = 0; + unsigned char defc[2]; + int firstReal; + + charinfo = (xCharInfo **) xalloc(count * sizeof(xCharInfo *)); + if (!charinfo) + return FALSE; + encoding = TwoD16Bit; + if (pFont->info.lastRow == 0) + encoding = Linear16Bit; + (*pFont->get_metrics) (pFont, count, chars, encoding, &n, charinfo); + + /* Do default character substitution as get_metrics doesn't */ + +#define IsNonExistentChar(ci) (!(ci) || \ + ((ci)->ascent == 0 && \ + (ci)->descent == 0 && \ + (ci)->leftSideBearing == 0 && \ + (ci)->rightSideBearing == 0 && \ + (ci)->characterWidth == 0)) + + firstReal = n; + defc[0] = pFont->info.defaultCh >> 8; + defc[1] = pFont->info.defaultCh; + (*pFont->get_metrics) (pFont, 1, defc, encoding, &t, &defaultChar); + if ((IsNonExistentChar (defaultChar))) + defaultChar = 0; + for (i = 0; i < n; i++) + { + if ((IsNonExistentChar (charinfo[i]))) + { + if (!defaultChar) + continue; + charinfo[i] = defaultChar; + } + if (firstReal == n) + firstReal = i; + } + cm = pFont->info.constantMetrics; + pFont->info.constantMetrics = FALSE; + QueryGlyphExtents(pFont, (CharInfoPtr*) charinfo + firstReal, + n - firstReal, info); + pFont->info.constantMetrics = cm; + xfree(charinfo); + return TRUE; +} + +Bool +ParseGlyphCachingMode(char *str) +{ + if (!strcmp(str, "none")) defaultGlyphCachingMode = CACHING_OFF; + else if (!strcmp(str, "all")) defaultGlyphCachingMode = CACHE_ALL_GLYPHS; + else if (!strcmp(str, "16")) defaultGlyphCachingMode = CACHE_16_BIT_GLYPHS; + else return FALSE; + return TRUE; +} + +void +InitGlyphCaching(void) +{ + /* Set glyphCachingMode to the mode the server hopes to + support. DDX drivers that do not support the requested level + of glyph caching can call SetGlyphCachingMode to lower the + level of support. + */ + + glyphCachingMode = defaultGlyphCachingMode; +} + +/* ddxen can call SetGlyphCachingMode to inform us of what level of glyph + * caching they can support. + */ +void +SetGlyphCachingMode(int newmode) +{ + if ( (glyphCachingMode > newmode) && (newmode >= 0) ) + glyphCachingMode = newmode; +} + +#define range_alloc_granularity 16 +#define mincharp(p) ((p)->min_char_low + ((p)->min_char_high << 8)) +#define maxcharp(p) ((p)->max_char_low + ((p)->max_char_high << 8)) + +/* add_range(): Add range to a list of ranges, with coalescence */ +int +add_range(fsRange *newrange, + int *nranges, + fsRange **range, + Bool charset_subset) +{ + int first, last, middle; + unsigned long keymin, keymax; + unsigned long ptrmin = 0, ptrmax = 0; + fsRange *ptr = NULL, *ptr1, *ptr2, *endptr; + + /* There are two different ways to treat ranges: + + 1) Charset subsetting (support of the HP XLFD enhancements), in + which a range of 0x1234,0x3456 means all numbers between + 0x1234 and 0x3456, and in which min and max might be swapped. + + 2) Row/column ranges, in which a range of 0x1234,0x3456 means the + ranges 0x1234-0x1256, 0x1334-0x1356, ... , 0x3434-0x3456. + This is for support of glyph caching. + + The choice of treatment is selected with the "charset_subset" + flag */ + + /* If newrange covers multiple rows; break up the rows */ + if (!charset_subset && newrange->min_char_high != newrange->max_char_high) + { + int i, err = 0; + fsRange temprange; + for (i = newrange->min_char_high; + i <= newrange->max_char_high; + i++) + { + temprange.min_char_low = newrange->min_char_low; + temprange.max_char_low = newrange->max_char_low; + temprange.min_char_high = temprange.max_char_high = i; + err = add_range(&temprange, nranges, range, charset_subset); + if (err != Successful) break; + } + return err; + } + + keymin = mincharp(newrange); + keymax = maxcharp(newrange); + + if (charset_subset && keymin > keymax) + { + unsigned long temp = keymin; + keymin = keymax; + keymax = temp; + } + + /* add_range() maintains a sorted list; this makes possible coalescence + and binary searches */ + + /* Binary search for a range with which the new range can merge */ + + first = middle = 0; + last = *nranges - 1; + while (last >= first) + { + middle = (first + last) / 2; + ptr = (*range) + middle; + ptrmin = mincharp(ptr); + ptrmax = maxcharp(ptr); + + if (ptrmin > 0 && keymax < ptrmin - 1) last = middle - 1; + else if (keymin > ptrmax + 1) first = middle + 1; + else if (!charset_subset) + { + /* We might have a range with which to merge... IF the + result doesn't cross rows */ + if (newrange->min_char_high != ptr->min_char_high) + last = first - 1; /* Force adding a new range */ + break; + } + else break; /* We have at least one range with which we can merge */ + } + + if (last < first) + { + /* Search failed; we need to add a new range to the list. */ + + /* Grow the list if necessary */ + if (*nranges == 0 || *range == (fsRange *)0) + { + *range = (fsRange *)xalloc(range_alloc_granularity * + SIZEOF(fsRange)); + *nranges = 0; + } + else if (!(*nranges % range_alloc_granularity)) + { + *range = (fsRange *)xrealloc((char *)*range, + (*nranges + range_alloc_granularity) * + SIZEOF(fsRange)); + } + + /* If alloc failed, just return a null list */ + if (*range == (fsRange *)0) + { + *nranges = 0; + return AllocError; + } + + /* Should new entry go *at* or *after* ptr? */ + ptr = (*range) + middle; + if (middle < *nranges && keymin > ptrmin) ptr++; /* after */ + + /* Open up a space for our new range */ + memmove((char *)(ptr + 1), + (char *)ptr, + (char *)(*range + *nranges) - (char *)ptr); + + /* Insert the new range */ + ptr->min_char_low = keymin & 0xff; + ptr->min_char_high = keymin >> 8; + ptr->max_char_low = keymax & 0xff; + ptr->max_char_high = keymax >> 8; + + /* Update range count */ + (*nranges)++; + + /* Done */ + return Successful; + } + + /* Join our new range to that pointed to by "ptr" */ + if (keymin < ptrmin) + { + ptr->min_char_low = keymin & 0xff; + ptr->min_char_high = keymin >> 8; + } + if (keymax > ptrmax) + { + ptr->max_char_low = keymax & 0xff; + ptr->max_char_high = keymax >> 8; + } + + ptrmin = mincharp(ptr); + ptrmax = maxcharp(ptr); + + endptr = *range + *nranges; + + for (ptr1 = ptr; ptr1 >= *range; ptr1--) + { + if (ptrmin <= maxcharp(ptr1) + 1) + { + if (!charset_subset && ptr->min_char_high != ptr1->min_char_high) + break; + if (ptrmin >= mincharp(ptr1)) + ptrmin = mincharp(ptr1); + } + else break; + } + for (ptr2 = ptr; ptr2 < endptr; ptr2++) + { + if ((ptr2->min_char_low == 0 && ptr2->min_char_high == 0) || + ptrmax >= mincharp(ptr2) - 1) + { + if (!charset_subset && ptr->min_char_high != ptr2->min_char_high) + break; + if (ptrmax <= maxcharp(ptr2)) + ptrmax = maxcharp(ptr2); + } + else break; + } + + /* We need to coalesce ranges between ptr1 and ptr2 exclusive */ + ptr1++; + ptr2--; + if (ptr1 != ptr2) + { + memmove(ptr1, ptr2, (char *)endptr - (char *)ptr2); + *nranges -= (ptr2 - ptr1); + } + + /* Write the new range into the range list */ + ptr1->min_char_low = ptrmin & 0xff; + ptr1->min_char_high = ptrmin >> 8; + ptr1->max_char_low = ptrmax & 0xff; + ptr1->max_char_high = ptrmax >> 8; + + return Successful; +} + +/* It is difficult to find a good place for this. */ +#ifdef NEED_STRCASECMP +int +f_strcasecmp(const char *s1, const char *s2) +{ + char c1, c2; + + if (*s1 == 0) + if (*s2 == 0) + return 0; + else + return 1; + + c1 = (isupper (*s1) ? tolower (*s1) : *s1); + c2 = (isupper (*s2) ? tolower (*s2) : *s2); + while (c1 == c2) { + if (c1 == '\0') + return 0; + s1++; + s2++; + c1 = (isupper (*s1) ? tolower (*s1) : *s1); + c2 = (isupper (*s2) ? tolower (*s2) : *s2); + } + return c1 - c2; +} +#endif + diff --git a/nx-X11/lib/font/util/fontxlfd.c b/nx-X11/lib/font/util/fontxlfd.c new file mode 100644 index 000000000..7adf74f4c --- /dev/null +++ b/nx-X11/lib/font/util/fontxlfd.c @@ -0,0 +1,637 @@ +/* $Xorg: fontxlfd.c,v 1.4 2001/02/09 02:04:04 xorgcvs Exp $ */ + +/* + +Copyright 1990, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + +*/ +/* $XFree86: xc/lib/font/util/fontxlfd.c,v 3.16tsi Exp $ */ + +/* + * Author: Keith Packard, MIT X Consortium + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <X11/fonts/fontmisc.h> +#include <X11/fonts/fontstruct.h> +#include <X11/fonts/fontxlfd.h> +#include <X11/fonts/fontutil.h> +#include <X11/Xos.h> +#include <math.h> +#include <stdlib.h> +#if defined(sony) && !defined(SYSTYPE_SYSV) && !defined(_SYSTYPE_SYSV) +#define NO_LOCALE +#endif +#ifndef NO_LOCALE +#include <locale.h> +#endif +#include <ctype.h> +#include <stdio.h> /* for sprintf() */ + +static char * +GetInt(char *ptr, int *val) +{ + if (*ptr == '*') { + *val = -1; + ptr++; + } else + for (*val = 0; *ptr >= '0' && *ptr <= '9';) + *val = *val * 10 + *ptr++ - '0'; + if (*ptr == '-') + return ptr; + return (char *) 0; +} + +#define minchar(p) ((p).min_char_low + ((p).min_char_high << 8)) +#define maxchar(p) ((p).max_char_low + ((p).max_char_high << 8)) + + +#ifndef NO_LOCALE +static struct lconv *locale = 0; +#endif +static char *radix = ".", *plus = "+", *minus = "-"; + +static char * +readreal(char *ptr, double *result) +{ + char buffer[80], *p1, *p2; + +#ifndef NO_LOCALE + /* Figure out what symbols apply in this locale */ + + if (!locale) + { + locale = localeconv(); + if (locale->decimal_point && *locale->decimal_point) + radix = locale->decimal_point; + if (locale->positive_sign && *locale->positive_sign) + plus = locale->positive_sign; + if (locale->negative_sign && *locale->negative_sign) + minus = locale->negative_sign; + } +#endif + /* Copy the first 80 chars of ptr into our local buffer, changing + symbols as needed. */ + for (p1 = ptr, p2 = buffer; + *p1 && (p2 - buffer) < sizeof(buffer) - 1; + p1++, p2++) + { + switch(*p1) + { + case '~': *p2 = *minus; break; + case '+': *p2 = *plus; break; + case '.': *p2 = *radix; break; + default: *p2 = *p1; + } + } + *p2 = 0; + + /* Now we have something that strtod() can interpret... do it. */ + *result = strtod(buffer, &p1); + /* Return NULL if failure, pointer past number if success */ + return (p1 == buffer) ? (char *)0 : (ptr + (p1 - buffer)); +} + +static char * +xlfd_double_to_text(double value, char *buffer, int space_required) +{ + char formatbuf[40]; + register char *p1; + int ndigits, exponent; + +#ifndef NO_LOCALE + if (!locale) + { + locale = localeconv(); + if (locale->decimal_point && *locale->decimal_point) + radix = locale->decimal_point; + if (locale->positive_sign && *locale->positive_sign) + plus = locale->positive_sign; + if (locale->negative_sign && *locale->negative_sign) + minus = locale->negative_sign; + } +#endif + /* Compute a format to use to render the number */ + sprintf(formatbuf, "%%.%dle", XLFD_NDIGITS); + + if (space_required) + *buffer++ = ' '; + + /* Render the number using printf's idea of formatting */ + sprintf(buffer, formatbuf, value); + + /* Find and read the exponent value */ + for (p1 = buffer + strlen(buffer); + *p1-- != 'e' && p1[1] != 'E';); + exponent = atoi(p1 + 2); + if (value == 0.0) exponent = 0; + + /* Figure out how many digits are significant */ + while (p1 >= buffer && (!isdigit(*p1) || *p1 == '0')) p1--; + ndigits = 0; + while (p1 >= buffer) if (isdigit(*p1--)) ndigits++; + + /* Figure out notation to use */ + if (exponent >= XLFD_NDIGITS || ndigits - exponent > XLFD_NDIGITS + 1) + { + /* Scientific */ + sprintf(formatbuf, "%%.%dle", ndigits - 1); + sprintf(buffer, formatbuf, value); + } + else + { + /* Fixed */ + ndigits -= exponent + 1; + if (ndigits < 0) ndigits = 0; + sprintf(formatbuf, "%%.%dlf", ndigits); + sprintf(buffer, formatbuf, value); + if (exponent < 0) + { + p1 = buffer; + while (*p1 && *p1 != '0') p1++; + while (*p1++) p1[-1] = *p1; + } + } + + /* Last step, convert the locale-specific sign and radix characters + to our own. */ + for (p1 = buffer; *p1; p1++) + { + if (*p1 == *minus) *p1 = '~'; + else if (*p1 == *plus) *p1 = '+'; + else if (*p1 == *radix) *p1 = '.'; + } + + return buffer - space_required; +} + +double +xlfd_round_double(double x) +{ + /* Utility for XLFD users to round numbers to XLFD_NDIGITS + significant digits. How do you round to n significant digits on + a binary machine? */ + +#if defined(i386) || defined(__i386__) || \ + defined(ia64) || defined(__ia64__) || \ + defined(__alpha__) || defined(__alpha) || \ + defined(__hppa__) || \ + defined(__amd64__) || defined(__amd64) || \ + defined(sgi) +#if !defined(__UNIXOS2__) +#include <float.h> + +/* if we have IEEE 754 fp, we can round to binary digits... */ + +#if (FLT_RADIX == 2) && (DBL_DIG == 15) && (DBL_MANT_DIG == 53) + +#ifndef M_LN2 +#define M_LN2 0.69314718055994530942 +#endif +#ifndef M_LN10 +#define M_LN10 2.30258509299404568402 +#endif + +/* convert # of decimal digits to # of binary digits */ +#define XLFD_NDIGITS_2 ((int)(XLFD_NDIGITS * M_LN10 / M_LN2 + 0.5)) + + union conv_d { + double d; + unsigned char b[8]; + } d; + int i,j,k,d_exp; + + if (x == 0) + return x; + + /* do minor sanity check for IEEE 754 fp and correct byte order */ + d.d = 1.0; + if (sizeof(double) == 8 && d.b[7] == 0x3f && d.b[6] == 0xf0) { + + /* + * this code will round IEEE 754 double to XLFD_NDIGITS_2 binary digits + */ + + d.d = x; + d_exp = (d.b[7] << 4) | (d.b[6] >> 4); + + i = (DBL_MANT_DIG-XLFD_NDIGITS_2) >> 3; + j = 1 << ((DBL_MANT_DIG-XLFD_NDIGITS_2) & 0x07); + for (; i<7; i++) { + k = d.b[i] + j; + d.b[i] = k; + if (k & 0x100) j = 1; + else break; + } + if ((i==7) && ((d.b[6] & 0xf0) != ((d_exp<<4) & 0xf0))) { + /* mantissa overflow: increment exponent */ + d_exp = (d_exp & 0x800 ) | ((d_exp & 0x7ff) + 1); + d.b[7] = d_exp >> 4; + d.b[6] = (d.b[6] & 0x0f) | (d_exp << 4); + } + + i = (DBL_MANT_DIG-XLFD_NDIGITS_2) >> 3; + j = 1 << ((DBL_MANT_DIG-XLFD_NDIGITS_2) & 0x07); + d.b[i] &= ~(j-1); + for (;--i>=0;) d.b[i] = 0; + + return d.d; + } + else +#endif +#endif /* !__UNIXOS2__ */ +#endif /* i386 || __i386__ */ + { + /* + * If not IEEE 754: Let printf() do it for you. + */ + + char formatbuf[40], buffer[40]; + + sprintf(formatbuf, "%%.%dlg", XLFD_NDIGITS); + sprintf(buffer, formatbuf, x); + return atof(buffer); + } +} + +static char * +GetMatrix(char *ptr, FontScalablePtr vals, int which) +{ + double *matrix; + + if (which == PIXELSIZE_MASK) + matrix = vals->pixel_matrix; + else if (which == POINTSIZE_MASK) + matrix = vals->point_matrix; + else return (char *)0; + + while (isspace(*ptr)) ptr++; + if (*ptr == '[') + { + /* This is a matrix containing real numbers. It would be nice + to use strtod() or sscanf() to read the numbers, but those + don't handle '~' for minus and we cannot force them to use a + "." for the radix. We'll have to do the hard work ourselves + (in readreal()). */ + + if ((ptr = readreal(++ptr, matrix + 0)) && + (ptr = readreal(ptr, matrix + 1)) && + (ptr = readreal(ptr, matrix + 2)) && + (ptr = readreal(ptr, matrix + 3))) + { + while (isspace(*ptr)) ptr++; + if (*ptr != ']') + ptr = (char *)0; + else + { + ptr++; + while (isspace(*ptr)) ptr++; + if (*ptr == '-') + { + if (which == POINTSIZE_MASK) + vals->values_supplied |= POINTSIZE_ARRAY; + else + vals->values_supplied |= PIXELSIZE_ARRAY; + } + else ptr = (char *)0; + } + } + } + else + { + int value; + if ((ptr = GetInt(ptr, &value))) + { + vals->values_supplied &= ~which; + if (value > 0) + { + matrix[3] = (double)value; + if (which == POINTSIZE_MASK) + { + matrix[3] /= 10.0; + vals->values_supplied |= POINTSIZE_SCALAR; + } + else + vals->values_supplied |= PIXELSIZE_SCALAR; + /* If we're concocting the pixelsize array from a scalar, + we will need to normalize element 0 for the pixel shape. + This is done in FontFileCompleteXLFD(). */ + matrix[0] = matrix[3]; + matrix[1] = matrix[2] = 0.0; + } + else if (value < 0) + { + if (which == POINTSIZE_MASK) + vals->values_supplied |= POINTSIZE_WILDCARD; + else + vals->values_supplied |= PIXELSIZE_WILDCARD; + } + } + } + return ptr; +} + + +static void +append_ranges(char *fname, int nranges, fsRange *ranges) +{ + if (nranges) + { + int i; + + strcat(fname, "["); + for (i = 0; i < nranges && strlen(fname) < 1010; i++) + { + if (i) strcat(fname, " "); + sprintf(fname + strlen(fname), "%d", + minchar(ranges[i])); + if (ranges[i].min_char_low == + ranges[i].max_char_low && + ranges[i].min_char_high == + ranges[i].max_char_high) continue; + sprintf(fname + strlen(fname), "_%d", + maxchar(ranges[i])); + } + strcat(fname, "]"); + } +} + +Bool +FontParseXLFDName(char *fname, FontScalablePtr vals, int subst) +{ + register char *ptr; + register char *ptr1, + *ptr2, + *ptr3, + *ptr4; + register char *ptr5; + FontScalableRec tmpvals; + char replaceChar = '0'; + char tmpBuf[1024]; + int spacingLen; + int l; + char *p; + + bzero(&tmpvals, sizeof(tmpvals)); + if (subst != FONT_XLFD_REPLACE_VALUE) + *vals = tmpvals; + + if (!(*(ptr = fname) == '-' || (*ptr++ == '*' && *ptr == '-')) || /* fndry */ + !(ptr = strchr(ptr + 1, '-')) || /* family_name */ + !(ptr1 = ptr = strchr(ptr + 1, '-')) || /* weight_name */ + !(ptr = strchr(ptr + 1, '-')) || /* slant */ + !(ptr = strchr(ptr + 1, '-')) || /* setwidth_name */ + !(ptr = strchr(ptr + 1, '-')) || /* add_style_name */ + !(ptr = strchr(ptr + 1, '-')) || /* pixel_size */ + !(ptr = GetMatrix(ptr + 1, &tmpvals, PIXELSIZE_MASK)) || + !(ptr2 = ptr = GetMatrix(ptr + 1, &tmpvals, POINTSIZE_MASK)) || + !(ptr = GetInt(ptr + 1, &tmpvals.x)) || /* resolution_x */ + !(ptr3 = ptr = GetInt(ptr + 1, &tmpvals.y)) || /* resolution_y */ + !(ptr4 = ptr = strchr(ptr + 1, '-')) || /* spacing */ + !(ptr5 = ptr = GetInt(ptr + 1, &tmpvals.width)) || /* average_width */ + !(ptr = strchr(ptr + 1, '-')) || /* charset_registry */ + strchr(ptr + 1, '-'))/* charset_encoding */ + return FALSE; + + /* Lop off HP charset subsetting enhancement. Interpreting this + field requires allocating some space in which to return the + results. So, to prevent memory leaks, this procedure will simply + lop off and ignore charset subsetting, and initialize the + relevant vals fields to zero. It's up to the caller to make its + own call to FontParseRanges() if it's interested in the charset + subsetting. */ + + if (subst != FONT_XLFD_REPLACE_NONE && + (p = strchr(strrchr(fname, '-'), '['))) + { + tmpvals.values_supplied |= CHARSUBSET_SPECIFIED; + *p = '\0'; + } + + /* Fill in deprecated fields for the benefit of rasterizers that care + about them. */ + tmpvals.pixel = (tmpvals.pixel_matrix[3] >= 0) ? + (int)(tmpvals.pixel_matrix[3] + .5) : + (int)(tmpvals.pixel_matrix[3] - .5); + tmpvals.point = (tmpvals.point_matrix[3] >= 0) ? + (int)(tmpvals.point_matrix[3] * 10 + .5) : + (int)(tmpvals.point_matrix[3] * 10 - .5); + + spacingLen = ptr4 - ptr3 + 1; + + switch (subst) { + case FONT_XLFD_REPLACE_NONE: + *vals = tmpvals; + break; + case FONT_XLFD_REPLACE_STAR: + replaceChar = '*'; + case FONT_XLFD_REPLACE_ZERO: + strcpy(tmpBuf, ptr2); + ptr5 = tmpBuf + (ptr5 - ptr2); + ptr3 = tmpBuf + (ptr3 - ptr2); + ptr2 = tmpBuf; + ptr = ptr1 + 1; + + ptr = strchr(ptr, '-') + 1; /* skip weight */ + ptr = strchr(ptr, '-') + 1; /* skip slant */ + ptr = strchr(ptr, '-') + 1; /* skip setwidth_name */ + ptr = strchr(ptr, '-') + 1; /* skip add_style_name */ + + if ((ptr - fname) + spacingLen + strlen(ptr5) + 10 >= (unsigned)1024) + return FALSE; + *ptr++ = replaceChar; + *ptr++ = '-'; + *ptr++ = replaceChar; + *ptr++ = '-'; + *ptr++ = '*'; + *ptr++ = '-'; + *ptr++ = '*'; + if (spacingLen > 2) + { + memmove(ptr, ptr3, spacingLen); + ptr += spacingLen; + } + else + { + *ptr++ = '-'; + *ptr++ = '*'; + *ptr++ = '-'; + } + *ptr++ = replaceChar; + strcpy(ptr, ptr5); + *vals = tmpvals; + break; + case FONT_XLFD_REPLACE_VALUE: + if (vals->values_supplied & PIXELSIZE_MASK) + { + tmpvals.values_supplied = + (tmpvals.values_supplied & ~PIXELSIZE_MASK) | + (vals->values_supplied & PIXELSIZE_MASK); + tmpvals.pixel_matrix[0] = vals->pixel_matrix[0]; + tmpvals.pixel_matrix[1] = vals->pixel_matrix[1]; + tmpvals.pixel_matrix[2] = vals->pixel_matrix[2]; + tmpvals.pixel_matrix[3] = vals->pixel_matrix[3]; + } + if (vals->values_supplied & POINTSIZE_MASK) + { + tmpvals.values_supplied = + (tmpvals.values_supplied & ~POINTSIZE_MASK) | + (vals->values_supplied & POINTSIZE_MASK); + tmpvals.point_matrix[0] = vals->point_matrix[0]; + tmpvals.point_matrix[1] = vals->point_matrix[1]; + tmpvals.point_matrix[2] = vals->point_matrix[2]; + tmpvals.point_matrix[3] = vals->point_matrix[3]; + } + if (vals->x >= 0) + tmpvals.x = vals->x; + if (vals->y >= 0) + tmpvals.y = vals->y; + if (vals->width >= 0) + tmpvals.width = vals->width; + else if (vals->width < -1) /* overload: -1 means wildcard */ + tmpvals.width = -vals->width; + + + p = ptr1 + 1; /* weight field */ + l = strchr(p, '-') - p; + sprintf(tmpBuf, "%*.*s", l, l, p); + + p += l + 1; /* slant field */ + l = strchr(p, '-') - p; + sprintf(tmpBuf + strlen(tmpBuf), "-%*.*s", l, l, p); + + p += l + 1; /* setwidth_name */ + l = strchr(p, '-') - p; + sprintf(tmpBuf + strlen(tmpBuf), "-%*.*s", l, l, p); + + p += l + 1; /* add_style_name field */ + l = strchr(p, '-') - p; + sprintf(tmpBuf + strlen(tmpBuf), "-%*.*s", l, l, p); + + strcat(tmpBuf, "-"); + if ((tmpvals.values_supplied & PIXELSIZE_MASK) == PIXELSIZE_ARRAY) + { + char buffer[80]; + strcat(tmpBuf, "["); + strcat(tmpBuf, xlfd_double_to_text(tmpvals.pixel_matrix[0], + buffer, 0)); + strcat(tmpBuf, xlfd_double_to_text(tmpvals.pixel_matrix[1], + buffer, 1)); + strcat(tmpBuf, xlfd_double_to_text(tmpvals.pixel_matrix[2], + buffer, 1)); + strcat(tmpBuf, xlfd_double_to_text(tmpvals.pixel_matrix[3], + buffer, 1)); + strcat(tmpBuf, "]"); + } + else + { + sprintf(tmpBuf + strlen(tmpBuf), "%d", + (int)(tmpvals.pixel_matrix[3] + .5)); + } + strcat(tmpBuf, "-"); + if ((tmpvals.values_supplied & POINTSIZE_MASK) == POINTSIZE_ARRAY) + { + char buffer[80]; + strcat(tmpBuf, "["); + strcat(tmpBuf, xlfd_double_to_text(tmpvals.point_matrix[0], + buffer, 0)); + strcat(tmpBuf, xlfd_double_to_text(tmpvals.point_matrix[1], + buffer, 1)); + strcat(tmpBuf, xlfd_double_to_text(tmpvals.point_matrix[2], + buffer, 1)); + strcat(tmpBuf, xlfd_double_to_text(tmpvals.point_matrix[3], + buffer, 1)); + strcat(tmpBuf, "]"); + } + else + { + sprintf(tmpBuf + strlen(tmpBuf), "%d", + (int)(tmpvals.point_matrix[3] * 10.0 + .5)); + } + sprintf(tmpBuf + strlen(tmpBuf), "-%d-%d%*.*s%d%s", + tmpvals.x, tmpvals.y, + spacingLen, spacingLen, ptr3, tmpvals.width, ptr5); + strcpy(ptr1 + 1, tmpBuf); + if ((vals->values_supplied & CHARSUBSET_SPECIFIED) && !vals->nranges) + strcat(fname, "[]"); + else + append_ranges(fname, vals->nranges, vals->ranges); + break; + } + return TRUE; +} + +fsRange *FontParseRanges(char *name, int *nranges) +{ + int n; + unsigned long l; + char *p1, *p2; + fsRange *result = (fsRange *)0; + + name = strchr(name, '-'); + for (n = 1; name && n < 14; n++) + name = strchr(name + 1, '-'); + + *nranges = 0; + if (!name || !(p1 = strchr(name, '['))) return (fsRange *)0; + p1++; + + while (*p1 && *p1 != ']') + { + fsRange thisrange; + + l = strtol(p1, &p2, 0); + if (p2 == p1 || l > 0xffff) break; + thisrange.max_char_low = thisrange.min_char_low = l & 0xff; + thisrange.max_char_high = thisrange.min_char_high = l >> 8; + + p1 = p2; + if (*p1 == ']' || *p1 == ' ') + { + while (*p1 == ' ') p1++; + if (add_range(&thisrange, nranges, &result, TRUE) != Successful) + break; + } + else if (*p1 == '_') + { + l = strtol(++p1, &p2, 0); + if (p2 == p1 || l > 0xffff) break; + thisrange.max_char_low = l & 0xff; + thisrange.max_char_high = l >> 8; + p1 = p2; + if (*p1 == ']' || *p1 == ' ') + { + while (*p1 == ' ') p1++; + if (add_range(&thisrange, nranges, &result, TRUE) != Successful) + break; + } + } + else break; + } + + return result; +} diff --git a/nx-X11/lib/font/util/format.c b/nx-X11/lib/font/util/format.c new file mode 100644 index 000000000..6700721f9 --- /dev/null +++ b/nx-X11/lib/font/util/format.c @@ -0,0 +1,126 @@ +/* $Xorg: format.c,v 1.4 2001/02/09 02:04:04 xorgcvs Exp $ */ +/* + * Copyright 1990, 1991 Network Computing Devices; + * Portions Copyright 1987 by Digital Equipment Corporation + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the names of Network Computing Devices or Digital + * not be used in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. Network Computing + * Devices and Digital make no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * NETWORK COMPUTING DEVICES AND DIGITAL DISCLAIM ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES OR DIGITAL BE + * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + +Copyright 1987, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + +*/ +/* $XFree86: xc/lib/font/util/format.c,v 1.4 2001/01/17 19:43:33 dawes Exp $ */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <X11/fonts/FSproto.h> +#include <X11/fonts/font.h> +#include <X11/fonts/fontstruct.h> +#include <X11/fonts/fontutil.h> + +int +CheckFSFormat(fsBitmapFormat format, + fsBitmapFormatMask fmask, + int *bit_order, + int *byte_order, + int *scan, + int *glyph, + int *image) +{ + /* convert format to what the low levels want */ + if (fmask & BitmapFormatMaskBit) { + *bit_order = format & BitmapFormatBitOrderMask; + *bit_order = (*bit_order == BitmapFormatBitOrderMSB) + ? MSBFirst : LSBFirst; + } + if (fmask & BitmapFormatMaskByte) { + *byte_order = format & BitmapFormatByteOrderMask; + *byte_order = (*byte_order == BitmapFormatByteOrderMSB) + ? MSBFirst : LSBFirst; + } + if (fmask & BitmapFormatMaskScanLineUnit) { + *scan = format & BitmapFormatScanlineUnitMask; + /* convert byte paddings into byte counts */ + switch (*scan) { + case BitmapFormatScanlineUnit8: + *scan = 1; + break; + case BitmapFormatScanlineUnit16: + *scan = 2; + break; + case BitmapFormatScanlineUnit32: + *scan = 4; + break; + default: + return BadFontFormat; + } + } + if (fmask & BitmapFormatMaskScanLinePad) { + *glyph = format & BitmapFormatScanlinePadMask; + /* convert byte paddings into byte counts */ + switch (*glyph) { + case BitmapFormatScanlinePad8: + *glyph = 1; + break; + case BitmapFormatScanlinePad16: + *glyph = 2; + break; + case BitmapFormatScanlinePad32: + *glyph = 4; + break; + default: + return BadFontFormat; + } + } + if (fmask & BitmapFormatMaskImageRectangle) { + *image = format & BitmapFormatImageRectMask; + + if (*image != BitmapFormatImageRectMin && + *image != BitmapFormatImageRectMaxWidth && + *image != BitmapFormatImageRectMax) + return BadFontFormat; + } + return Successful; +} diff --git a/nx-X11/lib/font/util/miscutil.c b/nx-X11/lib/font/util/miscutil.c new file mode 100644 index 000000000..03b4d061d --- /dev/null +++ b/nx-X11/lib/font/util/miscutil.c @@ -0,0 +1,99 @@ +/* $Xorg: miscutil.c,v 1.4 2001/02/09 02:04:04 xorgcvs Exp $ */ + +/* + +Copyright 1991, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + +*/ +/* $XFree86: xc/lib/font/util/miscutil.c,v 1.7 2001/07/25 15:04:57 dawes Exp $ */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <X11/Xosdefs.h> +#include <stdlib.h> +#include <X11/fonts/fontmisc.h> + +#define XK_LATIN1 +#include <X11/keysymdef.h> +/* #include <X11/Xmu/CharSet.h> */ + +/* make sure everything initializes themselves at least once */ + +long serverGeneration = 1; + +void * +Xalloc (unsigned long m) +{ + return malloc (m); +} + +void * +Xrealloc (void *n, unsigned long m) +{ + if (!n) + return malloc (m); + else + return realloc (n, m); +} + +void +Xfree (void *n) +{ + if (n) + free (n); +} + +void * +Xcalloc (unsigned long n) +{ + return calloc (n, 1); +} + +void +CopyISOLatin1Lowered (char *dst, char *src, int len) +{ + register unsigned char *dest, *source; + + for (dest = (unsigned char *)dst, source = (unsigned char *)src; + *source && len > 0; + source++, dest++, len--) + { + if ((*source >= XK_A) && (*source <= XK_Z)) + *dest = *source + (XK_a - XK_A); + else if ((*source >= XK_Agrave) && (*source <= XK_Odiaeresis)) + *dest = *source + (XK_agrave - XK_Agrave); + else if ((*source >= XK_Ooblique) && (*source <= XK_Thorn)) + *dest = *source + (XK_oslash - XK_Ooblique); + else + *dest = *source; + } + *dest = '\0'; +} + +void +register_fpe_functions () +{ +} diff --git a/nx-X11/lib/font/util/patcache.c b/nx-X11/lib/font/util/patcache.c new file mode 100644 index 000000000..0351b1ac2 --- /dev/null +++ b/nx-X11/lib/font/util/patcache.c @@ -0,0 +1,221 @@ +/* $Xorg: patcache.c,v 1.4 2001/02/09 02:04:04 xorgcvs Exp $ */ + +/* + +Copyright 1991, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ +/* $XFree86: xc/lib/font/util/patcache.c,v 3.4 2001/01/17 19:43:33 dawes Exp $ */ + +/* + * Author: Keith Packard, MIT X Consortium + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <X11/fonts/fontmisc.h> +#include <X11/fonts/fontstruct.h> + +/* + * Static sized hash table for looking up font name patterns + * + * LRU entries, reusing old entries + */ + +#define NBUCKETS 16 +#define NENTRIES 64 + +#define UNSET (NENTRIES+1) + +typedef unsigned char EntryPtr; + +typedef struct _FontPatternCacheEntry { + struct _FontPatternCacheEntry *next, **prev; + short patlen; + char *pattern; + int hash; + FontPtr pFont; /* associated font */ +} FontPatternCacheEntryRec, *FontPatternCacheEntryPtr; + +typedef struct _FontPatternCache { + FontPatternCacheEntryPtr buckets[NBUCKETS]; + FontPatternCacheEntryRec entries[NENTRIES]; + FontPatternCacheEntryPtr free; +} FontPatternCacheRec; + +/* Empty cache (for rehash) */ +void +EmptyFontPatternCache (FontPatternCachePtr cache) +{ + int i; + + for (i = 0; i < NBUCKETS; i++) + cache->buckets[i] = 0; + for (i = 0; i < NENTRIES; i++) + { + cache->entries[i].next = &cache->entries[i+1]; + cache->entries[i].prev = 0; + cache->entries[i].pFont = 0; + xfree (cache->entries[i].pattern); + cache->entries[i].pattern = 0; + cache->entries[i].patlen = 0; + } + cache->free = &cache->entries[0]; + cache->entries[NENTRIES - 1].next = 0; +} + +/* Create and initialize cache */ +FontPatternCachePtr +MakeFontPatternCache (void) +{ + FontPatternCachePtr cache; + int i; + cache = (FontPatternCachePtr) xalloc (sizeof *cache); + if (!cache) + return 0; + for (i = 0; i < NENTRIES; i++) { + cache->entries[i].patlen = 0; + cache->entries[i].pattern = 0; + cache->entries[i].pFont = 0; + } + EmptyFontPatternCache (cache); + return cache; +} + +/* toss cache */ +void +FreeFontPatternCache (FontPatternCachePtr cache) +{ + int i; + + for (i = 0; i < NENTRIES; i++) + xfree (cache->entries[i].pattern); + xfree (cache); +} + +/* compute id for string */ +static int +Hash (const char *string, int len) +{ + int hash; + + hash = 0; + while (len--) + hash = (hash << 1) ^ *string++; + if (hash < 0) + hash = -hash; + return hash; +} + +/* add entry */ +void +CacheFontPattern (FontPatternCachePtr cache, + char *pattern, + int patlen, + FontPtr pFont) +{ + FontPatternCacheEntryPtr e; + char *newpat; + int i; + + newpat = (char *) xalloc (patlen); + if (!newpat) + return; + if (cache->free) + { + e = cache->free; + cache->free = e->next; + } + else + { + i = rand (); + if (i < 0) + i = -i; + i %= NENTRIES; + e = &cache->entries[i]; + if (e->next) + e->next->prev = e->prev; + *e->prev = e->next; + xfree (e->pattern); + } + /* set pattern */ + memcpy (newpat, pattern, patlen); + e->pattern = newpat; + e->patlen = patlen; + /* link to new hash chain */ + e->hash = Hash (pattern, patlen); + i = e->hash % NBUCKETS; + e->next = cache->buckets[i]; + if (e->next) + e->next->prev = &(e->next); + cache->buckets[i] = e; + e->prev = &(cache->buckets[i]); + e->pFont = pFont; +} + +/* find matching entry */ +FontPtr +FindCachedFontPattern (FontPatternCachePtr cache, + char *pattern, + int patlen) +{ + int hash; + int i; + FontPatternCacheEntryPtr e; + + hash = Hash (pattern, patlen); + i = hash % NBUCKETS; + for (e = cache->buckets[i]; e; e = e->next) + { + if (e->patlen == patlen && e->hash == hash && + !memcmp (e->pattern, pattern, patlen)) + { + return e->pFont; + } + } + return 0; +} + +void +RemoveCachedFontPattern (FontPatternCachePtr cache, + FontPtr pFont) +{ + FontPatternCacheEntryPtr e; + int i; + + for (i = 0; i < NENTRIES; i++) + { + if ((e = &cache->entries[i])->pFont == pFont) + { + e->pFont = 0; + if (e->next) + e->next->prev = e->prev; + *e->prev = e->next; + e->next = cache->free; + cache->free = e; + xfree (e->pattern); + e->pattern = 0; + } + } +} diff --git a/nx-X11/lib/font/util/private.c b/nx-X11/lib/font/util/private.c new file mode 100644 index 000000000..85e90e57b --- /dev/null +++ b/nx-X11/lib/font/util/private.c @@ -0,0 +1,107 @@ +/* $Xorg: private.c,v 1.4 2001/02/09 02:04:04 xorgcvs Exp $ */ + +/* + +Copyright 1991, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ +/* $XFree86: xc/lib/font/util/private.c,v 1.8tsi Exp $ */ + +/* + * Author: Keith Packard, MIT X Consortium + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <X11/fonts/fontmisc.h> +#include <X11/fonts/fontstruct.h> + +static int _FontPrivateAllocateIndex = 0; + +int +AllocateFontPrivateIndex (void) +{ + return _FontPrivateAllocateIndex++; +} + +FontPtr +CreateFontRec (void) +{ + FontPtr pFont; + int size; + + size = sizeof(FontRec) + (sizeof(pointer) * _FontPrivateAllocateIndex); + + pFont = (FontPtr)xalloc(size); + + if(pFont) { + bzero((char*)pFont, size); + pFont->maxPrivate = _FontPrivateAllocateIndex - 1; + if(_FontPrivateAllocateIndex) + pFont->devPrivates = (pointer)(&pFont[1]); + } + + return pFont; +} + +void +DestroyFontRec (FontPtr pFont) +{ + if (pFont->devPrivates && pFont->devPrivates != (pointer)(&pFont[1])) + xfree(pFont->devPrivates); + xfree(pFont); +} + +void +ResetFontPrivateIndex (void) +{ + _FontPrivateAllocateIndex = 0; +} + +Bool +_FontSetNewPrivate (FontPtr pFont, int n, pointer ptr) +{ + pointer *new; + + if (n > pFont->maxPrivate) { + if (pFont->devPrivates && pFont->devPrivates != (pointer)(&pFont[1])) { + new = (pointer *) xrealloc (pFont->devPrivates, (n + 1) * sizeof (pointer)); + if (!new) + return FALSE; + } else { + new = (pointer *) xalloc ((n + 1) * sizeof (pointer)); + if (!new) + return FALSE; + if (pFont->devPrivates) + memcpy (new, pFont->devPrivates, (pFont->maxPrivate + 1) * sizeof (pointer)); + } + pFont->devPrivates = new; + /* zero out new, uninitialized privates */ + while(++pFont->maxPrivate < n) + pFont->devPrivates[pFont->maxPrivate] = (pointer)0; + } + pFont->devPrivates[n] = ptr; + return TRUE; +} + diff --git a/nx-X11/lib/font/util/utilbitmap.c b/nx-X11/lib/font/util/utilbitmap.c new file mode 100644 index 000000000..a817a4ec6 --- /dev/null +++ b/nx-X11/lib/font/util/utilbitmap.c @@ -0,0 +1,188 @@ +/* $Xorg: utilbitmap.c,v 1.4 2001/02/09 02:04:04 xorgcvs Exp $ */ + +/* + +Copyright 1990, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ +/* $XFree86: xc/lib/font/util/utilbitmap.c,v 1.4 2001/01/17 19:43:34 dawes Exp $ */ + +/* + * Author: Keith Packard, MIT X Consortium + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <X11/fonts/fontmisc.h> + +/* Utility functions for reformating font bitmaps */ + +static unsigned char _reverse_byte[0x100] = { + 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, + 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, + 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, + 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, + 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, + 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, + 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, + 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, + 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, + 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, + 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, + 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, + 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, + 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, + 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, + 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, + 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, + 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, + 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, + 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, + 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, + 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, + 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, + 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, + 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, + 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, + 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, + 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, + 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, + 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, + 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, + 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff +}; + +/* + * Invert bit order within each BYTE of an array. + */ +void +BitOrderInvert(unsigned char *buf, int nbytes) +{ + unsigned char *rev = _reverse_byte; + + for (; --nbytes >= 0; buf++) + *buf = rev[*buf]; +} + +/* + * Invert byte order within each 16-bits of an array. + */ +void +TwoByteSwap(unsigned char *buf, int nbytes) +{ + unsigned char c; + + for (; nbytes > 0; nbytes -= 2, buf += 2) + { + c = buf[0]; + buf[0] = buf[1]; + buf[1] = c; + } +} + +/* + * Invert byte order within each 32-bits of an array. + */ +void +FourByteSwap(unsigned char *buf, int nbytes) +{ + unsigned char c; + + for (; nbytes > 0; nbytes -= 4, buf += 4) + { + c = buf[0]; + buf[0] = buf[3]; + buf[3] = c; + c = buf[1]; + buf[1] = buf[2]; + buf[2] = c; + } +} + +/* + * Repad a bitmap + */ + +int +RepadBitmap (char *pSrc, char *pDst, + unsigned int srcPad, unsigned int dstPad, + int width, int height) +{ + int srcWidthBytes,dstWidthBytes; + int row,col; + char *pTmpSrc,*pTmpDst; + + switch (srcPad) { + case 1: + srcWidthBytes = (width+7)>>3; + break; + case 2: + srcWidthBytes = ((width+15)>>4)<<1; + break; + case 4: + srcWidthBytes = ((width+31)>>5)<<2; + break; + case 8: + srcWidthBytes = ((width+63)>>6)<<3; + break; + default: + return 0; + } + switch (dstPad) { + case 1: + dstWidthBytes = (width+7)>>3; + break; + case 2: + dstWidthBytes = ((width+15)>>4)<<1; + break; + case 4: + dstWidthBytes = ((width+31)>>5)<<2; + break; + case 8: + dstWidthBytes = ((width+63)>>6)<<3; + break; + default: + return 0; + } + + width = srcWidthBytes; + if (width > dstWidthBytes) + width = dstWidthBytes; + pTmpSrc= pSrc; + pTmpDst= pDst; + for (row = 0; row < height; row++) + { + for (col = 0; col < width; col++) + *pTmpDst++ = *pTmpSrc++; + while (col < dstWidthBytes) + { + *pTmpDst++ = '\0'; + col++; + } + pTmpSrc += srcWidthBytes - width; + } + return dstWidthBytes * height; +} + + |