[ot-glyph] Initial cff1 support

This commit is contained in:
Ebrahim Byagowi 2019-10-20 16:24:14 +03:30
parent 3dcba9f215
commit 5cc09c462b
3 changed files with 116 additions and 0 deletions

View File

@ -342,6 +342,116 @@ bool OT::cff1::accelerator_t::get_extents (hb_font_t *font, hb_codepoint_t glyph
return true; return true;
} }
struct cff1_path_param_t
{
void init (const OT::cff1::accelerator_t *_cff, hb_vector_t<hb_position_t> *points_, hb_vector_t<uint8_t> *commands_)
{
path_open = false;
cff = _cff;
points = points_;
commands = commands_;
}
void start_path () { path_open = true; }
void end_path () { path_open = false; }
bool is_path_open () const { return path_open; }
void push (const point_t &p) { points->push (p.x.to_real ()); points->push (p.y.to_real ()); }
void push_command (uint8_t c) { commands->push (c); }
bool path_open;
hb_vector_t<hb_position_t> *points;
hb_vector_t<uint8_t> *commands;
const OT::cff1::accelerator_t *cff;
};
struct cff1_path_procs_path_t : path_procs_t<cff1_path_procs_path_t, cff1_cs_interp_env_t, cff1_path_param_t>
{
static void moveto (cff1_cs_interp_env_t &env, cff1_path_param_t& param, const point_t &pt)
{
param.end_path (); param.push_command ('Z');
env.moveto (pt); param.push_command ('M');
}
static void line (cff1_cs_interp_env_t &env, cff1_path_param_t& param, const point_t &pt1)
{
if (!param.is_path_open ())
{
param.start_path ();
param.push (env.get_pt ()); param.push_command ('M');
}
env.moveto (pt1);
param.push (env.get_pt ()); param.push_command ('L');
}
static void curve (cff1_cs_interp_env_t &env, cff1_path_param_t& param, const point_t &pt1, const point_t &pt2, const point_t &pt3)
{
if (!param.is_path_open ())
{
param.start_path ();
param.push (env.get_pt ()); param.push_command ('M');
}
/* include control points */param.push_command ('C');
param.push (pt1);
param.push (pt2);
env.moveto (pt3);
param.push (env.get_pt ());
}
};
static bool _get_path (const OT::cff1::accelerator_t *cff, hb_codepoint_t glyph, hb_vector_t<hb_position_t> *points, hb_vector_t<uint8_t> *commands, bool in_seac=false);
struct cff1_cs_opset_path_t : cff1_cs_opset_t<cff1_cs_opset_path_t, cff1_path_param_t, cff1_path_procs_path_t>
{
static void process_seac (cff1_cs_interp_env_t &env, cff1_path_param_t& param)
{
// unsigned int n = env.argStack.get_count ();
// point_t delta;
// delta.x = env.argStack[n-4];
// delta.y = env.argStack[n-3];
// hb_codepoint_t base = param.cff->std_code_to_glyph (env.argStack[n-2].to_int ());
// hb_codepoint_t accent = param.cff->std_code_to_glyph (env.argStack[n-1].to_int ());
// bounds_t base_bounds, accent_bounds;
// if (likely (!env.in_seac && base && accent
// && _get_path (param.cff, base, base_bounds, true)
// && _get_path (param.cff, accent, accent_bounds, true)))
// {
// param.bounds.merge (base_bounds);
// accent_bounds.offset (delta);
// param.bounds.merge (accent_bounds);
// }
// else
// env.set_error ();
}
};
bool _get_path (const OT::cff1::accelerator_t *cff, hb_codepoint_t glyph, hb_vector_t<hb_position_t> *points, hb_vector_t<uint8_t> *commands, bool in_seac)
{
if (unlikely (!cff->is_valid () || (glyph >= cff->num_glyphs))) return false;
unsigned int fd = cff->fdSelect->get_fd (glyph);
cff1_cs_interpreter_t<cff1_cs_opset_path_t, cff1_path_param_t> interp;
const byte_str_t str = (*cff->charStrings)[glyph];
interp.env.init (str, *cff, fd);
interp.env.set_in_seac (in_seac);
cff1_path_param_t param;
param.init (cff, points, commands);
if (unlikely (!interp.interpret (param))) return false;
return true;
}
bool OT::cff1::accelerator_t::get_path (hb_font_t *font, hb_codepoint_t glyph, hb_vector_t<hb_position_t> *points, hb_vector_t<uint8_t> *commands) const
{
#ifdef HB_NO_OT_FONT_CFF
/* XXX Remove check when this code moves to .hh file. */
return true;
#endif
return _get_path (this, glyph, points, commands);
}
struct get_seac_param_t struct get_seac_param_t
{ {
void init (const OT::cff1::accelerator_t *_cff) void init (const OT::cff1::accelerator_t *_cff)

View File

@ -1347,6 +1347,7 @@ struct cff1
HB_INTERNAL bool get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents) const; HB_INTERNAL bool get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents) const;
HB_INTERNAL bool get_seac_components (hb_codepoint_t glyph, hb_codepoint_t *base, hb_codepoint_t *accent) const; HB_INTERNAL bool get_seac_components (hb_codepoint_t glyph, hb_codepoint_t *base, hb_codepoint_t *accent) const;
HB_INTERNAL bool get_path (hb_font_t *font, hb_codepoint_t glyph, hb_vector_t<hb_position_t> *points, hb_vector_t<uint8_t> *commands) const;
private: private:
struct gname_t struct gname_t

View File

@ -28,6 +28,7 @@
#include "hb-ot.h" #include "hb-ot.h"
#include "hb-ot-glyf-table.hh" #include "hb-ot-glyf-table.hh"
#include "hb-ot-cff1-table.hh"
struct hb_ot_glyph_path_t struct hb_ot_glyph_path_t
{ {
@ -154,6 +155,10 @@ hb_ot_glyph_create_path_from_font (hb_font_t *font, hb_codepoint_t glyph)
coords.push (font->em_scalef_x (x)); coords.push (font->em_scalef_x (x));
coords.push (font->em_scalef_y (y)); coords.push (font->em_scalef_y (y));
}); });
if (!commands.length)
{
font->face->table.cff1->get_path (font, glyph, &coords, &commands);
}
return hb_ot_glyph_create_path (coords.arrayZ, coords.length, commands.arrayZ, commands.length, return hb_ot_glyph_create_path (coords.arrayZ, coords.length, commands.arrayZ, commands.length,
user_data, (hb_destroy_func_t) _hb_ot_glyph_free_path_vectors); user_data, (hb_destroy_func_t) _hb_ot_glyph_free_path_vectors);