From 38706a0746822865008f810f9f577740c32580fa Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Sun, 28 Oct 2018 23:19:04 +0330 Subject: [PATCH] [ot-color] Preparation for setting PNG width/height in extents --- src/dump-emoji.cc | 7 +++-- src/hb-ot-color-sbix-table.hh | 52 +++++++++++++++++++++++++++++------ src/hb-ot-color.cc | 14 ++++------ src/hb-ot-font.cc | 7 ++++- 4 files changed, 59 insertions(+), 21 deletions(-) diff --git a/src/dump-emoji.cc b/src/dump-emoji.cc index 5cbf31abe..e3cabc738 100644 --- a/src/dump-emoji.cc +++ b/src/dump-emoji.cc @@ -69,12 +69,13 @@ sbix_dump (hb_face_t *face) for (unsigned int glyph_id = 0; glyph_id < num_glyphs; glyph_id++) { hb_blob_t *blob; - blob = sbix.reference_blob_for_glyph (glyph_id, 0, available_ppems[group], - HB_TAG('p','n','g',' ')); + unsigned int ppem = available_ppems[group]; + blob = sbix.reference_blob_for_glyph (glyph_id, ppem, ppem, + HB_TAG('p','n','g',' '), nullptr, nullptr); if (hb_blob_get_length (blob) == 0) continue; char output_path[255]; - sprintf (output_path, "out/sbix-%d-%d.png", available_ppems[group], glyph_id); + sprintf (output_path, "out/sbix-%d-%d.png", ppem, glyph_id); FILE *f = fopen (output_path, "wb"); unsigned int length; const char* data = hb_blob_get_data (blob, &length); diff --git a/src/hb-ot-color-sbix-table.hh b/src/hb-ot-color-sbix-table.hh index a5bfa281e..bb2590240 100644 --- a/src/hb-ot-color-sbix-table.hh +++ b/src/hb-ot-color-sbix-table.hh @@ -75,7 +75,7 @@ struct SBIXStrike inline unsigned int get_resolution () const { return resolution; } - inline unsigned int blob_size (unsigned int glyph_id) const + inline unsigned int calculate_blob_size (unsigned int glyph_id) const { return imageOffsetsZ[glyph_id + 1] - imageOffsetsZ[glyph_id] - SBIXGlyph::min_size; } @@ -84,6 +84,8 @@ struct SBIXStrike hb_blob_t *sbix_blob, unsigned int sbix_len, unsigned int strike_offset, + int *x_offset, + int *y_offset, hb_tag_t file_type, unsigned int num_glyphs) const { @@ -95,7 +97,7 @@ struct SBIXStrike const SBIXGlyph *glyph = &(this+imageOffsetsZ[glyph_id]); if (unlikely (glyph->graphicType == HB_TAG ('d','u','p','e') && - blob_size (glyph_id) >= 2)) + calculate_blob_size (glyph_id) >= 2)) { unsigned int new_glyph_id = *((HBUINT16 *) &glyph->data); if (new_glyph_id < num_glyphs) @@ -108,9 +110,15 @@ struct SBIXStrike } if (unlikely (file_type != glyph->graphicType)) return hb_blob_get_empty (); + unsigned int blob_size = calculate_blob_size (glyph_id); + if (unlikely (blob_size == 0)) + return hb_blob_get_empty (); + + if (x_offset) *x_offset = glyph->xOffset; + if (y_offset) *y_offset = glyph->yOffset; unsigned int offset = strike_offset + SBIXGlyph::min_size; offset += imageOffsetsZ[glyph_id]; - return hb_blob_create_sub_blob (sbix_blob, offset, blob_size (glyph_id)); + return hb_blob_create_sub_blob (sbix_blob, offset, blob_size); } protected: @@ -163,25 +171,51 @@ struct sbix } inline hb_blob_t *reference_blob_for_glyph (hb_codepoint_t glyph_id, - unsigned int ptem HB_UNUSED, - unsigned int requested_ppem, - unsigned int requested_file_type) const + unsigned int x_ppem, + unsigned int y_ppem, + unsigned int file_type, + int *x_offset, + int *y_offset) const { if (unlikely (sbix_len == 0 || sbix_table->strikes.len == 0)) return hb_blob_get_empty (); /* TODO: Does spec guarantee strikes are ascended sorted? */ unsigned int group = sbix_table->strikes.len - 1; - if (requested_ppem != 0) + unsigned int ppem = MAX (x_ppem, y_ppem); + if (ppem != 0) /* TODO: Use bsearch maybe or doesn't worth it? */ for (group = 0; group < sbix_table->strikes.len; group++) - if ((sbix_table+sbix_table->strikes[group]).get_ppem () >= requested_ppem) + if ((sbix_table+sbix_table->strikes[group]).get_ppem () >= ppem) break; const SBIXStrike &strike = sbix_table+sbix_table->strikes[group]; return strike.get_glyph_blob (glyph_id, sbix_blob, sbix_len, sbix_table->strikes[group], - requested_file_type, num_glyphs); + x_offset, y_offset, + file_type, num_glyphs); + } + + inline bool get_png_extents (hb_codepoint_t glyph, + unsigned int x_ppem, + unsigned int y_ppem, + hb_glyph_extents_t *extents) const + { + int x_offset, y_offset; + hb_blob_t *blob = reference_blob_for_glyph (glyph, x_ppem, y_ppem, + HB_TAG ('P','N','G',' '), + &x_offset, &y_offset); + if (hb_blob_get_length (blob) == 0) + return false; + + extents->x_bearing = x_offset; + extents->y_bearing = y_offset; + /* XXX: Help me please! */ + extents->width = 0; + extents->height = 0; + hb_blob_destroy (blob); + + return true; } inline bool has_data () const diff --git a/src/hb-ot-color.cc b/src/hb-ot-color.cc index ed41a3b2b..82fa7e294 100644 --- a/src/hb-ot-color.cc +++ b/src/hb-ot-color.cc @@ -316,16 +316,14 @@ hb_blob_t * hb_ot_color_glyph_reference_png (hb_font_t *font, hb_codepoint_t glyph) { hb_blob_t *blob = hb_blob_get_empty (); - /* don't run cbdt first if aat is set */ - if (!hb_options ().aat && _get_cbdt (font->face).has_data ()) - blob = _get_cbdt (font->face).reference_blob_for_glyph (glyph, font->x_ppem, font->y_ppem); - if (_get_sbix (font->face).has_data () && !hb_blob_get_length (blob)) - blob = _get_sbix (font->face).reference_blob_for_glyph (glyph, font->ptem, - MAX (font->x_ppem, font->y_ppem), - HB_TAG('p','n','g',' ')); + if (_get_sbix (font->face).has_data ()) + blob = _get_sbix (font->face).reference_blob_for_glyph (glyph, + font->x_ppem, font->y_ppem, + HB_TAG('p','n','g',' '), + nullptr, nullptr); - if (hb_options ().aat && _get_cbdt (font->face).has_data () && !hb_blob_get_length (blob)) + if (hb_blob_get_length (blob) == 0 && _get_cbdt (font->face).has_data ()) blob = _get_cbdt (font->face).reference_blob_for_glyph (glyph, font->x_ppem, font->y_ppem); return blob; diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc index 047c4eae5..c8ad6f2f7 100644 --- a/src/hb-ot-font.cc +++ b/src/hb-ot-font.cc @@ -39,6 +39,7 @@ #include "hb-ot-glyf-table.hh" #include "hb-ot-vorg-table.hh" #include "hb-ot-color-cbdt-table.hh" +#include "hb-ot-color-sbix-table.hh" /** @@ -182,7 +183,11 @@ hb_ot_get_glyph_extents (hb_font_t *font, void *user_data HB_UNUSED) { const hb_ot_face_data_t *ot_face = (const hb_ot_face_data_t *) font_data; - bool ret = ot_face->glyf->get_extents (glyph, extents); + bool ret = false; + if (ot_face->sbix->has_data ()) + ret = ot_face->sbix->get_png_extents (glyph, font->x_ppem, font->y_ppem, extents); + if (!ret) + ret = ot_face->glyf->get_extents (glyph, extents); if (!ret) ret = ot_face->CBDT->get_extents (glyph, extents); // TODO Hook up side-bearings variations.