コード例 #1
0
ファイル: cairo-freelist.c プロジェクト: lofter2011/Icefox
void *
_cairo_freepool_alloc_from_new_pool (cairo_freepool_t *freepool)
{
    cairo_freelist_pool_t *pool;
    int poolsize;

    if (freepool->pools != &freepool->embedded_pool)
        poolsize = 2 * freepool->pools->size;
    else
        poolsize = (128 * freepool->nodesize + 8191) & -8192;
    pool = malloc (sizeof (cairo_freelist_pool_t) + poolsize);
    if (unlikely (pool == NULL))
        return pool;

    pool->next = freepool->pools;
    freepool->pools = pool;

    pool->size = poolsize;
    pool->rem = poolsize - freepool->nodesize;
    pool->data = (uint8_t *) (pool + 1) + freepool->nodesize;

    VG (VALGRIND_MAKE_MEM_NOACCESS (pool->data, poolsize));
    VG (VALGRIND_MAKE_MEM_UNDEFINED (pool->data, freepool->nodesize));

    return pool + 1;
}
コード例 #2
0
ファイル: cairo-freelist.c プロジェクト: popekim/cairo-vs
cairo_status_t
_cairo_freepool_alloc_array (cairo_freepool_t *freepool,
                             int count,
                             void **array)
{
    int i;

    for (i = 0; i < count; i++) {
        cairo_freelist_node_t *node;

        node = freepool->first_free_node;
        if (likely (node != NULL)) {
            VG (VALGRIND_MAKE_MEM_DEFINED (node, sizeof (node->next)));
            freepool->first_free_node = node->next;
            VG (VALGRIND_MAKE_MEM_UNDEFINED (node, freepool->nodesize));
        } else {
            node = _cairo_freepool_alloc_from_pool (freepool);
            if (unlikely (node == NULL))
                goto CLEANUP;
        }

        array[i] = node;
    }

    return CAIRO_STATUS_SUCCESS;

CLEANUP:
    while (i--)
        _cairo_freepool_free (freepool, array[i]);

    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
コード例 #3
0
ファイル: cairo-stroke-style.c プロジェクト: ublisa/cairo
cairo_status_t
_cairo_stroke_style_init_copy (cairo_stroke_style_t *style,
			       const cairo_stroke_style_t *other)
{
    if (CAIRO_INJECT_FAULT ())
	return _cairo_error (CAIRO_STATUS_NO_MEMORY);

    VG (VALGRIND_MAKE_MEM_UNDEFINED (style, sizeof (cairo_stroke_style_t)));

    style->line_width = other->line_width;
    style->line_cap = other->line_cap;
    style->line_join = other->line_join;
    style->miter_limit = other->miter_limit;

    style->num_dashes = other->num_dashes;

    if (other->dash == NULL) {
	style->dash = NULL;
    } else {
	style->dash = _cairo_malloc_ab (style->num_dashes, sizeof (double));
	if (unlikely (style->dash == NULL))
	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);

	memcpy (style->dash, other->dash,
		style->num_dashes * sizeof (double));
    }

    style->dash_offset = other->dash_offset;

    return CAIRO_STATUS_SUCCESS;
}
コード例 #4
0
ファイル: cairo-pen.c プロジェクト: Distrotech/cairo
cairo_status_t
_cairo_pen_init_copy (cairo_pen_t *pen, const cairo_pen_t *other)
{
    VG (VALGRIND_MAKE_MEM_UNDEFINED (pen, sizeof (cairo_pen_t)));

    *pen = *other;

    if (CAIRO_INJECT_FAULT ())
	return _cairo_error (CAIRO_STATUS_NO_MEMORY);

    pen->vertices = pen->vertices_embedded;
    if (pen->num_vertices) {
	if (pen->num_vertices > ARRAY_LENGTH (pen->vertices_embedded)) {
	    pen->vertices = _cairo_malloc_ab (pen->num_vertices,
					      sizeof (cairo_pen_vertex_t));
	    if (unlikely (pen->vertices == NULL))
		return _cairo_error (CAIRO_STATUS_NO_MEMORY);
	}

	memcpy (pen->vertices, other->vertices,
		pen->num_vertices * sizeof (cairo_pen_vertex_t));
    }

    return CAIRO_STATUS_SUCCESS;
}
コード例 #5
0
ファイル: caller.cpp プロジェクト: arrogantrobot/vg
void Caller::clear() {
    _node_calls.clear();
    _call_graph = VG();
    _start_node_map.clear();
    _end_node_map.clear();
    _visited_nodes.clear();
}
コード例 #6
0
void
_cairo_path_fixed_init (cairo_path_fixed_t *path)
{
    VG (VALGRIND_MAKE_MEM_UNDEFINED (path, sizeof (cairo_path_fixed_t)));

    cairo_list_init (&path->buf.base.link);

    path->buf.base.num_ops = 0;
    path->buf.base.num_points = 0;
    path->buf.base.size_ops = ARRAY_LENGTH (path->buf.op);
    path->buf.base.size_points = ARRAY_LENGTH (path->buf.points);
    path->buf.base.op = path->buf.op;
    path->buf.base.points = path->buf.points;

    path->current_point.x = 0;
    path->current_point.y = 0;
    path->last_move_point = path->current_point;
    path->has_last_move_point = FALSE;
    path->has_current_point = FALSE;
    path->has_curve_to = FALSE;
    path->is_rectilinear = TRUE;
    path->maybe_fill_region = TRUE;
    path->is_empty_fill = TRUE;

    path->extents.p1.x = path->extents.p1.y = INT_MAX;
    path->extents.p2.x = path->extents.p2.y = INT_MIN;
}
コード例 #7
0
ファイル: cairo-freelist.c プロジェクト: popekim/cairo-vs
void *
_cairo_freelist_alloc (cairo_freelist_t *freelist)
{
    if (freelist->first_free_node) {
        cairo_freelist_node_t *node;

        node = freelist->first_free_node;
        VG (VALGRIND_MAKE_MEM_DEFINED (node, sizeof (node->next)));
        freelist->first_free_node = node->next;
        VG (VALGRIND_MAKE_MEM_UNDEFINED (node, freelist->nodesize));

        return node;
    }

    return malloc (freelist->nodesize);
}
コード例 #8
0
void
_cairo_region_fini (cairo_region_t *region)
{
    assert (! CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&region->ref_count));
    pixman_region32_fini (&region->rgn);
    VG (VALGRIND_MAKE_MEM_NOACCESS (region, sizeof (cairo_region_t)));
}
コード例 #9
0
ファイル: testgamma.cpp プロジェクト: allenday/libmaus
void testRandom(unsigned int const n)
{
	srand(time(0));
	std::vector<uint64_t> V(n);
	for ( uint64_t i = 0; i <n; ++i )
		V[i] = rand();

	::libmaus::timing::RealTimeClock rtc; 
	
	rtc.start();
	CountPut CP;
	::libmaus::gamma::GammaEncoder< CountPut > GCP(CP);	
	for ( uint64_t i = 0; i < n; ++i )
		GCP.encode(V[i]);
	GCP.flush();
	double const cencsecs = rtc.getElapsedSeconds();
	std::cerr << "[V] count encoded " << n << " numbers in time " << cencsecs 
		<< " rate " << (n / cencsecs)/(1000*1000) << " m/s"
		<< " output words " << CP.cnt
		<< std::endl;
	
	VectorPut<uint64_t> VP;
	rtc.start();
	::libmaus::gamma::GammaEncoder< VectorPut<uint64_t> > GE(VP);	
	for ( uint64_t i = 0; i < n; ++i )
		GE.encode(V[i]);
	GE.flush();
	double const encsecs = rtc.getElapsedSeconds();
	std::cerr << "[V] encoded " << n << " numbers to dyn growing vector in time " << encsecs 
		<< " rate " << (n / encsecs)/(1000*1000) << " m/s"
		<< std::endl;

	rtc.start();
	VectorGet<uint64_t> VG(VP.begin());
	::libmaus::gamma::GammaDecoder < VectorGet<uint64_t> > GD(VG);
	bool ok = true;
	for ( uint64_t i = 0; ok && i < n; ++i )
	{
		uint64_t const v = GD.decode();
		ok = ok && (v==V[i]);
		if ( ! ok )
		{
			std::cerr << "expected " << V[i] << " got " << v << std::endl;
		}
	}
	double const decsecs = rtc.getElapsedSeconds();
	std::cerr << "[V] decoded " << n << " numbers in time " << decsecs
		<< " rate " << (n / decsecs)/(1000*1000) << " m/s"
		<< std::endl;
	
	if ( ok )
	{
		std::cout << "Test of gamma coding with " << n << " random numbers ok." << std::endl;
	}
	else
	{
		std::cout << "Test of gamma coding with " << n << " random numbers failed." << std::endl;
	}
}
コード例 #10
0
ファイル: cairo-polygon.c プロジェクト: mgya/xCairo
void
_cairo_polygon_fini (cairo_polygon_t *polygon)
{
    if (polygon->edges != polygon->edges_embedded)
	xmemory_free (polygon->edges);

    VG (VALGRIND_MAKE_MEM_NOACCESS (polygon, sizeof (cairo_polygon_t)));
}
コード例 #11
0
ファイル: cairo-traps.c プロジェクト: Distrotech/cairo
void
_cairo_traps_fini (cairo_traps_t *traps)
{
    if (traps->traps != traps->traps_embedded)
	free (traps->traps);

    VG (VALGRIND_MAKE_MEM_UNDEFINED (traps, sizeof (cairo_traps_t)));
}
コード例 #12
0
void
_cairo_region_init (cairo_region_t *region)
{
    VG (VALGRIND_MAKE_MEM_UNDEFINED (region, sizeof (cairo_region_t)));

    region->status = CAIRO_STATUS_SUCCESS;
    CAIRO_REFERENCE_COUNT_INIT (&region->ref_count, 0);
    pixman_region32_init (&region->rgn);
}
コード例 #13
0
ファイル: cairo-pen.c プロジェクト: Distrotech/cairo
void
_cairo_pen_fini (cairo_pen_t *pen)
{
    if (pen->vertices != pen->vertices_embedded)
	free (pen->vertices);


    VG (VALGRIND_MAKE_MEM_UNDEFINED (pen, sizeof (cairo_pen_t)));
}
コード例 #14
0
ファイル: cairo-freelist.c プロジェクト: popekim/cairo-vs
void
_cairo_freelist_free (cairo_freelist_t *freelist, void *voidnode)
{
    cairo_freelist_node_t *node = voidnode;
    if (node) {
        node->next = freelist->first_free_node;
        freelist->first_free_node = node;
        VG (VALGRIND_MAKE_MEM_UNDEFINED (node, freelist->nodesize));
    }
}
コード例 #15
0
ファイル: cairo-stroke-style.c プロジェクト: ublisa/cairo
void
_cairo_stroke_style_fini (cairo_stroke_style_t *style)
{
    free (style->dash);
    style->dash = NULL;

    style->num_dashes = 0;

    VG (VALGRIND_MAKE_MEM_UNDEFINED (style, sizeof (cairo_stroke_style_t)));
}
コード例 #16
0
ファイル: cairo-freelist.c プロジェクト: lofter2011/Icefox
void
_cairo_freepool_fini (cairo_freepool_t *freepool)
{
    cairo_freelist_pool_t *pool = freepool->pools;
    while (pool != &freepool->embedded_pool) {
        cairo_freelist_pool_t *next = pool->next;
        free (pool);
        pool = next;
    }
    VG (VALGRIND_MAKE_MEM_NOACCESS (freepool, sizeof (freepool)));
}
コード例 #17
0
ファイル: cairo-pen.c プロジェクト: Distrotech/cairo
cairo_status_t
_cairo_pen_init (cairo_pen_t	*pen,
		 double		 radius,
		 double		 tolerance,
		 const cairo_matrix_t	*ctm)
{
    int i;
    int reflect;

    if (CAIRO_INJECT_FAULT ())
	return _cairo_error (CAIRO_STATUS_NO_MEMORY);

    VG (VALGRIND_MAKE_MEM_UNDEFINED (pen, sizeof (cairo_pen_t)));

    pen->radius = radius;
    pen->tolerance = tolerance;

    reflect = _cairo_matrix_compute_determinant (ctm) < 0.;

    pen->num_vertices = _cairo_pen_vertices_needed (tolerance,
						    radius,
						    ctm);

    if (pen->num_vertices > ARRAY_LENGTH (pen->vertices_embedded)) {
	pen->vertices = _cairo_malloc_ab (pen->num_vertices,
					  sizeof (cairo_pen_vertex_t));
	if (unlikely (pen->vertices == NULL))
	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
    } else {
	pen->vertices = pen->vertices_embedded;
    }

    /*
     * Compute pen coordinates.  To generate the right ellipse, compute points around
     * a circle in user space and transform them to device space.  To get a consistent
     * orientation in device space, flip the pen if the transformation matrix
     * is reflecting
     */
    for (i=0; i < pen->num_vertices; i++) {
	cairo_pen_vertex_t *v = &pen->vertices[i];
	double theta = 2 * M_PI * i / (double) pen->num_vertices, dx, dy;
	if (reflect)
	    theta = -theta;
	dx = radius * cos (theta);
	dy = radius * sin (theta);
	cairo_matrix_transform_distance (ctm, &dx, &dy);
	v->point.x = _cairo_fixed_from_double (dx);
	v->point.y = _cairo_fixed_from_double (dy);
    }

    _cairo_pen_compute_slopes (pen);

    return CAIRO_STATUS_SUCCESS;
}
コード例 #18
0
void
_cairo_region_init_rectangle (cairo_region_t *region,
			      const cairo_rectangle_int_t *rectangle)
{
    VG (VALGRIND_MAKE_MEM_UNDEFINED (region, sizeof (cairo_region_t)));

    region->status = CAIRO_STATUS_SUCCESS;
    CAIRO_REFERENCE_COUNT_INIT (&region->ref_count, 0);
    pixman_region32_init_rect (&region->rgn,
			       rectangle->x, rectangle->y,
			       rectangle->width, rectangle->height);
}
コード例 #19
0
ファイル: cairo-stroke-style.c プロジェクト: ublisa/cairo
void
_cairo_stroke_style_init (cairo_stroke_style_t *style)
{
    VG (VALGRIND_MAKE_MEM_UNDEFINED (style, sizeof (cairo_stroke_style_t)));

    style->line_width = CAIRO_GSTATE_LINE_WIDTH_DEFAULT;
    style->line_cap = CAIRO_GSTATE_LINE_CAP_DEFAULT;
    style->line_join = CAIRO_GSTATE_LINE_JOIN_DEFAULT;
    style->miter_limit = CAIRO_GSTATE_MITER_LIMIT_DEFAULT;

    style->dash = NULL;
    style->num_dashes = 0;
    style->dash_offset = 0.0;
}
コード例 #20
0
ファイル: cairo-freelist.c プロジェクト: popekim/cairo-vs
void
_cairo_freelist_fini (cairo_freelist_t *freelist)
{
    cairo_freelist_node_t *node = freelist->first_free_node;
    while (node) {
        cairo_freelist_node_t *next;

        VG (VALGRIND_MAKE_MEM_DEFINED (node, sizeof (node->next)));
        next = node->next;

        free (node);
        node = next;
    }
}
コード例 #21
0
ファイル: cairo-freelist.c プロジェクト: popekim/cairo-vs
void
_cairo_freepool_init (cairo_freepool_t *freepool, unsigned nodesize)
{
    freepool->first_free_node = NULL;
    freepool->pools = &freepool->embedded_pool;
    freepool->freepools = NULL;
    freepool->nodesize = nodesize;

    freepool->embedded_pool.next = NULL;
    freepool->embedded_pool.size = sizeof (freepool->embedded_data);
    freepool->embedded_pool.rem = sizeof (freepool->embedded_data);
    freepool->embedded_pool.data = freepool->embedded_data;

    VG (VALGRIND_MAKE_MEM_UNDEFINED (freepool->embedded_data, sizeof (freepool->embedded_data)));
}
コード例 #22
0
ファイル: cairo-polygon.c プロジェクト: mgya/xCairo
cairo_status_t
_cairo_polygon_init_boxes (cairo_polygon_t *polygon,
			   const cairo_boxes_t *boxes)
{
    const struct _cairo_boxes_chunk *chunk;
    int i;

    VG (VALGRIND_MAKE_MEM_UNDEFINED (polygon, sizeof (cairo_polygon_t)));

    polygon->status = CAIRO_STATUS_SUCCESS;

    polygon->num_edges = 0;

    polygon->edges = polygon->edges_embedded;
    polygon->edges_size = ARRAY_LENGTH (polygon->edges_embedded);
    if (boxes->num_boxes > ARRAY_LENGTH (polygon->edges_embedded)/2) {
	polygon->edges_size = 2 * boxes->num_boxes;
	polygon->edges = _cairo_malloc_ab (polygon->edges_size,
					   2*sizeof(cairo_edge_t));
	if (unlikely (polygon->edges == XNULL))
	    return polygon->status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
    }

    polygon->extents.p1.x = polygon->extents.p1.y = INT32_MAX;
    polygon->extents.p2.x = polygon->extents.p2.y = INT32_MIN;

    polygon->limits = XNULL;
    polygon->num_limits = 0;

    for (chunk = &boxes->chunks; chunk != XNULL; chunk = chunk->next) {
	for (i = 0; i < chunk->count; i++) {
	    cairo_point_t p1, p2;

	    p1 = chunk->base[i].p1;
	    p2.x = p1.x;
	    p2.y = chunk->base[i].p2.y;
	    _cairo_polygon_add_edge (polygon, &p1, &p2, 1);

	    p1 = chunk->base[i].p2;
	    p2.x = p1.x;
	    p2.y = chunk->base[i].p1.y;
	    _cairo_polygon_add_edge (polygon, &p1, &p2, 1);
	}
    }

    return polygon->status;
}
コード例 #23
0
ファイル: cairo-polygon.c プロジェクト: mgya/xCairo
cairo_status_t
_cairo_polygon_init_box_array (cairo_polygon_t *polygon,
			       cairo_box_t *boxes,
			       int num_boxes)
{
    int i;

    VG (VALGRIND_MAKE_MEM_UNDEFINED (polygon, sizeof (cairo_polygon_t)));

    polygon->status = CAIRO_STATUS_SUCCESS;

    polygon->num_edges = 0;

    polygon->edges = polygon->edges_embedded;
    polygon->edges_size = ARRAY_LENGTH (polygon->edges_embedded);
    if (num_boxes > ARRAY_LENGTH (polygon->edges_embedded)/2) {
	polygon->edges_size = 2 * num_boxes;
	polygon->edges = _cairo_malloc_ab (polygon->edges_size,
					   2*sizeof(cairo_edge_t));
	if (unlikely (polygon->edges == XNULL))
	    return polygon->status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
    }

    polygon->extents.p1.x = polygon->extents.p1.y = INT32_MAX;
    polygon->extents.p2.x = polygon->extents.p2.y = INT32_MIN;

    polygon->limits = XNULL;
    polygon->num_limits = 0;

    for (i = 0; i < num_boxes; i++) {
	cairo_point_t p1, p2;

	p1 = boxes[i].p1;
	p2.x = p1.x;
	p2.y = boxes[i].p2.y;
	_cairo_polygon_add_edge (polygon, &p1, &p2, 1);

	p1 = boxes[i].p2;
	p2.x = p1.x;
	p2.y = boxes[i].p1.y;
	_cairo_polygon_add_edge (polygon, &p1, &p2, 1);
    }

    return polygon->status;
}
コード例 #24
0
ファイル: anv_gem.c プロジェクト: ndesh26/Mesa
/**
 * Wrapper around DRM_IOCTL_I915_GEM_MMAP. Returns MAP_FAILED on error.
 */
void*
anv_gem_mmap(struct anv_device *device, uint32_t gem_handle,
             uint64_t offset, uint64_t size, uint32_t flags)
{
   struct drm_i915_gem_mmap gem_mmap = {
      .handle = gem_handle,
      .offset = offset,
      .size = size,
      .flags = flags,
   };

   int ret = anv_ioctl(device->fd, DRM_IOCTL_I915_GEM_MMAP, &gem_mmap);
   if (ret != 0)
      return MAP_FAILED;

   VG(VALGRIND_MALLOCLIKE_BLOCK(gem_mmap.addr_ptr, gem_mmap.size, 0, 1));
   return (void *)(uintptr_t) gem_mmap.addr_ptr;
}
コード例 #25
0
ファイル: cairo-polygon.c プロジェクト: 499940913/moon
void
_cairo_polygon_init (cairo_polygon_t *polygon)
{
    VG (VALGRIND_MAKE_MEM_UNDEFINED (polygon, sizeof (cairo_polygon_t)));

    polygon->status = CAIRO_STATUS_SUCCESS;

    polygon->num_edges = 0;

    polygon->edges = polygon->edges_embedded;
    polygon->edges_size = ARRAY_LENGTH (polygon->edges_embedded);

    polygon->has_current_point = FALSE;
    polygon->has_current_edge = FALSE;
    polygon->num_limits = 0;

    polygon->extents.p1.x = polygon->extents.p1.y = INT32_MAX;
    polygon->extents.p2.x = polygon->extents.p2.y = INT32_MIN;
}
コード例 #26
0
ファイル: cairo-polygon.c プロジェクト: mgya/xCairo
void
_cairo_polygon_init (cairo_polygon_t *polygon,
		     const cairo_box_t *limits,
		     int num_limits)
{
    VG (VALGRIND_MAKE_MEM_UNDEFINED (polygon, sizeof (cairo_polygon_t)));

    polygon->status = CAIRO_STATUS_SUCCESS;

    polygon->num_edges = 0;

    polygon->edges = polygon->edges_embedded;
    polygon->edges_size = ARRAY_LENGTH (polygon->edges_embedded);

    polygon->extents.p1.x = polygon->extents.p1.y = INT32_MAX;
    polygon->extents.p2.x = polygon->extents.p2.y = INT32_MIN;

    _cairo_polygon_limit (polygon, limits, num_limits);
}
コード例 #27
0
ファイル: cairo-traps.c プロジェクト: Distrotech/cairo
void
_cairo_traps_init (cairo_traps_t *traps)
{
    VG (VALGRIND_MAKE_MEM_UNDEFINED (traps, sizeof (cairo_traps_t)));

    traps->status = CAIRO_STATUS_SUCCESS;

    traps->maybe_region = 1;
    traps->is_rectilinear = 0;
    traps->is_rectangular = 0;

    traps->num_traps = 0;

    traps->traps_size = ARRAY_LENGTH (traps->traps_embedded);
    traps->traps = traps->traps_embedded;

    traps->num_limits = 0;
    traps->has_intersections = FALSE;
}
コード例 #28
0
ファイル: cairo-freelist.c プロジェクト: popekim/cairo-vs
void
_cairo_freepool_fini (cairo_freepool_t *freepool)
{
    cairo_freelist_pool_t *pool;

    pool = freepool->pools;
    while (pool != &freepool->embedded_pool) {
        cairo_freelist_pool_t *next = pool->next;
        free (pool);
        pool = next;
    }

    pool = freepool->freepools;
    while (pool != NULL) {
        cairo_freelist_pool_t *next = pool->next;
        free (pool);
        pool = next;
    }

    VG (VALGRIND_MAKE_MEM_UNDEFINED (freepool, sizeof (freepool)));
}
コード例 #29
0
ファイル: testgamma.cpp プロジェクト: allenday/libmaus
void testLow()
{
	unsigned int const n = 127;
	VectorPut<uint64_t> VP;
	::libmaus::gamma::GammaEncoder< VectorPut<uint64_t> > GE(VP);	
	for ( uint64_t i = 0; i < n; ++i )
		GE.encode(i);
	GE.flush();
	
	VectorGet<uint64_t> VG(VP.begin());
	::libmaus::gamma::GammaDecoder < VectorGet<uint64_t> > GD(VG);
	bool ok = true;
	for ( uint64_t i = 0; ok && i < n; ++i )
		ok = ok && ( GD.decode() == i );

	if ( ok )
	{
		std::cout << "Test of gamma coding with numbers up to 126 ok." << std::endl;
	}
	else
	{
		std::cout << "Test of gamma coding with numbers up to 126 failed." << std::endl;
	}
}
コード例 #30
0
cairo_status_t
_cairo_path_fixed_init_copy (cairo_path_fixed_t *path,
			     const cairo_path_fixed_t *other)
{
    cairo_path_buf_t *buf, *other_buf;
    unsigned int num_points, num_ops;

    VG (VALGRIND_MAKE_MEM_UNDEFINED (path, sizeof (cairo_path_fixed_t)));

    cairo_list_init (&path->buf.base.link);

    path->buf.base.op = path->buf.op;
    path->buf.base.points = path->buf.points;
    path->buf.base.size_ops = ARRAY_LENGTH (path->buf.op);
    path->buf.base.size_points = ARRAY_LENGTH (path->buf.points);

    path->current_point = other->current_point;
    path->last_move_point = other->last_move_point;
    path->has_last_move_point = other->has_last_move_point;
    path->has_current_point = other->has_current_point;
    path->has_curve_to = other->has_curve_to;
    path->is_rectilinear = other->is_rectilinear;
    path->maybe_fill_region = other->maybe_fill_region;
    path->is_empty_fill = other->is_empty_fill;

    path->extents = other->extents;

    path->buf.base.num_ops = other->buf.base.num_ops;
    path->buf.base.num_points = other->buf.base.num_points;
    memcpy (path->buf.op, other->buf.base.op,
	    other->buf.base.num_ops * sizeof (other->buf.op[0]));
    memcpy (path->buf.points, other->buf.points,
	    other->buf.base.num_points * sizeof (other->buf.points[0]));

    num_points = num_ops = 0;
    for (other_buf = cairo_path_buf_next (cairo_path_head (other));
	 other_buf != cairo_path_head (other);
	 other_buf = cairo_path_buf_next (other_buf))
    {
	num_ops    += other_buf->num_ops;
	num_points += other_buf->num_points;
    }

    if (num_ops) {
	buf = _cairo_path_buf_create (num_ops, num_points);
	if (unlikely (buf == NULL)) {
	    _cairo_path_fixed_fini (path);
	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
	}

	for (other_buf = cairo_path_buf_next (cairo_path_head (other));
	     other_buf != cairo_path_head (other);
	     other_buf = cairo_path_buf_next (other_buf))
	{
	    memcpy (buf->op + buf->num_ops, other_buf->op,
		    other_buf->num_ops * sizeof (buf->op[0]));
	    buf->num_ops += other_buf->num_ops;

	    memcpy (buf->points + buf->num_points, other_buf->points,
		    other_buf->num_points * sizeof (buf->points[0]));
	    buf->num_points += other_buf->num_points;
	}

	_cairo_path_fixed_add_buf (path, buf);
    }

    return CAIRO_STATUS_SUCCESS;
}