[cairo] Recording final move_to in copy_path()

Behdad Esfahbod behdad at behdad.org
Wed Jan 15 21:48:06 PST 2014


On 14-01-16 03:59 AM, Uli Schlachter wrote:
> Hi,
> 
> On 15.01.2014 04:17, Behdad Esfahbod wrote:
>> Currently if one does cairo_copy_path(), any final move_to in the path is not
>> copied over.  This is unfortunate since copying the path and applying it later
>> does not leave the current point the way it was before.
>>
>> Unless there's any objections, I'm going to push the following patch that
>> fixes this:
>>
>> diff --git a/src/cairo-path-fixed.c b/src/cairo-path-fixed.c
>> index 14913fd..4143307 100644
>> --- a/src/cairo-path-fixed.c
>> +++ b/src/cairo-path-fixed.c
>> @@ -847,6 +847,9 @@ _cairo_path_fixed_interpret (const cairo_path_fixed_t
>>         }
>>      } cairo_path_foreach_buf_end (buf, path);
>>
>> +    if (path->has_current_point)
>> +       return (*move_to) (closure, &path->current_point);
>> +
>>      return CAIRO_STATUS_SUCCESS;
>>  }
> 
> This does not do what you want it to do, because cairo_move_to() implicitly
> calls cairo_new_sub_path() (see _cairo_path_fixed_move_to()). This means that
> e.g. no line join will be applied if the path is continued.
> 
> Thus, I guess you will need to some more complicated patch for this. Something
> that checks path->has_current_point and also checks if patch->last_move_point ==
> path->current_point (this is just a quick idea, no idea if it is correct).

Does this one look better?

diff --git a/src/cairo-path-fixed.c b/src/cairo-path-fixed.c
index 14913fd..390b43e 100644
--- a/src/cairo-path-fixed.c
+++ b/src/cairo-path-fixed.c
@@ -815,14 +815,16 @@ _cairo_path_fixed_interpret (const cairo_path_fixed_t
          *path,
                             void                               *closure)
 {
     const cairo_path_buf_t *buf;
-    cairo_status_t status;
+    cairo_path_op_t last_op = CAIRO_PATH_OP_CLOSE_PATH;

     cairo_path_foreach_buf_start (buf, path) {
        const cairo_point_t *points = buf->points;
        unsigned int i;
+       cairo_status_t status;

        for (i = 0; i < buf->num_ops; i++) {
-           switch (buf->op[i]) {
+           last_op = buf->op[i];
+           switch (last_op) {
            case CAIRO_PATH_OP_MOVE_TO:
                status = (*move_to) (closure, &points[0]);
                points += 1;
@@ -847,6 +849,9 @@ _cairo_path_fixed_interpret (const cairo_path_fixed_t
          *path,
        }
     } cairo_path_foreach_buf_end (buf, path);

+    if (path->has_current_point && last_op == CAIRO_PATH_OP_CLOSE_PATH)
+       return (*move_to) (closure, &path->current_point);
+
     return CAIRO_STATUS_SUCCESS;
 }

b


More information about the cairo mailing list