[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-cairo-utils.hh"
|
||||||
|
|
||||||
|
#include "hb-utf.hh"
|
||||||
|
|
||||||
static void
|
static void
|
||||||
move_to (hb_draw_funcs_t *dfuncs,
|
move_to (hb_draw_funcs_t *dfuncs,
|
||||||
cairo_t *cr,
|
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);
|
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_EXTERN hb_font_t *
|
||||||
hb_cairo_font_face_get_font (cairo_font_face_t *font_face);
|
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
|
HB_END_DECLS
|
||||||
|
|
||||||
#endif /* HB_CAIRO_H */
|
#endif /* HB_CAIRO_H */
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
struct hb_utf8_t
|
struct hb_utf8_t
|
||||||
{
|
{
|
||||||
typedef uint8_t codepoint_t;
|
typedef uint8_t codepoint_t;
|
||||||
|
static constexpr unsigned max_len = 4;
|
||||||
|
|
||||||
static const codepoint_t *
|
static const codepoint_t *
|
||||||
next (const codepoint_t *text,
|
next (const codepoint_t *text,
|
||||||
|
@ -182,6 +183,7 @@ struct hb_utf16_xe_t
|
||||||
{
|
{
|
||||||
static_assert (sizeof (TCodepoint) == 2, "");
|
static_assert (sizeof (TCodepoint) == 2, "");
|
||||||
typedef TCodepoint codepoint_t;
|
typedef TCodepoint codepoint_t;
|
||||||
|
static constexpr unsigned max_len = 2;
|
||||||
|
|
||||||
static const codepoint_t *
|
static const codepoint_t *
|
||||||
next (const codepoint_t *text,
|
next (const codepoint_t *text,
|
||||||
|
@ -290,6 +292,7 @@ struct hb_utf32_xe_t
|
||||||
{
|
{
|
||||||
static_assert (sizeof (TCodepoint) == 4, "");
|
static_assert (sizeof (TCodepoint) == 4, "");
|
||||||
typedef TCodepoint codepoint_t;
|
typedef TCodepoint codepoint_t;
|
||||||
|
static constexpr unsigned max_len = 1;
|
||||||
|
|
||||||
static const TCodepoint *
|
static const TCodepoint *
|
||||||
next (const TCodepoint *text,
|
next (const TCodepoint *text,
|
||||||
|
@ -348,6 +351,7 @@ typedef hb_utf32_xe_t<uint32_t, false> hb_utf32_novalidate_t;
|
||||||
struct hb_latin1_t
|
struct hb_latin1_t
|
||||||
{
|
{
|
||||||
typedef uint8_t codepoint_t;
|
typedef uint8_t codepoint_t;
|
||||||
|
static constexpr unsigned max_len = 1;
|
||||||
|
|
||||||
static const codepoint_t *
|
static const codepoint_t *
|
||||||
next (const codepoint_t *text,
|
next (const codepoint_t *text,
|
||||||
|
@ -399,12 +403,13 @@ struct hb_latin1_t
|
||||||
struct hb_ascii_t
|
struct hb_ascii_t
|
||||||
{
|
{
|
||||||
typedef uint8_t codepoint_t;
|
typedef uint8_t codepoint_t;
|
||||||
|
static constexpr unsigned max_len = 1;
|
||||||
|
|
||||||
static const codepoint_t *
|
static const codepoint_t *
|
||||||
next (const codepoint_t *text,
|
next (const codepoint_t *text,
|
||||||
const codepoint_t *end HB_UNUSED,
|
const codepoint_t *end HB_UNUSED,
|
||||||
hb_codepoint_t *unicode,
|
hb_codepoint_t *unicode,
|
||||||
hb_codepoint_t replacement HB_UNUSED)
|
hb_codepoint_t replacement)
|
||||||
{
|
{
|
||||||
*unicode = *text++;
|
*unicode = *text++;
|
||||||
if (*unicode >= 0x0080u)
|
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 */
|
#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
|
static inline void
|
||||||
helper_cairo_line_from_buffer (helper_cairo_line_t *l,
|
helper_cairo_line_from_buffer (helper_cairo_line_t *l,
|
||||||
hb_buffer_t *buffer,
|
hb_buffer_t *buffer,
|
||||||
|
|
Loading…
Reference in New Issue