Shadows have three characteristics:
-
An x-offset, which specifies how far in the horizontal direction the shadow is offset from the image.
-
A y-offset, which specifies how far in the vertical direction the shadow is offset from the image.
-
A blur value, which specifies whether the image has a hard edge, as seen in the left side of Figure 7-2, or a diffuse edge, as seen in the right side of the figure.
This chapter describes how shadows work and shows how to use the Quartz 2D API to create them.
A shadow with no blur and another with a soft edgeHow Shadows Work
Shadows in Quartz are part of the graphics state. You call the functionCGContextSetShadow。The shadow is drawn using RGBA values set to {0, 0, 0, 1.0/3.0}
.You can draw colored shadows by calling the function CGContextSetShadowWithColor.
If you save the graphics state before you call CGContextSetShadow
or CGContextSetShadowWithColor
, you can turn off shadowing by restoring the graphics state. You also disable shadows by setting the shadow color to NULL
.
Shadow Drawing Conventions Vary Based on the Context
The offsets described earlier specify where the shadow is located related to the image that cast the shadow. Those offsets are interpreted by the context and used to calculate the shadow’s location:
-
A positive x offset indicates the shadows is to the right of the graphics object.
-
In Mac OS X, a positive y offset indicates upward displacement. This matches the default coordinate system for Quartz 2D.
-
In iOS, if your application uses Quartz 2D APIs to create a PDF or bitmap context, a positive y offset indicates upwards displacement.
-
In iOS, if the graphics context was created by UIKit, such as a graphics context created by a UIView
object or a context created by calling the UIGraphicsBeginImageContextWithOptions
function, then a positive y offset indicates a downward displacement. This matches the drawing conventions of the UIKit coordinate system.
-
The shadow-drawing convention is not affected by the current transformation matrix.
Painting with Shadows
Follow these steps to paint with shadows:
-
Save the graphics state.
-
Call the function
CGContextSetShadow
, passing the appropriate values. -
Perform all the drawing to which you want to apply shadows.
-
Restore the graphics state.
Follow these steps to paint with colored shadows:
-
Save the graphics state.
-
Create a CGColorSpace object to ensure that Quartz interprets the shadow color values correctly.
-
Create a CGColor object that specifies the shadow color you want to use.
-
Call the function
CGContextSetShadowWithColor
, passing the appropriate values. -
Perform all the drawing to which you want to apply shadows.
-
Restore the graphics state.
A function that sets up shadows
void MyDrawWithShadows (CGContextRef myContext, // 1 |
CGFloat wd, CGFloat ht); |
{ |
CGSize myShadowOffset = CGSizeMake (-15, 20);// 2 |
CGFloat myColorValues[] = {1, 0, 0, .6};// 3 |
CGColorRef myColor;// 4 |
CGColorSpaceRef myColorSpace;// 5 |
|
CGContextSaveGState(myContext);// 6 |
|
CGContextSetShadow (myContext, myShadowOffset, 5); // 7 |
// Your drawing code here// 8 |
CGContextSetRGBFillColor (myContext, 0, 1, 0, 1); |
CGContextFillRect (myContext, CGRectMake (wd/3 + 75, ht/2 , wd/4, ht/4)); |
|
myColorSpace = CGColorSpaceCreateDeviceRGB ();// 9 |
myColor = CGColorCreate (myColorSpace, myColorValues);// 10 |
CGContextSetShadowWithColor (myContext, myShadowOffset, 5, myColor);// 11 |
// Your drawing code here// 12 |
CGContextSetRGBFillColor (myContext, 0, 0, 1, 1); |
CGContextFillRect (myContext, CGRectMake (wd/3-75,ht/2-100,wd/4,ht/4)); |
|
CGColorRelease (myColor);// 13 |
CGColorSpaceRelease (myColorSpace); // 14 |
|
CGContextRestoreGState(myContext);// 15 |
} |