static cairo_status_t _cairo_stroker_init (cairo_stroker_t *stroker, const cairo_stroke_style_t *stroke_style, const cairo_matrix_t *ctm, const cairo_matrix_t *ctm_inverse, double tolerance) { cairo_status_t status; stroker->style = *stroke_style; stroker->ctm = ctm; stroker->ctm_inverse = ctm_inverse; stroker->tolerance = tolerance; stroker->ctm_determinant = _cairo_matrix_compute_determinant (stroker->ctm); stroker->ctm_det_positive = stroker->ctm_determinant >= 0.0; status = _cairo_pen_init (&stroker->pen, stroke_style->line_width / 2.0, tolerance, ctm); if (unlikely (status)) return status; stroker->has_bounds = FALSE; stroker->has_current_face = FALSE; stroker->has_first_face = FALSE; stroker->has_initial_sub_path = FALSE; _cairo_stroker_dash_init (&stroker->dash, stroke_style); stroker->add_external_edge = NULL; return CAIRO_STATUS_SUCCESS; }
static cairo_bool_t _cairo_rectilinear_stroker_init (cairo_rectilinear_stroker_t *stroker, const cairo_stroke_style_t *stroke_style, const cairo_matrix_t *ctm, cairo_antialias_t antialias, cairo_boxes_t *boxes) { /* This special-case rectilinear stroker only supports * miter-joined lines (not curves) and a translation-only matrix * (though it could probably be extended to support a matrix with * uniform, integer scaling). * * It also only supports horizontal and vertical line_to * elements. But we don't catch that here, but instead return * UNSUPPORTED from _cairo_rectilinear_stroker_line_to if any * non-rectilinear line_to is encountered. */ if (stroke_style->line_join != CAIRO_LINE_JOIN_MITER) return FALSE; /* If the miter limit turns right angles into bevels, then we * can't use this optimization. Remember, the ratio is * 1/sin(ɸ/2). So the cutoff is 1/sin(π/4.0) or ⎷2, * which we round for safety. */ if (stroke_style->miter_limit < M_SQRT2) return FALSE; //TODO PROBABLY NOT add LINE_CAP_TRIANGULAR if (! (stroke_style->line_cap == CAIRO_LINE_CAP_BUTT || stroke_style->line_cap == CAIRO_LINE_CAP_SQUARE)) { return FALSE; } if (! _cairo_matrix_is_scale (ctm)) return FALSE; stroker->stroke_style = stroke_style; stroker->ctm = ctm; stroker->antialias = antialias; stroker->half_line_x = _cairo_fixed_from_double (fabs(ctm->xx) * stroke_style->line_width / 2.0); stroker->half_line_y = _cairo_fixed_from_double (fabs(ctm->yy) * stroke_style->line_width / 2.0); stroker->open_sub_path = FALSE; stroker->segments = stroker->segments_embedded; stroker->segments_size = ARRAY_LENGTH (stroker->segments_embedded); stroker->num_segments = 0; _cairo_stroker_dash_init (&stroker->dash, stroke_style); stroker->has_bounds = FALSE; stroker->boxes = boxes; return TRUE; }
static cairo_status_t _cairo_stroker_init (cairo_stroker_t *stroker, cairo_stroke_style_t *stroke_style, const cairo_matrix_t *ctm, const cairo_matrix_t *ctm_inverse, double tolerance, cairo_traps_t *traps) { cairo_status_t status; stroker->style = stroke_style; stroker->ctm = ctm; stroker->ctm_inverse = ctm_inverse; stroker->tolerance = tolerance; stroker->traps = traps; stroker->ctm_determinant = _cairo_matrix_compute_determinant (stroker->ctm); stroker->ctm_det_positive = stroker->ctm_determinant >= 0.0; status = _cairo_pen_init (&stroker->pen, stroke_style->line_width / 2.0, tolerance, ctm); if (unlikely (status)) return status; stroker->has_current_face = FALSE; stroker->has_first_face = FALSE; stroker->has_initial_sub_path = FALSE; _cairo_stroker_dash_init (&stroker->dash, stroke_style); stroker->has_bounds = _cairo_traps_get_limit (traps, &stroker->bounds); if (stroker->has_bounds) { /* Extend the bounds in each direction to account for the maximum area * we might generate trapezoids, to capture line segments that are outside * of the bounds but which might generate rendering that's within bounds. */ double dx, dy; cairo_fixed_t fdx, fdy; _cairo_stroke_style_max_distance_from_path (stroker->style, stroker->ctm, &dx, &dy); fdx = _cairo_fixed_from_double (dx); stroker->bounds.p1.x -= fdx; stroker->bounds.p2.x += fdx; fdy = _cairo_fixed_from_double (dy); stroker->bounds.p1.y -= fdy; stroker->bounds.p2.y += fdy; } return CAIRO_STATUS_SUCCESS; }
static void _cairo_rectilinear_stroker_init (cairo_rectilinear_stroker_t *stroker, cairo_stroke_style_t *stroke_style, const cairo_matrix_t *ctm, cairo_traps_t *traps) { stroker->stroke_style = stroke_style; stroker->ctm = ctm; stroker->half_line_width = _cairo_fixed_from_double (stroke_style->line_width / 2.0); stroker->traps = traps; stroker->open_sub_path = FALSE; stroker->segments = stroker->segments_embedded; stroker->segments_size = ARRAY_LENGTH (stroker->segments_embedded); stroker->num_segments = 0; _cairo_stroker_dash_init (&stroker->dash, stroke_style); stroker->has_bounds = FALSE; }