[hb-cairo] Make hb_cairo_glyphs_from_buffer public
This commit is contained in:
parent
bf52386cfa
commit
20a50acc91
125
src/hb-cairo.cc
125
src/hb-cairo.cc
|
@ -30,6 +30,8 @@
|
|||
|
||||
#include "hb-cairo-utils.hh"
|
||||
|
||||
#include "hb-utf.hh"
|
||||
|
||||
static void
|
||||
move_to (hb_draw_funcs_t *dfuncs,
|
||||
cairo_t *cr,
|
||||
|
@ -395,3 +397,126 @@ hb_cairo_font_face_get_font (cairo_font_face_t *font_face)
|
|||
{
|
||||
return (hb_font_t *) cairo_font_face_get_user_data (font_face, &hb_cairo_font_user_data_key);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
hb_cairo_glyphs_from_buffer (hb_buffer_t *buffer,
|
||||
const char *text,
|
||||
int text_len,
|
||||
hb_bool_t utf8_clusters,
|
||||
int scale_factor,
|
||||
cairo_glyph_t **glyphs,
|
||||
unsigned int *num_glyphs,
|
||||
cairo_text_cluster_t **clusters,
|
||||
unsigned int *num_clusters,
|
||||
cairo_text_cluster_flags_t *cluster_flags)
|
||||
{
|
||||
if (text && text_len < 0)
|
||||
text_len = strlen (text);
|
||||
|
||||
*num_glyphs = hb_buffer_get_length (buffer);
|
||||
hb_glyph_info_t *hb_glyph = hb_buffer_get_glyph_infos (buffer, nullptr);
|
||||
hb_glyph_position_t *hb_position = hb_buffer_get_glyph_positions (buffer, nullptr);
|
||||
*glyphs = cairo_glyph_allocate (*num_glyphs + 1);
|
||||
|
||||
if (text)
|
||||
{
|
||||
*num_clusters = *num_glyphs ? 1 : 0;
|
||||
for (unsigned int i = 1; i < *num_glyphs; i++)
|
||||
if (hb_glyph[i].cluster != hb_glyph[i-1].cluster)
|
||||
(*num_clusters)++;
|
||||
*clusters = cairo_text_cluster_allocate (*num_clusters);
|
||||
}
|
||||
else if (clusters)
|
||||
{
|
||||
*clusters = nullptr;
|
||||
*num_clusters = 0;
|
||||
*cluster_flags = (cairo_text_cluster_flags_t) 0;
|
||||
}
|
||||
|
||||
if ((*num_glyphs && !*glyphs) ||
|
||||
(clusters && *num_clusters && !*clusters))
|
||||
{
|
||||
if (*glyphs)
|
||||
{
|
||||
cairo_glyph_free (*glyphs);
|
||||
*glyphs = nullptr;
|
||||
*num_glyphs = 0;
|
||||
}
|
||||
if (clusters && *clusters)
|
||||
{
|
||||
cairo_text_cluster_free (*clusters);
|
||||
*clusters = nullptr;
|
||||
*num_clusters = 0;
|
||||
*cluster_flags = (cairo_text_cluster_flags_t) 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
double iscale = scale_factor ? 1. / scale_factor : 0.;
|
||||
hb_position_t x = 0, y = 0;
|
||||
int i;
|
||||
for (i = 0; i < (int) *num_glyphs; i++)
|
||||
{
|
||||
(*glyphs)[i].index = hb_glyph[i].codepoint;
|
||||
(*glyphs)[i].x = (+hb_position->x_offset + x) * iscale;
|
||||
(*glyphs)[i].y = (-hb_position->y_offset + y) * iscale;
|
||||
x += hb_position->x_advance;
|
||||
y += -hb_position->y_advance;
|
||||
|
||||
hb_position++;
|
||||
}
|
||||
(*glyphs)[i].index = -1;
|
||||
(*glyphs)[i].x = x * iscale;
|
||||
(*glyphs)[i].y = y * iscale;
|
||||
|
||||
if (*num_clusters)
|
||||
{
|
||||
memset ((void *) *clusters, 0, *num_clusters * sizeof ((*clusters)[0]));
|
||||
hb_bool_t backward = HB_DIRECTION_IS_BACKWARD (hb_buffer_get_direction (buffer));
|
||||
*cluster_flags = backward ? CAIRO_TEXT_CLUSTER_FLAG_BACKWARD : (cairo_text_cluster_flags_t) 0;
|
||||
unsigned int cluster = 0;
|
||||
const char *start = text, *end;
|
||||
(*clusters)[cluster].num_glyphs++;
|
||||
if (backward)
|
||||
{
|
||||
for (i = *num_glyphs - 2; i >= 0; i--)
|
||||
{
|
||||
if (hb_glyph[i].cluster != hb_glyph[i+1].cluster)
|
||||
{
|
||||
assert (hb_glyph[i].cluster > hb_glyph[i+1].cluster);
|
||||
if (utf8_clusters)
|
||||
end = start + hb_glyph[i].cluster - hb_glyph[i+1].cluster;
|
||||
else
|
||||
end = (const char *) hb_utf_offset_to_pointer<hb_utf8_t> ((const uint8_t *) start,
|
||||
(signed) (hb_glyph[i].cluster - hb_glyph[i+1].cluster));
|
||||
(*clusters)[cluster].num_bytes = end - start;
|
||||
start = end;
|
||||
cluster++;
|
||||
}
|
||||
(*clusters)[cluster].num_glyphs++;
|
||||
}
|
||||
(*clusters)[cluster].num_bytes = text + text_len - start;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 1; i < (int) *num_glyphs; i++)
|
||||
{
|
||||
if (hb_glyph[i].cluster != hb_glyph[i-1].cluster)
|
||||
{
|
||||
assert (hb_glyph[i].cluster > hb_glyph[i-1].cluster);
|
||||
if (utf8_clusters)
|
||||
end = start + hb_glyph[i].cluster - hb_glyph[i-1].cluster;
|
||||
else
|
||||
end = (const char *) hb_utf_offset_to_pointer<hb_utf8_t> ((const uint8_t *) start,
|
||||
(signed) (hb_glyph[i].cluster - hb_glyph[i-1].cluster));
|
||||
(*clusters)[cluster].num_bytes = end - start;
|
||||
start = end;
|
||||
cluster++;
|
||||
}
|
||||
(*clusters)[cluster].num_glyphs++;
|
||||
}
|
||||
(*clusters)[cluster].num_bytes = text + text_len - start;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,6 +39,18 @@ hb_cairo_font_face_create (hb_font_t *font);
|
|||
HB_EXTERN hb_font_t *
|
||||
hb_cairo_font_face_get_font (cairo_font_face_t *font_face);
|
||||
|
||||
HB_EXTERN void
|
||||
hb_cairo_glyphs_from_buffer (hb_buffer_t *buffer,
|
||||
const char *text,
|
||||
int text_len,
|
||||
hb_bool_t utf8_clusters,
|
||||
int scale_factor,
|
||||
cairo_glyph_t **glyphs,
|
||||
unsigned int *num_glyphs,
|
||||
cairo_text_cluster_t **clusters,
|
||||
unsigned int *num_clusters,
|
||||
cairo_text_cluster_flags_t *cluster_flags);
|
||||
|
||||
HB_END_DECLS
|
||||
|
||||
#endif /* HB_CAIRO_H */
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
struct hb_utf8_t
|
||||
{
|
||||
typedef uint8_t codepoint_t;
|
||||
static constexpr unsigned max_len = 4;
|
||||
|
||||
static const codepoint_t *
|
||||
next (const codepoint_t *text,
|
||||
|
@ -182,6 +183,7 @@ struct hb_utf16_xe_t
|
|||
{
|
||||
static_assert (sizeof (TCodepoint) == 2, "");
|
||||
typedef TCodepoint codepoint_t;
|
||||
static constexpr unsigned max_len = 2;
|
||||
|
||||
static const codepoint_t *
|
||||
next (const codepoint_t *text,
|
||||
|
@ -290,6 +292,7 @@ struct hb_utf32_xe_t
|
|||
{
|
||||
static_assert (sizeof (TCodepoint) == 4, "");
|
||||
typedef TCodepoint codepoint_t;
|
||||
static constexpr unsigned max_len = 1;
|
||||
|
||||
static const TCodepoint *
|
||||
next (const TCodepoint *text,
|
||||
|
@ -348,6 +351,7 @@ typedef hb_utf32_xe_t<uint32_t, false> hb_utf32_novalidate_t;
|
|||
struct hb_latin1_t
|
||||
{
|
||||
typedef uint8_t codepoint_t;
|
||||
static constexpr unsigned max_len = 1;
|
||||
|
||||
static const codepoint_t *
|
||||
next (const codepoint_t *text,
|
||||
|
@ -399,12 +403,13 @@ struct hb_latin1_t
|
|||
struct hb_ascii_t
|
||||
{
|
||||
typedef uint8_t codepoint_t;
|
||||
static constexpr unsigned max_len = 1;
|
||||
|
||||
static const codepoint_t *
|
||||
next (const codepoint_t *text,
|
||||
const codepoint_t *end HB_UNUSED,
|
||||
hb_codepoint_t *unicode,
|
||||
hb_codepoint_t replacement HB_UNUSED)
|
||||
hb_codepoint_t replacement)
|
||||
{
|
||||
*unicode = *text++;
|
||||
if (*unicode >= 0x0080u)
|
||||
|
@ -450,4 +455,27 @@ struct hb_ascii_t
|
|||
}
|
||||
};
|
||||
|
||||
template <typename utf_t>
|
||||
static inline const typename utf_t::codepoint_t *
|
||||
hb_utf_offset_to_pointer (const typename utf_t::codepoint_t *start,
|
||||
signed offset)
|
||||
{
|
||||
hb_codepoint_t unicode;
|
||||
|
||||
while (offset-- > 0)
|
||||
start = utf_t::next (start,
|
||||
start + utf_t::max_len,
|
||||
&unicode,
|
||||
HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT);
|
||||
|
||||
while (offset++ < 0)
|
||||
start = utf_t::prev (start,
|
||||
start - utf_t::max_len,
|
||||
&unicode,
|
||||
HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT);
|
||||
|
||||
return start;
|
||||
}
|
||||
|
||||
|
||||
#endif /* HB_UTF_HH */
|
||||
|
|
|
@ -592,127 +592,6 @@ struct helper_cairo_line_t {
|
|||
}
|
||||
};
|
||||
|
||||
static inline void
|
||||
hb_cairo_glyphs_from_buffer (hb_buffer_t *buffer,
|
||||
const char *text,
|
||||
int text_len,
|
||||
hb_bool_t utf8_clusters,
|
||||
int scale,
|
||||
cairo_glyph_t **glyphs,
|
||||
unsigned int *num_glyphs,
|
||||
cairo_text_cluster_t **clusters,
|
||||
unsigned int *num_clusters,
|
||||
cairo_text_cluster_flags_t *cluster_flags)
|
||||
{
|
||||
if (text && text_len < 0)
|
||||
text_len = strlen (text);
|
||||
|
||||
*num_glyphs = hb_buffer_get_length (buffer);
|
||||
hb_glyph_info_t *hb_glyph = hb_buffer_get_glyph_infos (buffer, nullptr);
|
||||
hb_glyph_position_t *hb_position = hb_buffer_get_glyph_positions (buffer, nullptr);
|
||||
*glyphs = cairo_glyph_allocate (*num_glyphs + 1);
|
||||
|
||||
if (text)
|
||||
{
|
||||
*num_clusters = *num_glyphs ? 1 : 0;
|
||||
for (unsigned int i = 1; i < *num_glyphs; i++)
|
||||
if (hb_glyph[i].cluster != hb_glyph[i-1].cluster)
|
||||
(*num_clusters)++;
|
||||
*clusters = cairo_text_cluster_allocate (*num_clusters);
|
||||
}
|
||||
else if (clusters)
|
||||
{
|
||||
*clusters = nullptr;
|
||||
*num_clusters = 0;
|
||||
*cluster_flags = (cairo_text_cluster_flags_t) 0;
|
||||
}
|
||||
|
||||
if ((*num_glyphs && !*glyphs) ||
|
||||
(clusters && *num_clusters && !*clusters))
|
||||
{
|
||||
if (*glyphs)
|
||||
{
|
||||
cairo_glyph_free (*glyphs);
|
||||
*glyphs = nullptr;
|
||||
*num_glyphs = 0;
|
||||
}
|
||||
if (clusters && *clusters)
|
||||
{
|
||||
cairo_text_cluster_free (*clusters);
|
||||
*clusters = nullptr;
|
||||
*num_clusters = 0;
|
||||
*cluster_flags = (cairo_text_cluster_flags_t) 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
double iscale = scale ? 1. / scale : 0.;
|
||||
hb_position_t x = 0, y = 0;
|
||||
int i;
|
||||
for (i = 0; i < (int) *num_glyphs; i++)
|
||||
{
|
||||
(*glyphs)[i].index = hb_glyph[i].codepoint;
|
||||
(*glyphs)[i].x = (+hb_position->x_offset + x) * iscale;
|
||||
(*glyphs)[i].y = (-hb_position->y_offset + y) * iscale;
|
||||
x += hb_position->x_advance;
|
||||
y += -hb_position->y_advance;
|
||||
|
||||
hb_position++;
|
||||
}
|
||||
(*glyphs)[i].index = -1;
|
||||
(*glyphs)[i].x = x * iscale;
|
||||
(*glyphs)[i].y = y * iscale;
|
||||
|
||||
if (*num_clusters)
|
||||
{
|
||||
memset ((void *) *clusters, 0, *num_clusters * sizeof ((*clusters)[0]));
|
||||
hb_bool_t backward = HB_DIRECTION_IS_BACKWARD (hb_buffer_get_direction (buffer));
|
||||
*cluster_flags = backward ? CAIRO_TEXT_CLUSTER_FLAG_BACKWARD : (cairo_text_cluster_flags_t) 0;
|
||||
unsigned int cluster = 0;
|
||||
const char *start = text, *end;
|
||||
(*clusters)[cluster].num_glyphs++;
|
||||
if (backward)
|
||||
{
|
||||
for (i = *num_glyphs - 2; i >= 0; i--)
|
||||
{
|
||||
if (hb_glyph[i].cluster != hb_glyph[i+1].cluster)
|
||||
{
|
||||
assert (hb_glyph[i].cluster > hb_glyph[i+1].cluster);
|
||||
if (utf8_clusters)
|
||||
end = start + hb_glyph[i].cluster - hb_glyph[i+1].cluster;
|
||||
else
|
||||
end = g_utf8_offset_to_pointer (start, hb_glyph[i].cluster - hb_glyph[i+1].cluster);
|
||||
(*clusters)[cluster].num_bytes = end - start;
|
||||
start = end;
|
||||
cluster++;
|
||||
}
|
||||
(*clusters)[cluster].num_glyphs++;
|
||||
}
|
||||
(*clusters)[cluster].num_bytes = text + text_len - start;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 1; i < (int) *num_glyphs; i++)
|
||||
{
|
||||
if (hb_glyph[i].cluster != hb_glyph[i-1].cluster)
|
||||
{
|
||||
assert (hb_glyph[i].cluster > hb_glyph[i-1].cluster);
|
||||
if (utf8_clusters)
|
||||
end = start + hb_glyph[i].cluster - hb_glyph[i-1].cluster;
|
||||
else
|
||||
end = g_utf8_offset_to_pointer (start, hb_glyph[i].cluster - hb_glyph[i-1].cluster);
|
||||
(*clusters)[cluster].num_bytes = end - start;
|
||||
start = end;
|
||||
cluster++;
|
||||
}
|
||||
(*clusters)[cluster].num_glyphs++;
|
||||
}
|
||||
(*clusters)[cluster].num_bytes = text + text_len - start;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
helper_cairo_line_from_buffer (helper_cairo_line_t *l,
|
||||
hb_buffer_t *buffer,
|
||||
|
|
Loading…
Reference in New Issue