examples/PIPS/antiword/src/fonts_u.c

00001 /*
00002  * fonts_u.c
00003  * Copyright (C) 1999-2004 A.J. van Os; Released under GNU GPL
00004  *
00005  * Description:
00006  * Functions to deal with fonts (Unix version)
00007  */
00008 
00009 #include <stdio.h>
00010 #include <stdlib.h>
00011 #include <string.h>
00012 #include "antiword.h"
00013 #include "fontinfo.h"
00014 
00015 /* Don't use fonts, just plain text */
00016 static BOOL             bUsePlainText = TRUE;
00017 /* Which character set should be used */
00018 static encoding_type    eEncoding = encoding_neutral;
00019 
00020 
00021 /*
00022  * pOpenFontTableFile - open the Font translation file
00023  *
00024  * Returns the file pointer or NULL
00025  */
00026 FILE *
00027 pOpenFontTableFile(void)
00028 {
00029         FILE            *pFile;
00030         const char      *szHome, *szAntiword, *szGlobalFile;
00031         char            szEnvironmentFile[PATH_MAX+1];
00032         char            szLocalFile[PATH_MAX+1];
00033 
00034         szEnvironmentFile[0] = '\0';
00035         szLocalFile[0] = '\0';
00036 
00037         /* Try the environment version of the fontnames file */
00038         szAntiword = szGetAntiwordDirectory();
00039         if (szAntiword != NULL && szAntiword[0] != '\0') {
00040                 if (strlen(szAntiword) +
00041                     sizeof(FILE_SEPARATOR FONTNAMES_FILE) >=
00042                     sizeof(szEnvironmentFile)) {
00043                         werr(0,
00044                         "The name of your ANTIWORDHOME directory is too long");
00045                         return NULL;
00046                 }
00047                 sprintf(szEnvironmentFile, "%s%s",
00048                         szAntiword,
00049                         FILE_SEPARATOR FONTNAMES_FILE);
00050                 DBG_MSG(szEnvironmentFile);
00051 
00052                 pFile = fopen(szEnvironmentFile, "r");
00053                 if (pFile != NULL) {
00054                         return pFile;
00055                 }
00056         }
00057 
00058         /* Try the local version of the fontnames file */
00059         szHome = szGetHomeDirectory();
00060         if (strlen(szHome) +
00061             sizeof(FILE_SEPARATOR ANTIWORD_DIR FILE_SEPARATOR FONTNAMES_FILE) >=
00062             sizeof(szLocalFile)) {
00063                 werr(0, "The name of your HOME directory is too long");
00064                 return NULL;
00065         }
00066 
00067         #ifndef SYMBIAN
00068         sprintf(szLocalFile, "%s%s",
00069                 szHome,
00070                 FILE_SEPARATOR ANTIWORD_DIR FILE_SEPARATOR FONTNAMES_FILE);
00071                 DBG_MSG(szLocalFile);
00072         #else
00073         sprintf(szLocalFile, "%s%s",
00074                 szHome,
00075                 FONTNAMES_FILE);
00076                 DBG_MSG(szLocalFile);
00077         #endif /*SYMBIAN*/
00078         pFile = fopen(szLocalFile, "r");
00079         if (pFile != NULL) {
00080                 return pFile;
00081         }
00082 
00083         /* Try the global version of the fontnames file */
00084         szGlobalFile = GLOBAL_ANTIWORD_DIR FILE_SEPARATOR FONTNAMES_FILE;
00085         DBG_MSG(szGlobalFile);
00086 
00087         pFile = fopen(szGlobalFile, "r");
00088         if (pFile != NULL) {
00089                 return pFile;
00090         }
00091 
00092         if (szEnvironmentFile[0] != '\0') {
00093                 werr(0, "I can not open your fontnames file.\n"
00094                         "Neither '%s' nor\n"
00095                         "'%s' nor\n"
00096                         "'%s' can be opened for reading.",
00097                         szEnvironmentFile, szLocalFile, szGlobalFile);
00098         } else {
00099                 werr(0, "I can not open your fontnames file.\n"
00100                         "Neither '%s' nor\n"
00101                         "'%s' can be opened for reading.",
00102                         szLocalFile, szGlobalFile);
00103         }
00104         return NULL;
00105 } /* end of pOpenFontTableFile */
00106 
00107 /*
00108  * vCloseFont - close the current font, if any
00109  */
00110 void
00111 vCloseFont(void)
00112 {
00113         NO_DBG_MSG("vCloseFont");
00114         /* For safety: to be overwritten at the next call of tOpenfont() */
00115         eEncoding = encoding_neutral;
00116         bUsePlainText = TRUE;
00117 } /* end of vCloseFont */
00118 
00119 /*
00120  * tOpenFont - make the specified font the current font
00121  *
00122  * Returns the font reference number
00123  */
00124 drawfile_fontref
00125 tOpenFont(UCHAR ucWordFontNumber, USHORT usFontStyle, USHORT usWordFontSize)
00126 {
00127         options_type    tOptions;
00128         const char      *szOurFontname;
00129         size_t  tIndex;
00130         int     iFontnumber;
00131 
00132         NO_DBG_MSG("tOpenFont");
00133         NO_DBG_DEC(ucWordFontNumber);
00134         NO_DBG_HEX(usFontStyle);
00135         NO_DBG_DEC(usWordFontSize);
00136 
00137         /* Keep the relevant bits */
00138         usFontStyle &= FONT_BOLD|FONT_ITALIC;
00139         NO_DBG_HEX(usFontStyle);
00140 
00141         vGetOptions(&tOptions);
00142         eEncoding = tOptions.eEncoding;
00143         bUsePlainText = tOptions.eConversionType != conversion_draw &&
00144                         tOptions.eConversionType != conversion_ps &&
00145                         tOptions.eConversionType != conversion_pdf;
00146 
00147         if (bUsePlainText) {
00148                 /* Plain text, no fonts */
00149                 return (drawfile_fontref)0;
00150         }
00151 
00152         iFontnumber = iGetFontByNumber(ucWordFontNumber, usFontStyle);
00153         szOurFontname = szGetOurFontname(iFontnumber);
00154         if (szOurFontname == NULL || szOurFontname[0] == '\0') {
00155                 DBG_DEC(iFontnumber);
00156                 return (drawfile_fontref)0;
00157         }
00158         NO_DBG_MSG(szOurFontname);
00159 
00160         for (tIndex = 0; tIndex < elementsof(szFontnames); tIndex++) {
00161                 if (STREQ(szFontnames[tIndex], szOurFontname)) {
00162                         NO_DBG_DEC(tIndex);
00163                         return (drawfile_fontref)tIndex;
00164                 }
00165         }
00166         return (drawfile_fontref)0;
00167 } /* end of tOpenFont */
00168 
00169 /*
00170  * tOpenTableFont - make the table font the current font
00171  *
00172  * Returns the font reference number
00173  */
00174 drawfile_fontref
00175 tOpenTableFont(USHORT usWordFontSize)
00176 {
00177         options_type    tOptions;
00178         int     iWordFontnumber;
00179 
00180         NO_DBG_MSG("tOpenTableFont");
00181 
00182         vGetOptions(&tOptions);
00183         eEncoding = tOptions.eEncoding;
00184         bUsePlainText = tOptions.eConversionType != conversion_draw &&
00185                         tOptions.eConversionType != conversion_ps &&
00186                         tOptions.eConversionType != conversion_pdf;
00187 
00188         if (bUsePlainText) {
00189                 /* Plain text, no fonts */
00190                 return (drawfile_fontref)0;
00191         }
00192 
00193         iWordFontnumber = iFontname2Fontnumber(TABLE_FONT, FONT_REGULAR);
00194         if (iWordFontnumber < 0 || iWordFontnumber > (int)UCHAR_MAX) {
00195                 DBG_DEC(iWordFontnumber);
00196                 return (drawfile_fontref)0;
00197         }
00198 
00199         return tOpenFont((UCHAR)iWordFontnumber, FONT_REGULAR, usWordFontSize);
00200 } /* end of tOpenTableFont */
00201 
00202 /*
00203  * szGetFontname - get the fontname
00204  */
00205 const char *
00206 szGetFontname(drawfile_fontref tFontRef)
00207 {
00208         fail((size_t)(UCHAR)tFontRef >= elementsof(szFontnames));
00209         return szFontnames[(int)(UCHAR)tFontRef];
00210 } /* end of szGetFontname */
00211 
00212 /*
00213  * lComputeStringWidth - compute the string width
00214  *
00215  * Note: the fontsize is specified in half-points!
00216  *       the stringlength is specified in bytes, not characters!
00217  *
00218  * Returns the string width in millipoints
00219  */
00220 long
00221 lComputeStringWidth(const char *szString, size_t tStringLength,
00222         drawfile_fontref tFontRef, USHORT usFontSize)
00223 {
00224         USHORT  *ausCharWidths;
00225         UCHAR   *pucChar;
00226         long    lRelWidth;
00227         size_t  tIndex;
00228         int     iFontRef;
00229 
00230         fail(szString == NULL);
00231         fail(usFontSize < MIN_FONT_SIZE || usFontSize > MAX_FONT_SIZE);
00232 
00233         if (szString[0] == '\0' || tStringLength == 0) {
00234                 /* Empty string */
00235                 return 0;
00236         }
00237 
00238         if (eEncoding == encoding_utf_8) {
00239                 fail(!bUsePlainText);
00240                 return lChar2MilliPoints(
00241                         utf8_strwidth(szString, tStringLength));
00242         }
00243 
00244         if (bUsePlainText) {
00245                 /* No current font, use "systemfont" */
00246                 return lChar2MilliPoints(tStringLength);
00247         }
00248 
00249         if (eEncoding == encoding_cyrillic) {
00250                 /* FIXME: until the character tables are available */
00251                 return (tStringLength * 600L * (long)usFontSize + 1) / 2;
00252         }
00253 
00254         DBG_DEC_C(eEncoding != encoding_latin_1 &&
00255                 eEncoding != encoding_latin_2, eEncoding);
00256         fail(eEncoding != encoding_latin_1 &&
00257                 eEncoding != encoding_latin_2);
00258 
00259         /* Compute the relative string width */
00260         iFontRef = (int)(UCHAR)tFontRef;
00261         if (eEncoding == encoding_latin_2) {
00262                 ausCharWidths = ausCharacterWidths2[iFontRef];
00263         } else {
00264                 ausCharWidths = ausCharacterWidths1[iFontRef];
00265         }
00266         lRelWidth = 0;
00267         for (tIndex = 0, pucChar = (UCHAR *)szString;
00268              tIndex < tStringLength;
00269              tIndex++, pucChar++) {
00270                 lRelWidth += (long)ausCharWidths[(int)*pucChar];
00271         }
00272 
00273         /* Compute the absolute string width */
00274         return (lRelWidth * (long)usFontSize + 1) / 2;
00275 } /* end of lComputeStringWidth */
00276 
00277 /*
00278  * tCountColumns - count the number of columns in a string
00279  *
00280  * Note: the length is specified in bytes!
00281  *       A UTF-8 a character can be 0, 1 or 2 columns wide.
00282  *
00283  * Returns the number of columns
00284  */
00285 size_t
00286 tCountColumns(const char *szString, size_t tLength)
00287 {
00288         fail(szString == NULL);
00289 
00290         if (eEncoding != encoding_utf_8) {
00291                 /* One byte, one character, one column */
00292                 return tLength;
00293         }
00294         return (size_t)utf8_strwidth(szString, tLength);
00295 } /* end of tCountColumns */
00296 
00297 /*
00298  * tGetCharacterLength - the length of the specified character in bytes
00299  *
00300  * Returns the length in bytes
00301  */
00302 size_t
00303 tGetCharacterLength(const char *szString)
00304 {
00305         fail(szString == NULL);
00306 
00307         if (eEncoding != encoding_utf_8) {
00308                 return 1;
00309         }
00310         return (size_t)utf8_chrlength(szString);
00311 } /* end of tGetCharacterLength */

Generated by  doxygen 1.6.2