diff --git a/src/hb-ot-color-cbdt-table.hh b/src/hb-ot-color-cbdt-table.hh index beaee108d..a6b906408 100644 --- a/src/hb-ot-color-cbdt-table.hh +++ b/src/hb-ot-color-cbdt-table.hh @@ -81,14 +81,15 @@ struct SmallGlyphMetrics return_trace (c->check_struct (this)); } - void get_extents (hb_font_t *font, hb_glyph_extents_t *extents) const + void get_extents (hb_font_t *font, hb_glyph_extents_t *extents, bool scale) const { extents->x_bearing = bearingX; extents->y_bearing = bearingY; extents->width = width; extents->height = -static_cast (height); - font->scale_glyph_extents (extents); + if (scale) + font->scale_glyph_extents (extents); } HBUINT8 height; @@ -310,7 +311,7 @@ struct IndexSubtable } } - bool get_extents (hb_glyph_extents_t *extents HB_UNUSED) const + bool get_extents (hb_glyph_extents_t *extents HB_UNUSED, bool scale HB_UNUSED) const { switch (u.header.indexFormat) { @@ -507,8 +508,8 @@ struct IndexSubtableRecord return num_missing; } - bool get_extents (hb_glyph_extents_t *extents, const void *base) const - { return (base+offsetToSubtable).get_extents (extents); } + bool get_extents (hb_glyph_extents_t *extents, const void *base, bool scale) const + { return (base+offsetToSubtable).get_extents (extents, scale); } bool get_image_data (unsigned int gid, const void *base, @@ -836,7 +837,7 @@ struct CBDT } bool - get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents) const + get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents, bool scale = true) const { const void *base; const BitmapSizeTable &strike = this->cblc->choose_strike (font); @@ -844,7 +845,7 @@ struct CBDT if (!subtable_record || !strike.ppemX || !strike.ppemY) return false; - if (subtable_record->get_extents (extents, base)) + if (subtable_record->get_extents (extents, base, scale)) return true; unsigned int image_offset = 0, image_length = 0, image_format = 0; @@ -861,26 +862,29 @@ struct CBDT if (unlikely (image_length < GlyphBitmapDataFormat17::min_size)) return false; auto &glyphFormat17 = StructAtOffset (this->cbdt, image_offset); - glyphFormat17.glyphMetrics.get_extents (font, extents); + glyphFormat17.glyphMetrics.get_extents (font, extents, scale); break; } case 18: { if (unlikely (image_length < GlyphBitmapDataFormat18::min_size)) return false; auto &glyphFormat18 = StructAtOffset (this->cbdt, image_offset); - glyphFormat18.glyphMetrics.get_extents (font, extents); + glyphFormat18.glyphMetrics.get_extents (font, extents, scale); break; } default: return false; /* TODO: Support other image formats. */ } /* Convert to font units. */ - float x_scale = upem / (float) strike.ppemX; - float y_scale = upem / (float) strike.ppemY; - extents->x_bearing = roundf (extents->x_bearing * x_scale); - extents->y_bearing = roundf (extents->y_bearing * y_scale); - extents->width = roundf (extents->width * x_scale); - extents->height = roundf (extents->height * y_scale); + if (scale) + { + float x_scale = upem / (float) strike.ppemX; + float y_scale = upem / (float) strike.ppemY; + extents->x_bearing = roundf (extents->x_bearing * x_scale); + extents->y_bearing = roundf (extents->y_bearing * y_scale); + extents->width = roundf (extents->width * x_scale); + extents->height = roundf (extents->height * y_scale); + } return true; } @@ -940,6 +944,7 @@ struct CBDT bool paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data) const { hb_glyph_extents_t extents; + hb_glyph_extents_t pixel_extents; hb_blob_t *blob = reference_png (font, glyph); if (unlikely (blob == hb_blob_get_empty ())) @@ -948,7 +953,15 @@ struct CBDT if (unlikely (!hb_font_get_glyph_extents (font, glyph, &extents))) return false; - funcs->image (data, blob, HB_PAINT_IMAGE_FORMAT_PNG, font->slant_xy, &extents); + if (unlikely (!get_extents (font, glyph, &pixel_extents, false))) + return false; + + funcs->image (data, + blob, + pixel_extents.width, -pixel_extents.height, + HB_PAINT_IMAGE_FORMAT_PNG, + font->slant_xy, + &extents); hb_blob_destroy (blob); return true; diff --git a/src/hb-ot-color-sbix-table.hh b/src/hb-ot-color-sbix-table.hh index 20f2b0444..10d4b3a85 100644 --- a/src/hb-ot-color-sbix-table.hh +++ b/src/hb-ot-color-sbix-table.hh @@ -214,10 +214,11 @@ struct sbix bool get_extents (hb_font_t *font, hb_codepoint_t glyph, - hb_glyph_extents_t *extents) const + hb_glyph_extents_t *extents, + bool scale = true) const { /* We only support PNG right now, and following function checks type. */ - return get_png_extents (font, glyph, extents); + return get_png_extents (font, glyph, extents, scale); } hb_blob_t *reference_png (hb_font_t *font, @@ -241,6 +242,7 @@ struct sbix unsigned int strike_ppem = 0; hb_blob_t *blob = reference_png (font, glyph, &x_offset, &y_offset, &strike_ppem); hb_glyph_extents_t extents; + hb_glyph_extents_t pixel_extents; if (blob == hb_blob_get_empty ()) return false; @@ -248,7 +250,15 @@ struct sbix if (!hb_font_get_glyph_extents (font, glyph, &extents)) return false; - funcs->image (data, blob, HB_PAINT_IMAGE_FORMAT_PNG, font->slant_xy, &extents); + if (unlikely (!get_extents (font, glyph, &pixel_extents, false))) + return false; + + funcs->image (data, + blob, + pixel_extents.width, -pixel_extents.height, + HB_PAINT_IMAGE_FORMAT_PNG, + font->slant_xy, + &extents); hb_blob_destroy (blob); return true; @@ -308,7 +318,8 @@ struct sbix bool get_png_extents (hb_font_t *font, hb_codepoint_t glyph, - hb_glyph_extents_t *extents) const + hb_glyph_extents_t *extents, + bool scale = true) const { /* Following code is safe to call even without data. * But faster to short-circuit. */ @@ -333,7 +344,7 @@ struct sbix extents->height = -1 * png.IHDR.height; /* Convert to font units. */ - if (strike_ppem) + if (strike_ppem && scale) { float scale = font->face->get_upem () / (float) strike_ppem; extents->x_bearing = roundf (extents->x_bearing * scale); @@ -341,15 +352,9 @@ struct sbix extents->width = roundf (extents->width * scale); extents->height = roundf (extents->height * scale); } - else - { - extents->x_bearing = extents->x_bearing; - extents->y_bearing = extents->y_bearing; - extents->width = extents->width; - extents->height = extents->height; - } - font->scale_glyph_extents (extents); + if (scale) + font->scale_glyph_extents (extents); hb_blob_destroy (blob); diff --git a/src/hb-ot-color-svg-table.hh b/src/hb-ot-color-svg-table.hh index f9990d44b..042faa384 100644 --- a/src/hb-ot-color-svg-table.hh +++ b/src/hb-ot-color-svg-table.hh @@ -103,7 +103,12 @@ struct SVG if (blob == hb_blob_get_empty ()) return false; - funcs->image (data, blob, HB_PAINT_IMAGE_FORMAT_SVG, font->slant_xy, nullptr); + funcs->image (data, + blob, + 0, 0, + HB_PAINT_IMAGE_FORMAT_SVG, + font->slant_xy, + nullptr); hb_blob_destroy (blob); return true; diff --git a/src/hb-paint.cc b/src/hb-paint.cc index fdce759a1..a22c3a25b 100644 --- a/src/hb-paint.cc +++ b/src/hb-paint.cc @@ -77,6 +77,8 @@ hb_paint_color_nil (hb_paint_funcs_t *funcs, void *paint_data, static void hb_paint_image_nil (hb_paint_funcs_t *funcs, void *paint_data, hb_blob_t *image, + unsigned int width, + unsigned int height, hb_tag_t format, float slant_xy, hb_glyph_extents_t *extents, diff --git a/src/hb-paint.h b/src/hb-paint.h index 85d35814c..c695891a0 100644 --- a/src/hb-paint.h +++ b/src/hb-paint.h @@ -243,9 +243,11 @@ typedef void (*hb_paint_color_func_t) (hb_paint_funcs_t *funcs, * @funcs: paint functions object * @paint_data: The data accompanying the paint functions in hb_font_paint_glyph() * @image: the image data + * @width: width of the raster image in pixels + * @height: height of the raster image in pixels * @format: the image format as a tag - * @slant: the synthetic slant of the font - * @extents: (nullable): glyph extents + * @slant: the synthetic slant ratio to be applied to the image during rendering + * @extents: (nullable): glyph extents for desired rendering * @user_data: User data pointer passed to hb_paint_funcs_set_image_func() * * A virtual method for the #hb_paint_funcs_t to paint the @@ -264,6 +266,8 @@ typedef void (*hb_paint_color_func_t) (hb_paint_funcs_t *funcs, typedef void (*hb_paint_image_func_t) (hb_paint_funcs_t *funcs, void *paint_data, hb_blob_t *image, + unsigned int width, + unsigned int height, hb_tag_t format, float slant, hb_glyph_extents_t *extents, diff --git a/src/hb-paint.hh b/src/hb-paint.hh index eaba99bce..89be4cb3d 100644 --- a/src/hb-paint.hh +++ b/src/hb-paint.hh @@ -99,11 +99,12 @@ struct hb_paint_funcs_t !user_data ? nullptr : user_data->color); } void image (void *paint_data, hb_blob_t *image, + unsigned width, unsigned height, hb_tag_t format, float slant, hb_glyph_extents_t *extents) { func.image (this, paint_data, - image, format, slant, extents, + image, width, height, format, slant, extents, !user_data ? nullptr : user_data->image); } void linear_gradient (void *paint_data, hb_color_line_t *color_line, diff --git a/util/hb-cairo-utils.c b/util/hb-cairo-utils.c index d40b56458..36c4acd6b 100644 --- a/util/hb-cairo-utils.c +++ b/util/hb-cairo-utils.c @@ -99,6 +99,8 @@ read_blob (void *closure, void hb_cairo_paint_glyph_image (cairo_t *cr, hb_blob_t *blob, + unsigned width, + unsigned height, hb_tag_t format, float slant, hb_glyph_extents_t *extents) @@ -111,8 +113,11 @@ hb_cairo_paint_glyph_image (cairo_t *cr, r.blob = blob; r.offset = 0; cairo_surface_t *surface = cairo_image_surface_create_from_png_stream (read_blob, &r); - int width = cairo_image_surface_get_width (surface); - int height = cairo_image_surface_get_width (surface); + + /* For PNG, width,height can be unreliable, as is the case for NotoColorEmoji :(. + * Just pull them out of the surface. */ + width = cairo_image_surface_get_width (surface); + height = cairo_image_surface_get_width (surface); cairo_pattern_t *pattern = cairo_pattern_create_for_surface (surface); cairo_pattern_set_extend (pattern, CAIRO_EXTEND_PAD); diff --git a/util/hb-cairo-utils.h b/util/hb-cairo-utils.h index fdc9de884..fdf7c01af 100644 --- a/util/hb-cairo-utils.h +++ b/util/hb-cairo-utils.h @@ -72,6 +72,8 @@ hb_paint_composite_mode_to_cairo (hb_paint_composite_mode_t mode) void hb_cairo_paint_glyph_image (cairo_t *cr, hb_blob_t *blob, + unsigned width, + unsigned height, hb_tag_t format, float slant, hb_glyph_extents_t *extents); diff --git a/util/helper-cairo-user.hh b/util/helper-cairo-user.hh index 8ad970a0b..2784b39bb 100644 --- a/util/helper-cairo-user.hh +++ b/util/helper-cairo-user.hh @@ -221,6 +221,8 @@ static void paint_image (hb_paint_funcs_t *funcs, void *paint_data, hb_blob_t *blob, + unsigned width, + unsigned height, hb_tag_t format, float slant, hb_glyph_extents_t *extents, @@ -228,7 +230,7 @@ paint_image (hb_paint_funcs_t *funcs, { cairo_t *cr = (cairo_t *)paint_data; - hb_cairo_paint_glyph_image (cr, blob, format, slant, extents); + hb_cairo_paint_glyph_image (cr, blob, width, height, format, slant, extents); } static void