📄 graphicscontextskia.cpp
字号:
return; platformContext()->canvas()->clipPath(path, SkRegion::kDifference_Op);}void GraphicsContext::clipOutEllipseInRect(const IntRect& rect){ if (paintingDisabled()) return; SkRect oval(rect); if (!isRectSkiaSafe(getCTM(), oval)) return; SkPath path; path.addOval(oval, SkPath::kCCW_Direction); platformContext()->canvas()->clipPath(path, SkRegion::kDifference_Op);}void GraphicsContext::clipPath(WindRule clipRule){ if (paintingDisabled()) return; SkPath path = platformContext()->currentPathInLocalCoordinates(); path.setFillType(clipRule == RULE_EVENODD ? SkPath::kEvenOdd_FillType : SkPath::kWinding_FillType); platformContext()->canvas()->clipPath(path);}void GraphicsContext::clipToImageBuffer(const FloatRect& rect, const ImageBuffer* imageBuffer){ if (paintingDisabled()) return;#if defined(__linux__) || PLATFORM(WIN_OS) platformContext()->beginLayerClippedToImage(rect, imageBuffer);#endif}void GraphicsContext::concatCTM(const TransformationMatrix& xform){ if (paintingDisabled()) return; platformContext()->canvas()->concat(xform);}void GraphicsContext::drawConvexPolygon(size_t numPoints, const FloatPoint* points, bool shouldAntialias){ if (paintingDisabled()) return; if (numPoints <= 1) return; SkPath path; path.incReserve(numPoints); path.moveTo(WebCoreFloatToSkScalar(points[0].x()), WebCoreFloatToSkScalar(points[0].y())); for (size_t i = 1; i < numPoints; i++) { path.lineTo(WebCoreFloatToSkScalar(points[i].x()), WebCoreFloatToSkScalar(points[i].y())); } if (!isPathSkiaSafe(getCTM(), path)) return; SkPaint paint; if (fillColor().alpha() > 0) { platformContext()->setupPaintForFilling(&paint); platformContext()->canvas()->drawPath(path, paint); } if (strokeStyle() != NoStroke) { paint.reset(); platformContext()->setupPaintForStroking(&paint, 0, 0); platformContext()->canvas()->drawPath(path, paint); }}// This method is only used to draw the little circles used in lists.void GraphicsContext::drawEllipse(const IntRect& elipseRect){ if (paintingDisabled()) return; SkRect rect = elipseRect; if (!isRectSkiaSafe(getCTM(), rect)) return; SkPaint paint; if (fillColor().alpha() > 0) { platformContext()->setupPaintForFilling(&paint); platformContext()->canvas()->drawOval(rect, paint); } if (strokeStyle() != NoStroke) { paint.reset(); platformContext()->setupPaintForStroking(&paint, &rect, 0); platformContext()->canvas()->drawOval(rect, paint); }}void GraphicsContext::drawFocusRing(const Color& color){ if (paintingDisabled()) return; const Vector<IntRect>& rects = focusRingRects(); unsigned rectCount = rects.size(); if (0 == rectCount) return; SkRegion focusRingRegion; const SkScalar focusRingOutset = WebCoreFloatToSkScalar(0.5); for (unsigned i = 0; i < rectCount; i++) { SkIRect r = rects[i]; r.inset(-focusRingOutset, -focusRingOutset); focusRingRegion.op(r, SkRegion::kUnion_Op); } SkPath path; SkPaint paint; paint.setAntiAlias(true); paint.setStyle(SkPaint::kStroke_Style); paint.setColor(focusRingColor().rgb()); paint.setStrokeWidth(focusRingOutset * 2); paint.setPathEffect(new SkCornerPathEffect(focusRingOutset * 2))->unref(); focusRingRegion.getBoundaryPath(&path); platformContext()->canvas()->drawPath(path, paint);}// This is only used to draw borders.void GraphicsContext::drawLine(const IntPoint& point1, const IntPoint& point2){ if (paintingDisabled()) return; StrokeStyle penStyle = strokeStyle(); if (penStyle == NoStroke) return; SkPaint paint; SkPoint pts[2] = { (SkPoint)point1, (SkPoint)point2 }; if (!isPointSkiaSafe(getCTM(), pts[0]) || !isPointSkiaSafe(getCTM(), pts[1])) return; // We know these are vertical or horizontal lines, so the length will just // be the sum of the displacement component vectors give or take 1 - // probably worth the speed up of no square root, which also won't be exact. SkPoint disp = pts[1] - pts[0]; int length = SkScalarRound(disp.fX + disp.fY); int width = roundf( platformContext()->setupPaintForStroking(&paint, 0, length)); // "Borrowed" this comment and idea from GraphicsContextCG.cpp // For odd widths, we add in 0.5 to the appropriate x/y so that the float // arithmetic works out. For example, with a border width of 3, KHTML will // pass us (y1+y2)/2, e.g., (50+53)/2 = 103/2 = 51 when we want 51.5. It is // always true that an even width gave us a perfect position, but an odd // width gave us a position that is off by exactly 0.5. bool isVerticalLine = pts[0].fX == pts[1].fX; if (width & 1) { // Odd. if (isVerticalLine) { pts[0].fX = pts[0].fX + SK_ScalarHalf; pts[1].fX = pts[0].fX; } else { // Horizontal line pts[0].fY = pts[0].fY + SK_ScalarHalf; pts[1].fY = pts[0].fY; } } platformContext()->canvas()->drawPoints(SkCanvas::kLines_PointMode, 2, pts, paint);}void GraphicsContext::drawLineForMisspellingOrBadGrammar(const IntPoint& pt, int width, bool grammar){ if (paintingDisabled()) return; // Create the pattern we'll use to draw the underline. static SkBitmap* misspellBitmap = 0; if (!misspellBitmap) { // We use a 2-pixel-high misspelling indicator because that seems to be // what WebKit is designed for, and how much room there is in a typical // page for it. const int rowPixels = 32; // Must be multiple of 4 for pattern below. const int colPixels = 2; misspellBitmap = new SkBitmap; misspellBitmap->setConfig(SkBitmap::kARGB_8888_Config, rowPixels, colPixels); misspellBitmap->allocPixels(); misspellBitmap->eraseARGB(0, 0, 0, 0); const uint32_t lineColor = 0xFFFF0000; // Opaque red. const uint32_t antiColor = 0x60600000; // Semitransparent red. // Pattern: X o o X o o X // o X o o X o uint32_t* row1 = misspellBitmap->getAddr32(0, 0); uint32_t* row2 = misspellBitmap->getAddr32(0, 1); for (int x = 0; x < rowPixels; x++) { switch (x % 4) { case 0: row1[x] = lineColor; break; case 1: row1[x] = antiColor; row2[x] = antiColor; break; case 2: row2[x] = lineColor; break; case 3: row1[x] = antiColor; row2[x] = antiColor; break; } } } // Offset it vertically by 1 so that there's some space under the text. SkScalar originX = SkIntToScalar(pt.x()); SkScalar originY = SkIntToScalar(pt.y()) + 1; // Make a shader for the bitmap with an origin of the box we'll draw. This // shader is refcounted and will have an initial refcount of 1. SkShader* shader = SkShader::CreateBitmapShader( *misspellBitmap, SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode); SkMatrix matrix; matrix.reset(); matrix.postTranslate(originX, originY); shader->setLocalMatrix(matrix); // Assign the shader to the paint & release our reference. The paint will // now own the shader and the shader will be destroyed when the paint goes // out of scope. SkPaint paint; paint.setShader(shader); shader->unref(); SkRect rect; rect.set(originX, originY, originX + SkIntToScalar(width), originY + SkIntToScalar(misspellBitmap->height())); platformContext()->canvas()->drawRect(rect, paint);}void GraphicsContext::drawLineForText(const IntPoint& pt, int width, bool printing){ if (paintingDisabled()) return; if (width <= 0) return; int thickness = SkMax32(static_cast<int>(strokeThickness()), 1); SkRect r; r.fLeft = SkIntToScalar(pt.x()); r.fTop = SkIntToScalar(pt.y()); r.fRight = r.fLeft + SkIntToScalar(width); r.fBottom = r.fTop + SkIntToScalar(thickness); SkPaint paint; platformContext()->setupPaintForFilling(&paint); // Text lines are drawn using the stroke color. paint.setColor(platformContext()->effectiveStrokeColor()); platformContext()->canvas()->drawRect(r, paint);}// Draws a filled rectangle with a stroked border.void GraphicsContext::drawRect(const IntRect& rect){ if (paintingDisabled()) return; SkRect r = rect; if (!isRectSkiaSafe(getCTM(), r)) // See the fillRect below. ClipRectToCanvas(*platformContext()->canvas(), r, &r); platformContext()->drawRect(r);}void GraphicsContext::fillPath(){ if (paintingDisabled()) return; SkPath path = platformContext()->currentPathInLocalCoordinates(); if (!isPathSkiaSafe(getCTM(), path)) return; const GraphicsContextState& state = m_common->state; ColorSpace colorSpace = state.fillColorSpace; if (colorSpace == SolidColorSpace && !fillColor().alpha()) return; path.setFillType(state.fillRule == RULE_EVENODD ? SkPath::kEvenOdd_FillType : SkPath::kWinding_FillType); SkPaint paint; platformContext()->setupPaintForFilling(&paint); if (colorSpace == PatternColorSpace) { SkShader* pat = state.fillPattern->createPlatformPattern(getCTM()); paint.setShader(pat); pat->unref(); } else if (colorSpace == GradientColorSpace) paint.setShader(state.fillGradient->platformGradient()); platformContext()->canvas()->drawPath(path, paint);}void GraphicsContext::fillRect(const FloatRect& rect){ if (paintingDisabled()) return; SkRect r = rect; if (!isRectSkiaSafe(getCTM(), r)) // See the other version of fillRect below. ClipRectToCanvas(*platformContext()->canvas(), r, &r); const GraphicsContextState& state = m_common->state; ColorSpace colorSpace = state.fillColorSpace; if (colorSpace == SolidColorSpace && !fillColor().alpha()) return; SkPaint paint; platformContext()->setupPaintForFilling(&paint); if (colorSpace == PatternColorSpace) { SkShader* pat = state.fillPattern->createPlatformPattern(getCTM()); paint.setShader(pat); pat->unref(); } else if (colorSpace == GradientColorSpace) paint.setShader(state.fillGradient->platformGradient()); platformContext()->canvas()->drawRect(r, paint);}void GraphicsContext::fillRect(const FloatRect& rect, const Color& color){ if (paintingDisabled()) return; if (!color.alpha()) return; SkRect r = rect; if (!isRectSkiaSafe(getCTM(), r)) { // Special case when the rectangle overflows fixed point. This is a // workaround to fix bug 1212844. When the input rectangle is very // large, it can overflow Skia's internal fixed point rect. This // should be fixable in Skia (since the output bitmap isn't that // large), but until that is fixed, we try to handle it ourselves. // // We manually clip the rectangle to the current clip rect. This // will prevent overflow. The rectangle will be transformed to the // canvas' coordinate space before it is converted to fixed point // so we are guaranteed not to overflow after doing this. ClipRectToCanvas(*platformContext()->canvas(), r, &r); } SkPaint paint; platformContext()->setupPaintCommon(&paint); paint.setColor(color.rgb());
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -