bitmap-font.c 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. /*
  2. * Copyright © 2005 Red Hat, Inc.
  3. *
  4. * Permission to use, copy, modify, distribute, and sell this software
  5. * and its documentation for any purpose is hereby granted without
  6. * fee, provided that the above copyright notice appear in all copies
  7. * and that both that copyright notice and this permission notice
  8. * appear in supporting documentation, and that the name of
  9. * Red Hat, Inc. not be used in advertising or publicity pertaining to
  10. * distribution of the software without specific, written prior
  11. * permission. Red Hat, Inc. makes no representations about the
  12. * suitability of this software for any purpose. It is provided "as
  13. * is" without express or implied warranty.
  14. *
  15. * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
  16. * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
  17. * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
  18. * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
  19. * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  20. * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
  21. * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  22. *
  23. * Author: Carl D. Worth <cworth@cworth.org>
  24. */
  25. #include "cairo-test.h"
  26. #include <sys/types.h>
  27. #include <sys/stat.h>
  28. #include <unistd.h>
  29. #include <cairo-ft.h>
  30. #include <fontconfig/fontconfig.h>
  31. #include <fontconfig/fcfreetype.h>
  32. #define FONT "6x13.pcf"
  33. #define TEXT_SIZE 13
  34. static cairo_bool_t
  35. font_extents_equal (const cairo_font_extents_t *A,
  36. const cairo_font_extents_t *B)
  37. {
  38. return
  39. CAIRO_TEST_DOUBLE_EQUALS (A->ascent, B->ascent) &&
  40. CAIRO_TEST_DOUBLE_EQUALS (A->descent, B->descent) &&
  41. CAIRO_TEST_DOUBLE_EQUALS (A->height, B->height) &&
  42. CAIRO_TEST_DOUBLE_EQUALS (A->max_x_advance, B->max_x_advance) &&
  43. CAIRO_TEST_DOUBLE_EQUALS (A->max_y_advance, B->max_y_advance);
  44. }
  45. static cairo_test_status_t
  46. check_font_extents (const cairo_test_context_t *ctx, cairo_t *cr, const char *comment)
  47. {
  48. cairo_font_extents_t font_extents, ref_font_extents = {11, 2, 13, 6, 0};
  49. cairo_status_t status;
  50. memset (&font_extents, 0xff, sizeof (cairo_font_extents_t));
  51. cairo_font_extents (cr, &font_extents);
  52. status = cairo_status (cr);
  53. if (status)
  54. return cairo_test_status_from_status (ctx, status);
  55. if (! font_extents_equal (&font_extents, &ref_font_extents)) {
  56. cairo_test_log (ctx, "Error: %s: cairo_font_extents(); extents (%g, %g, %g, %g, %g)\n",
  57. comment,
  58. font_extents.ascent, font_extents.descent,
  59. font_extents.height,
  60. font_extents.max_x_advance, font_extents.max_y_advance);
  61. return CAIRO_TEST_FAILURE;
  62. }
  63. return CAIRO_TEST_SUCCESS;
  64. }
  65. static cairo_test_status_t
  66. draw (cairo_t *cr, int width, int height)
  67. {
  68. const cairo_test_context_t *ctx = cairo_test_get_context (cr);
  69. FcPattern *pattern;
  70. cairo_font_face_t *font_face;
  71. cairo_font_extents_t font_extents;
  72. cairo_font_options_t *font_options;
  73. cairo_status_t status;
  74. char *filename;
  75. int face_count;
  76. struct stat stat_buf;
  77. xasprintf (&filename, "%s/%s", ctx->srcdir, FONT);
  78. if (stat (filename, &stat_buf) || ! S_ISREG (stat_buf.st_mode)) {
  79. cairo_test_log (ctx, "Error finding font: %s: file not found?\n", filename);
  80. return CAIRO_TEST_FAILURE;
  81. }
  82. pattern = FcFreeTypeQuery ((unsigned char *)filename, 0, NULL, &face_count);
  83. if (! pattern) {
  84. cairo_test_log (ctx, "FcFreeTypeQuery failed.\n");
  85. free (filename);
  86. return cairo_test_status_from_status (ctx, CAIRO_STATUS_NO_MEMORY);
  87. }
  88. font_face = cairo_ft_font_face_create_for_pattern (pattern);
  89. FcPatternDestroy (pattern);
  90. status = cairo_font_face_status (font_face);
  91. if (status) {
  92. cairo_test_log (ctx, "Error creating font face for %s: %s\n",
  93. filename,
  94. cairo_status_to_string (status));
  95. free (filename);
  96. return cairo_test_status_from_status (ctx, status);
  97. }
  98. free (filename);
  99. if (cairo_font_face_get_type (font_face) != CAIRO_FONT_TYPE_FT) {
  100. cairo_test_log (ctx, "Unexpected value from cairo_font_face_get_type: %d (expected %d)\n",
  101. cairo_font_face_get_type (font_face), CAIRO_FONT_TYPE_FT);
  102. cairo_font_face_destroy (font_face);
  103. return CAIRO_TEST_FAILURE;
  104. }
  105. cairo_set_font_face (cr, font_face);
  106. cairo_font_face_destroy (font_face);
  107. cairo_set_font_size (cr, 13);
  108. font_options = cairo_font_options_create ();
  109. #define CHECK_FONT_EXTENTS(comment) do {\
  110. cairo_test_status_t test_status; \
  111. test_status = check_font_extents (ctx, cr, (comment)); \
  112. if (test_status != CAIRO_TEST_SUCCESS) { \
  113. cairo_font_options_destroy (font_options); \
  114. return test_status; \
  115. } \
  116. } while (0)
  117. cairo_font_extents (cr, &font_extents);
  118. CHECK_FONT_EXTENTS ("default");
  119. cairo_font_options_set_hint_metrics (font_options, CAIRO_HINT_METRICS_ON);
  120. cairo_set_font_options (cr, font_options);
  121. CHECK_FONT_EXTENTS ("HINT_METRICS_ON");
  122. cairo_move_to (cr, 1, font_extents.ascent - 1);
  123. cairo_set_source_rgb (cr, 0.0, 0.0, 1.0); /* blue */
  124. cairo_font_options_set_hint_style (font_options, CAIRO_HINT_STYLE_NONE);
  125. cairo_set_font_options (cr, font_options);
  126. CHECK_FONT_EXTENTS ("HINT_METRICS_ON HINT_STYLE_NONE");
  127. cairo_show_text (cr, "the ");
  128. cairo_font_options_set_hint_style (font_options, CAIRO_HINT_STYLE_SLIGHT);
  129. cairo_set_font_options (cr, font_options);
  130. CHECK_FONT_EXTENTS ("HINT_METRICS_ON HINT_STYLE_SLIGHT");
  131. cairo_show_text (cr, "quick ");
  132. cairo_font_options_set_hint_style (font_options, CAIRO_HINT_STYLE_MEDIUM);
  133. cairo_set_font_options (cr, font_options);
  134. CHECK_FONT_EXTENTS ("HINT_METRICS_ON HINT_STYLE_MEDIUM");
  135. cairo_show_text (cr, "brown");
  136. cairo_font_options_set_hint_style (font_options, CAIRO_HINT_STYLE_FULL);
  137. cairo_set_font_options (cr, font_options);
  138. CHECK_FONT_EXTENTS ("HINT_METRICS_ON HINT_STYLE_FULL");
  139. cairo_show_text (cr, " fox");
  140. /* Switch from show_text to text_path/fill to exercise bug #7889 */
  141. cairo_text_path (cr, " jumps over a lazy dog");
  142. cairo_fill (cr);
  143. /* And test it rotated as well for the sake of bug #7888 */
  144. cairo_translate (cr, width, height);
  145. cairo_rotate (cr, M_PI);
  146. cairo_font_options_set_hint_style (font_options, CAIRO_HINT_STYLE_DEFAULT);
  147. cairo_font_options_set_hint_metrics (font_options, CAIRO_HINT_METRICS_OFF);
  148. cairo_set_font_options (cr, font_options);
  149. CHECK_FONT_EXTENTS ("HINT_METRICS_OFF");
  150. cairo_move_to (cr, 1, font_extents.height - font_extents.descent - 1);
  151. cairo_font_options_set_hint_style (font_options, CAIRO_HINT_STYLE_NONE);
  152. cairo_set_font_options (cr, font_options);
  153. CHECK_FONT_EXTENTS ("HINT_METRICS_OFF HINT_STYLE_NONE");
  154. cairo_show_text (cr, "the ");
  155. cairo_font_options_set_hint_style (font_options, CAIRO_HINT_STYLE_SLIGHT);
  156. cairo_set_font_options (cr, font_options);
  157. CHECK_FONT_EXTENTS ("HINT_METRICS_OFF HINT_STYLE_SLIGHT");
  158. cairo_show_text (cr, "quick");
  159. cairo_font_options_set_hint_style (font_options, CAIRO_HINT_STYLE_MEDIUM);
  160. cairo_set_font_options (cr, font_options);
  161. CHECK_FONT_EXTENTS ("HINT_METRICS_OFF HINT_STYLE_MEDIUM");
  162. cairo_show_text (cr, " brown");
  163. cairo_font_options_set_hint_style (font_options, CAIRO_HINT_STYLE_FULL);
  164. cairo_set_font_options (cr, font_options);
  165. CHECK_FONT_EXTENTS ("HINT_METRICS_OFF HINT_STYLE_FULL");
  166. cairo_show_text (cr, " fox");
  167. cairo_text_path (cr, " jumps over");
  168. cairo_text_path (cr, " a lazy dog");
  169. cairo_fill (cr);
  170. cairo_font_options_destroy (font_options);
  171. return CAIRO_TEST_SUCCESS;
  172. }
  173. CAIRO_TEST (bitmap_font,
  174. "Test drawing with a font consisting only of bitmaps"
  175. "\nThe PDF and PS backends embed a slightly distorted font for the rotated case.",
  176. "text", /* keywords */
  177. "ft", /* requirements */
  178. 246 + 1, 2 * TEXT_SIZE,
  179. NULL, draw)