Quartz 2D编程指南 (八) —— Patterns图案样式(一)

版本记录

版本号 时间
V1.0 2018.09.05

前言

Quartz 2D框架相信大家都知道,也都一直在使用。Quartz 2D的API是纯C语言的,它是一个二维绘图引擎,同时支持iOS和Mac系统。Quartz 2D的API来自于Core Graphics框架,数据类型和函数基本都以CG作为前缀,接下来几篇我们就一起来看一下这个框架。感兴趣可以看上面几篇文章。
1. Quartz 2D编程指南 (一) —— 简介(一)
2. Quartz 2D编程指南 (二) —— Quartz 2D概览(二)
3. Quartz 2D编程指南 (三) —— 图形上下文(三)
4. Quartz 2D编程指南 (四) —— Paths路径(一)
5. Quartz 2D编程指南 (五) —— Paths路径(二)
6. Quartz 2D编程指南 (六) —— 颜色和颜色空间(一)
7. Quartz 2D编程指南 (七) —— 变换(一)

Patterns - 图案样式

pattern是一系列绘制操作,重复绘制到图形上下文。 您可以使用与使用颜色相同的方式使用模式。 当您使用pattern进行绘制时,Quartz将页面划分为一组pattern单元格,每个单元格都是图案pattern图像的大小,并使用您提供的回调绘制每个单元格。 图6-1显示了绘制到窗口图形上下文的pattern

Quartz 2D编程指南 (八) —— Patterns图案样式(一)_第1张图片
Figure 6-1 A pattern drawn to a window

The Anatomy of a Pattern - 图案的剖析

模式pattern单元是模式的基本组件。 图6-1中所示模式的模式单元如图6-2所示。 黑色矩形不是图案的一部分,它被绘制以显示模式单元格的结束位置。

Figure 6-2 A pattern cell

该特定图案单元的大小包括四个彩色矩形的区域以及矩形上方和右侧的空间,如图6-3所示。 图中每个图案单元周围的黑色矩形不是单元的一部分; 它被绘制以指示单元的边界。 创建模式单元格时,可以定义单元格的边界并在边界内绘制。

Quartz 2D编程指南 (八) —— Patterns图案样式(一)_第2张图片
Figure 6-3 Pattern cells with black rectangles drawn to show the bounds of each cell

您可以指定Quartz在水平和垂直方向上绘制每个图案单元的起点与下一个图案单元的距离。 绘制图6-3中的图案单元,使得一个图案单元的开始正好是与下一个图案单元分开的图案宽度,导致每个图案单元在下一个图案单元上邻接。 图6-4中的图案单元在水平和垂直两个方向上都添加了空间。 您可以为每个方向指定不同的间距值。 如果使间距小于图案单元格的宽度或高度,则图案单元格会重叠。

Quartz 2D编程指南 (八) —— Patterns图案样式(一)_第3张图片
Figure 6-4 Spacing between pattern cells

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

注意:模式空间(pattern space)与用户空间分开。无论当前转换矩阵的状态如何,未转换的模式空间都映射到基本(未转换的)用户空间。将变换应用于模式空间时,Quartz仅将变换应用于模式空间。模式坐标系的默认约定是底层图形上下文的约定。默认情况下,Quartz使用坐标系,其中正x值表示向右的位移,正y值表示向上位移。但是,UIKit创建的图形上下文使用不同的约定,其中正y值表示向下位移。虽然此约定通常通过将变换连接到坐标系统来应用于图形上下文,但在这种情况下,Quartz还会修改模式空间的默认约定以进行匹配。

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

Quartz 2D编程指南 (八) —— Patterns图案样式(一)_第4张图片
Figure 6-5 A scaled pattern cell
Quartz 2D编程指南 (八) —— Patterns图案样式(一)_第5张图片
Figure 6-6 A rotated pattern cell
Quartz 2D编程指南 (八) —— Patterns图案样式(一)_第6张图片
Figure 6-7 A translated pattern cell

Colored Patterns and Stencil (Uncolored) Patterns - 彩色模式和模具(无色)模式

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

Figure 6-8 A colored pattern has inherent color

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

Quartz 2D编程指南 (八) —— Patterns图案样式(一)_第7张图片
Figure 6-9 A stencil pattern does not have inherent color

您可以在Quartz 2D中创建任何一种图案(colored or stencil)


Tiling - 平铺

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

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

  • 该模式以牺牲图案单元之间的间距为代价,但不超过一个设备像素。 这被称为无失真(no distortion)
  • 单元之间的间隔,代价是略微扭曲图案单元,但不超过一个设备像素。 这被称为具有最小失真的恒定间隔(constant spacing with minimal distortion)
  • 单元之间的间隔(对于最小失真选项),代价是扭曲模式单元,以达到快速平铺所需的程度。 这被称为恒定间距(constant spacing)

How Patterns Work - Patterns工作原理

图案的操作与颜色类似,因为您设置了填充或描边图案,然后调用绘画函数。 Quartz使用您设置为“paint”的模式。例如,如果要绘制带有纯色的填充矩形,则首先调用函数(如CGContextSetFillColor)来设置填充颜色。然后调用函数CGContextFillRect以使用指定的颜色绘制填充的矩形。要使用模式绘制,首先调用函数CGContextSetFillPattern来设置模式。然后调用CGContextFillRect实际使用指定的模式绘制填充的矩形。绘画与颜色和图案之间的区别在于您必须定义pattern。您将pattern和颜色信息提供给函数CGContextSetFillPattern。您将看到如何在Painting Colored Patterns和Painting Stencil Patterns中创建,设置和绘制pattern

下面是Quartz如何在幕后工作以使用您提供的模式进行绘制的示例。当您使用模式填充或描边时,Quartz在概念上执行以下任务来绘制每个模式单元格:

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

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


Painting Colored Patterns - 绘画彩色图案

以下各节介绍了绘制彩色图案所需执行的五个步骤:

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

这些步骤与用于绘制模板图案的步骤相同。 两者之间的区别在于您如何设置颜色信息。 您可以在A Complete Colored Pattern Painting Function中查看所有步骤如何组合在一起。

1. Write a Callback Function That Draws a Colored Pattern Cell - 编写绘制彩色图案单元格的回调函数

模式单元格看起来怎么样完全取决于您。 对于此示例,Listing 6-1中的代码绘制了图6-2中所示的模式单元。 回想一下,模式单元周围的黑线不是单元的一部分,它的绘制表明模式单元格的边界大于代码绘制的矩形。 您稍后将模式大小指定为Quartz。

您的模式单元格绘制函数是一个遵循此形式的回调:

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

你可以随意命名你的回调。Listing 6-1中的名为MyDrawColoredPattern。回调有两个参数:

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

Listing 6-1中的代码绘制的模式单元格是任意的。您的代码会绘制适合您创建的模式的任何内容。有关代码的这些详细信息非常重要:

  • 声明了pattern size。在编写绘图代码时,需要牢记图案尺寸。这里,大小被声明为全局。除评论外,绘图函数不具体指代大小。稍后,您将图案大小指定为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 - 设置彩色图案颜色空间

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

// Listing 6-2  Creating a base pattern color space

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

这是代码的作用:

  • 1)通过调用函数CGColorSpaceCreatePattern创建适合彩色图案的图案颜色空间,将NULL作为基色空间传递。
  • 2)将填充颜色空间设置为图案颜色空间。 如果您正在stroke图案,请调用CGContextSetStrokeColorSpace
  • 3)释放图案颜色空间。

3. Set Up the Anatomy of the Colored Pattern - 建立彩色图案Anatomy

有关anatomy of a pattern的信息保存在CGPattern对象中。 您可以通过调用函数CGPatternCreate来创建CGPattern对象,其原型如Listing 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 );

info参数是指向要传递给绘图回调的数据的指针。这是 Write a Callback Function That Draws a Colored Pattern Cell中讨论的相同指针。

您可以在bounds参数中指定图案单元格的大小size。matrix参数指定图案矩阵,它将图案坐标系映射到图形上下文的默认坐标系。如果要使用与图形上下文相同的坐标系绘制图案,请使用单位矩阵。 xStepyStep参数指定图案坐标系中单元格之间的水平和垂直间距。请参阅The Anatomy of a Pattern以查看有关边界,图案矩阵和间距的信息。

tiling参数可以是以下三个值之一:

  • kCGPatternTilingNoDistortion
  • kCGPatternTilingConstantSpacingMinimalDistortion
  • kCGPatternTilingConstantSpacing

请参阅Tiling以查看有关平铺的信息。

isColored参数指定图案单元格是彩色图案(true)还是模板图案(false)。如果在此处传递true,则绘图图案回调指定图案颜色,并且必须将图案颜色空间设置为彩色图案颜色空间(请参阅Set Up the Colored Pattern Color Space)。

传递给函数CGPatternCreate的最后一个参数是指向CGPatternCallbacks数据结构的指针。这个结构有三个字段:

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

version字段设置为0drawPattern字段是指向绘图回调的指针。 releaseInfo字段是指向释放CGPattern对象时调用的回调的指针,用于释放传递给绘图回调的info参数的存储。 如果未在此参数中传递任何数据,则将此字段设置为NULL

4. Specify the Colored Pattern as a Fill or Stroke Pattern - 将彩色图案指定为填充或描边图案

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

这些函数各有三个参数:

  • 图形上下文
  • 您之前创建的CGPattern对象
  • 一系列颜色组件

尽管彩色图案提供了自己的颜色,但您必须传递单个Alpha值以通知Quartz绘制时图案的整体不透明度。 Alpha可以从1(完全不透明)到0(完全透明)变化。 这些代码行显示了如何为用于填充的彩色图案设置不透明度的示例。

CGFloat alpha = 1;
 
CGContextSetFillPattern (myContext, myPattern, &alpha);

5. Draw With the Colored Pattern - 用彩色图案绘制

完成上述步骤后,您可以调用任何绘制的Quartz 2D函数。 您的图案用作“paint”。例如,您可以调用CGContextStrokePathCGContextFillPathCGContextFillRect或任何其他绘制函数。

6. A Complete Colored Pattern Painting Function - 一个完整的彩色图案绘画函数

Listing 6-4中的代码包含一个绘制彩色图案的函数。 该函数包含了前面讨论的所有步骤。 列表后面有每个编号行代码的详细说明。

// 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);
}

这是代码的作用:

  • 1)声明稍后创建的CGPattern对象的存储。
  • 2)声明稍后创建的图像颜色空间的存储。
  • 3)声明alpha的变量并将其设置为1,它将模式的不透明度指定为完全不透明。
  • 4)声明变量以保持窗口的高度和宽度。在此示例中,图案绘制在窗口区域上。
  • 5)声明并填充回调结构,将0作为版本传递,并将指针传递给绘图回调函数。此示例未提供释放信息回调,因此该字段设置为NULL
  • 6)创建图案颜色空间对象,将图案的基色空间设置为NULL。绘制彩色图案时,图案在图形回调中提供自己的颜色,这就是您将颜色空间设置为NULL的原因。
  • 7)将填充颜色空间设置为刚刚创建的图案颜色空间对象。
  • 8)释放图案颜色空间对象。
  • 9)传递NULL,因为图案不需要传递给绘图回调的任何其他信息。
  • 10)传递一个CGRect对象,该对象指定图案单元格的边界。
  • 11)传递CGAffineTransform矩阵,该矩阵指定如何将图案空间转换为使用图案的上下文的默认用户空间。此示例传递单位矩阵。
  • 12)将水平图案大小作为每个单元格开头之间的水平位移。在此示例中,一个单元格与下一个单元格相邻。
  • 13)将垂直图案大小作为每个单元格开始之间的垂直位移。
  • 14)传递常量kCGPatternTilingConstantSpacing以指定Quartz应如何呈现图案。有关更多信息,请参阅Tiling。
  • 15)对isColored参数传递true,以指定图案为彩色图案。
  • 16)传递指向包含版本信息的回调结构的指针,以及指向绘图回调函数的指针。
  • 17)设置填充模式,传递上下文,刚刚创建的CGPattern对象,以及指向Alpha值的指针,该值指定Quartz应用于模式的不透明度。
  • 18)释放CGPattern对象。
  • 19)填充一个矩形,该矩形是传递给MyColoredPatternPainting例程的窗口大小。Quartz使用您刚刚设置的图案填充矩形。

Painting Stencil Patterns - 绘制模板图案

以下各节介绍了绘制模板图案所需执行的五个步骤:

  • 1) Write a Callback Function That Draws a Stencil Pattern Cell
  • 2) Set Up the Stencil Pattern Color Space
  • 3) Set Up the Anatomy of the Stencil Pattern
  • 4) Specify the Stencil Pattern as a Fill or Stroke Pattern
  • 5) Drawing with the Stencil Pattern

这些实际上与您用于绘制彩色图案的步骤相同。 两者之间的区别在于您如何设置颜色信息。 您可以在A Complete Stencil Pattern Painting Function中查看所有步骤如何组合在一起。

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

您为绘制模板图案而编写的回调遵循与彩色图案单元格所描述的相同的形式。 请参阅 Write a Callback Function That Draws a Colored Pattern Cell。 唯一的区别是您的绘图回调没有指定任何颜色。 图6-10中显示的图案单元格没有从图形回调中获得颜色。 颜色设置在图案颜色空间中的绘图颜色之外。

Figure 6-10 A stencil pattern cell

看一下Listing 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 - 设置模板图案颜色空间

模板图案要求您为Quartz设置图案颜色空间以进行绘制,如Listing 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);// 5

这是代码的作用:

  • 1) 此函数创建一个通用RGB空间。 通用颜色空间使颜色与系统匹配。 有关更多信息,请参阅 Creating Generic Color Spaces。
  • 2) 创建图案颜色空间。 您提供的颜色空间指定了如何为图案表示颜色。 稍后,当您为图案设置颜色时,必须使用图案颜色空间设置它们。 对于此示例,您需要使用RGB值指定颜色。
  • 3) 设置填充图案时要使用的颜色空间。 您可以通过调用CGContextSetStrokeColorSpace函数来设置描边颜色空间。
  • 4) 释放图案颜色空间对象。
  • 5) 释放基色空间对象。

3. Set Up the Anatomy of the Stencil Pattern - 建立模板图案的剖析

Stencil patterns要求您为Quartz设置图案颜色空间以进行绘制,如Listing 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);// 5

这是代码的作用:

  • 1) 此函数创建一个通用RGB空间。 通用颜色空间使颜色与系统匹配。 有关更多信息,请参阅Creating Generic Color Spaces。
  • 2) 创建图案颜色空间。 您提供的颜色空间指定了如何为图案表示颜色。 稍后,当您为图案设置颜色时,必须使用图案颜色空间设置它们。 对于此示例,您需要使用RGB值指定颜色。
  • 3) 设置填充图案时要使用的颜色空间。 您可以通过调用CGContextSetStrokeColorSpace函数来设置描边颜色空间。
  • 4) 释放图案颜色空间对象。
  • 5) 释放基色空间对象。

4. Specify the Stencil Pattern as a Fill or Stroke Pattern - 将模板图案指定为填充或描边图案

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

这些函数各有三个参数:

  • 1) 图形上下文
  • 2) 您之前创建的CGPattern对象
  • 3) 一系列颜色组件

模板图案不会在图形回调中提供颜色,因此您必须将颜色传递给填充或描边函数以通知Quartz要使用的颜色。 Listing 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. Drawing with the Stencil Pattern - 用模具图案绘图

完成上述步骤后,您可以调用任何绘制的Quartz 2D函数。 您的模式用作“paint”。例如,您可以调用CGContextStrokePathCGContextFillPathCGContextFillRect或任何其他绘制函数。

6. A Complete Stencil Pattern Painting Function - 完整的模板图案绘画功能

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
}

这是代码的作用:

  • 1) 声明一个数组以保存颜色值并将值(将在RGB颜色空间中)设置为不透明绿色。
  • 2) 声明并填充回调结构,将0作为版本传递,并将指针传递给绘图回调函数。此示例未提供发布信息回调,因此该字段设置为NULL
  • 3) 创建RGB设备颜色空间。如果将图案绘制到显示器,则需要提供此类型的色彩空间。
  • 4) 从RGB设备颜色空间创建图案颜色空间对象。
  • 5) 将填充颜色空间设置为刚刚创建的图案颜色空间对象。
  • 6) 创建一个图案对象。请注意,倒数第二个参数 - isColored参数 - 为false。模板图案不提供颜色,因此您必须为此参数传递false。所有其他参数类似于为彩色图案示例传递的参数。请参阅A Complete Colored Pattern Painting Function。
  • 7) 设置填充图案,传递先前声明的颜色数组。
  • 8) 释放CGPattern对象。
  • 9) 填充矩形。 Quartz使用您刚刚设置的图案填充矩形。

后记

本篇主要讲述了Patterns图案样式,感兴趣的给个赞或者关注~~~

Quartz 2D编程指南 (八) —— Patterns图案样式(一)_第8张图片

你可能感兴趣的:(Quartz 2D编程指南 (八) —— Patterns图案样式(一))