[ot-color] Preparation for setting PNG width/height in extents

This commit is contained in:
Ebrahim Byagowi 2018-10-28 23:19:04 +03:30 committed by Behdad Esfahbod
parent d6d6f3bc22
commit 38706a0746
4 changed files with 59 additions and 21 deletions

View File

@ -69,12 +69,13 @@ sbix_dump (hb_face_t *face)
for (unsigned int glyph_id = 0; glyph_id < num_glyphs; glyph_id++) for (unsigned int glyph_id = 0; glyph_id < num_glyphs; glyph_id++)
{ {
hb_blob_t *blob; hb_blob_t *blob;
blob = sbix.reference_blob_for_glyph (glyph_id, 0, available_ppems[group], unsigned int ppem = available_ppems[group];
HB_TAG('p','n','g',' ')); 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; if (hb_blob_get_length (blob) == 0) continue;
char output_path[255]; 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"); FILE *f = fopen (output_path, "wb");
unsigned int length; unsigned int length;
const char* data = hb_blob_get_data (blob, &length); const char* data = hb_blob_get_data (blob, &length);

View File

@ -75,7 +75,7 @@ struct SBIXStrike
inline unsigned int get_resolution () const inline unsigned int get_resolution () const
{ return resolution; } { 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; return imageOffsetsZ[glyph_id + 1] - imageOffsetsZ[glyph_id] - SBIXGlyph::min_size;
} }
@ -84,6 +84,8 @@ struct SBIXStrike
hb_blob_t *sbix_blob, hb_blob_t *sbix_blob,
unsigned int sbix_len, unsigned int sbix_len,
unsigned int strike_offset, unsigned int strike_offset,
int *x_offset,
int *y_offset,
hb_tag_t file_type, hb_tag_t file_type,
unsigned int num_glyphs) const unsigned int num_glyphs) const
{ {
@ -95,7 +97,7 @@ struct SBIXStrike
const SBIXGlyph *glyph = &(this+imageOffsetsZ[glyph_id]); const SBIXGlyph *glyph = &(this+imageOffsetsZ[glyph_id]);
if (unlikely (glyph->graphicType == HB_TAG ('d','u','p','e') && 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); unsigned int new_glyph_id = *((HBUINT16 *) &glyph->data);
if (new_glyph_id < num_glyphs) if (new_glyph_id < num_glyphs)
@ -108,9 +110,15 @@ struct SBIXStrike
} }
if (unlikely (file_type != glyph->graphicType)) if (unlikely (file_type != glyph->graphicType))
return hb_blob_get_empty (); 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; unsigned int offset = strike_offset + SBIXGlyph::min_size;
offset += imageOffsetsZ[glyph_id]; 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: protected:
@ -163,25 +171,51 @@ struct sbix
} }
inline hb_blob_t *reference_blob_for_glyph (hb_codepoint_t glyph_id, inline hb_blob_t *reference_blob_for_glyph (hb_codepoint_t glyph_id,
unsigned int ptem HB_UNUSED, unsigned int x_ppem,
unsigned int requested_ppem, unsigned int y_ppem,
unsigned int requested_file_type) const unsigned int file_type,
int *x_offset,
int *y_offset) const
{ {
if (unlikely (sbix_len == 0 || sbix_table->strikes.len == 0)) if (unlikely (sbix_len == 0 || sbix_table->strikes.len == 0))
return hb_blob_get_empty (); return hb_blob_get_empty ();
/* TODO: Does spec guarantee strikes are ascended sorted? */ /* TODO: Does spec guarantee strikes are ascended sorted? */
unsigned int group = sbix_table->strikes.len - 1; 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? */ /* TODO: Use bsearch maybe or doesn't worth it? */
for (group = 0; group < sbix_table->strikes.len; group++) 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; break;
const SBIXStrike &strike = sbix_table+sbix_table->strikes[group]; const SBIXStrike &strike = sbix_table+sbix_table->strikes[group];
return strike.get_glyph_blob (glyph_id, sbix_blob, sbix_len, return strike.get_glyph_blob (glyph_id, sbix_blob, sbix_len,
sbix_table->strikes[group], 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 inline bool has_data () const

View File

@ -316,16 +316,14 @@ hb_blob_t *
hb_ot_color_glyph_reference_png (hb_font_t *font, hb_codepoint_t glyph) hb_ot_color_glyph_reference_png (hb_font_t *font, hb_codepoint_t glyph)
{ {
hb_blob_t *blob = hb_blob_get_empty (); 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)) if (_get_sbix (font->face).has_data ())
blob = _get_sbix (font->face).reference_blob_for_glyph (glyph, font->ptem, blob = _get_sbix (font->face).reference_blob_for_glyph (glyph,
MAX (font->x_ppem, font->y_ppem), font->x_ppem, font->y_ppem,
HB_TAG('p','n','g',' ')); 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); blob = _get_cbdt (font->face).reference_blob_for_glyph (glyph, font->x_ppem, font->y_ppem);
return blob; return blob;

View File

@ -39,6 +39,7 @@
#include "hb-ot-glyf-table.hh" #include "hb-ot-glyf-table.hh"
#include "hb-ot-vorg-table.hh" #include "hb-ot-vorg-table.hh"
#include "hb-ot-color-cbdt-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) void *user_data HB_UNUSED)
{ {
const hb_ot_face_data_t *ot_face = (const hb_ot_face_data_t *) font_data; 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) if (!ret)
ret = ot_face->CBDT->get_extents (glyph, extents); ret = ot_face->CBDT->get_extents (glyph, extents);
// TODO Hook up side-bearings variations. // TODO Hook up side-bearings variations.