| 54 | | static void setCompositingOperation(cairo_t* context, CompositeOperator op, bool hasAlpha) |
| 55 | | { |
| 56 | | // FIXME: Add support for more operators. |
| 57 | | // FIXME: This should really move to be a graphics context function once we have |
| 58 | | // a C++ abstraction for GraphicsContext. |
| 59 | | if (op == CompositeSourceOver && !hasAlpha) |
| 60 | | op = CompositeCopy; |
| 61 | | |
| 62 | | if (op == CompositeCopy) |
| 63 | | cairo_set_operator(context, CAIRO_OPERATOR_SOURCE); |
| 64 | | else |
| 65 | | cairo_set_operator(context, CAIRO_OPERATOR_OVER); |
| 66 | | } |
| 67 | | |
| | 101 | void Image::drawPattern(GraphicsContext* ctxt, const FloatRect& tileRect, const AffineTransform& patternTransform, |
| | 102 | const FloatPoint& phase, CompositeOperator op, const FloatRect& destRect) |
| | 103 | { |
| | 104 | cairo_surface_t* image = nativeImageForCurrentFrame(); |
| | 105 | if (!image) // If it's too early we won't have an image yet. |
| | 106 | return; |
| | 107 | |
| | 108 | cairo_t* context = ctxt->platformContext(); |
| | 109 | ctxt->save(); |
| | 110 | |
| | 111 | // TODO: Make use of tileRect. |
| | 112 | |
| | 113 | cairo_pattern_t* pattern = cairo_pattern_create_for_surface(image); |
| | 114 | cairo_pattern_set_extend(pattern, CAIRO_EXTEND_REPEAT); |
| | 115 | |
| | 116 | cairo_matrix_t pattern_matrix = cairo_matrix_t(patternTransform); |
| | 117 | cairo_matrix_t phase_matrix = {1, 0, 0, 1, phase.x(), phase.y()}; |
| | 118 | cairo_matrix_t combined; |
| | 119 | cairo_matrix_multiply(&combined, &pattern_matrix, &phase_matrix); |
| | 120 | cairo_matrix_invert(&combined); |
| | 121 | cairo_pattern_set_matrix(pattern, &combined); |
| | 122 | |
| | 123 | ctxt->setCompositeOperation(op); |
| | 124 | cairo_set_source(context, pattern); |
| | 125 | cairo_rectangle(context, destRect.x(), destRect.y(), destRect.width(), destRect.height()); |
| | 126 | cairo_fill(context); |
| | 127 | |
| | 128 | cairo_pattern_destroy(pattern); |
| | 129 | ctxt->restore(); |
| | 130 | } |
| | 131 | |