void ImageBuffer::clip(GraphicsContext* contextToClip, const FloatRect& rect) const { CGContextRef platformContextToClip = contextToClip->platformContext(); RetainPtr<CGImageRef> image(AdoptCF, copyNativeImage(DontCopyBackingStore)); CGContextTranslateCTM(platformContextToClip, rect.x(), rect.y() + rect.height()); CGContextScaleCTM(platformContextToClip, 1, -1); CGContextClipToMask(platformContextToClip, FloatRect(FloatPoint(), rect.size()), image.get()); CGContextScaleCTM(platformContextToClip, 1, -1); CGContextTranslateCTM(platformContextToClip, -rect.x(), -rect.y() - rect.height()); }
void SVGPaintServerGradient::teardown(GraphicsContext*& context, const RenderObject* object, SVGPaintTargetType type, bool isPaintingText) const { CGShadingRef shading = m_shadingCache; CGContextRef contextRef = context->platformContext(); RenderStyle* style = object->style(); ASSERT(contextRef); // As renderPath() is not used when painting text, special logic needed here. if (isPaintingText) { IntRect textBoundary = const_cast<RenderObject*>(object)->absoluteBoundingBoxRect(); FloatRect targetRect = object->absoluteTransform().inverse().mapRect(textBoundary); handleBoundingBoxModeAndGradientTransformation(context, targetRect); } if ((type & ApplyToFillTargetType) && style->svgStyle()->hasFill()) { // workaround for filling the entire screen with the shading in the case that no text was intersected with the clip if (!isPaintingText || (object->width() > 0 && object->height() > 0)) CGContextDrawShading(contextRef, shading); context->restore(); } if ((type & ApplyToStrokeTargetType) && style->svgStyle()->hasStroke()) { if (isPaintingText && m_savedContext) { IntRect maskRect = const_cast<RenderObject*>(object)->absoluteBoundingBoxRect(); maskRect = object->absoluteTransform().inverse().mapRect(maskRect); // Translate from 0x0 image origin to actual rendering position m_savedContext->translate(maskRect.x(), maskRect.y()); // Clip current context to mask image (gradient) CGContextClipToMask(m_savedContext->platformContext(), CGRectMake(0, 0, maskRect.width(), maskRect.height()), m_imageBuffer->cgImage()); m_savedContext->translate(-maskRect.x(), -maskRect.y()); // Restore on-screen drawing context, after we got the image of the gradient delete m_imageBuffer; context = m_savedContext; contextRef = context->platformContext(); m_savedContext = 0; m_imageBuffer = 0; } CGContextDrawShading(contextRef, shading); context->restore(); } context->restore(); }
void ImageBuffer::clip(GraphicsContext* context, const FloatRect& rect) const { CGContextRef platformContext = context->platformContext(); RetainPtr<CGImageRef> image; if (!m_accelerateRendering) image.adoptCF(cgImage(m_size, m_data)); #if USE(IOSURFACE_CANVAS_BACKING_STORE) else image.adoptCF(wkIOSurfaceContextCreateImage(platformContext)); #endif CGContextTranslateCTM(platformContext, rect.x(), rect.y() + rect.height()); CGContextScaleCTM(platformContext, 1, -1); CGContextClipToMask(platformContext, FloatRect(FloatPoint(), rect.size()), image.get()); CGContextScaleCTM(platformContext, 1, -1); CGContextTranslateCTM(platformContext, -rect.x(), -rect.y() - rect.height()); }
bool LockTarget(MCStackSurfaceTargetType p_type, void*& r_context) { if (p_type != kMCStackSurfaceTargetCoreGraphics) return false; CGImageRef t_mask; t_mask = nil; if (m_stack -> getwindowshape() != nil) t_mask = (CGImageRef)m_stack -> getwindowshape() -> handle; if (t_mask != nil) { MCRectangle t_card_rect; t_card_rect = m_stack -> getcurcard() -> getrect(); MCRectangle t_rect; t_rect = MCRegionGetBoundingBox(m_region); CGContextClearRect(m_context, CGRectMake(t_rect . x, t_card_rect . height - (t_rect . y + t_rect . height), t_rect . width, t_rect . height)); // MW-2012-07-25: [[ Bug ]] Make sure we use signed arithmetic to // compute the y-origin otherwise it wraps to 2^32! int32_t t_mask_height, t_mask_width; t_mask_width = (int32_t)CGImageGetWidth(t_mask); t_mask_height = (int32_t)CGImageGetHeight(t_mask); CGRect t_dst_rect; t_dst_rect . origin . x = 0; t_dst_rect . origin . y = ((int32_t)t_card_rect . height) - t_mask_height - m_stack -> getscroll(); t_dst_rect . size . width = t_mask_width; t_dst_rect . size . height = t_mask_height; CGContextClipToMask(m_context, t_dst_rect, t_mask); } CGContextSaveGState(m_context); r_context = m_context; return true; }
FX_BOOL CFX_AggDeviceDriver::DrawDeviceText(int nChars, const FXTEXT_CHARPOS * pCharPos, CFX_Font * pFont, CFX_FontCache * pCache, const CFX_AffineMatrix * pObject2Device, FX_FLOAT font_size, FX_DWORD argb, int alpha_flag, void* pIccTransform) { if (!pFont) { return FALSE; } FX_BOOL bBold = pFont->IsBold(); if (!bBold && pFont->GetSubstFont() && pFont->GetSubstFont()->m_Weight >= 500 && pFont->GetSubstFont()->m_Weight <= 600) { return FALSE; } for (int i = 0; i < nChars; i ++) { if (pCharPos[i].m_bGlyphAdjust) { return FALSE; } } CGContextRef ctx = CGContextRef(m_pPlatformGraphics); if (NULL == ctx) { return FALSE; } CGContextSaveGState(ctx); CGContextSetTextDrawingMode(ctx, kCGTextFillClip); CGRect rect_cg; CGImageRef pImageCG = NULL; if (m_pClipRgn) { rect_cg = CGRectMake(m_pClipRgn->GetBox().left, m_pClipRgn->GetBox().top, m_pClipRgn->GetBox().Width(), m_pClipRgn->GetBox().Height()); const CFX_DIBitmap* pClipMask = m_pClipRgn->GetMask(); if (pClipMask) { CGDataProviderRef pClipMaskDataProvider = CGDataProviderCreateWithData(NULL, pClipMask->GetBuffer(), pClipMask->GetPitch() * pClipMask->GetHeight(), _DoNothing); CGFloat decode_f[2] = {255.f, 0.f}; pImageCG = CGImageMaskCreate(pClipMask->GetWidth(), pClipMask->GetHeight(), 8, 8, pClipMask->GetPitch(), pClipMaskDataProvider, decode_f, FALSE); CGDataProviderRelease(pClipMaskDataProvider); } } else { rect_cg = CGRectMake(0, 0, m_pBitmap->GetWidth(), m_pBitmap->GetHeight()); } rect_cg = CGContextConvertRectToDeviceSpace(ctx, rect_cg); if (pImageCG) { CGContextClipToMask(ctx, rect_cg, pImageCG); } else { CGContextClipToRect(ctx, rect_cg); } FX_BOOL ret = _CGDrawGlyphRun(ctx, nChars, pCharPos, pFont, pCache, pObject2Device, font_size, argb, alpha_flag, pIccTransform); if (pImageCG) { CGImageRelease(pImageCG); } CGContextRestoreGState(ctx); return ret; }
FX_BOOL CFX_QuartzDeviceDriver::StretchDIBits(const CFX_DIBSource* pBitmap, FX_ARGB argb, int dest_left, int dest_top, int dest_width, int dest_height, const FX_RECT* clipRect, FX_DWORD flags, int alphaFlag , void* iccTransform , int blend_type) { SaveState(); if (clipRect) { CGContextBeginPath(_context); CGRect rect_clip = CGRectMake(clipRect->left, clipRect->top, clipRect->Width(), clipRect->Height()); rect_clip = CGRectApplyAffineTransform(rect_clip, _foxitDevice2User); CGContextAddRect(_context, rect_clip); CGContextClip(_context); } CGRect rect = CGRectMake(dest_left, dest_top, dest_width, dest_height); rect = CGRectApplyAffineTransform(rect, _foxitDevice2User); if (FXDIB_BICUBIC_INTERPOL == flags) { CGContextSetInterpolationQuality(_context, kCGInterpolationHigh); } else if (FXDIB_DOWNSAMPLE == flags) { CGContextSetInterpolationQuality(_context, kCGInterpolationNone); } else { CGContextSetInterpolationQuality(_context, kCGInterpolationMedium); } CG_SetImageTransform(dest_left, dest_top, dest_width, dest_height); CFX_DIBitmap* pBitmap1 = NULL; if (pBitmap->IsAlphaMask()) { if (pBitmap->GetBuffer()) { pBitmap1 = (CFX_DIBitmap*)pBitmap; } else { pBitmap1 = pBitmap->Clone(); } if (NULL == pBitmap1) { RestoreState(FALSE); return FALSE; } CGDataProviderRef pBitmapProvider = CGDataProviderCreateWithData(NULL, pBitmap1->GetBuffer(), pBitmap1->GetPitch() * pBitmap1->GetHeight(), NULL); CGColorSpaceRef pColorSpace = CGColorSpaceCreateDeviceGray(); CGBitmapInfo bitmapInfo = kCGImageAlphaNone | kCGBitmapByteOrderDefault; CGImageRef pImage = CGImageCreate(pBitmap1->GetWidth(), pBitmap1->GetHeight(), pBitmap1->GetBPP(), pBitmap1->GetBPP(), pBitmap1->GetPitch(), pColorSpace, bitmapInfo, pBitmapProvider, NULL, true, kCGRenderingIntentDefault); CGContextClipToMask(_context, rect, pImage); CGContextSetRGBFillColor(_context, FXARGB_R(argb) / 255.f, FXARGB_G(argb) / 255.f, FXARGB_B(argb) / 255.f, FXARGB_A(argb) / 255.f); CGContextFillRect(_context, rect); CGImageRelease(pImage); CGColorSpaceRelease(pColorSpace); CGDataProviderRelease(pBitmapProvider); if (pBitmap1 != pBitmap) { delete pBitmap1; } RestoreState(FALSE); return TRUE; } if (pBitmap->GetBPP() < 32) { pBitmap1 = pBitmap->CloneConvert(FXDIB_Rgb32); } else { if (pBitmap->GetBuffer()) { pBitmap1 = (CFX_DIBitmap*)pBitmap; } else { pBitmap1 = pBitmap->Clone(); } } if (NULL == pBitmap1) { RestoreState(FALSE); return FALSE; } if (pBitmap1->HasAlpha()) { if (pBitmap1 == pBitmap) { pBitmap1 = pBitmap->Clone(); if (!pBitmap1) { RestoreState(FALSE); return FALSE; } } for (int row = 0; row < pBitmap1->GetHeight(); row ++) { FX_LPBYTE pScanline = (FX_LPBYTE)pBitmap1->GetScanline(row); for (int col = 0; col < pBitmap1->GetWidth(); col ++) { pScanline[0] = (FX_BYTE)(pScanline[0] * pScanline[3] / 255.f + .5f); pScanline[1] = (FX_BYTE)(pScanline[1] * pScanline[3] / 255.f + .5f); pScanline[2] = (FX_BYTE)(pScanline[2] * pScanline[3] / 255.f + .5f); pScanline += 4; } } } CGContextRef ctx = createContextWithBitmap(pBitmap1); CGImageRef image = CGBitmapContextCreateImage(ctx); CGContextDrawImage(_context, rect, image); CGImageRelease(image); CGContextRelease(ctx); if (pBitmap1 != pBitmap) { delete pBitmap1; } RestoreState(FALSE); return TRUE; }
FX_BOOL CFX_QuartzDeviceDriver::SetDIBits(const CFX_DIBSource* pBitmap, FX_ARGB argb, const FX_RECT* srcRect, int dest_left, int dest_top, int blendType, int alphaFlag , void* iccTransform ) { SaveState(); CGFloat src_left, src_top, src_width, src_height; if (srcRect) { src_left = srcRect->left; src_top = srcRect->top; src_width = srcRect->Width(); src_height = srcRect->Height(); } else { src_left = src_top = 0; src_width = pBitmap->GetWidth(); src_height = pBitmap->GetHeight(); } CGAffineTransform ctm = CGContextGetCTM(_context); CGFloat scale_x = FXSYS_fabs(ctm.a); CGFloat scale_y = FXSYS_fabs(ctm.d); src_left /= scale_x; src_top /= scale_y; src_width /= scale_x; src_height /= scale_y; CGRect rect_fx = CGRectMake(dest_left, dest_top, src_width, src_height); CGRect rect_usr = CGRectApplyAffineTransform(rect_fx, _foxitDevice2User); CGContextBeginPath(_context); CGContextAddRect(_context, rect_usr); CGContextClip(_context); rect_usr.size = CGSizeMake(pBitmap->GetWidth() / scale_x, pBitmap->GetHeight() / scale_y); rect_usr = CGRectOffset(rect_usr, -src_left, -src_top); CG_SetImageTransform(dest_left, dest_top, src_width, src_height, &rect_usr); CFX_DIBitmap* pBitmap1 = NULL; if (pBitmap->IsAlphaMask()) { if (pBitmap->GetBuffer()) { pBitmap1 = (CFX_DIBitmap*)pBitmap; } else { pBitmap1 = pBitmap->Clone(); } if (NULL == pBitmap1) { RestoreState(FALSE); return FALSE; } CGDataProviderRef pBitmapProvider = CGDataProviderCreateWithData(NULL, pBitmap1->GetBuffer(), pBitmap1->GetPitch() * pBitmap1->GetHeight(), NULL); CGColorSpaceRef pColorSpace = CGColorSpaceCreateDeviceGray(); CGBitmapInfo bitmapInfo = kCGImageAlphaNone | kCGBitmapByteOrderDefault; CGImageRef pImage = CGImageCreate(pBitmap1->GetWidth(), pBitmap1->GetHeight(), pBitmap1->GetBPP(), pBitmap1->GetBPP(), pBitmap1->GetPitch(), pColorSpace, bitmapInfo, pBitmapProvider, NULL, true, kCGRenderingIntentDefault); CGContextClipToMask(_context, rect_usr, pImage); CGContextSetRGBFillColor(_context, FXARGB_R(argb) / 255.f, FXARGB_G(argb) / 255.f, FXARGB_B(argb) / 255.f, FXARGB_A(argb) / 255.f); CGContextFillRect(_context, rect_usr); CGImageRelease(pImage); CGColorSpaceRelease(pColorSpace); CGDataProviderRelease(pBitmapProvider); if (pBitmap1 != pBitmap) { delete pBitmap1; } RestoreState(FALSE); return TRUE; } if (pBitmap->GetBPP() < 32) { pBitmap1 = pBitmap->CloneConvert(FXDIB_Rgb32); } else { if (pBitmap->GetBuffer()) { pBitmap1 = (CFX_DIBitmap*)pBitmap; } else { pBitmap1 = pBitmap->Clone(); } } if (NULL == pBitmap1) { RestoreState(FALSE); return FALSE; } if (pBitmap1->HasAlpha()) { if (pBitmap1 == pBitmap) { pBitmap1 = pBitmap->Clone(); if (!pBitmap1) { RestoreState(FALSE); return FALSE; } } for (int row = 0; row < pBitmap1->GetHeight(); row ++) { FX_LPBYTE pScanline = (FX_LPBYTE)pBitmap1->GetScanline(row); for (int col = 0; col < pBitmap1->GetWidth(); col ++) { pScanline[0] = (FX_BYTE)(pScanline[0] * pScanline[3] / 255.f + .5f); pScanline[1] = (FX_BYTE)(pScanline[1] * pScanline[3] / 255.f + .5f); pScanline[2] = (FX_BYTE)(pScanline[2] * pScanline[3] / 255.f + .5f); pScanline += 4; } } } CGContextRef ctx = createContextWithBitmap(pBitmap1); CGImageRef image = CGBitmapContextCreateImage(ctx); int blend_mode = blendType; if (FXDIB_BLEND_HARDLIGHT == blendType) { blend_mode = kCGBlendModeSoftLight; } else if (FXDIB_BLEND_SOFTLIGHT == blendType) { blend_mode = kCGBlendModeHardLight; } else if (blendType >= FXDIB_BLEND_NONSEPARABLE && blendType <= FXDIB_BLEND_LUMINOSITY) { blend_mode = blendType - 9; } else if (blendType > FXDIB_BLEND_LUMINOSITY || blendType < 0) { blend_mode = kCGBlendModeNormal; } CGContextSetBlendMode(_context, (CGBlendMode)blend_mode); CGContextDrawImage(_context, rect_usr, image); CGImageRelease(image); CGContextRelease(ctx); if (pBitmap1 != pBitmap) { delete pBitmap1; } RestoreState(FALSE); return TRUE; }
void CGContextClipToMask_wrap(CGContextRef c, float x, float y, float w, float h, CGImageRef mask) { CGContextClipToMask(c, CGRectMake(x, y, w, h), mask); }