summaryrefslogtreecommitdiff
path: root/src/cairo-colr-glyph-render.c
diff options
context:
space:
mode:
authorAdrian Johnson <ajohnson@redneon.com>2023-01-08 10:08:14 +1030
committerAdrian Johnson <ajohnson@redneon.com>2023-01-08 15:15:13 +1030
commit2dfc52064ee9139333e741c998b0066aade9c538 (patch)
tree2cabec8b1f6932792b1e5e855fa2095d8bfba3f5 /src/cairo-colr-glyph-render.c
parent1129b194b5d65ee27df404106b1b5f51c3739e7e (diff)
downloadcairo-2dfc52064ee9139333e741c998b0066aade9c538.tar.gz
Use cairo-ft-font.c decompose function
Diffstat (limited to 'src/cairo-colr-glyph-render.c')
-rw-r--r--src/cairo-colr-glyph-render.c278
1 files changed, 26 insertions, 252 deletions
diff --git a/src/cairo-colr-glyph-render.c b/src/cairo-colr-glyph-render.c
index d55bed583..4a25f54af 100644
--- a/src/cairo-colr-glyph-render.c
+++ b/src/cairo-colr-glyph-render.c
@@ -32,6 +32,7 @@
#include "cairoint.h"
#include "cairo-array-private.h"
#include "cairo-ft-private.h"
+#include "cairo-path-private.h"
#include <assert.h>
#include <math.h>
@@ -181,242 +182,6 @@ cairo_extend (FT_PaintExtend extend)
}
/* }}} */
-/* {{{ Paths */
-
-typedef struct {
- cairo_array_t points;
- int needs_move;
- int last_move_op;
-} path_data_t;
-
-static cairo_status_t
-close_path (path_data_t *pdata)
-{
- cairo_path_data_t p;
- int status;
-
- if (pdata->last_move_op < 0)
- return CAIRO_STATUS_SUCCESS;
-
- p.header.type = CAIRO_PATH_LINE_TO;
- p.header.length = 2;
- status = _cairo_array_append (&pdata->points, &p);
- if (unlikely (status))
- return status;
-
- p = *(cairo_path_data_t *) _cairo_array_index (&pdata->points, pdata->last_move_op + 1);
- status = _cairo_array_append (&pdata->points, &p);
- if (unlikely (status))
- return status;
-
- p.header.type = CAIRO_PATH_CLOSE_PATH;
- p.header.length = 1;
- status = _cairo_array_append (&pdata->points, &p);
- if (unlikely (status))
- return status;
-
- pdata->needs_move = 1;
- pdata->last_move_op = -1;
-
- return CAIRO_STATUS_SUCCESS;
-}
-
-static int
-move_to (const FT_Vector *to,
- void *data)
-{
- path_data_t *pdata = data;
- cairo_path_data_t p;
- cairo_status_t status;
-
- status = close_path (pdata);
- if (unlikely (status))
- return status;
-
- pdata->needs_move = 0;
- pdata->last_move_op = pdata->points.num_elements;
-
- p.header.type = CAIRO_PATH_MOVE_TO;
- p.header.length = 2;
- status = _cairo_array_append (&pdata->points, &p);
- if (unlikely (status))
- return status;
-
- p.point.x = to->x / (float) (1 << 6);
- p.point.y = to->y / (float) (1 << 6);
- status = _cairo_array_append (&pdata->points, &p);
- if (unlikely (status))
- return status;
-
- return CAIRO_STATUS_SUCCESS;
-}
-
-static int
-line_to (const FT_Vector *to,
- void *data)
-{
- path_data_t *pdata = data;
- cairo_path_data_t p;
- cairo_status_t status;
-
- if (pdata->needs_move)
- return move_to (to, data);
-
- p.header.type = CAIRO_PATH_LINE_TO;
- p.header.length = 2;
- status = _cairo_array_append (&pdata->points, &p);
- if (unlikely (status))
- return status;
-
- p.point.x = to->x / (float) (1 << 6);
- p.point.y = to->y / (float) (1 << 6);
- status = _cairo_array_append (&pdata->points, &p);
- if (unlikely (status))
- return status;
-
- return CAIRO_STATUS_SUCCESS;
-}
-
-static int
-conic_to (const FT_Vector *control,
- const FT_Vector *to,
- void *data)
-{
- path_data_t *pdata = data;
- cairo_path_data_t p;
- double cx, cy;
- double x0, y0;
- double x1, y1;
- double x2, y2;
- double x3, y3;
- cairo_status_t status;
-
- assert (!pdata->needs_move);
- assert (pdata->points.num_elements > 0);
-
- p.header.type = CAIRO_PATH_CURVE_TO;
- p.header.length = 4;
- status = _cairo_array_append (&pdata->points, &p);
- if (unlikely (status))
- return status;
-
- p = *(cairo_path_data_t *) _cairo_array_index (&pdata->points, pdata->points.num_elements - 2);
-
- x0 = p.point.x;
- y0 = p.point.y;
-
- cx = control->x / (float) (1 << 6);
- cy = control->y / (float) (1 << 6);
-
- x3 = to->x / (float) (1 << 6);
- y3 = to->y / (float) (1 << 6);
-
- x1 = x0 + (2./3.) * (cx - x0);
- y1 = y0 + (2./3.) * (cy - y0);
-
- x2 = x3 + (2./3.) * (cx - x3);
- y2 = y3 + (2./3.) * (cy - y3);
-
- p.point.x = x1;
- p.point.y = y1;
- status = _cairo_array_append (&pdata->points, &p);
- if (unlikely (status))
- return status;
-
- p.point.x = x2;
- p.point.y = y2;
- status = _cairo_array_append (&pdata->points, &p);
- if (unlikely (status))
- return status;
-
- p.point.x = x3;
- p.point.y = y3;
- status = _cairo_array_append (&pdata->points, &p);
- if (unlikely (status))
- return status;
-
- return CAIRO_STATUS_SUCCESS;
-}
-
-static int
-cubic_to (const FT_Vector *control1,
- const FT_Vector *control2,
- const FT_Vector *to,
- void *data)
-{
- path_data_t *pdata = data;
- cairo_path_data_t p;
- cairo_status_t status;
-
- assert (!pdata->needs_move);
- assert (pdata->points.num_elements > 0);
-
- p.header.type = CAIRO_PATH_CURVE_TO;
- p.header.length = 4;
- status = _cairo_array_append (&pdata->points, &p);
- if (unlikely (status))
- return status;
-
- p.point.x = control1->x / (float) (1 << 6);
- p.point.y = control1->y / (float) (1 << 6);
- status = _cairo_array_append (&pdata->points, &p);
- if (unlikely (status))
- return status;
-
- p.point.x = control2->x / (float) (1 << 6);
- p.point.y = control2->y / (float) (1 << 6);
- status = _cairo_array_append (&pdata->points, &p);
- if (unlikely (status))
- return status;
-
- p.point.x = to->x / (float) (1 << 6);
- p.point.y = to->y / (float) (1 << 6);
- status = _cairo_array_append (&pdata->points, &p);
- if (unlikely (status))
- return status;
-
- return CAIRO_STATUS_SUCCESS;
-}
-
-static cairo_status_t
-get_path_for_glyph (FT_Face face,
- unsigned int glyph,
- cairo_path_t **path)
-{
- path_data_t pdata;
- FT_Outline_Funcs callbacks = {
- move_to, line_to, conic_to, cubic_to, 0, 0
- };
- FT_Error error;
-
- *path = NULL;
-
- error = FT_Load_Glyph (face, glyph, FT_LOAD_DEFAULT);
- if (error != 0)
- return CAIRO_STATUS_INVALID_PATH_DATA;
-
- _cairo_array_init (&pdata.points, sizeof (cairo_path_data_t));
- pdata.needs_move = 1;
- pdata.last_move_op = -1;
-
- if (FT_Outline_Decompose (&face->glyph->outline, &callbacks, &pdata) != 0)
- {
- _cairo_array_fini (&pdata.points);
- return CAIRO_STATUS_INVALID_PATH_DATA;
- }
-
- close_path (&pdata);
-
- *path = _cairo_malloc (sizeof (cairo_path_t));
- if (unlikely (path == NULL))
- return CAIRO_STATUS_NO_MEMORY;
-
- (*path)->status = CAIRO_STATUS_SUCCESS;
- (*path)->data = (cairo_path_data_t *) pdata.points.elements;
- (*path)->num_data = pdata.points.num_elements;
-
- return CAIRO_STATUS_SUCCESS;
-}
/* }}} */
@@ -1104,33 +869,42 @@ draw_paint_glyph (cairo_colr_glyph_render_t *render,
FT_PaintGlyph *glyph,
cairo_t *cr)
{
- cairo_path_t *path;
- cairo_status_t status = CAIRO_STATUS_SUCCESS;
+ cairo_path_fixed_t *path_fixed;
+ cairo_path_t *path;
+ cairo_status_t status = CAIRO_STATUS_SUCCESS;
+ FT_Error error;
#if DEBUG_COLR
- printf ("%*sDraw PaintGlyph\n", 2 * render->level, "");
+ printf ("%*sDraw PaintGlyph\n", 2 * render->level, "");
#endif
- status = get_path_for_glyph (render->face, glyph->glyphID, &path);
- if (unlikely (status))
- goto cleanup;
+ error = FT_Load_Glyph (render->face, glyph->glyphID, FT_LOAD_DEFAULT);
+ status = _cairo_ft_to_cairo_error (error);
+ if (unlikely (status))
+ return status;
- cairo_save (cr);
+ status = _cairo_ft_face_decompose_glyph_outline (render->face, &path_fixed);
+ if (unlikely (status))
+ return status;
- cairo_new_path (cr);
- cairo_append_path (cr, path);
- cairo_clip (cr);
+ cairo_save (cr);
+ cairo_identity_matrix (cr);
+ path = _cairo_path_create (path_fixed, cr);
+ _cairo_path_fixed_destroy (path_fixed);
+ cairo_restore (cr);
- status = draw_paint (render, &glyph->paint, cr);
+ cairo_save (cr);
- cairo_restore (cr);
+ cairo_new_path (cr);
+ cairo_append_path (cr, path);
+ cairo_path_destroy (path);
+ cairo_clip (cr);
-cleanup:
+ status = draw_paint (render, &glyph->paint, cr);
- if (path)
- cairo_path_destroy (path);
+ cairo_restore (cr);
- return status;
+ return status;
}
static cairo_status_t draw_colr_glyph (cairo_colr_glyph_render_t *render,