Paths
path定義了一個或多個形狀或子路徑。子路徑可以由直線、曲線或兩者組成。它可以是打開的路徑可以是關(guān)閉的路徑。子路可以是簡單的形狀,如直線、圓形、矩形或星形,也可以是更復(fù)雜的形狀,如山脈的輪廓或抽象的涂鴉。圖3-1顯示了可以創(chuàng)建的一些路徑。直線(在圖的左上角)被虛線;線條也可以是實(shí)心的。彎彎曲曲的路徑(在中間的頂部)由幾條曲線組成,是一條開放的路徑。同心圓被填滿,但沒有被填充。加州地圖(在左下角)是一條封閉的路徑,由許多曲線和線條組成,路徑被繪制和填充。星形圖展示了兩種填充路徑的選項(xiàng),您將在本章后面讀到。

在本章中,您將了解組成路徑的構(gòu)建塊,如何描邊和繪制路徑,以及影響路徑外觀的參數(shù)。
路徑創(chuàng)建和路徑繪制
路徑創(chuàng)建和路徑繪制是獨(dú)立的任務(wù)。首先創(chuàng)建一條路徑。當(dāng)您想要呈現(xiàn)一個路徑時(shí),您需要請求Quartz來繪制它。如圖3-1所示,您可以選擇描邊路徑,填充路徑,或者同時(shí)描邊和填充。您還可以使用路徑將其他對象的繪制限制在創(chuàng)建剪切區(qū)域的路徑范圍內(nèi)。
圖3-2顯示了已繪制的路徑,其中包含兩個子路徑。左邊的子路徑是矩形,右邊的子路徑是由直線和曲線組成的抽象形狀。圖中每個子路徑都被填充,它的輪廓被描邊。
Figure 3-2 A path that contains two shapes, or subpaths

圖3-3顯示了獨(dú)立繪制的多條路徑。每個路徑都包含一個隨機(jī)生成的曲線,其中一些曲線被填充,另一些則被繪制。繪圖被一個裁剪區(qū)域限制在一個圓形區(qū)域。
Figure 3-3 A clipping area constrains drawing

The Building Blocks
子路徑由直線、弧線和曲線構(gòu)成。Quartz還提供了方便的函數(shù),可以通過一個函數(shù)調(diào)用來添加矩形和橢圓。點(diǎn)也是路徑的基本構(gòu)建塊,因?yàn)辄c(diǎn)定義了形狀的起始和結(jié)束位置。
Points
點(diǎn)是在用戶空間中指定位置的x和y坐標(biāo)。您可以調(diào)用函數(shù)CGContextMoveToPoint來為新子路徑指定起始位置。Quartz跟蹤當(dāng)前點(diǎn),這是用于路徑構(gòu)建的最后一個位置。例如,如果您調(diào)用函數(shù)CGContextMoveToPoint來設(shè)置一個位置(10,10),那么將當(dāng)前點(diǎn)移動到(10,10)。如果你畫一條長50單位的水平線,這條線上的最后一點(diǎn),也就是(60,10),變成了現(xiàn)在的點(diǎn)。線、弧和曲線總是從當(dāng)前點(diǎn)開始畫。
大多數(shù)情況下,通過將兩個浮點(diǎn)值傳遞給Quartz函數(shù)來指定一個點(diǎn)來指定x和y坐標(biāo)。有些函數(shù)需要傳遞一個CGPoint數(shù)據(jù)結(jié)構(gòu),該結(jié)構(gòu)包含兩個浮點(diǎn)值。
Lines
直線由其端點(diǎn)定義。它的起點(diǎn)總是假設(shè)為當(dāng)前點(diǎn),所以當(dāng)創(chuàng)建一行時(shí),只指定它的端點(diǎn)。使用CGContextAddLineToPoint函數(shù)向子路徑追加一行代碼。
通過調(diào)用CGContextAddLines函數(shù),可以將一系列連接的行添加到路徑中。你給這個函數(shù)傳遞一個點(diǎn)數(shù)組。第一個點(diǎn)必須是第一行的起點(diǎn);剩下的點(diǎn)是端點(diǎn)。Quartz從第一個點(diǎn)開始一個新的子路徑,并將直線段連接到每個端點(diǎn)。
Arcs
圓弧。Quartz提供兩個創(chuàng)建弧的功能。函數(shù)CGContextAddArc創(chuàng)建了一個圓形的曲線段。指定圓的中心、半徑和徑向角度(以弧度表示)。你可以通過指定一個2的徑向角度來創(chuàng)建一個完整的圓。圖3-4顯示了獨(dú)立繪制的多條路徑。每個路徑包含一個隨機(jī)生成的圓;有的被填滿,有的被繪制。
Figure 3-4 Multiple paths; each path contains a randomly generated circle

CGContextAddArcToPoint函數(shù)是理想的用于圓角矩形的函數(shù)。Quartz使用您提供的端點(diǎn)創(chuàng)建兩條切線。您還可以提供Quartz切割弧的圓的半徑。圓弧的中心點(diǎn)是兩個半徑的交點(diǎn),每個半徑都垂直于兩條切線中的一條。圓弧的每個端點(diǎn)是其中一條切線上的一個切線點(diǎn),如圖3-5所示。圓圈的紅色部分是實(shí)際畫出來的。
Figure 3-5 Defining an arc with two tangent lines and a radius

如果當(dāng)前路徑已經(jīng)包含子路徑,則Quartz會將一條從當(dāng)前點(diǎn)到弧的起始點(diǎn)的直線段追加進(jìn)來。如果當(dāng)前路徑為空,Quartz將在弧線的起始點(diǎn)創(chuàng)建一個新的子路徑,而不添加初始的直線段。
Curves
二次曲線和三次貝塞爾曲線是可以指定任意數(shù)量的有趣曲線形狀的代數(shù)曲線。這些曲線上的點(diǎn)是通過對起始點(diǎn)和結(jié)束點(diǎn)以及一個或多個控制點(diǎn)應(yīng)用多項(xiàng)式公式計(jì)算出來的。以這種方式定義的形狀是向量圖形的基礎(chǔ)。公式比位數(shù)組存儲要緊湊得多,而且它的優(yōu)點(diǎn)是可以在任何分辨率下重新創(chuàng)建曲線。
圖3-6顯示了通過獨(dú)立繪制多條路徑創(chuàng)建的各種曲線。每個路徑包含一個隨機(jī)生成的曲線;有的被填滿,有的被繪制。
Figure 3-6 Multiple paths; each path contains a randomly generated curve

在許多描述計(jì)算機(jī)圖形學(xué)的數(shù)學(xué)文本和在線資料中,討論了多項(xiàng)式公式產(chǎn)生二次曲線和三次貝塞爾曲線的公式,以及如何從公式中生成曲線的細(xì)節(jié)。這里不討論這些細(xì)節(jié)。
使用CGContextAddCurveToPoint函數(shù)從當(dāng)前點(diǎn)附加一個立方貝塞爾曲線,使用控制點(diǎn)和指定的端點(diǎn)。圖3-7顯示了由圖中所示的當(dāng)前點(diǎn)、控制點(diǎn)和端點(diǎn)產(chǎn)生的立方貝塞爾曲線。兩個控制點(diǎn)的位置決定了曲線的幾何形狀。如果控制點(diǎn)同時(shí)高于起點(diǎn)和終點(diǎn),曲線向上拱起。如果控制點(diǎn)同時(shí)低于起點(diǎn)和終點(diǎn),曲線會向下彎曲。
Figure 3-7 A cubic Bézier curve uses two control points

通過調(diào)用函數(shù)CGContextAddQuadCurveToPoint并指定控制點(diǎn)和端點(diǎn),可以從當(dāng)前點(diǎn)追加一個二次貝塞爾曲線。圖3-8顯示了使用相同端點(diǎn)但控制點(diǎn)不同的兩條曲線??刂泣c(diǎn)決定曲線拱起的方向。用二次貝塞爾曲線創(chuàng)造出盡可能多有趣的形狀是不可能的因?yàn)槎吻€只用一個控制點(diǎn)。例如,不可能創(chuàng)建一個交叉使用單一控制點(diǎn)。
Figure 3-8 A quadratic Bézier curve uses one control point

Closing a Subpath
要關(guān)閉當(dāng)前的子路徑,應(yīng)用程序應(yīng)該調(diào)用CGContextClosePath。該函數(shù)將從當(dāng)前點(diǎn)到子路徑起點(diǎn)的線段添加到子路徑,并關(guān)閉子路徑。在子路徑的起始點(diǎn)結(jié)束的線、弧和曲線實(shí)際上并不關(guān)閉子路徑。必須顯式調(diào)用CGContextClosePath來關(guān)閉子路徑。
有些Quartz函數(shù)將路徑的子路徑視為由應(yīng)用程序關(guān)閉的。這些命令將每個子路徑視為應(yīng)用程序調(diào)用CGContextClosePath來關(guān)閉它,隱式地在子路徑的起始點(diǎn)添加一條線段。
在關(guān)閉子路徑之后,如果應(yīng)用程序發(fā)出額外的調(diào)用,向路徑添加線條、弧線或曲線,Quartz將從剛剛關(guān)閉的子路徑的起點(diǎn)開始新的子路徑。
Ellipses
橢圓實(shí)質(zhì)上是一個被壓扁的圓。你通過定義兩個焦點(diǎn)來創(chuàng)建一個點(diǎn)然后畫出所有在一定距離上的點(diǎn)使橢圓上的任何點(diǎn)到一個焦點(diǎn)的距離加上從同一點(diǎn)到另一個焦點(diǎn)的距離總是相同的值。圖3-9顯示了獨(dú)立繪制的多條路徑。每個路徑包含一個隨機(jī)生成的橢圓;有的被填滿,有的被繪制。
Figure 3-9 Multiple paths; each path contains a randomly generated ellipse

您可以通過調(diào)用CGContextAddEllipseInRect函數(shù)向當(dāng)前路徑添加一個橢圓。您提供了一個定義橢圓邊界的矩形。Quartz使用一系列貝塞爾曲線來近似橢圓。橢圓的中心是矩形的中心。如果矩形的寬度和高度相等(即為正方形),則橢圓為圓形,其半徑等于矩形寬度(或高度)的一半。如果矩形的寬度和高度不相等,則定義橢圓的主軸和小軸。
添加到路徑上的橢圓從移動到操作開始,到關(guān)閉子路徑操作結(jié)束,所有的移動都是順時(shí)針方向。
Rectangles
您可以通過調(diào)用CGContextAddRect函數(shù)向當(dāng)前路徑添加一個矩形。您提供了一個CGRect結(jié)構(gòu),該結(jié)構(gòu)包含矩形的原點(diǎn)及其寬度和高度。
添加到路徑的矩形以移動到操作開始,以關(guān)閉子路徑操作結(jié)束,所有的移動都以逆時(shí)針方向進(jìn)行。
通過調(diào)用函數(shù)CGContextAddRects并提供CGRect結(jié)構(gòu)數(shù)組,可以向當(dāng)前路徑添加許多矩形。圖3-10顯示了獨(dú)立繪制的多條路徑。每個路徑包含一個隨機(jī)生成的矩形;有的被填滿,有的被繪制。
Figure 3-10 Multiple paths; each path contains a randomly generated rectangle

Creating a Path
當(dāng)您想在圖形上下文中構(gòu)造一個路徑時(shí),您可以通過調(diào)用CGContextBeginPath函數(shù)來給Quartz信號。接下來,通過調(diào)用CGContextMoveToPoint函數(shù),為路徑中的第一個形狀或子路徑設(shè)置起點(diǎn)。在建立第一個點(diǎn)之后,可以在路徑中添加直線、弧線和曲線,記住以下幾點(diǎn):
1、在開始新路徑之前,調(diào)用函數(shù)CGContextBeginPath。
2、從當(dāng)前點(diǎn)開始畫線、弧和曲線??章窂?jīng)]有當(dāng)前點(diǎn);您必須調(diào)用3、CGContextMoveToPoint來設(shè)置第一個子路徑的起始點(diǎn),或者調(diào)用一個隱式執(zhí)行此操作的便利函數(shù)。
4、當(dāng)您想在路徑中關(guān)閉當(dāng)前子路徑時(shí),調(diào)用函數(shù)CGContextClosePath來將一個段連接到子路徑的起始點(diǎn)。后續(xù)路徑調(diào)用開始一個新的子路徑,即使您沒有顯式地設(shè)置一個新的起點(diǎn)。
5、在繪制弧時(shí),Quartz在當(dāng)前點(diǎn)和弧的起始點(diǎn)之間劃一條線。
添加橢圓和矩形的石英例程向路徑添加一個新的封閉子路徑。
6、您必須調(diào)用繪制函數(shù)來填充或描邊路徑,因?yàn)閯?chuàng)建路徑不會繪制路徑。詳細(xì)信息請參見繪制路徑。
在繪制路徑之后,它將從圖形上下文刷新。你可能不想這么容易迷路,尤其是當(dāng)它描述了一個復(fù)雜的場景,你想一遍又一遍地使用。因此,Quartz提供了兩種數(shù)據(jù)類型來創(chuàng)建可重用路徑—cgpathref和CGMutablePathRef。您可以調(diào)用CGPathCreateMutable函數(shù)來創(chuàng)建一個可變的CGPath對象,您可以向其添加直線、弧線、曲線和矩形。Quartz提供了一組CGPath函數(shù),它們與構(gòu)建塊中討論的函數(shù)并行。路徑函數(shù)操作CGPath對象而不是圖形上下文。這些函數(shù)是:
CGPathCreateMutable取代CGContextBeginPath
CGPathMoveToPoint取代 CGContextMoveToPoint
CGPathAddLineToPoint取代CGContextAddLineToPoint
CGPathAddCurveToPoint取代CGContextAddCurveToPoint
CGPathAddEllipseInRect取代 CGContextAddEllipseInRect
CGPathAddArc取代 CGContextAddArc
CGPathAddRect取代 CGContextAddRect
CGPathCloseSubpath取代 CGContextClosePath
有關(guān)路徑函數(shù)的完整列表,請參閱Quartz 2D參考集合。
當(dāng)您想要將路徑附加到圖形上下文時(shí),您可以調(diào)用CGContextAddPath函數(shù)。該路徑在Quartz繪制之前一直停留在圖形上下文中。您可以通過調(diào)用CGContextAddPath再次添加路徑。
注意:通過調(diào)用函數(shù)CGContextReplacePathWithStrokedPath,可以用路徑的描邊版本替換圖形上下文中的路徑。
Painting a Path
您可以通過描邊或填充或兩者都畫出當(dāng)前路徑。撫摸畫出一條橫跨在道路上的線條。填充繪制路徑中包含的區(qū)域。Quartz具有一些函數(shù),可以讓您描邊路徑、填充路徑或同時(shí)描邊和填充路徑。描邊線的特征(寬度、顏色等等)、填充顏色以及Quartz用于計(jì)算填充區(qū)域的方法都是圖形狀態(tài)的一部分(參見圖形狀態(tài))。
影響描邊的參數(shù)
可以通過修改表3-1中列出的參數(shù)來影響路徑的遍歷方式。這些參數(shù)是圖形狀態(tài)的一部分,這意味著您為一個參數(shù)設(shè)置的值會影響所有后續(xù)的筆畫操作,直到您將參數(shù)設(shè)置為另一個值為止。

line width是線的總寬度,用用戶空間的單位表示。這條線橫跨在道路上,兩邊各占總寬度的一半。
line join指定Quartz如何在連接的線段之間繪制連接。Quartz支持表3-2中描述的行連接樣式。默認(rèn)的樣式是miter join。

line cap指定了CGContextStrokePath用來繪制線端點(diǎn)的方法。Quartz支持表3-3中描述的線帽樣式。默認(rèn)的樣式是屁股蓋。

封閉子路徑將起始點(diǎn)作為連接線段之間的連接點(diǎn);起始點(diǎn)是使用選定的行連接方法呈現(xiàn)的。相反,如果通過添加連接到起始點(diǎn)的線段來關(guān)閉路徑,則路徑的兩端都使用所選的線蓋方法繪制。
line dash pattern允許你沿著描邊路徑畫一條分段的線。通過將dash數(shù)組和dash phase指定為CGContextSetLineDash的參數(shù),可以控制dash分段的大小和位置:
void CGContextSetLineDash (
CGContextRef ctx,
CGFloat phase,
const CGFloat lengths[],
size_t count
);
length參數(shù)的元素指定了破折號的寬度,在繪制和未繪制的線段之間交替使用。相位參數(shù)指定dash模式的起點(diǎn)。圖3-11顯示了一些線劃線模式。

筆畫顏色空間決定了筆畫顏色值如何由Quartz解釋。還可以指定封裝顏色和顏色空間的Quartz顏色(CGColorRef數(shù)據(jù)類型)。有關(guān)設(shè)置顏色空間和顏色的更多信息,請參閱顏色和顏色空間。
Functions for Stroking a Path
Quartz提供了如表3-4所示的用于撫摸當(dāng)前路徑的函數(shù)。一些是用于描邊矩形或橢圓的方便函數(shù)。
CGContextStrokeLineSegments函數(shù)相當(dāng)于以下代碼:
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);
當(dāng)您調(diào)用CGContextStrokeLineSegments時(shí),您將線段指定為點(diǎn)數(shù)組,以對的形式組織。每一對由線段的起始點(diǎn)和線段的結(jié)束點(diǎn)組成。例如,數(shù)組中的第一個點(diǎn)指定第一行的起始位置,第二個點(diǎn)指定第一行的結(jié)束位置,第三個點(diǎn)指定第二行的起始位置,等等。
Filling a Path
當(dāng)您填充當(dāng)前路徑時(shí),Quartz就好像路徑中包含的每個子路徑都是關(guān)閉的。然后它使用這些封閉子路徑并計(jì)算要填充的像素。Quartz表有兩種計(jì)算填充面積的方法。簡單的路徑,例如橢圓和矩形,有一個定義明確的區(qū)域。但是,如果您的路徑由重疊部分組成,或者路徑包含多個子路徑,比如圖3-12所示的同心圓,則可以使用兩個規(guī)則來確定填充區(qū)域。
你可以選擇使用奇偶法則。要確定是否應(yīng)該繪制特定的點(diǎn),從該點(diǎn)開始,畫出超出該點(diǎn)界限的線。計(jì)算直線穿過的路徑段數(shù)。如果結(jié)果是奇數(shù),則繪制該點(diǎn)。如果結(jié)果是偶數(shù),則不繪制該點(diǎn)。繪制路徑段的方向不影響結(jié)果。正如您在圖3-12中所看到的,繪制每個圓的方向并不重要,填充將始終如圖所示。

Quartz為填充當(dāng)前路徑提供了表3-5所示的函數(shù)。一些是用于描邊矩形或橢圓的方便函數(shù)。

Setting Blend Modes
混合模式指定Quartz如何應(yīng)用繪制背景。Quartz默認(rèn)使用普通的混合模式,它使用以下公式將前景畫和背景畫結(jié)合起來:
result = (alpha * foreground) + (1 - alpha) * background
Color and Color Spaces提供了關(guān)于顏色的alpha組件的詳細(xì)討論,它指定了顏色的不透明度。對于本節(jié)中的示例,您可以假設(shè)顏色是完全不透明的(alpha值= 1.0)。對于不透明的顏色,當(dāng)你使用普通的混合模式作畫時(shí),你在背景上畫的任何東西都會完全模糊背景。
您可以通過調(diào)用函數(shù)CGContextSetBlendMode來設(shè)置混合模式以實(shí)現(xiàn)各種效果,并傳遞適當(dāng)?shù)幕旌夏J匠A?。請記住,混合模式是圖形狀態(tài)的一部分。如果在更改混合模式之前使用了函數(shù)CGContextSaveGState,那么調(diào)用函數(shù)cgcontext trestoregstate將混合模式重置為正常模式。
本節(jié)的其余部分顯示了將圖3-13所示的矩形繪制到圖3-14所示矩形之上的結(jié)果。在每種情況下(圖3-15到圖3-30),背景矩形都是使用普通混合模式繪制的。然后通過使用適當(dāng)?shù)某A空{(diào)用CGContextSetBlendMode函數(shù)來更改混合模式。最后,繪制前景矩形。


注意:您還可以使用混合模式來組合兩個圖像,或者將圖像與任何已經(jīng)繪制到圖形上下文的內(nèi)容進(jìn)行組合。在圖像中使用混合模式提供了如何將混合模式用于復(fù)合圖像的信息,并顯示了對兩個圖像應(yīng)用混合模式的結(jié)果。
Normal Blend Mode(正常的混合模式)
因?yàn)槠胀ǖ幕旌夏J绞悄J(rèn)的混合模式,所以您可以使用常量CGContextSetBlendMode調(diào)用函數(shù)CGContextSetBlendMode,只有將混合模式重置為默認(rèn)模式,才能使用其他混合模式常量。圖3-15顯示了使用普通混合模式繪制圖3-13比圖3-14的結(jié)果。

Multiply Blend Mode
多重混合模式指定將前景圖像樣本與背景圖像樣本疊加。產(chǎn)生的顏色至少和兩個產(chǎn)生的樣本顏色一樣暗。圖3-16顯示了使用多重混合模式繪制圖3-13 /圖3-14的結(jié)果。要使用這種混合模式,請使用常量CGContextSetBlendMode調(diào)用函數(shù)CGContextSetBlendMode。

Screen Blend Mode
屏幕混合模式指定將前景圖像樣本的逆與背景圖像樣本的逆相乘。產(chǎn)生的顏色至少和兩個產(chǎn)生的樣例顏色一樣輕。圖3-17顯示了使用屏幕混合模式繪制圖3-13比圖3-14的結(jié)果。要使用此混合模式,請使用常量kCGBlendModeScreen調(diào)用函數(shù)CGContextSetBlendMode。

Overlay Blend Mode
疊加混合模式指定根據(jù)背景顏色,將前景圖像樣本與背景圖像樣本相疊加或遮蔽。背景顏色與前景顏色混合以反映背景的明度或暗度。圖3-18顯示了使用疊加混合模式繪制圖3-13比圖3-14的結(jié)果。要使用這種混合模式,可以使用常量kCGBlendModeOverlay調(diào)用CGContextSetBlendMode函數(shù)。

Darken Blend Mode
指定通過選擇較暗的樣本(從前景圖像或背景圖像)來創(chuàng)建復(fù)合圖像樣本。背景圖像樣本被任何較暗的前景圖像樣本所取代。否則,背景圖像樣本將保持不變。圖3-19顯示了使用暗混合模式繪制圖3-13比圖3-14的結(jié)果。要使用這種混合模式,可以使用常量kCGBlendModeDarken調(diào)用CGContextSetBlendMode函數(shù)。

Lighten Blend Mode
指定通過選擇較輕的樣本(從前景或背景)來創(chuàng)建復(fù)合圖像樣本。結(jié)果是,背景圖像樣本被任何較輕的前景圖像樣本所取代。否則,背景圖像樣本將保持不變。圖3-20顯示了使用變淡混合模式繪制圖3-13比圖3-14的結(jié)果。要使用此混合模式,請使用常量kcgblendmodeli調(diào)用函數(shù)CGContextSetBlendMode。

Color Dodge Blend Mode
指定使背景圖像樣本變亮以反映前景圖像樣本。指定黑色的前景圖像示例值不會產(chǎn)生更改。圖3-21顯示了使用顏色減淡混合模式繪制圖3-13比圖3-14的結(jié)果。要使用這種混合模式,可以使用常量kCGBlendModeColorDodge調(diào)用CGContextSetBlendMode函數(shù)。

Color Burn Blend Mode
指定使背景圖像樣本變暗以反映前景圖像樣本。指定白色的前景圖像示例值不會產(chǎn)生更改。圖3-22顯示了使用顏色加深混合模式繪制圖3-13比圖3-14的結(jié)果。要使用此混合模式,請使用常量kcgblendmodecolburn調(diào)用函數(shù)CGContextSetBlendMode。

Soft Light Blend Mode
根據(jù)前景圖像樣本顏色的不同,指定顏色變暗或變淺。如果前景圖像樣本的顏色比50%的灰度淺,背景會變淺,類似于躲避。如果前景圖像的樣本顏色比50%的灰度深,背景會變暗,類似于燃燒。如果前景圖像的樣本顏色等于50%的灰度,背景不會改變。與純黑或純白相等的圖像樣本會產(chǎn)生較暗或較淺的區(qū)域,但不會產(chǎn)生純黑或純白。整體效果與你在前景圖像上使用漫射聚光燈所達(dá)到的效果相似。用這個來給場景添加高光。圖3-23顯示了使用柔光混合模式繪制圖3-13比圖3-14的結(jié)果。要使用此混合模式,請使用常量kCGBlendModeSoftLight調(diào)用函數(shù)CGContextSetBlendMode。

Hard Light Blend Mode
指定相乘或屏幕顏色,取決于前景圖像樣本顏色。如果前景圖像樣本的顏色比50%的灰度淺,背景會變淺,類似于篩選。如果前景圖像的樣本顏色比50%的灰度深,背景會變暗,類似于相乘。如果前景圖像樣本顏色為50%灰度,則前景圖像不改變。等于純黑或純白的圖像樣本結(jié)果是純黑或純白。整體效果類似于你在前景圖像上發(fā)出強(qiáng)烈的聚光燈所能達(dá)到的效果。用這個來給場景添加高光。圖3-24顯示了使用強(qiáng)光混合模式繪制圖3-13比圖3-14的結(jié)果。要使用這種混合模式,請使用常量kCGBlendModeHardLight調(diào)用函數(shù)
Difference Blend Mode
指定從背景圖像樣本顏色中減去前景圖像樣本顏色,或者反過來,這取決于哪個樣本的亮度值更大。前景圖像樣本值為黑色不會產(chǎn)生變化;白色反轉(zhuǎn)背景顏色的值。圖3-25顯示了使用差異混合模式繪制圖3-13比圖3-14的結(jié)果。要使用這種混合模式,請使用常量kCGBlendModeDifference調(diào)用CGContextSetBlendMode函數(shù)。

Exclusion Blend Mode
指定類似于kCGBlendModeDifference產(chǎn)生的效果,但具有較低的對比度。前景圖像樣本值為黑色不會產(chǎn)生變化;白色反轉(zhuǎn)背景顏色的值。圖3-26顯示了使用排除混合模式繪制圖3-13比圖3-14的結(jié)果。要使用這種混合模式,請使用常量kCGBlendModeExclusion調(diào)用函數(shù)CGContextSetBlendMode。

Hue Blend Mode
指定將背景的亮度和飽和度值與前景圖像的色調(diào)一起使用。圖3-27顯示了使用色調(diào)混合模式繪制圖3-13比圖3-14的結(jié)果。要使用這種混合模式,請使用常量kCGBlendModeHue調(diào)用CGContextSetBlendMode函數(shù)。
Saturation Blend Mode
指定在前景圖像的飽和度下使用背景的亮度和色調(diào)值。沒有飽和度的背景區(qū)域(即純灰色區(qū)域)不會產(chǎn)生變化。圖3-28顯示了使用飽和度混合模式繪制圖3-13比圖3-14的結(jié)果。要使用這種混合模式,使用常量kCGBlendModeSaturation調(diào)用函數(shù)CGContextSetBlendMode即可。

Color Blend Mode
指定將背景的亮度值與前景圖像的色調(diào)和飽和度值一起使用。這種模式保留了圖像中的灰度。您可以使用此模式為單色圖像著色或?yàn)椴噬珗D像著色。圖3-29顯示了使用顏色混合模式繪制圖3-13比圖3-14的結(jié)果。要使用此混合模式,請使用常量kCGBlendModeColor調(diào)用函數(shù)CGContextSetBlendMode。

Luminosity Blend Mode
指定使用帶有前景圖像亮度的背景色調(diào)和飽和度。此模式創(chuàng)建的效果與kCGBlendModeColor創(chuàng)建的效果相反。圖3-30顯示了使用光度混合模式繪制圖3-13比圖3-14的結(jié)果。要使用這種混合模式,請使用常量kcgblendmodelosity來調(diào)用CGContextSetBlendMode函數(shù)。

Clipping to a Path
當(dāng)前的剪切區(qū)域是從一個用作遮罩的路徑創(chuàng)建的,允許您將不希望繪制的頁面部分屏蔽掉。例如,如果您有一個非常大的位圖圖像,并且想只顯示它的一小部分,您可以設(shè)置剪切區(qū)域來只顯示您想顯示的部分。
當(dāng)您繪制時(shí),Quartz只在剪切區(qū)域內(nèi)呈現(xiàn)繪制。在剪切區(qū)域的閉合子路徑內(nèi)的繪制是可見的;發(fā)生在剪切區(qū)域的閉合子路徑之外的繪制不是。
當(dāng)最初創(chuàng)建圖形上下文時(shí),剪切區(qū)域包括上下文的所有可繪制區(qū)域(例如,PDF上下文的媒體框)。通過設(shè)置當(dāng)前路徑,然后使用剪切函數(shù)而不是繪圖函數(shù)來更改剪切區(qū)域。剪切函數(shù)將當(dāng)前路徑的填充區(qū)域與現(xiàn)有的剪切區(qū)域相交。因此,您可以與裁剪區(qū)域相交,縮小圖片的可見區(qū)域,但不能增加裁剪區(qū)域的面積。
剪切區(qū)域是圖形狀態(tài)的一部分。要將剪切區(qū)域恢復(fù)到以前的狀態(tài),可以在剪切之前保存圖形狀態(tài),并在剪切完成后恢復(fù)圖形狀態(tài)。
清單3-1顯示了一個代碼片段,該代碼片段設(shè)置了一個圓形的剪切區(qū)域。這段代碼使繪圖被裁剪,類似于圖3-3所示。(另一個例子,請參閱漸變章節(jié)中的上下文剪輯。)
CGContextBeginPath (context);
CGContextAddArc (context, w/2, h/2, ((w>h) ? h : w)/2, 0, 2*PI, 0);
CGContextClosePath (context);
CGContextClip (context);
