diff options
author | Kaleb Keithley <kaleb@freedesktop.org> | 2003-11-14 16:48:50 +0000 |
---|---|---|
committer | Kaleb Keithley <kaleb@freedesktop.org> | 2003-11-14 16:48:50 +0000 |
commit | 3795e9702b3b3a6fe0594d09cdd110adeb5e42f9 (patch) | |
tree | caec4aaf13f12f0a31c15cb24ad2127eff834dd2 /src | |
parent | 153e8da44452905ae04a0e20ad0d85f40399b4ca (diff) |
Initial revision
Diffstat (limited to 'src')
43 files changed, 8512 insertions, 0 deletions
diff --git a/src/FreeType/ft.h b/src/FreeType/ft.h new file mode 100644 index 0000000..d4cacc2 --- /dev/null +++ b/src/FreeType/ft.h @@ -0,0 +1,89 @@ +/* +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.19 2002/10/01 00:02:09 alanh Exp $ */ + +#ifndef _FT_H_ +#define _FT_H_ + +#include <X11/Xfuncproto.h> + +#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)) + +/* 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 */ + +void FreeTypeRegisterFontFileFunctions(void); + +/* ftenc.c */ + +int FTPickMapping(char*, int, char*, FT_Face, FTMappingPtr); +unsigned FTRemap(FT_Face face, FTMappingPtr, unsigned code); + +/* fttools.c */ + +int FTu2a(int, char*, char*, int, int); +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/src/FreeType/ftenc.c b/src/FreeType/ftenc.c new file mode 100644 index 0000000..7243f3f --- /dev/null +++ b/src/FreeType/ftenc.c @@ -0,0 +1,212 @@ +/* +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/ftenc.c,v 1.21 2002/10/01 00:02:10 alanh Exp $ */ + +#ifndef FONTMODULE +#include <string.h> +#else +#include "Xmd.h" +#include "Xdefs.h" +#include "xf86_ansic.h" +#endif + +#include "fontmisc.h" +#include "fontenc.h" +#include "freetype/freetype.h" +#include "freetype/ttnameid.h" +#include "freetype/tttables.h" +#include "freetype/t1tables.h" +#include "freetype/ftxf86.h" +#include "ft.h" + +static int find_cmap(int, int, int, FT_Face, FT_CharMap *); + +static int +FTEncFontSpecific(char *encoding) +{ + char *p = encoding; + + 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; + + char *encoding_name = 0; + + if(xlfd) + encoding_name = FontEncFromXLFD(xlfd, length); + if(!encoding_name) + encoding_name = "iso8859-1"; + + if(FTEncFontSpecific(encoding_name)) { + ftrc = FT_Select_Charmap(face, ft_encoding_adobe_custom); + if(ftrc != 0) { + ErrorF("FreeType: couldn't select custom Type 1 encoding\n"); + return -1; + } else { + tm->named = 0; + tm->cmap = face->charmap; + tm->base = 0; + tm->mapping = NULL; + return 0; + } + } + + encoding = FontEncFind(encoding_name, filename); + if(encoding == NULL) { + ErrorF("FreeType: couldn't find encoding %s\n", encoding_name); + encoding = FontEncFind("iso8859-1", filename); + } + if(encoding == NULL) { + ErrorF("FreeType: couldn't find encoding iso8859-1.\n"); + return -1; + } + + 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 0; + } + } + } + + 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(strcasecmp(encoding_name, "microsoft-symbol") == 0) { + /* deal with undocumented lossage */ + 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 0; + } + } + + return -1; +} + +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/src/FreeType/ftfuncs.c b/src/FreeType/ftfuncs.c new file mode 100644 index 0000000..fa58006 --- /dev/null +++ b/src/FreeType/ftfuncs.c @@ -0,0 +1,1770 @@ +/* +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/ftfuncs.c,v 1.27 2003/02/13 03:01:45 dawes Exp $ */ + +#include "fontmisc.h" + +#ifndef FONTMODULE +#include <string.h> +#include <math.h> +#else +#include "Xmd.h" +#include "Xdefs.h" +#include "xf86_ansic.h" +#endif + +#include "fntfilst.h" +#include "fontutil.h" +#include "FSproto.h" +#include "freetype/freetype.h" +#include "freetype/ftsizes.h" +#include "freetype/ttnameid.h" +#include "freetype/tttables.h" +#include "freetype/t1tables.h" +#include "freetype/ftxf86.h" + +#include "fontenc.h" +#include "ft.h" +#include "ftfuncs.h" + +/* 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? */ +static 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<<2) + (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 *fileName) +{ + FT_Error ftrc; + int bucket; + FTFacePtr face, otherFace; + char *realFileName; + int faceNumber; + + 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(fileName)%NUMFACEBUCKETS; + otherFace = faceTable[bucket]; + while(otherFace) { + if(strcmp(otherFace->filename, fileName) == 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; + } + + face->filename = (char*)xalloc(strlen(fileName)+1); + if(face->filename == NULL) { + xfree(face); + return AllocError; + } + strcpy(face->filename, fileName); + + face->instances = NULL; + face->active_instance = NULL; + + if(FTcheckForTTCName(fileName, &realFileName, &faceNumber)) { + ftrc = FT_New_Face(ftypeLibrary, realFileName, faceNumber, &face->face); + xfree(realFileName); + } else + ftrc = FT_New_Face(ftypeLibrary, fileName, 0, &face->face); + if(ftrc != 0) { + ErrorF("FreeType: couldn't open face %s: %d\n", fileName, ftrc); + xfree(face->filename); + xfree(face); + return BadFontPath; + } + + /* 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 +FTInstanceMatch(FTInstancePtr instance, + char *fileName, FTNormalisedTransformationPtr trans, + int charcell, FontBitmapFormatPtr bmfmt) +{ + if(strcmp(instance->face->filename, fileName) != 0) { + return 0; + } else if(!TransEqual(&instance->transformation, trans)) { + return 0; + } else if((charcell && instance->monospaced != FT_CHARCELL) || + (!charcell && instance->monospaced == FT_CHARCELL)) { + return 0; + } else if(!BitmapFormatEqual(&instance->bmfmt, bmfmt)) { + 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 +FreeTypeOpenInstance(FTInstancePtr *instance_return, + char *fileName, FTNormalisedTransformationPtr trans, + int charcell, FontBitmapFormatPtr bmfmt) +{ + FT_Error ftrc; + int xrc; + FTInstancePtr instance, otherInstance; + FTFacePtr face; + + xrc = FreeTypeOpenFace(&face, fileName); + if(xrc != Successful) { + return xrc; + } + + /* Search for a matching instance */ + for(otherInstance = face->instances; + otherInstance; + otherInstance = otherInstance->next) { + if(FTInstanceMatch(otherInstance, fileName, trans, charcell, bmfmt)) + 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->monospaced = charcell?FT_CHARCELL:0; + instance->charcellMetrics = 0; + instance->width = 0; + + instance->transformation = *trans; + instance->bmfmt = *bmfmt; + instance->nglyphs = instance->face->face->num_glyphs; + instance->glyphs = NULL; + instance->available = NULL; + + ftrc = FT_New_Size(instance->face->face, &instance->size); + if(ftrc != 0) { + ErrorF("FreeType: couldn't create size object: %d\n", ftrc); + FreeTypeFreeFace(instance->face); + xfree(instance); + return FTtoXReturnCode(ftrc); + } + FreeTypeActivateInstance(instance); + 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); + if(ftrc != 0) { + FT_Done_Size(instance->size); + FreeTypeFreeFace(instance->face); + xfree(instance); + return FTtoXReturnCode(ftrc); + } + + /* 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->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->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, FTInstancePtr instance, + CharInfoPtr **glyphs, int ***available, + int *found, int *segmentP, int *offsetP) +{ + int segment, offset; + + 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, CharInfoPtr *g, FTInstancePtr instance) +{ + int found, segment, offset; + FT_Error ftrc; + int xrc; + int ***available; + CharInfoPtr **glyphs; + + available = &instance->available; + glyphs = &instance->glyphs; + + xrc = FreeTypeInstanceFindGlyph(idx, instance, glyphs, available, + &found, &segment, &offset); + if(xrc != Successful) + return xrc; + + if(!found || (*available)[segment][offset] == FT_AVAILABLE_NO) { + *g = 0; + return Successful; + } else if((*available)[segment][offset] == FT_AVAILABLE_RASTERISED) { + *g = &(*glyphs)[segment][offset]; + return Successful; + } + + /* Tough: need to rasterise a new glyph. */ + FreeTypeActivateInstance(instance); + ftrc = FT_Load_Glyph(instance->face->face, idx, + FT_LOAD_RENDER | FT_LOAD_MONOCHROME); + if(ftrc != 0) + return FTtoXReturnCode(ftrc); + + if(instance->monospaced == FT_CHARCELL && + (*available)[segment][offset] == 0) + memcpy((char*)&(*glyphs)[segment][offset].metrics, + (char*)instance->charcellMetrics, + sizeof(xCharInfo)); + + xrc = FreeTypeRasteriseGlyph(&(*glyphs)[segment][offset], + instance, instance->monospaced == FT_CHARCELL); + if(xrc != Successful) + return xrc; + else + (*available)[segment][offset] = FT_AVAILABLE_RASTERISED; + + /* Update the width to match the width of the font */ + if(instance->monospaced) { + if((*available)[segment][offset] >= FT_AVAILABLE_RASTERISED) + (*glyphs)[segment][offset].metrics.characterWidth = instance->width; + } + + /* return the glyph */ + if((*available)[segment][offset] >= FT_AVAILABLE_RASTERISED) + *g = &(*glyphs)[segment][offset]; + else + *g = 0; + return Successful; +} + +static int +FreeTypeInstanceGetGlyphMetrics(unsigned idx, + xCharInfo **metrics, FTInstancePtr instance) +{ + CharInfoPtr g; + int xrc; + int found, segment, offset; + + xrc = FreeTypeInstanceFindGlyph(idx, instance, + &instance->glyphs, &instance->available, + &found, &segment, &offset); + if(xrc != Successful) + return xrc; + + if(!found) { + *metrics = 0; + return Successful; + } + + if(instance->available[segment][offset] == 0) { + if(instance->monospaced < FT_CHARCELL) { + xrc = FreeTypeInstanceGetGlyph(idx, &g, instance); + if(xrc != Successful) + return xrc; + } else { + memcpy((char*)&instance->glyphs[segment][offset].metrics, + (char*)instance->charcellMetrics, + sizeof(xCharInfo)); + instance->available[segment][offset] = FT_AVAILABLE_YES; + } + } + + if(instance->available[segment][offset] >= FT_AVAILABLE_YES) { + *metrics = &instance->glyphs[segment][offset].metrics; + } else + *metrics = 0; + + return Successful; +} + +int +FreeTypeRasteriseGlyph(CharInfoPtr tgp, FTInstancePtr instance, + int hasMetrics) +{ +#define TRANSFORM_X(x_value) \ + ((int)floor((((double)(x_value)*(double)instance->transformation.matrix.xx)/\ + (TWO_SIXTEENTH*TWO_SIXTH))+0.5)) + +#define TRANSFORM_Y(y_value) \ + ((int)floor((((double)(y_value)*(double)instance->transformation.matrix.yy)/\ + (TWO_SIXTEENTH*TWO_SIXTH))+0.5)) + +#define TRANSFORM_X_RAW(value) \ + ((int)floor((double)(value)/instance->transformation.scale/TWO_SIXTH/(smetrics.x_ppem/72.0)*1000.0+0.5)) + + FTFacePtr face; + FT_Bitmap *bitmap; + char *raster = NULL; + FT_Size_Metrics smetrics; + FT_Glyph_Metrics *metrics; + int wd, ht, bpr; /* width, height, bytes per row */ + int dx, dy; + int leftSideBearing, rightSideBearing, characterWidth, rawCharacterWidth, + ascent, descent; + int i = 0, j; + + face = instance->face; + smetrics = instance->size->metrics; + + FreeTypeActivateInstance(instance); + + metrics = &face->face->glyph->metrics; + bitmap = &face->face->glyph->bitmap; + + if(hasMetrics) { + wd = tgp->metrics.rightSideBearing - tgp->metrics.leftSideBearing; + ht = tgp->metrics.ascent + tgp->metrics.descent; + dx = -tgp->metrics.leftSideBearing + + TRANSFORM_X(metrics->horiBearingX); + dy = tgp->metrics.ascent - TRANSFORM_Y(metrics->horiBearingY); + } else { + wd = bitmap->width; + ht = bitmap->rows; + dx = 0; + dy = 0; + /* The X convention is to consider a character with an empty + * bounding box as undefined. This convention is broken. */ + if(wd <= 0) wd = 1; + if(ht <= 0) ht = 1; + } + + /* Make sure rounding doesn't cause a crash in memcpy below */ + if(wd < bitmap->width) + wd = bitmap->width; + if(ht < bitmap->rows) + ht = bitmap->rows; + + bpr = (((wd + (instance->bmfmt.glyph<<3) - 1) >> 3) & + -instance->bmfmt.glyph); + if(tgp) { + raster = (char*)xalloc(ht * bpr); + if(raster == NULL) + return AllocError; + memset(raster, 0, ht * bpr); + } + + if(dx == 0 && dy == 0 && bpr == bitmap->pitch) { + memcpy(raster, bitmap->buffer, bitmap->rows * bitmap->pitch); + } else if(dx == 0) { + for(i = MAX(0, -dy); i < bitmap->rows && i + dy < ht; i++) + memcpy(raster + (i + dy) * bpr, + bitmap->buffer + i * bitmap->pitch, + bitmap->pitch); + } else { + for(i = MAX(0, -dy); i < bitmap->rows && i + dy < ht; i++) { + for(j = MAX(0, -dx); j < bitmap->width && j + dx < wd; j++) { + int set; + set = (bitmap->buffer[i * bitmap->pitch + j / 8] & + 1 << (7 - j % 8)); + if(set) + raster[(i + dy) * bpr + (j + dx) / 8] |= + 1 << (7 - (j + dx) % 8); + } + } + } + + tgp->bits = raster; + + 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: + ; + } + } + + + if(!hasMetrics) { + leftSideBearing = TRANSFORM_X(metrics->horiBearingX); + rightSideBearing = wd + TRANSFORM_X(metrics->horiBearingX); + + characterWidth = TRANSFORM_X(metrics->horiAdvance); + rawCharacterWidth = TRANSFORM_X_RAW(metrics->horiAdvance); + + ascent = TRANSFORM_Y(metrics->horiBearingY); + descent = ht - TRANSFORM_Y(metrics->horiBearingY); + + if(tgp) { + /* 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; + } + } + return Successful; +#undef TRANSFORM_X +#undef TRANSFORM_Y +#undef TRANSFORM_X_RAW +} + +static void +FreeTypeFreeFont(FTFontPtr font) +{ + FreeTypeFreeInstance(font->instance); + if(font->ranges) + xfree(font->ranges); + 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) +{ + int i, j, maxprops; + char *sp, *ep, val[MAXFONTNAMELEN], *vp; + FTFacePtr face; + FTInstancePtr instance; + FT_Size_Metrics smetrics; + 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; + smetrics = instance->size->metrics; + trans = &instance->transformation; + upm = face->face->units_per_EM; + + 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 */ + 8 + + (os2 ? 6 : 0) + + (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_AVERAGE_WIDTH", 17, TRUE); + info->props[i].value = rawAverageWidth; + i++; + + info->props[i].name = MakeAtom("FONT_ASCENT", 11, TRUE); + info->props[i].value = info->fontAscent; + i++; + + info->props[i].name = MakeAtom("RAW_ASCENT", 15, TRUE); + info->props[i].value = + ((double)face->face->ascender/(double)upm*1000.0); + i++; + + info->props[i].name = MakeAtom("FONT_DESCENT", 12, TRUE); + info->props[i].value = info->fontDescent; + i++; + + info->props[i].name = MakeAtom("RAW_DESCENT", 16, 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++; + } + + 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)trans->matrix.xx/TWO_SIXTEENTH)*(double)smetrics.x_ppem)+\ + 0.5)) + +#define TRANSFORM_FUNITS_Y(yval) \ + ((int) \ + floor((((double)(yval)/(double)upm) * \ + ((double)trans->matrix.yy/TWO_SIXTEENTH) * (double)smetrics.y_ppem)+\ + 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(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(post || t1info) { + int underlinePosition, underlineThickness; + + 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 +FreeTypeFontGetGlyph(unsigned code, CharInfoPtr *g, FTFontPtr font) +{ + unsigned idx; + int i; + + /* 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. */ + + if(code > 0 && font->nranges) { + 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) { + *g = 0; + return Successful; + } + } + + idx = FTRemap(font->instance->face->face, &font->mapping, code); + + /* Only pass the default glyph if there is no first index */ + if(idx == 0 && + (code != 0 || + (font->mapping.mapping && + (font->mapping.mapping->encoding->first != 0 || + font->mapping.mapping->encoding->first_col != 0)))) { + *g = 0; + return Successful; + } else { + return FreeTypeInstanceGetGlyph(idx, g, font->instance); + } +} + +static int +FreeTypeFontGetGlyphMetrics(unsigned code, xCharInfo **metrics, FTFontPtr font) +{ + unsigned idx; + int i; + + /* 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. */ + + if(code>0 && font->nranges) { + 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) { + *metrics = 0; + return Successful; + } + } + + idx = FTRemap(font->instance->face->face, &font->mapping, code); + + if(idx == 0 && + (code != 0 || + (font->mapping.mapping && + (font->mapping.mapping->encoding->first != 0 || + font->mapping.mapping->encoding->first_col != 0)))) { + *metrics = 0; + return Successful; + } else { + return FreeTypeInstanceGetGlyphMetrics(idx, metrics, font->instance); + } +} + +static int +FreeTypeFontGetDefaultGlyph(CharInfoPtr *g, FTFontPtr font) +{ + /* Disable default glyph generation if there is a first index */ + if(font->mapping.mapping && + (font->mapping.mapping->encoding->first || + font->mapping.mapping->encoding->first_col)) { + *g = 0; + return Successful; + } + + /* Using FreeTypeInstanceGetGlyph(0,...) would cause inconsistencies + between metrics and glyphs in the unlikely case that 0 is not + mapped to 0. */ + return FreeTypeFontGetGlyph(0, g, font); +} + +static int +FreeTypeLoadFont(FTFontPtr *font_return, char *fileName, + FontScalablePtr vals, FontEntryPtr entry, + FontBitmapFormatPtr bmfmt) +{ + int xrc; + FTFontPtr font; + FTNormalisedTransformationRec trans; + int charcell; + + font = (FTFontPtr)xalloc(sizeof(FTFontRec)); + if(font == NULL) + return AllocError; + + /* 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 = MAX(hypot(vals->point_matrix[0], vals->point_matrix[2]), + hypot(vals->point_matrix[1], 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; + + /* Check for charcell in XLFD */ + charcell = 0; + 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]=='-') + charcell=1; + break; + } + } + } + } + + xrc = FreeTypeOpenInstance(&font->instance, + fileName, &trans, charcell, bmfmt); + if(xrc != Successful) + return xrc; + + if(entry->name.ndashes == 14) { + if(FTPickMapping(entry->name.name, entry->name.length, fileName, + font->instance->face->face, &font->mapping)) + return BadFontFormat; + } else { + if(FTPickMapping(0, 0, fileName, + font->instance->face->face, &font->mapping)) + return BadFontFormat; + } + + + font->nranges = vals->nranges; + font->ranges = 0; + if(font->nranges) { + font->ranges = (fsRange*)xalloc(vals->nranges*sizeof(fsRange)); + if(font->ranges == NULL) { + FreeTypeFreeFont(font); + return AllocError; + } + memcpy((char*)font->ranges, (char*)vals->ranges, + vals->nranges*sizeof(fsRange)); + } + *font_return = font; + + return Successful; +} + +/* Given a BBox in FUnits, return a transformed BBox in pixels */ +static void +transformBBox(FTNormalisedTransformationPtr transformation, + int upm, int x_ppem, int y_ppem, + int x1, int y1, int x2, int y2, + int *tx1p, int *ty1p, int *tx2p, int *ty2p) +{ + double + xx1, yy1, xx2, yy2, + tx11, ty11, tx12, ty12, tx21, ty21, tx22, ty22, + tx1, ty1, tx2, ty2; + + /* Convert arguments to EM units */ + + xx1 = ((double)x1/(double)upm); + yy1 = ((double)y1/(double)upm); + xx2 = ((double)x2/(double)upm); + yy2 = ((double)y2/(double)upm); + + /* Apply transformation matrix */ + + if(!transformation->nonIdentity) { + tx1 = xx1; + ty1 = yy1; + tx2 = xx2; + ty2 = yy2; + } else { + /* Not an identity matrix, need to compute images of all corners */ + tx11 = + (transformation->matrix.xx/TWO_SIXTEENTH)*xx1 + + (transformation->matrix.xy/TWO_SIXTEENTH)*yy1; + ty11 = + (transformation->matrix.yx/TWO_SIXTEENTH)*xx1 + + (transformation->matrix.yy/TWO_SIXTEENTH)*yy1; + tx12 = + (transformation->matrix.xx/TWO_SIXTEENTH)*xx1 + + (transformation->matrix.xy/TWO_SIXTEENTH)*yy2; + ty12 = + (transformation->matrix.yx/TWO_SIXTEENTH)*xx1 + + (transformation->matrix.yy/TWO_SIXTEENTH)*yy2; + tx21 = + (transformation->matrix.xx/TWO_SIXTEENTH)*xx2 + + (transformation->matrix.xy/TWO_SIXTEENTH)*yy1; + ty21 = + (transformation->matrix.yx/TWO_SIXTEENTH)*xx2 + + (transformation->matrix.yy/TWO_SIXTEENTH)*yy1; + tx22 = + (transformation->matrix.xx/TWO_SIXTEENTH)*xx2 + + (transformation->matrix.xy/TWO_SIXTEENTH)*yy2; + ty22 = + (transformation->matrix.yx/TWO_SIXTEENTH)*xx2 + + (transformation->matrix.yy/TWO_SIXTEENTH)*yy2; + + /* Compute the corners of the new bounding box */ + + tx1 = MIN(MIN(tx11,tx12),MIN(tx21,tx22)); + ty1 = MIN(MIN(ty11,ty12),MIN(ty21,ty22)); + tx2 = MAX(MAX(tx11,tx12),MAX(tx21,tx22)); + ty2 = MAX(MAX(ty11,ty12),MAX(ty21,ty22)); + } + + + /* Convert to device space */ + *tx1p = (int)floor(tx1*(double)x_ppem); + *ty1p = (int)floor(ty1*(double)y_ppem); + *tx2p = (int)ceil(tx2*(double)x_ppem); + *ty2p = (int)ceil(ty2*(double)y_ppem); + + /* Ensure the resulting bounding box is not empty */ + if(*tx1p == *tx2p) + (*tx2p)++; + if(*ty1p == *ty2p) + (*ty2p)++; +} + +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; +} + +/* 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) +{ +#define TRANSFORM_FUNITS_X(xval) \ + ((int) \ + floor((((double)(xval)/(double)upm) * \ + ((double)instance->transformation.matrix.xx/TWO_SIXTEENTH)*(double)smetrics.x_ppem)+0.5)) +#define TRANSFORM_FUNITS_X_DOWN(xval) \ + ((int) \ + floor((((double)(xval)/(double)upm) * \ + ((double)instance->transformation.matrix.xx/TWO_SIXTEENTH)*(double)smetrics.x_ppem))) +#define TRANSFORM_FUNITS_X_UP(xval) \ + ((int) \ + ceil((((double)(xval)/(double)upm) * \ + ((double)instance->transformation.matrix.xx/TWO_SIXTEENTH)*(double)smetrics.x_ppem))) +#define TRANSFORM_FUNITS_Y(yval) \ + ((int) \ + floor((((double)(yval)/(double)upm) * \ + ((double)instance->transformation.matrix.yy/TWO_SIXTEENTH)*(double)smetrics.x_ppem)+0.5)) +#define TRANSFORM_FUNITS_Y_DOWN(yval) \ + ((int) \ + floor((((double)(yval)/(double)upm) * \ + ((double)instance->transformation.matrix.yy/TWO_SIXTEENTH) * (double)smetrics.y_ppem))) +#define TRANSFORM_FUNITS_Y_UP(yval) \ + ((int) \ + ceil((((double)(yval)/(double)upm) * \ + ((double)instance->transformation.matrix.yy/TWO_SIXTEENTH) * (double)smetrics.y_ppem))) +#define TRANSFORM_FUNITS_RAW(value) \ + ((long) \ + floor(((double)(value)/(double)upm) * 1000.0 + 0.5)) +#define TRANSFORM_FUNITS_RAW_DOWN(value) \ + ((long) \ + floor(((double)(value)/(double)upm) * 1000.0)) +#define TRANSFORM_FUNITS_RAW_UP(value) \ + ((long) \ + ceil(((double)(value)/(double)upm) * 1000.0)) + + + FTFontPtr font; + FTInstancePtr instance; + FT_Size_Metrics smetrics; + FTFacePtr face; + int xrc, i; + int charcell, constantWidth; + long rawWidth, rawAverageWidth, aw, code, lastCode, firstCode; + int upm, minLsb, maxRsb, ascent, descent, width, averageWidth; + + + xrc = FreeTypeLoadFont(&font, fileName, vals, entry, bmfmt); + if(xrc != Successful) + return xrc; + + instance = font->instance; + face = instance->face; + smetrics = instance->size->metrics; + + upm = face->face->units_per_EM; + charcell = (instance->monospaced == FT_CHARCELL); + constantWidth = charcell || is_fixed_width(face->face); + if(constantWidth && instance->monospaced == 0) + instance->monospaced = FT_MONOSPACED; + + /* There's no way to get the average width right without rasterising + all of the glyphs. We make a serious attempt at getting it right + for monospaced fonts, and try to provide a reasonable + approximation for others. */ + + if(constantWidth) + aw = face->face->max_advance_width; + else + aw = face->face->max_advance_width / 2; + + if(constantWidth) + averageWidth = 10*TRANSFORM_FUNITS_X(aw); + else + averageWidth = TRANSFORM_FUNITS_X(aw*10L); + rawAverageWidth = TRANSFORM_FUNITS_RAW(aw*10L); + + vals->width = averageWidth; + + if(info) { + info->fontAscent = + TRANSFORM_FUNITS_Y(face->face->ascender); + info->fontDescent = + -TRANSFORM_FUNITS_Y(face->face->descender); + firstCode = 0; + lastCode = 0xFFFFL; + if(font->nranges) { + lastCode = 0; + /* The ranges information does not have an effect on firstCode, + as we pass the default glyph at position 0. */ + for(i=0; i<font->nranges; i++) { + code = font->ranges[i].max_char_low + + (font->ranges[i].max_char_high<<8); + if(lastCode < code) + lastCode = code; + } + } + + 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); + } 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); + } + + /* firstCode and lastCode are not valid in case of a matrix + encoding */ + + transformBBox(&instance->transformation, upm, + smetrics.x_ppem, smetrics.y_ppem, + charcell? 0 : + face->face->bbox.xMin, + face->face->bbox.yMin, + charcell ? + face->face->max_advance_width : + face->face->bbox.xMax, + face->face->bbox.yMax, + &minLsb, &descent, &maxRsb, &ascent); + descent = -descent; + + width = TRANSFORM_FUNITS_X(face->face->max_advance_width); + rawWidth = + TRANSFORM_FUNITS_RAW(face->face->max_advance_width); + instance->width = width; + + info->constantWidth=constantWidth; + info->constantMetrics=charcell; + + info->minbounds.leftSideBearing = minLsb; + info->minbounds.rightSideBearing = charcell?maxRsb:minLsb; + info->minbounds.characterWidth = constantWidth?width:-width; + info->minbounds.ascent = charcell?ascent:-descent; + info->minbounds.descent = charcell?descent:-ascent; + info->minbounds.attributes = + (unsigned short)(short)(constantWidth?rawWidth:-rawWidth); + + info->maxbounds.leftSideBearing = charcell?minLsb:maxRsb; + info->maxbounds.rightSideBearing = maxRsb; + info->maxbounds.characterWidth = width; + info->maxbounds.ascent = ascent; + info->maxbounds.descent = descent; + info->maxbounds.attributes = (unsigned short)(short)rawWidth; + + if(charcell && instance->charcellMetrics == 0) { + instance->charcellMetrics = (xCharInfo*)xalloc(sizeof(xCharInfo)); + if(instance->charcellMetrics == 0) { + FreeTypeFreeFont(font); + return AllocError; + } + memcpy((char*)instance->charcellMetrics, + (char*)&info->maxbounds, sizeof(xCharInfo)); + } + + /* 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; + } + + if(xf) + xf->fontPrivate = (void*)font; + + if(info) { + xrc = FreeTypeAddProperties(font, vals, info, entry->name.name, + rawAverageWidth); + if (xrc != Successful) { + FreeTypeFreeFont(font); + return xrc; + } + } + + return Successful; +#undef TRANSFORM_FUNITS_X +#undef TRANSFORM_FUNITS_X_DOWN +#undef TRANSFORM_FUNITS_X_UP +#undef TRANSFORM_FUNITS_Y +#undef TRANSFORM_FUNITS_Y_DOWN +#undef TRANSFORM_FUNITS_Y_UP +#undef TRANSFORM_FUNITS_RAW +#undef TRANSFORM_FUNITS_RAW_DOWN +#undef TRANSFORM_FUNITS_RAW_UP +} + +/* 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; + FTFontPtr tf; + xCharInfo **mp, *m; + + + /* The compiler is supposed to initialise all the fields to 0 */ + static xCharInfo noSuchChar; + + /* MUMBLE1("Get metrics for %ld characters\n", count);*/ + + tf = (FTFontPtr)pFont->fontPrivate; + mp = metrics; + + while (count-- > 0) { + switch (charEncoding) { + case Linear8Bit: + case TwoD8Bit: + code = *chars++; + break; + case Linear16Bit: + case TwoD16Bit: + code = (*chars++ << 8); + code |= *chars++; + break; + } + + if(FreeTypeFontGetGlyphMetrics(code, &m, tf) == Successful && m!=0) { + *mp++ = m; + } else + *mp++ = &noSuchChar; + } + + *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; + FTFontPtr tf; + CharInfoPtr *gp; + CharInfoPtr g; + + tf = (FTFontPtr)pFont->fontPrivate; + gp = glyphs; + + while (count-- > 0) { + switch (charEncoding) { + case Linear8Bit: case TwoD8Bit: + code = *chars++; + break; + case Linear16Bit: case TwoD16Bit: + code = *chars++ << 8; + code |= *chars++; + break; + } + + if(FreeTypeFontGetGlyph(code, &g, tf) == Successful && g!=0) { + *gp++ = g; + } else + if(FreeTypeFontGetDefaultGlyph(&g, tf) == Successful && g!=0) + *gp++ = g; + } + + *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"); + + /* Reject ridiculously small values. Singular matrices are okay. */ + if(MAX(hypot(vals->pixel_matrix[0], vals->pixel_matrix[1]), + hypot(vals->pixel_matrix[2], vals->pixel_matrix[3])) + <1.0) + return BadFontName; + + /* Create an X11 server-side font. */ + xf = CreateFontRec(); + if (xf == NULL) + return AllocError; + + xrc = FreeTypeSetUpFont(fpe, xf, &xf->info, format, fmask, &bmfmt); + if(xrc != Successful) { + DestroyFontRec(xf); + return xrc; + } + /* Load the font and fill its info structure. */ + xrc = FreeTypeLoadXFont(fileName, vals, xf, &xf->info, &bmfmt, entry); + if(xrc != Successful) { + /* Free everything up at this level and return the error code. */ + MUMBLE1("Error during load: %d\n",xrc); + DestroyFontRec(xf); + return xrc; + } + + /* Set the font and return. */ + *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"); + + if(MAX(hypot(vals->pixel_matrix[0], vals->pixel_matrix[1]), + hypot(vals->pixel_matrix[2], vals->pixel_matrix[3])) < 1.0) + return BadFontName; + + 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]); + +void +FreeTypeRegisterFontFileFunctions(void) +{ + int i; + + for (i = 0; i < num_renderers; i++) + FontFileRegisterRenderer(&renderers[i]); +} diff --git a/src/FreeType/ftfuncs.h b/src/FreeType/ftfuncs.h new file mode 100644 index 0000000..6d57abe --- /dev/null +++ b/src/FreeType/ftfuncs.h @@ -0,0 +1,122 @@ +/* +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/ftfuncs.h,v 1.12 2002/10/01 00:02:10 alanh 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; + 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_MONOSPACED 1 +#define FT_CHARCELL 2 + +#define FT_AVAILABLE_UNKNOWN 0 +#define FT_AVAILABLE_NO 1 +#define FT_AVAILABLE_YES 2 +#define FT_AVAILABLE_RASTERISED 3 + +/* 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; + int monospaced; + int width; /* the width of all glyphs if monospaced */ + xCharInfo *charcellMetrics; /* the metrics if charcell is 1 */ + FontBitmapFormatRec bmfmt; + unsigned nglyphs; + CharInfoPtr *glyphs; /* glyphs and available are used in parallel */ + int **available; + 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; + int nranges; + fsRange *ranges; +} FTFontRec, *FTFontPtr; + +/* Prototypes for some local functions */ + +static int FreeTypeOpenFace(FTFacePtr *facep, char *fileName); +static void FreeTypeFreeFace(FTFacePtr face); +static int + FreeTypeOpenInstance(FTInstancePtr *instancep, + char *fileName, FTNormalisedTransformationPtr trans, + int charcell, FontBitmapFormatPtr bmfmt); +static void FreeTypeFreeInstance(FTInstancePtr instance); +static int + FreeTypeInstanceGetGlyph(unsigned idx, CharInfoPtr *g, FTInstancePtr instance); +static int +FreeTypeRasteriseGlyph(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); +static int FreeTypeFontGetGlyph(unsigned code, CharInfoPtr *g, FTFontPtr font); +static int FreeTypeFontGetDefaultGlyph(CharInfoPtr *g, FTFontPtr font); +static int +FreeTypeLoadFont(FTFontPtr *fontp, char *fileName, + FontScalablePtr vals, FontEntryPtr entry, + FontBitmapFormatPtr bmfmt); diff --git a/src/FreeType/ftsystem.c b/src/FreeType/ftsystem.c new file mode 100644 index 0000000..300ff5a --- /dev/null +++ b/src/FreeType/ftsystem.c @@ -0,0 +1,329 @@ +/***************************************************************************/ +/* */ +/* 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: xc/lib/font/FreeType/ftsystem.c,v 1.3 2002/10/01 00:02:10 alanh Exp $ */ + + /*************************************************************************/ + /* */ + /* 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. */ + /* */ + /*************************************************************************/ + + +#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/src/FreeType/fttools.c b/src/FreeType/fttools.c new file mode 100644 index 0000000..f6510af --- /dev/null +++ b/src/FreeType/fttools.c @@ -0,0 +1,188 @@ +/* + 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.4 2003/02/25 21:36:54 dawes Exp $ */ + +#include "fontmisc.h" +#ifndef FONTMODULE +#include <ctype.h> +#include <string.h> +#else +#include "Xmd.h" +#include "Xdefs.h" +#include "xf86_ansic.h" +#endif + +#include "font.h" +#include "freetype/freetype.h" +#include "freetype/ftsnames.h" +#include "freetype/ttnameid.h" +#include "ft.h" + +#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; + else return BadFontFormat; +} + +/* 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. */ +int +FTu2a(int slen, char *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, name_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(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/src/Speedo/bics-unicode.c b/src/Speedo/bics-unicode.c new file mode 100644 index 0000000..22eed88 --- /dev/null +++ b/src/Speedo/bics-unicode.c @@ -0,0 +1,135 @@ +/* +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: xc/lib/font/Speedo/bics-unicode.c,v 1.1 1999/01/31 04:59:25 dawes Exp $ */ + +/* These data are very dodgy. */ + +#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/src/Speedo/bics-unicode.h b/src/Speedo/bics-unicode.h new file mode 100644 index 0000000..3cf2ae4 --- /dev/null +++ b/src/Speedo/bics-unicode.h @@ -0,0 +1,3 @@ +/* $XFree86: xc/lib/font/Speedo/bics-unicode.h,v 1.1 1999/01/31 04:59:26 dawes Exp $ */ + +int unicode_to_bics(unsigned); diff --git a/src/Type1/AFM.h b/src/Type1/AFM.h new file mode 100644 index 0000000..4f44b08 --- /dev/null +++ b/src/Type1/AFM.h @@ -0,0 +1,58 @@ +/* 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 +#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/src/Type1/afm.c b/src/Type1/afm.c new file mode 100644 index 0000000..960e76f --- /dev/null +++ b/src/Type1/afm.c @@ -0,0 +1,187 @@ +/* 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.3 2001/08/27 19:49:52 dawes Exp $ */ + +#ifdef BUILDCID +#ifndef FONTMODULE +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#else +#include "Xmd.h" /* For INT32 declaration */ +#include "Xdefs.h" /* For Bool */ +#include "xf86_ansic.h" +#endif +#include "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); + + 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/src/Type1/cidchar.c b/src/Type1/cidchar.c new file mode 100644 index 0000000..e70d371 --- /dev/null +++ b/src/Type1/cidchar.c @@ -0,0 +1,617 @@ +/* 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.9 2001/10/28 03:32:44 tsi Exp $ */ + +#ifdef BUILDCID +#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 "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) +{ + int rc; + FILE *fp; + FontInfo *fi = NULL; + cidglyphs *cid; + CharInfoPtr *glyphsBase; + register unsigned int c; + + register CharInfoPtr pci; + CharInfoPtr pDefault; + unsigned int firstRow, firstCol, numRows, code, char_row, char_col; + double sxmult; + + cid = (cidglyphs *)pFont->fontPrivate; + + if (cid->AFMinfo == NULL) { + if (!(fp = fopen(cidafmfile, "rb"))) + return(BadFontName); + + if ((rc = 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: + firstRow = pFont->info.firstRow; + numRows = pFont->info.lastRow - firstRow + 1; + 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/src/Type1/range.h b/src/Type1/range.h new file mode 100644 index 0000000..c611e72 --- /dev/null +++ b/src/Type1/range.h @@ -0,0 +1,44 @@ +/* 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 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/src/Type1/t1unicode.c b/src/Type1/t1unicode.c new file mode 100644 index 0000000..c6b1cd9 --- /dev/null +++ b/src/Type1/t1unicode.c @@ -0,0 +1,248 @@ +/* +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: xc/lib/font/Type1/t1unicode.c,v 1.1 1999/01/31 04:59:30 dawes Exp $ */ + +#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/src/Type1/t1unicode.h b/src/Type1/t1unicode.h new file mode 100644 index 0000000..f2a13fd --- /dev/null +++ b/src/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: xc/lib/font/Type1/t1unicode.h,v 1.1 1999/01/31 04:59:31 dawes Exp $ */ + +char *unicodetoPSname(unsigned short code); diff --git a/src/builtins/buildfont b/src/builtins/buildfont new file mode 100644 index 0000000..aa4602f --- /dev/null +++ b/src/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/src/builtins/builtin.h b/src/builtins/builtin.h new file mode 100644 index 0000000..caee81c --- /dev/null +++ b/src/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.4 2000/02/23 20:29:33 dawes Exp $ */ + +#include <X11/Xdefs.h> +#include <font.h> +#include "fontxlfd.h" +#include "fntfil.h" +#include "fntfilio.h" +#include "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/src/builtins/dir.c b/src/builtins/dir.c new file mode 100644 index 0000000..c657710 --- /dev/null +++ b/src/builtins/dir.c @@ -0,0 +1,61 @@ +/* + * 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.4 2000/02/23 20:29:33 dawes Exp $ */ + +#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/src/builtins/file.c b/src/builtins/file.c new file mode 100644 index 0000000..6fcaa79 --- /dev/null +++ b/src/builtins/file.c @@ -0,0 +1,135 @@ +/* + * 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.4 2000/02/23 20:29:33 dawes Exp $ */ + +#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; +} + +BuiltinFileClose (f) + FontFilePtr f; +{ + return BufFileClose ((BufFilePtr) f, TRUE); +} diff --git a/src/builtins/fonts.c b/src/builtins/fonts.c new file mode 100644 index 0000000..cc7928e --- /dev/null +++ b/src/builtins/fonts.c @@ -0,0 +1,2435 @@ +/* + * 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.4 2000/02/23 20:29:34 dawes Exp $ */ + +#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/src/builtins/fpe.c b/src/builtins/fpe.c new file mode 100644 index 0000000..d96fc3d --- /dev/null +++ b/src/builtins/fpe.c @@ -0,0 +1,93 @@ +/* + * 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.4 2000/02/23 20:29:36 dawes Exp $ */ + +#include "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; +} + +BuiltinRegisterFpeFunctions() +{ + 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/src/builtins/render.c b/src/builtins/render.c new file mode 100644 index 0000000..5f63c66 --- /dev/null +++ b/src/builtins/render.c @@ -0,0 +1,109 @@ +/* + * 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.4 2000/02/23 20:29:36 dawes Exp $ */ + +#include "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]) + +BuiltinRegisterFontFileFunctions() +{ + int i; + for (i = 0; i < numRenderers; i++) + FontFileRegisterRenderer ((FontRendererRec *) &renderers[i]); +} + diff --git a/src/fontcache/fcqueue.h b/src/fontcache/fcqueue.h new file mode 100644 index 0000000..58ba6df --- /dev/null +++ b/src/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/src/fontcache/fontcache.c b/src/fontcache/fontcache.c new file mode 100644 index 0000000..0fec03b --- /dev/null +++ b/src/fontcache/fontcache.c @@ -0,0 +1,1019 @@ +/*- + * 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.5 2001/10/28 03:32:45 tsi Exp $ */ + +#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/src/fontcache/fontcache.h b/src/fontcache/fontcache.h new file mode 100644 index 0000000..3a10b9f --- /dev/null +++ b/src/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.7 2003/01/26 03:02:19 dawes Exp $ */ + +#ifndef _FONTCACHE_H_ +#define _FONTCACHE_H_ + +#include "fontmisc.h" +#include "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/src/fontfile/fontencc.c b/src/fontfile/fontencc.c new file mode 100644 index 0000000..2c8bdbd --- /dev/null +++ b/src/fontfile/fontencc.c @@ -0,0 +1,74 @@ +/* +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.2 2001/08/16 14:33:46 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. */ + +#include "fontenc.h" +#include "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/src/stubs/cauthgen.c b/src/stubs/cauthgen.c new file mode 100644 index 0000000..b40a440 --- /dev/null +++ b/src/stubs/cauthgen.c @@ -0,0 +1,11 @@ +/* $XFree86: xc/lib/font/stubs/cauthgen.c,v 1.1 1999/01/11 05:13:18 dawes Exp $ */ + +#include "stubs.h" + +int +client_auth_generation(ClientPtr client) +{ + return 0; +} + +/* end of file */ diff --git a/src/stubs/csignal.c b/src/stubs/csignal.c new file mode 100644 index 0000000..668f4f5 --- /dev/null +++ b/src/stubs/csignal.c @@ -0,0 +1,11 @@ +/* $XFree86: xc/lib/font/stubs/csignal.c,v 1.1 1999/01/11 05:13:18 dawes Exp $ */ + +#include "stubs.h" + +Bool +ClientSignal(ClientPtr client) +{ + return True; +} + +/* end of file */ diff --git a/src/stubs/delfntcid.c b/src/stubs/delfntcid.c new file mode 100644 index 0000000..a9aaf35 --- /dev/null +++ b/src/stubs/delfntcid.c @@ -0,0 +1,10 @@ +/* $XFree86: xc/lib/font/stubs/delfntcid.c,v 1.1 1999/01/11 05:13:19 dawes Exp $ */ + +#include "stubs.h" + +void +DeleteFontClientID(Font id) +{ +} + +/* end of file */ diff --git a/src/stubs/errorf.c b/src/stubs/errorf.c new file mode 100644 index 0000000..44d675c --- /dev/null +++ b/src/stubs/errorf.c @@ -0,0 +1,10 @@ +/* $XFree86: xc/lib/font/stubs/errorf.c,v 1.1 1999/01/11 05:13:19 dawes Exp $ */ + +#include "stubs.h" + +void +ErrorF(char *f) +{ +} + +/* end of file */ diff --git a/src/stubs/fatalerror.c b/src/stubs/fatalerror.c new file mode 100644 index 0000000..62f571c --- /dev/null +++ b/src/stubs/fatalerror.c @@ -0,0 +1,10 @@ +/* $XFree86: xc/lib/font/stubs/fatalerror.c,v 1.1 1999/01/11 05:13:19 dawes Exp $ */ + +#include "stubs.h" + +void +FatalError(char *f) +{ +} + +/* end of file */ diff --git a/src/stubs/findoldfnt.c b/src/stubs/findoldfnt.c new file mode 100644 index 0000000..ce8a9de --- /dev/null +++ b/src/stubs/findoldfnt.c @@ -0,0 +1,11 @@ +/* $XFree86: xc/lib/font/stubs/findoldfnt.c,v 1.1 1999/01/11 05:13:19 dawes Exp $ */ + +#include "stubs.h" + +FontPtr +find_old_font(FSID id) +{ + return (FontPtr)NULL; +} + +/* end of file */ diff --git a/src/stubs/getcres.c b/src/stubs/getcres.c new file mode 100644 index 0000000..e1ce577 --- /dev/null +++ b/src/stubs/getcres.c @@ -0,0 +1,11 @@ +/* $XFree86: xc/lib/font/stubs/getcres.c,v 1.1 1999/01/11 05:13:20 dawes Exp $ */ + +#include "stubs.h" + +FontResolutionPtr +GetClientResolutions(int *num) +{ + return (FontResolutionPtr) 0; +} + +/* end of file */ diff --git a/src/stubs/getdefptsize.c b/src/stubs/getdefptsize.c new file mode 100644 index 0000000..ada6c6a --- /dev/null +++ b/src/stubs/getdefptsize.c @@ -0,0 +1,11 @@ +/* $XFree86: xc/lib/font/stubs/getdefptsize.c,v 1.1 1999/01/11 05:13:20 dawes Exp $ */ + +#include "stubs.h" + +int +GetDefaultPointSize(void) +{ + return 0; +} + +/* end of file */ diff --git a/src/stubs/getnewfntcid.c b/src/stubs/getnewfntcid.c new file mode 100644 index 0000000..a65fd27 --- /dev/null +++ b/src/stubs/getnewfntcid.c @@ -0,0 +1,11 @@ +/* $XFree86: xc/lib/font/stubs/getnewfntcid.c,v 1.1 1999/01/11 05:13:20 dawes Exp $ */ + +#include "stubs.h" + +Font +GetNewFontClientID(void) +{ + return (Font)0; +} + +/* end of file */ diff --git a/src/stubs/gettime.c b/src/stubs/gettime.c new file mode 100644 index 0000000..023441f --- /dev/null +++ b/src/stubs/gettime.c @@ -0,0 +1,11 @@ +/* $XFree86: xc/lib/font/stubs/gettime.c,v 1.1 1999/12/15 01:14:36 robin Exp $ */ + +#include "stubs.h" + +unsigned long +GetTimeInMillis (void) +{ + return 0; +} + +/* end of file */ diff --git a/src/stubs/initfshdl.c b/src/stubs/initfshdl.c new file mode 100644 index 0000000..13d2230 --- /dev/null +++ b/src/stubs/initfshdl.c @@ -0,0 +1,12 @@ +/* $XFree86: xc/lib/font/stubs/initfshdl.c,v 1.1 1999/01/11 05:13:20 dawes Exp $ */ + +#include "stubs.h" + +int +init_fs_handlers(FontPathElementPtr fpe, + void (*block_handler)()) +{ + return Successful; +} + +/* end of file */ diff --git a/src/stubs/regfpefunc.c b/src/stubs/regfpefunc.c new file mode 100644 index 0000000..96f4b92 --- /dev/null +++ b/src/stubs/regfpefunc.c @@ -0,0 +1,25 @@ +/* $XFree86: xc/lib/font/stubs/regfpefunc.c,v 1.2 1999/08/21 13:48:07 dawes Exp $ */ + +#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/src/stubs/rmfshdl.c b/src/stubs/rmfshdl.c new file mode 100644 index 0000000..4e6d1da --- /dev/null +++ b/src/stubs/rmfshdl.c @@ -0,0 +1,12 @@ +/* $XFree86: xc/lib/font/stubs/rmfshdl.c,v 1.1 1999/01/11 05:13:21 dawes Exp $ */ + +#include "stubs.h" + +void +remove_fs_handlers(FontPathElementPtr fpe, + void (*block_handler) (), + Bool all) +{ +} + +/* end of file */ diff --git a/src/stubs/servclient.c b/src/stubs/servclient.c new file mode 100644 index 0000000..7f3e786 --- /dev/null +++ b/src/stubs/servclient.c @@ -0,0 +1,3 @@ +/* $XFree86: xc/lib/font/stubs/servclient.c,v 1.1 1999/01/11 05:13:21 dawes Exp $ */ + +void *serverClient = 0; diff --git a/src/stubs/setfntauth.c b/src/stubs/setfntauth.c new file mode 100644 index 0000000..75e59c4 --- /dev/null +++ b/src/stubs/setfntauth.c @@ -0,0 +1,11 @@ +/* $XFree86: xc/lib/font/stubs/setfntauth.c,v 1.1 1999/01/11 05:13:21 dawes Exp $ */ + +#include "stubs.h" + +int +set_font_authorizations(char **authorizations, int *authlen, ClientPtr client) +{ + return 0; +} + +/* end of file */ diff --git a/src/stubs/stfntcfnt.c b/src/stubs/stfntcfnt.c new file mode 100644 index 0000000..cbb544f --- /dev/null +++ b/src/stubs/stfntcfnt.c @@ -0,0 +1,11 @@ +/* $XFree86: xc/lib/font/stubs/stfntcfnt.c,v 1.1 1999/01/11 05:13:21 dawes Exp $ */ + +#include "stubs.h" + +int +StoreFontClientFont(FontPtr pfont, Font id) +{ + return 0; +} + +/* end of file */ diff --git a/src/stubs/stubs.h b/src/stubs/stubs.h new file mode 100644 index 0000000..e88dc39 --- /dev/null +++ b/src/stubs/stubs.h @@ -0,0 +1,29 @@ +/* $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 "fntfilst.h" +#include "font.h" + + +#ifndef True +#define True (-1) +#endif +#ifndef False +#define False (0) +#endif + +extern FontPtr find_old_font ( FSID id ); +extern FontResolutionPtr GetClientResolutions ( int *num ); +extern int GetDefaultPointSize ( void ); +extern int set_font_authorizations ( char **authorizations, + int *authlen, + ClientPtr client ); +extern Bool XpClientIsBitmapClient ( ClientPtr client ); +extern Bool XpClientIsPrintClient ( ClientPtr client, + FontPathElementPtr fpe ); + +extern unsigned long GetTimeInMillis (void); + +/* end of file */ diff --git a/src/stubs/xpstubs.c b/src/stubs/xpstubs.c new file mode 100644 index 0000000..c692bbc --- /dev/null +++ b/src/stubs/xpstubs.c @@ -0,0 +1,21 @@ +/* $XFree86: xc/lib/font/stubs/xpstubs.c,v 1.1 1999/01/11 05:13:22 dawes Exp $ */ + +/* + stub for XpClient* functions. +*/ + +#include "stubs.h" + +Bool +XpClientIsBitmapClient(ClientPtr client) +{ + return True; +} + +Bool +XpClientIsPrintClient(ClientPtr client, FontPathElementPtr fpe) +{ + return False; +} + +/* end of file */ |