void PlatformContextSkia::setupPaintForFilling(SkPaint* paint) const { setupPaintCommon(paint); const GraphicsContextState& state = m_gc->state(); setupShader(paint, state.fillGradient.get(), state.fillPattern.get(), m_state->m_fillColor); }
float PlatformContextSkia::setupPaintForStroking(SkPaint* paint, SkRect* rect, int length) const { setupPaintCommon(paint); const GraphicsContextState& state = m_gc->state(); setupShader(paint, state.strokeGradient.get(), state.strokePattern.get(), m_state->m_strokeColor); float width = m_state->m_strokeThickness; paint->setStyle(SkPaint::kStroke_Style); paint->setStrokeWidth(SkFloatToScalar(width)); paint->setStrokeCap(m_state->m_lineCap); paint->setStrokeJoin(m_state->m_lineJoin); paint->setStrokeMiter(SkFloatToScalar(m_state->m_miterLimit)); if (m_state->m_dash) paint->setPathEffect(m_state->m_dash); else { switch (m_state->m_strokeStyle) { case NoStroke: case SolidStroke: #if ENABLE(CSS3_TEXT) case DoubleStroke: case WavyStroke: // FIXME: https://bugs.webkit.org/show_bug.cgi?id=93509 - Needs platform support. #endif // CSS3_TEXT break; case DashedStroke: width = m_state->m_dashRatio * width; // Fall through. case DottedStroke: // Truncate the width, since we don't want fuzzy dots or dashes. int dashLength = static_cast<int>(width); // Subtract off the endcaps, since they're rendered separately. int distance = length - 2 * static_cast<int>(m_state->m_strokeThickness); int phase = 1; if (dashLength > 1) { // Determine how many dashes or dots we should have. int numDashes = distance / dashLength; int remainder = distance % dashLength; // Adjust the phase to center the dashes within the line. if (numDashes % 2 == 0) { // Even: shift right half a dash, minus half the remainder phase = (dashLength - remainder) / 2; } else { // Odd: shift right a full dash, minus half the remainder phase = dashLength - remainder / 2; } } SkScalar dashLengthSk = SkIntToScalar(dashLength); SkScalar intervals[2] = { dashLengthSk, dashLengthSk }; paint->setPathEffect(new SkDashPathEffect(intervals, 2, SkIntToScalar(phase)))->unref(); } } return width; }
float PlatformContextSkia::setupPaintForStroking(SkPaint* paint, SkRect* rect, int length) const { setupPaintCommon(paint); float width = m_state->m_strokeThickness; paint->setColor(m_state->applyAlpha(m_state->m_strokeColor)); paint->setShader(m_state->m_strokeShader); paint->setStyle(SkPaint::kStroke_Style); // The limits here (512 and 256) were made up but are hopefully large // enough to be reasonable. They are, empirically, small enough not to // cause overflows in Skia. paint->setStrokeWidth(scalarBound(SkFloatToScalar(width), 0, 512)); paint->setStrokeCap(m_state->m_lineCap); paint->setStrokeJoin(m_state->m_lineJoin); paint->setStrokeMiter(scalarBound(SkFloatToScalar(m_state->m_miterLimit), 0, 256)); if (m_state->m_dash) paint->setPathEffect(m_state->m_dash); else { switch (m_state->m_strokeStyle) { case WebCore::NoStroke: case WebCore::SolidStroke: break; case WebCore::DashedStroke: width = m_state->m_dashRatio * width; // Fall through. case WebCore::DottedStroke: // Truncate the width, since we don't want fuzzy dots or dashes. int dashLength = static_cast<int>(width); // Subtract off the endcaps, since they're rendered separately. int distance = length - 2 * static_cast<int>(m_state->m_strokeThickness); int phase = 1; if (dashLength > 1) { // Determine how many dashes or dots we should have. int numDashes = distance / dashLength; int remainder = distance % dashLength; // Adjust the phase to center the dashes within the line. if (numDashes % 2 == 0) { // Even: shift right half a dash, minus half the remainder phase = (dashLength - remainder) / 2; } else { // Odd: shift right a full dash, minus half the remainder phase = dashLength - remainder / 2; } } SkScalar dashLengthSk = SkIntToScalar(dashLength); SkScalar intervals[2] = { dashLengthSk, dashLengthSk }; paint->setPathEffect(new SkDashPathEffect(intervals, 2, SkIntToScalar(phase)))->unref(); } } return width; }
void PlatformGraphicsContextSkia::drawBitmapRect(const SkBitmap& bitmap, const SkIRect* src, const SkRect& dst, CompositeOperator op) { SkPaint paint; setupPaintCommon(&paint); paint.setAlpha(getNormalizedAlpha()); paint.setXfermodeMode(WebCoreCompositeToSkiaComposite(op)); fixPaintForBitmapsThatMaySeam(&paint); mCanvas->drawBitmapRect(bitmap, src, dst, &paint); }
float PlatformContextSkia::setupPaintForStroking(SkPaint* paint, SkRect* rect, int length) const { setupPaintCommon(paint); float width = m_state->m_strokeThickness; // This allows dashing and dotting to work properly for hairline strokes. if (width == 0) width = 1; paint->setColor(m_state->applyAlpha(m_state->m_strokeColor)); paint->setStyle(SkPaint::kStroke_Style); paint->setStrokeWidth(SkFloatToScalar(width)); paint->setStrokeCap(m_state->m_lineCap); paint->setStrokeJoin(m_state->m_lineJoin); paint->setStrokeMiter(SkFloatToScalar(m_state->m_miterLimit)); if (rect != 0 && (static_cast<int>(roundf(width)) & 1)) rect->inset(-SK_ScalarHalf, -SK_ScalarHalf); if (m_state->m_dash) paint->setPathEffect(m_state->m_dash); else { switch (m_state->m_strokeStyle) { case WebCore::NoStroke: case WebCore::SolidStroke: break; case WebCore::DashedStroke: width = m_state->m_dashRatio * width; // Fall through. case WebCore::DottedStroke: SkScalar dashLength; if (length) { // Determine about how many dashes or dots we should have. int numDashes = length / roundf(width); if (!(numDashes & 1)) numDashes++; // Make it odd so we end on a dash/dot. // Use the number of dashes to determine the length of a // dash/dot, which will be approximately width dashLength = SkScalarDiv(SkIntToScalar(length), SkIntToScalar(numDashes)); } else dashLength = SkFloatToScalar(width); SkScalar intervals[2] = { dashLength, dashLength }; paint->setPathEffect(new SkDashPathEffect(intervals, 2, 0))->unref(); } } return width; }
void PlatformGraphicsContextSkia::drawBitmapPattern( const SkBitmap& bitmap, const SkMatrix& matrix, CompositeOperator compositeOp, const FloatRect& destRect) { SkShader* shader = SkShader::CreateBitmapShader(bitmap, SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode); shader->setLocalMatrix(matrix); SkPaint paint; setupPaintCommon(&paint); paint.setAlpha(getNormalizedAlpha()); paint.setShader(shader)->unref(); paint.setXfermodeMode(WebCoreCompositeToSkiaComposite(compositeOp)); fixPaintForBitmapsThatMaySeam(&paint); mCanvas->drawRect(destRect, paint); }
void PlatformContextSkia::setupPaintForFilling(SkPaint* paint) const { setupPaintCommon(paint); paint->setColor(m_state->applyAlpha(m_state->m_fillColor)); paint->setShader(m_state->m_fillShader); }