Skip to content
This repository was archived by the owner on Aug 31, 2021. It is now read-only.

Commit ee299d1

Browse files
committed
[[ libgraphics ]] Add text shaping API to libgraphics & implement on Android
This patch adds types MCGGlyphInfo, MCGFontLayoutTextCallback and function MCGFontLayoutText to the libgraphics public header. These can then be used to retrieve glyph layout info for a block of text that will match the values used when measuring and rendering text with libgraphics. Also adds MCGFontLayoutText implementation on Android.
1 parent 1cf84c2 commit ee299d1

File tree

2 files changed

+73
-0
lines changed

2 files changed

+73
-0
lines changed

libgraphics/include/graphics.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -581,6 +581,23 @@ bool MCGFontGetPlatformFontList(MCProperListRef &r_fonts);
581581

582582
////////////////////////////////////////////////////////////////////////////////
583583

584+
struct MCGGlyphInfo
585+
{
586+
uindex_t codepoint;
587+
uindex_t cluster;
588+
589+
MCGFloat x_offset;
590+
MCGFloat y_offset;
591+
MCGFloat x_advance;
592+
MCGFloat y_advance;
593+
};
594+
595+
typedef bool (*MCGFontLayoutTextCallback)(void *context, const MCGFont &p_font, const MCGGlyphInfo *p_glyphs, uindex_t p_glyph_count, const unichar_t *p_chars, uindex_t p_char_count);
596+
597+
bool MCGFontLayoutText(const MCGFont &p_font, const unichar_t *p_text, uindex_t p_char_count, bool p_rtl, MCGFontLayoutTextCallback p_callback, void *p_context);
598+
599+
////////////////////////////////////////////////////////////////////////////////
600+
584601
inline bool MCGPointIsEqual(const MCGPoint &p_a, const MCGPoint &p_b)
585602
{
586603
return p_a.x == p_b.x && p_a.y == p_b.y;

libgraphics/src/harfbuzztext.cpp

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -654,6 +654,62 @@ bool MCGContextMeasurePlatformTextImageBounds(MCGContextRef self, const unichar_
654654
/* UNCHECKED */ MCHarfbuzzShape(p_text, p_length / 2, false, p_font, false, _measure_image_bounds_callback, &t_context);
655655

656656
r_bounds = MCGRectangleFromSkRect(t_context.bounds);
657+
657658
return true;
658659
}
659660

661+
////////////////////////////////////////////////////////////////////////////////
662+
663+
struct _layout_text_context_t
664+
{
665+
MCGFontLayoutTextCallback callback;
666+
void *context;
667+
const unichar_t *chars;
668+
bool success;
669+
};
670+
671+
static bool _layout_text_callback(void *context, const hb_glyph_info_t *p_infos, const hb_glyph_position_t *p_positions, uindex_t p_glyph_count, const unichar_t *p_chars, uindex_t p_char_count, const MCGFont &p_font)
672+
{
673+
_layout_text_context_t *self;
674+
self = (_layout_text_context_t*)context;
675+
676+
MCAutoArray<MCGGlyphInfo> t_info;
677+
if (!t_info.New(p_glyph_count))
678+
{
679+
self->success = false;
680+
return false;
681+
}
682+
683+
// Glyph cluster points to a char position in the original string
684+
// Calculate the offset of this substring so we can maintain the
685+
// relationship from glyph to char index
686+
uindex_t t_char_offset;
687+
t_char_offset = p_chars - self->chars;
688+
689+
for (uindex_t i = 0; i < p_glyph_count; i++)
690+
{
691+
t_info[i].codepoint = p_infos[i].codepoint;
692+
t_info[i].cluster = p_infos[i].cluster - t_char_offset;
693+
t_info[i].x_offset = (MCGFloat)p_positions[i].x_offset / (MCGFloat)HB_SCALE_FACTOR;
694+
t_info[i].y_offset = (MCGFloat)p_positions[i].y_offset / (MCGFloat)HB_SCALE_FACTOR;
695+
t_info[i].x_advance = (MCGFloat)p_positions[i].x_advance / (MCGFloat)HB_SCALE_FACTOR;
696+
t_info[i].y_advance = (MCGFloat)p_positions[i].y_advance / (MCGFloat)HB_SCALE_FACTOR;
697+
}
698+
699+
return self->callback(self->context, p_font, t_info.Ptr(), t_info.Size(), p_chars, p_char_count);
700+
}
701+
702+
bool MCGFontLayoutText(const MCGFont &p_font, const unichar_t *p_text, uindex_t p_char_count, bool p_rtl, MCGFontLayoutTextCallback p_callback, void *p_context)
703+
{
704+
_layout_text_context_t t_context;
705+
t_context.callback = p_callback;
706+
t_context.context = p_context;
707+
t_context.success = true;
708+
709+
bool t_success;
710+
t_success = MCHarfbuzzShape(p_text, p_char_count, p_rtl, p_font, false, _layout_text_callback, &t_context);
711+
return t_success && t_context.success;
712+
}
713+
714+
////////////////////////////////////////////////////////////////////////////////
715+

0 commit comments

Comments
 (0)