Paths

ps:缓慢翻译中...bezier曲线部分给我翻译吐了...

路径(path)定义了一个或多个形状, 或者子路径(subpath). 一个子路径可以由直线, 曲线, 或者由两者同时构成. 它可以是开放的或闭合的. 一个子路径可以是简单的形状, 如 线, 圆, 矩形, 星星, 或者复杂的形状, 如 山脉轮廓或者抽象涂鸦. **图 3-1 **展示了一些你可以创建的路径. 直虚线 (在图的左上边) ; 线也可以是实线. 由多条曲线组成的开放路径 (在图的中上方) . 旁边的同心圆填充(fill)了颜色, 但是没有描边(stroke). 左下的加利福尼亚洲是闭合路径, 由许多曲线和直线构成, 并且路径有填充也有描边. 星星说明了填充路径的两种方式, 你会在本章的后面了解到详细描述.
图 3-1 Quartz supports path-based drawing

path_vector_examples.gif

在本章中, 你将了解组成路径的构建块(building block), 如何对路径进行填充和描边, 以及影响路径表现形式的参数.

Path Creation and Path Painting


路径的创建和路径的绘制是两个独立的工作. 首先你要创建一个路径. 当你想渲染一条路径的时候, 你就需要使用 Quartz 来绘制它. 正如你在** 图 3-1 **中看到的, 你可以选择去描边路径, 填充路径, 或者同时进行这两种操作. 你也可以将其他对象会知道路径所表示的范围内, 即, 一个裁剪区域.
图 3-2 绘制了一条路径并且它包含了2个子路径. 左边的路径是一个矩形, 右边的路径是由直线和曲线构成的抽象图形, 每个子路径都进行了填充和轮廓描边.
图 3-2 A path that contains two shapes, or subpaths

subpaths.gif

图 3-3 展示了多条独立绘制的路径. 每条路径包含一个随机生成的曲线, 一些进行了描边, 另一些进行了填充. 这些路径都包含在了一个圆形的裁剪区域内.
图 3-3 A clipping area constrains drawing

circle_clipping.gif

The Building Blocks


子路径是由直线, 圆弧和曲线构成的. Quartz 同样也提供了简便的函数用于添加矩形或椭圆等形状. 点也是路径的最基本构建块, 因为点定义了图形的起始点和终止点.

Points


点用X和Y坐标在用户空间内指定一个位置, 你可以调用 CGContextMoveToPoint 方法为新的子路径指定一个起始点. Quartz 跟踪当前点, 用于记录路径构建过程中最新的位置. 例如, 如果你调用 CGContextMoveToPoint 方法将点移动到 (10,10) 位置, 即将当前点移动到(10,10) 位置. 如果你在水平位置画一条50个单位长的直线, 则直线的终点是 (60,10), 这个点变成当前点. 直线, 圆弧和曲线总是从当前点开始绘制的.
通常我们通过传递 (X, Y) 坐标值给Quartz的函数来指定一个点 . 一些函数需要我们传递一个CGPoint的数据结构, 这个结构包含2个浮点数值.

Lines


一条直线由它的端点定义. 起始点一般被设定为当前点, 所以当你创建一条直线时, 你只需要指定终止点. 你可以使用 CGContextAddLineToPoint 方法添加一条直线到子路径中.
你可以通过调用 CGContextAddLines 方法来给子路径添加一系列的连接线. 你传递一个点的数组给这个函数. 第一个点必须是第一条直线的起始点; 剩下的点都是终止点. Quartz 从第一个点开始绘制一条子路径用直线连接下一个点, 直到所有点都连接.

Arcs


弧是圆的一段. Quartz 提供了2中方法来创建圆弧. CGContextAddArc 方法通过圆来创建一个曲线段. 你需要指定一个圆心, 半径和放射角 (弧度). 你可通过指定放射角为2π来创建一个完整的圆.** 图 3-4 **展示了多条独立绘制的路径. 每个路径包含了一个自动生成的圆; 一些是填充的, 另一些是描边的.
图 3-4 Multiple paths; each path contains a randomly generated circle

circles.gif

CGContextAddArcToPoint 函数用于当你想在一个矩形角内切一个弧形的时候. Quartz 使用你提供的端点创建2条正切线. 你同样需要提供圆的半径. 圆弧的中心点是两个半径的交点, 每条半径都与相应的正切线垂直。弧的两个端点是正切线的正切点,如 图3-5 所示。红色的部分是实际绘制的部分。.
图 3-5 Defining an arc with two tangent lines and a radius

rounded_corner.gif

如果当前路径已经包含了一个子路径, Quartz 将会在当前点和圆弧的起始点之间追加一条直线. 如果当前路径为空, Quartz 将创建一个新的子路径,该子路径从弧的起始点开始,而不添加初始的直线段.

Curves


二次和三次 Bézier 曲线是可以指定任意曲线形状的代数曲线. 曲线上的点由起始点, 终止点及一个或多个控制点通过一个多项式计算得出. 这种方式定义的形状是矢量图的基础. 这个公式比将位(bit)数组更容易使用, 并且曲线可以在任何分辨下重新创建.
**图 3-6 **显示了一些独立路径的曲线. 每条路径包含一条随机生成的曲线; 一些是填充的, 另一些是描边的.
图 3-6 Multiple paths; each path contains a randomly generated curve

bezier_paths.gif

The polynomial formulas that give to rise to quadratic and cubic Bézier curves(不懂), 如何从公式中生成曲线的详情, 在许多数学文本和描述计算机图形学的网络资源里面讨论了. 详情不在这里讨论.
你可以指定控制点和终止点来使用 CGContextAddCurveToPoint 函数来通过当前点来连接一个Bezier曲线. 图 3-7 shows the cubic Bézier curve that results from the current point, control points, and endpoint shown in the figure. The placement of the two control points determines the geometry of the curve. If the control points are both above the starting and ending points, the curve arches upward. If the control points are both below the starting and ending points, the curve arches downward.
Figure 3-7 A cubic Bézier curve uses two control points

You can append a quadratic Bézier curve from the current point by calling the function CGContextAddQuadCurveToPoint, and specifying a control point and an endpoint. Figure 3-8 shows two curves that result from using the same endpoints but different control points. The control point determines the direction that the curve arches. It’s not possible to create as many interesting shapes with a quadratic Bézier curve as you can with a cubic one because quadratic curves use only one control point. For example, it’s not possible to create a crossover using a single control point.
Figure 3-8 A quadratic Bézier curve uses one control point

Closing a Subpath

To close the current subpath, your application should call CGContextClosePath. This function adds a line segment from the current point to the starting point of the subpath and closes the subpath. Lines, arcs, and curves that end at the starting point of a subpath do not actually close the subpath. You must explicitly call CGContextClosePath to close a subpath.
Some Quartz functions treat a path’s subpaths as if they were closed by your application. Those commands treat each subpath as if your application had called CGContextClosePath to close it, implicitly adding a line segment to the starting point of the subpath.
After closing a subpath, if your application makes additional calls to add lines, arcs, or curves to the path, Quartz begins a new subpath starting at the starting point of the subpath you just closed.
Ellipses

An ellipse is essentially a squashed circle. You create one by defining two focus points and then plotting all the points that lie at a distance such that adding the distance from any point on the ellipse to one focus to the distance from that same point to the other focus point is always the same value. Figure 3-9 shows multiple paths drawn independently. Each path contains a randomly generated ellipse; some are filled and others are stroked.
Figure 3-9 Multiple paths; each path contains a randomly generated ellipse

You can add an ellipse to the current path by calling the function CGContextAddEllipseInRect. You supply a rectangle that defines the bounds of the ellipse. Quartz approximates the ellipse using a sequence of Bézier curves. The center of the ellipse is the center of the rectangle. If the width and height of the rectangle are equal (that is, a square), the ellipse is circular, with a radius equal to one-half the width (or height) of the rectangle. If the width and height of the rectangle are unequal, they define the major and minor axes of the ellipse.
The ellipse that is added to the path starts with a move-to operation and ends with a close-subpath operation, with all moves oriented in the clockwise direction.
Rectangles

You can add a rectangle to the current path by calling the function CGContextAddRect. You supply a CGRect structure that contains the origin of the rectangle and its width and height.
The rectangle that is added to the path starts with a move-to operation and ends with a close-subpath operation, with all moves oriented in the counter-clockwise direction.
You can add many rectangles to the current path by calling the function CGContextAddRects and supplying an array of CGRect structures. Figure 3-10 shows multiple paths drawn independently. Each path contains a randomly generated rectangle; some are filled and others are stroked.
Figure 3-10 Multiple paths; each path contains a randomly generated rectangle

Creating a Path

When you want to construct a path in a graphics context, you signal Quartz by calling the function CGContextBeginPath . Next, you set the starting point for the first shape, or subpath, in the path by calling the function CGContextMoveToPoint. After you establish the first point, you can add lines, arcs, and curves to the path, keeping in mind the following:
Before you begin a new path, call the function CGContextBeginPath.
Lines, arcs, and curves are drawn starting at the current point. An empty path has no current point; you must call CGContextMoveToPoint to set the starting point for the first subpath or call a convenience function that implicitly does this for you.
When you want to close the current subpath within a path, call the function CGContextClosePath to connect a segment to the starting point of the subpath. Subsequent path calls begin a new subpath, even if you do not explicitly set a new starting point.
When you draw arcs, Quartz draws a line between the current point and the starting point of the arc.
Quartz routines that add ellipses and rectangles add a new closed subpath to the path.
You must call a painting function to fill or stroke the path because creating a path does not draw the path. See Painting a Path for detailed information.

After you paint a path, it is flushed from the graphics context. You might not want to lose your path so easily, especially if it depicts a complex scene you want to use over and over again. For that reason, Quartz provides two data types for creating reusable paths—CGPathRef and CGMutablePathRef. You can call the function CGPathCreateMutable to create a mutable CGPath object to which you can add lines, arcs, curves, and rectangles. Quartz provides a set of CGPath functions that parallel the functions discussed in The Building Blocks. The path functions operate on a CGPath object instead of a graphics context. These functions are:
CGPathCreateMutable, which replacesCGContextBeginPath
CGPathMoveToPoint, which replaces CGContextMoveToPoint
CGPathAddLineToPoint, which replaces CGContextAddLineToPoint
CGPathAddCurveToPoint, which replaces CGContextAddCurveToPoint
CGPathAddEllipseInRect, which replaces CGContextAddEllipseInRect
CGPathAddArc, which replaces CGContextAddArc
CGPathAddRect, which replaces CGContextAddRect
CGPathCloseSubpath, which replaces CGContextClosePath

See a target="_self" Quartz 2D Reference Collection/a for a complete list of the path functions.
When you want to append the path to a graphics context, you call the function CGContextAddPath. The path stays in the graphics context until Quartz paints it. You can add the path again by calling CGContextAddPath.
Note: You can replace the path in a graphics context with the stroked version of the path by calling the function CGContextReplacePathWithStrokedPath.

Painting a Path

You can paint the current path by stroking or filling or both. Stroking paints a line that straddles the path. Filling paints the area contained within the path. Quartz has functions that let you stroke a path, fill a path, or both stroke and fill a path. The characteristics of the stroked line (width, color, and so forth), the fill color, and the method Quartz uses to calculate the fill area are all part of the graphics state (see Graphics States).
Parameters That Affect Stroking

You can affect how a path is stroked by modifying the parameters listed in Table 3-1. These parameters are part of the graphics state, which means that the value you set for a parameter affects all subsequent stroking until you set the parameter to another value.
Table 3-1 Parameters that affect how Quartz strokes the current path
Parameter

Function to set parameter value

Line width

CGContextSetLineWidth

Line join

CGContextSetLineJoin

Line cap

CGContextSetLineCap

Miter limit

CGContextSetMiterLimit

Line dash pattern

CGContextSetLineDash

Stroke color space

CGContextSetStrokeColorSpace

Stroke color

CGContextSetStrokeColorCGContextSetStrokeColorWithColor

Stroke pattern

CGContextSetStrokePattern

The line width is the total width of the line, expressed in units of the user space. The line straddles the path, with half of the total width on either side.
The line join specifies how Quartz draws the junction between connected line segments. Quartz supports the line join styles described in Table 3-2. The default style is miter join.
Table 3-2 Line join styles
Style

Appearance

Description

Miter join

Quartz extends the outer edges of the strokes for the two segments until they meet at an angle, as in a picture frame. If the segments meet at too sharp an angle, a bevel join is used instead. A segment is too sharp if the length of the miter divided by the line width is greater than the miter limit.

Round join

Quartz draws a semicircular arc with a diameter equal to the line width around the endpoint. The enclosed area is filled in.

Bevel join

Quartz finishes the two segments with butt caps. The resulting notch beyond the ends of the segments is filled with a triangle.

The line cap specifies the method used by CGContextStrokePath to draw the endpoint of the line. Quartz supports the line cap styles described in Table 3-3. The default style is butt cap.
Table 3-3 Line cap styles
Style

Appearance

Description

Butt cap

Quartz squares off the stroke at the endpoint of the path. There is no projection beyond the end of the path.

Round cap

Quartz draws a circle with a diameter equal to the line width around the point where the two segments meet, producing a rounded corner. The enclosed area is filled in.

Projecting square cap

Quartz extends the stroke beyond the endpoint of the path for a distance equal to half the line width. The extension is squared off.

A closed subpath treats the starting point as a junction between connected line segments; the starting point is rendered using the selected line-join method. In contrast, if you close the path by adding a line segment that connects to the starting point, both ends of the path are drawn using the selected line-cap method.
A line dash pattern allows you to draw a segmented line along the stroked path. You control the size and placement of dash segments along the line by specifying the dash array and the dash phase as parameters to CGContextSetLineDash:
void CGContextSetLineDash (

CGContextRef ctx,

CGFloat phase,

const CGFloat lengths[],

size_t count

);

The elements of the lengths parameter specify the widths of the dashes, alternating between the painted and unpainted segments of the line. The phase parameter specifies the starting point of the dash pattern. Figure 3-11 shows some line dash patterns.
Figure 3-11 Examples of line dash patterns

The stroke color space determines how the stroke color values are interpreted by Quartz. You can also specify a Quartz color (CGColorRef data type) that encapsulates both color and color space. For more information on setting color space and color, see Color and Color Spaces.
Functions for Stroking a Path

Quartz provides the functions shown in Table 3-4 for stroking the current path. Some are convenience functions for stroking rectangles or ellipses.
Table 3-4 Functions that stroke paths
Function

Description

CGContextStrokePath

Strokes the current path.

CGContextStrokeRect

Strokes the specified rectangle.

CGContextStrokeRectWithWidth

Strokes the specified rectangle, using the specified line width.

CGContextStrokeEllipseInRect

Strokes an ellipse that fits inside the specified rectangle.

CGContextStrokeLineSegments

Strokes a sequence of lines.

CGContextDrawPath

If you pass the constant kCGPathStroke, strokes the current path. See Filling a Path if you want to both fill and stroke a path.

The function CGContextStrokeLineSegments is equivalent to the following code:
CGContextBeginPath (context);

for (k = 0; k < count; k += 2) {

CGContextMoveToPoint(context, s[k].x, s[k].y);

CGContextAddLineToPoint(context, s[k+1].x, s[k+1].y);

}

CGContextStrokePath(context);

When you call CGContextStrokeLineSegments, you specify the line segments as an array of points, organized as pairs. Each pair consists of the starting point of a line segment followed by the ending point of a line segment. For example, the first point in the array specifies the starting position of the first line, the second point specifies the ending position of the first line, the third point specifies the starting position of the second line, and so forth.
Filling a Path

When you fill the current path, Quartz acts as if each subpath contained in the path were closed. It then uses these closed subpaths and calculates the pixels to fill. There are two ways Quartz can calculate the fill area. Simple paths such as ovals and rectangles have a well-defined area. But if your path is composed of overlapping segments or if the path includes multiple subpaths, such as the concentric circles shown in Figure 3-12, there are two rules you can use to determine the fill area.
The default fill rule is called the nonzero winding number rule. To determine whether a specific point should be painted, start at the point and draw a line beyond the bounds of the drawing. Starting with a count of 0, add 1 to the count every time a path segment crosses the line from left to right, and subtract 1 every time a path segment crosses the line from right to left. If the result is 0, the point is not painted. Otherwise, the point is painted. The direction that the path segments are drawn affects the outcome. Figure 3-12 shows two sets of inner and outer circles that are filled using the nonzero winding number rule. When each circle is drawn in the same direction, both circles are filled. When the circles are drawn in opposite directions, the inner circle is not filled.
You can opt to use the even-odd rule. To determine whether a specific point should be painted, start at the point and draw a line beyond the bounds of the drawing. Count the number of path segments that the line crosses. If the result is odd, the point is painted. If the result is even, the point is not painted. The direction that the path segments are drawn doesn’t affect the outcome. As you can see in Figure 3-12, it doesn’t matter which direction each circle is drawn, the fill will always be as shown.
Figure 3-12 Concentric circles filled using different fill rules

Quartz provides the functions shown in Table 3-5 for filling the current path. Some are convenience functions for stroking rectangles or ellipses.
Table 3-5 Functions that fill paths
Function

Description

CGContextEOFillPath

Fills the current path using the even-odd rule.

CGContextFillPath

Fills the current path using the nonzero winding number rule.

CGContextFillRect

Fills the area that fits inside the specified rectangle.

CGContextFillRects

Fills the areas that fits inside the specified rectangles.

CGContextFillEllipseInRect

Fills an ellipse that fits inside the specified rectangle.

CGContextDrawPath

Fills the current path if you pass kCGPathFill (nonzero winding number rule) or kCGPathEOFill (even-odd rule). Fills and strokes the current path if you pass kCGPathFillStroke or kCGPathEOFillStroke.

Setting Blend Modes

Blend modes specify how Quartz applies paint over a background. Quartz uses normal blend mode by default, which combines the foreground painting with the background painting using the following formula:
result = (alpha * foreground) + (1 - alpha) * background
Color and Color Spaces provides a detailed discussion of the alpha component of a color, which specifies the opacity of a color. For the examples in this section, you can assume a color is completely opaque (alpha value = 1.0). For opaque colors, when you paint using normal blend mode, anything you paint over the background completely obscures the background.
You can set the blend mode to achieve a variety of effects by calling the function CGContextSetBlendMode, passing the appropriate blend mode constant. Keep in mind that the blend mode is part of the graphics state. If you use the function CGContextSaveGState prior to changing the blend mode, then calling the function CGContextRestoreGState resets the blend mode to normal.
The rest of this section show the results of painting the rectangles shown in Figure 3-13 over the rectangles shown in Figure 3-14. In each case (Figure 3-15 through Figure 3-30), the background rectangles are painted using normal blend mode. Then the blend mode is changed by calling the function CGContextSetBlendMode with the appropriate constant. Finally, the foreground rectangles are painted.
Figure 3-13 The rectangles painted in the foreground

Figure 3-14 The rectangles painted in the background

Note: You can also use blend modes to composite two images or to composite an image over any content that’s already drawn to the graphics context. Using Blend Modes with Images provides information on how to use blend modes to composite images and shows the results of applying blend modes to two images.

Normal Blend Mode
Because normal blend mode is the default blend mode, you call the function CGContextSetBlendMode with the constant kCGBlendModeNormal only to reset the blend mode back to the default after you’ve used one of the other blend mode constants. Figure 3-15 shows the result of painting Figure 3-13 over Figure 3-14 using normal blend mode.
Figure 3-15 Rectangles painted using normal blend mode

Multiply Blend Mode
Multiply blend mode specifies to multiply the foreground image samples with the background image samples. The resulting colors are at least as dark as either of the two contributing sample colors. Figure 3-16 shows the result of painting Figure 3-13 over Figure 3-14 using multiply blend mode. To use this blend mode, call the function CGContextSetBlendMode with the constant kCGBlendModeMultiply.
Figure 3-16 Rectangles painted using multiply blend mode

Screen Blend Mode
Screen blend mode specifies to multiply the inverse of the foreground image samples with the inverse of the background image samples. The resulting colors are at least as light as either of the two contributing sample colors. Figure 3-17 shows the result of painting Figure 3-13 over Figure 3-14 using screen blend mode. To use this blend mode, call the function CGContextSetBlendMode with the constant kCGBlendModeScreen.
Figure 3-17 Rectangles painted using screen blend mode

Overlay Blend Mode
Overlay blend mode specifies to either multiply or screen the foreground image samples with the background image samples, depending on the background color. The background color mixes with the foreground color to reflect the lightness or darkness of the background. Figure 3-18 shows the result of painting Figure 3-13 over Figure 3-14 using overlay blend mode. To use this blend mode, call the function CGContextSetBlendMode with the constant kCGBlendModeOverlay.
Figure 3-18 Rectangles painted using overlay blend mode

Darken Blend Mode
Specifies to create the composite image samples by choosing the darker samples (either from the foreground image or the background). The background image samples are replaced by any foreground image samples that are darker. Otherwise, the background image samples are left unchanged. Figure 3-19 shows the result of painting Figure 3-13 over Figure 3-14 using darken blend mode. To use this blend mode, call the function CGContextSetBlendMode with the constant kCGBlendModeDarken.
Figure 3-19 Rectangles painted using darken blend mode

Lighten Blend Mode
Specifies to create the composite image samples by choosing the lighter samples (either from the foreground or the background). The result is that the background image samples are replaced by any foreground image samples that are lighter. Otherwise, the background image samples are left unchanged. Figure 3-20 shows the result of painting Figure 3-13 over Figure 3-14 using lighten blend mode. To use this blend mode, call the function CGContextSetBlendMode with the constant kCGBlendModeLighten.
Figure 3-20 Rectangles painted using lighten blend mode

Color Dodge Blend Mode
Specifies to brighten the background image samples to reflect the foreground image samples. Foreground image sample values that specify black do not produce a change. Figure 3-21 shows the result of painting Figure 3-13 over Figure 3-14 using color dodge blend mode. To use this blend mode, call the function CGContextSetBlendMode with the constant kCGBlendModeColorDodge.
Figure 3-21 Rectangles painted using color dodge blend mode

Color Burn Blend Mode
Specifies to darken the background image samples to reflect the foreground image samples. Foreground image sample values that specify white do not produce a change. Figure 3-22 shows the result of painting Figure 3-13 over Figure 3-14 using color burn blend mode. To use this blend mode, call the function CGContextSetBlendMode with the constant kCGBlendModeColorBurn.
Figure 3-22 Rectangles painted using color burn blend mode

Soft Light Blend Mode
Specifies to either darken or lighten colors, depending on the foreground image sample color. If the foreground image sample color is lighter than 50% gray, the background is lightened, similar to dodging. If the foreground image sample color is darker than 50% gray, the background is darkened, similar to burning. If the foreground image sample color is equal to 50% gray, the background is not changed. Image samples that are equal to pure black or pure white produce darker or lighter areas, but do not result in pure black or white. The overall effect is similar to what you’d achieve by shining a diffuse spotlight on the foreground image. Use this to add highlights to a scene. Figure 3-23 shows the result of painting Figure 3-13 over Figure 3-14 using soft light blend mode. To use this blend mode, call the function CGContextSetBlendMode with the constant kCGBlendModeSoftLight.
Figure 3-23 Rectangles painted using soft light blend mode

Hard Light Blend Mode
Specifies to either multiply or screen colors, depending on the foreground image sample color. If the foreground image sample color is lighter than 50% gray, the background is lightened, similar to screening. If the foreground image sample color is darker than 50% gray, the background is darkened, similar to multiplying. If the foreground image sample color is equal to 50% gray, the foreground image is not changed. Image samples that are equal to pure black or pure white result in pure black or white. The overall effect is similar to what you’d achieve by shining a harsh spotlight on the foreground image. Use this to add highlights to a scene. Figure 3-24 shows the result of painting Figure 3-13 over Figure 3-14 using hard light blend mode. To use this blend mode, call the function CGContextSetBlendMode with the constant kCGBlendModeHardLight.
Figure 3-24 Rectangles painted using hard light blend mode

Difference Blend Mode
Specifies to subtract either the foreground image sample color from the background image sample color, or the reverse, depending on which sample has the greater brightness value. Foreground image sample values that are black produce no change; white inverts the background color values. Figure 3-25 shows the result of painting Figure 3-13 over Figure 3-14 using difference blend mode. To use this blend mode, call the function CGContextSetBlendMode with the constant kCGBlendModeDifference.
Figure 3-25 Rectangles painted using difference blend mode

Exclusion Blend Mode
Specifies an effect similar to that produced by kCGBlendModeDifference, but with lower contrast. Foreground image sample values that are black don’t produce a change; white inverts the background color values. Figure 3-26 shows the result of painting Figure 3-13 over Figure 3-14 using exclusion blend mode. To use this blend mode, call the function CGContextSetBlendMode with the constant kCGBlendModeExclusion.
Figure 3-26 Rectangles painted using exclusion blend mode

Hue Blend Mode
Specifies to use the luminance and saturation values of the background with the hue of the foreground image. Figure 3-27 shows the result of painting Figure 3-13 over Figure 3-14 using hue blend mode. To use this blend mode, call the function CGContextSetBlendMode with the constant kCGBlendModeHue.
Figure 3-27 Rectangles painted using hue blend mode

Saturation Blend Mode
Specifies to use the luminance and hue values of the background with the saturation of the foreground image. Areas of the background that have no saturation (that is, pure gray areas) don’t produce a change. Figure 3-28 shows the result of painting Figure 3-13 over Figure 3-14 using saturation blend mode. To use this blend mode, call the function CGContextSetBlendMode with the constant kCGBlendModeSaturation.
Figure 3-28 Rectangles painted using saturation blend mode

Color Blend Mode
Specifies to use the luminance values of the background with the hue and saturation values of the foreground image. This mode preserves the gray levels in the image. You can use this mode to color monochrome images or to tint color images. Figure 3-29 shows the result of painting Figure 3-13 over Figure 3-14 using color blend mode. To use this blend mode, call the function CGContextSetBlendMode with the constant kCGBlendModeColor.
Figure 3-29 Rectangles painted using color blend mode

Luminosity Blend Mode
Specifies to use the hue and saturation of the background with the luminance of the foreground image. This mode creates an effect that is inverse to the effect created by kCGBlendModeColor. Figure 3-30 shows the result of painting Figure 3-13 over Figure 3-14 using luminosity blend mode. To use this blend mode, call the function CGContextSetBlendMode with the constant kCGBlendModeLuminosity.
Figure 3-30 Rectangles painted using luminosity blend mode

Clipping to a Path

The current clipping area is created from a path that serves as a mask, allowing you to block out the part of the page that you don’t want to paint. For example, if you have a very large bitmap image and want to show only a small portion of it, you could set the clipping area to display only the portion you want to show.
When you paint, Quartz renders paint only within the clipping area. Drawing that occurs inside the closed subpaths of the clipping area is visible; drawing that occurs outside the closed subpaths of the clipping area is not.
When the graphics context is initially created, the clipping area includes all of the paintable area of the context (for example, the media box of a PDF context). You alter the clipping area by setting the current path and then using a clipping function instead of a drawing function. The clipping function intersects the filled area of the current path with the existing clipping area. Thus, you can intersect the clipping area, shrinking the visible area of the picture, but you cannot increase the area of the clipping area.
The clipping area is part of the graphics state. To restore the clipping area to a previous state, you can save the graphics state before you clip, and restore the graphics state after you’re done with clipped drawing.
Listing 3-1 shows a code fragment that sets up a clipping area in the shape of a circle. This code causes drawing to be clipped, similar to what’s shown in Figure 3-3. (For another example, see Clip the Context in the chapter Gradients.)
Listing 3-1 Setting up a circular clip area
CGContextBeginPath (context);

CGContextAddArc (context, w/2, h/2, ((w>h) ? h : w)/2, 0, 2*PI, 0);

CGContextClosePath (context);

CGContextClip (context);

Table 3-6 Functions that clip the graphics context
Function

Description

CGContextClip

Uses the nonzero winding number rule to calculate the intersection of the current path with the current clipping path.

CGContextEOClip

Uses the even-odd rule to calculate the intersection of the current path with the current clipping path.

CGContextClipToRect

Sets the clipping area to the area that intersects both the current clipping path and the specified rectangle.

CGContextClipToRects

Sets the clipping area to the area that intersects both the current clipping path and region within the specified rectangles.

CGContextClipToMask

Maps a mask into the specified rectangle and intersects it with the current clipping area of the graphics context. Any subsequent path drawing you perform to the graphics context is clipped. (See Masking an Image by Clipping the Context.)

Next
Previous

Copyright © 2001, 2014 Apple Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2014-09-17


Feedback

How helpful is this document?

Very helpful
Somewhat helpful
Not helpful
How can we improve this document?
Fix typos or links
Fix incorrect information
Add or update code samples
Add or update illustrations
Add information about...

  • Required information
    To submit a product bug or enhancement request, please visit the Bug Reporter page.
    Please read Apple's Unsolicited Idea Submission Policy before you send us your feedback.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,393评论 5 467
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,790评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,391评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,703评论 1 270
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,613评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,003评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,507评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,158评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,300评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,256评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,274评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,984评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,569评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,662评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,899评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,268评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,840评论 2 339

推荐阅读更多精彩内容