Text.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. #include <grass/glocale.h>
  2. #include "cairodriver.h"
  3. #ifdef HAVE_ICONV_H
  4. #include <iconv.h>
  5. #endif
  6. static cairo_matrix_t mat;
  7. static char *convert(const char *in)
  8. {
  9. size_t ilen, olen;
  10. char *out;
  11. ilen = strlen(in);
  12. olen = 3 * ilen + 1;
  13. out = G_malloc(olen);
  14. #ifdef HAVE_ICONV_H
  15. {
  16. char *p1 = (char *) in;
  17. char *p2 = out;
  18. size_t ret;
  19. iconv_t cd;
  20. if (!encoding)
  21. encoding = G_store("US-ASCII");
  22. if ((cd = iconv_open("UTF-8", encoding)) < 0)
  23. G_fatal_error(_("Unable to convert from <%s> to UTF-8"));
  24. ret = iconv(cd, &p1, &ilen, &p2, &olen);
  25. iconv_close(cd);
  26. *p2++ = '\0';
  27. if (ret > 0)
  28. G_warning(_("Some characters could not be converted to UTF-8"));
  29. }
  30. #else
  31. {
  32. const unsigned char *p1 = (const unsigned char *) in;
  33. unsigned char *p2 = (unsigned char *) out;
  34. int i, j;
  35. for (i = j = 0; i < len; i++) {
  36. int c = p1[i];
  37. if (c < 0x80)
  38. p2[j++] = c;
  39. else {
  40. p2[j++] = 0xC0 + (c >> 6);
  41. p2[j++] = 0x80 + (c & 0x3F);
  42. }
  43. }
  44. p2[j++] = '\0';
  45. }
  46. #endif
  47. return out;
  48. }
  49. static void set_matrix(void)
  50. {
  51. if (matrix_valid)
  52. return;
  53. cairo_matrix_init_identity(&mat);
  54. cairo_matrix_scale(&mat, text_size_x * 25, text_size_y * 25);
  55. cairo_matrix_rotate(&mat, -text_rotation * M_PI / 180);
  56. cairo_set_font_matrix(cairo, &mat);
  57. matrix_valid = 1;
  58. }
  59. void Cairo_draw_text(const char *str)
  60. {
  61. char *utf8 = convert(str);
  62. if (!utf8)
  63. return;
  64. set_matrix();
  65. cairo_move_to(cairo, cur_x, cur_y);
  66. cairo_show_text(cairo, utf8);
  67. G_free(utf8);
  68. modified = 1;
  69. }
  70. void Cairo_text_box(const char *str, double *t, double *b, double *l, double *r)
  71. {
  72. char *utf8 = convert(str);
  73. cairo_text_extents_t ext;
  74. if (!utf8)
  75. return;
  76. set_matrix();
  77. cairo_text_extents(cairo, utf8, &ext);
  78. G_free(utf8);
  79. *l = cur_x + ext.x_bearing;
  80. *r = cur_x + ext.x_bearing + ext.width;
  81. *t = cur_x + ext.y_bearing;
  82. *b = cur_x + ext.y_bearing + ext.height;
  83. }
  84. void Cairo_set_font(const char *name)
  85. {
  86. char *font = G_store(name);
  87. cairo_font_weight_t weight = CAIRO_FONT_WEIGHT_NORMAL;
  88. cairo_font_slant_t slant = CAIRO_FONT_SLANT_NORMAL;
  89. for (;;) {
  90. char *p = strrchr(font, '-');
  91. if (!p)
  92. break;
  93. if (G_strcasecmp(p, "-bold") == 0)
  94. weight = CAIRO_FONT_WEIGHT_BOLD;
  95. else if (strcasecmp(p, "-italic") == 0)
  96. slant = CAIRO_FONT_SLANT_ITALIC;
  97. else if (G_strcasecmp(p, "-oblique") == 0)
  98. slant = CAIRO_FONT_SLANT_OBLIQUE;
  99. else
  100. break;
  101. *p = '\0';
  102. }
  103. cairo_select_font_face(cairo, font, slant, weight);
  104. G_free(font);
  105. }
  106. void Cairo_set_encoding(const char *enc)
  107. {
  108. if (encoding)
  109. G_free(encoding);
  110. encoding = G_store(enc);
  111. }
  112. void Cairo_text_size(double width, double height)
  113. {
  114. text_size_x = width;
  115. text_size_y = height;
  116. matrix_valid = 0;
  117. }
  118. void Cairo_text_rotation(double angle)
  119. {
  120. text_rotation = angle;
  121. matrix_valid = 0;
  122. }
  123. void Cairo_font_list(char ***list, int *count)
  124. {
  125. char **fonts;
  126. int num_fonts;
  127. num_fonts = 1;
  128. fonts = G_malloc(num_fonts * sizeof(char *));
  129. fonts[0] = G_store("serif");
  130. *list = fonts;
  131. *count = num_fonts;
  132. }
  133. void Cairo_font_info(char ***list, int *count)
  134. {
  135. char **fonts;
  136. int num_fonts;
  137. num_fonts = 1;
  138. fonts = G_malloc(num_fonts * sizeof(char *));
  139. fonts[0] = G_store("serif|serif|1||0|utf-8|");
  140. *list = fonts;
  141. *count = num_fonts;
  142. }