PageRenderTime 30ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/ATF2/control-software/epics-3.14.10/extensions/src/edm/lib/font_pkg.cc

http://atf2flightsim.googlecode.com/
C++ | 2293 lines | 1653 code | 555 blank | 85 comment | 343 complexity | 70cdeabea5133d278693481788ad5559 MD5 | raw file
Possible License(s): BSD-2-Clause, LGPL-2.0, IPL-1.0, BSD-3-Clause
  1. // edm - extensible display manager
  2. // Copyright (C) 1999 John W. Sinclair
  3. // This program is free software; you can redistribute it and/or modify
  4. // it under the terms of the GNU General Public License as published by
  5. // the Free Software Foundation; either version 2 of the License, or
  6. // (at your option) any later version.
  7. // This program is distributed in the hope that it will be useful,
  8. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. // GNU General Public License for more details.
  11. // You should have received a copy of the GNU General Public License
  12. // along with this program; if not, write to the Free Software
  13. // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  14. // font model code
  15. //
  16. #include "font_pkg.h"
  17. #include "remFileOpen.h"
  18. #include "thread.h"
  19. static int debugMode ( void ) {
  20. int val;
  21. char *envPtr;
  22. envPtr = getenv( "EDMDEBUGMODE" );
  23. if ( envPtr ) {
  24. val = atol(envPtr);
  25. if ( !val ) val = 1; // if value is non-numeric make it 1
  26. return val;
  27. }
  28. else {
  29. return 0;
  30. }
  31. }
  32. static void fixFontSize (
  33. char *spec
  34. ) {
  35. // On non-english speaking systems, the format of floating points
  36. // rendered by "sprintf" may use a ',' for the decimal separator,
  37. // instead of a '.'. If so, change each ',' to '.'.
  38. int i;
  39. for ( i=0; i<(int) strlen(spec); i++ ) {
  40. if ( spec[i] == ',' ) spec[i] = '.';
  41. }
  42. }
  43. static int compare_nodes (
  44. void *node1,
  45. void *node2
  46. ) {
  47. fontNameListPtr p1, p2;
  48. p1 = (fontNameListPtr) node1;
  49. p2 = (fontNameListPtr) node2;
  50. return strcmp( p1->name, p2->name );
  51. }
  52. static int compare_key (
  53. void *key,
  54. void *node
  55. ) {
  56. fontNameListPtr p;
  57. char *name;
  58. p = (fontNameListPtr) node;
  59. name = (char *) key;
  60. return strcmp( name, p->name );
  61. }
  62. static int copy_nodes (
  63. void *node1,
  64. void *node2
  65. ) {
  66. fontNameListPtr p1, p2;
  67. p1 = (fontNameListPtr) node1;
  68. p2 = (fontNameListPtr) node2;
  69. *p1 = *p2;
  70. return 1;
  71. }
  72. fontInfoClass::fontInfoClass ( void ) { // constructor
  73. int stat;
  74. stat = thread_init();
  75. stat = avl_init_tree( compare_nodes,
  76. compare_key, copy_nodes, &(this->fontNameListH) );
  77. if ( !( stat & 1 ) ) this->fontNameListH = (AVL_HANDLE) NULL;
  78. // create sentinel node
  79. familyHead = new familyListType;
  80. familyTail = familyHead;
  81. familyTail->flink = NULL;
  82. fontListEmpty = 1;
  83. requireExactMatch = 0;
  84. strcpy( mediumString, "medium" );
  85. strcpy( boldString, "bold" );
  86. strcpy( regularString, "r" );
  87. strcpy( italicString, "i" );
  88. lineNum = lastNonCommentLine = 1;
  89. }
  90. fontInfoClass::~fontInfoClass ( void ) { // destructor
  91. int stat;
  92. fontNameListPtr cur;
  93. familyListPtr curFamily, nextFamily;
  94. sizeListPtr curSize, nextSize;
  95. stat = avl_get_first( this->fontNameListH, (void **) &cur );
  96. if ( !( stat & 1 ) ) {
  97. cur = NULL;
  98. }
  99. while ( cur ) {
  100. stat = avl_delete_node( this->fontNameListH, (void **) &cur );
  101. if ( stat & 1 ) {
  102. if ( cur->fontLoaded ) {
  103. if ( cur->fontStruct ) {
  104. XFreeFont( this->display, cur->fontStruct );
  105. cur->fontLoaded = 0;
  106. }
  107. }
  108. if ( cur->name ) {
  109. delete[] cur->name;
  110. cur->name = NULL;
  111. }
  112. if ( cur->fullName ) {
  113. delete[] cur->fullName;
  114. cur->fullName = NULL;
  115. }
  116. if ( cur->family ) {
  117. delete[] cur->family;
  118. cur->family = NULL;
  119. }
  120. delete cur;
  121. }
  122. stat = avl_get_first( this->fontNameListH, (void **) &cur );
  123. if ( !( stat & 1 ) ) {
  124. cur = NULL;
  125. }
  126. }
  127. stat = avl_destroy( this->fontNameListH );
  128. curFamily = familyHead->flink;
  129. while ( curFamily ) {
  130. nextFamily = curFamily->flink;
  131. curSize = curFamily->sizeHead->flink;
  132. while ( curSize ) {
  133. nextSize = curSize->flink;
  134. delete curSize;
  135. curSize = nextSize;
  136. }
  137. delete curFamily->sizeHead;
  138. delete[] curFamily->name;
  139. delete curFamily;
  140. curFamily = nextFamily;
  141. }
  142. delete familyHead;
  143. }
  144. char *fontInfoClass::getStrFromFile (
  145. char *str,
  146. int maxLen,
  147. FILE *f
  148. ) {
  149. char *ctx, *ptr, *tk, stackBuf[255+1];
  150. char *buf;
  151. int tryAgain, bufOnHeap;
  152. // ignore blank lines and comment lines
  153. if ( maxLen < 1 ) return (char *) NULL;
  154. if ( maxLen > 255 ) {
  155. buf = new char[maxLen+1];
  156. bufOnHeap = 1;
  157. }
  158. else {
  159. buf = stackBuf;
  160. bufOnHeap = 0;
  161. }
  162. do {
  163. tryAgain = 0;
  164. ptr = fgets( str, maxLen, f );
  165. if ( !ptr ) {
  166. strcpy( str, "" );
  167. if ( bufOnHeap ) delete [] buf;
  168. return (char *) NULL;
  169. }
  170. lineNum++;
  171. strcpy( buf, str );
  172. ctx = NULL;
  173. tk = strtok_r( buf, "\n", &ctx );
  174. if ( tk ) {
  175. if ( tk[0] == '#' ) tryAgain = 1;
  176. }
  177. else {
  178. tryAgain = 1;
  179. }
  180. } while ( tryAgain );
  181. lastNonCommentLine = lineNum;
  182. if ( bufOnHeap ) delete [] buf;
  183. return str;
  184. }
  185. int fontInfoClass::parseFontSpec (
  186. char *fontSpec,
  187. char *foundary,
  188. char *family,
  189. char *weight,
  190. char *slant,
  191. char *pixelSize ) {
  192. static const int GETTING_DASH = 1;
  193. static const int GETTING_STRING = 2;
  194. static const int GETTING_LAST_STRING = 3;
  195. static const int STORE_VALUE = 4;
  196. static const int DONE = -1;
  197. int l, ii, iii, i = 0, first = 0, last = 0, n = 0;
  198. int state = GETTING_DASH;
  199. char value[14][63+1];
  200. l = strlen( fontSpec );
  201. while ( state != DONE ) {
  202. //fprintf( stderr, "s: %-d, n=%-d, i=%-d\n", state, n, i );
  203. switch ( state ) {
  204. case GETTING_DASH:
  205. if ( fontSpec[i] == '-' ) {
  206. i++;
  207. if ( i >= l ) return FONTINFO_BADSPEC;
  208. first = i;
  209. state = GETTING_STRING;
  210. }
  211. else if ( fontSpec[i] == '\t' ) {
  212. return FONTINFO_BADSPEC;
  213. }
  214. else {
  215. return FONTINFO_BADSPEC;
  216. }
  217. break;
  218. case GETTING_STRING:
  219. if ( fontSpec[i] == '-' ) {
  220. last = i - 1;
  221. state = STORE_VALUE;
  222. }
  223. else if ( fontSpec[i] == '\t' ) {
  224. return FONTINFO_BADSPEC;
  225. }
  226. i++;
  227. if ( i >= l ) return FONTINFO_BADSPEC;
  228. break;
  229. case GETTING_LAST_STRING:
  230. if ( fontSpec[i] == '\t' ) {
  231. last = i - 1;
  232. state = STORE_VALUE;
  233. }
  234. i++;
  235. if ( i >= l ) {
  236. last = i - 1;
  237. state = STORE_VALUE;
  238. }
  239. break;
  240. case STORE_VALUE:
  241. if ( last >= first ) {
  242. for ( ii=first, iii=0; ii<=last; ii++, iii++ ) {
  243. value[n][iii] = fontSpec[ii];
  244. }
  245. value[n][iii] = 0;
  246. //fprintf( stderr, "value[%-d] = [%s]\n", n, value[n] );
  247. }
  248. else {
  249. strcpy( value[n], "" );
  250. //fprintf( stderr, "value[%-d] = NULL\n", n );
  251. }
  252. first = i;
  253. n++;
  254. if ( n < 13 ) {
  255. state = GETTING_STRING;
  256. }
  257. else if ( n == 13 ) {
  258. state = GETTING_LAST_STRING;
  259. }
  260. else {
  261. state = DONE;
  262. }
  263. break;
  264. }
  265. }
  266. strncpy( foundary, value[0], 63 );
  267. foundary[63] = 0;
  268. strncpy( family, value[1], 63 );
  269. family[63] = 0;
  270. strncpy( weight, value[2], 63 );
  271. weight[63] = 0;
  272. strncpy( slant, value[3], 63 );
  273. slant[63] = 0;
  274. strncpy( pixelSize, value[7], 63 );
  275. pixelSize[63] = 0;
  276. return FONTINFO_SUCCESS;
  277. }
  278. static char **findBestFont(
  279. Display *d,
  280. char *fontSpec,
  281. int *n ) {
  282. char **list;
  283. char *tk, *ctx, spec[127+1], rest[127+1], foundry[63+1], family[63+1],
  284. weight[31+1], slant[31+1], ftype[31+1], size[31+1], newFont[127+1];
  285. strncpy( spec, fontSpec, 127 );
  286. spec[127] = 0;
  287. ctx = NULL;
  288. tk = strtok_r( spec, "-", &ctx );
  289. if ( !tk ) goto err_return;
  290. strncpy( foundry, tk, 63 );
  291. foundry[63] = 0;
  292. tk = strtok_r( NULL, "-", &ctx );
  293. if ( !tk ) goto err_return;
  294. strncpy( family, tk, 63 );
  295. family[63] = 0;
  296. tk = strtok_r( NULL, "\n", &ctx );
  297. if ( !tk ) goto err_return;
  298. strncpy( rest, tk, 127 );
  299. rest[127] = 0;
  300. strncpy( newFont, "-", 127 );
  301. Strncat( newFont, foundry, 127 );
  302. Strncat( newFont, "-", 127 );
  303. Strncat( newFont, "*-", 127 );
  304. Strncat( newFont, rest, 127 );
  305. // fprintf( stderr, "new font is %s\n", newFont );
  306. list = XListFonts( d, newFont, 1, n );
  307. if ( *n == 1 ) return list;
  308. strncpy( spec, rest, 127 );
  309. spec[127] = 0;
  310. ctx = NULL;
  311. tk = strtok_r( spec, "-", &ctx );
  312. if ( !tk ) goto err_return;
  313. strncpy( weight, tk, 31 );
  314. weight[31] = 0;
  315. tk = strtok_r( NULL, "\n", &ctx );
  316. if ( !tk ) goto err_return;
  317. strncpy( rest, tk, 127 );
  318. rest[127] = 0;
  319. strncpy( newFont, "-", 127 );
  320. Strncat( newFont, foundry, 127 );
  321. Strncat( newFont, "-", 127 );
  322. Strncat( newFont, "*-", 127 );
  323. Strncat( newFont, "*-", 127 );
  324. Strncat( newFont, rest, 127 );
  325. // fprintf( stderr, "new font is %s\n", newFont );
  326. list = XListFonts( d, newFont, 1, n );
  327. if ( *n == 1 ) return list;
  328. strncpy( spec, rest, 127 );
  329. spec[127] = 0;
  330. ctx = NULL;
  331. tk = strtok_r( spec, "-", &ctx );
  332. if ( !tk ) goto err_return;
  333. strncpy( slant, tk, 31 );
  334. slant[31] = 0;
  335. tk = strtok_r( NULL, "\n", &ctx );
  336. if ( !tk ) goto err_return;
  337. strncpy( rest, tk, 127 );
  338. rest[127] = 0;
  339. strncpy( newFont, "-", 127 );
  340. Strncat( newFont, foundry, 127 );
  341. Strncat( newFont, "-", 127 );
  342. Strncat( newFont, "*-", 127 );
  343. Strncat( newFont, "*-", 127 );
  344. Strncat( newFont, "*-", 127 );
  345. Strncat( newFont, rest, 127 );
  346. // fprintf( stderr, "new font is %s\n", newFont );
  347. list = XListFonts( d, newFont, 1, n );
  348. if ( *n == 1 ) return list;
  349. strncpy( spec, rest, 127 );
  350. spec[127] = 0;
  351. ctx = NULL;
  352. tk = strtok_r( spec, "-", &ctx );
  353. if ( !tk ) goto err_return;
  354. strncpy( ftype, tk, 31 );
  355. ftype[31] = 0;
  356. tk = strtok_r( NULL, "-", &ctx );
  357. if ( !tk ) goto err_return;
  358. strncpy( size, tk, 31 );
  359. size[31] = 0;
  360. tk = strtok_r( NULL, "\n", &ctx );
  361. if ( !tk ) goto err_return;
  362. strncpy( rest, tk, 127 );
  363. rest[127] = 0;
  364. strncpy( newFont, "-", 127 );
  365. Strncat( newFont, foundry, 127 );
  366. Strncat( newFont, "-", 127 );
  367. Strncat( newFont, "*-", 127 );
  368. Strncat( newFont, "*-", 127 );
  369. Strncat( newFont, "*-", 127 );
  370. Strncat( newFont, ftype, 127 );
  371. Strncat( newFont, "--", 127 );
  372. Strncat( newFont, size, 127 );
  373. Strncat( newFont, "-", 127 );
  374. Strncat( newFont, "*-*-*-*-*-*-*", 127 );
  375. // fprintf( stderr, "new font is %s\n", newFont );
  376. list = XListFonts( d, newFont, 1, n );
  377. if ( *n == 1 ) return list;
  378. strncpy( newFont, "-", 127 );
  379. Strncat( newFont, foundry, 127 );
  380. Strncat( newFont, "-*-*-*-*--*-*-*-*-*-*-*-*", 127 );
  381. // fprintf( stderr, "new font is %s\n", newFont );
  382. list = XListFonts( d, newFont, 1, n );
  383. if ( *n == 1 ) return list;
  384. strncpy( newFont, "-*-*-*-*-*--*-*-*-*-*-*-*-*", 127 );
  385. // fprintf( stderr, "new font is %s\n", newFont );
  386. list = XListFonts( d, newFont, 1, n );
  387. if ( *n == 1 ) return list;
  388. err_return:
  389. *n = 0;
  390. return (char **) NULL;
  391. }
  392. int fontInfoClass::resolveFont (
  393. char *fontSpec,
  394. fontNameListPtr ptr ) {
  395. int n, isize, isScalable;
  396. float fsize;
  397. char **list;
  398. char *tk, *ctx, spec[127+1], name[127+1], family[63+1], weight[31+1],
  399. slant[31+1], size[31+1];
  400. ptr->fontLoaded = 0;
  401. list = XListFonts( this->display, fontSpec, 1, &n );
  402. if ( n == 0 ) {
  403. list = findBestFont( this->display, fontSpec, &n );
  404. if ( n == 0 ) {
  405. return FONTINFO_NO_FONT;
  406. }
  407. }
  408. strncpy( spec, list[0], 127 );
  409. if ( debugMode() == 1000 ) fprintf( stderr, "Font Spec: [%s]\n", spec );
  410. ctx = NULL;
  411. tk = strtok_r( spec, "-", &ctx );
  412. tk = strtok_r( NULL, "-", &ctx );
  413. strncpy( family, tk, 63 );
  414. tk = strtok_r( NULL, "-", &ctx );
  415. strncpy( weight, tk, 31 );
  416. tk = strtok_r( NULL, "-", &ctx );
  417. if ( strcmp( tk, "r" ) == 0 )
  418. strncpy( slant, "r", 31 );
  419. else
  420. strncpy( slant, "i", 31 );
  421. tk = strtok_r( NULL, "-", &ctx );
  422. tk = strtok_r( NULL, "-", &ctx );
  423. tk = strtok_r( NULL, "-", &ctx );
  424. strncpy( size, tk, 31 );
  425. if ( strcmp( size, "0" ) == 0 )
  426. isScalable = 1;
  427. else
  428. isScalable = 0;
  429. isize = atol( size );
  430. fsize = atof( size );
  431. fsize /= 10;
  432. ptr->size = isize;
  433. ptr->fsize = fsize;
  434. sprintf( size, "%-.1f", fsize );
  435. fixFontSize( size );
  436. strncpy( name, family, 127 );
  437. Strncat( name, "-", 127 );
  438. Strncat( name, weight, 127 );
  439. Strncat( name, "-", 127 );
  440. Strncat( name, slant, 127 );
  441. Strncat( name, "-", 127 );
  442. Strncat( name, size, 127 );
  443. ptr->isScalable = (char) isScalable;
  444. ptr->fullName = new char[strlen(list[0])+1];
  445. strcpy( ptr->fullName, list[0] );
  446. ptr->name = new char[strlen(name)+1];
  447. strcpy( ptr->name, name );
  448. ptr->family = new char[strlen(family)+1];
  449. strcpy( ptr->family, family );
  450. ptr->weight = weight[0];
  451. ptr->slant = slant[0];
  452. XFreeFontNames( list );
  453. return FONTINFO_SUCCESS;
  454. }
  455. void fontInfoClass::setMediumString (
  456. char *str
  457. ) {
  458. strncpy( mediumString, str, 63 );
  459. mediumString[63] = 0;
  460. }
  461. void fontInfoClass::setBoldString (
  462. char *str
  463. ) {
  464. strncpy( boldString, str, 63 );
  465. boldString[63] = 0;
  466. }
  467. void fontInfoClass::setRegularString (
  468. char *str
  469. ) {
  470. strncpy( regularString, str, 63 );
  471. regularString[63] = 0;
  472. }
  473. void fontInfoClass::setItalicString (
  474. char *str
  475. ) {
  476. strncpy( italicString, str, 63 );
  477. italicString[63] = 0;
  478. }
  479. int fontInfoClass::resolveFont (
  480. char *fontSpec,
  481. char *userFontFamilyName,
  482. fontNameListPtr ptr ) {
  483. int n, isize, isScalable, stat;
  484. float fsize;
  485. char **list;
  486. char spec[127+1], name[127+1], foundary[63+1], family[63+1], weight[63+1],
  487. slant[63+1], size[63+1];
  488. ptr->fontLoaded = 0;
  489. list = XListFonts( this->display, fontSpec, 1, &n );
  490. if ( n == 0 ) {
  491. if ( requireExactMatch ) {
  492. fprintf( stderr, fontInfoClass_str8, fontSpec );
  493. fprintf( stderr, fontInfoClass_str9, lastNonCommentLine );
  494. return FONTINFO_NO_FONT;
  495. }
  496. else {
  497. list = findBestFont( this->display, fontSpec, &n );
  498. if ( n == 0 ) {
  499. fprintf( stderr, fontInfoClass_str8, fontSpec );
  500. fprintf( stderr, fontInfoClass_str9, lastNonCommentLine );
  501. return FONTINFO_NO_FONT;
  502. }
  503. }
  504. }
  505. strncpy( spec, list[0], 127 );
  506. if ( debugMode() == 1000 ) fprintf( stderr, "Font Spec: [%s]\n", spec );
  507. stat = parseFontSpec( spec, foundary, family, weight, slant, size );
  508. if ( strcmp( weight, mediumString ) == 0 ) {
  509. strcpy( weight, "medium" );
  510. }
  511. else if ( strcmp( weight, boldString ) == 0 ) {
  512. strcpy( weight, "bold" );
  513. }
  514. else {
  515. strcpy( weight, "medium" );
  516. }
  517. if ( strcmp( slant, regularString ) == 0 ) {
  518. strcpy( slant, "r" );
  519. }
  520. else if ( strcmp( slant, italicString ) == 0 ) {
  521. strcpy( slant, "i" );
  522. }
  523. else {
  524. strcpy( slant, "r" );
  525. }
  526. if ( strcmp( size, "0" ) == 0 )
  527. isScalable = 1;
  528. else
  529. isScalable = 0;
  530. isize = atol( size );
  531. fsize = atof( size );
  532. fsize /= 10;
  533. ptr->size = isize;
  534. ptr->fsize = fsize;
  535. sprintf( size, "%-.1f", fsize );
  536. fixFontSize( size );
  537. strncpy( name, userFontFamilyName, 127 );
  538. Strncat( name, "-", 127 );
  539. Strncat( name, weight, 127 );
  540. Strncat( name, "-", 127 );
  541. Strncat( name, slant, 127 );
  542. Strncat( name, "-", 127 );
  543. Strncat( name, size, 127 );
  544. //fprintf( stderr, "name=[%s]\n", name );
  545. ptr->isScalable = (char) isScalable;
  546. ptr->fullName = new char[strlen(list[0])+1];
  547. strcpy( ptr->fullName, list[0] );
  548. ptr->name = new char[strlen(name)+1];
  549. strcpy( ptr->name, name );
  550. ptr->family = new char[strlen(userFontFamilyName)+1];
  551. strcpy( ptr->family, userFontFamilyName );
  552. ptr->weight = weight[0];
  553. ptr->slant = slant[0];
  554. XFreeFontNames( list );
  555. return FONTINFO_SUCCESS;
  556. }
  557. int fontInfoClass::resolveOneFont (
  558. char *fontSpec,
  559. fontNameListPtr ptr ) {
  560. int n, isize, isScalable;
  561. float fsize;
  562. char **list;
  563. char *tk, *ctx, spec[127+1], name[127+1], family[63+1], weight[31+1],
  564. slant[31+1], size[31+1];
  565. ptr->fontLoaded = 0;
  566. list = XListFonts( this->display, fontSpec, 1, &n );
  567. if ( n == 0 ) {
  568. return FONTINFO_NO_FONT;
  569. }
  570. strncpy( spec, list[0], 127 );
  571. // fprintf( stderr, "Spec is [%s]\n", spec );
  572. ctx = NULL;
  573. tk = strtok_r( spec, "-", &ctx );
  574. tk = strtok_r( NULL, "-", &ctx );
  575. strncpy( family, tk, 63 );
  576. tk = strtok_r( NULL, "-", &ctx );
  577. strncpy( weight, tk, 31 );
  578. tk = strtok_r( NULL, "-", &ctx );
  579. if ( strcmp( tk, "r" ) == 0 )
  580. strncpy( slant, "r", 31 );
  581. else
  582. strncpy( slant, "i", 31 );
  583. tk = strtok_r( NULL, "-", &ctx );
  584. tk = strtok_r( NULL, "-", &ctx );
  585. tk = strtok_r( NULL, "-", &ctx );
  586. strncpy( size, tk, 31 );
  587. if ( strcmp( size, "0" ) == 0 )
  588. isScalable = 1;
  589. else
  590. isScalable = 0;
  591. isize = atol( size );
  592. fsize = atof( size );
  593. fsize /= 10;
  594. ptr->size = isize;
  595. ptr->fsize = fsize;
  596. sprintf( size, "%-.1f", fsize );
  597. fixFontSize( size );
  598. strncpy( name, family, 127 );
  599. Strncat( name, "-", 127 );
  600. Strncat( name, weight, 127 );
  601. Strncat( name, "-", 127 );
  602. Strncat( name, slant, 127 );
  603. Strncat( name, "-", 127 );
  604. Strncat( name, size, 127 );
  605. ptr->isScalable = (char) isScalable;
  606. ptr->fullName = new char[strlen(list[0])+1];
  607. strcpy( ptr->fullName, list[0] );
  608. ptr->name = new char[strlen(name)+1];
  609. strcpy( ptr->name, name );
  610. ptr->family = new char[strlen(family)+1];
  611. strcpy( ptr->family, family );
  612. ptr->weight = weight[0];
  613. ptr->slant = slant[0];
  614. XFreeFontNames( list );
  615. return FONTINFO_SUCCESS;
  616. }
  617. int fontInfoClass::appendSizeMenu(
  618. char *family,
  619. int size,
  620. float fsize )
  621. {
  622. familyListPtr curFamily;
  623. sizeListPtr curSize;
  624. curFamily = familyHead->flink;
  625. while ( curFamily ) {
  626. if ( strcmp( curFamily->name, family ) == 0 ) {
  627. curSize = curFamily->sizeHead->flink;
  628. while ( curSize ) {
  629. if ( curSize->fsize == fsize ) return FONTINFO_SUCCESS;
  630. curSize = curSize->flink;
  631. }
  632. // append size to list
  633. curSize = new sizeListType;
  634. if ( !curSize ) return FONTINFO_NO_MEM;
  635. curSize->size = size;
  636. curSize->fsize = fsize;
  637. curFamily->sizeTail->flink = curSize;
  638. curFamily->sizeTail = curSize;
  639. curFamily->sizeTail->flink = NULL;
  640. return FONTINFO_SUCCESS;
  641. }
  642. curFamily = curFamily->flink;
  643. }
  644. // new family, append to list
  645. curFamily = new familyListType;
  646. if ( !curFamily ) return FONTINFO_NO_MEM;
  647. curFamily->name = new char[strlen(family)+1];
  648. if ( !curFamily->name ) return FONTINFO_NO_MEM;
  649. strcpy( curFamily->name, family );
  650. curFamily->sizeHead = new sizeListType;
  651. if ( !curFamily->sizeHead ) return FONTINFO_NO_MEM;
  652. curFamily->sizeTail = curFamily->sizeHead;
  653. curFamily->sizeTail->flink = NULL;
  654. familyTail->flink = curFamily;
  655. familyTail = curFamily;
  656. familyTail->flink = NULL;
  657. // append size to new list
  658. curSize = new sizeListType;
  659. if ( !curSize ) return FONTINFO_NO_MEM;
  660. curSize->size = size;
  661. curSize->fsize = fsize;
  662. curFamily->sizeTail->flink = curSize;
  663. curFamily->sizeTail = curSize;
  664. curFamily->sizeTail->flink = NULL;
  665. return FONTINFO_SUCCESS;
  666. }
  667. int fontInfoClass::checkSingleFontSpecGeneric (
  668. XtAppContext app,
  669. Display *d,
  670. char *userFontFamilyName,
  671. char *line,
  672. int checkBestFont,
  673. int major,
  674. int minor,
  675. int release )
  676. {
  677. char buf[255+1], t1[255+1], t2[255+1], t3[255+1], t4[255+1],
  678. t5[255+1], t6[255+1], t7[255+1], mod[4][255+1], fontSpec[255+1],
  679. *tk1, *tk2, *ctx1, *ctx2;
  680. int i, ii, iii, n, pointSize[200], numSizes;
  681. int preload;
  682. char **list;
  683. strncpy( buf, line, 255 );
  684. ctx1 = NULL;
  685. tk1 = strtok_r( buf, "\t\n()", &ctx1 );
  686. if ( tk1 ) {
  687. strcpy( t1, tk1 );
  688. }
  689. else {
  690. fprintf( stderr, fontInfoClass_str5, lastNonCommentLine );
  691. return FONTINFO_SYNTAX;
  692. }
  693. tk1 = strtok_r( NULL, "\t\n()", &ctx1 );
  694. if ( tk1 ) {
  695. strcpy( t2, tk1 );
  696. }
  697. else {
  698. fprintf( stderr, fontInfoClass_str5, lastNonCommentLine );
  699. return FONTINFO_SYNTAX;
  700. }
  701. // get bold and medium indicators
  702. ctx2 = NULL;
  703. tk2 = strtok_r( t2, ",", &ctx2 );
  704. if ( tk2 ) {
  705. strcpy( mod[0], tk2 );
  706. }
  707. else {
  708. fprintf( stderr, fontInfoClass_str5, lastNonCommentLine );
  709. return FONTINFO_SYNTAX;
  710. }
  711. tk2 = strtok_r( NULL, ",", &ctx2 );
  712. if ( tk2 ) {
  713. strcpy( mod[1], tk2 );
  714. }
  715. else {
  716. fprintf( stderr, fontInfoClass_str5, lastNonCommentLine );
  717. return FONTINFO_SYNTAX;
  718. }
  719. tk1 = strtok_r( NULL, "\t\n()", &ctx1 );
  720. if ( tk1 ) {
  721. strcpy( t3, tk1 );
  722. }
  723. else {
  724. fprintf( stderr, fontInfoClass_str5, lastNonCommentLine );
  725. return FONTINFO_SYNTAX;
  726. }
  727. tk1 = strtok_r( NULL, "\t\n()", &ctx1 );
  728. if ( tk1 ) {
  729. strcpy( t4, tk1 );
  730. }
  731. else {
  732. fprintf( stderr, fontInfoClass_str5, lastNonCommentLine );
  733. return FONTINFO_SYNTAX;
  734. }
  735. // get italic and regular indicators
  736. ctx2 = NULL;
  737. tk2 = strtok_r( t4, ",", &ctx2 );
  738. if ( tk2 ) {
  739. strcpy( mod[2], tk2 );
  740. }
  741. else {
  742. fprintf( stderr, fontInfoClass_str5, lastNonCommentLine );
  743. return FONTINFO_SYNTAX;
  744. }
  745. tk2 = strtok_r( NULL, ",", &ctx2 );
  746. if ( tk2 ) {
  747. strcpy( mod[3], tk2 );
  748. }
  749. else {
  750. fprintf( stderr, fontInfoClass_str5, lastNonCommentLine );
  751. return FONTINFO_SYNTAX;
  752. }
  753. tk1 = strtok_r( NULL, "\t\n()", &ctx1 );
  754. if ( tk1 ) {
  755. strcpy( t5, tk1 );
  756. }
  757. else {
  758. fprintf( stderr, fontInfoClass_str5, lastNonCommentLine );
  759. return FONTINFO_SYNTAX;
  760. }
  761. tk1 = strtok_r( NULL, "\t\n()", &ctx1 );
  762. if ( tk1 ) {
  763. strcpy( t6, tk1 );
  764. }
  765. else {
  766. fprintf( stderr, fontInfoClass_str5, lastNonCommentLine );
  767. return FONTINFO_SYNTAX;
  768. }
  769. // get point sizes
  770. numSizes = 0;
  771. ctx2 = NULL;
  772. tk2 = strtok_r( t6, ",", &ctx2 );
  773. if ( tk2 ) {
  774. pointSize[numSizes] = atol( tk2 );
  775. numSizes++;
  776. if ( numSizes >= 200 ) {
  777. fprintf( stderr, fontInfoClass_str7, lastNonCommentLine );
  778. return FONTINFO_TOOMANYSIZES;
  779. }
  780. }
  781. else {
  782. fprintf( stderr, fontInfoClass_str5, lastNonCommentLine );
  783. return FONTINFO_SYNTAX;
  784. }
  785. do {
  786. tk2 = strtok_r( NULL, ",", &ctx2 );
  787. if ( tk2 ) {
  788. pointSize[numSizes] = atol( tk2 );
  789. numSizes++;
  790. if ( numSizes >= 200 ) {
  791. fprintf( stderr, fontInfoClass_str7, lastNonCommentLine );
  792. return FONTINFO_TOOMANYSIZES;
  793. }
  794. }
  795. } while ( tk2 );
  796. tk1 = strtok_r( NULL, "\t\n()", &ctx1 );
  797. if ( tk1 ) {
  798. strcpy( t7, tk1 );
  799. }
  800. else {
  801. fprintf( stderr, fontInfoClass_str5, lastNonCommentLine );
  802. return FONTINFO_SYNTAX;
  803. }
  804. preload = 0;
  805. requireExactMatch = 0;
  806. tk1 = strtok_r( NULL, "\t\n", &ctx1 );
  807. if ( tk1 ) {
  808. if ( strcmp( tk1, "preload" ) == 0 ) {
  809. preload = 1;
  810. }
  811. else if ( strcmp( tk1, "exact" ) == 0 ) {
  812. requireExactMatch = 1;
  813. }
  814. }
  815. tk1 = strtok_r( NULL, "\t\n", &ctx1 );
  816. if ( tk1 ) {
  817. if ( strcmp( tk1, "preload" ) == 0 ) {
  818. preload = 1;
  819. }
  820. else if ( strcmp( tk1, "exact" ) == 0 ) {
  821. requireExactMatch = 1;
  822. }
  823. }
  824. //fprintf( stderr, "t1 = [%s]\n", t1 );
  825. //fprintf( stderr, " mod[0] = [%s]\n", mod[0] );
  826. //fprintf( stderr, " mod[1] = [%s]\n", mod[1] );
  827. //fprintf( stderr, "t3 = [%s]\n", t3 );
  828. //fprintf( stderr, " mod[2] = [%s]\n", mod[2] );
  829. //fprintf( stderr, " mod[3] = [%s]\n", mod[3] );
  830. //fprintf( stderr, "t5 = [%s]\n", t5 );
  831. //for ( i=0; i<numSizes; i++ ) {
  832. // fprintf( stderr, " size[%-d] = %-d\n", i, pointSize[i] );
  833. //}
  834. //fprintf( stderr, "t7 = [%s]\n", t7 );
  835. // Build fontspec
  836. for ( i=0; i<2; i++ ) {
  837. for ( ii=2; ii<4; ii++ ) {
  838. for ( iii=0; iii<numSizes; iii++ ) {
  839. sprintf( fontSpec, "%s%s%s%s%s%-d%s", t1, mod[i], t3, mod[ii],
  840. t5, pointSize[iii], t7 );
  841. list = XListFonts( display, fontSpec, 1, &n );
  842. if ( n == 0 ) {
  843. if ( checkBestFont && !requireExactMatch ) {
  844. list = findBestFont( this->display, fontSpec, &n );
  845. if ( n == 0 ) {
  846. fprintf( stderr, fontInfoClass_str8, fontSpec );
  847. fprintf( stderr, fontInfoClass_str9, lastNonCommentLine );
  848. return FONTINFO_NO_FONT;
  849. }
  850. }
  851. else {
  852. return FONTINFO_NO_FONT;
  853. }
  854. }
  855. XFreeFontNames( list );
  856. }
  857. }
  858. }
  859. return FONTINFO_SUCCESS;
  860. }
  861. int fontInfoClass::checkSingleFontSpec (
  862. XtAppContext app,
  863. Display *d,
  864. char *userFontFamilyName,
  865. char *line,
  866. int major,
  867. int minor,
  868. int release )
  869. {
  870. int checkBest = 0;
  871. return checkSingleFontSpecGeneric( app, d, userFontFamilyName,
  872. line, checkBest, major, minor, release );
  873. }
  874. int fontInfoClass::checkBestSingleFontSpec (
  875. XtAppContext app,
  876. Display *d,
  877. char *userFontFamilyName,
  878. char *line,
  879. int major,
  880. int minor,
  881. int release )
  882. {
  883. int checkBest = 1;
  884. return checkSingleFontSpecGeneric( app, d, userFontFamilyName,
  885. line, checkBest, major, minor, release );
  886. }
  887. int fontInfoClass::getSingleFontSpec (
  888. XtAppContext app,
  889. Display *d,
  890. char *userFontFamilyName,
  891. char *buf,
  892. int major,
  893. int minor,
  894. int release )
  895. {
  896. char t1[255+1], t2[255+1], t3[255+1], t4[255+1],
  897. t5[255+1], t6[255+1], t7[255+1], mod[4][255+1], fontSpec[255+1],
  898. *tk1, *tk2, *ctx1, *ctx2;
  899. int i, ii, iii, pointSize[200], numSizes;
  900. int stat, preload;
  901. int empty = 1;
  902. fontNameListPtr cur;
  903. int dup;
  904. XFontStruct *fs;
  905. ctx1 = NULL;
  906. tk1 = strtok_r( buf, "\t\n()", &ctx1 );
  907. if ( tk1 ) {
  908. strcpy( t1, tk1 );
  909. }
  910. else {
  911. fprintf( stderr, fontInfoClass_str5, lastNonCommentLine );
  912. return FONTINFO_SYNTAX;
  913. }
  914. tk1 = strtok_r( NULL, "\t\n()", &ctx1 );
  915. if ( tk1 ) {
  916. strcpy( t2, tk1 );
  917. }
  918. else {
  919. fprintf( stderr, fontInfoClass_str5, lastNonCommentLine );
  920. return FONTINFO_SYNTAX;
  921. }
  922. // get medium and bold modifiers
  923. ctx2 = NULL;
  924. tk2 = strtok_r( t2, ",", &ctx2 );
  925. if ( tk2 ) {
  926. strcpy( mod[0], tk2 );
  927. }
  928. else {
  929. fprintf( stderr, fontInfoClass_str5, lastNonCommentLine );
  930. return FONTINFO_SYNTAX;
  931. }
  932. setMediumString( mod[0] );
  933. tk2 = strtok_r( NULL, ",", &ctx2 );
  934. if ( tk2 ) {
  935. strcpy( mod[1], tk2 );
  936. }
  937. else {
  938. fprintf( stderr, fontInfoClass_str5, lastNonCommentLine );
  939. return FONTINFO_SYNTAX;
  940. }
  941. setBoldString( mod[1] );
  942. tk1 = strtok_r( NULL, "\t\n()", &ctx1 );
  943. if ( tk1 ) {
  944. strcpy( t3, tk1 );
  945. }
  946. else {
  947. fprintf( stderr, fontInfoClass_str5, lastNonCommentLine );
  948. return FONTINFO_SYNTAX;
  949. }
  950. tk1 = strtok_r( NULL, "\t\n()", &ctx1 );
  951. if ( tk1 ) {
  952. strcpy( t4, tk1 );
  953. }
  954. else {
  955. fprintf( stderr, fontInfoClass_str5, lastNonCommentLine );
  956. return FONTINFO_SYNTAX;
  957. }
  958. // get italic and regular indicators
  959. ctx2 = NULL;
  960. tk2 = strtok_r( t4, ",", &ctx2 );
  961. if ( tk2 ) {
  962. strcpy( mod[2], tk2 );
  963. }
  964. else {
  965. fprintf( stderr, fontInfoClass_str5, lastNonCommentLine );
  966. return FONTINFO_SYNTAX;
  967. }
  968. setRegularString( mod[2] );
  969. tk2 = strtok_r( NULL, ",", &ctx2 );
  970. if ( tk2 ) {
  971. strcpy( mod[3], tk2 );
  972. }
  973. else {
  974. fprintf( stderr, fontInfoClass_str5, lastNonCommentLine );
  975. return FONTINFO_SYNTAX;
  976. }
  977. setItalicString( mod[3] );
  978. tk1 = strtok_r( NULL, "\t\n()", &ctx1 );
  979. if ( tk1 ) {
  980. strcpy( t5, tk1 );
  981. }
  982. else {
  983. fprintf( stderr, fontInfoClass_str5, lastNonCommentLine );
  984. return FONTINFO_SYNTAX;
  985. }
  986. tk1 = strtok_r( NULL, "\t\n()", &ctx1 );
  987. if ( tk1 ) {
  988. strcpy( t6, tk1 );
  989. }
  990. else {
  991. fprintf( stderr, fontInfoClass_str5, lastNonCommentLine );
  992. return FONTINFO_SYNTAX;
  993. }
  994. // get point sizes
  995. numSizes = 0;
  996. ctx2 = NULL;
  997. tk2 = strtok_r( t6, ",", &ctx2 );
  998. if ( tk2 ) {
  999. pointSize[numSizes] = atol( tk2 );
  1000. numSizes++;
  1001. if ( numSizes >= 200 ) {
  1002. fprintf( stderr, fontInfoClass_str7, lastNonCommentLine );
  1003. return FONTINFO_TOOMANYSIZES;
  1004. }
  1005. }
  1006. else {
  1007. fprintf( stderr, fontInfoClass_str5, lastNonCommentLine );
  1008. return FONTINFO_SYNTAX;
  1009. }
  1010. do {
  1011. tk2 = strtok_r( NULL, ",", &ctx2 );
  1012. if ( tk2 ) {
  1013. pointSize[numSizes] = atol( tk2 );
  1014. numSizes++;
  1015. if ( numSizes >= 200 ) {
  1016. fprintf( stderr, fontInfoClass_str7, lastNonCommentLine );
  1017. return FONTINFO_TOOMANYSIZES;
  1018. }
  1019. }
  1020. } while ( tk2 );
  1021. tk1 = strtok_r( NULL, "\t\n()", &ctx1 );
  1022. if ( tk1 ) {
  1023. strcpy( t7, tk1 );
  1024. }
  1025. else {
  1026. fprintf( stderr, fontInfoClass_str5, lastNonCommentLine );
  1027. return FONTINFO_SYNTAX;
  1028. }
  1029. preload = 0;
  1030. requireExactMatch = 0;
  1031. tk1 = strtok_r( NULL, "\t\n", &ctx1 );
  1032. if ( tk1 ) {
  1033. if ( strcmp( tk1, "preload" ) == 0 ) {
  1034. preload = 1;
  1035. }
  1036. else if ( strcmp( tk1, "exact" ) == 0 ) {
  1037. requireExactMatch = 1;
  1038. }
  1039. }
  1040. tk1 = strtok_r( NULL, "\t\n", &ctx1 );
  1041. if ( tk1 ) {
  1042. if ( strcmp( tk1, "preload" ) == 0 ) {
  1043. preload = 1;
  1044. }
  1045. else if ( strcmp( tk1, "exact" ) == 0 ) {
  1046. requireExactMatch = 1;
  1047. }
  1048. }
  1049. //fprintf( stderr, "preload = %-d\n", preload );
  1050. //fprintf( stderr, "exact = %-d\n", requireExactMatch );
  1051. //fprintf( stderr, "t1 = [%s]\n", t1 );
  1052. //fprintf( stderr, " mod[0] = [%s]\n", mod[0] );
  1053. //fprintf( stderr, " mod[1] = [%s]\n", mod[1] );
  1054. //fprintf( stderr, "t3 = [%s]\n", t3 );
  1055. //fprintf( stderr, " mod[2] = [%s]\n", mod[2] );
  1056. //fprintf( stderr, " mod[3] = [%s]\n", mod[3] );
  1057. //fprintf( stderr, "t5 = [%s]\n", t5 );
  1058. //for ( i=0; i<numSizes; i++ ) {
  1059. // fprintf( stderr, " size[%-d] = %-d\n", i, pointSize[i] );
  1060. //}
  1061. //fprintf( stderr, "t7 = [%s]\n", t7 );
  1062. // Build fontspec
  1063. for ( i=0; i<2; i++ ) {
  1064. for ( ii=2; ii<4; ii++ ) {
  1065. for ( iii=0; iii<numSizes; iii++ ) {
  1066. sprintf( fontSpec, "%s%s%s%s%s%-d%s", t1, mod[i], t3, mod[ii],
  1067. t5, pointSize[iii], t7 );
  1068. //fprintf( stderr, "[%s]\n", fontSpec );
  1069. cur = new fontNameListType;
  1070. stat = this->resolveFont( fontSpec, userFontFamilyName, cur );
  1071. if ( !( stat & 1 ) ) {
  1072. delete cur;
  1073. return stat;
  1074. }
  1075. stat = avl_insert_node( this->fontNameListH, (void *) cur,
  1076. &dup );
  1077. if ( !( stat & 1 ) ) {
  1078. fprintf( stderr, fontInfoClass_str11, __LINE__, __FILE__ );
  1079. return stat;
  1080. }
  1081. if ( dup ) {
  1082. fprintf( stderr, fontInfoClass_str13, cur->name, lastNonCommentLine );
  1083. }
  1084. if ( preload ) {
  1085. //fprintf( stderr, "preload %s\n", cur->name );
  1086. fs = getXFontStruct( cur->name );
  1087. }
  1088. stat = appendSizeMenu( cur->family, cur->size, cur->fsize );
  1089. if ( !( stat & 1 ) ) return stat;
  1090. empty = 0;
  1091. }
  1092. }
  1093. }
  1094. return 1;
  1095. }
  1096. int fontInfoClass::flushToBrace (
  1097. FILE *f )
  1098. {
  1099. char line[255+1], *tk, *ptr, *ctx;
  1100. int foundBrace;
  1101. do {
  1102. ptr = getStrFromFile ( line, 255, f );
  1103. if ( ptr ) {
  1104. ctx = NULL;
  1105. tk = strtok_r( line, " \t\n", &ctx );
  1106. if ( tk ) {
  1107. if ( tk[0] == '}' ) {
  1108. foundBrace = 1;
  1109. }
  1110. else {
  1111. foundBrace = 0;
  1112. }
  1113. }
  1114. }
  1115. else {
  1116. fprintf( stderr, fontInfoClass_str10 );
  1117. return FONTINFO_FAIL;
  1118. }
  1119. } while ( !foundBrace );
  1120. return FONTINFO_SUCCESS;
  1121. }
  1122. int fontInfoClass::processFontGroup (
  1123. XtAppContext app,
  1124. Display *d,
  1125. char *userFontFamilyName,
  1126. FILE *f,
  1127. int major,
  1128. int minor,
  1129. int release )
  1130. {
  1131. char line[255+1], buf[255+1], lastLine[255+1], *ptr, *tk1, *ctx1;
  1132. int stat;
  1133. int foundBrace;
  1134. strcpy( lastLine, "" );
  1135. stat = FONTINFO_GROUPSYNTAX; // in case all lines are blank
  1136. do {
  1137. processAllEvents( app, display );
  1138. ptr = getStrFromFile ( line, 255, f );
  1139. if ( ptr ) {
  1140. ctx1 = NULL;
  1141. strcpy( buf, line );
  1142. tk1 = strtok_r( buf, "\t\n", &ctx1 );
  1143. if ( tk1 ) {
  1144. if ( tk1[0] == '}' ) {
  1145. foundBrace = 1;
  1146. }
  1147. else {
  1148. foundBrace = 0;
  1149. }
  1150. }
  1151. if ( ! foundBrace ) {
  1152. strcpy( lastLine, line );
  1153. stat = checkSingleFontSpec( app, d, userFontFamilyName, line,
  1154. major, minor, release );
  1155. if ( stat & 1 ) {
  1156. if ( debugMode() == 1000 ) fprintf( stderr, "Using font: %s", line );
  1157. stat = getSingleFontSpec( app, d, userFontFamilyName, line,
  1158. major, minor, release );
  1159. flushToBrace( f );
  1160. return stat; // return stat from getSingleFontSpec
  1161. }
  1162. else {
  1163. if ( debugMode() == 1000 ) fprintf( stderr, "Font not found: %s", line );
  1164. }
  1165. }
  1166. }
  1167. else {
  1168. fprintf( stderr, fontInfoClass_str5, lastNonCommentLine );
  1169. return FONTINFO_SYNTAX;
  1170. }
  1171. } while ( !foundBrace );
  1172. // If we never found a matching font, try to get something that matches,
  1173. // even badly, using the findBestFont function (in this file)
  1174. stat = checkBestSingleFontSpec( app, d, userFontFamilyName, lastLine,
  1175. major, minor, release );
  1176. if ( stat & 1 ) {
  1177. if ( debugMode() == 1000 ) fprintf( stderr, "Using font (with substitutions): %s",
  1178. lastLine );
  1179. stat = getSingleFontSpec( app, d, userFontFamilyName, lastLine,
  1180. major, minor, release );
  1181. }
  1182. if ( stat == FONTINFO_GROUPSYNTAX ) {
  1183. fprintf( stderr, fontInfoClass_str12, lastNonCommentLine );
  1184. }
  1185. return stat; // return last stat from checkSingleFontSpec or GROUPSYNTAX
  1186. }
  1187. int fontInfoClass::initFromFileVer3 (
  1188. XtAppContext app,
  1189. Display *d,
  1190. FILE *f,
  1191. int major,
  1192. int minor,
  1193. int release )
  1194. {
  1195. char line[255+1], buf[255+1], userFontFamilyName[63+1], *ptr, *tk1, *ctx1;
  1196. int stat;
  1197. int empty = 1;
  1198. ptr = getStrFromFile( line, 255, f );
  1199. if ( !ptr ) {
  1200. fclose( f );
  1201. fprintf( stderr, fontInfoClass_str3, lastNonCommentLine );
  1202. return FONTINFO_EMPTY;
  1203. }
  1204. strncpy( defSiteFontTag, line, 127 );
  1205. defSiteFontTag[127] = 0;
  1206. defSiteFontTag[strlen(defSiteFontTag)-1] = 0; // discard \n
  1207. ptr = getStrFromFile( line, 255, f );
  1208. if ( !ptr ) {
  1209. fclose( f );
  1210. fprintf( stderr, fontInfoClass_str4, lastNonCommentLine );
  1211. return FONTINFO_EMPTY;
  1212. }
  1213. strncpy( defFontTag, line, 127 );
  1214. defFontTag[127] = 0;
  1215. defFontTag[strlen(defFontTag)-1] = 0; // discard \n
  1216. do {
  1217. processAllEvents( app, display );
  1218. ptr = getStrFromFile ( line, 255, f );
  1219. if ( ptr ) {
  1220. empty = 0;
  1221. ctx1 = NULL;
  1222. strcpy( buf, line );
  1223. tk1 = strtok_r( buf, "=\t\n()", &ctx1 );
  1224. if ( tk1 ) {
  1225. strncpy( userFontFamilyName, tk1, 63 );
  1226. userFontFamilyName[63] = 0;
  1227. }
  1228. else {
  1229. fclose( f );
  1230. fprintf( stderr, fontInfoClass_str5, lastNonCommentLine );
  1231. return FONTINFO_SYNTAX;
  1232. }
  1233. tk1 = strtok_r( NULL, "\t\n()", &ctx1 );
  1234. if ( tk1 ) {
  1235. if ( strcmp( tk1, "{" ) == 0 ) { // font groups
  1236. stat = processFontGroup( app, d, userFontFamilyName, f,
  1237. major, minor, release );
  1238. if ( !( stat & 1 ) ) {
  1239. fclose( f );
  1240. return stat;
  1241. }
  1242. }
  1243. else {
  1244. // tk1 points to first character after "<name>="
  1245. strcpy( buf, line );
  1246. stat = getSingleFontSpec( app, d, userFontFamilyName, tk1,
  1247. major, minor, release );
  1248. if ( !( stat & 1 ) ) {
  1249. fclose( f );
  1250. return stat;
  1251. }
  1252. }
  1253. }
  1254. else {
  1255. fclose( f );
  1256. fprintf( stderr, fontInfoClass_str5, lastNonCommentLine );
  1257. return FONTINFO_SYNTAX;
  1258. }
  1259. }
  1260. } while ( ptr );
  1261. fclose( f );
  1262. if ( empty ) {
  1263. fprintf( stderr, fontInfoClass_str6 );
  1264. return FONTINFO_EMPTY;
  1265. }
  1266. return FONTINFO_SUCCESS;
  1267. }
  1268. int fontInfoClass::initFromFile (
  1269. XtAppContext app,
  1270. Display *d,
  1271. char *fileName )
  1272. {
  1273. // Read font specs from given file, query server, and populate data structure.
  1274. // If font does not exist, use some other font.
  1275. char line[127+1], *ptr, *fontSpec, *tk, *ctx;
  1276. int stat, preload;
  1277. FILE *f;
  1278. int empty = 1;
  1279. fontNameListPtr cur;
  1280. int dup;
  1281. int major, minor, release;
  1282. XFontStruct *fs;
  1283. this->display = d;
  1284. strncpy( defSiteFontTag, "helvetica-medium-r-10.0", 127 );
  1285. strncpy( defFontTag, "helvetica-medium-r-14.0", 127 );
  1286. //f = fopen( fileName, "r" );
  1287. f = fileOpen( fileName, "r" );
  1288. if ( !f ) {
  1289. return FONTINFO_NO_FILE;
  1290. }
  1291. ptr = fgets( line, 127, f );
  1292. if ( !ptr ) {
  1293. fprintf( stderr, fontInfoClass_str6 );
  1294. return FONTINFO_EMPTY;
  1295. }
  1296. sscanf( line, "%d %d %d\n", &major, &minor, &release );
  1297. if ( major == 3 ) {
  1298. stat = initFromFileVer3( app, d, f, major, minor, release );
  1299. return stat;
  1300. }
  1301. if ( ( major > 1 ) || ( minor > 0 ) ) {
  1302. ptr = fgets ( defSiteFontTag, 127, f );
  1303. if ( !ptr ) {
  1304. fclose( f );
  1305. return FONTINFO_EMPTY;
  1306. }
  1307. defSiteFontTag[strlen(defSiteFontTag)-1] = 0; // discard \n
  1308. }
  1309. ptr = fgets ( defFontTag, 127, f );
  1310. if ( !ptr ) {
  1311. fclose( f );
  1312. return FONTINFO_EMPTY;
  1313. }
  1314. defFontTag[strlen(defFontTag)-1] = 0; // discard \n
  1315. do {
  1316. processAllEvents( app, display );
  1317. ptr = fgets ( line, 127, f );
  1318. if ( ptr ) { // ignore blank lines
  1319. ctx = NULL;
  1320. fontSpec = strtok_r( line, "\t\n", &ctx );
  1321. if ( fontSpec ) {
  1322. if ( major >= 2 ) {
  1323. tk = strtok_r( NULL, "\t\n", &ctx );
  1324. if ( tk ) {
  1325. if ( strcmp( tk, "preload" ) == 0 ) {
  1326. preload = 1;
  1327. }
  1328. else {
  1329. preload = 0;
  1330. }
  1331. }
  1332. else {
  1333. preload = 0;
  1334. }
  1335. }
  1336. else {
  1337. preload = 0;
  1338. }
  1339. cur = new fontNameListType;
  1340. stat = this->resolveFont( fontSpec, cur );
  1341. if ( !( stat & 1 ) ) {
  1342. delete cur;
  1343. return stat;
  1344. }
  1345. stat = avl_insert_node( this->fontNameListH, (void *) cur, &dup );
  1346. if ( !( stat & 1 ) ) return stat;
  1347. // if ( dup ) fprintf( stderr, "duplicate\n" );
  1348. if ( preload ) {
  1349. //fprintf( stderr, "preload %s\n", cur->name );
  1350. fs = getXFontStruct( cur->name );
  1351. }
  1352. stat = appendSizeMenu( cur->family, cur->size, cur->fsize );
  1353. if ( !( stat & 1 ) ) return stat;
  1354. empty = 0;
  1355. }
  1356. }
  1357. } while ( ptr );
  1358. fclose( f );
  1359. if ( empty ) return FONTINFO_EMPTY;
  1360. return FONTINFO_SUCCESS;
  1361. }
  1362. int fontInfoClass::addFont (
  1363. char *oneName )
  1364. {
  1365. int stat, slantLoc;
  1366. fontNameListPtr cur;
  1367. char *tk, *ctx, spec[127+1], family[63+1], weight[31+1],
  1368. slant[31+1], pixels[31+1], size[31+1];
  1369. int dup;
  1370. stat = avl_get_match( this->fontNameListH, (void *) oneName,
  1371. (void **) &cur );
  1372. if ( !(stat & 1) ) return stat;
  1373. if ( cur ) return FONTINFO_SUCCESS;
  1374. strncpy( spec, oneName, 127 );
  1375. ctx = NULL;
  1376. tk = strtok_r( spec, "-", &ctx );
  1377. if ( !tk ) return FONTINFO_FAIL;
  1378. strncpy( family, tk, 63 );
  1379. tk = strtok_r( NULL, "-", &ctx );
  1380. if ( !tk ) return FONTINFO_FAIL;
  1381. strncpy( weight, tk, 31 );
  1382. tk = strtok_r( NULL, "-", &ctx );
  1383. if ( !tk ) return FONTINFO_FAIL;
  1384. strncpy( slant, tk, 31 );
  1385. tk = strtok_r( NULL, "-", &ctx );
  1386. if ( !tk ) return FONTINFO_FAIL;
  1387. strncpy( pixels, tk, 31 );
  1388. tk = strtok_r( NULL, "-", &ctx );
  1389. if ( !tk ) return FONTINFO_FAIL;
  1390. strncpy( size, tk, 31 );
  1391. // slant here is always 'i' but the actual font spec may use 'o' so
  1392. // build the font spec first with i then with o
  1393. strncpy( spec, "-*-", 127 ); // don't care about foundry
  1394. Strncat( spec, family, 127 );
  1395. Strncat( spec, "-", 127 );
  1396. Strncat( spec, weight, 127 );
  1397. Strncat( spec, "-", 127 );
  1398. slantLoc = strlen(spec);
  1399. Strncat( spec, "?", 127 ); // will hold slant
  1400. Strncat( spec, "-", 127 );
  1401. Strncat( spec, "normal", 127 );
  1402. Strncat( spec, "--", 127 );
  1403. Strncat( spec, pixels, 127 );
  1404. Strncat( spec, "-", 127 );
  1405. Strncat( spec, size, 127 );
  1406. Strncat( spec, "-*-*-*-*-*-*", 127 );
  1407. cur = new fontNameListType;
  1408. if ( strcmp( slant, "i" ) ) {
  1409. spec[slantLoc] = 'i';
  1410. // fprintf( stderr, "trying [%s]\n", spec );
  1411. stat = this->resolveOneFont( spec, cur );
  1412. if ( ( stat & 1 ) ) {
  1413. goto success;
  1414. }
  1415. spec[slantLoc] = 'o';
  1416. // fprintf( stderr, "trying [%s]\n", spec );
  1417. stat = this->resolveOneFont( spec, cur );
  1418. if ( ( stat & 1 ) ) {
  1419. goto success;
  1420. }
  1421. // fprintf( stderr, "last try [%s]\n", spec );
  1422. stat = this->resolveFont( spec, cur );
  1423. if ( ( stat & 1 ) ) {
  1424. goto success;
  1425. }
  1426. delete cur;
  1427. return FONTINFO_NO_FONT;
  1428. }
  1429. else {
  1430. spec[slantLoc] = 'r';
  1431. // fprintf( stderr, "trying [%s]\n", spec );
  1432. stat = this->resolveOneFont( spec, cur );
  1433. if ( ( stat & 1 ) ) {
  1434. goto success;
  1435. }
  1436. // fprintf( stderr, "last try [%s]\n", spec );
  1437. stat = this->resolveFont( spec, cur );
  1438. if ( ( stat & 1 ) ) {
  1439. goto success;
  1440. }
  1441. delete cur;
  1442. return FONTINFO_NO_FONT;
  1443. }
  1444. success:
  1445. // fprintf( stderr, "success\n" );
  1446. stat = avl_insert_node( this->fontNameListH, (void *) cur, &dup );
  1447. if ( !( stat & 1 ) ) return stat;
  1448. // if ( dup ) fprintf( stderr, "duplicate\n" );
  1449. return FONTINFO_SUCCESS;
  1450. }
  1451. int fontInfoClass::getFontName (
  1452. char *fontTag,
  1453. double rotation,
  1454. char *name,
  1455. int len )
  1456. {
  1457. int stat;
  1458. fontNameListPtr cur;
  1459. double radians = rotation * 0.017453;
  1460. double s, c, pixels;
  1461. double term;
  1462. char buf[127+1], tmp[31+1], matrix[63+1], sign[2], *tk, *context;
  1463. stat = avl_get_match( this->fontNameListH, (void *) fontTag,
  1464. (void **) &cur );
  1465. if ( !(stat & 1) ) return 0;
  1466. if ( rotation == 0.0 ) {
  1467. strncpy( name, cur->fullName, len );
  1468. name[len] = 0;
  1469. return 1;
  1470. }
  1471. s = sin(radians);
  1472. c = cos(radians);
  1473. strncpy( buf, cur->fullName, 127 );
  1474. strncpy( name, "-", len );
  1475. context = NULL;
  1476. tk = strtok_r( buf, "-", &context ); // foundary
  1477. Strncat( name, tk, len );
  1478. Strncat( name, "-", len );
  1479. tk = strtok_r( NULL, "-", &context ); // name
  1480. Strncat( name, tk, len );
  1481. Strncat( name, "-", len );
  1482. tk = strtok_r( NULL, "-", &context ); // weight
  1483. Strncat( name, tk, len );
  1484. Strncat( name, "-", len );
  1485. tk = strtok_r( NULL, "-", &context ); // slant
  1486. Strncat( name, tk, len );
  1487. Strncat( name, "-", len );
  1488. tk = strtok_r( NULL, "-", &context ); // set width
  1489. Strncat( name, tk, len );
  1490. Strncat( name, "-", len );
  1491. Strncat( name, "-", len );
  1492. tk = strtok_r( NULL, "-", &context ); // points
  1493. Strncat( name, "0", len );
  1494. Strncat( name, "-", len );
  1495. tk = strtok_r( NULL, "-", &context ); // pixels
  1496. strncpy( matrix, "[", 63 );
  1497. pixels = atof( tk ) / 10.0;
  1498. if ( c < 0.0 ) {
  1499. strcpy( sign, "~" );
  1500. }
  1501. else {
  1502. strcpy( sign, "+" );
  1503. }
  1504. term = fabs(c) * pixels;
  1505. sprintf( tmp, "%s%-.1f", sign, term );
  1506. fixFontSize( tmp );
  1507. Strncat( matrix, tmp, 63 );
  1508. if ( s < 0.0 ) {
  1509. strcpy( sign, "~" );
  1510. }
  1511. else {
  1512. strcpy( sign, "+" );
  1513. }
  1514. term = fabs(s) * pixels;
  1515. sprintf( tmp, "%s%-.1f", sign, term );
  1516. fixFontSize( tmp );
  1517. Strncat( matrix, tmp, 63 );
  1518. if ( s < 0.0 ) {
  1519. strcpy( sign, "+" );
  1520. }
  1521. else {
  1522. strcpy( sign, "~" );
  1523. }
  1524. term = fabs(s) * pixels;
  1525. sprintf( tmp, "%s%-.1f", sign, term );
  1526. fixFontSize( tmp );
  1527. Strncat( matrix, tmp, 63 );
  1528. if ( c < 0.0 ) {
  1529. strcpy( sign, "~" );
  1530. }
  1531. else {
  1532. strcpy( sign, "+" );
  1533. }
  1534. term = fabs(c) * pixels;
  1535. sprintf( tmp, "%s%-.1f", sign, term );
  1536. fixFontSize( tmp );
  1537. Strncat( matrix, tmp, 63 );
  1538. Strncat( matrix, "]", 63 );
  1539. Strncat( name, matrix, len );
  1540. Strncat( name, "-", len );
  1541. tk = strtok_r( NULL, "-", &context ); // horz res
  1542. Strncat( name, tk, len );
  1543. Strncat( name, "-", len );
  1544. tk = strtok_r( NULL, "-", &context ); // vert res
  1545. Strncat( name, tk, len );
  1546. Strncat( name, "-", len );
  1547. tk = strtok_r( NULL, "-", &context ); // spacing
  1548. Strncat( name, tk, len );
  1549. Strncat( name, "-", len );
  1550. tk = strtok_r( NULL, "-", &context ); // average width
  1551. Strncat( name, "0", len );
  1552. Strncat( name, "-", len );
  1553. tk = strtok_r( NULL, "-", &context ); // char set
  1554. Strncat( name, tk, len );
  1555. tk = strtok_r( NULL, "-", &context ); // char set
  1556. if ( tk ) {
  1557. Strncat( name, "-", len );
  1558. Strncat( name, tk, len );
  1559. }
  1560. tk = strtok_r( NULL, "-", &context ); // char set
  1561. if ( tk ) {
  1562. Strncat( name, "-", len );
  1563. Strncat( name, tk, len );
  1564. }
  1565. name[len] = 0;
  1566. return 1;
  1567. }
  1568. XFontStruct *fontInfoClass::getXFontStruct (
  1569. char *name )
  1570. {
  1571. int stat;
  1572. fontNameListPtr cur;
  1573. XmFontListEntry entry;
  1574. stat = avl_get_match( this->fontNameListH, (void *) name, (void **) &cur );
  1575. if ( !(stat & 1) ) return (XFontStruct *) NULL;
  1576. if ( !cur ) return (XFontStruct *) NULL;
  1577. if ( cur->fontLoaded ) return cur->fontStruct;
  1578. cur->fontStruct = XLoadQueryFont( this->display, cur->fullName );
  1579. entry = XmFontListEntryLoad( this->display, cur->fullName,
  1580. XmFONT_IS_FONT, cur->name );
  1581. if ( entry ) {
  1582. if ( this->fontListEmpty ) {
  1583. this->fontList = XmFontListAppendEntry( NULL, entry );
  1584. this->fontListEmpty = 0;
  1585. }
  1586. else {
  1587. this->fontList = XmFontListAppendEntry( this->fontList, entry );
  1588. }
  1589. XmFontListEntryFree( &entry );
  1590. }
  1591. if ( cur->fontStruct ) {
  1592. cur->fontLoaded = 1;
  1593. }
  1594. return cur->fontStruct;
  1595. }
  1596. XFontStruct *fontInfoClass::getXNativeFontStruct (
  1597. char *name )
  1598. {
  1599. XmFontListEntry entry;
  1600. XFontStruct *fs;
  1601. fs = XLoadQueryFont( this->display, name );
  1602. entry = XmFontListEntryLoad( this->display, name,
  1603. XmFONT_IS_FONT, name );
  1604. if ( entry ) {
  1605. if ( this->fontListEmpty ) {
  1606. this->fontList = XmFontListAppendEntry( NULL, entry );
  1607. this->fontListEmpty = 0;
  1608. }
  1609. else {
  1610. this->fontList = XmFontListAppendEntry( this->fontList, entry );
  1611. }
  1612. XmFontListEntryFree( &entry );
  1613. }
  1614. return fs;
  1615. }
  1616. XmFontList fontInfoClass::getXmFontList ( void )
  1617. {
  1618. return this->fontList;
  1619. }
  1620. int fontInfoClass::loadFontTag (
  1621. char *name )
  1622. {
  1623. int stat;
  1624. fontNameListPtr cur;
  1625. XmFontListEntry entry;
  1626. stat = avl_get_match( this->fontNameListH, (void *) name, (void **) &cur );
  1627. if ( !(stat & 1) ) return stat;
  1628. if ( !cur ) return FONTINFO_FAIL;
  1629. if ( cur->fontLoaded ) return FONTINFO_SUCCESS;
  1630. cur->fontStruct = XLoadQueryFont( this->display, cur->fullName );
  1631. entry = XmFontListEntryLoad( this->display, cur->fullName,
  1632. XmFONT_IS_FONT, cur->name );
  1633. if ( entry ) {
  1634. if ( this->fontListEmpty ) {
  1635. this->fontList = XmFontListAppendEntry( NULL, entry );
  1636. this->fontListEmpty = 0;
  1637. }
  1638. else {
  1639. this->fontList = XmFontListAppendEntry( this->fontList, entry );
  1640. }
  1641. XmFontListEntryFree( &entry );
  1642. }
  1643. if ( cur->fontStruct ) {
  1644. cur->fontLoaded = 1;
  1645. }
  1646. return FONTINFO_SUCCESS;
  1647. }
  1648. int fontInfoClass::getTextFontList (
  1649. char *name,
  1650. XmFontList *oneFontList )
  1651. {
  1652. int stat;
  1653. fontNameListPtr cur;
  1654. XmFontListEntry entry;
  1655. stat = avl_get_match( this->fontNameListH, (void *) name, (void **) &cur );
  1656. if ( !(stat & 1) ) return stat;
  1657. if ( !cur ) return FONTINFO_FAIL;
  1658. if ( !cur->fontLoaded ) {
  1659. stat = this->loadFontTag( name );
  1660. if ( !( stat & 1 ) ) return FONTINFO_FAIL;
  1661. }
  1662. entry = XmFontListEntryLoad( this->display, cur->fullName,
  1663. XmFONT_IS_FONT, cur->name );
  1664. if ( entry ) {
  1665. *oneFontList = XmFontListAppendEntry( NULL, entry );
  1666. XmFontListEntryFree( &entry );
  1667. }
  1668. else {
  1669. return FONTINFO_FAIL;
  1670. }
  1671. return FONTINFO_SUCCESS;
  1672. }
  1673. int fontInfoClass::getFirstFontMapping (
  1674. char *tag,
  1675. int tagMax,
  1676. char *spec,
  1677. int specMax
  1678. ) {
  1679. int stat;
  1680. fontNameListPtr cur;
  1681. stat = avl_get_first( this->fontNameListH, (void **) &cur );
  1682. if ( !( stat & 1 ) || !cur ) {
  1683. return 0;
  1684. }
  1685. strncpy( tag, cur->name, tagMax );
  1686. tag[tagMax] = 0;
  1687. strncpy( spec, cur->fullName, specMax );
  1688. spec[specMax] = 0;
  1689. return 1;
  1690. }
  1691. int fontInfoClass::getNextFontMapping (
  1692. char *tag,
  1693. int tagMax,
  1694. char *spec,
  1695. int specMax
  1696. ) {
  1697. int stat;
  1698. fontNameListPtr cur;
  1699. stat = avl_get_next( this->fontNameListH, (void **) &cur );
  1700. if ( !( stat & 1 ) || !cur ) {
  1701. return 0;
  1702. }
  1703. strncpy( tag, cur->name, tagMax );
  1704. tag[tagMax] = 0;
  1705. strncpy( spec, cur->fullName, specMax );
  1706. spec[specMax] = 0;
  1707. return 1;
  1708. }