void PlatformCALayer::drawRepaintIndicator(CGContextRef context, PlatformCALayer* platformCALayer, int repaintCount, CGColorRef customBackgroundColor) { char text[16]; // that's a lot of repaints snprintf(text, sizeof(text), "%d", repaintCount); CGRect indicatorBox = platformCALayer->bounds(); CGContextSaveGState(context); indicatorBox.size.width = 12 + 10 * strlen(text); indicatorBox.size.height = 27; CGContextSetAlpha(context, 0.5f); CGContextBeginTransparencyLayerWithRect(context, indicatorBox, 0); if (customBackgroundColor) CGContextSetFillColorWithColor(context, customBackgroundColor); else CGContextSetRGBFillColor(context, 0, 0.5f, 0.25f, 1); CGContextFillRect(context, indicatorBox); if (platformCALayer->acceleratesDrawing()) CGContextSetRGBFillColor(context, 1, 0, 0, 1); else CGContextSetRGBFillColor(context, 1, 1, 1, 1); platformCALayer->drawTextAtPoint(context, indicatorBox.origin.x + 5, indicatorBox.origin.y + 22, CGSizeMake(1, -1), 22, text, strlen(text)); CGContextEndTransparencyLayer(context); CGContextRestoreGState(context); }
bool MCTileCacheCoreGraphicsCompositor_BeginLayer(void *p_context, const MCRectangle& p_clip, uint32_t p_opacity, uint32_t p_ink) { MCTileCacheCoreGraphicsCompositorContext *self; self = (MCTileCacheCoreGraphicsCompositorContext *)p_context; CGContextSaveGState(self -> cgcontext); // MW-2012-09-18: [[ Bug 10202 ]] If the ink is no-op then ensure nothing happens. if (p_ink == GXnoop) CGContextClipToRect(self -> cgcontext, CGRectZero); else { CGContextClipToRect(self -> cgcontext, CGRectMake(p_clip . x, self -> viewport_height - (p_clip . y + p_clip . height), p_clip . width, p_clip . height)); CGContextSetAlpha(self -> cgcontext, p_opacity / 255.0); CGBlendMode t_blend_mode; switch(p_ink) { case GXblendMultiply: t_blend_mode = kCGBlendModeMultiply; break; case GXblendScreen: t_blend_mode = kCGBlendModeScreen; break; case GXblendOverlay: t_blend_mode = kCGBlendModeOverlay; break; case GXblendDarken: t_blend_mode = kCGBlendModeDarken; break; case GXblendLighten: t_blend_mode = kCGBlendModeLighten; break; case GXblendDodge: t_blend_mode = kCGBlendModeColorDodge; break; case GXblendBurn: t_blend_mode = kCGBlendModeColorBurn; break; case GXblendSoftLight: t_blend_mode = kCGBlendModeSoftLight; break; case GXblendHardLight: t_blend_mode = kCGBlendModeHardLight; break; case GXblendDifference: t_blend_mode = kCGBlendModeDifference; break; case GXblendExclusion: t_blend_mode = kCGBlendModeExclusion; break; default: t_blend_mode = kCGBlendModeNormal; break; } CGContextSetBlendMode(self -> cgcontext, t_blend_mode); } return true; }
void PlatformCALayer::drawRepaintIndicator(CGContextRef context, PlatformCALayer* platformCALayer, int repaintCount, CGColorRef customBackgroundColor) { char text[16]; // that's a lot of repaints snprintf(text, sizeof(text), "%d", repaintCount); CGRect indicatorBox = platformCALayer->bounds(); indicatorBox.size.width = 12 + 10 * strlen(text); indicatorBox.size.height = 27; CGContextSaveGState(context); CGContextSetAlpha(context, 0.5f); CGContextBeginTransparencyLayerWithRect(context, indicatorBox, 0); if (customBackgroundColor) CGContextSetFillColorWithColor(context, customBackgroundColor); else CGContextSetRGBFillColor(context, 0, 0.5f, 0.25f, 1); CGContextFillRect(context, indicatorBox); if (platformCALayer->acceleratesDrawing()) CGContextSetRGBFillColor(context, 1, 0, 0, 1); else CGContextSetRGBFillColor(context, 1, 1, 1, 1); #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" CGContextSetTextMatrix(context, CGAffineTransformMakeScale(1, -1)); CGContextSelectFont(context, "Helvetica", 22, kCGEncodingMacRoman); CGContextShowTextAtPoint(context, indicatorBox.origin.x + 5, indicatorBox.origin.y + 22, text, strlen(text)); #pragma clang diagnostic pop CGContextEndTransparencyLayer(context); CGContextRestoreGState(context); }
void ImageBuffer::putByteArray(Multiply multiplied, ByteArray* source, const IntSize& sourceSize, const IntRect& sourceRect, const IntPoint& destPoint) { if (!m_context->isAcceleratedContext()) { m_data.putData(source, sourceSize, sourceRect, destPoint, internalSize(), m_context->isAcceleratedContext(), multiplied == Unmultiplied); return; } #if USE(IOSURFACE_CANVAS_BACKING_STORE) // Make a copy of the source to ensure the bits don't change before being drawn IntSize sourceCopySize(sourceRect.width(), sourceRect.height()); OwnPtr<ImageBuffer> sourceCopy = ImageBuffer::create(sourceCopySize, 1, ColorSpaceDeviceRGB, Unaccelerated); if (!sourceCopy) return; sourceCopy->m_data.putData(source, sourceSize, sourceRect, IntPoint(-sourceRect.x(), -sourceRect.y()), sourceCopy->internalSize(), sourceCopy->context()->isAcceleratedContext(), multiplied == Unmultiplied); // Set up context for using drawImage as a direct bit copy CGContextRef destContext = context()->platformContext(); CGContextSaveGState(destContext); CGContextConcatCTM(destContext, AffineTransform(CGContextGetCTM(destContext)).inverse()); wkCGContextResetClip(destContext); CGContextSetInterpolationQuality(destContext, kCGInterpolationNone); CGContextSetAlpha(destContext, 1.0); CGContextSetBlendMode(destContext, kCGBlendModeCopy); CGContextSetShadowWithColor(destContext, CGSizeZero, 0, 0); // Draw the image in CG coordinate space IntPoint destPointInCGCoords(destPoint.x() + sourceRect.x(), internalSize().height() - (destPoint.y()+sourceRect.y()) - sourceRect.height()); IntRect destRectInCGCoords(destPointInCGCoords, sourceCopySize); RetainPtr<CGImageRef> sourceCopyImage(AdoptCF, sourceCopy->copyNativeImage()); CGContextDrawImage(destContext, destRectInCGCoords, sourceCopyImage.get()); CGContextRestoreGState(destContext); #endif }
//----------------------------------------------------------------------------- void CGDrawContext::setGlobalAlpha (float newAlpha) { if (newAlpha == currentState.globalAlpha) return; CGContextSetAlpha (cgContext, newAlpha); CDrawContext::setGlobalAlpha (newAlpha); }
//----------------------------------------------------------------------------- void CGDrawContext::drawBitmap (CBitmap* bitmap, const CRect& inRect, const CPoint& inOffset, float alpha) { if (bitmap == 0 || alpha == 0.f) return; CGBitmap* cgBitmap = bitmap->getPlatformBitmap () ? dynamic_cast<CGBitmap*> (bitmap->getPlatformBitmap ()) : 0; CGImageRef image = cgBitmap ? cgBitmap->getCGImage () : 0; if (image) { CGContextRef context = beginCGContext (false, true); if (context) { CRect rect (inRect); rect.makeIntegral (); CPoint offset (inOffset); offset.makeIntegral (); CGContextSetAlpha (context, (CGFloat)alpha*currentState.globalAlpha); CGRect dest; dest.origin.x = rect.left - offset.h; dest.origin.y = -(rect.top) - (bitmap->getHeight () - offset.v); dest.size.width = cgBitmap->getSize ().x; dest.size.height = cgBitmap->getSize ().y; CGRect clipRect2; clipRect2.origin.x = rect.left; clipRect2.origin.y = -(rect.top) - rect.height (); clipRect2.size.width = rect.width (); clipRect2.size.height = rect.height (); CGContextClipToRect (context, clipRect2); CGLayerRef layer = cgBitmap->getCGLayer (); if (layer == 0) { BitmapDrawCountMap::iterator it = bitmapDrawCount.find (cgBitmap); if (it == bitmapDrawCount.end ()) { bitmapDrawCount.insert (std::pair<CGBitmap*, int32_t> (cgBitmap, 1)); CGContextDrawImage (context, dest, image); } else { it->second++; layer = cgBitmap->createCGLayer (context); } } if (layer) { CGContextDrawLayerInRect (context, dest, layer); } releaseCGContext (context); } } }
void GraphicsContext::beginTransparencyLayer(float opacity) { if (paintingDisabled()) return; CGContextRef context = platformContext(); CGContextSaveGState(context); CGContextSetAlpha(context, opacity); CGContextBeginTransparencyLayer(context, 0); m_data->beginTransparencyLayer(); }
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; }
DRAW_TEST_F(CGContext, DrawAnImageWithInterpolationQualityAndAlpha, UIKitMimicTest<>) { auto drawingConfig = DrawingTestConfig::Get(); woc::unique_cf<CFStringRef> testFilename{ _CFStringCreateWithStdString(drawingConfig->GetResourcePath("png1.9.png")) }; woc::unique_cf<CGImageRef> image{ _CGImageCreateFromPNGFile(testFilename.get()) }; ASSERT_NE(image, nullptr); CGContextRef context = GetDrawingContext(); CGRect bounds = GetDrawingBounds(); CGContextSetAlpha(context, 0.25); CGContextSetInterpolationQuality(context, kCGInterpolationHigh); CGContextDrawImage(context, bounds, image.get()); }
void PlatformCALayer::drawRepaintIndicator(CGContextRef context, PlatformCALayer* platformCALayer, int repaintCount, CGColorRef customBackgroundColor) { char text[16]; // that's a lot of repaints snprintf(text, sizeof(text), "%d", repaintCount); FloatRect indicatorBox = platformCALayer->bounds();\ indicatorBox.setLocation( { 1, 1 } ); indicatorBox.setSize(FloatSize(12 + 10 * strlen(text), 27)); CGContextStateSaver stateSaver(context); CGContextSetAlpha(context, 0.5f); CGContextBeginTransparencyLayerWithRect(context, indicatorBox, 0); if (customBackgroundColor) CGContextSetFillColorWithColor(context, customBackgroundColor); else CGContextSetRGBFillColor(context, 0, 0.5f, 0.25f, 1); if (platformCALayer->isOpaque()) CGContextFillRect(context, indicatorBox); else { Path boundsPath; boundsPath.moveTo(indicatorBox.maxXMinYCorner()); boundsPath.addLineTo(indicatorBox.maxXMaxYCorner()); boundsPath.addLineTo(indicatorBox.minXMaxYCorner()); const float cornerChunk = 8; boundsPath.addLineTo(FloatPoint(indicatorBox.x(), indicatorBox.y() + cornerChunk)); boundsPath.addLineTo(FloatPoint(indicatorBox.x() + cornerChunk, indicatorBox.y())); boundsPath.closeSubpath(); CGContextAddPath(context, boundsPath.platformPath()); CGContextFillPath(context); } if (platformCALayer->owner()->isUsingDisplayListDrawing(platformCALayer)) { CGContextSetRGBStrokeColor(context, 0, 0, 0, 0.65); CGContextSetLineWidth(context, 2); CGContextStrokeRect(context, indicatorBox); } if (platformCALayer->acceleratesDrawing()) CGContextSetRGBFillColor(context, 1, 0, 0, 1); else CGContextSetRGBFillColor(context, 1, 1, 1, 1); platformCALayer->drawTextAtPoint(context, indicatorBox.x() + 5, indicatorBox.y() + 22, CGSizeMake(1, -1), 22, text, strlen(text)); CGContextEndTransparencyLayer(context); }
void ImageBuffer::putByteArray(Multiply multiplied, Uint8ClampedArray* source, const IntSize& sourceSize, const IntRect& sourceRect, const IntPoint& destPoint, CoordinateSystem coordinateSystem) { if (!context().isAcceleratedContext()) { IntRect scaledSourceRect = sourceRect; IntSize scaledSourceSize = sourceSize; if (coordinateSystem == LogicalCoordinateSystem) { scaledSourceRect.scale(m_resolutionScale); scaledSourceSize.scale(m_resolutionScale); } m_data.putData(source, scaledSourceSize, scaledSourceRect, destPoint, internalSize(), false, multiplied == Unmultiplied, 1); return; } #if USE(IOSURFACE_CANVAS_BACKING_STORE) // Make a copy of the source to ensure the bits don't change before being drawn IntSize sourceCopySize(sourceRect.width(), sourceRect.height()); // FIXME (149431): Should this ImageBuffer be unconditionally unaccelerated? Making it match the context seems to break putData(). std::unique_ptr<ImageBuffer> sourceCopy = ImageBuffer::create(sourceCopySize, Unaccelerated, 1, ColorSpaceDeviceRGB); if (!sourceCopy) return; sourceCopy->m_data.putData(source, sourceSize, sourceRect, IntPoint(-sourceRect.x(), -sourceRect.y()), sourceCopy->internalSize(), sourceCopy->context().isAcceleratedContext(), multiplied == Unmultiplied, 1); // Set up context for using drawImage as a direct bit copy CGContextRef destContext = context().platformContext(); CGContextSaveGState(destContext); if (coordinateSystem == LogicalCoordinateSystem) CGContextConcatCTM(destContext, AffineTransform(wkGetUserToBaseCTM(destContext)).inverse()); else CGContextConcatCTM(destContext, AffineTransform(CGContextGetCTM(destContext)).inverse()); CGContextResetClip(destContext); CGContextSetInterpolationQuality(destContext, kCGInterpolationNone); CGContextSetAlpha(destContext, 1.0); CGContextSetBlendMode(destContext, kCGBlendModeCopy); CGContextSetShadowWithColor(destContext, CGSizeZero, 0, 0); // Draw the image in CG coordinate space FloatSize scaledDestSize = scaleSizeToUserSpace(coordinateSystem == LogicalCoordinateSystem ? logicalSize() : internalSize(), m_data.backingStoreSize, internalSize()); IntPoint destPointInCGCoords(destPoint.x() + sourceRect.x(), scaledDestSize.height() - (destPoint.y() + sourceRect.y()) - sourceRect.height()); IntRect destRectInCGCoords(destPointInCGCoords, sourceCopySize); CGContextClipToRect(destContext, destRectInCGCoords); RetainPtr<CGImageRef> sourceCopyImage = sourceCopy->copyNativeImage(); FloatRect backingStoreInDestRect = FloatRect(FloatPoint(destPointInCGCoords.x(), destPointInCGCoords.y() + sourceCopySize.height() - (int)CGImageGetHeight(sourceCopyImage.get())), FloatSize(CGImageGetWidth(sourceCopyImage.get()), CGImageGetHeight(sourceCopyImage.get()))); CGContextDrawImage(destContext, backingStoreInDestRect, sourceCopyImage.get()); CGContextRestoreGState(destContext); #endif }
bool SVGPaintServerGradient::setup(GraphicsContext*& context, const RenderObject* object, SVGPaintTargetType type, bool isPaintingText) const { m_ownerElement->buildGradient(); // We need a hook to call this when the gradient gets updated, before drawn. if (!m_shadingCache) const_cast<SVGPaintServerGradient*>(this)->updateQuartzGradientCache(this); CGContextRef contextRef = context->platformContext(); RenderStyle* style = object->style(); ASSERT(contextRef); context->save(); CGContextSetAlpha(contextRef, style->opacity()); if ((type & ApplyToFillTargetType) && style->svgStyle()->hasFill()) { context->save(); if (isPaintingText) context->setTextDrawingMode(cTextClip); } if ((type & ApplyToStrokeTargetType) && style->svgStyle()->hasStroke()) { context->save(); applyStrokeStyleToContext(contextRef, style, object); if (isPaintingText) { IntRect maskRect = const_cast<RenderObject*>(object)->absoluteBoundingBoxRect(); maskRect = object->absoluteTransform().inverse().mapRect(maskRect); auto_ptr<ImageBuffer> maskImage = ImageBuffer::create(IntSize(maskRect.width(), maskRect.height()), false); // FIXME: maskImage could be NULL GraphicsContext* maskImageContext = maskImage->context(); maskImageContext->save(); maskImageContext->translate(-maskRect.x(), -maskRect.y()); const_cast<RenderObject*>(object)->style()->setColor(Color(255, 255, 255)); maskImageContext->setTextDrawingMode(cTextStroke); m_imageBuffer = maskImage.release(); m_savedContext = context; context = maskImageContext; } } return true; }
DRAW_TEST_F(CGContext, DrawAnImageWithOpacity, UIKitMimicTest<>) { // Load an Image and draw it into the canvas context auto drawingConfig = DrawingTestConfig::Get(); woc::unique_cf<CFStringRef> testFilename{ _CFStringCreateWithStdString(drawingConfig->GetResourcePath("png1.9.png")) }; woc::unique_cf<CGImageRef> image{ _CGImageCreateFromPNGFile(testFilename.get()) }; ASSERT_NE(image, nullptr); CGContextRef context = GetDrawingContext(); CGRect bounds = GetDrawingBounds(); CGAffineTransform flip = CGAffineTransformMakeScale(1, -1); CGAffineTransform shift = CGAffineTransformTranslate(flip, 0, bounds.size.height * -1); CGContextConcatCTM(context, shift); CGContextSetAlpha(context, 0.7); CGContextDrawImage(context, bounds, image.get()); }
//----------------------------------------------------------------------------- void CGDrawContext::drawCGImageRef (CGContextRef context, CGImageRef image, CGLayerRef layer, double bitmapScaleFactor, const CRect& inRect, const CPoint& inOffset, float alpha, CBitmap* bitmap) { CRect rect (inRect); CPoint offset (inOffset); CGContextSetAlpha (context, (CGFloat)alpha*currentState.globalAlpha); CGRect dest; dest.origin.x = static_cast<CGFloat> (rect.left - offset.x); dest.origin.y = static_cast<CGFloat> (-(rect.top) - (bitmap->getHeight () - offset.y)); dest.size.width = static_cast<CGFloat> (bitmap->getWidth ()); dest.size.height = static_cast<CGFloat> (bitmap->getHeight ()); CGRect clipRect; clipRect.origin.x = static_cast<CGFloat> (rect.left); clipRect.origin.y = static_cast<CGFloat> (-(rect.top) - rect.getHeight ()); clipRect.size.width = static_cast<CGFloat> (rect.getWidth ()); clipRect.size.height = static_cast<CGFloat> (rect.getHeight ()); if (bitmapScaleFactor != 1.) { CGContextConcatCTM (context, CGAffineTransformMakeScale (static_cast<CGFloat> (1./bitmapScaleFactor), static_cast<CGFloat> (1./bitmapScaleFactor))); CGAffineTransform transform = CGAffineTransformMakeScale (static_cast<CGFloat> (bitmapScaleFactor), static_cast<CGFloat> (bitmapScaleFactor)); clipRect.origin = CGPointApplyAffineTransform (clipRect.origin, transform); clipRect.size = CGSizeApplyAffineTransform (clipRect.size, transform); dest.origin = CGPointApplyAffineTransform (dest.origin, transform); dest.size = CGSizeApplyAffineTransform (dest.size, transform); } dest = pixelAlligned (dest); clipRect = pixelAlligned (clipRect); CGContextClipToRect (context, clipRect); if (layer) { CGContextDrawLayerInRect (context, dest, layer); } else { CGContextDrawImage (context, dest, image); } }
void drawWithGlobalAlpha(CGContextRef context) { int i; CGRect rect = CGRectMake(40., 210., 100., 100.); float color[4] = { 1.0, 0.0, 0.0, 1.0 }; // opaque red // Set the fill color space to that returned by getTheCalibratedRGBColorSpace. CGContextSetFillColorSpace(context, getTheCalibratedRGBColorSpace()); CGContextSetFillColor(context, color); for(i = 0; i < 2 ; i++){ CGContextSaveGState(context); // Paint the leftmost rect on this row with 100% opaque red. CGContextFillRect(context, rect); CGContextTranslateCTM(context, rect.size.width + 70., 0.); // Set the alpha value of this rgba color to 0.5. color[3] = 0.5; // Use the new color as the fill color in the graphics state. CGContextSetFillColor(context, color); // Paint the center rect on this row with 50% opaque red. CGContextFillRect(context, rect); CGContextTranslateCTM(context, rect.size.width + 70., 0.); // Set the alpha value of this rgba color to 0.25. color[3] = 0.25; // Use the new color as the fill color in the graphics state. CGContextSetFillColor(context, color); // Paint the rightmost rect on this row with 25% opaque red. CGContextFillRect(context, rect); CGContextRestoreGState(context); // After restoring the graphics state, the fill color is set to // that prior to calling CGContextSaveGState, that is, opaque // red. The coordinate system is also restored. // Now set the context global alpha value to 50% opaque. CGContextSetAlpha(context, 0.5); // Translate down for a second row of rectangles. CGContextTranslateCTM(context, 0., -(rect.size.height + 70.)); // Reset the alpha value of the color array to fully opaque. color[3] = 1.0; } }
DISABLED_DRAW_TEST_F(CGImageDrawing, TiledImageMultiColorFlowerScaledAlpha2, UIKitMimicTest<>) { CGRect rect = { { 0, 0 }, { 256, 256 } }; CGContextSetAlpha(GetDrawingContext(), 0.24); _drawTiledImage(GetDrawingContext(), rect, "tiledImageMultiColorFlower.png"); }
void GraphicsContext::drawLineForMisspellingOrBadGrammar(const IntPoint& point, int width, bool grammar) { if (paintingDisabled()) return; // These are the same for misspelling or bad grammar const int patternHeight = 3; // 3 rows ASSERT(cMisspellingLineThickness == patternHeight); const int patternWidth = 4; // 4 pixels ASSERT(patternWidth == cMisspellingLinePatternWidth); // Make sure to draw only complete dots. // NOTE: Code here used to shift the underline to the left and increase the width // to make sure everything gets underlined, but that results in drawing out of // bounds (e.g. when at the edge of a view) and could make it appear that the // space between adjacent misspelled words was underlined. // allow slightly more considering that the pattern ends with a transparent pixel int widthMod = width % patternWidth; if (patternWidth - widthMod > cMisspellingLinePatternGapWidth) width -= widthMod; // Draw the underline CGContextRef context = platformContext(); CGContextSaveGState(context); const Color& patternColor = grammar ? grammarPatternColor() : spellingPatternColor(); setCGStrokeColor(context, patternColor); wkSetPatternPhaseInUserSpace(context, point); CGContextSetBlendMode(context, kCGBlendModeNormal); // 3 rows, each offset by half a pixel for blending purposes const CGPoint upperPoints [] = {{point.x(), point.y() + patternHeight - 2.5 }, {point.x() + width, point.y() + patternHeight - 2.5}}; const CGPoint middlePoints [] = {{point.x(), point.y() + patternHeight - 1.5 }, {point.x() + width, point.y() + patternHeight - 1.5}}; const CGPoint lowerPoints [] = {{point.x(), point.y() + patternHeight - 0.5 }, {point.x() + width, point.y() + patternHeight - 0.5 }}; // Dash lengths for the top and bottom of the error underline are the same. // These are magic. static const float edge_dash_lengths[] = {2.0f, 2.0f}; static const float middle_dash_lengths[] = {2.76f, 1.24f}; static const float edge_offset = -(edge_dash_lengths[1] - 1.0f) / 2.0f; static const float middle_offset = -(middle_dash_lengths[1] - 1.0f) / 2.0f; // Line opacities. Once again, these are magic. const float upperOpacity = 0.33f; const float middleOpacity = 0.75f; const float lowerOpacity = 0.88f; //Top line CGContextSetLineDash(context, edge_offset, edge_dash_lengths, sizeof(edge_dash_lengths) / sizeof(edge_dash_lengths[0])); CGContextSetAlpha(context, upperOpacity); CGContextStrokeLineSegments(context, upperPoints, 2); // Middle line CGContextSetLineDash(context, middle_offset, middle_dash_lengths, sizeof(middle_dash_lengths) / sizeof(middle_dash_lengths[0])); CGContextSetAlpha(context, middleOpacity); CGContextStrokeLineSegments(context, middlePoints, 2); // Bottom line CGContextSetLineDash(context, edge_offset, edge_dash_lengths, sizeof(edge_dash_lengths) / sizeof(edge_dash_lengths[0])); CGContextSetAlpha(context, lowerOpacity); CGContextStrokeLineSegments(context, lowerPoints, 2); CGContextRestoreGState(context); }
static void _GraphicsScreen_cellArrayOrImage (GraphicsScreen me, double **z_float, double_rgbt **z_rgbt, unsigned char **z_byte, long ix1, long ix2, long x1DC, long x2DC, long iy1, long iy2, long y1DC, long y2DC, double minimum, double maximum, long clipx1, long clipx2, long clipy1, long clipy2, int interpolate) { /*long t=clock();*/ long nx = ix2 - ix1 + 1; /* The number of cells along the horizontal axis. */ long ny = iy2 - iy1 + 1; /* The number of cells along the vertical axis. */ double dx = (double) (x2DC - x1DC) / (double) nx; /* Horizontal pixels per cell. Positive. */ double dy = (double) (y2DC - y1DC) / (double) ny; /* Vertical pixels per cell. Negative. */ double scale = 255.0 / (maximum - minimum), offset = 255.0 + minimum * scale; if (x2DC <= x1DC || y1DC <= y2DC) return; trace ("scale %f", scale); /* Clip by the intersection of the world window and the outline of the cells. */ //Melder_casual ("clipy1 %ld clipy2 %ld", clipy1, clipy2); if (clipx1 < x1DC) clipx1 = x1DC; if (clipx2 > x2DC) clipx2 = x2DC; if (clipy1 > y1DC) clipy1 = y1DC; if (clipy2 < y2DC) clipy2 = y2DC; /* * The first decision is whether we are going to use the standard rectangle drawing * (cellArray only), or whether we are going to write into a bitmap. * The standard drawing is best for small numbers of cells, * provided that some cells are larger than a pixel. */ if (! interpolate && nx * ny < 3000 && (dx > 1.0 || dy < -1.0)) { try { /*unsigned int cellWidth = (unsigned int) dx + 1;*/ unsigned int cellHeight = (unsigned int) (- (int) dy) + 1; long ix, iy; #if cairo cairo_pattern_t *grey [256]; for (int igrey = 0; igrey < sizeof (grey) / sizeof (*grey); igrey ++) { double v = igrey / ((double) (sizeof (grey) / sizeof (*grey)) - 1.0); grey [igrey] = cairo_pattern_create_rgb (v, v, v); } #elif win static HBRUSH greyBrush [256]; RECT rect; if (! greyBrush [0]) for (int igrey = 0; igrey <= 255; igrey ++) greyBrush [igrey] = CreateSolidBrush (RGB (igrey, igrey, igrey)); // once #elif mac GraphicsQuartz_initDraw (me); CGContextSetAlpha (my d_macGraphicsContext, 1.0); CGContextSetBlendMode (my d_macGraphicsContext, kCGBlendModeNormal); #endif autoNUMvector <long> lefts (ix1, ix2 + 1); for (ix = ix1; ix <= ix2 + 1; ix ++) lefts [ix] = x1DC + (long) ((ix - ix1) * dx); for (iy = iy1; iy <= iy2; iy ++) { long bottom = y1DC + (long) ((iy - iy1) * dy), top = bottom - cellHeight; if (top > clipy1 || bottom < clipy2) continue; if (top < clipy2) top = clipy2; if (bottom > clipy1) bottom = clipy1; #if win rect. bottom = bottom; rect. top = top; #endif for (ix = ix1; ix <= ix2; ix ++) { long left = lefts [ix], right = lefts [ix + 1]; if (right < clipx1 || left > clipx2) continue; if (left < clipx1) left = clipx1; if (right > clipx2) right = clipx2; if (z_rgbt) { #if cairo // NYI #elif win // NYI #elif mac double red = z_rgbt [iy] [ix]. red; double green = z_rgbt [iy] [ix]. green; double blue = z_rgbt [iy] [ix]. blue; double transparency = z_rgbt [iy] [ix]. transparency; red = ( red <= 0.0 ? 0.0 : red >= 1.0 ? 1.0 : red ); green = ( green <= 0.0 ? 0.0 : green >= 1.0 ? 1.0 : green ); blue = ( blue <= 0.0 ? 0.0 : blue >= 1.0 ? 1.0 : blue ); CGContextSetRGBFillColor (my d_macGraphicsContext, red, green, blue, 1.0 - transparency); CGContextFillRect (my d_macGraphicsContext, CGRectMake (left, top, right - left, bottom - top)); #endif } else { #if cairo long value = offset - scale * ( z_float ? z_float [iy] [ix] : z_byte [iy] [ix] ); cairo_set_source (my d_cairoGraphicsContext, grey [value <= 0 ? 0 : value >= sizeof (grey) / sizeof (*grey) ? sizeof (grey) / sizeof (*grey) : value]); cairo_rectangle (my d_cairoGraphicsContext, left, top, right - left, bottom - top); cairo_fill (my d_cairoGraphicsContext); #elif win long value = offset - scale * ( z_float ? z_float [iy] [ix] : z_byte [iy] [ix] ); rect. left = left; rect. right = right; FillRect (my d_gdiGraphicsContext, & rect, greyBrush [value <= 0 ? 0 : value >= 255 ? 255 : value]); #elif mac double value = offset - scale * ( z_float ? z_float [iy] [ix] : z_byte [iy] [ix] ); double igrey = ( value <= 0 ? 0 : value >= 255 ? 255 : value ) / 255.0; CGContextSetRGBFillColor (my d_macGraphicsContext, igrey, igrey, igrey, 1.0); CGContextFillRect (my d_macGraphicsContext, CGRectMake (left, top, right - left, bottom - top)); #endif } } } #if cairo for (int igrey = 0; igrey < sizeof (grey) / sizeof (*grey); igrey ++) cairo_pattern_destroy (grey [igrey]); #elif mac CGContextSetRGBFillColor (my d_macGraphicsContext, 0.0, 0.0, 0.0, 1.0); GraphicsQuartz_exitDraw (me); #endif } catch (MelderError) { } } else { long xDC, yDC; long undersampling = 1; /* * Prepare for off-screen bitmap drawing. */ #if cairo long arrayWidth = clipx2 - clipx1; long arrayHeight = clipy1 - clipy2; trace ("arrayWidth %f, arrayHeight %f", (double) arrayWidth, (double) arrayHeight); cairo_surface_t *sfc = cairo_image_surface_create (CAIRO_FORMAT_RGB24, arrayWidth, arrayHeight); unsigned char *bits = cairo_image_surface_get_data (sfc); int scanLineLength = cairo_image_surface_get_stride (sfc); unsigned char grey [256]; trace ("image surface address %p, bits address %p, scanLineLength %d, numberOfGreys %d", sfc, bits, scanLineLength, sizeof(grey)/sizeof(*grey)); for (int igrey = 0; igrey < sizeof (grey) / sizeof (*grey); igrey++) grey [igrey] = 255 - (unsigned char) (igrey * 255.0 / (sizeof (grey) / sizeof (*grey) - 1)); #elif win long bitmapWidth = clipx2 - clipx1, bitmapHeight = clipy1 - clipy2; int igrey; /* * Create a device-independent bitmap, 32 bits deep. */ struct { BITMAPINFOHEADER header; } bitmapInfo; long scanLineLength = bitmapWidth * 4; // for 24 bits: (bitmapWidth * 3 + 3) & ~3L; HBITMAP bitmap; unsigned char *bits; // a pointer to memory allocated by VirtualAlloc or by CreateDIBSection () bitmapInfo. header.biSize = sizeof (BITMAPINFOHEADER); bitmapInfo. header.biWidth = bitmapWidth; // scanLineLength; bitmapInfo. header.biHeight = bitmapHeight; bitmapInfo. header.biPlanes = 1; bitmapInfo. header.biBitCount = 32; bitmapInfo. header.biCompression = 0; bitmapInfo. header.biSizeImage = 0; bitmapInfo. header.biXPelsPerMeter = 0; bitmapInfo. header.biYPelsPerMeter = 0; bitmapInfo. header.biClrUsed = 0; bitmapInfo. header.biClrImportant = 0; bitmap = CreateDIBSection (my d_gdiGraphicsContext /* ignored */, (CONST BITMAPINFO *) & bitmapInfo, DIB_RGB_COLORS, (VOID **) & bits, NULL, 0); #elif mac long bytesPerRow = (clipx2 - clipx1) * 4; Melder_assert (bytesPerRow > 0); long numberOfRows = clipy1 - clipy2; Melder_assert (numberOfRows > 0); unsigned char *imageData = Melder_malloc_f (unsigned char, bytesPerRow * numberOfRows); #endif /* * Draw into the bitmap. */ #if cairo #define ROW_START_ADDRESS (bits + (clipy1 - 1 - yDC) * scanLineLength) #define PUT_PIXEL \ if (1) { \ unsigned char kar = value <= 0 ? 0 : value >= 255 ? 255 : (int) value; \ *pixelAddress ++ = kar; \ *pixelAddress ++ = kar; \ *pixelAddress ++ = kar; \ *pixelAddress ++ = 0; \ } #elif win #define ROW_START_ADDRESS (bits + (clipy1 - 1 - yDC) * scanLineLength) #define PUT_PIXEL \ if (1) { \ unsigned char kar = value <= 0 ? 0 : value >= 255 ? 255 : (int) value; \ *pixelAddress ++ = kar; \ *pixelAddress ++ = kar; \ *pixelAddress ++ = kar; \ *pixelAddress ++ = 0; \ } #elif mac #define ROW_START_ADDRESS (imageData + (clipy1 - 1 - yDC) * bytesPerRow) #define PUT_PIXEL \ if (my colourScale == kGraphics_colourScale_GREY) { \ unsigned char kar = value <= 0 ? 0 : value >= 255 ? 255 : (int) value; \ *pixelAddress ++ = kar; \ *pixelAddress ++ = kar; \ *pixelAddress ++ = kar; \ *pixelAddress ++ = 0; \ } else if (my colourScale == kGraphics_colourScale_BLUE_TO_RED) { \ if (value < 0.0) { \ *pixelAddress ++ = 0; \ *pixelAddress ++ = 0; \ *pixelAddress ++ = 63; \ *pixelAddress ++ = 0; \ } else if (value < 64.0) { \ *pixelAddress ++ = 0; \ *pixelAddress ++ = 0; \ *pixelAddress ++ = (int) (value * 3 + 63.999); \ *pixelAddress ++ = 0; \ } else if (value < 128.0) { \ *pixelAddress ++ = (int) (value * 4 - 256.0); \ *pixelAddress ++ = (int) (value * 4 - 256.0); \ *pixelAddress ++ = 255; \ *pixelAddress ++ = 0; \ } else if (value < 192.0) { \ *pixelAddress ++ = 255; \ *pixelAddress ++ = (int) ((256.0 - value) * 4 - 256.0); \ *pixelAddress ++ = (int) ((256.0 - value) * 4 - 256.0); \ *pixelAddress ++ = 0; \ } else if (value < 256.0) { \ *pixelAddress ++ = (int) ((256.0 - value) * 3 + 63.999); \ *pixelAddress ++ = 0; \ *pixelAddress ++ = 0; \ *pixelAddress ++ = 0; \ } else { \ *pixelAddress ++ = 63; \ *pixelAddress ++ = 0; \ *pixelAddress ++ = 0; \ *pixelAddress ++ = 0; \ } \ } #else #define ROW_START_ADDRESS NULL #define PUT_PIXEL #endif if (interpolate) { try { autoNUMvector <long> ileft (clipx1, clipx2); autoNUMvector <long> iright (clipx1, clipx2); autoNUMvector <double> rightWeight (clipx1, clipx2); autoNUMvector <double> leftWeight (clipx1, clipx2); for (xDC = clipx1; xDC < clipx2; xDC += undersampling) { double ix_real = ix1 - 0.5 + ((double) nx * (xDC - x1DC)) / (x2DC - x1DC); ileft [xDC] = floor (ix_real), iright [xDC] = ileft [xDC] + 1; rightWeight [xDC] = ix_real - ileft [xDC], leftWeight [xDC] = 1.0 - rightWeight [xDC]; if (ileft [xDC] < ix1) ileft [xDC] = ix1; if (iright [xDC] > ix2) iright [xDC] = ix2; } for (yDC = clipy2; yDC < clipy1; yDC += undersampling) { double iy_real = iy2 + 0.5 - ((double) ny * (yDC - y2DC)) / (y1DC - y2DC); long itop = ceil (iy_real), ibottom = itop - 1; double bottomWeight = itop - iy_real, topWeight = 1.0 - bottomWeight; unsigned char *pixelAddress = ROW_START_ADDRESS; if (itop > iy2) itop = iy2; if (ibottom < iy1) ibottom = iy1; if (z_float) { double *ztop = z_float [itop], *zbottom = z_float [ibottom]; for (xDC = clipx1; xDC < clipx2; xDC += undersampling) { double interpol = rightWeight [xDC] * (topWeight * ztop [iright [xDC]] + bottomWeight * zbottom [iright [xDC]]) + leftWeight [xDC] * (topWeight * ztop [ileft [xDC]] + bottomWeight * zbottom [ileft [xDC]]); double value = offset - scale * interpol; PUT_PIXEL } } else if (z_rgbt) { double_rgbt *ztop = z_rgbt [itop], *zbottom = z_rgbt [ibottom]; for (xDC = clipx1; xDC < clipx2; xDC += undersampling) { double red = rightWeight [xDC] * (topWeight * ztop [iright [xDC]]. red + bottomWeight * zbottom [iright [xDC]]. red) + leftWeight [xDC] * (topWeight * ztop [ileft [xDC]]. red + bottomWeight * zbottom [ileft [xDC]]. red); double green = rightWeight [xDC] * (topWeight * ztop [iright [xDC]]. green + bottomWeight * zbottom [iright [xDC]]. green) + leftWeight [xDC] * (topWeight * ztop [ileft [xDC]]. green + bottomWeight * zbottom [ileft [xDC]]. green); double blue = rightWeight [xDC] * (topWeight * ztop [iright [xDC]]. blue + bottomWeight * zbottom [iright [xDC]]. blue) + leftWeight [xDC] * (topWeight * ztop [ileft [xDC]]. blue + bottomWeight * zbottom [ileft [xDC]]. blue); double transparency = rightWeight [xDC] * (topWeight * ztop [iright [xDC]]. transparency + bottomWeight * zbottom [iright [xDC]]. transparency) + leftWeight [xDC] * (topWeight * ztop [ileft [xDC]]. transparency + bottomWeight * zbottom [ileft [xDC]]. transparency); if (red < 0.0) red = 0.0; else if (red > 1.0) red = 1.0; if (green < 0.0) green = 0.0; else if (green > 1.0) green = 1.0; if (blue < 0.0) blue = 0.0; else if (blue > 1.0) blue = 1.0; if (transparency < 0.0) transparency = 0.0; else if (transparency > 1.0) transparency = 1.0; #if win *pixelAddress ++ = blue * 255.0; *pixelAddress ++ = green * 255.0; *pixelAddress ++ = red * 255.0; *pixelAddress ++ = 0; #elif mac *pixelAddress ++ = red * 255.0; *pixelAddress ++ = green * 255.0; *pixelAddress ++ = blue * 255.0; *pixelAddress ++ = transparency * 255.0; #elif cairo *pixelAddress ++ = blue * 255.0; *pixelAddress ++ = green * 255.0; *pixelAddress ++ = red * 255.0; *pixelAddress ++ = transparency * 255.0; #endif } } else { unsigned char *ztop = z_byte [itop], *zbottom = z_byte [ibottom]; for (xDC = clipx1; xDC < clipx2; xDC += undersampling) { double interpol = rightWeight [xDC] * (topWeight * ztop [iright [xDC]] + bottomWeight * zbottom [iright [xDC]]) + leftWeight [xDC] * (topWeight * ztop [ileft [xDC]] + bottomWeight * zbottom [ileft [xDC]]); double value = offset - scale * interpol; PUT_PIXEL } } } } catch (MelderError) { Melder_clearError (); } } else { try { autoNUMvector <long> ix (clipx1, clipx2); for (xDC = clipx1; xDC < clipx2; xDC += undersampling) ix [xDC] = floor (ix1 + (nx * (xDC - x1DC)) / (x2DC - x1DC)); for (yDC = clipy2; yDC < clipy1; yDC += undersampling) { long iy = ceil (iy2 - (ny * (yDC - y2DC)) / (y1DC - y2DC)); unsigned char *pixelAddress = ROW_START_ADDRESS; Melder_assert (iy >= iy1 && iy <= iy2); if (z_float) { double *ziy = z_float [iy]; for (xDC = clipx1; xDC < clipx2; xDC += undersampling) { double value = offset - scale * ziy [ix [xDC]]; PUT_PIXEL } } else { unsigned char *ziy = z_byte [iy]; for (xDC = clipx1; xDC < clipx2; xDC += undersampling) { double value = offset - scale * ziy [ix [xDC]]; PUT_PIXEL } } } } catch (MelderError) { Melder_clearError (); } } /* * Copy the bitmap to the screen. */ #if cairo cairo_matrix_t clip_trans; cairo_matrix_init_identity (& clip_trans); cairo_matrix_scale (& clip_trans, 1, -1); // we painted in the reverse y-direction cairo_matrix_translate (& clip_trans, - clipx1, - clipy1); cairo_pattern_t *bitmap_pattern = cairo_pattern_create_for_surface (sfc); trace ("bitmap pattern %p", bitmap_pattern); if (cairo_status_t status = cairo_pattern_status (bitmap_pattern)) { Melder_casual ("bitmap pattern status: %s", cairo_status_to_string (status)); } else { cairo_pattern_set_matrix (bitmap_pattern, & clip_trans); cairo_save (my d_cairoGraphicsContext); cairo_set_source (my d_cairoGraphicsContext, bitmap_pattern); cairo_paint (my d_cairoGraphicsContext); cairo_restore (my d_cairoGraphicsContext); } cairo_pattern_destroy (bitmap_pattern); #elif win SetDIBitsToDevice (my d_gdiGraphicsContext, clipx1, clipy2, bitmapWidth, bitmapHeight, 0, 0, 0, bitmapHeight, bits, (CONST BITMAPINFO *) & bitmapInfo, DIB_RGB_COLORS); //StretchDIBits (my d_gdiGraphicsContext, clipx1, clipy2, bitmapWidth, bitmapHeight, 0, 0, 0, bitmapHeight, // bits, (CONST BITMAPINFO *) & bitmapInfo, DIB_RGB_COLORS, SRCCOPY); #elif mac CGImageRef image; static CGColorSpaceRef colourSpace = NULL; if (colourSpace == NULL) { colourSpace = CGColorSpaceCreateWithName (kCGColorSpaceGenericRGB); // used to be kCGColorSpaceUserRGB Melder_assert (colourSpace != NULL); } if (1) { CGDataProviderRef dataProvider = CGDataProviderCreateWithData (NULL, imageData, bytesPerRow * numberOfRows, _mac_releaseDataCallback // we need this because we cannot release the image data immediately after drawing, // because in PDF files the imageData has to stay available through EndPage ); Melder_assert (dataProvider != NULL); image = CGImageCreate (clipx2 - clipx1, numberOfRows, 8, 32, bytesPerRow, colourSpace, kCGImageAlphaNone, dataProvider, NULL, false, kCGRenderingIntentDefault); CGDataProviderRelease (dataProvider); } else if (0) { Melder_assert (CGBitmapContextCreate != NULL); CGContextRef bitmaptest = CGBitmapContextCreate (imageData, 100, 100, 8, 800, colourSpace, 0); Melder_assert (bitmaptest != NULL); CGContextRef bitmap = CGBitmapContextCreate (NULL/*imageData*/, clipx2 - clipx1, numberOfRows, 8, bytesPerRow, colourSpace, kCGImageAlphaLast); Melder_assert (bitmap != NULL); image = CGBitmapContextCreateImage (bitmap); // release bitmap? } Melder_assert (image != NULL); GraphicsQuartz_initDraw (me); CGContextDrawImage (my d_macGraphicsContext, CGRectMake (clipx1, clipy2, clipx2 - clipx1, clipy1 - clipy2), image); GraphicsQuartz_exitDraw (me); //CGColorSpaceRelease (colourSpace); CGImageRelease (image); #endif /* * Clean up. */ #if cairo cairo_surface_destroy (sfc); #elif win DeleteBitmap (bitmap); #endif }
static void quartzPrepareFill (GraphicsScreen me) { CGContextSetAlpha (my d_macGraphicsContext, 1.0); CGContextSetBlendMode (my d_macGraphicsContext, kCGBlendModeNormal); CGContextSetRGBFillColor (my d_macGraphicsContext, my d_macColour.red / 65536.0, my d_macColour.green / 65536.0, my d_macColour.blue / 65536.0, 1.0); }
static cairo_int_status_t _cairo_quartz_init_glyph_surface (cairo_quartz_scaled_font_t *font, cairo_scaled_glyph_t *scaled_glyph) { cairo_int_status_t status = CAIRO_STATUS_SUCCESS; cairo_quartz_font_face_t *font_face = _cairo_quartz_scaled_to_face(font); cairo_image_surface_t *surface = NULL; CGGlyph glyph = _cairo_quartz_scaled_glyph_index (scaled_glyph); int advance; CGRect bbox; double width, height; double emscale = CGFontGetUnitsPerEmPtr (font_face->cgFont); CGContextRef cgContext = NULL; CGAffineTransform textMatrix; CGRect glyphRect, glyphRectInt; CGPoint glyphOrigin; //fprintf (stderr, "scaled_glyph: %p surface: %p\n", scaled_glyph, scaled_glyph->surface); /* Create blank 2x2 image if we don't have this character. * Maybe we should draw a better missing-glyph slug or something, * but this is ok for now. */ if (glyph == INVALID_GLYPH) { surface = (cairo_image_surface_t*) cairo_image_surface_create (CAIRO_FORMAT_A8, 2, 2); status = cairo_surface_status ((cairo_surface_t *) surface); if (status) return status; _cairo_scaled_glyph_set_surface (scaled_glyph, &font->base, surface); return CAIRO_STATUS_SUCCESS; } if (!CGFontGetGlyphAdvancesPtr (font_face->cgFont, &glyph, 1, &advance) || !CGFontGetGlyphBBoxesPtr (font_face->cgFont, &glyph, 1, &bbox)) { return CAIRO_INT_STATUS_UNSUPPORTED; } /* scale(1,-1) * font->base.scale * scale(1,-1) */ textMatrix = CGAffineTransformMake (font->base.scale.xx, -font->base.scale.yx, -font->base.scale.xy, font->base.scale.yy, 0, -0); glyphRect = CGRectMake (bbox.origin.x / emscale, bbox.origin.y / emscale, bbox.size.width / emscale, bbox.size.height / emscale); glyphRect = CGRectApplyAffineTransform (glyphRect, textMatrix); /* Round the rectangle outwards, so that we don't have to deal * with non-integer-pixel origins or dimensions. */ glyphRectInt = CGRectIntegral (glyphRect); #if 0 fprintf (stderr, "glyphRect[o]: %f %f %f %f\n", glyphRect.origin.x, glyphRect.origin.y, glyphRect.size.width, glyphRect.size.height); fprintf (stderr, "glyphRectInt: %f %f %f %f\n", glyphRectInt.origin.x, glyphRectInt.origin.y, glyphRectInt.size.width, glyphRectInt.size.height); #endif glyphOrigin = glyphRectInt.origin; //textMatrix = CGAffineTransformConcat (textMatrix, CGAffineTransformInvert (ctm)); width = glyphRectInt.size.width; height = glyphRectInt.size.height; //fprintf (stderr, "glyphRect[n]: %f %f %f %f\n", glyphRect.origin.x, glyphRect.origin.y, glyphRect.size.width, glyphRect.size.height); surface = (cairo_image_surface_t*) cairo_image_surface_create (CAIRO_FORMAT_A8, width, height); if (surface->base.status) return surface->base.status; if (surface->width != 0 && surface->height != 0) { cgContext = CGBitmapContextCreate (surface->data, surface->width, surface->height, 8, surface->stride, NULL, kCGImageAlphaOnly); if (cgContext == NULL) { cairo_surface_destroy (&surface->base); return _cairo_error (CAIRO_STATUS_NO_MEMORY); } CGContextSetFont (cgContext, font_face->cgFont); CGContextSetFontSize (cgContext, 1.0); CGContextSetTextMatrix (cgContext, textMatrix); switch (font->base.options.antialias) { case CAIRO_ANTIALIAS_SUBPIXEL: case CAIRO_ANTIALIAS_BEST: CGContextSetShouldAntialias (cgContext, TRUE); CGContextSetShouldSmoothFonts (cgContext, TRUE); if (CGContextSetAllowsFontSmoothingPtr && !CGContextGetAllowsFontSmoothingPtr (cgContext)) CGContextSetAllowsFontSmoothingPtr (cgContext, TRUE); break; case CAIRO_ANTIALIAS_NONE: CGContextSetShouldAntialias (cgContext, FALSE); break; case CAIRO_ANTIALIAS_GRAY: case CAIRO_ANTIALIAS_GOOD: case CAIRO_ANTIALIAS_FAST: CGContextSetShouldAntialias (cgContext, TRUE); CGContextSetShouldSmoothFonts (cgContext, FALSE); break; case CAIRO_ANTIALIAS_DEFAULT: default: /* Don't do anything */ break; } CGContextSetAlpha (cgContext, 1.0); CGContextShowGlyphsAtPoint (cgContext, - glyphOrigin.x, - glyphOrigin.y, &glyph, 1); CGContextRelease (cgContext); } cairo_surface_set_device_offset (&surface->base, - glyphOrigin.x, height + glyphOrigin.y); _cairo_scaled_glyph_set_surface (scaled_glyph, &font->base, surface); return status; }
DISABLED_DRAW_TEST_F(CGImageDrawing, TiledImageCustomScaledAlpha, UIKitMimicTest<>) { CGRect rect = { { 0, 0 }, { 128, 128 } }; CGContextSetAlpha(GetDrawingContext(), 0.88); _drawTiledImage(GetDrawingContext(), rect, "tiledImageCircleMe.png"); }
void GraphicsContext::setAlpha(float alpha) { if (paintingDisabled()) return; CGContextSetAlpha(platformContext(), alpha); }
bool SVGPaintServerPattern::setup(GraphicsContext*& context, const RenderObject* object, SVGPaintTargetType type, bool isPaintingText) const { CGContextRef contextRef = context->platformContext(); // Build pattern tile, passing destination object bounding box FloatRect targetRect; if (isPaintingText) { IntRect textBoundary = const_cast<RenderObject*>(object)->absoluteBoundingBoxRect(); targetRect = object->absoluteTransform().inverse().mapRect(textBoundary); } else targetRect = CGContextGetPathBoundingBox(contextRef); m_ownerElement->buildPattern(targetRect); if (!tile()) return false; CGSize cellSize = CGSize(tile()->size()); CGFloat alpha = 1; // canvasStyle->opacity(); //which? context->save(); // Repesct local pattern transformations CGContextConcatCTM(contextRef, patternTransform()); // Pattern space seems to start in the lower-left, so we flip the Y here. CGSize phase = CGSizeMake(patternBoundaries().x(), -patternBoundaries().y()); CGContextSetPatternPhase(contextRef, phase); RenderStyle* style = object->style(); CGContextSetAlpha(contextRef, style->opacity()); // or do I set the alpha above? ASSERT(!m_pattern); CGPatternCallbacks callbacks = {0, patternCallback, NULL}; m_pattern = CGPatternCreate(tile(), CGRectMake(0, 0, cellSize.width, cellSize.height), CGContextGetCTM(contextRef), patternBoundaries().width(), patternBoundaries().height(), kCGPatternTilingConstantSpacing, // FIXME: should ask CG guys. true, // has color &callbacks); if (!m_patternSpace) m_patternSpace = CGColorSpaceCreatePattern(0); if ((type & ApplyToFillTargetType) && style->svgStyle()->hasFill()) { CGContextSetFillColorSpace(contextRef, m_patternSpace); CGContextSetFillPattern(contextRef, m_pattern, &alpha); if (isPaintingText) context->setTextDrawingMode(cTextFill); } if ((type & ApplyToStrokeTargetType) && style->svgStyle()->hasStroke()) { CGContextSetStrokeColorSpace(contextRef, m_patternSpace); CGContextSetStrokePattern(contextRef, m_pattern, &alpha); applyStrokeStyleToContext(contextRef, style, object); if (isPaintingText) context->setTextDrawingMode(cTextStroke); } return true; }
DISABLED_DRAW_TEST_F(CGImageDrawing, TiledImageFlowerScaledAlpha3, UIKitMimicTest<>) { CGRect rect = { { 0, 0 }, { 300, 513 } }; CGContextSetAlpha(GetDrawingContext(), 0.66); _drawTiledImage(GetDrawingContext(), rect, "tiledImageFlower.png"); }