Quartz 2D編程指南 (八) —— Patterns圖案樣式(一)

版本記錄

版本號 時(shí)間
V1.0 2018.09.05

前言

Quartz 2D框架相信大家都知道壮锻,也都一直在使用琐旁。Quartz 2D的API是純C語言的,它是一個(gè)二維繪圖引擎猜绣,同時(shí)支持iOS和Mac系統(tǒng)灰殴。Quartz 2D的API來自于Core Graphics框架,數(shù)據(jù)類型和函數(shù)基本都以CG作為前綴掰邢,接下來幾篇我們就一起來看一下這個(gè)框架牺陶。感興趣可以看上面幾篇文章。
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是一系列繪制操作辣之,重復(fù)繪制到圖形上下文掰伸。 您可以使用與使用顏色相同的方式使用模式。 當(dāng)您使用pattern進(jìn)行繪制時(shí)怀估,Quartz將頁面劃分為一組pattern單元格狮鸭,每個(gè)單元格都是圖案pattern圖像的大小,并使用您提供的回調(diào)繪制每個(gè)單元格多搀。 圖6-1顯示了繪制到窗口圖形上下文的pattern歧蕉。

Figure 6-1 A pattern drawn to a window

The Anatomy of a Pattern - 圖案的剖析

模式pattern單元是模式的基本組件。 圖6-1中所示模式的模式單元如圖6-2所示康铭。 黑色矩形不是圖案的一部分廊谓,它被繪制以顯示模式單元格的結(jié)束位置。

Figure 6-2 A pattern cell

該特定圖案單元的大小包括四個(gè)彩色矩形的區(qū)域以及矩形上方和右側(cè)的空間麻削,如圖6-3所示蒸痹。 圖中每個(gè)圖案單元周圍的黑色矩形不是單元的一部分; 它被繪制以指示單元的邊界。 創(chuàng)建模式單元格時(shí)呛哟,可以定義單元格的邊界并在邊界內(nèi)繪制叠荠。

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

您可以指定Quartz在水平和垂直方向上繪制每個(gè)圖案單元的起點(diǎn)與下一個(gè)圖案單元的距離。 繪制圖6-3中的圖案單元扫责,使得一個(gè)圖案單元的開始正好是與下一個(gè)圖案單元分開的圖案寬度榛鼎,導(dǎo)致每個(gè)圖案單元在下一個(gè)圖案單元上鄰接。 圖6-4中的圖案單元在水平和垂直兩個(gè)方向上都添加了空間鳖孤。 您可以為每個(gè)方向指定不同的間距值者娱。 如果使間距小于圖案單元格的寬度或高度,則圖案單元格會(huì)重疊苏揣。

Figure 6-4 Spacing between pattern cells

繪制圖案單元格時(shí)黄鳍,Quartz使用模式空間(pattern space)作為坐標(biāo)系。(pattern space)是一個(gè)抽象空間平匈,它通過您在創(chuàng)建模式時(shí)指定的變換矩陣(模式矩陣)映射到默認(rèn)用戶空間框沟。

注意:模式空間(pattern space)與用戶空間分開。無論當(dāng)前轉(zhuǎn)換矩陣的狀態(tài)如何增炭,未轉(zhuǎn)換的模式空間都映射到基本(未轉(zhuǎn)換的)用戶空間忍燥。將變換應(yīng)用于模式空間時(shí),Quartz僅將變換應(yīng)用于模式空間隙姿。模式坐標(biāo)系的默認(rèn)約定是底層圖形上下文的約定梅垄。默認(rèn)情況下,Quartz使用坐標(biāo)系输玷,其中正x值表示向右的位移队丝,正y值表示向上位移。但是饲嗽,UIKit創(chuàng)建的圖形上下文使用不同的約定炭玫,其中正y值表示向下位移。雖然此約定通常通過將變換連接到坐標(biāo)系統(tǒng)來應(yīng)用于圖形上下文貌虾,但在這種情況下吞加,Quartz還會(huì)修改模式空間的默認(rèn)約定以進(jìn)行匹配。

如果您不希望Quartz轉(zhuǎn)換模式單元格尽狠,則可以指定單位矩陣衔憨。但是,您可以通過提供轉(zhuǎn)換矩陣來實(shí)現(xiàn)有趣的效果袄膏。圖6-5顯示了縮放圖6-2中所示的模式單元的效果践图。圖6-6演示了旋轉(zhuǎn)模式單元。轉(zhuǎn)換模式單元有點(diǎn)微妙沉馆。圖6-7顯示了圖案的原點(diǎn)码党,圖案單元在水平和垂直兩個(gè)方向上平移德崭,因此圖案不再像圖6-1那樣鄰接窗口。

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

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

彩色圖案(Colored patterns)具有與之相關(guān)的固有顏色揖盘。 更改用于創(chuàng)建模式單元格的顏色眉厨,模式失去其含義。 蘇格蘭格子(如圖6-8中所示的樣本)是彩色圖案的一個(gè)例子兽狭。 彩色圖案中的顏色被指定為圖案單元格創(chuàng)建過程的一部分憾股,而不是圖案繪制過程的一部分。

Figure 6-8 A colored pattern has inherent color

其他圖案僅根據(jù)其形狀定義箕慧,因此可以被認(rèn)為是模板圖案(stencil patterns)服球,無色圖案,甚至是圖像蒙版颠焦。 圖6-9中顯示的紅色和黑色星是每個(gè)相同模式單元的再現(xiàn)斩熊。 單元本身由一個(gè)形狀 - 一個(gè)填充的星星組成。 定義圖案單元格時(shí)蒸健,沒有顏色與之相關(guān)聯(lián)座享。 顏色被指定為圖案繪制過程的一部分,而不是圖像單元?jiǎng)?chuàng)建的一部分似忧。

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

您可以在Quartz 2D中創(chuàng)建任何一種圖案(colored or stencil)渣叛。


Tiling - 平鋪

平鋪是將圖案單元格(pattern cell)渲染到頁面的一部分的過程。 當(dāng)Quartz向設(shè)備呈現(xiàn)模式(pattern)時(shí)盯捌,Quartz可能需要調(diào)整模式以適應(yīng)設(shè)備空間淳衙。 也就是說,由于用戶空間單元和設(shè)備像素之間的差異,在用戶空間中定義的模式單元在渲染到設(shè)備時(shí)可能不完美。

Quartz有三個(gè)平鋪選項(xiàng)杰妓,可用于在必要時(shí)調(diào)整模式秒咨。 Quartz可以保存:

  • 該模式以犧牲圖案單元之間的間距為代價(jià)松蒜,但不超過一個(gè)設(shè)備像素。 這被稱為無失真(no distortion)
  • 單元之間的間隔,代價(jià)是略微扭曲圖案單元梢睛,但不超過一個(gè)設(shè)備像素。 這被稱為具有最小失真的恒定間隔(constant spacing with minimal distortion)识椰。
  • 單元之間的間隔(對于最小失真選項(xiàng))绝葡,代價(jià)是扭曲模式單元,以達(dá)到快速平鋪所需的程度腹鹉。 這被稱為恒定間距(constant spacing)藏畅。

How Patterns Work - Patterns工作原理

圖案的操作與顏色類似,因?yàn)槟O(shè)置了填充或描邊圖案功咒,然后調(diào)用繪畫函數(shù)愉阎。 Quartz使用您設(shè)置為“paint”的模式绞蹦。例如,如果要繪制帶有純色的填充矩形榜旦,則首先調(diào)用函數(shù)(如CGContextSetFillColor)來設(shè)置填充顏色坦辟。然后調(diào)用函數(shù)CGContextFillRect以使用指定的顏色繪制填充的矩形。要使用模式繪制章办,首先調(diào)用函數(shù)CGContextSetFillPattern來設(shè)置模式。然后調(diào)用CGContextFillRect實(shí)際使用指定的模式繪制填充的矩形滨彻。繪畫與顏色和圖案之間的區(qū)別在于您必須定義pattern藕届。您將pattern和顏色信息提供給函數(shù)CGContextSetFillPattern。您將看到如何在Painting Colored PatternsPainting Stencil Patterns中創(chuàng)建亭饵,設(shè)置和繪制pattern休偶。

下面是Quartz如何在幕后工作以使用您提供的模式進(jìn)行繪制的示例。當(dāng)您使用模式填充或描邊時(shí)辜羊,Quartz在概念上執(zhí)行以下任務(wù)來繪制每個(gè)模式單元格:

  • 保存圖形狀態(tài)踏兜。
  • 將當(dāng)前變換矩陣轉(zhuǎn)換為模式單元的原點(diǎn)。
  • 將CTM與模式矩陣連接在一起八秃。
  • 剪輯到模式單元格的邊界矩形碱妆。
  • 調(diào)用繪圖回調(diào)來繪制模式單元格。
  • 恢復(fù)圖形狀態(tài)昔驱。

Quartz為您處理所有平鋪疹尾,重復(fù)將圖案單元格渲染到繪圖空間,直到繪制整個(gè)空間骤肛。您可以使用圖案填充或描邊纳本。模式單元格可以是您指定的任何大小。如果要查看圖案腋颠,則應(yīng)確保圖案單元格適合繪圖空間繁成。例如,如果您的圖案單元格為8個(gè)單位乘以10個(gè)單位淑玫,并且您使用該圖案來描繪寬度為2個(gè)單位的線條巾腕,則圖案單元格將被裁剪,因?yàn)樗?0個(gè)單位寬度混移。在這種情況下祠墅,您可能無法識(shí)別該模式。


Painting Colored Patterns - 繪畫彩色圖案

以下各節(jié)介紹了繪制彩色圖案所需執(zhí)行的五個(gè)步驟:

這些步驟與用于繪制模板圖案的步驟相同歌径。 兩者之間的區(qū)別在于您如何設(shè)置顏色信息毁嗦。 您可以在A Complete Colored Pattern Painting Function中查看所有步驟如何組合在一起。

1. Write a Callback Function That Draws a Colored Pattern Cell - 編寫繪制彩色圖案單元格的回調(diào)函數(shù)

模式單元格看起來怎么樣完全取決于您回铛。 對于此示例狗准,Listing 6-1中的代碼繪制了圖6-2中所示的模式單元克锣。 回想一下,模式單元周圍的黑線不是單元的一部分腔长,它的繪制表明模式單元格的邊界大于代碼繪制的矩形袭祟。 您稍后將模式大小指定為Quartz。

您的模式單元格繪制函數(shù)是一個(gè)遵循此形式的回調(diào):

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

你可以隨意命名你的回調(diào)捞附。Listing 6-1中的名為MyDrawColoredPattern巾乳。回調(diào)有兩個(gè)參數(shù):

  • info鸟召,指向與pattern關(guān)聯(lián)的私有數(shù)據(jù)的通用指針胆绊。此參數(shù)是可選的;你可以傳遞NULL欧募。傳遞給回調(diào)的數(shù)據(jù)與您稍后在創(chuàng)建模式時(shí)提供的數(shù)據(jù)相同压状。
  • context,用于繪制模式單元格的圖形上下文跟继。

Listing 6-1中的代碼繪制的模式單元格是任意的种冬。您的代碼會(huì)繪制適合您創(chuàng)建的模式的任何內(nèi)容。有關(guān)代碼的這些詳細(xì)信息非常重要:

  • 聲明了pattern size舔糖。在編寫繪圖代碼時(shí)娱两,需要牢記圖案尺寸。這里剩盒,大小被聲明為全局谷婆。除評論外,繪圖函數(shù)不具體指代大小辽聊。稍后纪挎,您將圖案大小指定為Quartz 2D。請參閱Set Up the Anatomy of the Colored Pattern跟匆。
  • 繪圖函數(shù)遵循由CGPatternDrawPatternCallback回調(diào)類型定義定義的原型异袄。
  • 在代碼中執(zhí)行的繪圖設(shè)置顏色,這使其成為彩色圖案玛臂。
// 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 - 設(shè)置彩色圖案顏色空間

Listing 6-1中的代碼使用顏色繪制圖案單元格烤蜕。 您必須通過將基本模式顏色空間設(shè)置為NULL來確保Quartz使用您在繪圖例程中使用的顏色進(jìn)行繪制,如Listing 6-2所示迹冤。 列表后面的每個(gè)編號行代碼有詳細(xì)說明讽营。

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

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

這是代碼的作用:

  • 1)通過調(diào)用函數(shù)CGColorSpaceCreatePattern創(chuàng)建適合彩色圖案的圖案顏色空間,將NULL作為基色空間傳遞泡徙。
  • 2)將填充顏色空間設(shè)置為圖案顏色空間橱鹏。 如果您正在stroke圖案,請調(diào)用CGContextSetStrokeColorSpace
  • 3)釋放圖案顏色空間莉兰。

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

有關(guān)anatomy of a pattern的信息保存在CGPattern對象中挑围。 您可以通過調(diào)用函數(shù)CGPatternCreate來創(chuàng)建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參數(shù)是指向要傳遞給繪圖回調(diào)的數(shù)據(jù)的指針杉辙。這是 Write a Callback Function That Draws a Colored Pattern Cell中討論的相同指針。

您可以在bounds參數(shù)中指定圖案單元格的大小size捶朵。matrix參數(shù)指定圖案矩陣蜘矢,它將圖案坐標(biāo)系映射到圖形上下文的默認(rèn)坐標(biāo)系。如果要使用與圖形上下文相同的坐標(biāo)系繪制圖案综看,請使用單位矩陣硼端。 xStepyStep參數(shù)指定圖案坐標(biāo)系中單元格之間的水平和垂直間距。請參閱The Anatomy of a Pattern以查看有關(guān)邊界寓搬,圖案矩陣和間距的信息。

tiling參數(shù)可以是以下三個(gè)值之一:

  • kCGPatternTilingNoDistortion
  • kCGPatternTilingConstantSpacingMinimalDistortion
  • kCGPatternTilingConstantSpacing

請參閱Tiling以查看有關(guān)平鋪的信息县耽。

isColored參數(shù)指定圖案單元格是彩色圖案(true)還是模板圖案(false)句喷。如果在此處傳遞true,則繪圖圖案回調(diào)指定圖案顏色兔毙,并且必須將圖案顏色空間設(shè)置為彩色圖案顏色空間(請參閱Set Up the Colored Pattern Color Space)唾琼。

傳遞給函數(shù)CGPatternCreate的最后一個(gè)參數(shù)是指向CGPatternCallbacks數(shù)據(jù)結(jié)構(gòu)的指針。這個(gè)結(jié)構(gòu)有三個(gè)字段:

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

version字段設(shè)置為0澎剥。drawPattern字段是指向繪圖回調(diào)的指針锡溯。 releaseInfo字段是指向釋放CGPattern對象時(shí)調(diào)用的回調(diào)的指針,用于釋放傳遞給繪圖回調(diào)的info參數(shù)的存儲(chǔ)哑姚。 如果未在此參數(shù)中傳遞任何數(shù)據(jù)祭饭,則將此字段設(shè)置為NULL

4. Specify the Colored Pattern as a Fill or Stroke Pattern - 將彩色圖案指定為填充或描邊圖案

您可以通過調(diào)用相應(yīng)的函數(shù)CGContextSetFillPatternCGContextSetStrokePattern來使用您的圖案進(jìn)行填充或描邊叙量。 Quartz使用您的模式進(jìn)行任何后續(xù)填充或描邊倡蝙。

這些函數(shù)各有三個(gè)參數(shù):

  • 圖形上下文
  • 您之前創(chuàng)建的CGPattern對象
  • 一系列顏色組件

盡管彩色圖案提供了自己的顏色,但您必須傳遞單個(gè)Alpha值以通知Quartz繪制時(shí)圖案的整體不透明度绞佩。 Alpha可以從1(完全不透明)到0(完全透明)變化寺鸥。 這些代碼行顯示了如何為用于填充的彩色圖案設(shè)置不透明度的示例。

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

5. Draw With the Colored Pattern - 用彩色圖案繪制

完成上述步驟后品山,您可以調(diào)用任何繪制的Quartz 2D函數(shù)胆建。 您的圖案用作“paint”。例如肘交,您可以調(diào)用CGContextStrokePath笆载,CGContextFillPathCGContextFillRect或任何其他繪制函數(shù)。

6. A Complete Colored Pattern Painting Function - 一個(gè)完整的彩色圖案繪畫函數(shù)

Listing 6-4中的代碼包含一個(gè)繪制彩色圖案的函數(shù)宰译。 該函數(shù)包含了前面討論的所有步驟檐蚜。 列表后面有每個(gè)編號行代碼的詳細(xì)說明。

// 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)聲明稍后創(chuàng)建的CGPattern對象的存儲(chǔ)沿侈。
  • 2)聲明稍后創(chuàng)建的圖像顏色空間的存儲(chǔ)闯第。
  • 3)聲明alpha的變量并將其設(shè)置為1,它將模式的不透明度指定為完全不透明缀拭。
  • 4)聲明變量以保持窗口的高度和寬度咳短。在此示例中,圖案繪制在窗口區(qū)域上蛛淋。
  • 5)聲明并填充回調(diào)結(jié)構(gòu)咙好,將0作為版本傳遞,并將指針傳遞給繪圖回調(diào)函數(shù)褐荷。此示例未提供釋放信息回調(diào)勾效,因此該字段設(shè)置為NULL
  • 6)創(chuàng)建圖案顏色空間對象叛甫,將圖案的基色空間設(shè)置為NULL层宫。繪制彩色圖案時(shí),圖案在圖形回調(diào)中提供自己的顏色其监,這就是您將顏色空間設(shè)置為NULL的原因萌腿。
  • 7)將填充顏色空間設(shè)置為剛剛創(chuàng)建的圖案顏色空間對象。
  • 8)釋放圖案顏色空間對象抖苦。
  • 9)傳遞NULL毁菱,因?yàn)閳D案不需要傳遞給繪圖回調(diào)的任何其他信息。
  • 10)傳遞一個(gè)CGRect對象锌历,該對象指定圖案單元格的邊界贮庞。
  • 11)傳遞CGAffineTransform矩陣,該矩陣指定如何將圖案空間轉(zhuǎn)換為使用圖案的上下文的默認(rèn)用戶空間究西。此示例傳遞單位矩陣贸伐。
  • 12)將水平圖案大小作為每個(gè)單元格開頭之間的水平位移。在此示例中怔揩,一個(gè)單元格與下一個(gè)單元格相鄰捉邢。
  • 13)將垂直圖案大小作為每個(gè)單元格開始之間的垂直位移。
  • 14)傳遞常量kCGPatternTilingConstantSpacing以指定Quartz應(yīng)如何呈現(xiàn)圖案商膊。有關(guān)更多信息伏伐,請參閱Tiling
  • 15)對isColored參數(shù)傳遞true晕拆,以指定圖案為彩色圖案藐翎。
  • 16)傳遞指向包含版本信息的回調(diào)結(jié)構(gòu)的指針材蹬,以及指向繪圖回調(diào)函數(shù)的指針。
  • 17)設(shè)置填充模式吝镣,傳遞上下文堤器,剛剛創(chuàng)建的CGPattern對象,以及指向Alpha值的指針末贾,該值指定Quartz應(yīng)用于模式的不透明度闸溃。
  • 18)釋放CGPattern對象。
  • 19)填充一個(gè)矩形拱撵,該矩形是傳遞給MyColoredPatternPainting例程的窗口大小辉川。Quartz使用您剛剛設(shè)置的圖案填充矩形。

Painting Stencil Patterns - 繪制模板圖案

以下各節(jié)介紹了繪制模板圖案所需執(zhí)行的五個(gè)步驟:

這些實(shí)際上與您用于繪制彩色圖案的步驟相同拴测。 兩者之間的區(qū)別在于您如何設(shè)置顏色信息乓旗。 您可以在A Complete Stencil Pattern Painting Function中查看所有步驟如何組合在一起。

1. Write a Callback Function That Draws a Stencil Pattern Cell - 編寫一個(gè)繪制模板模式單元的回調(diào)函數(shù)

您為繪制模板圖案而編寫的回調(diào)遵循與彩色圖案單元格所描述的相同的形式集索。 請參閱 Write a Callback Function That Draws a Colored Pattern Cell屿愚。 唯一的區(qū)別是您的繪圖回調(diào)沒有指定任何顏色。 圖6-10中顯示的圖案單元格沒有從圖形回調(diào)中獲得顏色务荆。 顏色設(shè)置在圖案顏色空間中的繪圖顏色之外渺鹦。

Figure 6-10 A stencil pattern cell

看一下Listing 6-5中的代碼,它繪制了圖6-10中所示的模式單元蛹含。 請注意,代碼只是創(chuàng)建一個(gè)路徑并填充路徑塞颁。 代碼沒有設(shè)置顏色浦箱。

// 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 - 設(shè)置模板圖案顏色空間

模板圖案要求您為Quartz設(shè)置圖案顏色空間以進(jìn)行繪制,如Listing 6-6所示祠锣。 列表后面的每個(gè)編號行代碼的詳細(xì)說明酷窥。

// 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) 此函數(shù)創(chuàng)建一個(gè)通用RGB空間。 通用顏色空間使顏色與系統(tǒng)匹配伴网。 有關(guān)更多信息蓬推,請參閱 Creating Generic Color Spaces
  • 2) 創(chuàng)建圖案顏色空間澡腾。 您提供的顏色空間指定了如何為圖案表示顏色沸伏。 稍后,當(dāng)您為圖案設(shè)置顏色時(shí)动分,必須使用圖案顏色空間設(shè)置它們毅糟。 對于此示例,您需要使用RGB值指定顏色澜公。
  • 3) 設(shè)置填充圖案時(shí)要使用的顏色空間姆另。 您可以通過調(diào)用CGContextSetStrokeColorSpace函數(shù)來設(shè)置描邊顏色空間。
  • 4) 釋放圖案顏色空間對象。
  • 5) 釋放基色空間對象迹辐。

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

Stencil patterns要求您為Quartz設(shè)置圖案顏色空間以進(jìn)行繪制蝶防,如Listing 6-6所示。 列表后面的每個(gè)編號行代碼的詳細(xì)說明明吩。

// 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) 此函數(shù)創(chuàng)建一個(gè)通用RGB空間间学。 通用顏色空間使顏色與系統(tǒng)匹配。 有關(guān)更多信息贺喝,請參閱Creating Generic Color Spaces菱鸥。
  • 2) 創(chuàng)建圖案顏色空間。 您提供的顏色空間指定了如何為圖案表示顏色躏鱼。 稍后氮采,當(dāng)您為圖案設(shè)置顏色時(shí),必須使用圖案顏色空間設(shè)置它們染苛。 對于此示例鹊漠,您需要使用RGB值指定顏色。
  • 3) 設(shè)置填充圖案時(shí)要使用的顏色空間茶行。 您可以通過調(diào)用CGContextSetStrokeColorSpace函數(shù)來設(shè)置描邊顏色空間躯概。
  • 4) 釋放圖案顏色空間對象。
  • 5) 釋放基色空間對象畔师。

4. Specify the Stencil Pattern as a Fill or Stroke Pattern - 將模板圖案指定為填充或描邊圖案

您可以通過調(diào)用相應(yīng)的函數(shù)CGContextSetFillPatternCGContextSetStrokePattern來使用您的模式進(jìn)行填充或描邊娶靡。 Quartz使用您的模式進(jìn)行任何后續(xù)填充或描邊。

這些函數(shù)各有三個(gè)參數(shù):

  • 1) 圖形上下文
  • 2) 您之前創(chuàng)建的CGPattern對象
  • 3) 一系列顏色組件

模板圖案不會(huì)在圖形回調(diào)中提供顏色看锉,因此您必須將顏色傳遞給填充或描邊函數(shù)以通知Quartz要使用的顏色姿锭。 Listing 6-7顯示了如何為模板圖案設(shè)置顏色的示例。 顏色數(shù)組中的值由Quartz在您之前設(shè)置的顏色空間中解釋伯铣。 由于此示例使用設(shè)備RGB呻此,因此顏色數(shù)組包含紅色,綠色和藍(lán)色組件的值腔寡。 第四個(gè)值指定顏色的不透明度焚鲜。

// 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 - 用模具圖案繪圖

完成上述步驟后,您可以調(diào)用任何繪制的Quartz 2D函數(shù)放前。 您的模式用作“paint”忿磅。例如,您可以調(diào)用CGContextStrokePath凭语,CGContextFillPath贝乎,CGContextFillRect或任何其他繪制函數(shù)。

6. A Complete Stencil Pattern Painting Function - 完整的模板圖案繪畫功能

Listing 6-8中的代碼包含一個(gè)繪制模板圖案的函數(shù)叽粹。 該功能包含了前面討論的所有步驟览效。 列表后面列出了每個(gè)編號行代碼的詳細(xì)說明却舀。

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) 聲明一個(gè)數(shù)組以保存顏色值并將值(將在RGB顏色空間中)設(shè)置為不透明綠色。
  • 2) 聲明并填充回調(diào)結(jié)構(gòu)锤灿,將0作為版本傳遞挽拔,并將指針傳遞給繪圖回調(diào)函數(shù)。此示例未提供發(fā)布信息回調(diào)但校,因此該字段設(shè)置為NULL螃诅。
  • 3) 創(chuàng)建RGB設(shè)備顏色空間。如果將圖案繪制到顯示器状囱,則需要提供此類型的色彩空間术裸。
  • 4) 從RGB設(shè)備顏色空間創(chuàng)建圖案顏色空間對象。
  • 5) 將填充顏色空間設(shè)置為剛剛創(chuàng)建的圖案顏色空間對象亭枷。
  • 6) 創(chuàng)建一個(gè)圖案對象袭艺。請注意,倒數(shù)第二個(gè)參數(shù) - isColored參數(shù) - 為false叨粘。模板圖案不提供顏色猾编,因此您必須為此參數(shù)傳遞false。所有其他參數(shù)類似于為彩色圖案示例傳遞的參數(shù)升敲。請參閱A Complete Colored Pattern Painting Function答倡。
  • 7) 設(shè)置填充圖案,傳遞先前聲明的顏色數(shù)組驴党。
  • 8) 釋放CGPattern對象瘪撇。
  • 9) 填充矩形。 Quartz使用您剛剛設(shè)置的圖案填充矩形港庄。

后記

本篇主要講述了Patterns圖案樣式倔既,感興趣的給個(gè)贊或者關(guān)注~~~

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市攘轩,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌码俩,老刑警劉巖度帮,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異稿存,居然都是意外死亡笨篷,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進(jìn)店門瓣履,熙熙樓的掌柜王于貴愁眉苦臉地迎上來率翅,“玉大人,你說我怎么就攤上這事袖迎∶岢簦” “怎么了腺晾?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長辜贵。 經(jīng)常有香客問我悯蝉,道長,這世上最難降的妖魔是什么托慨? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任鼻由,我火速辦了婚禮,結(jié)果婚禮上厚棵,老公的妹妹穿的比我還像新娘蕉世。我一直安慰自己,他們只是感情好婆硬,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布狠轻。 她就那樣靜靜地躺著,像睡著了一般柿祈。 火紅的嫁衣襯著肌膚如雪哈误。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天躏嚎,我揣著相機(jī)與錄音蜜自,去河邊找鬼。 笑死卢佣,一個(gè)胖子當(dāng)著我的面吹牛重荠,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播虚茶,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼戈鲁,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了嘹叫?” 一聲冷哼從身側(cè)響起婆殿,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎罩扇,沒想到半個(gè)月后婆芦,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡喂饥,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年消约,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片员帮。...
    茶點(diǎn)故事閱讀 39,785評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡或粮,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出捞高,到底是詐尸還是另有隱情氯材,我是刑警寧澤渣锦,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站浓体,受9級特大地震影響泡挺,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜命浴,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一娄猫、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧生闲,春花似錦媳溺、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至捉兴,卻和暖如春蝎困,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背倍啥。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工禾乘, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人虽缕。 一個(gè)月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓始藕,卻偏偏與公主長得像,于是被迫代替她去往敵國和親氮趋。 傳聞我的和親對象是個(gè)殘疾皇子伍派,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評論 2 354

推薦閱讀更多精彩內(nèi)容