| 1 | /* |
|---|
| 2 | * FIG : Facility for Interactive Generation of figures |
|---|
| 3 | * Copyright (c) 1985 by Supoj Sutanthavibul |
|---|
| 4 | * Copyright (c) 1992 by Brian V. Smith |
|---|
| 5 | * |
|---|
| 6 | * "Permission to use, copy, modify, distribute, and sell this software and its |
|---|
| 7 | * documentation for any purpose is hereby granted without fee, provided that |
|---|
| 8 | * the above copyright notice appear in all copies and that both the copyright |
|---|
| 9 | * notice and this permission notice appear in supporting documentation. |
|---|
| 10 | * No representations are made about the suitability of this software for |
|---|
| 11 | * any purpose. It is provided "as is" without express or implied warranty." |
|---|
| 12 | * |
|---|
| 13 | * This software has been widely modified for usage inside ARB. |
|---|
| 14 | */ |
|---|
| 15 | |
|---|
| 16 | #include <stdio.h> |
|---|
| 17 | #include <stdlib.h> |
|---|
| 18 | #include <string.h> |
|---|
| 19 | #include <memory.h> |
|---|
| 20 | #include <ctype.h> |
|---|
| 21 | #include <X11/Xlib.h> |
|---|
| 22 | |
|---|
| 23 | #include <arbdb.h> |
|---|
| 24 | #include <aw_root.hxx> |
|---|
| 25 | #include "aw_device.hxx" |
|---|
| 26 | #include "aw_commn.hxx" |
|---|
| 27 | #include "aw_xfont.hxx" |
|---|
| 28 | |
|---|
| 29 | // -------------------------------------------------------------------------------- |
|---|
| 30 | |
|---|
| 31 | #define FONT_EXAMINE_MAX 5000 |
|---|
| 32 | #define KNOWN_ISO_VERSIONS 3 |
|---|
| 33 | |
|---|
| 34 | #if defined(DEVEL_RALF) |
|---|
| 35 | // #warning font debugging is active in release |
|---|
| 36 | #endif // DEVEL_RALF |
|---|
| 37 | // #define DUMP_FONT_LOOKUP |
|---|
| 38 | // #define DUMP_FONT_DETAILS |
|---|
| 39 | |
|---|
| 40 | // -------------------------------------------------------------------------------- |
|---|
| 41 | |
|---|
| 42 | |
|---|
| 43 | static bool openwinfonts; |
|---|
| 44 | |
|---|
| 45 | typedef XFontStruct *PIX_FONT; |
|---|
| 46 | appresStruct appres = { |
|---|
| 47 | true, |
|---|
| 48 | false, |
|---|
| 49 | 0, |
|---|
| 50 | }; |
|---|
| 51 | |
|---|
| 52 | // defines the preferred xfontsel-'rgstry' values (most wanted first) |
|---|
| 53 | |
|---|
| 54 | #define PREFER_ISO10646 |
|---|
| 55 | |
|---|
| 56 | #if defined(DEVEL_RALF) |
|---|
| 57 | #if defined(PREFER_ISO10646) |
|---|
| 58 | // #warning current iso setting: prefer ISO10646 (this is recommended) |
|---|
| 59 | #else |
|---|
| 60 | #warning current iso setting: prefer ISO8859 |
|---|
| 61 | #endif // PREFER_ISO10646 |
|---|
| 62 | #endif // DEVEL_RALF |
|---|
| 63 | |
|---|
| 64 | #if defined(PREFER_ISO10646) |
|---|
| 65 | static const char *known_iso_versions[KNOWN_ISO_VERSIONS] = { "ISO10646", "ISO8859", "*" }; |
|---|
| 66 | #else |
|---|
| 67 | static const char *known_iso_versions[KNOWN_ISO_VERSIONS] = { "ISO8859", "ISO10646", "*" }; |
|---|
| 68 | #endif |
|---|
| 69 | |
|---|
| 70 | struct _xfstruct x_fontinfo[AW_NUM_FONTS] = { |
|---|
| 71 | {"-adobe-times-medium-r-*--", (struct xfont*) NULL}, // #0 |
|---|
| 72 | {"-adobe-times-medium-i-*--", (struct xfont*) NULL}, // #1 |
|---|
| 73 | {"-adobe-times-bold-r-*--", (struct xfont*) NULL}, // #2 |
|---|
| 74 | {"-adobe-times-bold-i-*--", (struct xfont*) NULL}, // #3 |
|---|
| 75 | {"-schumacher-clean-medium-r-*--", (struct xfont*) NULL}, /* closest to Avant-Garde */ |
|---|
| 76 | {"-schumacher-clean-medium-i-*--", (struct xfont*) NULL}, // #5 |
|---|
| 77 | {"-schumacher-clean-bold-r-*--", (struct xfont*) NULL}, // #6 |
|---|
| 78 | {"-schumacher-clean-bold-i-*--", (struct xfont*) NULL}, // #7 |
|---|
| 79 | {"-adobe-times-medium-r-*--", (struct xfont*) NULL}, /* closest to Bookman */ |
|---|
| 80 | {"-adobe-times-medium-i-*--", (struct xfont*) NULL}, // #9 |
|---|
| 81 | {"-adobe-times-bold-r-*--", (struct xfont*) NULL}, // #10 |
|---|
| 82 | {"-adobe-times-bold-i-*--", (struct xfont*) NULL}, // #11 |
|---|
| 83 | {"-adobe-courier-medium-r-*--", (struct xfont*) NULL}, // #12 |
|---|
| 84 | {"-adobe-courier-medium-o-*--", (struct xfont*) NULL}, // #13 |
|---|
| 85 | {"-adobe-courier-bold-r-*--", (struct xfont*) NULL}, // #14 |
|---|
| 86 | {"-adobe-courier-bold-o-*--", (struct xfont*) NULL}, // #15 |
|---|
| 87 | {"-adobe-helvetica-medium-r-*--", (struct xfont*) NULL}, // #16 |
|---|
| 88 | {"-adobe-helvetica-medium-o-*--", (struct xfont*) NULL}, // #17 |
|---|
| 89 | {"-adobe-helvetica-bold-r-*--", (struct xfont*) NULL}, // #18 |
|---|
| 90 | {"-adobe-helvetica-bold-o-*--", (struct xfont*) NULL}, // #19 |
|---|
| 91 | {"-adobe-helvetica-medium-r-*--", (struct xfont*) NULL}, /* closest to Helv-nar. */ |
|---|
| 92 | {"-adobe-helvetica-medium-o-*--", (struct xfont*) NULL}, // #21 |
|---|
| 93 | {"-adobe-helvetica-bold-r-*--", (struct xfont*) NULL}, // #22 |
|---|
| 94 | {"-adobe-helvetica-bold-o-*--", (struct xfont*) NULL}, // #23 |
|---|
| 95 | {"-adobe-new century schoolbook-medium-r-*--", (struct xfont*) NULL}, // #24 |
|---|
| 96 | {"-adobe-new century schoolbook-medium-i-*--", (struct xfont*) NULL}, // #25 |
|---|
| 97 | {"-adobe-new century schoolbook-bold-r-*--", (struct xfont*) NULL}, // #26 |
|---|
| 98 | {"-adobe-new century schoolbook-bold-i-*--", (struct xfont*) NULL}, // #27 |
|---|
| 99 | {"-*-lucidabright-medium-r-*--", (struct xfont*) NULL}, /* closest to Palatino */ |
|---|
| 100 | {"-*-lucidabright-medium-i-*--", (struct xfont*) NULL}, // #29 |
|---|
| 101 | {"-*-lucidabright-demibold-r-*--", (struct xfont*) NULL}, // #30 |
|---|
| 102 | {"-*-lucidabright-demibold-i-*--", (struct xfont*) NULL}, // #31 |
|---|
| 103 | {"-*-symbol-medium-r-*--", (struct xfont*) NULL}, // #32 |
|---|
| 104 | {"-*-zapfchancery-medium-i-*--", (struct xfont*) NULL}, // #33 |
|---|
| 105 | {"-*-zapfdingbats-*-*-*--", (struct xfont*) NULL}, // #34 |
|---|
| 106 | // non xfig fonts, will be mapped to xfig fonts on export |
|---|
| 107 | {"-*-lucida-medium-r-*-*-", (struct xfont*) NULL}, // #35 |
|---|
| 108 | {"-*-lucida-medium-i-*-*-", (struct xfont*) NULL}, // #36 |
|---|
| 109 | {"-*-lucida-bold-r-*-*-", (struct xfont*) NULL}, // #37 |
|---|
| 110 | {"-*-lucida-bold-i-*-*-", (struct xfont*) NULL}, // #38 |
|---|
| 111 | {"-*-lucidatypewriter-medium-r-*-*-", (struct xfont*) NULL}, // #39 |
|---|
| 112 | {"-*-lucidatypewriter-bold-r-*-*-", (struct xfont*) NULL}, // #40 |
|---|
| 113 | {"-*-screen-medium-r-*-*-", (struct xfont*) NULL}, // #41 |
|---|
| 114 | {"-*-screen-bold-r-*-*-", (struct xfont*) NULL}, // #42 |
|---|
| 115 | {"-*-clean-medium-r-*-*-", (struct xfont*) NULL}, // #43 |
|---|
| 116 | {"-*-clean-bold-r-*-*-", (struct xfont*) NULL}, // #44 |
|---|
| 117 | {"-*-terminal-medium-r-*-*-", (struct xfont*) NULL}, // #45 |
|---|
| 118 | {"-*-terminal-bold-r-*-*-", (struct xfont*) NULL}, // #46 |
|---|
| 119 | }; |
|---|
| 120 | |
|---|
| 121 | struct _fstruct ps_fontinfo[AW_NUM_FONTS + 1] = { |
|---|
| 122 | // map window fonts to postscript fonts |
|---|
| 123 | // negative values indicate monospaced fonts |
|---|
| 124 | {"Default", -1}, |
|---|
| 125 | {"Times-Roman", 0}, |
|---|
| 126 | {"Times-Italic", 1}, |
|---|
| 127 | {"Times-Bold", 2}, |
|---|
| 128 | {"Times-BoldItalic", 3}, |
|---|
| 129 | {"AvantGarde-Book", 4}, |
|---|
| 130 | {"AvantGarde-BookOblique", 5}, |
|---|
| 131 | {"AvantGarde-Demi", 6}, |
|---|
| 132 | {"AvantGarde-DemiOblique", 7}, |
|---|
| 133 | {"Bookman-Light", 8}, |
|---|
| 134 | {"Bookman-LightItalic", 9}, |
|---|
| 135 | {"Bookman-Demi", 10}, |
|---|
| 136 | {"Bookman-DemiItalic", 11}, |
|---|
| 137 | {"Courier", -12}, |
|---|
| 138 | {"Courier-Oblique", -13}, |
|---|
| 139 | {"Courier-Bold", -14}, |
|---|
| 140 | {"Courier-BoldOblique", -15}, |
|---|
| 141 | {"Helvetica", 16}, |
|---|
| 142 | {"Helvetica-Oblique", 17}, |
|---|
| 143 | {"Helvetica-Bold", 18}, |
|---|
| 144 | {"Helvetica-BoldOblique", 19}, |
|---|
| 145 | {"Helvetica-Narrow", 20}, |
|---|
| 146 | {"Helvetica-Narrow-Oblique", 21}, |
|---|
| 147 | {"Helvetica-Narrow-Bold", 22}, |
|---|
| 148 | {"Helvetica-Narrow-BoldOblique", 23}, |
|---|
| 149 | {"NewCenturySchlbk-Roman", 24}, |
|---|
| 150 | {"NewCenturySchlbk-Italic", 25}, |
|---|
| 151 | {"NewCenturySchlbk-Bold", 26}, |
|---|
| 152 | {"NewCenturySchlbk-BoldItalic", 27}, |
|---|
| 153 | {"Palatino-Roman", 28}, |
|---|
| 154 | {"Palatino-Italic", 29}, |
|---|
| 155 | {"Palatino-Bold", 30}, |
|---|
| 156 | {"Palatino-BoldItalic", 31}, |
|---|
| 157 | {"Symbol", 32}, |
|---|
| 158 | {"ZapfChancery-MediumItalic", 33}, |
|---|
| 159 | {"ZapfDingbats", 34}, |
|---|
| 160 | {"LucidaSans", 16}, |
|---|
| 161 | {"LucidaSans-Italic", 17}, |
|---|
| 162 | {"LucidaSans-Bold", 18}, |
|---|
| 163 | {"LucidaSans-BoldItalic", 19}, |
|---|
| 164 | {"LucidaSansTypewriter", -12}, |
|---|
| 165 | {"LucidaSansTypewriter-Bold", -14}, |
|---|
| 166 | {"Screen", -16}, |
|---|
| 167 | {"Screen-Bold", -18}, |
|---|
| 168 | {"Clean", -12}, |
|---|
| 169 | {"Clean-Bold", -14}, |
|---|
| 170 | {"Terminal", -12}, |
|---|
| 171 | {"Terminal-Bold", -14}, |
|---|
| 172 | }; |
|---|
| 173 | |
|---|
| 174 | #define FONT_STRING_PARTS 14 |
|---|
| 175 | |
|---|
| 176 | static const char *parseFontString(const char *fontname, int *minus_position) { |
|---|
| 177 | const char *error = 0; |
|---|
| 178 | const char *minus = strchr(fontname, '-'); |
|---|
| 179 | int count = 0; |
|---|
| 180 | |
|---|
| 181 | for (; minus; minus = strchr(minus+1, '-'), ++count) { |
|---|
| 182 | if (count >= FONT_STRING_PARTS) { error = "too many '-'"; break; } |
|---|
| 183 | minus_position[count] = minus-fontname; |
|---|
| 184 | } |
|---|
| 185 | if (count != FONT_STRING_PARTS) error = "expected 14 '-'"; |
|---|
| 186 | |
|---|
| 187 | return error; |
|---|
| 188 | } |
|---|
| 189 | static char *getParsedFontPart(const char *fontname, int *minus_position, int idx) { |
|---|
| 190 | aw_assert(idx >= 0 && idx<FONT_STRING_PARTS); |
|---|
| 191 | |
|---|
| 192 | int startpos = minus_position[idx]+1; // behind minus |
|---|
| 193 | int endpos = (idx == (FONT_STRING_PARTS-1) ? strlen(fontname) : minus_position[idx+1])-1; // in front of minus/string-end |
|---|
| 194 | int length = endpos-startpos+1; // excluding minus |
|---|
| 195 | char *result = new char[length+1]; |
|---|
| 196 | |
|---|
| 197 | memcpy(result, fontname+startpos, length); |
|---|
| 198 | result[length] = 0; |
|---|
| 199 | |
|---|
| 200 | return result; |
|---|
| 201 | } |
|---|
| 202 | |
|---|
| 203 | /* parse the point size of font 'name' */ |
|---|
| 204 | /* e.g. -adobe-courier-bold-o-normal--10-100-75-75-m-60-ISO8859-1 */ |
|---|
| 205 | |
|---|
| 206 | static int parsesize(const char *fontname) { |
|---|
| 207 | int pos[14]; |
|---|
| 208 | int size; |
|---|
| 209 | const char *error = parseFontString(fontname, pos); |
|---|
| 210 | |
|---|
| 211 | if (!error) { |
|---|
| 212 | char *sizeString = getParsedFontPart(fontname, pos, 6); |
|---|
| 213 | size = atoi(sizeString); |
|---|
| 214 | if (size == 0 && strcmp(sizeString, "0") != 0) { |
|---|
| 215 | error = GBS_global_string("Can't parse size (from '%s')", sizeString); |
|---|
| 216 | } |
|---|
| 217 | delete [] sizeString; |
|---|
| 218 | } |
|---|
| 219 | |
|---|
| 220 | if (error) { |
|---|
| 221 | fprintf(stderr, "Error parsing size info from '%s' (%s)\n", fontname, error); |
|---|
| 222 | return 0; |
|---|
| 223 | } |
|---|
| 224 | |
|---|
| 225 | return size; |
|---|
| 226 | } |
|---|
| 227 | |
|---|
| 228 | void aw_root_init_font(Display *tool_d) |
|---|
| 229 | { |
|---|
| 230 | if (appres.display) return; |
|---|
| 231 | |
|---|
| 232 | appres.display = tool_d; |
|---|
| 233 | #if defined(DUMP_FONT_LOOKUP) |
|---|
| 234 | appres.debug = true; |
|---|
| 235 | #endif // DUMP_FONT_LOOKUP |
|---|
| 236 | |
|---|
| 237 | /* |
|---|
| 238 | * Now initialize the font structure for the X fonts corresponding to the |
|---|
| 239 | * Postscript fonts for the canvas. OpenWindows can use any LaserWriter |
|---|
| 240 | * fonts at any size, so we don't need to load anything if we are using |
|---|
| 241 | * it. |
|---|
| 242 | */ |
|---|
| 243 | |
|---|
| 244 | /* if the user hasn't disallowed off scalable fonts, check that the |
|---|
| 245 | server really has them by checking for font of 0-0 size */ |
|---|
| 246 | openwinfonts = false; |
|---|
| 247 | if (appres.SCALABLEFONTS) { |
|---|
| 248 | char **fontlist; |
|---|
| 249 | int count; |
|---|
| 250 | |
|---|
| 251 | #if defined(DUMP_FONT_LOOKUP) |
|---|
| 252 | printf("Searching for SCALABLEFONTS\n"); |
|---|
| 253 | #endif // DUMP_FONT_LOOKUP |
|---|
| 254 | |
|---|
| 255 | /* first look for OpenWindow style font names (e.g. times-roman) */ |
|---|
| 256 | if ((fontlist = XListFonts(tool_d, ps_fontinfo[1].name, 1, &count))!=0) { |
|---|
| 257 | openwinfonts = true; /* yes, use them */ |
|---|
| 258 | for (int f=0; f<AW_NUM_FONTS; f++) { /* copy the OpenWindow font names */ |
|---|
| 259 | x_fontinfo[f].templat = ps_fontinfo[f+1].name; |
|---|
| 260 | #if defined(DUMP_FONT_LOOKUP) |
|---|
| 261 | printf("ps_fontinfo[f+1].name='%s'\n",ps_fontinfo[f+1].name); |
|---|
| 262 | #endif // DUMP_FONT_LOOKUP |
|---|
| 263 | } |
|---|
| 264 | XFreeFontNames(fontlist); |
|---|
| 265 | } else { |
|---|
| 266 | char templat[200]; |
|---|
| 267 | strcpy(templat,x_fontinfo[0].templat); /* nope, check for font size 0 */ |
|---|
| 268 | strcat(templat,"0-0-*-*-*-*-*-*"); |
|---|
| 269 | if ((fontlist = XListFonts(tool_d, templat, 1, &count))!=0){ |
|---|
| 270 | #if defined(DUMP_FONT_LOOKUP) |
|---|
| 271 | printf("Using SCALABLEFONTS!\n"); |
|---|
| 272 | #endif // DUMP_FONT_LOOKUP |
|---|
| 273 | XFreeFontNames(fontlist); |
|---|
| 274 | }else{ |
|---|
| 275 | #if defined(DUMP_FONT_LOOKUP) |
|---|
| 276 | printf("Not using SCALABLEFONTS!\n"); |
|---|
| 277 | #endif // DUMP_FONT_LOOKUP |
|---|
| 278 | appres.SCALABLEFONTS = false; /* none, turn off request for them */ |
|---|
| 279 | } |
|---|
| 280 | } |
|---|
| 281 | } |
|---|
| 282 | |
|---|
| 283 | /* no scalable fonts - query the server for all the font |
|---|
| 284 | names and sizes and build a list of them */ |
|---|
| 285 | |
|---|
| 286 | struct found_font { const char *fn; int s; }; |
|---|
| 287 | |
|---|
| 288 | if (!appres.SCALABLEFONTS) { |
|---|
| 289 | found_font *flist = new found_font[FONT_EXAMINE_MAX]; |
|---|
| 290 | |
|---|
| 291 | for (int f = 0; f < AW_NUM_FONTS; f++) { |
|---|
| 292 | char **fontlist[KNOWN_ISO_VERSIONS]; |
|---|
| 293 | int iso; |
|---|
| 294 | int found_fonts = 0; |
|---|
| 295 | |
|---|
| 296 | for (iso = 0; iso<KNOWN_ISO_VERSIONS; ++iso) fontlist[iso] = 0; |
|---|
| 297 | |
|---|
| 298 | for (iso = 0; iso<KNOWN_ISO_VERSIONS; ++iso) { |
|---|
| 299 | char *font_template = GBS_global_string_copy("%s*-*-*-*-*-*-%s-*", x_fontinfo[f].templat, known_iso_versions[iso]); |
|---|
| 300 | int count; |
|---|
| 301 | |
|---|
| 302 | fontlist[iso] = XListFonts(tool_d, font_template, FONT_EXAMINE_MAX, &count); |
|---|
| 303 | if (fontlist[iso]) { |
|---|
| 304 | if ((found_fonts+count) >= FONT_EXAMINE_MAX) { |
|---|
| 305 | printf("Warning: Too many fonts found for '%s..%s' - ARB can't examine all fonts\n", x_fontinfo[f].templat, known_iso_versions[iso]); |
|---|
| 306 | count = FONT_EXAMINE_MAX-found_fonts; |
|---|
| 307 | } |
|---|
| 308 | for (int c = 0; c<count; ++c) { |
|---|
| 309 | const char *fontname = fontlist[iso][c]; |
|---|
| 310 | int size = parsesize(fontname); |
|---|
| 311 | flist[found_fonts].fn = fontname; // valid as long fontlist[iso] is not free'd! |
|---|
| 312 | flist[found_fonts].s = size; |
|---|
| 313 | found_fonts++; |
|---|
| 314 | } |
|---|
| 315 | } |
|---|
| 316 | |
|---|
| 317 | free(font_template); |
|---|
| 318 | } |
|---|
| 319 | |
|---|
| 320 | #if defined(DUMP_FONT_LOOKUP) |
|---|
| 321 | printf("Considering %i fonts for '%s'\n", found_fonts, x_fontinfo[f].templat); |
|---|
| 322 | #endif // DUMP_FONT_LOOKUP |
|---|
| 323 | |
|---|
| 324 | aw_assert(found_fonts <= FONT_EXAMINE_MAX); |
|---|
| 325 | struct xfont *nf = NULL; |
|---|
| 326 | |
|---|
| 327 | for (int size = MIN_FONTSIZE; size <= MAX_FONTSIZE; size++) { // scan all useful sizes |
|---|
| 328 | int i; |
|---|
| 329 | for (i = 0; i < found_fonts; i++) { |
|---|
| 330 | if (flist[i].s == size) break; // search first font matching current size |
|---|
| 331 | } |
|---|
| 332 | |
|---|
| 333 | if (i < found_fonts && flist[i].s == size) { |
|---|
| 334 | struct xfont *newfont = (struct xfont *)malloc(sizeof(struct xfont)); |
|---|
| 335 | |
|---|
| 336 | (nf ? nf->next : x_fontinfo[f].xfontlist) = newfont; |
|---|
| 337 | nf = newfont; |
|---|
| 338 | |
|---|
| 339 | // store size and actual fontname : |
|---|
| 340 | nf->size = size; |
|---|
| 341 | nf->fname = strdup(flist[i].fn); |
|---|
| 342 | nf->fstruct = NULL; |
|---|
| 343 | nf->next = NULL; |
|---|
| 344 | } |
|---|
| 345 | } |
|---|
| 346 | |
|---|
| 347 | if (!nf) { // no font has been found -> fallback to "fixed 12pt" |
|---|
| 348 | aw_assert(x_fontinfo[f].xfontlist == 0); |
|---|
| 349 | struct xfont *newfont = (struct xfont *)malloc(sizeof(struct xfont)); |
|---|
| 350 | x_fontinfo[f].xfontlist = newfont; |
|---|
| 351 | |
|---|
| 352 | newfont->size = DEF_FONTSIZE; |
|---|
| 353 | newfont->fname = strdup(NORMAL_FONT); |
|---|
| 354 | newfont->fstruct = NULL; |
|---|
| 355 | newfont->next = NULL; |
|---|
| 356 | } |
|---|
| 357 | |
|---|
| 358 | #if defined(DUMP_FONT_LOOKUP) |
|---|
| 359 | nf = x_fontinfo[f].xfontlist; |
|---|
| 360 | printf("Fonts used for '%s':\n", x_fontinfo[f].templat); |
|---|
| 361 | while (nf) { |
|---|
| 362 | printf("- %2i pt: '%s'\n", nf->size, nf->fname); |
|---|
| 363 | nf = nf->next; |
|---|
| 364 | } |
|---|
| 365 | #endif // DUMP_FONT_LOOKUP |
|---|
| 366 | |
|---|
| 367 | for (iso = 0; iso<KNOWN_ISO_VERSIONS; ++iso) XFreeFontNames(fontlist[iso]); |
|---|
| 368 | } |
|---|
| 369 | |
|---|
| 370 | delete [] flist; |
|---|
| 371 | } |
|---|
| 372 | } |
|---|
| 373 | |
|---|
| 374 | #if defined(DUMP_FONT_DETAILS) |
|---|
| 375 | static void dumpFontInformation(struct xfont *xf) { |
|---|
| 376 | printf("Font information for '%s':\n", xf->fname); |
|---|
| 377 | XFontStruct *xfs = xf->fstruct; |
|---|
| 378 | printf("- max letter ascent = %2i\n", xfs->max_bounds.ascent); |
|---|
| 379 | printf("- max letter descent = %2i\n", xfs->max_bounds.descent); |
|---|
| 380 | printf("- max letter height = %2i\n", xfs->max_bounds.ascent + xfs->max_bounds.descent); |
|---|
| 381 | printf("- max letter width = %2i\n", xfs->max_bounds.width); |
|---|
| 382 | } |
|---|
| 383 | #endif // DEBUG |
|---|
| 384 | |
|---|
| 385 | /* |
|---|
| 386 | * Lookup an X font, "f" corresponding to a Postscript font style that is |
|---|
| 387 | * close in size to "s" |
|---|
| 388 | */ |
|---|
| 389 | |
|---|
| 390 | static bool lookfont(Display *tool_d, int f, int s, int& found_size, bool verboose, bool only_query, PIX_FONT *fontstPtr) |
|---|
| 391 | // returns true if appropriate font is available. |
|---|
| 392 | // |
|---|
| 393 | // 'found_size' is set to the actually found size, which may be bigger or smaller than 's', if the requested size is not available |
|---|
| 394 | // |
|---|
| 395 | // if 'only_query' is true, then only report availability |
|---|
| 396 | // if 'only_query' is false, then actually load the font and store the loaded fontstruct in 'fontstPtr' |
|---|
| 397 | { |
|---|
| 398 | // char fn[128]; memset(fn,0,128); |
|---|
| 399 | bool found; |
|---|
| 400 | struct xfont *newfont, *nf, *oldnf; |
|---|
| 401 | |
|---|
| 402 | #if defined(DEVEL_RALF) |
|---|
| 403 | #warning scalability shall be checked for each font -- not only for first |
|---|
| 404 | #warning fontdetection is called for each GC -- do some caching ? |
|---|
| 405 | #endif // DEVEL_RALF |
|---|
| 406 | |
|---|
| 407 | found_size = -1; |
|---|
| 408 | |
|---|
| 409 | if (f == DEFAULT) |
|---|
| 410 | f = 0; /* pass back the -normal font font */ |
|---|
| 411 | if (s < 0) |
|---|
| 412 | s = DEF_FONTSIZE; /* default font size */ |
|---|
| 413 | |
|---|
| 414 | /* see if we've already loaded that font size 's' |
|---|
| 415 | from the font family 'f' */ |
|---|
| 416 | |
|---|
| 417 | found = false; |
|---|
| 418 | |
|---|
| 419 | /* start with the basic font name (e.g. adobe-times-medium-r-normal-... |
|---|
| 420 | OR times-roman for OpenWindows fonts) */ |
|---|
| 421 | |
|---|
| 422 | nf = x_fontinfo[f].xfontlist; |
|---|
| 423 | if (!nf) nf = x_fontinfo[0].xfontlist; |
|---|
| 424 | oldnf = nf; |
|---|
| 425 | if (nf != NULL) { |
|---|
| 426 | if (nf->size > s && !appres.SCALABLEFONTS) { |
|---|
| 427 | found = true; |
|---|
| 428 | } |
|---|
| 429 | else { |
|---|
| 430 | while (nf != NULL) { |
|---|
| 431 | if (nf->size == s || |
|---|
| 432 | (!appres.SCALABLEFONTS && (nf->size >= s && oldnf->size <= s ))) |
|---|
| 433 | { |
|---|
| 434 | found = true; |
|---|
| 435 | break; |
|---|
| 436 | } |
|---|
| 437 | oldnf = nf; |
|---|
| 438 | nf = nf->next; |
|---|
| 439 | } |
|---|
| 440 | } |
|---|
| 441 | } |
|---|
| 442 | if (found) { /* found exact size (or only larger available) */ |
|---|
| 443 | // strcpy(fn,nf->fname); /* put the name in fn */ |
|---|
| 444 | if (verboose) { |
|---|
| 445 | if (s < nf->size) fprintf(stderr, "Font size %d not found, using larger %d point\n", s, nf->size); |
|---|
| 446 | if (appres.debug) fprintf(stderr, "Detected font %s\n", nf->fname); |
|---|
| 447 | } |
|---|
| 448 | } |
|---|
| 449 | else if (!appres.SCALABLEFONTS) { /* not found, use largest available */ |
|---|
| 450 | nf = oldnf; |
|---|
| 451 | // strcpy(fn,nf->fname); /* put the name in fn */ |
|---|
| 452 | if (verboose) { |
|---|
| 453 | if (s > nf->size) fprintf(stderr, "Font size %d not found, using smaller %d point\n", s, nf->size); |
|---|
| 454 | if (appres.debug) fprintf(stderr, "Using font %s for size %d\n", nf->fname, s); |
|---|
| 455 | } |
|---|
| 456 | } |
|---|
| 457 | else { /* SCALABLE; none yet of that size, alloc one and put it in the list */ |
|---|
| 458 | newfont = (struct xfont *) malloc(sizeof(struct xfont)); |
|---|
| 459 | /* add it on to the end of the list */ |
|---|
| 460 | |
|---|
| 461 | nf = oldnf ? oldnf->next : 0; // store successor |
|---|
| 462 | |
|---|
| 463 | if (x_fontinfo[f].xfontlist == NULL) x_fontinfo[f].xfontlist = newfont; |
|---|
| 464 | else oldnf->next = newfont; |
|---|
| 465 | |
|---|
| 466 | newfont->next = nf; // old successor in fontlist |
|---|
| 467 | newfont->size = s; |
|---|
| 468 | newfont->fstruct = NULL; |
|---|
| 469 | newfont->fname = NULL; |
|---|
| 470 | |
|---|
| 471 | nf = newfont; |
|---|
| 472 | |
|---|
| 473 | if (openwinfonts) { |
|---|
| 474 | /* OpenWindows fonts, create font name like times-roman-13 */ |
|---|
| 475 | |
|---|
| 476 | nf->fname = GBS_global_string_copy("%s-%d", x_fontinfo[f].templat, s); |
|---|
| 477 | // sprintf(fn, "%s-%d", x_fontinfo[f].templat, s); |
|---|
| 478 | } |
|---|
| 479 | else { |
|---|
| 480 | // X11 fonts, create a full XLFD font name |
|---|
| 481 | // attach pointsize to font name, use the pixel field instead of points in the fontname so that the |
|---|
| 482 | // font scales with screen size |
|---|
| 483 | |
|---|
| 484 | for (int iso = 0; iso<KNOWN_ISO_VERSIONS; ++iso) { |
|---|
| 485 | char *fontname = GBS_global_string_copy("%s%d-*-*-*-*-*-%s-*", x_fontinfo[f].templat, s, known_iso_versions[iso]); |
|---|
| 486 | // sprintf(fn, "%s%d-*-*-*-*-*-%s-*", x_fontinfo[f].templat, s, known_iso_versions[iso]); |
|---|
| 487 | #if defined(DUMP_FONT_LOOKUP) |
|---|
| 488 | fprintf(stderr, "Checking for '%s' (x_fontinfo[%i].templat='%s')\n", fontname, f, x_fontinfo[f].templat); |
|---|
| 489 | #endif |
|---|
| 490 | |
|---|
| 491 | // PIX_FONT fontst = XQueryFont(tool_d, fontname); |
|---|
| 492 | // PIX_FONT fontst = XLoadQueryFont(tool_d, fontname); // @@@ why loaded here and not below (at least use XQueryFont instead!) |
|---|
| 493 | |
|---|
| 494 | int matching_fonts_found; |
|---|
| 495 | char **matching_fonts = XListFonts(tool_d, fontname, 1, &matching_fonts_found); |
|---|
| 496 | |
|---|
| 497 | if (matching_fonts) { |
|---|
| 498 | XFreeFontNames(matching_fonts); |
|---|
| 499 | aw_assert(matching_fonts_found >= 1); |
|---|
| 500 | nf->fname = fontname; |
|---|
| 501 | break; |
|---|
| 502 | } |
|---|
| 503 | |
|---|
| 504 | // if (fontst) { |
|---|
| 505 | // XFreeFontInfo(fontst); // only did query -- loading done below |
|---|
| 506 | // // nf->fstruct = fontst; |
|---|
| 507 | // nf->fname = fontname; |
|---|
| 508 | // break; |
|---|
| 509 | // } |
|---|
| 510 | free(fontname); |
|---|
| 511 | } |
|---|
| 512 | // @@@ what if nf->fstruct is 0 now ? |
|---|
| 513 | } |
|---|
| 514 | #ifndef DEVEL_JB |
|---|
| 515 | aw_assert(nf->fname); |
|---|
| 516 | #endif |
|---|
| 517 | } /* scalable */ |
|---|
| 518 | |
|---|
| 519 | bool font_found = true; |
|---|
| 520 | |
|---|
| 521 | if (nf->fstruct == NULL) { |
|---|
| 522 | if (only_query) { |
|---|
| 523 | ; // assume its available (or use XQueryFont to reduce server-client bandwidth) |
|---|
| 524 | } |
|---|
| 525 | else { |
|---|
| 526 | if (appres.debug && verboose) fprintf(stderr, "Loading font '%s'\n", nf->fname); |
|---|
| 527 | PIX_FONT fontst = XLoadQueryFont(tool_d, nf->fname); |
|---|
| 528 | if (fontst == NULL) { |
|---|
| 529 | fprintf(stderr, "ARB fontpackage: Unexpectedly couldn't load font '%s', falling back to '%s' (f=%i, s=%i)\n", nf->fname, NORMAL_FONT, f, s); |
|---|
| 530 | fontst = XLoadQueryFont(tool_d, NORMAL_FONT); // @@@ may return 0! |
|---|
| 531 | freedup(nf->fname, NORMAL_FONT); /* store actual name */ |
|---|
| 532 | } |
|---|
| 533 | /* put the structure in the list */ |
|---|
| 534 | nf->fstruct = fontst; |
|---|
| 535 | } |
|---|
| 536 | } |
|---|
| 537 | |
|---|
| 538 | #if defined(DUMP_FONT_DETAILS) |
|---|
| 539 | dumpFontInformation(nf); |
|---|
| 540 | #endif // DEBUG |
|---|
| 541 | |
|---|
| 542 | found_size = nf->size; // report used size |
|---|
| 543 | *fontstPtr = nf->fstruct; |
|---|
| 544 | |
|---|
| 545 | return font_found; |
|---|
| 546 | } |
|---|
| 547 | |
|---|
| 548 | static int get_available_fontsizes(Display *tool_d, int f, int *available_sizes) { |
|---|
| 549 | // returns number of available sizes |
|---|
| 550 | // specific sizes are stored in available_sizes[] |
|---|
| 551 | |
|---|
| 552 | int size_count = 0; |
|---|
| 553 | for (int size = MAX_FONTSIZE; size >= MIN_FONTSIZE; --size) { |
|---|
| 554 | int found_size; |
|---|
| 555 | PIX_FONT fontst; |
|---|
| 556 | |
|---|
| 557 | #if defined(DEBUG) |
|---|
| 558 | bool was_found = |
|---|
| 559 | #endif // DEBUG |
|---|
| 560 | lookfont(tool_d, f, size, found_size, false, true, &fontst); |
|---|
| 561 | |
|---|
| 562 | aw_assert(was_found); // because lookfont does fallback |
|---|
| 563 | |
|---|
| 564 | if (found_size<size) size = found_size; |
|---|
| 565 | if (found_size == size) available_sizes[size_count++] = size; |
|---|
| 566 | } |
|---|
| 567 | |
|---|
| 568 | // reverse order of found fontsizes |
|---|
| 569 | if (size_count>1) { |
|---|
| 570 | for (int reverse = size_count/2-1; reverse >= 0; --reverse) { |
|---|
| 571 | int o = size_count-1-reverse; |
|---|
| 572 | aw_assert(o >= 0 && o<size_count); |
|---|
| 573 | |
|---|
| 574 | int s = available_sizes[reverse]; |
|---|
| 575 | available_sizes[reverse] = available_sizes[o]; |
|---|
| 576 | available_sizes[o] = s; |
|---|
| 577 | } |
|---|
| 578 | } |
|---|
| 579 | |
|---|
| 580 | return size_count; |
|---|
| 581 | } |
|---|
| 582 | |
|---|
| 583 | static char *caps(char *sentence) { |
|---|
| 584 | bool doCaps = true; |
|---|
| 585 | for (int i = 0; sentence[i]; ++i) { |
|---|
| 586 | if (isalpha(sentence[i])) { |
|---|
| 587 | if (doCaps) { |
|---|
| 588 | sentence[i] = toupper(sentence[i]); |
|---|
| 589 | doCaps = false; |
|---|
| 590 | } |
|---|
| 591 | } |
|---|
| 592 | else { |
|---|
| 593 | doCaps = true; |
|---|
| 594 | } |
|---|
| 595 | } |
|---|
| 596 | return sentence; |
|---|
| 597 | } |
|---|
| 598 | |
|---|
| 599 | |
|---|
| 600 | const char *AW_root::font_2_ascii(AW_font font_nr) |
|---|
| 601 | { |
|---|
| 602 | aw_assert(font_nr >= 0); |
|---|
| 603 | // if (font_nr < 0) return "FIXED"; |
|---|
| 604 | if (font_nr<0 || font_nr>=AW_NUM_FONTS ) return 0; |
|---|
| 605 | |
|---|
| 606 | const char *readable_fontname = 0; |
|---|
| 607 | struct _xfstruct& xf = x_fontinfo[font_nr]; |
|---|
| 608 | |
|---|
| 609 | if (xf.xfontlist) { |
|---|
| 610 | const char *fontname = xf.xfontlist->fname; |
|---|
| 611 | |
|---|
| 612 | if (strcmp(fontname, "fixed") == 0) { |
|---|
| 613 | readable_fontname = GBS_global_string("[not found: %s]", xf.templat); |
|---|
| 614 | } |
|---|
| 615 | else { |
|---|
| 616 | int pos[14]; |
|---|
| 617 | const char *error = parseFontString(fontname, pos); |
|---|
| 618 | if (error) { |
|---|
| 619 | readable_fontname = GBS_global_string("[%s - parse-error (%s)]", fontname, error); |
|---|
| 620 | } |
|---|
| 621 | else { |
|---|
| 622 | char *fndry = caps(getParsedFontPart(fontname, pos, 0)); |
|---|
| 623 | char *fmly = caps(getParsedFontPart(fontname, pos, 1)); |
|---|
| 624 | char *wght = getParsedFontPart(fontname, pos, 2); wght[3] = 0; |
|---|
| 625 | char *slant = getParsedFontPart(fontname, pos, 3); |
|---|
| 626 | char *rgstry = getParsedFontPart(fontname, pos, 12); |
|---|
| 627 | |
|---|
| 628 | readable_fontname = GBS_global_string("%s %s %s,%s,%s", |
|---|
| 629 | fndry, fmly, |
|---|
| 630 | wght, slant, |
|---|
| 631 | rgstry); |
|---|
| 632 | delete [] rgstry; |
|---|
| 633 | delete [] slant; |
|---|
| 634 | delete [] wght; |
|---|
| 635 | delete [] fmly; |
|---|
| 636 | delete [] fndry; |
|---|
| 637 | } |
|---|
| 638 | } |
|---|
| 639 | } |
|---|
| 640 | else { |
|---|
| 641 | readable_fontname = xf.templat; |
|---|
| 642 | } |
|---|
| 643 | return readable_fontname; |
|---|
| 644 | // return (ps_fontinfo[font_nr+1].name); |
|---|
| 645 | } |
|---|
| 646 | |
|---|
| 647 | int AW_root::font_2_xfig(AW_font font_nr) |
|---|
| 648 | { |
|---|
| 649 | if (font_nr<0 || font_nr>=AW_NUM_FONTS ) return 0; |
|---|
| 650 | return (ps_fontinfo[font_nr+1].xfontnum); |
|---|
| 651 | } |
|---|
| 652 | |
|---|
| 653 | inline bool CI_NonExistChar(const XCharStruct *cs) { |
|---|
| 654 | return |
|---|
| 655 | cs->width == 0 && |
|---|
| 656 | (cs->rbearing|cs->lbearing|cs->ascent|cs->descent) == 0; |
|---|
| 657 | } |
|---|
| 658 | |
|---|
| 659 | inline void CI_GetCharInfo_1D(const XFontStruct *fs, unsigned col, const XCharStruct *def, const XCharStruct*& cs) |
|---|
| 660 | { |
|---|
| 661 | cs = def; |
|---|
| 662 | aw_assert(fs->min_byte1 == 0 && fs->max_byte1 == 0); // otherwise CI_GetCharInfo_1D is not the appropriate function |
|---|
| 663 | if (col >= fs->min_char_or_byte2 && col <= fs->max_char_or_byte2) { |
|---|
| 664 | if (fs->per_char == NULL) { |
|---|
| 665 | cs = &fs->min_bounds; |
|---|
| 666 | } else { |
|---|
| 667 | cs = &fs->per_char[col - fs->min_char_or_byte2]; |
|---|
| 668 | if (CI_NonExistChar(cs)) cs = def; |
|---|
| 669 | } |
|---|
| 670 | } |
|---|
| 671 | } |
|---|
| 672 | |
|---|
| 673 | inline void CI_GetDefaultInfo_1D(const XFontStruct *fs, const XCharStruct*& cs) { |
|---|
| 674 | CI_GetCharInfo_1D(fs, fs->default_char, NULL, cs); |
|---|
| 675 | } |
|---|
| 676 | |
|---|
| 677 | /* |
|---|
| 678 | * CI_GET_CHAR_INFO_2D - return the charinfo struct for the indicated row and |
|---|
| 679 | * column. This is used for fonts that have more than row zero. |
|---|
| 680 | */ |
|---|
| 681 | |
|---|
| 682 | inline void CI_GetCharInfo_2D(const XFontStruct *fs, unsigned row, unsigned col, const XCharStruct *def, const XCharStruct*& cs) |
|---|
| 683 | { |
|---|
| 684 | cs = def; |
|---|
| 685 | if (row >= fs->min_byte1 && row <= fs->max_byte1 && |
|---|
| 686 | col >= fs->min_char_or_byte2 && col <= fs->max_char_or_byte2) |
|---|
| 687 | { |
|---|
| 688 | if (fs->per_char == NULL) { |
|---|
| 689 | cs = &fs->min_bounds; |
|---|
| 690 | } |
|---|
| 691 | else { |
|---|
| 692 | cs = &fs->per_char[((row - fs->min_byte1) * |
|---|
| 693 | (fs->max_char_or_byte2 - |
|---|
| 694 | fs->min_char_or_byte2 + 1)) + |
|---|
| 695 | (col - fs->min_char_or_byte2)]; |
|---|
| 696 | if (CI_NonExistChar(cs)) cs = def; |
|---|
| 697 | } |
|---|
| 698 | } |
|---|
| 699 | } |
|---|
| 700 | |
|---|
| 701 | inline void CI_GetDefaultInfo_2D(const XFontStruct *fs, const XCharStruct*& cs) |
|---|
| 702 | { |
|---|
| 703 | unsigned int r = (fs->default_char >> 8); |
|---|
| 704 | unsigned int c = (fs->default_char & 0xff); |
|---|
| 705 | CI_GetCharInfo_2D (fs, r, c, NULL, cs); |
|---|
| 706 | } |
|---|
| 707 | |
|---|
| 708 | /* |
|---|
| 709 | * CI_GetRowzeroCharInfo_2D - do the same thing as CI_GetCharInfo_1D, |
|---|
| 710 | * except that the font has more than one row. This is special case of more |
|---|
| 711 | * general version used in XTextExt16.c since row == 0. This is used when |
|---|
| 712 | * max_byte2 is not zero. A further optimization would do the check for |
|---|
| 713 | * min_byte1 being zero ahead of time. |
|---|
| 714 | */ |
|---|
| 715 | |
|---|
| 716 | inline void CI_GetRowzeroCharInfo_2D(const XFontStruct *fs, unsigned col, const XCharStruct *def, const XCharStruct*& cs) |
|---|
| 717 | { |
|---|
| 718 | cs = def; |
|---|
| 719 | if (fs->min_byte1 == 0 && |
|---|
| 720 | col >= fs->min_char_or_byte2 && col <= fs->max_char_or_byte2) { |
|---|
| 721 | if (fs->per_char == NULL) { |
|---|
| 722 | cs = &fs->min_bounds; |
|---|
| 723 | } else { |
|---|
| 724 | cs = &fs->per_char[(col - fs->min_char_or_byte2)]; |
|---|
| 725 | if (CI_NonExistChar(cs)) cs = def; |
|---|
| 726 | } |
|---|
| 727 | } |
|---|
| 728 | } |
|---|
| 729 | |
|---|
| 730 | |
|---|
| 731 | void AW_GC_Xm::set_font(AW_font font_nr, int size, int *found_size) |
|---|
| 732 | // if found_size != 0 -> return value for used font size |
|---|
| 733 | { |
|---|
| 734 | XFontStruct *xfs; |
|---|
| 735 | |
|---|
| 736 | { |
|---|
| 737 | int found_font_size; |
|---|
| 738 | #if defined(DEBUG) |
|---|
| 739 | bool was_found = |
|---|
| 740 | #endif // DEBUG |
|---|
| 741 | lookfont(common->display, font_nr, size, found_font_size, true, false, &xfs); |
|---|
| 742 | aw_assert(was_found); // because lookfont does fallback |
|---|
| 743 | |
|---|
| 744 | if (found_size) *found_size = found_font_size; |
|---|
| 745 | } |
|---|
| 746 | XSetFont(common->display, gc, xfs->fid); |
|---|
| 747 | curfont = *xfs; |
|---|
| 748 | |
|---|
| 749 | const XCharStruct *cs; |
|---|
| 750 | const XCharStruct *def; /* info about default char */ |
|---|
| 751 | bool singlerow = (xfs->max_byte1 == 0); /* optimization */ |
|---|
| 752 | |
|---|
| 753 | if (singlerow) { /* optimization */ |
|---|
| 754 | CI_GetDefaultInfo_1D(xfs, def); |
|---|
| 755 | } |
|---|
| 756 | else { |
|---|
| 757 | CI_GetDefaultInfo_2D(xfs, def); |
|---|
| 758 | } |
|---|
| 759 | |
|---|
| 760 | fontinfo.max_letter.reset(); |
|---|
| 761 | fontinfo.max_all_letter.reset(); |
|---|
| 762 | |
|---|
| 763 | aw_assert(AW_FONTINFO_CHAR_MIN < AW_FONTINFO_CHAR_MAX); |
|---|
| 764 | aw_assert(AW_FONTINFO_CHAR_ASCII_MIN < AW_FONTINFO_CHAR_ASCII_MAX); |
|---|
| 765 | aw_assert(AW_FONTINFO_CHAR_MIN <= AW_FONTINFO_CHAR_ASCII_MIN); |
|---|
| 766 | aw_assert(AW_FONTINFO_CHAR_ASCII_MAX <= AW_FONTINFO_CHAR_MAX); |
|---|
| 767 | |
|---|
| 768 | unsigned int i; |
|---|
| 769 | for (i = AW_FONTINFO_CHAR_MIN; i <= AW_FONTINFO_CHAR_MAX; i++) { |
|---|
| 770 | if (singlerow) {/* optimization */ |
|---|
| 771 | CI_GetCharInfo_1D(xfs, i, def, cs); |
|---|
| 772 | } else { |
|---|
| 773 | // cs = def; // X11R4 |
|---|
| 774 | CI_GetRowzeroCharInfo_2D(xfs, i, def, cs); |
|---|
| 775 | } |
|---|
| 776 | if (cs) { |
|---|
| 777 | ascent_of_chars[i] = cs->ascent; |
|---|
| 778 | descent_of_chars[i] = cs->descent; |
|---|
| 779 | width_of_chars[i] = cs->width; |
|---|
| 780 | |
|---|
| 781 | if (i >= AW_FONTINFO_CHAR_ASCII_MIN && i <= AW_FONTINFO_CHAR_ASCII_MAX) { |
|---|
| 782 | fontinfo.max_letter.notify_all(cs->ascent, cs->descent, cs->width); |
|---|
| 783 | } |
|---|
| 784 | fontinfo.max_all_letter.notify_all(cs->ascent, cs->descent, cs->width); |
|---|
| 785 | } |
|---|
| 786 | else { |
|---|
| 787 | width_of_chars[i] = 0; |
|---|
| 788 | descent_of_chars[i] = 0; |
|---|
| 789 | ascent_of_chars[i] = 0; |
|---|
| 790 | } |
|---|
| 791 | } |
|---|
| 792 | |
|---|
| 793 | fontinfo.max_letter.calc_height(); |
|---|
| 794 | fontinfo.max_all_letter.calc_height(); |
|---|
| 795 | |
|---|
| 796 | this->fontnr = font_nr; |
|---|
| 797 | this->fontsize = size; |
|---|
| 798 | } |
|---|
| 799 | |
|---|
| 800 | int AW_GC_Xm::get_available_fontsizes(AW_font font_nr, int *available_sizes) { |
|---|
| 801 | return ::get_available_fontsizes(common->display, font_nr, available_sizes); |
|---|
| 802 | } |
|---|