stroke_fonts.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. /****************************************************************************
  2. *
  3. * MODULE: g.mkfontcap
  4. * AUTHOR(S): Paul Kelly
  5. * PURPOSE: Generates the font configuration file by scanning various
  6. * directories for GRASS stroke and Freetype-compatible fonts.
  7. *
  8. * COPYRIGHT: (C) 2007 by the GRASS Development Team
  9. *
  10. * This program is free software under the GNU General Public
  11. * License (>=v2). Read the file COPYING that comes with GRASS
  12. * for details.
  13. *
  14. *****************************************************************************/
  15. #include <stdio.h>
  16. #include <unistd.h>
  17. #include <string.h>
  18. #include <errno.h>
  19. #include <grass/gis.h>
  20. #include <grass/fontcap.h>
  21. #include "local_proto.h"
  22. struct font_desc
  23. {
  24. char *filename; /**< Filename in fonts directory */
  25. char *description;/**< Descriptive name of font contained in this file */
  26. };
  27. static struct font_desc *font_descriptions = NULL;
  28. static int num_descriptions = 0;
  29. static int load_font_descriptions(const char *);
  30. static void free_font_descriptions(void);
  31. static const char *get_desc(const char *);
  32. /**
  33. * \brief Find Stroke fonts and store them in a global GFONT_CAP struct
  34. *
  35. * The directory $GISBASE/fonts is listed to find all stroke fonts (i.e.
  36. * files with a .hmp extension).
  37. * Information on each font is stored in the global GFONT_CAP struct,
  38. * fontcap, to be used by the main program.
  39. **/
  40. void find_stroke_fonts(void)
  41. {
  42. char *dirpath, *fonttable;
  43. char **dirlisting;
  44. int numfiles, i;
  45. G_asprintf(&dirpath, "%s/fonts", G_gisbase());
  46. dirlisting = G_ls2(dirpath, &numfiles);
  47. G_asprintf(&fonttable, "%s/fonts.table", dirpath);
  48. if (access(fonttable, R_OK) == 0)
  49. load_font_descriptions(fonttable);
  50. for (i = 0; i < numfiles; i++) {
  51. if (!strstr(dirlisting[i], ".hmp"))
  52. continue;
  53. if (totalfonts >= maxfonts) {
  54. maxfonts += 20;
  55. fontcap = G_realloc(fontcap, maxfonts * sizeof(struct GFONT_CAP));
  56. }
  57. /* Path */
  58. G_asprintf(&fontcap[totalfonts].path, "%s%c%s", dirpath,
  59. HOST_DIRSEP, dirlisting[i]);
  60. G_convert_dirseps_to_host(fontcap[totalfonts].path);
  61. /* Description & Name */
  62. fontcap[totalfonts].longname = G_store(get_desc(dirlisting[i]));
  63. *(strstr(dirlisting[i], ".hmp")) = '\0';
  64. fontcap[totalfonts].name = G_store(dirlisting[i]);
  65. /* Font Type */
  66. fontcap[totalfonts].type = GFONT_STROKE;
  67. /* These two probably not relevant */
  68. fontcap[totalfonts].index = 0;
  69. fontcap[totalfonts].encoding = G_store("utf-8");
  70. totalfonts++;
  71. G_free(dirlisting[i]);
  72. }
  73. G_free(dirlisting);
  74. if (font_descriptions)
  75. free_font_descriptions();
  76. return;
  77. }
  78. /**
  79. * \brief Loads description file for stroke fonts into memory
  80. *
  81. * Parses the font description file and loads an array of filenames
  82. * and corresponding descriptions pointed at by the static variable
  83. * font_descriptions. After calling, num_descriptions will contain
  84. * the number of font descriptions that were loaded.
  85. *
  86. * \param descfile Filename to be loaded
  87. *
  88. * \return 1 if at least one font description was loaded; 0 otherwise
  89. **/
  90. static int load_font_descriptions(const char *descfile)
  91. {
  92. size_t memsize = 0;
  93. FILE *fp;
  94. char buff[500];
  95. fp = fopen(descfile, "r");
  96. if (fp == NULL) {
  97. G_warning("Unable to open font description file %s for reading: %s",
  98. descfile, strerror(errno));
  99. return 0;
  100. }
  101. while (G_getl2(buff, sizeof(buff), fp)) {
  102. char name[100], description[256];
  103. if (buff[0] == '#')
  104. continue;
  105. if (sscanf(buff, "%99[^|]|%255[^\n]", name, description) != 2)
  106. continue;
  107. if (num_descriptions >= memsize) {
  108. memsize += 20;
  109. font_descriptions = G_realloc(font_descriptions,
  110. memsize * sizeof(struct font_desc));
  111. }
  112. font_descriptions[num_descriptions].filename = G_store(name);
  113. font_descriptions[num_descriptions].description =
  114. G_store(description);
  115. num_descriptions++;
  116. }
  117. fclose(fp);
  118. return (num_descriptions > 0);
  119. }
  120. /**
  121. * \brief Returns the descriptive name corresponding to a stroke font
  122. *
  123. * Searches through the static font_descriptions name for a descriptive
  124. * name matching the filename passed to the function. If a match is found,
  125. * the descriptive name is returned; otherwise the filename that was
  126. * originally passed is returned.
  127. *
  128. * \param filename Filename of stroke font
  129. *
  130. * \return Const string containing descriptive name for the font
  131. **/
  132. static const char *get_desc(const char *filename)
  133. {
  134. int i;
  135. for (i = 0; i < num_descriptions; i++)
  136. if (G_strcasecmp(filename, font_descriptions[i].filename) == 0)
  137. return font_descriptions[i].description;
  138. /* If there was no font descriptions file, or the filename wasn't found
  139. * in it, we'll end up here and simply return the filename for the
  140. * description */
  141. return filename;
  142. }
  143. /**
  144. * \brief Frees the memory used by the table of font descriptive names
  145. **/
  146. static void free_font_descriptions(void)
  147. {
  148. int i;
  149. for (i = 0; i < num_descriptions; i++) {
  150. G_free(font_descriptions[i].filename);
  151. G_free(font_descriptions[i].description);
  152. }
  153. return;
  154. }