hb-fc.cc 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. /*
  2. * Copyright © 2014 Google, Inc.
  3. *
  4. * This is part of HarfBuzz, a text shaping library.
  5. *
  6. * Permission is hereby granted, without written agreement and without
  7. * license or royalty fees, to use, copy, modify, and distribute this
  8. * software and its documentation for any purpose, provided that the
  9. * above copyright notice and the following two paragraphs appear in
  10. * all copies of this software.
  11. *
  12. * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
  13. * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
  14. * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
  15. * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
  16. * DAMAGE.
  17. *
  18. * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
  19. * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  20. * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
  21. * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
  22. * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  23. *
  24. * Google Author(s): Behdad Esfahbod
  25. */
  26. #include <stdlib.h>
  27. #include <stdio.h>
  28. #include "hb-fc.h"
  29. static hb_bool_t
  30. hb_fc_get_glyph (hb_font_t *font /*HB_UNUSED*/,
  31. void *font_data,
  32. hb_codepoint_t unicode,
  33. hb_codepoint_t variation_selector,
  34. hb_codepoint_t *glyph,
  35. void *user_data /*HB_UNUSED*/)
  36. {
  37. FcCharSet *cs = (FcCharSet *) font_data;
  38. if (variation_selector)
  39. {
  40. /* Fontconfig doesn't cache cmap-14 info. However:
  41. * 1. If the font maps the variation_selector, assume it's
  42. * supported,
  43. * 2. If the font doesn't map it, still say it's supported,
  44. * but return 0. This way, the caller will see the zero
  45. * and reject. If we return unsupported here, then the
  46. * variation selector will be hidden and ignored.
  47. */
  48. if (FcCharSetHasChar (cs, unicode) &&
  49. FcCharSetHasChar (cs, variation_selector))
  50. {
  51. unsigned int var_num = 0;
  52. if (variation_selector - 0xFE00u < 16)
  53. var_num = variation_selector - 0xFE00 + 1;
  54. else if (variation_selector - 0xE0100u < (256 - 16))
  55. var_num = variation_selector - 0xE0100 + 17;
  56. *glyph = (var_num << 21) | unicode;
  57. }
  58. else
  59. {
  60. *glyph = 0;
  61. }
  62. return true;
  63. }
  64. *glyph = FcCharSetHasChar (cs, unicode) ? unicode : 0;
  65. return *glyph != 0;
  66. }
  67. static hb_font_funcs_t *
  68. _hb_fc_get_font_funcs ()
  69. {
  70. static const hb_font_funcs_t *fc_ffuncs;
  71. const hb_font_funcs_t *ffuncs;
  72. if (!(ffuncs = fc_ffuncs))
  73. {
  74. hb_font_funcs_t *newfuncs = hb_font_funcs_create ();
  75. hb_font_funcs_set_glyph_func (newfuncs, hb_fc_get_glyph, nullptr, nullptr);
  76. /* XXX MT-unsafe */
  77. if (fc_ffuncs)
  78. hb_font_funcs_destroy (newfuncs);
  79. else
  80. fc_ffuncs = ffuncs = newfuncs;
  81. }
  82. return const_cast<hb_font_funcs_t *> (fc_ffuncs);
  83. }
  84. hb_font_t *
  85. hb_fc_font_create (FcPattern *fcfont)
  86. {
  87. static hb_face_t *face;
  88. hb_font_t *font;
  89. FcCharSet *cs;
  90. if (FcResultMatch != FcPatternGetCharSet (fcfont, FC_CHARSET, 0, &cs))
  91. return hb_font_get_empty ();
  92. if (!face) /* XXX MT-unsafe */
  93. face = hb_face_create (hb_blob_get_empty (), 0);
  94. font = hb_font_create (face);
  95. hb_font_set_funcs (font,
  96. _hb_fc_get_font_funcs (),
  97. FcCharSetCopy (cs),
  98. (hb_destroy_func_t) FcCharSetDestroy);
  99. return font;
  100. }
  101. hb_bool_t
  102. hb_fc_can_render (hb_font_t *font, const char *text)
  103. {
  104. static const char *ot[] = {"ot", nullptr};
  105. hb_buffer_t *buffer = hb_buffer_create ();
  106. hb_buffer_add_utf8 (buffer, text, -1, 0, -1);
  107. /* XXX Do we need this? I think Arabic and Hangul shapers are the
  108. * only one that make any use of this. The Hangul case is not really
  109. * needed, and for Arabic we'll miss a very narrow set of fonts.
  110. * Might be better to force generic shaper perhaps. */
  111. hb_buffer_guess_segment_properties (buffer);
  112. if (!hb_shape_full (font, buffer, nullptr, 0, ot))
  113. abort (); /* hb-ot shaper not enabled? */
  114. unsigned int len;
  115. hb_glyph_info_t *info = hb_buffer_get_glyph_infos (buffer, &len);
  116. for (unsigned int i = 0; i < len; i++)
  117. {
  118. if (!info[i].codepoint)
  119. {
  120. return false;
  121. }
  122. }
  123. return true;
  124. }