Synopsis

#include <cpml-1/cpml.h>

struct              CpmlSegment;
int                 cpml_segment_from_cairo             (CpmlSegment *segment,
                                                         cairo_path_t *path);
void                cpml_segment_copy                   (CpmlSegment *segment,
                                                         const CpmlSegment *src);
void                cpml_segment_reset                  (CpmlSegment *segment);
int                 cpml_segment_next                   (CpmlSegment *segment);
double              cpml_segment_get_length             (const CpmlSegment *segment);
void                cpml_segment_put_extents            (const CpmlSegment *segment,
                                                         CpmlExtents *extents);
void                cpml_segment_put_pair_at            (const CpmlSegment *segment,
                                                         double pos,
                                                         CpmlPair *pair);
void                cpml_segment_put_vector_at          (const CpmlSegment *segment,
                                                         double pos,
                                                         CpmlVector *vector);
size_t              cpml_segment_put_intersections      (const CpmlSegment *segment,
                                                         const CpmlSegment *segment2,
                                                         size_t n_dest,
                                                         CpmlPair *dest);
void                cpml_segment_offset                 (CpmlSegment *segment,
                                                         double offset);
void                cpml_segment_transform              (CpmlSegment *segment,
                                                         const cairo_matrix_t *matrix);
void                cpml_segment_reverse                (CpmlSegment *segment);
void                cpml_segment_to_cairo               (const CpmlSegment *segment,
                                                         cairo_t *cr);
void                cpml_segment_dump                   (const CpmlSegment *segment);

Description

A segment is a single contiguous line got from a cairo path. The CPML library relies on one assumption to let the data be independent from the current point (and thus from the cairo context): any segment MUST be preceded by at least one CPML_MOVE primitive. This means a valid segment in cairo could be rejected by CPML.

CpmlSegment provides an unobtrusive way to access a cairo path. This means CpmlSegment itsself does not hold any coordinates but instead a bunch of pointers to the original cairo_path_t struct: modifying data throught this struct also changes the original path.

Every cairo_path_t struct can contain more than one segment: the CPML library provides iteration APIs to browse the segments of a path. Use cpml_segment_reset() to reset the iterator at the start of the cairo path (will point the first segment) and cpml_segment_next() to get the next segment. Getting the previous segment is not provided as the underlying cairo struct is not accessible in reverse order.

When initialized, CpmlSegment yet refers to the first segment so the initial reset is not required.

Details

struct CpmlSegment

struct CpmlSegment {
    cairo_path_t      *path;
    cairo_path_data_t *data;
    int                num_data;
};

This is an unobtrusive struct to identify a segment inside a cairo path. Unobtrusive means that the real coordinates are still stored in path: CpmlSegment only provides a way to access them.

cairo_path_t *path;

the source cairo_path_t struct

cairo_path_data_t *data;

the data points of the segment; the first primitive will always be a CPML_MOVE

int num_data;

size of data

Since 1.0


cpml_segment_from_cairo ()

int                 cpml_segment_from_cairo             (CpmlSegment *segment,
                                                         cairo_path_t *path);

Builds a CpmlSegment from a cairo_path_t structure. This operation involves stripping the duplicate CPML_MOVE primitives at the start of the path and setting num_data field to the end of the contiguous line, that is when another CPML_MOVE primitive is found or at the end of the path. A pointer to the source cairo path is kept though.

This function will fail if path is null, empty or if its status member is not CAIRO_STATUS_SUCCESS. Also, the first primitive must be a CPML_MOVE, so no dependency on the cairo context is needed.

segment :

a CpmlSegment

path :

the source cairo_path_t. [type gpointer]

Returns :

1 if segment has been succesfully computed, 0 on errors. [type gboolean]

Since 1.0


cpml_segment_copy ()

void                cpml_segment_copy                   (CpmlSegment *segment,
                                                         const CpmlSegment *src);

Makes a shallow copy of src into segment.

segment :

a CpmlSegment

src :

the source segment to copy

Since 1.0


cpml_segment_reset ()

void                cpml_segment_reset                  (CpmlSegment *segment);

Modifies segment to point to the first segment of the source cairo path.

segment :

a CpmlSegment

Since 1.0


cpml_segment_next ()

int                 cpml_segment_next                   (CpmlSegment *segment);

Modifies segment to point to the next segment of the source cairo path.

segment :

a CpmlSegment

Returns :

1 on success, 0 if no next segment found or errors. [type gboolean]

Since 1.0


cpml_segment_get_length ()

double              cpml_segment_get_length             (const CpmlSegment *segment);

Gets the whole length of segment.

segment :

a CpmlSegment

Returns :

the requested length

Since 1.0


cpml_segment_put_extents ()

void                cpml_segment_put_extents            (const CpmlSegment *segment,
                                                         CpmlExtents *extents);

Gets the whole extents of segment.

segment :

a CpmlSegment

extents :

where to store the extents

Since 1.0


cpml_segment_put_pair_at ()

void                cpml_segment_put_pair_at            (const CpmlSegment *segment,
                                                         double pos,
                                                         CpmlPair *pair);

Gets the coordinates of the point lying on segment at position pos. pos is an homogeneous factor where 0 is the start point, 1 the end point, 0.5 the mid point and so on. The relation 0 < pos < 1 should be satisfied, although some cases accept value outside this range.

TODO

  • The actual implementation returns only the start and end points, that is only when pos is 0 or 1.

segment :

a CpmlSegment

pos :

the position value

pair :

the destination CpmlPair

Since 1.0


cpml_segment_put_vector_at ()

void                cpml_segment_put_vector_at          (const CpmlSegment *segment,
                                                         double pos,
                                                         CpmlVector *vector);

Gets the steepness of the point lying on segment at position pos. pos is an homogeneous factor where 0 is the start point, 1 the end point, 0.5 the mid point and so on. The relation 0 < pos < 1 should be satisfied, although some cases accept value outside this range.

TODO

  • The actual implementation returns only the start and end steepness, that is only when pos is 0 or 1.

segment :

a CpmlSegment

pos :

the position value

vector :

the destination CpmlVector

Since 1.0


cpml_segment_put_intersections ()

size_t              cpml_segment_put_intersections      (const CpmlSegment *segment,
                                                         const CpmlSegment *segment2,
                                                         size_t n_dest,
                                                         CpmlPair *dest);

Computes the intersections between segment and segment2 and returns the found points in dest. If the intersections are more than n_dest, only the first n_dest pairs are stored in dest.

To get the job done, the primitives of segment are sequentially scanned for intersections with any primitive in segment2. This means segment has a higher precedence over segment2.

segment :

the first CpmlSegment

segment2 :

the second CpmlSegment

n_dest :

maximum number of intersections to return

dest :

the destination vector of CpmlPair

Returns :

the number of intersections found

Since 1.0


cpml_segment_offset ()

void                cpml_segment_offset                 (CpmlSegment *segment,
                                                         double offset);

Offsets a segment of the specified amount, that is builds a "parallel" segment at the offset distance from the original one and returns the result by replacing the original segment.

TODO

  • Closed path are not yet managed: an elegant solution is not so obvious: use cpml_close_offset() when available.
  • Degenerated primitives, such as lines of length 0, are not managed properly.

segment :

a CpmlSegment

offset :

the offset distance

Since 1.0


cpml_segment_transform ()

void                cpml_segment_transform              (CpmlSegment *segment,
                                                         const cairo_matrix_t *matrix);

Applies matrix on all the points of segment.

segment :

a CpmlSegment

matrix :

the matrix to be applied

Since 1.0


cpml_segment_reverse ()

void                cpml_segment_reverse                (CpmlSegment *segment);

Reverses segment in-place. The resulting rendering will be the same, but with the primitives generated in reverse order.

It is assumed that segment has yet been sanitized, that is returned by some CPML API function or it is a path yet conforming to the segment rules described by the cpml_segment_from_cairo() function.

segment :

a CpmlSegment

Since 1.0


cpml_segment_to_cairo ()

void                cpml_segment_to_cairo               (const CpmlSegment *segment,
                                                         cairo_t *cr);

Appends the path of segment to cr. The segment is "flattened", that is CPML_ARC primitives are approximated by one or more CPML_CURVE using cpml_arc_to_cairo(). Check its documentation for further details.

segment :

a CpmlSegment

cr :

the destination cairo context

Since 1.0


cpml_segment_dump ()

void                cpml_segment_dump                   (const CpmlSegment *segment);

Dumps the specified segment to stdout. Useful for debugging purposes.

segment :

a CpmlSegment

Since 1.0