diff --git a/src/hb-ot-color-cbdt-table.hh b/src/hb-ot-color-cbdt-table.hh index 770fe3eb9..a9518b774 100644 --- a/src/hb-ot-color-cbdt-table.hh +++ b/src/hb-ot-color-cbdt-table.hh @@ -504,12 +504,58 @@ struct CBDT } } - inline hb_blob_t* reference_blob_for_glyph (hb_codepoint_t glyph_id HB_UNUSED, - unsigned int requested_x_ppem HB_UNUSED, - unsigned int requested_y_ppem HB_UNUSED, - unsigned int *strike_x_ppem HB_UNUSED, - unsigned int *strike_y_ppem HB_UNUSED) const + inline hb_blob_t* reference_blob_for_glyph (hb_codepoint_t glyph_id, + unsigned int requested_x_ppem, + unsigned int requested_y_ppem, + unsigned int *strike_x_ppem, + unsigned int *strike_y_ppem) const { + if (!cblc) + return hb_blob_get_empty (); // Not a color bitmap font. + + if (requested_x_ppem == 0) requested_x_ppem = upem; + if (requested_y_ppem == 0) requested_y_ppem = upem; + unsigned int x_ppem = requested_x_ppem, y_ppem = requested_y_ppem; + + const void *base; + const IndexSubtableRecord *subtable_record = this->cblc->find_table (glyph_id, &x_ppem, &y_ppem, &base); + if (!subtable_record || !x_ppem || !y_ppem) + return hb_blob_get_empty (); + + unsigned int image_offset = 0, image_length = 0, image_format = 0; + if (!subtable_record->get_image_data (glyph_id, base, &image_offset, &image_length, &image_format)) + return hb_blob_get_empty (); + + switch (image_format) + { + case 17: { + if (strike_x_ppem) *strike_x_ppem = x_ppem; + if (strike_x_ppem) *strike_y_ppem = y_ppem; + const GlyphBitmapDataFormat17& glyphFormat17 = + StructAtOffset (this->cbdt, image_offset); + return hb_blob_create_sub_blob (cbdt_blob, + image_offset + GlyphBitmapDataFormat17::min_size, + glyphFormat17.data.len); + } + case 18: { + if (strike_x_ppem) *strike_x_ppem = x_ppem; + if (strike_x_ppem) *strike_y_ppem = y_ppem; + const GlyphBitmapDataFormat18& glyphFormat18 = + StructAtOffset (this->cbdt, image_offset); + return hb_blob_create_sub_blob (cbdt_blob, + image_offset + GlyphBitmapDataFormat18::min_size, + glyphFormat18.data.len); + } + case 19: { + if (strike_x_ppem) *strike_x_ppem = x_ppem; + if (strike_x_ppem) *strike_y_ppem = y_ppem; + const GlyphBitmapDataFormat19& glyphFormat19 = + StructAtOffset (this->cbdt, image_offset); + return hb_blob_create_sub_blob (cbdt_blob, + image_offset + GlyphBitmapDataFormat19::min_size, + glyphFormat19.data.len); + } + } return hb_blob_get_empty (); } diff --git a/src/hb-ot-color.cc b/src/hb-ot-color.cc index 8dd3b2a41..9de2f9ac6 100644 --- a/src/hb-ot-color.cc +++ b/src/hb-ot-color.cc @@ -75,22 +75,6 @@ _get_svg (hb_face_t *face) return *(hb_ot_face_data (face)->SVG.get ()); } -#if 0 -static inline const OT::CBDT_accelerator_t& -_get_cbdt (hb_face_t *face) -{ - if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::CBDT_accelerator_t); - return *(hb_ot_face_data (face)->CBDT.get ()); -} - -static inline const OT::sbix& -_get_sbix (hb_face_t *face) -{ - if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(OT::sbix); - return *(hb_ot_face_data (face)->sbix.get ()); -} -#endif - /* * CPAL @@ -289,7 +273,7 @@ hb_ot_color_glyph_reference_blob_svg (hb_face_t *face, hb_codepoint_t glyph) /* - * PNG, CBDT or sbix + * PNG: CBDT or sbix */ /** @@ -335,4 +319,5 @@ hb_ot_color_glyph_reference_blob_png (hb_font_t *font, HB_TAG('p','n','g',' '), strike_x_ppem, strike_y_ppem); + return hb_blob_get_empty (); } diff --git a/src/hb-ot-color.h b/src/hb-ot-color.h index 7901a3598..1810cd63b 100644 --- a/src/hb-ot-color.h +++ b/src/hb-ot-color.h @@ -121,6 +121,10 @@ hb_ot_color_has_svg (hb_face_t *face); HB_EXTERN hb_blob_t * hb_ot_color_glyph_reference_blob_svg (hb_face_t *face, hb_codepoint_t glyph); +/* + * PNG: CBDT or sbix + */ + HB_EXTERN hb_bool_t hb_ot_color_has_png (hb_face_t *face); diff --git a/test/api/test-ot-color.c b/test/api/test-ot-color.c index 767a3d61a..51b901d25 100644 --- a/test/api/test-ot-color.c +++ b/test/api/test-ot-color.c @@ -405,22 +405,41 @@ static void test_hb_ot_color_png (void) { hb_blob_t *blob; + unsigned int length; + const char *data; + unsigned int strike_x_ppem, strike_y_ppem; + /* sbix */ hb_font_t *sbix_font; sbix_font = hb_font_create (sbix); blob = hb_ot_color_glyph_reference_blob_png (sbix_font, 0, NULL, NULL); g_assert (hb_blob_get_length (blob) == 0); - unsigned int strike_x_ppem, strike_y_ppem; blob = hb_ot_color_glyph_reference_blob_png (sbix_font, 1, &strike_x_ppem, &strike_y_ppem); - unsigned int length; - const char *data = hb_blob_get_data (blob, &length); + data = hb_blob_get_data (blob, &length); g_assert_cmpuint (length, ==, 224); g_assert_cmpuint (strike_x_ppem, ==, 300); g_assert_cmpuint (strike_y_ppem, ==, 300); g_assert (strncmp (data + 1, "PNG", 3) == 0); hb_blob_destroy (blob); + hb_font_destroy (sbix_font); + + /* cbdt */ + hb_font_t *cbdt_font; + cbdt_font = hb_font_create (cbdt); + blob = hb_ot_color_glyph_reference_blob_png (cbdt_font, 0, NULL, NULL); + g_assert (hb_blob_get_length (blob) == 0); + + blob = hb_ot_color_glyph_reference_blob_png (cbdt_font, 1, + &strike_x_ppem, &strike_y_ppem); + data = hb_blob_get_data (blob, &length); + g_assert_cmpuint (length, ==, 88); + g_assert_cmpuint (strike_x_ppem, ==, 80); + g_assert_cmpuint (strike_y_ppem, ==, 80); + g_assert (strncmp (data + 1, "PNG", 3) == 0); + hb_blob_destroy (blob); + hb_font_destroy (cbdt_font); } int