1151497Sru/* 2151497Sru * font.c 3151497Sru * 4151497Sru * map dvi fonts to X fonts 5151497Sru */ 6151497Sru 7151497Sru#include <X11/Xos.h> 8151497Sru#include <X11/IntrinsicP.h> 9151497Sru#include <X11/StringDefs.h> 10151497Sru#include <stdio.h> 11151497Sru#include <ctype.h> 12151497Sru#include <stdlib.h> 13151497Sru#include "DviP.h" 14151497Sru#include "XFontName.h" 15151497Sru 16151497Srustatic void DisposeFontSizes(DviWidget, DviFontSizeList *); 17151497Sruvoid DestroyFontMap(DviFontMap *); 18151497Sru 19151497Srustatic char * 20151497Srusavestr (const char *s) 21151497Sru{ 22151497Sru char *n; 23151497Sru 24151497Sru if (!s) 25151497Sru return 0; 26151497Sru n = XtMalloc (strlen (s) + 1); 27151497Sru if (n) 28151497Sru strcpy (n, s); 29151497Sru return n; 30151497Sru} 31151497Sru 32151497Srustatic DviFontList * 33151497SruLookupFontByPosition (DviWidget dw, int position) 34151497Sru{ 35151497Sru DviFontList *f; 36151497Sru 37151497Sru for (f = dw->dvi.fonts; f; f = f->next) 38151497Sru if (f->dvi_number == position) 39151497Sru break; 40151497Sru return f; 41151497Sru} 42151497Sru 43151497Sruint 44151497SruMaxFontPosition (DviWidget dw) 45151497Sru{ 46151497Sru DviFontList *f; 47151497Sru int n = -1; 48151497Sru 49151497Sru for (f = dw->dvi.fonts; f; f = f->next) 50151497Sru if (f->dvi_number > n) 51151497Sru n = f->dvi_number; 52151497Sru return n; 53151497Sru} 54151497Sru 55151497Srustatic DviFontSizeList * 56151497SruLookupFontSizeBySize (DviWidget dw, DviFontList *f, int size) 57151497Sru{ 58151497Sru DviFontSizeList *fs, *best = 0, *smallest = 0; 59151497Sru int bestsize = 0; 60151497Sru XFontName fontName; 61151497Sru unsigned int fontNameAttributes; 62151497Sru char fontNameString[2048]; 63151497Sru int decipointsize; 64151497Sru 65151497Sru if (f->scalable) { 66151497Sru decipointsize = (10*size)/dw->dvi.sizescale; 67151497Sru for (best = f->sizes; best; best = best->next) 68151497Sru if (best->size == decipointsize) 69151497Sru return best; 70151497Sru best = (DviFontSizeList *) XtMalloc(sizeof *best); 71151497Sru best->next = f->sizes; 72151497Sru best->size = decipointsize; 73151497Sru f->sizes = best; 74151497Sru XParseFontName (f->x_name, &fontName, &fontNameAttributes); 75151497Sru fontNameAttributes &= ~(FontNamePixelSize|FontNameAverageWidth); 76151497Sru fontNameAttributes |= FontNameResolutionX; 77151497Sru fontNameAttributes |= FontNameResolutionY; 78151497Sru fontNameAttributes |= FontNamePointSize; 79151497Sru fontName.ResolutionX = dw->dvi.display_resolution; 80151497Sru fontName.ResolutionY = dw->dvi.display_resolution; 81151497Sru fontName.PointSize = decipointsize; 82151497Sru XFormatFontName (&fontName, fontNameAttributes, fontNameString); 83151497Sru best->x_name = savestr (fontNameString); 84151497Sru best->doesnt_exist = 0; 85151497Sru best->font = 0; 86151497Sru return best; 87151497Sru } 88151497Sru for (fs = f->sizes; fs; fs=fs->next) { 89151497Sru if (dw->dvi.sizescale*fs->size <= 10*size 90151497Sru && fs->size >= bestsize) { 91151497Sru best = fs; 92151497Sru bestsize = fs->size; 93151497Sru } 94151497Sru if (smallest == 0 || fs->size < smallest->size) 95151497Sru smallest = fs; 96151497Sru } 97151497Sru return best ? best : smallest; 98151497Sru} 99151497Sru 100151497Srustatic char * 101151497SruSkipFontNameElement (char *n) 102151497Sru{ 103151497Sru while (*n != '-') 104151497Sru if (!*++n) 105151497Sru return 0; 106151497Sru return n+1; 107151497Sru} 108151497Sru 109151497Sru# define SizePosition 8 110151497Sru# define EncodingPosition 13 111151497Sru 112151497Srustatic int 113151497SruConvertFontNameToSize (char *n) 114151497Sru{ 115151497Sru int i, size; 116151497Sru 117151497Sru for (i = 0; i < SizePosition; i++) { 118151497Sru n = SkipFontNameElement (n); 119151497Sru if (!n) 120151497Sru return -1; 121151497Sru } 122151497Sru size = atoi (n); 123151497Sru return size; 124151497Sru} 125151497Sru 126151497Srustatic char * 127151497SruConvertFontNameToEncoding (char *n) 128151497Sru{ 129151497Sru int i; 130151497Sru for (i = 0; i < EncodingPosition; i++) { 131151497Sru n = SkipFontNameElement (n); 132151497Sru if (!n) 133151497Sru return 0; 134151497Sru } 135151497Sru return n; 136151497Sru} 137151497Sru 138151497SruDviFontSizeList * 139151497SruInstallFontSizes (DviWidget dw, const char *x_name, Boolean *scalablep) 140151497Sru{ 141151497Sru char fontNameString[2048]; 142151497Sru char **fonts; 143151497Sru int i, count; 144151497Sru int size; 145151497Sru DviFontSizeList *sizes, *new_size; 146151497Sru XFontName fontName; 147151497Sru unsigned int fontNameAttributes; 148151497Sru 149151497Sru *scalablep = FALSE; 150151497Sru if (!XParseFontName ((XFontNameString)x_name, &fontName, 151151497Sru &fontNameAttributes)) 152151497Sru return 0; 153151497Sru fontNameAttributes &= ~(FontNamePixelSize|FontNamePointSize 154151497Sru |FontNameAverageWidth); 155151497Sru fontNameAttributes |= FontNameResolutionX; 156151497Sru fontNameAttributes |= FontNameResolutionY; 157151497Sru fontName.ResolutionX = dw->dvi.display_resolution; 158151497Sru fontName.ResolutionY = dw->dvi.display_resolution; 159151497Sru XFormatFontName (&fontName, fontNameAttributes, fontNameString); 160151497Sru fonts = XListFonts (XtDisplay (dw), fontNameString, 10000000, &count); 161151497Sru sizes = 0; 162151497Sru for (i = 0; i < count; i++) { 163151497Sru size = ConvertFontNameToSize (fonts[i]); 164151497Sru if (size == 0) { 165151497Sru DisposeFontSizes (dw, sizes); 166151497Sru sizes = 0; 167151497Sru *scalablep = TRUE; 168151497Sru break; 169151497Sru } 170151497Sru if (size != -1) { 171151497Sru new_size = (DviFontSizeList *) XtMalloc (sizeof *new_size); 172151497Sru new_size->next = sizes; 173151497Sru new_size->size = size; 174151497Sru new_size->x_name = savestr (fonts[i]); 175151497Sru new_size->doesnt_exist = 0; 176151497Sru new_size->font = 0; 177151497Sru sizes = new_size; 178151497Sru } 179151497Sru } 180151497Sru XFreeFontNames (fonts); 181151497Sru return sizes; 182151497Sru} 183151497Sru 184151497Srustatic void 185151497SruDisposeFontSizes (DviWidget dw, DviFontSizeList *fs) 186151497Sru{ 187151497Sru DviFontSizeList *next; 188151497Sru 189151497Sru for (; fs; fs=next) { 190151497Sru next = fs->next; 191151497Sru if (fs->x_name) 192151497Sru XtFree (fs->x_name); 193151497Sru if (fs->font && fs->font != dw->dvi.default_font) { 194151497Sru XUnloadFont (XtDisplay (dw), fs->font->fid); 195151497Sru XFree ((char *)fs->font); 196151497Sru } 197151497Sru XtFree ((char *) fs); 198151497Sru } 199151497Sru} 200151497Sru 201151497Srustatic DviFontList * 202151497SruInstallFont (DviWidget dw, int position, 203151497Sru const char *dvi_name, const char *x_name) 204151497Sru{ 205151497Sru DviFontList *f; 206151497Sru char *encoding; 207151497Sru 208151497Sru if ((f = LookupFontByPosition (dw, position)) != NULL) { 209151497Sru /* 210151497Sru * ignore gratuitous font loading 211151497Sru */ 212151497Sru if (!strcmp (f->dvi_name, dvi_name) && 213151497Sru !strcmp (f->x_name, x_name)) 214151497Sru return f; 215151497Sru 216151497Sru DisposeFontSizes (dw, f->sizes); 217151497Sru if (f->dvi_name) 218151497Sru XtFree (f->dvi_name); 219151497Sru if (f->x_name) 220151497Sru XtFree (f->x_name); 221151497Sru f->device_font = 0; 222151497Sru } else { 223151497Sru f = (DviFontList *) XtMalloc (sizeof (*f)); 224151497Sru f->next = dw->dvi.fonts; 225151497Sru dw->dvi.fonts = f; 226151497Sru } 227151497Sru f->initialized = FALSE; 228151497Sru f->dvi_name = savestr (dvi_name); 229151497Sru f->device_font = device_find_font (dw->dvi.device, dvi_name); 230151497Sru f->x_name = savestr (x_name); 231151497Sru f->dvi_number = position; 232151497Sru f->sizes = 0; 233151497Sru f->scalable = FALSE; 234151497Sru if (f->x_name) { 235151497Sru encoding = ConvertFontNameToEncoding (f->x_name); 236151497Sru f->char_map = DviFindMap (encoding); 237151497Sru } else 238151497Sru f->char_map = 0; 239151497Sru /* 240151497Sru * force requery of fonts 241151497Sru */ 242151497Sru dw->dvi.font = 0; 243151497Sru dw->dvi.font_number = -1; 244151497Sru dw->dvi.cache.font = 0; 245151497Sru dw->dvi.cache.font_number = -1; 246151497Sru dw->dvi.device_font = 0; 247151497Sru dw->dvi.device_font_number = -1; 248151497Sru return f; 249151497Sru} 250151497Sru 251151497Sruvoid 252151497SruForgetFonts (DviWidget dw) 253151497Sru{ 254151497Sru DviFontList *f = dw->dvi.fonts; 255151497Sru 256151497Sru while (f) { 257151497Sru DviFontList *tem = f; 258151497Sru 259151497Sru if (f->sizes) 260151497Sru DisposeFontSizes (dw, f->sizes); 261151497Sru if (f->dvi_name) 262151497Sru XtFree (f->dvi_name); 263151497Sru if (f->x_name) 264151497Sru XtFree (f->x_name); 265151497Sru f = f->next; 266151497Sru XtFree ((char *) tem); 267151497Sru } 268151497Sru 269151497Sru /* 270151497Sru * force requery of fonts 271151497Sru */ 272151497Sru dw->dvi.font = 0; 273151497Sru dw->dvi.font_number = -1; 274151497Sru dw->dvi.cache.font = 0; 275151497Sru dw->dvi.cache.font_number = -1; 276151497Sru dw->dvi.device_font = 0; 277151497Sru dw->dvi.device_font_number = -1; 278151497Sru dw->dvi.fonts = 0; 279151497Sru} 280151497Sru 281151497Sru 282151497Srustatic char * 283151497SruMapDviNameToXName (DviWidget dw, const char *dvi_name) 284151497Sru{ 285151497Sru DviFontMap *fm; 286151497Sru 287151497Sru for (fm = dw->dvi.font_map; fm; fm=fm->next) 288151497Sru if (!strcmp (fm->dvi_name, dvi_name)) 289151497Sru return fm->x_name; 290151497Sru return 0; 291151497Sru} 292151497Sru 293151497Sru#if 0 294151497Srustatic char * 295151497SruMapXNameToDviName (DviWidget dw, const char *x_name) 296151497Sru{ 297151497Sru DviFontMap *fm; 298151497Sru 299151497Sru for (fm = dw->dvi.font_map; fm; fm=fm->next) 300151497Sru if (!strcmp (fm->x_name, x_name)) 301151497Sru return fm->dvi_name; 302151497Sru return 0; 303151497Sru} 304151497Sru#endif 305151497Sru 306151497Sruvoid 307151497SruParseFontMap (DviWidget dw) 308151497Sru{ 309151497Sru char dvi_name[1024]; 310151497Sru char x_name[2048]; 311151497Sru char *m, *s; 312151497Sru DviFontMap *fm, *new_map; 313151497Sru 314151497Sru if (dw->dvi.font_map) 315151497Sru DestroyFontMap (dw->dvi.font_map); 316151497Sru fm = 0; 317151497Sru m = dw->dvi.font_map_string; 318151497Sru while (*m) { 319151497Sru s = m; 320151497Sru while (*m && !isspace (*m)) 321151497Sru ++m; 322151497Sru strncpy (dvi_name, s, m-s); 323151497Sru dvi_name[m-s] = '\0'; 324151497Sru while (isspace (*m)) 325151497Sru ++m; 326151497Sru s = m; 327151497Sru while (*m && *m != '\n') 328151497Sru ++m; 329151497Sru strncpy (x_name, s, m-s); 330151497Sru x_name[m-s] = '\0'; 331151497Sru new_map = (DviFontMap *) XtMalloc (sizeof *new_map); 332151497Sru new_map->x_name = savestr (x_name); 333151497Sru new_map->dvi_name = savestr (dvi_name); 334151497Sru new_map->next = fm; 335151497Sru fm = new_map; 336151497Sru ++m; 337151497Sru } 338151497Sru dw->dvi.font_map = fm; 339151497Sru} 340151497Sru 341151497Sruvoid 342151497SruDestroyFontMap (DviFontMap *font_map) 343151497Sru{ 344151497Sru DviFontMap *next; 345151497Sru 346151497Sru for (; font_map; font_map = next) { 347151497Sru next = font_map->next; 348151497Sru if (font_map->x_name) 349151497Sru XtFree (font_map->x_name); 350151497Sru if (font_map->dvi_name) 351151497Sru XtFree (font_map->dvi_name); 352151497Sru XtFree ((char *) font_map); 353151497Sru } 354151497Sru} 355151497Sru 356151497Sru/* ARGSUSED */ 357151497Sru 358151497Sruvoid 359151497SruSetFontPosition (DviWidget dw, int position, 360151497Sru const char *dvi_name, const char *extra) 361151497Sru{ 362151497Sru char *x_name; 363151497Sru 364151497Sru x_name = MapDviNameToXName (dw, dvi_name); 365151497Sru if (x_name) 366151497Sru (void) InstallFont (dw, position, dvi_name, x_name); 367151497Sru 368151497Sru extra = extra; /* unused; suppress compiler warning */ 369151497Sru} 370151497Sru 371151497SruXFontStruct * 372151497SruQueryFont (DviWidget dw, int position, int size) 373151497Sru{ 374151497Sru DviFontList *f; 375151497Sru DviFontSizeList *fs; 376151497Sru 377151497Sru f = LookupFontByPosition (dw, position); 378151497Sru if (!f) 379151497Sru return dw->dvi.default_font; 380151497Sru if (!f->initialized) { 381151497Sru f->sizes = InstallFontSizes (dw, f->x_name, &f->scalable); 382151497Sru f->initialized = TRUE; 383151497Sru } 384151497Sru fs = LookupFontSizeBySize (dw, f, size); 385151497Sru if (!fs) 386151497Sru return dw->dvi.default_font; 387151497Sru if (!fs->font) { 388151497Sru if (fs->x_name) 389151497Sru fs->font = XLoadQueryFont (XtDisplay (dw), fs->x_name); 390151497Sru if (!fs->font) 391151497Sru fs->font = dw->dvi.default_font; 392151497Sru } 393151497Sru return fs->font; 394151497Sru} 395151497Sru 396151497SruDeviceFont * 397151497SruQueryDeviceFont (DviWidget dw, int position) 398151497Sru{ 399151497Sru DviFontList *f; 400151497Sru 401151497Sru f = LookupFontByPosition (dw, position); 402151497Sru if (!f) 403151497Sru return 0; 404151497Sru return f->device_font; 405151497Sru} 406151497Sru 407151497SruDviCharNameMap * 408151497SruQueryFontMap (DviWidget dw, int position) 409151497Sru{ 410151497Sru DviFontList *f; 411151497Sru 412151497Sru f = LookupFontByPosition (dw, position); 413151497Sru if (f) 414151497Sru return f->char_map; 415151497Sru else 416151497Sru return 0; 417151497Sru} 418151497Sru 419151497Sru#if 0 420151497SruLoadFont (DviWidget dw, int position, int size) 421151497Sru{ 422151497Sru XFontStruct *font; 423151497Sru 424151497Sru font = QueryFont (dw, position, size); 425151497Sru dw->dvi.font_number = position; 426151497Sru dw->dvi.font_size = size; 427151497Sru dw->dvi.font = font; 428151497Sru XSetFont (XtDisplay (dw), dw->dvi.normal_GC, font->fid); 429151497Sru return; 430151497Sru} 431151497Sru#endif 432151497Sru 433151497Sru/* 434151497SruLocal Variables: 435151497Sruc-indent-level: 8 436151497Sruc-continued-statement-offset: 8 437151497Sruc-brace-offset: -8 438151497Sruc-argdecl-indent: 8 439151497Sruc-label-offset: -8 440151497Sruc-tab-always-indent: nil 441151497SruEnd: 442151497Sru*/ 443