示例#1
0
void PlatformContextCairo::prepareForStroking(const GraphicsContextState& state, AlphaPreservation alphaPreservation)
{
    prepareCairoContextSource(m_cr.get(),
                              state.strokePattern.get(),
                              state.strokeGradient.get(),
                              state.strokeColor,
                              alphaPreservation == PreserveAlpha ? globalAlpha() : 1);
}
示例#2
0
void PlatformContextCairo::prepareForFilling(const GraphicsContextState& state, PatternAdjustment patternAdjustment)
{
    cairo_set_fill_rule(m_cr.get(), state.fillRule == RULE_EVENODD ?  CAIRO_FILL_RULE_EVEN_ODD : CAIRO_FILL_RULE_WINDING);
    prepareCairoContextSource(m_cr.get(),
                              state.fillPattern.get(),
                              state.fillGradient.get(),
                              state.fillColor,
                              patternAdjustment == AdjustPatternForGlobalAlpha ? globalAlpha() : 1);
}
示例#3
0
void PlatformContextCairo::drawSurfaceToContext(cairo_surface_t* surface, const FloatRect& destRect, const FloatRect& srcRect, GraphicsContext* context)
{
    // If we're drawing a sub portion of the image or scaling then create
    // a pattern transformation on the image and draw the transformed pattern.
    // Test using example site at http://www.meyerweb.com/eric/css/edge/complexspiral/demo.html
    RefPtr<cairo_pattern_t> pattern = adoptRef(cairo_pattern_create_for_surface(surface));

    ASSERT(m_state);
    switch (m_state->m_imageInterpolationQuality) {
    case InterpolationNone:
    case InterpolationLow:
        cairo_pattern_set_filter(pattern.get(), CAIRO_FILTER_FAST);
        break;
    case InterpolationMedium:
    case InterpolationHigh:
        cairo_pattern_set_filter(pattern.get(), CAIRO_FILTER_BILINEAR);
        break;
    case InterpolationDefault:
        cairo_pattern_set_filter(pattern.get(), CAIRO_FILTER_BILINEAR);
        break;
    }
    cairo_pattern_set_extend(pattern.get(), CAIRO_EXTEND_PAD);

    float scaleX = srcRect.width() / destRect.width();
    float scaleY = srcRect.height() / destRect.height();
    cairo_matrix_t matrix = { scaleX, 0, 0, scaleY, srcRect.x(), srcRect.y() };
    cairo_pattern_set_matrix(pattern.get(), &matrix);

    ShadowBlur& shadow = context->platformContext()->shadowBlur();
    if (shadow.type() != ShadowBlur::NoShadow) {
        if (GraphicsContext* shadowContext = shadow.beginShadowLayer(context, destRect)) {
            drawPatternToCairoContext(shadowContext->platformContext()->cr(), pattern.get(), destRect, 1);
            shadow.endShadowLayer(context);
        }
    }

    cairo_save(m_cr.get());
    drawPatternToCairoContext(m_cr.get(), pattern.get(), destRect, globalAlpha());
    cairo_restore(m_cr.get());
}
int Context2D::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
    _id = QObject::qt_metacall(_c, _id, _a);
    if (_id < 0)
        return _id;
    if (_c == QMetaObject::InvokeMetaMethod) {
        switch (_id) {
        case 0: changed((*reinterpret_cast< const QImage(*)>(_a[1]))); break;
        case 1: save(); break;
        case 2: restore(); break;
        case 3: scale((*reinterpret_cast< qreal(*)>(_a[1])),(*reinterpret_cast< qreal(*)>(_a[2]))); break;
        case 4: rotate((*reinterpret_cast< qreal(*)>(_a[1]))); break;
        case 5: translate((*reinterpret_cast< qreal(*)>(_a[1])),(*reinterpret_cast< qreal(*)>(_a[2]))); break;
        case 6: transform((*reinterpret_cast< qreal(*)>(_a[1])),(*reinterpret_cast< qreal(*)>(_a[2])),(*reinterpret_cast< qreal(*)>(_a[3])),(*reinterpret_cast< qreal(*)>(_a[4])),(*reinterpret_cast< qreal(*)>(_a[5])),(*reinterpret_cast< qreal(*)>(_a[6]))); break;
        case 7: setTransform((*reinterpret_cast< qreal(*)>(_a[1])),(*reinterpret_cast< qreal(*)>(_a[2])),(*reinterpret_cast< qreal(*)>(_a[3])),(*reinterpret_cast< qreal(*)>(_a[4])),(*reinterpret_cast< qreal(*)>(_a[5])),(*reinterpret_cast< qreal(*)>(_a[6]))); break;
        case 8: { CanvasGradient _r = createLinearGradient((*reinterpret_cast< qreal(*)>(_a[1])),(*reinterpret_cast< qreal(*)>(_a[2])),(*reinterpret_cast< qreal(*)>(_a[3])),(*reinterpret_cast< qreal(*)>(_a[4])));
            if (_a[0]) *reinterpret_cast< CanvasGradient*>(_a[0]) = _r; }  break;
        case 9: { CanvasGradient _r = createRadialGradient((*reinterpret_cast< qreal(*)>(_a[1])),(*reinterpret_cast< qreal(*)>(_a[2])),(*reinterpret_cast< qreal(*)>(_a[3])),(*reinterpret_cast< qreal(*)>(_a[4])),(*reinterpret_cast< qreal(*)>(_a[5])),(*reinterpret_cast< qreal(*)>(_a[6])));
            if (_a[0]) *reinterpret_cast< CanvasGradient*>(_a[0]) = _r; }  break;
        case 10: clearRect((*reinterpret_cast< qreal(*)>(_a[1])),(*reinterpret_cast< qreal(*)>(_a[2])),(*reinterpret_cast< qreal(*)>(_a[3])),(*reinterpret_cast< qreal(*)>(_a[4]))); break;
        case 11: fillRect((*reinterpret_cast< qreal(*)>(_a[1])),(*reinterpret_cast< qreal(*)>(_a[2])),(*reinterpret_cast< qreal(*)>(_a[3])),(*reinterpret_cast< qreal(*)>(_a[4]))); break;
        case 12: strokeRect((*reinterpret_cast< qreal(*)>(_a[1])),(*reinterpret_cast< qreal(*)>(_a[2])),(*reinterpret_cast< qreal(*)>(_a[3])),(*reinterpret_cast< qreal(*)>(_a[4]))); break;
        case 13: beginPath(); break;
        case 14: closePath(); break;
        case 15: moveTo((*reinterpret_cast< qreal(*)>(_a[1])),(*reinterpret_cast< qreal(*)>(_a[2]))); break;
        case 16: lineTo((*reinterpret_cast< qreal(*)>(_a[1])),(*reinterpret_cast< qreal(*)>(_a[2]))); break;
        case 17: quadraticCurveTo((*reinterpret_cast< qreal(*)>(_a[1])),(*reinterpret_cast< qreal(*)>(_a[2])),(*reinterpret_cast< qreal(*)>(_a[3])),(*reinterpret_cast< qreal(*)>(_a[4]))); break;
        case 18: bezierCurveTo((*reinterpret_cast< qreal(*)>(_a[1])),(*reinterpret_cast< qreal(*)>(_a[2])),(*reinterpret_cast< qreal(*)>(_a[3])),(*reinterpret_cast< qreal(*)>(_a[4])),(*reinterpret_cast< qreal(*)>(_a[5])),(*reinterpret_cast< qreal(*)>(_a[6]))); break;
        case 19: arcTo((*reinterpret_cast< qreal(*)>(_a[1])),(*reinterpret_cast< qreal(*)>(_a[2])),(*reinterpret_cast< qreal(*)>(_a[3])),(*reinterpret_cast< qreal(*)>(_a[4])),(*reinterpret_cast< qreal(*)>(_a[5]))); break;
        case 20: rect((*reinterpret_cast< qreal(*)>(_a[1])),(*reinterpret_cast< qreal(*)>(_a[2])),(*reinterpret_cast< qreal(*)>(_a[3])),(*reinterpret_cast< qreal(*)>(_a[4]))); break;
        case 21: arc((*reinterpret_cast< qreal(*)>(_a[1])),(*reinterpret_cast< qreal(*)>(_a[2])),(*reinterpret_cast< qreal(*)>(_a[3])),(*reinterpret_cast< qreal(*)>(_a[4])),(*reinterpret_cast< qreal(*)>(_a[5])),(*reinterpret_cast< bool(*)>(_a[6]))); break;
        case 22: fill(); break;
        case 23: stroke(); break;
        case 24: clip(); break;
        case 25: { bool _r = isPointInPath((*reinterpret_cast< qreal(*)>(_a[1])),(*reinterpret_cast< qreal(*)>(_a[2])));
            if (_a[0]) *reinterpret_cast< bool*>(_a[0]) = _r; }  break;
        case 26: drawImage((*reinterpret_cast< DomImage*(*)>(_a[1])),(*reinterpret_cast< qreal(*)>(_a[2])),(*reinterpret_cast< qreal(*)>(_a[3]))); break;
        case 27: drawImage((*reinterpret_cast< DomImage*(*)>(_a[1])),(*reinterpret_cast< qreal(*)>(_a[2])),(*reinterpret_cast< qreal(*)>(_a[3])),(*reinterpret_cast< qreal(*)>(_a[4])),(*reinterpret_cast< qreal(*)>(_a[5]))); break;
        case 28: drawImage((*reinterpret_cast< DomImage*(*)>(_a[1])),(*reinterpret_cast< qreal(*)>(_a[2])),(*reinterpret_cast< qreal(*)>(_a[3])),(*reinterpret_cast< qreal(*)>(_a[4])),(*reinterpret_cast< qreal(*)>(_a[5])),(*reinterpret_cast< qreal(*)>(_a[6])),(*reinterpret_cast< qreal(*)>(_a[7])),(*reinterpret_cast< qreal(*)>(_a[8])),(*reinterpret_cast< qreal(*)>(_a[9]))); break;
        case 29: { ImageData _r = getImageData((*reinterpret_cast< qreal(*)>(_a[1])),(*reinterpret_cast< qreal(*)>(_a[2])),(*reinterpret_cast< qreal(*)>(_a[3])),(*reinterpret_cast< qreal(*)>(_a[4])));
            if (_a[0]) *reinterpret_cast< ImageData*>(_a[0]) = _r; }  break;
        case 30: putImageData((*reinterpret_cast< ImageData(*)>(_a[1])),(*reinterpret_cast< qreal(*)>(_a[2])),(*reinterpret_cast< qreal(*)>(_a[3]))); break;
        default: ;
        }
        _id -= 31;
    }
#ifndef QT_NO_PROPERTIES
      else if (_c == QMetaObject::ReadProperty) {
        void *_v = _a[0];
        switch (_id) {
        case 0: *reinterpret_cast< qreal*>(_v) = globalAlpha(); break;
        case 1: *reinterpret_cast< QString*>(_v) = globalCompositeOperation(); break;
        case 2: *reinterpret_cast< QVariant*>(_v) = strokeStyle(); break;
        case 3: *reinterpret_cast< QVariant*>(_v) = fillStyle(); break;
        case 4: *reinterpret_cast< qreal*>(_v) = lineWidth(); break;
        case 5: *reinterpret_cast< QString*>(_v) = lineCap(); break;
        case 6: *reinterpret_cast< QString*>(_v) = lineJoin(); break;
        case 7: *reinterpret_cast< qreal*>(_v) = miterLimit(); break;
        case 8: *reinterpret_cast< qreal*>(_v) = shadowOffsetX(); break;
        case 9: *reinterpret_cast< qreal*>(_v) = shadowOffsetY(); break;
        case 10: *reinterpret_cast< qreal*>(_v) = shadowBlur(); break;
        case 11: *reinterpret_cast< QString*>(_v) = shadowColor(); break;
        }
        _id -= 12;
    } else if (_c == QMetaObject::WriteProperty) {
        void *_v = _a[0];
        switch (_id) {
        case 0: setGlobalAlpha(*reinterpret_cast< qreal*>(_v)); break;
        case 1: setGlobalCompositeOperation(*reinterpret_cast< QString*>(_v)); break;
        case 2: setStrokeStyle(*reinterpret_cast< QVariant*>(_v)); break;
        case 3: setFillStyle(*reinterpret_cast< QVariant*>(_v)); break;
        case 4: setLineWidth(*reinterpret_cast< qreal*>(_v)); break;
        case 5: setLineCap(*reinterpret_cast< QString*>(_v)); break;
        case 6: setLineJoin(*reinterpret_cast< QString*>(_v)); break;
        case 7: setMiterLimit(*reinterpret_cast< qreal*>(_v)); break;
        case 8: setShadowOffsetX(*reinterpret_cast< qreal*>(_v)); break;
        case 9: setShadowOffsetY(*reinterpret_cast< qreal*>(_v)); break;
        case 10: setShadowBlur(*reinterpret_cast< qreal*>(_v)); break;
        case 11: setShadowColor(*reinterpret_cast< QString*>(_v)); break;
        }
        _id -= 12;
    } else if (_c == QMetaObject::ResetProperty) {
        _id -= 12;
    } else if (_c == QMetaObject::QueryPropertyDesignable) {
        _id -= 12;
    } else if (_c == QMetaObject::QueryPropertyScriptable) {
        _id -= 12;
    } else if (_c == QMetaObject::QueryPropertyStored) {
        _id -= 12;
    } else if (_c == QMetaObject::QueryPropertyEditable) {
        _id -= 12;
    } else if (_c == QMetaObject::QueryPropertyUser) {
        _id -= 12;
    }
#endif // QT_NO_PROPERTIES
    return _id;
}
void PlatformContextCairo::drawSurfaceToContext(cairo_surface_t* surface, const FloatRect& destRect, const FloatRect& originalSrcRect, GraphicsContext* context)
{
    FloatRect srcRect = originalSrcRect;

    // We need to account for negative source dimensions by flipping the rectangle.
    if (originalSrcRect.width() < 0) {
        srcRect.setX(originalSrcRect.x() + originalSrcRect.width());
        srcRect.setWidth(std::fabs(originalSrcRect.width()));
    }
    if (originalSrcRect.height() < 0) {
        srcRect.setY(originalSrcRect.y() + originalSrcRect.height());
        srcRect.setHeight(std::fabs(originalSrcRect.height()));
    }

    // Cairo subsurfaces don't support floating point boundaries well, so we expand the rectangle.
    IntRect expandedSrcRect(enclosingIntRect(srcRect));

    // We use a subsurface here so that we don't end up sampling outside the originalSrcRect rectangle.
    // See https://bugs.webkit.org/show_bug.cgi?id=58309
    RefPtr<cairo_surface_t> subsurface = adoptRef(cairo_surface_create_for_rectangle(
        surface, expandedSrcRect.x(), expandedSrcRect.y(), expandedSrcRect.width(), expandedSrcRect.height()));
    RefPtr<cairo_pattern_t> pattern = adoptRef(cairo_pattern_create_for_surface(subsurface.get()));

    ASSERT(m_state);
    switch (m_state->m_imageInterpolationQuality) {
    case InterpolationNone:
    case InterpolationLow:
        cairo_pattern_set_filter(pattern.get(), CAIRO_FILTER_FAST);
        break;
    case InterpolationMedium:
    case InterpolationHigh:
        cairo_pattern_set_filter(pattern.get(), CAIRO_FILTER_BILINEAR);
        break;
    case InterpolationDefault:
        cairo_pattern_set_filter(pattern.get(), CAIRO_FILTER_BILINEAR);
        break;
    }
    cairo_pattern_set_extend(pattern.get(), CAIRO_EXTEND_PAD);

    // The pattern transformation properly scales the pattern for when the source rectangle is a
    // different size than the destination rectangle. We also account for any offset we introduced
    // by expanding floating point source rectangle sizes. It's important to take the absolute value
    // of the scale since the original width and height might be negative.
    float scaleX = std::fabs(srcRect.width() / destRect.width());
    float scaleY = std::fabs(srcRect.height() / destRect.height());
    float leftPadding = static_cast<float>(expandedSrcRect.x()) - floorf(srcRect.x());
    float topPadding = static_cast<float>(expandedSrcRect.y()) - floorf(srcRect.y());
    cairo_matrix_t matrix = { scaleX, 0, 0, scaleY, leftPadding, topPadding };
    cairo_pattern_set_matrix(pattern.get(), &matrix);

    ShadowBlur& shadow = context->platformContext()->shadowBlur();
    if (shadow.type() != ShadowBlur::NoShadow) {
        if (GraphicsContext* shadowContext = shadow.beginShadowLayer(context, destRect)) {
            drawPatternToCairoContext(shadowContext->platformContext()->cr(), pattern.get(), destRect, 1);
            shadow.endShadowLayer(context);
        }
    }

    cairo_save(m_cr.get());
    drawPatternToCairoContext(m_cr.get(), pattern.get(), destRect, globalAlpha());
    cairo_restore(m_cr.get());
}