📄 graphicscontextcg.cpp
字号:
void GraphicsContext::setLineCap(LineCap cap){ if (paintingDisabled()) return; switch (cap) { case ButtCap: CGContextSetLineCap(platformContext(), kCGLineCapButt); break; case RoundCap: CGContextSetLineCap(platformContext(), kCGLineCapRound); break; case SquareCap: CGContextSetLineCap(platformContext(), kCGLineCapSquare); break; }}void GraphicsContext::setLineDash(const DashArray& dashes, float dashOffset){ CGContextSetLineDash(platformContext(), dashOffset, dashes.data(), dashes.size());}void GraphicsContext::setLineJoin(LineJoin join){ if (paintingDisabled()) return; switch (join) { case MiterJoin: CGContextSetLineJoin(platformContext(), kCGLineJoinMiter); break; case RoundJoin: CGContextSetLineJoin(platformContext(), kCGLineJoinRound); break; case BevelJoin: CGContextSetLineJoin(platformContext(), kCGLineJoinBevel); break; }}void GraphicsContext::beginPath(){ CGContextBeginPath(platformContext());}void GraphicsContext::addPath(const Path& path){ CGContextAddPath(platformContext(), path.platformPath());}void GraphicsContext::clip(const Path& path){ if (paintingDisabled()) return; CGContextRef context = platformContext(); CGContextBeginPath(context); CGContextAddPath(context, path.platformPath()); CGContextClip(context); m_data->clip(path);}void GraphicsContext::clipOut(const Path& path){ if (paintingDisabled()) return; CGContextBeginPath(platformContext()); CGContextAddRect(platformContext(), CGContextGetClipBoundingBox(platformContext())); CGContextAddPath(platformContext(), path.platformPath()); CGContextEOClip(platformContext());}void GraphicsContext::scale(const FloatSize& size){ if (paintingDisabled()) return; CGContextScaleCTM(platformContext(), size.width(), size.height()); m_data->scale(size); m_data->m_userToDeviceTransformKnownToBeIdentity = false;}void GraphicsContext::rotate(float angle){ if (paintingDisabled()) return; CGContextRotateCTM(platformContext(), angle); m_data->rotate(angle); m_data->m_userToDeviceTransformKnownToBeIdentity = false;}void GraphicsContext::translate(float x, float y){ if (paintingDisabled()) return; CGContextTranslateCTM(platformContext(), x, y); m_data->translate(x, y); m_data->m_userToDeviceTransformKnownToBeIdentity = false;}void GraphicsContext::concatCTM(const TransformationMatrix& transform){ if (paintingDisabled()) return; CGContextConcatCTM(platformContext(), transform); m_data->concatCTM(transform); m_data->m_userToDeviceTransformKnownToBeIdentity = false;}TransformationMatrix GraphicsContext::getCTM() const{ CGAffineTransform t = CGContextGetCTM(platformContext()); return TransformationMatrix(t.a, t.b, t.c, t.d, t.tx, t.ty);}FloatRect GraphicsContext::roundToDevicePixels(const FloatRect& rect){ // It is not enough just to round to pixels in device space. The rotation part of the // affine transform matrix to device space can mess with this conversion if we have a // rotating image like the hands of the world clock widget. We just need the scale, so // we get the affine transform matrix and extract the scale. if (m_data->m_userToDeviceTransformKnownToBeIdentity) return rect; CGAffineTransform deviceMatrix = CGContextGetUserSpaceToDeviceSpaceTransform(platformContext()); if (CGAffineTransformIsIdentity(deviceMatrix)) { m_data->m_userToDeviceTransformKnownToBeIdentity = true; return rect; } float deviceScaleX = sqrtf(deviceMatrix.a * deviceMatrix.a + deviceMatrix.b * deviceMatrix.b); float deviceScaleY = sqrtf(deviceMatrix.c * deviceMatrix.c + deviceMatrix.d * deviceMatrix.d); CGPoint deviceOrigin = CGPointMake(rect.x() * deviceScaleX, rect.y() * deviceScaleY); CGPoint deviceLowerRight = CGPointMake((rect.x() + rect.width()) * deviceScaleX, (rect.y() + rect.height()) * deviceScaleY); deviceOrigin.x = roundf(deviceOrigin.x); deviceOrigin.y = roundf(deviceOrigin.y); deviceLowerRight.x = roundf(deviceLowerRight.x); deviceLowerRight.y = roundf(deviceLowerRight.y); // Don't let the height or width round to 0 unless either was originally 0 if (deviceOrigin.y == deviceLowerRight.y && rect.height() != 0) deviceLowerRight.y += 1; if (deviceOrigin.x == deviceLowerRight.x && rect.width() != 0) deviceLowerRight.x += 1; FloatPoint roundedOrigin = FloatPoint(deviceOrigin.x / deviceScaleX, deviceOrigin.y / deviceScaleY); FloatPoint roundedLowerRight = FloatPoint(deviceLowerRight.x / deviceScaleX, deviceLowerRight.y / deviceScaleY); return FloatRect(roundedOrigin, roundedLowerRight - roundedOrigin);}void GraphicsContext::drawLineForText(const IntPoint& point, int width, bool printing){ if (paintingDisabled()) return; if (width <= 0) return; float x = point.x(); float y = point.y(); float lineLength = width; // Use a minimum thickness of 0.5 in user space. // See http://bugs.webkit.org/show_bug.cgi?id=4255 for details of why 0.5 is the right minimum thickness to use. float thickness = max(strokeThickness(), 0.5f); bool restoreAntialiasMode = false; if (!printing) { // On screen, use a minimum thickness of 1.0 in user space (later rounded to an integral number in device space). float adjustedThickness = max(thickness, 1.0f); // FIXME: This should be done a better way. // We try to round all parameters to integer boundaries in device space. If rounding pixels in device space // makes our thickness more than double, then there must be a shrinking-scale factor and rounding to pixels // in device space will make the underlines too thick. CGRect lineRect = roundToDevicePixels(FloatRect(x, y, lineLength, adjustedThickness)); if (lineRect.size.height < thickness * 2.0) { x = lineRect.origin.x; y = lineRect.origin.y; lineLength = lineRect.size.width; thickness = lineRect.size.height; if (shouldAntialias()) { CGContextSetShouldAntialias(platformContext(), false); restoreAntialiasMode = true; } } } if (fillColor() != strokeColor()) setCGFillColor(platformContext(), strokeColor()); CGContextFillRect(platformContext(), CGRectMake(x, y, lineLength, thickness)); if (fillColor() != strokeColor()) setCGFillColor(platformContext(), fillColor()); if (restoreAntialiasMode) CGContextSetShouldAntialias(platformContext(), true);}void GraphicsContext::setURLForRect(const KURL& link, const IntRect& destRect){ if (paintingDisabled()) return; CFURLRef urlRef = link.createCFURL(); if (urlRef) { CGContextRef context = platformContext(); // Get the bounding box to handle clipping. CGRect box = CGContextGetClipBoundingBox(context); IntRect intBox((int)box.origin.x, (int)box.origin.y, (int)box.size.width, (int)box.size.height); IntRect rect = destRect; rect.intersect(intBox); CGPDFContextSetURLForRect(context, urlRef, CGRectApplyAffineTransform(rect, CGContextGetCTM(context))); CFRelease(urlRef); }}void GraphicsContext::setImageInterpolationQuality(InterpolationQuality mode){ if (paintingDisabled()) return; CGInterpolationQuality quality = kCGInterpolationDefault; switch (mode) { case InterpolationDefault: quality = kCGInterpolationDefault; break; case InterpolationNone: quality = kCGInterpolationNone; break; case InterpolationLow: quality = kCGInterpolationLow; break; // Fall through to InterpolationHigh if kCGInterpolationMedium is not available case InterpolationMedium:#if HAVE(CG_INTERPOLATION_MEDIUM) quality = kCGInterpolationMedium; break;#endif case InterpolationHigh: quality = kCGInterpolationHigh; break; } CGContextSetInterpolationQuality(platformContext(), quality);}InterpolationQuality GraphicsContext::imageInterpolationQuality() const{ if (paintingDisabled()) return InterpolationDefault; CGInterpolationQuality quality = CGContextGetInterpolationQuality(platformContext()); switch (quality) { case kCGInterpolationDefault: return InterpolationDefault; case kCGInterpolationNone: return InterpolationNone; case kCGInterpolationLow: return InterpolationLow;#if HAVE(CG_INTERPOLATION_MEDIUM) case kCGInterpolationMedium: return InterpolationMedium;#endif case kCGInterpolationHigh: return InterpolationHigh; } return InterpolationDefault;}void GraphicsContext::setPlatformTextDrawingMode(int mode){ if (paintingDisabled()) return; // Wow, wish CG had used bits here. CGContextRef context = platformContext(); switch (mode) { case cTextInvisible: // Invisible CGContextSetTextDrawingMode(context, kCGTextInvisible); break; case cTextFill: // Fill CGContextSetTextDrawingMode(context, kCGTextFill); break; case cTextStroke: // Stroke CGContextSetTextDrawingMode(context, kCGTextStroke); break; case 3: // Fill | Stroke CGContextSetTextDrawingMode(context, kCGTextFillStroke); break; case cTextClip: // Clip CGContextSetTextDrawingMode(context, kCGTextClip); break; case 5: // Fill | Clip CGContextSetTextDrawingMode(context, kCGTextFillClip); break; case 6: // Stroke | Clip CGContextSetTextDrawingMode(context, kCGTextStrokeClip); break; case 7: // Fill | Stroke | Clip CGContextSetTextDrawingMode(context, kCGTextFillStrokeClip); break; default: break; }}void GraphicsContext::setPlatformStrokeColor(const Color& color){ if (paintingDisabled()) return; setCGStrokeColor(platformContext(), color);}void GraphicsContext::setPlatformStrokeThickness(float thickness){ if (paintingDisabled()) return; CGContextSetLineWidth(platformContext(), thickness);}void GraphicsContext::setPlatformFillColor(const Color& color){ if (paintingDisabled()) return; setCGFillColor(platformContext(), color);}void GraphicsContext::setPlatformShouldAntialias(bool enable){ if (paintingDisabled()) return; CGContextSetShouldAntialias(platformContext(), enable);}#ifndef BUILDING_ON_TIGER // Tiger's setCompositeOperation() is defined in GraphicsContextMac.mm.void GraphicsContext::setCompositeOperation(CompositeOperator mode){ if (paintingDisabled()) return; CGBlendMode target = kCGBlendModeNormal; switch (mode) { case CompositeClear: target = kCGBlendModeClear; break; case CompositeCopy: target = kCGBlendModeCopy; break; case CompositeSourceOver: //kCGBlendModeNormal break; case CompositeSourceIn: target = kCGBlendModeSourceIn; break; case CompositeSourceOut: target = kCGBlendModeSourceOut; break; case CompositeSourceAtop: target = kCGBlendModeSourceAtop; break; case CompositeDestinationOver: target = kCGBlendModeDestinationOver; break; case CompositeDestinationIn: target = kCGBlendModeDestinationIn; break; case CompositeDestinationOut: target = kCGBlendModeDestinationOut; break; case CompositeDestinationAtop: target = kCGBlendModeDestinationAtop; break; case CompositeXOR: target = kCGBlendModeXOR; break; case CompositePlusDarker: target = kCGBlendModePlusDarker; break; case CompositeHighlight: // currently unsupported break; case CompositePlusLighter: target = kCGBlendModePlusLighter; break; } CGContextSetBlendMode(platformContext(), target);}#endif}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -