358 {
359 if (graphemes) {
360 graphemes->clear();
361 }
362
363
364
366 return false;
367 }
368
369
370 const char32 kDottedCircleGlyph = 9676;
371 bool bad_glyph = false;
372 PangoFontMap *font_map = pango_cairo_font_map_get_default();
373 PangoContext *context = pango_context_new();
374 pango_context_set_font_map(context, font_map);
375 PangoLayout *layout;
376 {
377
379 layout = pango_layout_new(context);
380 }
381 if (desc_) {
382 pango_layout_set_font_description(layout, desc_);
383 } else {
384 PangoFontDescription *desc = pango_font_description_from_string(
DescriptionName().c_str());
385 pango_layout_set_font_description(layout, desc);
386 pango_font_description_free(desc);
387 }
388 pango_layout_set_text(layout, utf8_word, len);
389 PangoLayoutIter *run_iter = nullptr;
390 {
392 run_iter = pango_layout_get_iter(layout);
393 }
394 do {
395 PangoLayoutRun *run = pango_layout_iter_get_run_readonly(run_iter);
396 if (!run) {
397 tlog(2,
"Found end of line nullptr run marker\n");
398 continue;
399 }
400 PangoGlyph dotted_circle_glyph;
401 PangoFont *font = run->item->analysis.font;
402
403 dotted_circle_glyph = get_glyph(font, kDottedCircleGlyph);
404
406 PangoFontDescription *desc = pango_font_describe(font);
407 char *desc_str = pango_font_description_to_string(desc);
408 tlog(2,
"Desc of font in run: %s\n", desc_str);
409 g_free(desc_str);
410 pango_font_description_free(desc);
411 }
412
413 PangoGlyphItemIter cluster_iter;
414 gboolean have_cluster;
415 for (have_cluster = pango_glyph_item_iter_init_start(&cluster_iter, run, utf8_word);
416 have_cluster && !bad_glyph;
417 have_cluster = pango_glyph_item_iter_next_cluster(&cluster_iter)) {
418 const int start_byte_index = cluster_iter.start_index;
419 const int end_byte_index = cluster_iter.end_index;
420 int start_glyph_index = cluster_iter.start_glyph;
421 int end_glyph_index = cluster_iter.end_glyph;
422 std::string cluster_text =
423 std::string(utf8_word + start_byte_index, end_byte_index - start_byte_index);
424 if (graphemes) {
425 graphemes->push_back(cluster_text);
426 }
428 tlog(2,
"Skipping whitespace\n");
429 continue;
430 }
432 printf("start_byte=%d end_byte=%d start_glyph=%d end_glyph=%d ", start_byte_index,
433 end_byte_index, start_glyph_index, end_glyph_index);
434 }
435 for (
int i = start_glyph_index, step = (end_glyph_index > start_glyph_index) ? 1 : -1;
436 !bad_glyph &&
i != end_glyph_index;
i += step) {
437 const bool unknown_glyph =
438 (cluster_iter.glyph_item->glyphs->glyphs[
i].glyph & PANGO_GLYPH_UNKNOWN_FLAG);
439 const bool illegal_glyph =
440 (cluster_iter.glyph_item->glyphs->glyphs[
i].glyph == dotted_circle_glyph);
441 bad_glyph = unknown_glyph || illegal_glyph;
443 printf(
"(%d=%d)", cluster_iter.glyph_item->glyphs->glyphs[
i].glyph, bad_glyph ? 1 : 0);
444 }
445 }
447 printf(" '%s'\n", cluster_text.c_str());
448 }
449 if (bad_glyph)
450 tlog(1,
"Found illegal glyph!\n");
451 }
452 } while (!bad_glyph && pango_layout_iter_next_run(run_iter));
453
454 pango_layout_iter_free(run_iter);
455 g_object_unref(context);
456 g_object_unref(layout);
457 if (bad_glyph && graphemes) {
458 graphemes->clear();
459 }
460 return !bad_glyph;
461}
#define DISABLE_HEAP_LEAK_CHECK
#define TLOG_IS_ON(level)
bool IsUTF8Whitespace(const char *text)
bool CoversUTF8Text(const char *utf8_text, int byte_length) const
std::string DescriptionName() const