Quartz 2D 编程指南六:模式

作者: bobociel | 来源:发表于2017-06-21 10:23 被阅读49次

    Patterns

    A pattern is a sequence of drawing operations that is repeatedly painted to a graphics context. You can use patterns in the same way as you use colors. When you paint using a pattern, Quartz divides the page into a set of pattern cells, with each cell the size of the pattern image, and draws each cell using a callback you provide. Figure 6-1 shows a pattern drawn to a window graphics context.
    模式是重复绘制到图形上下文的绘图操作序列。 您可以使用与使用颜色相同的模式。 当您使用模式进行绘制时,Quartz将页面划分为一组模式单元格,每个单元格都是模式图像的大小,并使用您提供的回调绘制每个单元格。 图6-1显示了绘制到窗口图形上下文的图案。

    Figure 6-1  A pattern drawn to a windowFigure 6-1 A pattern drawn to a window

    The Anatomy of a Pattern(模式的骨架)

    The pattern cell is the basic component of a pattern. The pattern cell for the pattern shown in Figure 6-1 is shown in Figure 6-2. The black rectangle is not part of the pattern; it’s drawn to show where the pattern cell ends.
    图案单元格是图案的基本组件。 图6-1所示模式的模式单元如图6-2所示。 黑色矩形不是图案的一部分; 它代表图案单元的边界。

    Figure 6-2  A pattern cellFigure 6-2 A pattern cell

    The size of this particular pattern cell includes the area of the four colored rectangles and space above and to the right of the rectangles, as shown in Figure 6-3. The black rectangle surrounding each pattern cell in the figure is not part of the cell; it’s drawn to indicate the bounds of the cell. When you create a pattern cell, you define the bounds of the cell and draw within the bounds.
    该特定图形单元的大小包括四个彩色矩形的区域和矩形的上方和右侧的空间,如图6-3所示。 图中每个图案单元周围的黑色矩形不是单元格的一部分; 它被绘制以指示单元格的边界。 创建模式单元格时,可以定义单元格的边界并在边界内绘制。

    Figure 6-3  Pattern cells with black rectangles drawn to show the bounds of each cellFigure 6-3 Pattern cells with black rectangles drawn to show the bounds of each cell

    You can specify how far apart Quartz draws the start of each pattern cell from the next in the horizontal and vertical directions. The pattern cells in Figure 6-3 are drawn so that the start of one pattern cell is exactly a pattern width apart from the next pattern cell, resulting in each pattern cell abutting on the next. The pattern cells in Figure 6-4 have space added in both directions, horizontal and vertical. You can specify different spacing values for each direction. If you make the spacing less than the width or height of a pattern cell, the pattern cells overlap.
    您可以指定Quartz在水平和垂直方向绘制每个图案单元格的开始距离。 绘制图6-3中的图案单元,使得一个图案单元的开始正好是与下一图案单元分开的图案宽度,导致每个图案单元邻接在下一图案单元上。 图6-4中的图案单元格具有水平和垂直两个方向的空间。 您可以为每个方向指定不同的间距值。 如果使间距小于图案单元格的宽度或高度,则图案单元格重叠。

    Figure 6-4  Spacing between pattern cellsFigure 6-4 Spacing between pattern cells

    When you draw a pattern cell, Quartz uses pattern space as the coordinate system. Pattern space is an abstract space that maps to the default user space by the transformation matrix you specify when you create the pattern—the pattern matrix.

    绘制图案单元格时,Quartz会使用图案空间作为坐标系。 模式空间是一个抽象空间,通过您在创建模式时指定的转换矩阵(模式矩阵)映射到默认用户空间。

    Note: Pattern space is separate from user space. The untransformed pattern space maps to the base (untransformed) user space, regardless of the state of the current transformation matrix. When you apply a transformation to pattern space, Quartz applies the transform only to pattern space.

    注意:模式空间与用户空间分开。未转换的模式空间映射到基(未转换)用户空间,而不管当前变换矩阵的状态如何。当您将变换应用于模式空间时,Quartz仅将变换应用于模式空间。

    The default conventions for a pattern’s coordinate systems are those of the underlying graphics context. By default, Quartz uses a coordinate system where a positive x value represents a displacement to the right and a positive y value represents an upward displacement. However, a graphics context created by UIKit uses a different convention, where positive y values indicate a downward displacement. While this convention is normally applied to the graphics context by concatenating a transformation onto the coordinate system, in this case, Quartz also modifies the default conventions of pattern space to match.

    模式坐标系的默认约定是底层图形上下文的约定。默认情况下,Quartz使用坐标系,其中正x值表示右侧的位移,正y值表示向上位移。然而,由UIKit创建的图形上下文使用不同的约定,其中正y值表示向下的位移。虽然这个约定通常通过将转换连接到坐标系上来应用于图形上下文,但在这种情况下,Quartz还修改了匹配的模式空间的默认约定。

    If you don’t want Quartz to transform the pattern cell, you can specify the identity matrix. However, you can achieve interesting effects by supplying a transformation matrix. Figure 6-5 shows the effect of scaling the pattern cell shown in Figure 6-2. Figure 6-6demonstrates rotating the pattern cell. Translating the pattern cell is a bit more subtle. Figure 6-7 shows the origin of the pattern, with the pattern cell translated in both directions, horizontal and vertical, so that the pattern no longer abuts the window as it does in Figure 6-1.

    如果您不希望Quartz转换模式单元格,则可以指定单位矩阵。 但是,您可以通过提供转换矩阵来实现有趣的效果。 图6-5显示了如图6-2所示的缩放图案单元格的效果。 图6-6显示了旋转图案单元格。 翻译图案单元有点更微妙。 图6-7显示了图案的原点,图案单元在两个方向上均匀地水平和垂直折叠,使得图案不再像图6-1那样与窗口相邻。

    Figure 6-5  A scaled pattern cellFigure 6-5 A scaled pattern cell Figure 6-6  A rotated pattern cellFigure 6-6 A rotated pattern cell Figure 6-7  A translated pattern cellFigure 6-7 A translated pattern cell

    Colored patterns and Stencil(Uncolored) Patterns 着色模式和模板(未着色)模式

    Colored patterns have inherent colors associated with them. Change the coloring used to create the pattern cell, and the pattern loses its meaning. A Scottish tartan (such as the sample one shown in Figure 6-8) is an example of a colored pattern. The color in a colored pattern is specified as part of the pattern cell creation process, not as part of the pattern drawing process.

    着色模式具有与之相关的固有颜色。 更改用于创建图案单元格的着色,并且图案失去其含义。 苏格兰格子呢(如图6-8所示的样品)是彩色图案的一个例子。 彩色图案中的颜色被指定为图案单元格创建过程的一部分,而不是模式绘制过程的一部分。

    Figure 6-8  A colored pattern has inherent colorFigure 6-8 A colored pattern has inherent color

    Other patterns are defined solely on their shape and, for that reason, can be thought of as stencil patterns, uncolored patterns, or even as an image mask. The red and black stars shown in Figure 6-9 are each renditions of the same pattern cell. The cell itself consists of one shape—a filled star. When the pattern cell was defined, no color was associated with it. The color is specified as part of the pattern drawing process, not as part of the pattern cell creation.

    其他 模式仅根据其形状进行定义,因此,可以将其视为模板图案,无色图案,甚至可以作为图像遮照。 图6-9中所示的红色和黑色星星是相同图案单元的每个再现。 cell本身由一个形状组成 - 一个填充的星。 当定义图案单元格时,没有颜色与之相关联。 颜色被指定为图案绘制过程的一部分,而不是图案单元格创建的一部分。

    Figure 6-9  A stencil pattern does not have inherent colorFigure 6-9 A stencil pattern does not have inherent color

    You can create either kind of pattern—colored or stencil—in Quartz 2D.

    您可以在Quartz 2D中创建任何一种模式,着色模式或者模板模式。

    Tiling(平铺)

    Tiling is the process of rendering pattern cells to a portion of a page. When Quartz renders a pattern to a device, Quartz may need to adjust the pattern to fit the device space. That is, the pattern cell as defined in user space might not fit perfectly when rendered to the device because of differences between user space units and device pixels.

    平铺是将图案单元格渲染到页面的一部分的过程。 当Quartz将模式呈现给设备时,Quartz可能需要调整模式以适应设备空间。 也就是说,由于用户空间单元和设备像素之间的差异,用户空间中定义的模式单元格可能无法完美地呈现给设备。

    Quartz has three tiling options it can use to adjust patterns when necessary. Quartz can preserve:

    • The pattern, at the expense of adjusting the spacing between pattern cells slightly, but by no more than one device pixel. This is referred to as no distortion.
    • Spacing between cells, at the expense of distorting the pattern cell slightly, but by no more than one device pixel. This is referred to as constant spacing with minimal distortion.
    • Spacing between cells (as for the minimal distortion option) at the expense of distorting the pattern cell as much as needed to get fast tiling. This is referred to as constant spacing.

    Quartz有三个平铺选项,可以在必要时调整模式。 Quartz可以保存:

    • 该模式以牺牲图案单元之间的间距稍微调整而不超过一个器件像素为代价。 这被称为不变形。
    • 间隔在单元格之间,以牺牲图案单元格为单位,但不超过一个设备像素。 这被称为具有最小失真的恒定间隔。
    • 单元之间的间距(对于最小失真选项),以牺牲模式单元为代价,以获得快速平铺所需。 这被称为恒定间距。

    How Patterns Work(模式如何工作)

    Patterns operate similarly to colors, in that you set a fill or stroke pattern and then call a painting function. Quartz uses the pattern you set as the “paint.” For example, if you want to paint a filled rectangle with a solid color, you first call a function, such as CGContextSetFillColor, to set the fill color. Then you call the function CGContextFillRect to paint the filled rectangle with the color you specify. To paint with a pattern, you first call the function CGContextSetFillPattern to set the pattern. Then you call CGContextFillRect to actually paint the filled rectangle with the pattern you specify. The difference between painting with colors and with patterns is that you must define the pattern. You supply the pattern and color information to the function CGContextSetFillPattern. You’ll see how to create, set, and paint patterns in Painting Colored Patterns and Painting Stencil Patterns.

    模式的操作与颜色类似,您可以设置填充或描边模式,然后调用绘画功能。 Quartz使用您设置为“paint”的模式。例如,如果要使用纯色绘制一个填充的矩形,则首先调用一个函数,如CGContextSetFillColor来设置填充颜色。 然后,您调用函数CGContextFillRect以您指定的颜色绘制填充的矩形。 要使用模式进行绘制,您首先调用函数CGContextSetFillPattern来设置模式。 然后,您可以调用CGContextFillRect,使用您指定的模式来实际绘制填充的矩形。 绘画与颜色和图案之间的区别在于您必须定义图案。 您将模式和颜色信息提供给函数CGContextSetFillPattern。 您将看到如何在绘画彩色图案和绘画模板图案中创建,设置和绘制图案。

    Here’s an example of how Quartz works behind the scenes to paint with a pattern you provide. When you fill or stroke with a pattern, Quartz conceptually performs the following tasks to draw each pattern cell:

    • Saves the graphics state.
    • Translates the current transformation matrix to the origin of the pattern cell.
    • Concatenates the CTM with the pattern matrix.
    • Clips to the bounding rectangle of the pattern cell.
    • Calls your drawing callback to draw the pattern cell.
    • Restores the graphics state.

    这里有一个例子,说明Quartz如何离屏绘制模式。 当您使用模式填充或描边时,Quartz概念地执行以下任务来绘制每个模式单元格:

    • 保存图形状态。
    • 将当前变换矩阵转换为模式单元格的原点。
    • 将CTM与模式矩阵相连。
    • 剪切到图案单元格的边界矩形。
    • 调用绘图回调来绘制图案单元格。
    • 恢复图形状态。

    Quartz takes care of all the tiling for you, repeatedly rendering the pattern cell to the drawing space until the entire space is painted. You can fill or stroke with a pattern. The pattern cell can be of any size you specify. If you want to see the pattern, you should make sure the pattern cell fits in the drawing space. For example, if your pattern cell is 8 units by 10 units, and you use the pattern to stroke a line that has a width of 2 units, the pattern cell will be clipped since it is 10 units wide. In this case, you might not recognize the pattern.

    Quartz平铺,重复将图案单元格渲染到绘图空间,直到整个空间被绘制。 您可以使用图案填充或描边。 图案单元格可以是您指定的任何大小。 如果要查看图案,应确保图案单元适合图形空间。 例如,如果您的图案单元格是8个单位乘10单位,并且您使用该图案来划分宽度为2个单位的行,则图案单元格将被修剪,因为它是10单位宽。 在这种情况下,您可能无法识别该模式。

    Painting Colored Patterns(绘制着色模式)

    The five steps you need to perform to paint a colored pattern are described in the following sections:

    • Write a Callback Function That Draws a Colored Pattern Cell
    • Set Up the Colored Pattern Color Space
    • Set Up the Anatomy of the Colored Pattern
    • Specify the Colored Pattern as a Fill or Stroke Pattern
    • Draw With the Colored Pattern

    以下部分将介绍您需要执行以绘制着色模式的五个步骤:

    • 编写一个绘制彩色图案单元的回调函数
    • 设置彩色图案颜色空间
    • 设置彩色图案的解剖
    • 将彩色图案指定为填充或描边图案
    • 用彩色图案绘制

    These are the same steps you use to paint a stencil pattern. The difference between the two is how you set up color information. You can see how all the steps fit together in A Complete Colored Pattern Painting Function.

    这些也可用于绘制模板图案。 两者之间的区别是如何设置颜色信息。 您可以看到所有步骤如何在一个完整的彩色图案绘画功能中合并在一起。

    1.Write a Callback Function That Draws a Colored Pattern Cell(编写一个绘制着色模式单元的回调函数)

    What a pattern cell looks like is entirely up to you. For this example, the code in Listing 6-1 draws the pattern cell shown in Figure 6-2. Recall that the black line surrounding the pattern cell is not part of the cell; it’s drawn to show that the bounds of the pattern cell are larger than the rectangles painted by the code. You specify the pattern size to Quartz later.

    一个图案单元格看起来完全取决于你。 对于这个例子,清单6-1中的代码绘制了图6-2所示的模式单元格。 回想一下,围绕图案单元格的黑线不是单元格的一部分; 它被绘制以显示图案单元格的边界大于代码绘制的矩形。 您稍后可以将模式大小指定给Quartz。

    Your pattern cell drawing function is a callback that follows this form:

    typedef void (*CGPatternDrawPatternCallback) (
                            void *info,
                            CGContextRef context
        );
    

    You can name your callback whatever you like. The one in Listing 6-1 is named MyDrawColoredPattern. The callback takes two parameters:

    • info, a generic pointer to private data associated with the pattern. This parameter is optional; you can pass NULL. The data passed to your callback is the same data you supply later, when you create the pattern.
    • context, the graphics context for drawing the pattern cell.

    你可以命名你的回调,无论你喜欢什么。 清单6-1中的名为MyDrawColoredPattern。 回调有两个参数:

    • info,与模式相关联的私有数据的通用指针。 此参数是可选的; 你可以传递NULL。 当您创建模式时,传递给回调的数据与您稍后提供的数据相同。
    • context,用于绘制图案单元格的图形上下文。

    The pattern cell drawn by the code in Listing 6-1 is arbitrary. Your code draws whatever is appropriate for the pattern you create. These details about the code are important:

    • The pattern size is declared. You need to keep the pattern size in mind as you write your drawing code. Here, the size is declared as a global. The drawing function doesn’t specifically refer to the size, except in a comment. Later, you specify the pattern size to Quartz 2D. See Set Up the Anatomy of the Colored Pattern.
    • The drawing function follows the prototype defined by the CGPatternDrawPatternCallback callback type definition.
    • The drawing performed in the code sets colors, which makes this a colored pattern.

    由清单6-1中的代码绘制的模式单元格是任意的。 您的代码绘制适合您创建的模式的任何内容。 关于代码的这些细节很重要:

    • 模式大小被声明。 在编写图形代码时,需要牢记图案大小。 这里,大小被声明为全局。 绘图功能没有具体参考大小,除了在评论中。 之后,您可以将图案大小指定给Quartz 2D。 请参阅Set Up the Anatomy of the Colored Pattern
    • 绘图函数遵循由CGPatternDrawPatternCallback定义的原型回调类型定义。
    • 在代码中执行的绘图设置颜色,这使得它成为着色模式。

    Listing 6-1 A drawing callback that draws a colored pattern cell

    #define H_PATTERN_SIZE 16
    #define V_PATTERN_SIZE 18
    void MyDrawColoredPattern (void *info, CGContextRef myContext){
    CGFloat subunit = 5; // the pattern cell itself is 16 by 18
    CGRect myRect1 = {{0,0}, {subunit, subunit}},
    myRect2 = {{subunit, subunit}, {subunit, subunit}},
    myRect3 = {{0, subunit}, {subunit, subunit}},
    myRect4 = {{subunit,0}, {subunit, subunit}};
    CGContextSetRGBFillColor (myContext, 0, 0, 1, 0.5);
    CGContextFillRect (myContext, myRect1);
    CGContextSetRGBFillColor (myContext, 1, 0, 0, 0.5);
    CGContextFillRect (myContext, myRect2);
    CGContextSetRGBFillColor (myContext, 0, 1, 0, 0.5);
    CGContextFillRect (myContext, myRect3);
    CGContextSetRGBFillColor (myContext, .5, 0, .5, 0.5);
    CGContextFillRect (myContext, myRect4);
    }
    
    2.Set Up the Colored Pattern Color Space(设置着色模式颜色空间)

    The code in Listing 6-1 uses colors to draw the pattern cell. You must ensure that Quartz paints with the colors you use in your drawing routine by setting the base pattern color space to NULL, as shown in Listing 6-2. A detailed explanation for each numbered line of code follows the listing.

    清单6-1中的代码使用颜色来绘制模式单元格。 您必须确保Quartz通过将基本图案颜色空间设置为NULL来绘制您在绘图程序中使用的颜色,如清单6-2所示。 列出每个编号代码行的详细说明。

    Listing 6-2 Creating a base pattern color space

    CGColorSpaceRef patternSpace;
    patternSpace = CGColorSpaceCreatePattern (NULL);// 1
    CGContextSetFillColorSpace (myContext, patternSpace);// 2
    CGColorSpaceRelease (patternSpace);
    

    Here’s what the code does:

    1. Creates a pattern color space appropriate for a colored pattern by calling the function CGColorSpaceCreatePattern, passing NULL as the base color space.
    2. Sets the fill color space to the pattern color space. If you are stroking your pattern, call CGContextSetStrokeColorSpace.
    3. Releases the pattern color space.
    3.Set Up the Anatomy of the Colored Pattern(设置着色模式骨架)

    Information about the anatomy of a pattern is kept in a CGPattern object. You create a CGPattern object by calling the function CGPatternCreate, whose prototype is shown in Listing 6-3.
    有关模式骨架的信息保存在CGPattern对象中。 您可以通过调用函数CGPatternCreate来创建一个CGPattern对象,该函数的原型如清单6-3所示。

    Listing 6-3 The CGPatternCreate function prototype

    CGPatternRef CGPatternCreate ( void *info,
    CGRect bounds,
    CGAffineTransform matrix,
    CGFloat xStep,
    CGFloat yStep,
    CGPatternTiling tiling,
    bool isColored,
    const CGPatternCallbacks *callbacks );
    

    The info parameter is a pointer to data you want to pass to your drawing callback. This is the same pointer discussed in Write a Callback Function That Draws a Colored Pattern Cell.

    info参数是指向要传递给绘图回调的数据的指针。 这是在编写一个绘制彩色图案单元的回调函数中讨论的相同指针。

    You specify the size of the pattern cell in the bounds parameter. The matrix parameter is where you specify the pattern matrix, which maps the pattern coordinate system to the default coordinate system of the graphics context. Use the identity matrix if you want to draw the pattern using the same coordinate system as the graphics context. The xStep and yStep parameters specify the horizontal and vertical spacing between cells in the pattern coordinate system. See The Anatomy of a Pattern to review information on bounds, pattern matrix, and spacing.
    The tiling parameter can be one of three values:

    • kCGPatternTilingNoDistortion
    • kCGPatternTilingConstantSpacingMinimalDistortion
    • kCGPatternTilingConstantSpacing

    您可以在边界中指定模式单元格的大小参数。 矩阵参数是指定模式矩阵的位置,它将模式坐标系映射到图形上下文的默认坐标系。 如果要使用与图形上下文相同的坐标系绘制图案,请使用单位矩阵。 xStep和yStep参数指定模式坐标系中单元格之间的水平和垂直间距。 请参阅模式的解剖以查看关于边界,图案矩阵和间距的信息。
    平铺参数可选的三个值:

    • kCGPatternTilingNoDistortion
    • kCGPatternTilingConstantSpacingMinimalDistortion
    • kCGPatternTilingConstantSpacing

    See Tiling to review information on tiling.

    The isColored parameter specifies whether the pattern cell is a colored pattern (true) or a stencil pattern (false). If you pass true here, your drawing pattern callback specifies the pattern color, and you must set the pattern color space to the colored pattern color space (see Set Up the Colored Pattern Color Space).

    isColored参数指定图案单元格是彩色图案(true)还是模板图案(false)。如果您在此处传递true,则您的绘图模式回调指定图案颜色,您必须将图案颜色空间设置为彩色图案颜色空间(请参阅设置彩色图案颜色空间)。

    The last parameter you pass to the function CGPatternCreate is a pointer to a CGPatternCallbacks data structure. This structure has three fields:
    传递给函数CGPatternCreate的最后一个参数是指向CGPatternCallbacks数据结构的指针。这个结构有三个字段:

    struct CGPatternCallbacks
    {
    unsigned int version;
    CGPatternDrawPatternCallback drawPattern;
    CGPatternReleaseInfoCallback releaseInfo;
    };
    

    You set the version field to 0. The drawPattern field is a pointer to your drawing callback. The releaseInfo field is a pointer to a callback that’s invoked when the CGPattern object is released, to release storage for the info parameter you passed to your drawing callback. If you didn’t pass any data in this parameter, you set this field to NULL.
    您将版本字段设置为0. drawPattern字段是指向您的绘图回调的指针。 releaseInfo字段是一个指向在CGPattern对象被释放时调用的回调的指针,以释放您传递给绘图回调的info参数的存储。如果您没有在此参数中传递任何数据,则将此字段设置为NULL。

    4.Specify the Colored Pattern as a Fill or Stroke Pattern(指定着色模式作为填充或描边模式)

    You can use your pattern for filling or stroking by calling the appropriate function—CGContextSetFillPattern or CGContextSetStrokePattern. Quartz uses your pattern for any subsequent filling or stroking.
    These functions each take three parameters:

    • The graphics context
    • The CGPattern object that you created previously
    • An array of color components

    您可以通过调用相应的函数-CGContextSetFillPattern或CGContextSetStrokePattern来使用您的模式进行填充或调整。Quartz使用您的图案进行任何后续的填充或描边。

    Although colored patterns supply their own color, you must pass a single alpha value to inform Quartz of the overall opacity of the pattern when it’s drawn. Alpha can vary from 1 (completely opaque) to 0 (completely transparent). These lines of code show an example of how to set opacity for a colored pattern used to fill.
    虽然彩色图案提供自己的颜色,您必须传递一个单一的Alpha值,以便在绘制时通知Quartz图案的整体不透明度。 Alpha可以从1(完全不透明)到0(完全透明)。这些代码行显示了如何为用于填充的彩色图案设置不透明度的示例。

    CGFloat alpha = 1;
    CGContextSetFillPattern (myContext, myPattern, &alpha);
    
    5.Draw With the Colored Pattern(绘制着色模式)

    After you’ve completed the previous steps, you can call any Quartz 2D function that paints. Your pattern is used as the “paint.” For example, you can call CGContextStrokePath, CGContextFillPath, CGContextFillRect, or any other function that paints.

    完成上述步骤后,您可以调用任何绘制的Quartz 2D功能。您的模式用作“油漆”。例如,您可以调用CGContextStrokePath,CGContextFillPath,CGContextFillRect或任何其他绘制的功能。

    A Complete Colored Pattern Painting Function(完整着色模式实例)

    The code in Listing 6-4 contains a function that paints a colored pattern. The function incorporates all the steps discussed previously. A detailed explanation for each numbered line of code follows the listing.

    Listing 6-4 A function that paints a colored pattern

    void MyColoredPatternPainting (CGContextRef myContext,
                     CGRect rect)
    {
        CGPatternRef    pattern;// 1
        CGColorSpaceRef patternSpace;// 2
        CGFloat         alpha = 1,// 3
                        width, height;// 4
        static const    CGPatternCallbacks callbacks = {0, // 5
                                            &MyDrawPattern,
                                            NULL};
     
        CGContextSaveGState (myContext);
        patternSpace = CGColorSpaceCreatePattern (NULL);// 6
        CGContextSetFillColorSpace (myContext, patternSpace);// 7
        CGColorSpaceRelease (patternSpace);// 8
     
        pattern = CGPatternCreate (NULL, // 9
                        CGRectMake (0, 0, H_PSIZE, V_PSIZE),// 10
                        CGAffineTransformMake (1, 0, 0, 1, 0, 0),// 11
                        H_PATTERN_SIZE, // 12
                        V_PATTERN_SIZE, // 13
                        kCGPatternTilingConstantSpacing,// 14
                        true, // 15
                        &callbacks);// 16
     
        CGContextSetFillPattern (myContext, pattern, &alpha);// 17
        CGPatternRelease (pattern);// 18
        CGContextFillRect (myContext, rect);// 19
        CGContextRestoreGState (myContext);
    }
    

    Here’s what the code does:

    1. Declares storage for a CGPattern object that is created later.
    2. Declares storage for a pattern color space that is created later.
    3. Declares a variable for alpha and sets it to 1, which specifies the opacity of the pattern as completely opaque.
    4. Declares variable to hold the height and width of the window. In this example, the pattern is painted over the area of a window.
    5. Declares and fills a callbacks structure, passing 0
      as the version and a pointer to a drawing callback function. This example does not provide a release info callback, so that field is set to NULL.
    6. Creates a pattern color space object, setting the pattern’s base color space to NULL. When you paint a colored pattern, the pattern supplies its own color in the drawing callback, which is why you set the color space to NULL.
    7. Sets the fill color space to the pattern color space object you just created.
    8. Releases the pattern color space object.
    9. Passes NULL because the pattern does not need any additional information passed to the drawing callback.
    10. Passes a CGRect object that specifies the bounds of the pattern cell.
    11. Passes a CGAffineTransform matrix that specifies how to translate the pattern space to the default user space of the context in which the pattern is used. This example passes the identity matrix.
    12. Passes the horizontal pattern size as the horizontal displacement between the start of each cell. In this example, one cell is painted adjacent to the next.
    13. Passes the vertical pattern size as the vertical displacement between start of each cell.
    14. Passes the constant kCGPatternTilingConstantSpacing
      to specify how Quartz should render the pattern. For more information, see Tiling.
    15. Passes true for the isColored parameter, to specify that the pattern is a colored pattern.
    16. Passes a pointer to the callbacks structure that contains version information, and a pointer to your drawing callback function.
    17. Sets the fill pattern, passing the context, the CGPattern object you just created, and a pointer to the alpha value that specifies an opacity for Quartz to apply to the pattern.
    18. Releases the CGPattern object.
    19. Fills a rectangle that is the size of the window passed to the MyColoredPatternPainting routine. Quartz fills the rectangle using the pattern you just set up.

    Painting Stencil Patterns(绘制模板模式)

    The five steps you need to perform to paint a stencil pattern are described in the following sections:

    • Write a Callback Function That Draws a Stencil Pattern Cell.
    • Set Up the Stencil Pattern Color Space
    • Set Up the Anatomy of the Stencil Pattern
    • Specify the Stencil Pattern as a Fill or Stroke Pattern
    • Drawing with the Stencil Pattern

    以下部分将描述绘制模版模式所需执行的五个步骤:

    • 编写一个绘制模板图案单元的回调函数。
    • 设置模板图案颜色空间
    • 设置模板图案的解剖
    • 将模板图案指定为填充或描边图案
    • 用模板图案绘图

    These are actually the same steps you use to paint a colored pattern. The difference between the two is how you set up color information. You can see how all the steps fit together in A Complete Stencil Pattern Painting Function.

    这些实际上与您用来绘制着色模式的步骤相同。 两者之间的区别是如何设置颜色信息。 你可以看到所有的步骤如何配合在一个完整的模板图案绘画功能。

    1.Write a Callback Function That Draws a Stencil Pattern Cell(编写一个绘制模板模式单元的回调函数)

    The callback you write for drawing a stencil pattern follows the same form as that described for a colored pattern cell. See Write a Callback Function That Draws a Colored Pattern Cell. The only difference is that your drawing callback does not specify any color. The pattern cell shown in Figure 6-10 does not get its color from the drawing callback. The color is set outside the drawing color in the pattern color space.
    您为绘制模板模式编写的回调和与彩色图案单元格所描述的相同。 请参阅编写一个绘制着色模式单元格的回调函数。 唯一的区别是你的绘图回调没有指定任何颜色。 图6-10所示的模式单元格不会从绘图回调中获取其颜色。 颜色设置在图案颜色空间中的绘图颜色之外。

    Figure 6-10  A stencil pattern cellFigure 6-10 A stencil pattern cell

    Take a look at the code in Listing 6-5, which draws the pattern cell shown in Figure 6-10. Notice that the code simply creates a path and fills the path. The code does not set color.
    看看清单6-5中的代码,它们绘制了图6-10所示的模式单元格。 请注意,代码中只是创建一个路径并填充路径,没有设置颜色。

    Listing 6-5 A drawing callback that draws a stencil pattern cell

    #define PSIZE 16 // size of the pattern cell
    static void MyDrawStencilStar (void *info, CGContextRef myContext)
    {
    int k;
    double r, theta;
    r = 0.8 * PSIZE / 2;
    theta = 2 * M_PI * (2.0 / 5.0); // 144 degrees
    CGContextTranslateCTM (myContext, PSIZE/2, PSIZE/2);
    CGContextMoveToPoint(myContext, 0, r);
    for (k = 1; k < 5; k++) {
    CGContextAddLineToPoint (myContext,
    r * sin(k * theta),
    r * cos(k * theta));
    }
    CGContextClosePath(myContext);
    CGContextFillPath(myContext);
    }
    
    2.Set Up the Stencil Pattern Color Space(设置模板模式颜色空间)

    Stencil patterns require that you set up a pattern color space for Quartz to paint with, as shown in Listing 6-6. A detailed explanation for each numbered line of code follows the listing.
    模板模式要求您为Quartz绘制图案颜色空间,如清单6-6所示。代码说明如下。

    Listing 6-6 Code that creates a pattern color space for a stencil pattern

    CGPatternRef pattern;
    CGColorSpaceRef baseSpace;
    CGColorSpaceRef patternSpace;
    
    baseSpace = CGColorSpaceCreateWithName (kCGColorSpaceGenericRGB);// 1
    patternSpace = CGColorSpaceCreatePattern (baseSpace);// 2
    CGContextSetFillColorSpace (myContext, patternSpace);// 3
    CGColorSpaceRelease(patternSpace);// 4
    CGColorSpaceRelease(baseSpace);
    

    Here’s what the code does:

    1. This function creates a generic RGB space. Generic color spaces leave color matching to the system. For more information, see Creating Generic Color Spaces.
    2. Creates a pattern color space. The color space you supply specifies how colors are represented for the pattern. Later, when you set colors for the pattern, you must set them using the pattern color space. For this example, you will need to specify color using RGB values.
    3. Sets the color space to use when filling a pattern. You can set a stroke color space by calling the functionCGContextSetStrokeColorSpace.
    4. Releases the pattern color space object.
    5. Releases the base color space object.
    3.Set Up the Anatomy of the Stencil Pattern(设置模板模式骨架)

    You specify information about the anatomy of a pattern the way you would for a colored pattern—by calling the function CGPatternCreate. The only difference is that you pass false for the isColored parameter. See Set Up the Anatomy of the Colored Pattern for more information on the parameters you supply to the CGPatternCreate function.

    您可以通过调用函数CGPatternCreate来指定有关模式骨架的信息。唯一的区别是对于isColored参数传递false。有关您提供给CGPatternCreate函数的参数的更多信息,请参阅设置着色模式的骨架。

    4.Specify the Stencil Pattern as a Fill or Stroke Pattern(指定模板模式作为填充或描边模式)

    You can use your pattern for filling or stroking by calling the appropriate function, CGContextSetFillPattern or CGContextSetStrokePattern. Quartz uses your pattern for any subsequent filling or stroking.

    您可以通过调用相应的函数CGContextSetFillPattern或CGContextSetStrokePattern来使用您的模式进行填充或描边。 Quartz使用该模式进行后续的填充或描边。

    These functions each take three parameters:

    • The graphics context
    • The CGPattern object that you created previously
    • An array of color components

    这些函数需要三个参数参数:

    • 图形上下文
    • 您以前创建的CGPattern对象
    • 一系列颜色分量

    A stencil pattern does not supply a color in the drawing callback, so you must pass a color to the fill or stroke functions to inform Quartz what color to use. Listing 6-7 shows an example of how to set color for a stencil pattern. The values in the color array are interpreted by Quartz in the color space you set up earlier. Because this example uses device RGB, the color array contains values for red, green, and blue components. The fourth value specifies the opacity of the color.

    模板模式在绘图回调中不提供颜色,因此您必须将颜色传递给填充或描边函数,以通知Quartz要使用的颜色。清单6-7显示了如何为模板模式设置颜色的示例。 Quartz在您之前设置的颜色空间中解释颜色数组中的值。由于此示例使用设备RGB,颜色数组包含红色,绿色和蓝色组件的值。第四个值指定颜色的不透明度。

    Listing 6-7 Code that sets opacity for a colored pattern

    static const CGFloat color[4] = { 0, 1, 1, 0.5 }; //cyan, 50% transparent
    CGContextSetFillPattern (myContext, myPattern, color);
    
    5.Draw With the Stencil Pattern(绘制模板模式)

    After you’ve completed the previous steps, you can call any Quartz 2D function that paints. Your pattern is used as the “paint.” For example, you can call CGContextStrokePath, CGContextFillPath, CGContextFillRect, or any other function that paints.
    完成上述步骤后,您可以调用Quartz 2D函数进行绘制。 您的模式用作“绘图”。例如,您可以调用CGContextStrokePath,CGContextFillPath,CGContextFillRect或其他绘制的函数。

    A Complete Stencil Pattern Painting Function(完整模板模式实例)

    The code in Listing 6-8 contains a function that paints a stencil pattern. The function incorporates all the steps discussed previously. A detailed explanation for each numbered line of code follows the listing.
    清单6-8中的代码包含一个绘制模版模式的函数。 该功能包含以前讨论的所有步骤。 代码行及编号的详细说明如下。

    Listing 6-8 A function that paints a stencil pattern

    #define PSIZE 16
     
    void MyStencilPatternPainting (CGContextRef myContext,
                                    const Rect *windowRect)
    {
        CGPatternRef pattern;
        CGColorSpaceRef baseSpace;
        CGColorSpaceRef patternSpace;
        static const CGFloat color[4] = { 0, 1, 0, 1 };// 1
        static const CGPatternCallbacks callbacks = {0, &drawStar, NULL};// 2
     
        baseSpace = CGColorSpaceCreateDeviceRGB ();// 3
        patternSpace = CGColorSpaceCreatePattern (baseSpace);// 4
        CGContextSetFillColorSpace (myContext, patternSpace);// 5
        CGColorSpaceRelease (patternSpace);
        CGColorSpaceRelease (baseSpace);
        pattern = CGPatternCreate(NULL, CGRectMake(0, 0, PSIZE, PSIZE),// 6
                      CGAffineTransformIdentity, PSIZE, PSIZE,
                      kCGPatternTilingConstantSpacing,
                      false, &callbacks);
        CGContextSetFillPattern (myContext, pattern, color);// 7
        CGPatternRelease (pattern);// 8
        CGContextFillRect (myContext,CGRectMake (0,0,PSIZE*20,PSIZE*20));// 9
    }
    

    Here’s what the code does:

    1. Declares an array to hold a color value and sets the value (which will be in RGB color space) to opaque green.
    2. Declares and fills a callbacks structure, passing 0
      as the version and a pointer to a drawing callback function. This example does not provide a release info callback, so that field is set to NULL.
    3. Creates an RGB device color space. If the pattern is drawn to a display, you need to supply this type of color space.
    4. Creates a pattern color space object from the RGB device color space.
    5. Sets the fill color space to the pattern color space object you just created.
    6. Creates a pattern object. Note that the second to last parameter—the isColored parameter—is false. Stencil patterns do not supply color, so you must pass false
      for this parameter. All other parameters are similar to those passed for the colored pattern example. See A Complete Colored Pattern Painting Function.
    7. Sets the fill pattern, passing the color array declared previously.
    8. Releases the CGPattern object.
    9. Fills a rectangle. Quartz fills the rectangle using the pattern you just set up.

    相关文章

      网友评论

        本文标题:Quartz 2D 编程指南六:模式

        本文链接:https://www.haomeiwen.com/subject/xlqlfxtx.html