|
@@ -25,237 +25,313 @@
|
|
|
#include "hb.hh"
|
|
|
|
|
|
#ifndef HB_NO_DRAW
|
|
|
-#ifdef HB_EXPERIMENTAL_API
|
|
|
|
|
|
#include "hb-draw.hh"
|
|
|
-#include "hb-ot.h"
|
|
|
-#include "hb-ot-glyf-table.hh"
|
|
|
-#include "hb-ot-cff1-table.hh"
|
|
|
-#include "hb-ot-cff2-table.hh"
|
|
|
|
|
|
/**
|
|
|
- * hb_draw_funcs_set_move_to_func:
|
|
|
- * @funcs: draw functions object
|
|
|
- * @move_to: move-to callback
|
|
|
+ * SECTION:hb-draw
|
|
|
+ * @title: hb-draw
|
|
|
+ * @short_description: Glyph drawing
|
|
|
+ * @include: hb.h
|
|
|
*
|
|
|
- * Sets move-to callback to the draw functions object.
|
|
|
- *
|
|
|
- * Since: EXPERIMENTAL
|
|
|
+ * Functions for drawing (extracting) glyph shapes.
|
|
|
**/
|
|
|
-void
|
|
|
-hb_draw_funcs_set_move_to_func (hb_draw_funcs_t *funcs,
|
|
|
- hb_draw_move_to_func_t move_to)
|
|
|
+
|
|
|
+static void
|
|
|
+hb_draw_move_to_nil (hb_draw_funcs_t *dfuncs HB_UNUSED, void *draw_data HB_UNUSED,
|
|
|
+ hb_draw_state_t *st HB_UNUSED,
|
|
|
+ float to_x HB_UNUSED, float to_y HB_UNUSED,
|
|
|
+ void *user_data HB_UNUSED) {}
|
|
|
+
|
|
|
+static void
|
|
|
+hb_draw_line_to_nil (hb_draw_funcs_t *dfuncs HB_UNUSED, void *draw_data HB_UNUSED,
|
|
|
+ hb_draw_state_t *st HB_UNUSED,
|
|
|
+ float to_x HB_UNUSED, float to_y HB_UNUSED,
|
|
|
+ void *user_data HB_UNUSED) {}
|
|
|
+
|
|
|
+static void
|
|
|
+hb_draw_quadratic_to_nil (hb_draw_funcs_t *dfuncs, void *draw_data,
|
|
|
+ hb_draw_state_t *st,
|
|
|
+ float control_x, float control_y,
|
|
|
+ float to_x, float to_y,
|
|
|
+ void *user_data HB_UNUSED)
|
|
|
{
|
|
|
- if (unlikely (hb_object_is_immutable (funcs))) return;
|
|
|
- funcs->move_to = move_to;
|
|
|
+ dfuncs->emit_cubic_to (draw_data, *st,
|
|
|
+ (st->current_x + 2.f * control_x) / 3.f,
|
|
|
+ (st->current_y + 2.f * control_y) / 3.f,
|
|
|
+ (to_x + 2.f * control_x) / 3.f,
|
|
|
+ (to_y + 2.f * control_y) / 3.f,
|
|
|
+ to_x, to_y);
|
|
|
+}
|
|
|
+
|
|
|
+static void
|
|
|
+hb_draw_cubic_to_nil (hb_draw_funcs_t *dfuncs HB_UNUSED, void *draw_data HB_UNUSED,
|
|
|
+ hb_draw_state_t *st HB_UNUSED,
|
|
|
+ float control1_x HB_UNUSED, float control1_y HB_UNUSED,
|
|
|
+ float control2_x HB_UNUSED, float control2_y HB_UNUSED,
|
|
|
+ float to_x HB_UNUSED, float to_y HB_UNUSED,
|
|
|
+ void *user_data HB_UNUSED) {}
|
|
|
+
|
|
|
+static void
|
|
|
+hb_draw_close_path_nil (hb_draw_funcs_t *dfuncs HB_UNUSED, void *draw_data HB_UNUSED,
|
|
|
+ hb_draw_state_t *st HB_UNUSED,
|
|
|
+ void *user_data HB_UNUSED) {}
|
|
|
+
|
|
|
+
|
|
|
+#define HB_DRAW_FUNC_IMPLEMENT(name) \
|
|
|
+ \
|
|
|
+void \
|
|
|
+hb_draw_funcs_set_##name##_func (hb_draw_funcs_t *dfuncs, \
|
|
|
+ hb_draw_##name##_func_t func, \
|
|
|
+ void *user_data, \
|
|
|
+ hb_destroy_func_t destroy) \
|
|
|
+{ \
|
|
|
+ if (hb_object_is_immutable (dfuncs)) \
|
|
|
+ return; \
|
|
|
+ \
|
|
|
+ if (dfuncs->destroy.name) \
|
|
|
+ dfuncs->destroy.name (dfuncs->user_data.name); \
|
|
|
+ \
|
|
|
+ if (func) { \
|
|
|
+ dfuncs->func.name = func; \
|
|
|
+ dfuncs->user_data.name = user_data; \
|
|
|
+ dfuncs->destroy.name = destroy; \
|
|
|
+ } else { \
|
|
|
+ dfuncs->func.name = hb_draw_##name##_nil; \
|
|
|
+ dfuncs->user_data.name = nullptr; \
|
|
|
+ dfuncs->destroy.name = nullptr; \
|
|
|
+ } \
|
|
|
}
|
|
|
|
|
|
+HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS
|
|
|
+#undef HB_DRAW_FUNC_IMPLEMENT
|
|
|
+
|
|
|
/**
|
|
|
- * hb_draw_funcs_set_line_to_func:
|
|
|
- * @funcs: draw functions object
|
|
|
- * @line_to: line-to callback
|
|
|
+ * hb_draw_funcs_create: (Xconstructor)
|
|
|
+ *
|
|
|
+ * Creates a new draw callbacks object.
|
|
|
*
|
|
|
- * Sets line-to callback to the draw functions object.
|
|
|
+ * Return value: (transfer full):
|
|
|
+ * A newly allocated #hb_draw_funcs_t with a reference count of 1. The initial
|
|
|
+ * reference count should be released with hb_draw_funcs_destroy when you are
|
|
|
+ * done using the #hb_draw_funcs_t. This function never returns %NULL. If
|
|
|
+ * memory cannot be allocated, a special singleton #hb_draw_funcs_t object will
|
|
|
+ * be returned.
|
|
|
*
|
|
|
- * Since: EXPERIMENTAL
|
|
|
+ * Since: 4.0.0
|
|
|
**/
|
|
|
-void
|
|
|
-hb_draw_funcs_set_line_to_func (hb_draw_funcs_t *funcs,
|
|
|
- hb_draw_line_to_func_t line_to)
|
|
|
+hb_draw_funcs_t *
|
|
|
+hb_draw_funcs_create ()
|
|
|
{
|
|
|
- if (unlikely (hb_object_is_immutable (funcs))) return;
|
|
|
- funcs->line_to = line_to;
|
|
|
+ hb_draw_funcs_t *dfuncs;
|
|
|
+ if (unlikely (!(dfuncs = hb_object_create<hb_draw_funcs_t> ())))
|
|
|
+ return const_cast<hb_draw_funcs_t *> (&Null (hb_draw_funcs_t));
|
|
|
+
|
|
|
+ dfuncs->func = Null (hb_draw_funcs_t).func;
|
|
|
+
|
|
|
+ return dfuncs;
|
|
|
}
|
|
|
|
|
|
+DEFINE_NULL_INSTANCE (hb_draw_funcs_t) =
|
|
|
+{
|
|
|
+ HB_OBJECT_HEADER_STATIC,
|
|
|
+
|
|
|
+ {
|
|
|
+#define HB_DRAW_FUNC_IMPLEMENT(name) hb_draw_##name##_nil,
|
|
|
+ HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS
|
|
|
+#undef HB_DRAW_FUNC_IMPLEMENT
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+
|
|
|
/**
|
|
|
- * hb_draw_funcs_set_quadratic_to_func:
|
|
|
- * @funcs: draw functions object
|
|
|
- * @move_to: quadratic-to callback
|
|
|
+ * hb_draw_funcs_reference: (skip)
|
|
|
+ * @dfuncs: draw functions
|
|
|
+ *
|
|
|
+ * Increases the reference count on @dfuncs by one. This prevents @buffer from
|
|
|
+ * being destroyed until a matching call to hb_draw_funcs_destroy() is made.
|
|
|
*
|
|
|
- * Sets quadratic-to callback to the draw functions object.
|
|
|
+ * Return value: (transfer full):
|
|
|
+ * The referenced #hb_draw_funcs_t.
|
|
|
*
|
|
|
- * Since: EXPERIMENTAL
|
|
|
+ * Since: 4.0.0
|
|
|
**/
|
|
|
-void
|
|
|
-hb_draw_funcs_set_quadratic_to_func (hb_draw_funcs_t *funcs,
|
|
|
- hb_draw_quadratic_to_func_t quadratic_to)
|
|
|
+hb_draw_funcs_t *
|
|
|
+hb_draw_funcs_reference (hb_draw_funcs_t *dfuncs)
|
|
|
{
|
|
|
- if (unlikely (hb_object_is_immutable (funcs))) return;
|
|
|
- funcs->quadratic_to = quadratic_to;
|
|
|
- funcs->is_quadratic_to_set = true;
|
|
|
+ return hb_object_reference (dfuncs);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * hb_draw_funcs_set_cubic_to_func:
|
|
|
- * @funcs: draw functions
|
|
|
- * @cubic_to: cubic-to callback
|
|
|
+ * hb_draw_funcs_destroy: (skip)
|
|
|
+ * @dfuncs: draw functions
|
|
|
*
|
|
|
- * Sets cubic-to callback to the draw functions object.
|
|
|
+ * Deallocate the @dfuncs.
|
|
|
+ * Decreases the reference count on @dfuncs by one. If the result is zero, then
|
|
|
+ * @dfuncs and all associated resources are freed. See hb_draw_funcs_reference().
|
|
|
*
|
|
|
- * Since: EXPERIMENTAL
|
|
|
+ * Since: 4.0.0
|
|
|
**/
|
|
|
void
|
|
|
-hb_draw_funcs_set_cubic_to_func (hb_draw_funcs_t *funcs,
|
|
|
- hb_draw_cubic_to_func_t cubic_to)
|
|
|
+hb_draw_funcs_destroy (hb_draw_funcs_t *dfuncs)
|
|
|
{
|
|
|
- if (unlikely (hb_object_is_immutable (funcs))) return;
|
|
|
- funcs->cubic_to = cubic_to;
|
|
|
+ if (!hb_object_destroy (dfuncs)) return;
|
|
|
+
|
|
|
+#define HB_DRAW_FUNC_IMPLEMENT(name) \
|
|
|
+ if (dfuncs->destroy.name) dfuncs->destroy.name (dfuncs->user_data.name);
|
|
|
+ HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS
|
|
|
+#undef HB_DRAW_FUNC_IMPLEMENT
|
|
|
+
|
|
|
+
|
|
|
+ hb_free (dfuncs);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * hb_draw_funcs_set_close_path_func:
|
|
|
- * @funcs: draw functions object
|
|
|
- * @close_path: close-path callback
|
|
|
+ * hb_draw_funcs_make_immutable:
|
|
|
+ * @dfuncs: draw functions
|
|
|
*
|
|
|
- * Sets close-path callback to the draw functions object.
|
|
|
+ * Makes @dfuncs object immutable.
|
|
|
*
|
|
|
- * Since: EXPERIMENTAL
|
|
|
+ * Since: 4.0.0
|
|
|
**/
|
|
|
void
|
|
|
-hb_draw_funcs_set_close_path_func (hb_draw_funcs_t *funcs,
|
|
|
- hb_draw_close_path_func_t close_path)
|
|
|
+hb_draw_funcs_make_immutable (hb_draw_funcs_t *dfuncs)
|
|
|
{
|
|
|
- if (unlikely (hb_object_is_immutable (funcs))) return;
|
|
|
- funcs->close_path = close_path;
|
|
|
-}
|
|
|
-
|
|
|
-static void
|
|
|
-_move_to_nil (hb_position_t to_x HB_UNUSED, hb_position_t to_y HB_UNUSED, void *user_data HB_UNUSED) {}
|
|
|
-
|
|
|
-static void
|
|
|
-_line_to_nil (hb_position_t to_x HB_UNUSED, hb_position_t to_y HB_UNUSED, void *user_data HB_UNUSED) {}
|
|
|
-
|
|
|
-static void
|
|
|
-_quadratic_to_nil (hb_position_t control_x HB_UNUSED, hb_position_t control_y HB_UNUSED,
|
|
|
- hb_position_t to_x HB_UNUSED, hb_position_t to_y HB_UNUSED,
|
|
|
- void *user_data HB_UNUSED) {}
|
|
|
-
|
|
|
-static void
|
|
|
-_cubic_to_nil (hb_position_t control1_x HB_UNUSED, hb_position_t control1_y HB_UNUSED,
|
|
|
- hb_position_t control2_x HB_UNUSED, hb_position_t control2_y HB_UNUSED,
|
|
|
- hb_position_t to_x HB_UNUSED, hb_position_t to_y HB_UNUSED,
|
|
|
- void *user_data HB_UNUSED) {}
|
|
|
+ if (hb_object_is_immutable (dfuncs))
|
|
|
+ return;
|
|
|
|
|
|
-static void
|
|
|
-_close_path_nil (void *user_data HB_UNUSED) {}
|
|
|
+ hb_object_make_immutable (dfuncs);
|
|
|
+}
|
|
|
|
|
|
/**
|
|
|
- * hb_draw_funcs_create:
|
|
|
+ * hb_draw_funcs_is_immutable:
|
|
|
+ * @dfuncs: draw functions
|
|
|
*
|
|
|
- * Creates a new draw callbacks object.
|
|
|
+ * Checks whether @dfuncs is immutable.
|
|
|
+ *
|
|
|
+ * Return value: %true if @dfuncs is immutable, %false otherwise
|
|
|
*
|
|
|
- * Since: EXPERIMENTAL
|
|
|
+ * Since: 4.0.0
|
|
|
**/
|
|
|
-hb_draw_funcs_t *
|
|
|
-hb_draw_funcs_create ()
|
|
|
+hb_bool_t
|
|
|
+hb_draw_funcs_is_immutable (hb_draw_funcs_t *dfuncs)
|
|
|
{
|
|
|
- hb_draw_funcs_t *funcs;
|
|
|
- if (unlikely (!(funcs = hb_object_create<hb_draw_funcs_t> ())))
|
|
|
- return const_cast<hb_draw_funcs_t *> (&Null (hb_draw_funcs_t));
|
|
|
-
|
|
|
- funcs->move_to = (hb_draw_move_to_func_t) _move_to_nil;
|
|
|
- funcs->line_to = (hb_draw_line_to_func_t) _line_to_nil;
|
|
|
- funcs->quadratic_to = (hb_draw_quadratic_to_func_t) _quadratic_to_nil;
|
|
|
- funcs->is_quadratic_to_set = false;
|
|
|
- funcs->cubic_to = (hb_draw_cubic_to_func_t) _cubic_to_nil;
|
|
|
- funcs->close_path = (hb_draw_close_path_func_t) _close_path_nil;
|
|
|
- return funcs;
|
|
|
+ return hb_object_is_immutable (dfuncs);
|
|
|
}
|
|
|
|
|
|
+
|
|
|
/**
|
|
|
- * hb_draw_funcs_reference:
|
|
|
- * @funcs: draw functions
|
|
|
+ * hb_draw_move_to:
|
|
|
+ * @dfuncs: draw functions
|
|
|
+ * @draw_data: associated draw data passed by the caller
|
|
|
+ * @st: current draw state
|
|
|
+ * @to_x: X component of target point
|
|
|
+ * @to_y: Y component of target point
|
|
|
*
|
|
|
- * Add to callbacks object refcount.
|
|
|
+ * Perform a "move-to" draw operation.
|
|
|
*
|
|
|
- * Returns: The same object.
|
|
|
- * Since: EXPERIMENTAL
|
|
|
+ * Since: 4.0.0
|
|
|
**/
|
|
|
-hb_draw_funcs_t *
|
|
|
-hb_draw_funcs_reference (hb_draw_funcs_t *funcs)
|
|
|
+void
|
|
|
+hb_draw_move_to (hb_draw_funcs_t *dfuncs, void *draw_data,
|
|
|
+ hb_draw_state_t *st,
|
|
|
+ float to_x, float to_y)
|
|
|
{
|
|
|
- return hb_object_reference (funcs);
|
|
|
+ dfuncs->move_to (draw_data, *st,
|
|
|
+ to_x, to_y);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * hb_draw_funcs_destroy:
|
|
|
- * @funcs: draw functions
|
|
|
+ * hb_draw_line_to:
|
|
|
+ * @dfuncs: draw functions
|
|
|
+ * @draw_data: associated draw data passed by the caller
|
|
|
+ * @st: current draw state
|
|
|
+ * @to_x: X component of target point
|
|
|
+ * @to_y: Y component of target point
|
|
|
*
|
|
|
- * Decreases refcount of callbacks object and deletes the object if it reaches
|
|
|
- * to zero.
|
|
|
+ * Perform a "line-to" draw operation.
|
|
|
*
|
|
|
- * Since: EXPERIMENTAL
|
|
|
+ * Since: 4.0.0
|
|
|
**/
|
|
|
void
|
|
|
-hb_draw_funcs_destroy (hb_draw_funcs_t *funcs)
|
|
|
+hb_draw_line_to (hb_draw_funcs_t *dfuncs, void *draw_data,
|
|
|
+ hb_draw_state_t *st,
|
|
|
+ float to_x, float to_y)
|
|
|
{
|
|
|
- if (!hb_object_destroy (funcs)) return;
|
|
|
-
|
|
|
- hb_free (funcs);
|
|
|
+ dfuncs->line_to (draw_data, *st,
|
|
|
+ to_x, to_y);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * hb_draw_funcs_make_immutable:
|
|
|
- * @funcs: draw functions
|
|
|
+ * hb_draw_quadratic_to:
|
|
|
+ * @dfuncs: draw functions
|
|
|
+ * @draw_data: associated draw data passed by the caller
|
|
|
+ * @st: current draw state
|
|
|
+ * @control_x: X component of control point
|
|
|
+ * @control_y: Y component of control point
|
|
|
+ * @to_x: X component of target point
|
|
|
+ * @to_y: Y component of target point
|
|
|
*
|
|
|
- * Makes funcs object immutable.
|
|
|
+ * Perform a "quadratic-to" draw operation.
|
|
|
*
|
|
|
- * Since: EXPERIMENTAL
|
|
|
+ * Since: 4.0.0
|
|
|
**/
|
|
|
void
|
|
|
-hb_draw_funcs_make_immutable (hb_draw_funcs_t *funcs)
|
|
|
+hb_draw_quadratic_to (hb_draw_funcs_t *dfuncs, void *draw_data,
|
|
|
+ hb_draw_state_t *st,
|
|
|
+ float control_x, float control_y,
|
|
|
+ float to_x, float to_y)
|
|
|
{
|
|
|
- if (hb_object_is_immutable (funcs))
|
|
|
- return;
|
|
|
-
|
|
|
- hb_object_make_immutable (funcs);
|
|
|
+ dfuncs->quadratic_to (draw_data, *st,
|
|
|
+ control_x, control_y,
|
|
|
+ to_x, to_y);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * hb_draw_funcs_is_immutable:
|
|
|
- * @funcs: draw functions
|
|
|
+ * hb_draw_cubic_to:
|
|
|
+ * @dfuncs: draw functions
|
|
|
+ * @draw_data: associated draw data passed by the caller
|
|
|
+ * @st: current draw state
|
|
|
+ * @control1_x: X component of first control point
|
|
|
+ * @control1_y: Y component of first control point
|
|
|
+ * @control2_x: X component of second control point
|
|
|
+ * @control2_y: Y component of second control point
|
|
|
+ * @to_x: X component of target point
|
|
|
+ * @to_y: Y component of target point
|
|
|
*
|
|
|
- * Checks whether funcs is immutable.
|
|
|
+ * Perform a "cubic-to" draw operation.
|
|
|
*
|
|
|
- * Returns: If is immutable.
|
|
|
- * Since: EXPERIMENTAL
|
|
|
+ * Since: 4.0.0
|
|
|
**/
|
|
|
-hb_bool_t
|
|
|
-hb_draw_funcs_is_immutable (hb_draw_funcs_t *funcs)
|
|
|
+void
|
|
|
+hb_draw_cubic_to (hb_draw_funcs_t *dfuncs, void *draw_data,
|
|
|
+ hb_draw_state_t *st,
|
|
|
+ float control1_x, float control1_y,
|
|
|
+ float control2_x, float control2_y,
|
|
|
+ float to_x, float to_y)
|
|
|
{
|
|
|
- return hb_object_is_immutable (funcs);
|
|
|
+ dfuncs->cubic_to (draw_data, *st,
|
|
|
+ control1_x, control1_y,
|
|
|
+ control2_x, control2_y,
|
|
|
+ to_x, to_y);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * hb_font_draw_glyph:
|
|
|
- * @font: a font object
|
|
|
- * @glyph: a glyph id
|
|
|
- * @funcs: draw callbacks object
|
|
|
- * @user_data: parameter you like be passed to the callbacks when are called
|
|
|
+ * hb_draw_close_path:
|
|
|
+ * @dfuncs: draw functions
|
|
|
+ * @draw_data: associated draw data passed by the caller
|
|
|
+ * @st: current draw state
|
|
|
*
|
|
|
- * Draw a glyph.
|
|
|
+ * Perform a "close-path" draw operation.
|
|
|
*
|
|
|
- * Returns: Whether the font had the glyph and the operation completed successfully.
|
|
|
- * Since: EXPERIMENTAL
|
|
|
+ * Since: 4.0.0
|
|
|
**/
|
|
|
-hb_bool_t
|
|
|
-hb_font_draw_glyph (hb_font_t *font, hb_codepoint_t glyph,
|
|
|
- const hb_draw_funcs_t *funcs,
|
|
|
- void *user_data)
|
|
|
+void
|
|
|
+hb_draw_close_path (hb_draw_funcs_t *dfuncs, void *draw_data,
|
|
|
+ hb_draw_state_t *st)
|
|
|
{
|
|
|
- if (unlikely (funcs == &Null (hb_draw_funcs_t) ||
|
|
|
- glyph >= font->face->get_num_glyphs ()))
|
|
|
- return false;
|
|
|
-
|
|
|
- draw_helper_t draw_helper (funcs, user_data);
|
|
|
- if (font->face->table.glyf->get_path (font, glyph, draw_helper)) return true;
|
|
|
-#ifndef HB_NO_CFF
|
|
|
- if (font->face->table.cff1->get_path (font, glyph, draw_helper)) return true;
|
|
|
- if (font->face->table.cff2->get_path (font, glyph, draw_helper)) return true;
|
|
|
-#endif
|
|
|
-
|
|
|
- return false;
|
|
|
+ dfuncs->close_path (draw_data, *st);
|
|
|
}
|
|
|
|
|
|
-#endif
|
|
|
+
|
|
|
#endif
|