/* Copyright (c) 2004-2010, Dirk Krause All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above opyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Dirk Krause nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. */ /** @file dkfont.c Font handling module. */ /** Inside the dkfont module. */ #define DKFONT_C 1 #include "dk.h" #include "dkerror.h" #include "dkfont.h" #include "dkmem.h" #include "dkstr.h" #include "dksto.h" #include "dkstream.h" #line 61 "dkfont.ctr" /** Font family name: Times. */ static char svg_name_times[] = { "Times" }; /** Font family name: Palatino. */ static char svg_name_palatino[] = { "Palatino" }; /** Font family name: AvantGarde. */ static char svg_name_avantgard[] = { "AvantGarde" }; /** Font family name: Bookman. */ static char svg_name_bookman[] = { "Bookman" }; /** Font family name: Courier. */ static char svg_name_courier[] = { "Courier" }; /** Font family name: Helvetica. */ static char svg_name_helvetica[] = { "Helvetica" }; /** Font family name: Helvetica Narrow. */ static char svg_name_helvnarrow[] = { "Helvetica Narrow" }; /** Font family name: New Century Schoolbook. */ static char svg_name_newcent[] = { "New Century Schoolbook" }; /** Font family name: Symbol. */ static char svg_name_symbol[] = { "Symbol" }; /** Font family name: Zapf Chancery. */ static char svg_name_zapfchanc[] = { "Zapf Chancery" }; /** Font family name: Zapf Dingbats. */ static char svg_name_zapfding[] = { "Zapf Dingbats" }; /** The 35 default PostScript fonts. Note: Do not change the sort order, it must be the same as used by XFig. */ dk_font_t dkfont_ps_35[] = { /* 0 */ { (char *)"ptmr", (char *)"Times-Roman", DK_FONT_FEATURE_RM, svg_name_times, (char *)"NimbusRomNo9L-Regu", (char *)"n021003l", (char *)"NimbusRomanNo9L-Regu", (char *)"NimbusRomNo9L-Regu" }, /* 1 */ { (char *)"ptmri", (char *)"Times-Italic", (DK_FONT_FEATURE_RM | DK_FONT_FEATURE_IT), svg_name_times, (char *)"NimbusRomNo9L-ReguItal", (char *)"n021023l", (char *)"NimbusRomNo9L-ReguItal", (char *)"NimbusRomNo9L-ReguItal" }, /* 2 */ { (char *)"ptmb", (char *)"Times-Bold", (DK_FONT_FEATURE_RM | DK_FONT_FEATURE_BD), svg_name_times, (char *)"NimbusRomNo9L-Medi", (char *)"n021004l", (char *)"NimbusRomNo9L-Medi", (char *)"NimbusRomNo9L-Medi" }, /* 3 */ { (char *)"ptmbi", (char *)"Times-BoldItalic", (DK_FONT_FEATURE_RM | DK_FONT_FEATURE_BD | DK_FONT_FEATURE_IT), svg_name_times, (char *)"NimbusRomNo9L-MediItal", (char *)"n021024l", (char *)"NimbusRomNo9L-MediItal", (char *)"NimbusRomNo9L-MediItal" }, /* 4 */ { (char *)"pagk", (char *)"AvantGarde-Book", DK_FONT_FEATURE_SF, svg_name_avantgard, (char *)"URWGothicL-Book", (char *)"a010013l", (char *)"URWGothicL-Book", (char *)"URWGothicL-Book" }, /* 5 */ { (char *)"pagko", (char *)"AvantGarde-BookOblique", (DK_FONT_FEATURE_SF | DK_FONT_FEATURE_IT), svg_name_avantgard, (char *)"URWGothicL-BookObli", (char *)"a010033l", (char *)"URWGothicL-BookObli", (char *)"URWGothicL-BookObli" }, /* 6 */ { (char *)"pagd", (char *)"AvantGarde-Demi", (DK_FONT_FEATURE_SF | DK_FONT_FEATURE_BD), svg_name_avantgard, (char *)"URWGothicL-Demi", (char *)"a010015l", (char *)"URWGothicL-Demi", (char *)"URWGothicL-Demi" }, /* 7 */ { (char *)"pagdo", (char *)"AvantGarde-DemiOblique", (DK_FONT_FEATURE_SF | DK_FONT_FEATURE_BD | DK_FONT_FEATURE_IT), svg_name_avantgard, (char *)"URWGothicL-DemiObli", (char *)"a010035l", (char *)"URWGothicL-DemiObli", (char *)"URWGothicL-DemiObli" }, /* 8 */ { (char *)"pbkl", (char *)"Bookman-Light", DK_FONT_FEATURE_RM, svg_name_bookman, (char *)"URWBookmanL-Ligh", (char *)"b018012l", (char *)"URWBookmanL-Ligh", (char *)"URWBookmanL-Ligh" }, /* 9 */ { (char *)"pbkli", (char *)"Bookman-LightItalic", (DK_FONT_FEATURE_RM | DK_FONT_FEATURE_IT), svg_name_bookman, (char *)"URWBookmanL-LighItal", (char *)"b018032l", (char *)"URWBookmanL-LighItal", (char *)"URWBookmanL-LighItal" }, /* 10 */ { (char *)"pbkd", (char *)"Bookman-Demi", (DK_FONT_FEATURE_RM | DK_FONT_FEATURE_BD), svg_name_bookman, (char *)"URWBookmanL-Demi", (char *)"b018015l", (char *)"URWBookmanL-DemiBold", (char *)"URWBookmanL-DemiBold" }, /* 11 */ { (char *)"pbkdi", (char *)"Bookman-DemiItalic", (DK_FONT_FEATURE_RM | DK_FONT_FEATURE_IT | DK_FONT_FEATURE_BD), svg_name_bookman, (char *)"URWBookmanL-DemiItal", (char *)"b018035l", (char *)"URWBookmanL-DemiBoldItal", (char *)"URWBookmanL-DemiBoldItal" }, /* 12 */ { (char *)"pcrr", (char *)"Courier", DK_FONT_FEATURE_TT, svg_name_courier, (char *)"NimbusMonL-Regu", (char *)"n022003l", (char *)"NimbusMonL-Regu", (char *)"NimbusMonL-Regu" }, /* 13 */ { (char *)"pcrro", (char *)"Courier-Oblique", (DK_FONT_FEATURE_TT | DK_FONT_FEATURE_IT), svg_name_courier, (char *)"NimbusMonL-ReguObli", (char *)"n022023l", (char *)"NimbusMonL-ReguObli", (char *)"NimbusMonL-ReguObli" }, /* 14 */ { (char *)"pcrb", (char *)"Courier-Bold", (DK_FONT_FEATURE_TT | DK_FONT_FEATURE_BD), svg_name_courier, (char *)"NimbusMonL-Bold", (char *)"n022004l", (char *)"NimbusMonL-Bold", (char *)"NimbusMonL-Bold" }, /* 15 */ { (char *)"pcrbo", (char *)"Courier-BoldOblique", (DK_FONT_FEATURE_TT | DK_FONT_FEATURE_BD | DK_FONT_FEATURE_IT), svg_name_courier, (char *)"NimbusMonL-BoldObli", (char *)"n022024l", (char *)"NimbusMonL-BoldObli", (char *)"NimbusMonL-BoldObli" }, /* 16 */ { (char *)"phvr", (char *)"Helvetica", DK_FONT_FEATURE_SF, svg_name_helvetica, (char *)"NimbusSanL-Regu", (char *)"n019003l", (char *)"NimbusSansL-Regu", (char *)"NimbusSanL-Regu" }, /* 17 */ { (char *)"phvro", (char *)"Helvetica-Oblique", (DK_FONT_FEATURE_SF | DK_FONT_FEATURE_IT), svg_name_helvetica, (char *)"NimbusSanL-ReguItal", (char *)"n019023l", (char *)"NimbusSanL-ReguItal", (char *)"NimbusSanL-ReguItal" }, /* 18 */ { (char *)"phvb", (char *)"Helvetica-Bold", (DK_FONT_FEATURE_SF | DK_FONT_FEATURE_BD), svg_name_helvetica, (char *)"NimbusSanL-Bold", (char *)"n019004l", (char *)"NimbusSansL-Bold", (char *)"NimbusSanL-Bold" }, /* 19 */ { (char *)"phvbo", (char *)"Helvetica-BoldOblique", (DK_FONT_FEATURE_SF | DK_FONT_FEATURE_BD | DK_FONT_FEATURE_IT), svg_name_helvetica, (char *)"NimbusSanL-BoldItal", (char *)"n019024l", (char *)"NimbusSanL-BoldItal", (char *)"NimbusSanL-BoldItal" }, /* 20 */ { (char *)"phvrrn", (char *)"Helvetica-Narrow", DK_FONT_FEATURE_SF, svg_name_helvnarrow, (char *)"NimbusSanL-ReguCond", (char *)"n019043l", (char *)"NimbusSanL-ReguCond", (char *)"NimbusSanL-ReguCond" }, /* 21 */ { (char *)"phvron", (char *)"Helvetica-Narrow-Oblique", (DK_FONT_FEATURE_SF | DK_FONT_FEATURE_IT), svg_name_helvnarrow, (char *)"NimbusSanL-ReguCondItal", (char *)"n019063l", (char *)"NimbusSanL-ReguCondItal", (char *)"NimbusSanL-ReguCondItal" }, /* 22 */ { (char *)"phvbrn", (char *)"Helvetica-Narrow-Bold", (DK_FONT_FEATURE_SF | DK_FONT_FEATURE_BD), svg_name_helvnarrow, (char *)"NimbusSanL-BoldCond", (char *)"n019044l", (char *)"NimbusSanL-BoldCond", (char *)"NimbusSanL-BoldCond" }, /* 23 */ { (char *)"phvbon", (char *)"Helvetica-Narrow-BoldOblique", (DK_FONT_FEATURE_SF | DK_FONT_FEATURE_BD | DK_FONT_FEATURE_IT), svg_name_helvnarrow, (char *)"NimbusSanL-BoldCondItal", (char *)"n019064l", (char *)"NimbusSanL-BoldCondItal", (char *)"NimbusSanL-BoldCondItal" }, /* 24 */ { (char *)"pncr", (char *)"NewCenturySchlbk-Roman", DK_FONT_FEATURE_RM, svg_name_newcent, (char *)"CenturySchL-Roma", (char *)"c059013l", (char *)"CenturySchL-Roma", (char *)"CenturySchL-Roma" }, /* 25 */ { (char *)"pncri", (char *)"NewCenturySchlbk-Italic", (DK_FONT_FEATURE_RM | DK_FONT_FEATURE_IT), svg_name_newcent, (char *)"CenturySchL-RomaItal", (char *)"c059033l", (char *)"CenturySchL-Ital", (char *)"CenturySchL-Ital" }, /* 26 */ { (char *)"pncb", (char *)"NewCenturySchlbk-Bold", (DK_FONT_FEATURE_RM | DK_FONT_FEATURE_BD), svg_name_newcent, (char *)"CenturySchL-Bold", (char *)"c059016l", (char *)"CenturySchL-Bold", (char *)"CenturySchL-Bold" }, /* 27 */ { (char *)"pncbi", (char *)"NewCenturySchlbk-BoldItalic", (DK_FONT_FEATURE_RM | DK_FONT_FEATURE_BD | DK_FONT_FEATURE_IT), svg_name_newcent, (char *)"CenturySchL-BoldItal", (char *)"c059036l", (char *)"CenturySchL-BoldItal", (char *)"CenturySchL-BoldItal" }, /* 28 */ { (char *)"pplr", (char *)"Palatino-Roman", DK_FONT_FEATURE_RM, svg_name_palatino, (char *)"URWPalladioL-Roma", (char *)"p052003l", (char *)"URWPalladioL-Roma", (char *)"URWPalladioL-Roma" }, /* 29 */ { (char *)"pplri", (char *)"Palatino-Italic", (DK_FONT_FEATURE_RM | DK_FONT_FEATURE_IT), svg_name_palatino, (char *)"URWPalladioL-Ital", (char *)"p052023l", (char *)"URWPalladioL-Ital", (char *)"URWPalladioL-Ital" }, /* 30 */ { (char *)"pplb", (char *)"Palatino-Bold", (DK_FONT_FEATURE_RM | DK_FONT_FEATURE_BD), svg_name_palatino, (char *)"URWPalladioL-Bold", (char *)"p052004l", (char *)"URWPalladioL-Bold", (char *)"URWPalladioL-Bold" }, /* 31 */ { (char *)"pplbi", (char *)"Palatino-BoldItalic", (DK_FONT_FEATURE_RM | DK_FONT_FEATURE_BD | DK_FONT_FEATURE_IT), svg_name_palatino, (char *)"URWPalladioL-BoldItal", (char *)"p052024l", (char *)"URWPalladioL-BoldItal", (char *)"URWPalladioL-BoldItal" }, /* 32 */ { (char *)"psyr", (char *)"Symbol", 0, svg_name_symbol, (char *)"StandardSymL", (char *)"s050000l", (char *)"StandardSymL", (char *)"StandardSymL" }, /* 33 */ { (char *)"pzcmi", (char *)"ZapfChancery-MediumItalic", (DK_FONT_FEATURE_RM | DK_FONT_FEATURE_IT), svg_name_zapfchanc, (char *)"URWChanceryL-MediItal", (char *)"z003034l", (char *)"URWChanceryL-MediItal", (char *)"URWChanceryL-MediItal" }, /* 34 */ { (char *)"pzdr", (char *)"ZapfDingbats", 0, svg_name_zapfding, (char *)"Dingbats", (char *)"d050000l", (char *)"Dingbats", (char *)"Dingbats" } }; /** String exploder pattern. */ static char explode_pattern[] = { " \t\r\n" }; /** Font configuration file command: name. */ static char *cmd00[] = { (char *)"name", NULL }; /** Font configuration file command: source type. */ static char *cmd01[] = { (char *)"source", (char *)"type", NULL }; /** Font configuration file command: directory. */ static char *cmd02[] = { (char *)"directory", NULL }; /** Font configuration file command: file name. */ static char *cmd03[] = { (char *)"file", (char *)"name", NULL }; /** Font configuration file command: features. */ static char *cmd04[] = { (char *)"features", NULL }; /** Font configuration file command: family. */ static char *cmd05[] = { (char *)"family", NULL }; /** Font configuration file command: driver. */ static char *cmd06[] = { (char *)"driver", NULL }; /** Font configuration file command: font type. */ static char *cmd07[] = { (char *)"font", (char *)"type", NULL }; /** Font configuration file command: tex name. */ static char *cmd08[] = { (char *)"tex", (char *)"name", NULL }; /** Font configuration file command: pfb base. */ static char *cmd09[] = { (char *)"pfb", (char *)"base", NULL}; /** Font configuration file command: pfb file. */ static char *cmd10[] = { (char *)"pfb", (char *)"file", NULL}; /** Font configuration file command: ttf base. */ static char *cmd11[] = { (char *)"ttf", (char *)"base", NULL}; /** Font configuration file command: ttf file. */ static char *cmd12[] = { (char *)"ttf", (char *)"file", NULL}; /** Font configuration file command: svg base. */ static char *cmd13[] = { (char *)"svg", (char *)"base", NULL}; /** Font configuration file command: svg file. */ static char *cmd14[] = { (char *)"svg", (char *)"file", NULL}; /** Commands in font configuration file. */ static char **cmds[] = { cmd00, cmd01, cmd02, cmd03, cmd04, cmd05, cmd06, cmd07, cmd08, cmd09, cmd10, cmd11, cmd12, cmd13, cmd14, NULL }; /** Font feature settings keywords. */ static char *font_feature_strings[] = { (char *)"r$oman", (char *)"s$ans-serif", (char *)"t$ypewriter", (char *)"b$old", (char *)"i$talic", NULL }; /** Source types keywords. */ static char *font_source_types[] = { (char *)"s$ystem", (char *)"d$ownload", NULL }; /** Asterisk string for testing. */ static char str_asterisk[] = { "*" }; char * dkfont_get_tex_name DK_P1(size_t, number) { char *back = NULL; if(number < 35) { back = dkfont_ps_35[number].texname; } return back; } char * dkfont_get_ps_name DK_P1(size_t, number) { char *back = NULL; if(number < 35) { back = dkfont_ps_35[number].psname; } return back; } dk_font_t * dkfont_get_ps_fonts DK_P0() { return dkfont_ps_35; } int dkfont_get_features DK_P1(size_t, number) { int back = 0; if(number < 35) { back = dkfont_ps_35[number].features; } return back; } char * dkfont_get_svg_font_id DK_P1(size_t,number) { char *back = NULL; if(number < 35) { back = dkfont_ps_35[number].svgFontId; } return back; } char * dkfont_get_svg_family_name DK_P1(size_t,number) { char *back = NULL; if(number < 35) { back = dkfont_ps_35[number].svgFontFamily; } return back; } char * dkfont_get_gs_alias_name DK_P1(size_t,number) { char *back = NULL; if(number < 35) { back = dkfont_ps_35[number].gs_alias; } return back; } char * dkfont_get_gs_file_name DK_P1(size_t,number) { char *back = NULL; if(number < 35) { back = dkfont_ps_35[number].gs_actual; } return back; } char * dkfont_get_new_gs_file_name DK_P1(size_t,number) { char *back = NULL; if(number < 35) { back = dkfont_ps_35[number].gs_new; } return back; } /** Abbreviation for dk_font_replacement_t. */ typedef dk_font_replacement_t FR; /** Abbreviation for char *. */ typedef char *PCHAR; /** Compare two strings. @param l Left string. @param r Right string. @param cr Comparison criteria (ignored). @return Comparison result. */ static int compare_two_strings DK_P3(void *,l, void *,r, int,cr) { int back = 0; if(l) { if(r) { back = strcmp((char *)l, (char *)r); } else { back = 1; } } else { if(r) { back = -1; } } return back; } /** Compare two replacements by line number. @param l Left replacement. @param r Right replacement. @param cr Comparison criteria (ignored). @return Comparison result. */ static int compare_replacement_by_number DK_P3(void *,l, void *,r, int,cr) { int back = 0; dk_font_replacement_t *frl, *frr; if(l) { if(r) { frl = (dk_font_replacement_t *)l; frr = (dk_font_replacement_t *)r; if(frl->num > frr->num) { back = 1; } if(frl->num < frr->num) { back = -1; } } else { back = 1; } } else { if(r) { back = -1; } } return back; } /** Compare two replacements by name. @param l Left replacement. @param r Right replacement. @param cr Comparison criteria (1=replacement/name, 0=replacement/replacement). @return Comparison result. */ static int compare_replacement_by_name DK_P3(void *,l, void *,r, int,cr) { int back = 0; dk_font_replacement_t *frl, *frr; if(l) { if(r) { frl = (dk_font_replacement_t *)l; frr = (dk_font_replacement_t *)r; switch(cr) { case 1: { if(frl->n) { back = strcmp(frl->n, (char *)r); } else { back = -1; } } break; default: { if(frl->n) { if(frr->n) { back = strcmp(frl->n, frr->n); } else { back = 1; } } else { if(frr->n) { back = -1; } } } break; } } else { back = 1; } } else { if(r) { back = -1; } } return back; } /** Destroy a replacement, release memory. @param p Replacement to destroy. */ static void destroy_replacement DK_P1(dk_font_replacement_t *,p) { char *cp; if(p->d) { if(p->di) { #line 869 "dkfont.ctr" #line 870 "dkfont.ctr" #line 871 "dkfont.ctr" #line 872 "dkfont.ctr" #line 873 "dkfont.ctr" #line 874 "dkfont.ctr" #line 875 "dkfont.ctr" #line 876 "dkfont.ctr" #line 877 "dkfont.ctr" #line 878 "dkfont.ctr" dksto_it_close(p->di); p->di = NULL; } dksto_close(p->d); p->d = NULL; } if(p->tl) { cp = p->tl; dk_delete(cp); p->tl = NULL; } if(p->ts) { cp = p->ts; dk_delete(cp); p->ts = NULL; } if(p->pl) { cp = p->pl; dk_delete(cp); p->pl = NULL; } if(p->ps) { cp = p->ps; dk_delete(cp); p->ps = NULL; } if(p->tn) { cp = p->tn; dk_delete(cp); p->tn = NULL; } if(p->n) { cp = p->n; dk_delete(cp); p->n = NULL; } if(p->f) { cp = p->f; dk_delete(cp); p->f = NULL; } if(p->l) { cp = p->l; dk_delete(cp); p->l = NULL; } if(p->s) { cp = p->s; dk_delete(cp); p->s = NULL; } if(p->ft) { cp = p->ft; dk_delete(cp); p->ft = NULL; } p->ff = 0; p->t = 0; p->num = 0UL; dk_delete(p); } /** Initialize a new font replacement. @param p Replacement to initialize. @param n Replacement name. @param num Line number of occurance. @return 1 on success, 0 on error. */ static int initialize_replacement DK_P3(FR *,p, char *,n, unsigned long,num) { int back = 0; p->n = NULL; p->f = NULL; p->l = NULL; p->s = NULL; p->ft = NULL; p->ff = 0; p->t = 0; p->num = 0UL; p->tn = NULL; p->d = NULL; p->di = NULL; p->pl = NULL; p->ps = NULL; p->tl = NULL; p->ts = NULL; p->n = dkstr_dup(n); if(p->n) { p->num = num; p->d = dksto_open(0); if(p->d) { dksto_set_comp(p->d, compare_two_strings, 0); p->di = dksto_it_open(p->d); if(p->di) { back = 1; } } } return back; } /** Create a new font replacement. @param n Replacement name. @param num Line number in configuration file. */ static dk_font_replacement_t * create_replacement DK_P2(char *,n, unsigned long, num) { dk_font_replacement_t *back = NULL; back = dk_new(dk_font_replacement_t,1); if(back) { if(!initialize_replacement(back,n,num)) { destroy_replacement(back); back = NULL; } } return back; } /** Initialize the mapping structure for one PS font. @param p Font mapping to initialize. @return 1 on success, 0 on error. */ static int initialize_one_font_mapping DK_P1(dk_one_font_mapping_t *,p) { int back = 0; p->used = 0x00; p->noe = 0; p->r = NULL; p->ri = NULL; p->byname = NULL; p->bynamei = NULL; p->r = dksto_open(0); if(p->r) { dksto_set_comp(p->r, compare_replacement_by_number, 0); p->ri = dksto_it_open(p->r); if(p->ri) { p->byname = dksto_open(0); if(p->byname) { dksto_set_comp(p->byname, compare_replacement_by_name, 0); p->bynamei = dksto_it_open(p->byname); if(p->bynamei) { back = 1; } } } } return back; } /** Destroy the mapping structure for one PS font, release memory. @param p Font mapping to destroy. */ static void destroy_one_font_mapping DK_P1(dk_one_font_mapping_t *,p) { dk_font_replacement_t *ptr; if(p->r) { if(p->ri) { dksto_it_reset(p->ri); while((ptr = (FR *)dksto_it_next(p->ri)) != NULL) { destroy_replacement(ptr); } dksto_it_close(p->ri); p->ri = NULL; } dksto_close(p->r); p->r = NULL; p->used = 0x00; } if(p->byname) { if(p->bynamei) { dksto_it_close(p->bynamei); p->bynamei = NULL; } dksto_close(p->byname); p->byname = NULL; } } /** Close a complete mapping structure and release ressources. @param p Font mapping to close. */ void dkfont_mapping_close DK_P1(dk_font_mapping_t *,p) { size_t i; dk_one_font_mapping_t *ptr; char *cp; if(p) { p->error_code = 0; p->err_lineno = 0UL; if(p->m) { ptr = p->m; for(i = 0; i < 35; i++) { destroy_one_font_mapping(ptr); ptr++; } } if(p->d) { if(p->di) { dksto_it_reset(p->di); while((cp = (char *)dksto_it_next(p->di)) != NULL) { dk_delete(cp); } dksto_it_close(p->di); p->di = NULL; } dksto_close(p->d); p->d = NULL; } } } /** Initialize a new complete mapping structure. @param p Font mapping to initialize. @return 1 on success, 0 on error. */ static int initialize_mapping DK_P1(dk_font_mapping_t *,p) { int back = 0; dk_one_font_mapping_t *ptr; size_t i; p->error_code = 0; p->err_lineno = 0UL; p->m = NULL; p->d = NULL; p->di = NULL; p->m = dk_new(dk_one_font_mapping_t,35); if(p->m) { p->d = dksto_open(0); if(p->d) { dksto_set_comp(p->d, compare_two_strings, 0); p->di = dksto_it_open(p->d); if(p->di) { back = 1; ptr = p->m; for(i = 0; i < 35; i++) { if(!initialize_one_font_mapping(ptr)) { back = 0; } ptr++; } } } } return back; } dk_font_mapping_t * dkfont_mapping_open DK_P0() { dk_font_mapping_t *back = NULL; back = dk_new(dk_font_mapping_t,1); if(back) { if(!initialize_mapping(back)) { dkfont_mapping_close(back); back = NULL; } } return back; } /** Get index (0...34) of a PS font name. @param n Font name. @return Numeric font id used by XFig. */ static int get_index_ps_35 DK_P1(char *,n) { int back = -1; int i; dk_font_t *ptr; ptr = dkfont_ps_35; for(i = 0; ((i < 35) && (back == -1)); i++) { if(strcmp(ptr->psname, n) == 0) { back = i; } ptr++; } return back; } int dkfont_mapping_add_stream DK_P2(dk_font_mapping_t *,fm, dk_stream_t *,st) { int back = 0; int cc; char inputline[1024], *ls, *le, *vptr; dk_one_font_mapping_t *cofm = NULL; dk_font_replacement_t *cfr = NULL; if(fm) { if(st) { back = 1; cc = 1; fm->error_code = 0; fm->err_lineno = 0UL; while((cc == 1) && (fm->error_code == 0)) { if(dkstream_gets(st, inputline, sizeof(inputline))) { fm->err_lineno += 1UL; dkstr_delcomm(inputline, '#'); ls = dkstr_start(inputline, NULL); if(ls) { dkstr_chomp(ls, NULL); if(*ls == '[') { /* new font number */ ls++; ls = dkstr_start(ls, NULL); if(ls) { le = dkstr_chr(ls, ']'); if(le) { *le = '\0'; ls = dkstr_start(ls, NULL); if(ls) { int i; dkstr_chomp(ls, NULL); i = get_index_ps_35(ls); if((i >= 0) && (i < 35)) { cofm = &((fm->m)[i]); cfr = NULL; } else { fm->error_code = DK_ERR_SYNTAX; } } else { fm->error_code = DK_ERR_SYNTAX; } } else { fm->error_code = DK_ERR_SYNTAX; } } else { fm->error_code = DK_ERR_SYNTAX; } } else { /* continue editing current font */ if(cofm) { vptr = dkstr_chr(ls, '='); if(vptr) { *(vptr++) = '\0'; vptr = dkstr_start(vptr, NULL); if(vptr) { ls = dkstr_start(ls, NULL); if(ls) { char *parts[32]; size_t xsz; dkstr_chomp(ls, NULL); dkstr_chomp(vptr, NULL); xsz = sizeof(parts)/sizeof(PCHAR); if(dkstr_explode(parts, xsz, ls, explode_pattern)) { int i; i = dkstr_find_multi_part_abbr(parts, cmds, '$', 1); switch(i) { case 0: { /* name */ cfr = dksto_it_find_like(cofm->bynamei, vptr, 1); if(!cfr) { int ok; cfr = create_replacement(vptr, cofm->noe); cofm->noe += 1; if(cfr) { ok = 0; if(dksto_add(cofm->r, (void *)cfr)) { if(dksto_add(cofm->byname, (void *)cfr)) { ok = 1; } } else { destroy_replacement(cfr); cfr = NULL; } if(!ok) { fm->error_code = DK_ERR_NOMEM; } } } if(!cfr) { fm->error_code = DK_ERR_NOMEM; } } break; case 1: { /* source type */ if(cfr) { cfr->t = dkstr_array_abbr(font_source_types, vptr, '$', 0); if(cfr->t < 0) { fm->error_code = DK_ERR_SYNTAX; } } else { fm->error_code = DK_ERR_SYNTAX; } } break; case 2: case 13: { /* directory */ if(cfr->l) { fm->error_code = DK_ERR_SYNTAX; } else { cfr->l = dkstr_dup(vptr); if(!(cfr->l)) { fm->error_code = DK_ERR_NOMEM; } } } break; case 3: case 14: { /* file name */ if(cfr->s) { fm->error_code = DK_ERR_SYNTAX; } else { cfr->s = dkstr_dup(vptr); if(!(cfr->s)) { fm->error_code = DK_ERR_NOMEM; } } } break; case 4: { /* features */ char *p1, *p2; p1 = dkstr_start(vptr, NULL); while(p1) { p2 = dkstr_next(p1, NULL); switch(dkstr_array_abbr( font_feature_strings, p1, '$', 0 ) ) { case 0: { /* roman */ cfr->ff = DK_FONT_FEATURE_RM | ((cfr->ff) & (~(DK_FONT_FEATURE_FAMILY))); } break; case 1: { /* sans-serif */ cfr->ff = DK_FONT_FEATURE_SF | ((cfr->ff) & (~(DK_FONT_FEATURE_FAMILY))); } break; case 2: { /* typewriter */ cfr->ff = DK_FONT_FEATURE_TT | ((cfr->ff) & (~(DK_FONT_FEATURE_FAMILY))); } break; case 3: { /* bold */ cfr->ff = cfr->ff | DK_FONT_FEATURE_BD; } break; case 4: { /* italic */ cfr->ff = cfr->ff | DK_FONT_FEATURE_IT; } break; default: { fm->error_code = DK_ERR_SYNTAX; } break; } p1 = p2; } } break; case 5: { /* family */ if(cfr->f) { fm->error_code = DK_ERR_SYNTAX; } else { cfr->f = dkstr_dup(vptr); if(!(cfr->f)) { fm->error_code = DK_ERR_NOMEM; } } } break; case 6: { /* driver */ char *p1, *p2, *p3; p1 = dkstr_start(vptr, NULL); while(p1) { p2 = dkstr_next(p1, NULL); p3 = dksto_it_find_like(fm->di, p1, 0); if(p3) { if(!dksto_add(cfr->d, (void *)p3)) { fm->error_code = DK_ERR_NOMEM; } } else { p3 = dkstr_dup(p1); if(p3) { if(dksto_add(fm->d, (void *)p3)) { if(!dksto_add(cfr->d, (void *)p3)) { fm->error_code = DK_ERR_NOMEM; } } else { dk_delete(p3); } } else { fm->error_code = DK_ERR_NOMEM; } } p1 = p2; } } break; case 7: { /* font type */ if(cfr->ft) { fm->error_code = DK_ERR_SYNTAX; } else { cfr->ft = dkstr_dup(vptr); if(!(cfr->ft)) { fm->error_code = DK_ERR_NOMEM; } } } break; case 8: { if(cfr->tn) { fm->error_code = DK_ERR_SYNTAX; } else { cfr->tn = dkstr_dup(vptr); if(!(cfr->tn)) { fm->error_code = DK_ERR_NOMEM; } } } break; case 9: { if(cfr->pl) { fm->error_code = DK_ERR_SYNTAX; } else { cfr->pl = dkstr_dup(vptr); if(!(cfr->pl)) { fm->error_code = DK_ERR_NOMEM; } } } break; case 10: { if(cfr->ps) { fm->error_code = DK_ERR_SYNTAX; } else { cfr->ps = dkstr_dup(vptr); if(!(cfr->ps)) { fm->error_code = DK_ERR_NOMEM; } } } break; case 11: { if(cfr->tl) { fm->error_code = DK_ERR_SYNTAX; } else { cfr->tl = dkstr_dup(vptr); if(!(cfr->tl)) { fm->error_code = DK_ERR_NOMEM; } } } break; case 12: { if(cfr->ts) { fm->error_code = DK_ERR_SYNTAX; } else { cfr->ts = dkstr_dup(vptr); if(!(cfr->ts)) { fm->error_code = DK_ERR_NOMEM; } } } break; default: { fm->error_code = DK_ERR_SYNTAX; } break; } } else { fm->error_code = DK_ERR_SYNTAX; } } else { fm->error_code = DK_ERR_SYNTAX; } } else { fm->error_code = DK_ERR_SYNTAX; } } else { fm->error_code = DK_ERR_SYNTAX; } } else { fm->error_code = DK_ERR_SYNTAX; } } } } else { cc = 0; } } if(fm->error_code) { back = 0; } } else { } } else { } return back; } int dkfont_get_error_code DK_P1(dk_font_mapping_t *,fm) { int back = 0; if(fm) { back = fm->error_code; } return back; } unsigned long dkfont_get_error_lineno DK_P1(dk_font_mapping_t *,fm) { unsigned long back = 0UL; if(fm) { back = fm->err_lineno; } return back; } dk_one_font_mapping_t * dkfont_get_one_font DK_P2(dk_font_mapping_t *,fm, size_t,n) { dk_one_font_mapping_t *back = NULL; if(fm) { if(n < 35) { back = &((fm->m)[n]); } } return back; } void dkfont_set_used DK_P3(dk_font_mapping_t *,fm, size_t,n, int,b) { if(fm) { if(n < 35) { if(b) { ((fm->m)[n]).used = 1; } else { ((fm->m)[n]).used = 0; } } } } int dkfont_get_used DK_P2(dk_font_mapping_t *,fm, size_t,n) { int back = 0; if(fm) { if(n < 35) { if(((fm->m)[n]).used) { back = 1; } } } return back; } void dkfont_one_font_reset DK_P1(dk_one_font_mapping_t *,o) { if(o) { dksto_it_reset(o->ri); } } dk_font_replacement_t * dkfont_one_font_get DK_P1(dk_one_font_mapping_t *,o) { dk_font_replacement_t *back = NULL; if(o) { back = (dk_font_replacement_t *)dksto_it_next(o->ri); } return back; } char * dkfont_rep_get_name DK_P1(dk_font_replacement_t *,r) { char *back = NULL; if(r) { back = r->n; } return back; } char * dkfont_rep_get_family DK_P1(dk_font_replacement_t *,r) { char *back = NULL; if(r) { back = r->f; } return back; } char * dkfont_rep_get_location DK_P1(dk_font_replacement_t *,r) { char *back = NULL; if(r) { back = r->l; } return back; } char * dkfont_rep_get_source_name DK_P1(dk_font_replacement_t *,r) { char *back = NULL; if(r) { back = r->s; } return back; } char * dkfont_rep_get_pfb_location DK_P1(dk_font_replacement_t *,r) { char *back = NULL; if(r) { back = r->pl; } return back; } char * dkfont_rep_get_pfb_source_name DK_P1(dk_font_replacement_t *,r) { char *back = NULL; if(r) { back = r->ps; } return back; } char * dkfont_rep_get_ttf_location DK_P1(dk_font_replacement_t *,r) { char *back = NULL; if(r) { back = r->tl; } return back; } char * dkfont_rep_get_ttf_source_name DK_P1(dk_font_replacement_t *,r) { char *back = NULL; if(r) { back = r->ts; } return back; } char * dkfont_rep_get_font_type DK_P1(dk_font_replacement_t *,r) { char *back = NULL; if(r) { back = r->ft; } return back; } char * dkfont_rep_get_tex_name DK_P1(dk_font_replacement_t *,r) { char *back = NULL; if(r) { back = r->tn; } return back; } int dkfont_rep_get_features DK_P1(dk_font_replacement_t *,r) { int back = 0; if(r) { back = r->ff; } return back; } int dkfont_rep_get_source_type DK_P1(dk_font_replacement_t *,r) { int back = 0; if(r) { back = r->t; } return back; } int dkfont_rep_check_driver DK_P2(dk_font_replacement_t *,r, char *,n) { int back = 0; int found = 0; char *ptr; if(r) { if(n) { dksto_it_reset(r->di); while((ptr = (char *)dksto_it_next(r->di)) != NULL) { if(strcmp(ptr, str_asterisk) == 0) { back = 1; } if(strcmp(ptr,n) == 0) { back = 1; } found = 1; } } } if(!found) { back = 1; } return back; }