📄 graphicscontextcg.cpp
字号:
CGColorSpaceRelease(patternSpace); const CGFloat patternAlpha = 1; CGContextSetStrokePattern(cgContext, platformPattern, &patternAlpha); CGPatternRelease(platformPattern);}void GraphicsContext::applyFillPattern(){ CGContextRef cgContext = platformContext(); CGPatternRef platformPattern = m_common->state.fillPattern.get()->createPlatformPattern(getCTM()); if (!platformPattern) return; CGColorSpaceRef patternSpace = CGColorSpaceCreatePattern(0); CGContextSetFillColorSpace(cgContext, patternSpace); CGColorSpaceRelease(patternSpace); const CGFloat patternAlpha = 1; CGContextSetFillPattern(cgContext, platformPattern, &patternAlpha); CGPatternRelease(platformPattern);}static inline bool calculateDrawingMode(const GraphicsContextState& state, CGPathDrawingMode& mode){ bool shouldFill = state.fillColorSpace == PatternColorSpace || state.fillColor.alpha(); bool shouldStroke = state.strokeColorSpace == PatternColorSpace || (state.strokeStyle != NoStroke && state.strokeColor.alpha()); bool useEOFill = state.fillRule == RULE_EVENODD; if (shouldFill) { if (shouldStroke) { if (useEOFill) mode = kCGPathEOFillStroke; else mode = kCGPathFillStroke; } else { // fill, no stroke if (useEOFill) mode = kCGPathEOFill; else mode = kCGPathFill; } } else { // Setting mode to kCGPathStroke even if shouldStroke is false. In that case, we return false and mode will not be used, // but the compiler will not compain about an uninitialized variable. mode = kCGPathStroke; } return shouldFill || shouldStroke;}void GraphicsContext::drawPath(){ if (paintingDisabled()) return; CGContextRef context = platformContext(); const GraphicsContextState& state = m_common->state; if (state.fillColorSpace == GradientColorSpace || state.strokeColorSpace == GradientColorSpace) { // We don't have any optimized way to fill & stroke a path using gradients fillPath(); strokePath(); return; } if (state.fillColorSpace == PatternColorSpace) applyFillPattern(); if (state.strokeColorSpace == PatternColorSpace) applyStrokePattern(); CGPathDrawingMode drawingMode; if (calculateDrawingMode(state, drawingMode)) CGContextDrawPath(context, drawingMode);}static inline void fillPathWithFillRule(CGContextRef context, WindRule fillRule){ if (fillRule == RULE_EVENODD) CGContextEOFillPath(context); else CGContextFillPath(context);}void GraphicsContext::fillPath(){ if (paintingDisabled()) return; CGContextRef context = platformContext(); switch (m_common->state.fillColorSpace) { case SolidColorSpace: if (fillColor().alpha()) fillPathWithFillRule(context, fillRule()); break; case PatternColorSpace: applyFillPattern(); fillPathWithFillRule(context, fillRule()); break; case GradientColorSpace: CGContextSaveGState(context); if (fillRule() == RULE_EVENODD) CGContextEOClip(context); else CGContextClip(context); CGContextConcatCTM(context, m_common->state.fillGradient->gradientSpaceTransform()); CGContextDrawShading(context, m_common->state.fillGradient->platformGradient()); CGContextRestoreGState(context); break; }}void GraphicsContext::strokePath(){ if (paintingDisabled()) return; CGContextRef context = platformContext(); switch (m_common->state.strokeColorSpace) { case SolidColorSpace: if (strokeColor().alpha()) CGContextStrokePath(context); break; case PatternColorSpace: applyStrokePattern(); CGContextStrokePath(context); break; case GradientColorSpace: CGContextSaveGState(context); CGContextReplacePathWithStrokedPath(context); CGContextClip(context); CGContextConcatCTM(context, m_common->state.strokeGradient->gradientSpaceTransform()); CGContextDrawShading(context, m_common->state.strokeGradient->platformGradient()); CGContextRestoreGState(context); break; }}void GraphicsContext::fillRect(const FloatRect& rect){ if (paintingDisabled()) return; CGContextRef context = platformContext(); switch (m_common->state.fillColorSpace) { case SolidColorSpace: if (fillColor().alpha()) CGContextFillRect(context, rect); break; case PatternColorSpace: applyFillPattern(); CGContextFillRect(context, rect); break; case GradientColorSpace: CGContextSaveGState(context); CGContextClipToRect(context, rect); CGContextConcatCTM(context, m_common->state.fillGradient->gradientSpaceTransform()); CGContextDrawShading(context, m_common->state.fillGradient->platformGradient()); CGContextRestoreGState(context); break; }}void GraphicsContext::fillRect(const FloatRect& rect, const Color& color){ if (paintingDisabled()) return; if (color.alpha()) { CGContextRef context = platformContext(); Color oldFillColor = fillColor(); if (oldFillColor != color) setCGFillColor(context, color); CGContextFillRect(context, rect); if (oldFillColor != color) setCGFillColor(context, oldFillColor); }}void GraphicsContext::fillRoundedRect(const IntRect& rect, const IntSize& topLeft, const IntSize& topRight, const IntSize& bottomLeft, const IntSize& bottomRight, const Color& color){ if (paintingDisabled() || !color.alpha()) return; CGContextRef context = platformContext(); Color oldFillColor = fillColor(); if (oldFillColor != color) setCGFillColor(context, color); addPath(Path::createRoundedRectangle(rect, topLeft, topRight, bottomLeft, bottomRight)); fillPath(); if (oldFillColor != color) setCGFillColor(context, oldFillColor);}void GraphicsContext::clip(const FloatRect& rect){ if (paintingDisabled()) return; CGContextClipToRect(platformContext(), rect); m_data->clip(rect);}void GraphicsContext::clipOut(const IntRect& rect){ if (paintingDisabled()) return; CGRect rects[2] = { CGContextGetClipBoundingBox(platformContext()), rect }; CGContextBeginPath(platformContext()); CGContextAddRects(platformContext(), rects, 2); CGContextEOClip(platformContext());}void GraphicsContext::clipOutEllipseInRect(const IntRect& rect){ if (paintingDisabled()) return; CGContextBeginPath(platformContext()); CGContextAddRect(platformContext(), CGContextGetClipBoundingBox(platformContext())); CGContextAddEllipseInRect(platformContext(), rect); CGContextEOClip(platformContext());}void GraphicsContext::clipPath(WindRule clipRule){ if (paintingDisabled()) return; CGContextRef context = platformContext(); if (!CGContextIsPathEmpty(context)) { if (clipRule == RULE_EVENODD) CGContextEOClip(context); else CGContextClip(context); }}void GraphicsContext::addInnerRoundedRectClip(const IntRect& rect, int thickness){ if (paintingDisabled()) return; clip(rect); CGContextRef context = platformContext(); // Add outer ellipse CGContextAddEllipseInRect(context, CGRectMake(rect.x(), rect.y(), rect.width(), rect.height())); // Add inner ellipse. CGContextAddEllipseInRect(context, CGRectMake(rect.x() + thickness, rect.y() + thickness, rect.width() - (thickness * 2), rect.height() - (thickness * 2))); CGContextEOClip(context);}void GraphicsContext::clipToImageBuffer(const FloatRect& rect, const ImageBuffer* imageBuffer){ if (paintingDisabled()) return; CGContextTranslateCTM(platformContext(), rect.x(), rect.y() + rect.height()); CGContextScaleCTM(platformContext(), 1, -1); CGContextClipToMask(platformContext(), FloatRect(FloatPoint(), rect.size()), imageBuffer->image()->getCGImageRef()); CGContextScaleCTM(platformContext(), 1, -1); CGContextTranslateCTM(platformContext(), -rect.x(), -rect.y() - rect.height());}void GraphicsContext::beginTransparencyLayer(float opacity){ if (paintingDisabled()) return; CGContextRef context = platformContext(); CGContextSaveGState(context); CGContextSetAlpha(context, opacity); CGContextBeginTransparencyLayer(context, 0); m_data->beginTransparencyLayer(); m_data->m_userToDeviceTransformKnownToBeIdentity = false;}void GraphicsContext::endTransparencyLayer(){ if (paintingDisabled()) return; CGContextRef context = platformContext(); CGContextEndTransparencyLayer(context); CGContextRestoreGState(context); m_data->endTransparencyLayer(); m_data->m_userToDeviceTransformKnownToBeIdentity = false;}void GraphicsContext::setPlatformShadow(const IntSize& size, int blur, const Color& color){ if (paintingDisabled()) return; CGFloat width = size.width(); CGFloat height = size.height(); CGFloat blurRadius = blur; CGContextRef context = platformContext(); if (!m_common->state.shadowsIgnoreTransforms) { CGAffineTransform transform = CGContextGetCTM(context); CGFloat A = transform.a * transform.a + transform.b * transform.b; CGFloat B = transform.a * transform.c + transform.b * transform.d; CGFloat C = B; CGFloat D = transform.c * transform.c + transform.d * transform.d; CGFloat smallEigenvalue = narrowPrecisionToCGFloat(sqrt(0.5 * ((A + D) - sqrt(4 * B * C + (A - D) * (A - D))))); // Extreme "blur" values can make text drawing crash or take crazy long times, so clamp blurRadius = min(blur * smallEigenvalue, narrowPrecisionToCGFloat(1000.0)); CGSize sizeInDeviceSpace = CGSizeApplyAffineTransform(size, transform); width = sizeInDeviceSpace.width; height = sizeInDeviceSpace.height; } // Work around <rdar://problem/5539388> by ensuring that the offsets will get truncated // to the desired integer. static const CGFloat extraShadowOffset = narrowPrecisionToCGFloat(1.0 / 128); if (width > 0) width += extraShadowOffset; else if (width < 0) width -= extraShadowOffset; if (height > 0) height += extraShadowOffset; else if (height < 0) height -= extraShadowOffset; // Check for an invalid color, as this means that the color was not set for the shadow // and we should therefore just use the default shadow color. if (!color.isValid()) CGContextSetShadow(context, CGSizeMake(width, height), blurRadius); else { CGColorRef colorCG = createCGColor(color); CGContextSetShadowWithColor(context, CGSizeMake(width, height), blurRadius, colorCG); CGColorRelease(colorCG); }}void GraphicsContext::clearPlatformShadow(){ if (paintingDisabled()) return; CGContextSetShadowWithColor(platformContext(), CGSizeZero, 0, 0);}void GraphicsContext::setMiterLimit(float limit){ if (paintingDisabled()) return; CGContextSetMiterLimit(platformContext(), limit);}void GraphicsContext::setAlpha(float alpha){ if (paintingDisabled()) return; CGContextSetAlpha(platformContext(), alpha);}void GraphicsContext::clearRect(const FloatRect& r){ if (paintingDisabled()) return; CGContextClearRect(platformContext(), r);}void GraphicsContext::strokeRect(const FloatRect& r, float lineWidth){ if (paintingDisabled()) return; CGContextRef context = platformContext(); switch (m_common->state.strokeColorSpace) { case SolidColorSpace: if (strokeColor().alpha()) CGContextStrokeRectWithWidth(context, r, lineWidth); break; case PatternColorSpace: applyStrokePattern(); CGContextStrokeRectWithWidth(context, r, lineWidth); break; case GradientColorSpace: CGContextSaveGState(context); setStrokeThickness(lineWidth); CGContextAddRect(context, r); CGContextReplacePathWithStrokedPath(context); CGContextClip(context); CGContextDrawShading(context, m_common->state.strokeGradient->platformGradient()); CGContextRestoreGState(context); break; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -