Quartz 2D編程指南之六:模式(Pattern)

本文轉(zhuǎn)載自:http://southpeak.github.io/2014/12/05/quartz2d-6/

模式(Pattern)是繪制操作的一個(gè)序列,這些繪制操作可以重復(fù)地繪制到一個(gè)圖形上下文上。我們可以像使用顏色一樣使用這些模式。當(dāng)我們使用pattern來繪制時(shí),Quartz將Page分割成模式單元格的集合,其中每個(gè)單元格的大小不是模式圖片的大小,并使用我們提供的回調(diào)函數(shù)來繪制這些單元格。圖6-1演示了一個(gè)繪制到window圖形上下文的模式。

Figure 6-1 A pattern drawn to a window

模式的骨架(Anatomy)

模式單元格是模式的基礎(chǔ)組件。圖6-1中的模式的單元格如圖6-2所示。其中黑色邊框不是模式單元格的一部分;之所以畫出來是為了顯示模式單元格的邊界。

Figure 6-2 A pattern cell

該模式單元格的大小包含四個(gè)帶顏色的矩形以及這些矩形上部及右側(cè)的白色區(qū)域,如圖6-3所示。每個(gè)模式單元格的黑色邊框不是單元格的一部分;畫出來只是為是標(biāo)明單元格的邊界。當(dāng)我們創(chuàng)建一個(gè)模式單元格時(shí),我們需要定義單元格的邊界并在這個(gè)范圍內(nèi)進(jìn)行繪制。

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

我們可以指定水平和豎直方向上兩個(gè)單元格之間的間距。圖6-3所繪制的單元格是相互緊挨著的。而圖6-4在兩個(gè)方向上都指定了單元格之間的間距。我們可以為兩個(gè)方向指定不同的間距。我們亦可以指定間距為負(fù)數(shù),這樣單元格便會(huì)重疊。

Figure 6-4 Spacing between pattern cells

當(dāng)我們繪制一個(gè)模式單元格時(shí),Quartz使用模式空間(pattern space)作為坐標(biāo)系統(tǒng)。模式空間是一個(gè)抽象空間,它會(huì)使用我們創(chuàng)建模式時(shí)指定的變換矩陣(pattern matrix)來映射到默認(rèn)用戶空間。

注意:模式空間與用戶空間是分開的。未轉(zhuǎn)換的模式空間映射到基礎(chǔ)的用戶空間(未轉(zhuǎn)換的),而不管當(dāng)前轉(zhuǎn)換矩陣(CTM)。當(dāng)我們?cè)谀J娇臻g上應(yīng)用轉(zhuǎn)換時(shí),Quartz只將轉(zhuǎn)換應(yīng)用于模式空間。

如果我們不想要Quartz來轉(zhuǎn)換模式單元格,我們可以指定單位矩陣。然而,我們可以使用轉(zhuǎn)換矩陣來達(dá)到有趣的效果。圖6-5顯示了縮放6-2中的模式單元格的效果。圖6-6旋轉(zhuǎn)了這些單元格。圖6-7則平移了這些單元格。

Figure 6-5 A scaled pattern cell

Figure 6-6 A rotated pattern cell

Figure 6-7 A translated pattern cell

著色模式(Colored Patterns)和模板模式(Stencil Patterns)

著色模式有與其相關(guān)的固有顏色。如果修改了創(chuàng)建模式單元格的顏色,則模式也便失去了意義。圖6-8中顯示的蘇格蘭格子就是著色模式的一個(gè)例子。著色模式中的顏色是模式單元格創(chuàng)建流程的一部分,而不是繪制流程的一部分。

Figure 6-8 A colored pattern has inherent color

而其它模式只限定了形狀,因此可以認(rèn)為是模板模式(或者是非著色模式、甚至可以作為圖像蒙板)。圖6-9中展示的紅色和黑色星星就是使用相同的模式單元格。單元格由一個(gè)五角星組成。當(dāng)定義模式單元格時(shí),沒有與之相關(guān)的顏色。顏色值是在繪制過程中指定的,而不是創(chuàng)建過程的一部分。

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

在Quartz 2D中,我們可以創(chuàng)建這兩種模式。

平鋪(Tiling)

平鋪(Tiling)是將模式單元格繪制到頁面(Page)的某個(gè)部分的過程。當(dāng)Quartz將模式渲染到一個(gè)設(shè)備時(shí),Quartz可能需要調(diào)整模式以適應(yīng)設(shè)備空間。即,在用戶空間定義的模式單元格在渲染到設(shè)備時(shí)可能無法精確匹配,這是由用戶空間單元和設(shè)備像素之間的差異導(dǎo)致的。

Quartz有三個(gè)平鋪選項(xiàng),以在必要時(shí)調(diào)整模式:

沒有失真(no distortion): 以細(xì)微調(diào)整模式單元格之間的間距為代價(jià),但通常不超過一個(gè)設(shè)備像素。

最小的失真的恒定間距:設(shè)定單元格之間的間距,以細(xì)微調(diào)整單元大小為代價(jià),但通常不超過一個(gè)設(shè)備像素。

恒定間距:設(shè)定單元格之間間距,以調(diào)整單元格大小為代價(jià),以求盡快的平鋪

模式如何工作

模式操作類似于顏色,我們?cè)O(shè)置一個(gè)填充或描邊(stroke)模式,然后調(diào)用繪制函數(shù)。Quartz使用我們?cè)O(shè)置的模式作為“涂料”。例如,如果我們要使用純色繪制一個(gè)填充的的矩形,我們首先調(diào)用函數(shù)(如CGContextSetFillColor)來設(shè)置填充顏色。然后調(diào)用函數(shù)CGContextFillRect以使用我們指定的顏色來填充矩形。為了繪制一個(gè)模式,顏色調(diào)用函數(shù)CGContextSetFillPattern來設(shè)置指定的模式。繪制顏色和繪制模式的不同之處在于我們必須先定義一個(gè)模式。我們?yōu)楹瘮?shù)CGContextSetFillPattern提供模式和顏色信息。我們將在下面的繪制著色模式和繪制模板模式章節(jié)看到如何創(chuàng)建、設(shè)置和繪制模式。

這里有個(gè)例子說明Quartz在幕后是如何繪制一個(gè)模式的。當(dāng)我們填充或描邊一個(gè)模式時(shí),Quartz會(huì)按照以下指令來繪制每一個(gè)模式單元格:

保存圖形狀態(tài)

將當(dāng)前轉(zhuǎn)換矩陣應(yīng)用到原始的模式單元格上

連接CTM與模式矩陣

裁剪模式單元格的邊界矩形

調(diào)用繪制回調(diào)函數(shù)來繪制單元格

恢復(fù)圖形狀態(tài)

Quartz會(huì)執(zhí)行所有平鋪操作,重復(fù)繪制模式單元格到繪制空間,直到渲染滿整個(gè)空間。我們可以填充和描邊一個(gè)模式。模式單元格可以是指定的任何大小。如果我們想要看到模式,我們需要確保模式單元格與繪制空間匹配。例如,如果我們的模式單元格是8*10個(gè)單位的,而我們用這個(gè)模式來描邊一個(gè)只有2個(gè)單位的直線,則這個(gè)模式單元格將會(huì)被裁剪。這種情況下,我們可能無法辨認(rèn)出我們的模式。

繪制著色模式

繪制著色模式需要執(zhí)行以下五步操作:

寫一個(gè)繪制著色模式單元格的回調(diào)函數(shù)

設(shè)置著色模式的顏色空間

設(shè)置著色模式的骨架(Anatomy)

指定著色模式作為填充或描邊模式

使用著色模式繪制

繪制模板模式也是類似這幾步。兩者之間的區(qū)別在于如何設(shè)置顏色信息。

寫一個(gè)繪制著色模式單元格的回調(diào)函數(shù)

一個(gè)模式單元格看起來是什么樣的完全取決于我們。在這個(gè)例子中,代碼清單6-1繪制了圖6-2所示的模式單元格。

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

#defineH_PATTERN_SIZE 16

#defineV_PATTERN_SIZE 18

voidMyDrawColoredPattern(void*info, CGContextRef myContext)

{

CGFloat subunit =5;

CGSize size = {subunit, subunit};

CGPoint point1 = {0,0}, point2 = {subunit, subunit}, point3 = {0,subunit}, point4 = {subunit,0};

CGRect myRect1 = {point1, size}, myRect2 = {point2, size}, myRect3 = {point3, size}, myRect4 = {point4, size};

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

}

模式單元格繪制函數(shù)是類似于下面這種格式的一個(gè)回調(diào)函數(shù)

typedefvoid(*CGPatternDrawPatternCallback)(

void*info,

CGContextRef context

);

我們可以隨意命名我們的回調(diào)函數(shù)。代碼清單6-1中命名為MyDrawColoredPattern。這個(gè)回調(diào)函數(shù)帶有兩個(gè)參數(shù):

info: 一個(gè)指向模式相關(guān)數(shù)據(jù)的指針。這個(gè)參數(shù)是可選的,可以傳遞NULL。傳遞給回調(diào)的數(shù)據(jù)與后面創(chuàng)建模式的數(shù)據(jù)是一樣的。

context: 繪制模式單元格的圖形上下文

代碼清單6-1中繪制的模式單元格是隨意的。以下是一些關(guān)于繪制代碼的重要信息:

需要聲明模式大小。在繪制時(shí)我們需要記住模式大小。在這個(gè)例子中,大小是全局聲明的,繪制函數(shù)沒有具體提到大小,除了在注釋中。然后,我們將模式大小指定給Quartz 2D。

繪制函數(shù)后面是由CGPatternDrawPatternCallback回調(diào)函數(shù)類型定義定義的原型

代碼中執(zhí)行的繪制設(shè)置了顏色,讓其成為一個(gè)著色模式。

設(shè)置著色模式的顏色空間

代碼清單6-1中的代碼使用顏色來繪制模式單元格。我們必須設(shè)置基本的模式顏色空間為NULL,以確保Quartz使用繪制路徑指定的顏色來繪制,如代碼清單6-2所示。

Listing 6-2 Creating a base pattern color space

CGColorSpaceRef patternSpace;

// 創(chuàng)建模式顏色空間,并傳遞NULL作為參數(shù)

patternSpace = CGColorSpaceCreatePattern (NULL);

// 在模式顏色空間中設(shè)置填充顏色

CGContextSetFillColorSpace (myContext, patternSpace);

// 釋放模式顏色空間

CGColorSpaceRelease (patternSpace);

設(shè)置著色模式的骨架

一個(gè)模式的骨架基本信息保存在CGPattern對(duì)象中。我們調(diào)用CGPatternCreate函數(shù)來創(chuàng)建一個(gè)CGPattern對(duì)象,其原型如代碼清單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:是一個(gè)指針,指向我們要傳遞給繪制回調(diào)函數(shù)的數(shù)據(jù)

bound:指定模式單元格的大小

matrix:指定模式矩陣,它將模式坐標(biāo)系統(tǒng)映射到圖形上下文的默認(rèn)坐標(biāo)系統(tǒng)。如果希望兩個(gè)坐標(biāo)系統(tǒng)是一樣的,則可以使用單位矩陣。

xStep, yStep:指定單元格之間的水平和豎直間距。

tiling:平鋪模式,可以是kCGPatternTilingNoDistortion、kCGPatternTilingConstantSpacingMinimalDistortion、kCGPatternTilingConstantSpacing

isColored:指定模式單元格是著色模式(true)還是模板模式(false)

callbacks:是一個(gè)指向CGPatternCallbacks結(jié)構(gòu)體的指針,則定義如下:

structCGPatternCallbacks

{

unsignedintversion;

CGPatternDrawPatternCallback drawPattern;

CGPatternReleaseInfoCallback releaseInfo;

};

我們可以設(shè)置version為0。drawPattern是指向繪制回調(diào)的指針。releaseInfo是指向一個(gè)回調(diào)函數(shù),該回調(diào)在釋放CGPattern對(duì)象時(shí)被調(diào)用,以釋放存儲(chǔ)在我們傳遞給繪制回調(diào)的info參數(shù)中的數(shù)據(jù)。如果在這個(gè)參數(shù)中沒有傳遞任何數(shù)據(jù),則設(shè)置該域?yàn)镹ULL。

指定著色模式作為填充或描邊模式

我們可以調(diào)用CGContextSetFillPattern或者CGContextSetStrokePattern函數(shù)來使用模式進(jìn)行填充或描邊。Quartz可以將模式用于任何填充或描邊流程。

這兩個(gè)函數(shù)包含以下幾個(gè)參數(shù):

圖形上下文

先前創(chuàng)建的CGPattern對(duì)象

顏色組件的數(shù)組

雖然著色模式提供了自己的顏色,我們?nèi)匀恍枰獋鬟f一個(gè)單一的alpha值來告訴Quartz在繪制時(shí)著色模式的透明度。alpha值的范圍在0到1中。可以如以下代碼來設(shè)置著色模式的透明度:

CGFloat alpha =1;

CGContextSetFillPattern (myContext, myPattern, &alpha);

使用顏色模式繪制

在完成前面的步驟之后,我們就可以調(diào)用Quartz 2D函數(shù)來繪制了。我們的模式被當(dāng)作“涂料”。例如,可以調(diào)用CGContextStrokePath, CGContextFillPath, CGContextFillRect或其它函數(shù)來繪制。

完整示例

代碼清單6-4包含一個(gè)繪制著色模式的函數(shù)。這個(gè)函數(shù)包含了前面討論的所有步驟。

Listing 6-4 A function that paints a colored pattern

void MyColoredPatternPainting(CGContextRef myContext,

CGRect rect)

{

CGPatternRef? ? pattern;

CGColorSpaceRef patternSpace;

CGFloat? ? ? ? alpha =1,

width, height;

static const CGPatternCallbacks callbacks = {0,

&MyDrawPattern,

NULL};

CGContextSaveGState (myContext);

patternSpace = CGColorSpaceCreatePattern (NULL);

CGContextSetFillColorSpace (myContext, patternSpace);

CGColorSpaceRelease (patternSpace);

pattern = CGPatternCreate (NULL,

CGRectMake (0,0, H_PSIZE, V_PSIZE),

CGAffineTransformMake (1,0,0,1,0,0),

H_PATTERN_SIZE,

V_PATTERN_SIZE,

kCGPatternTilingConstantSpacing,

true,

&callbacks);

CGContextSetFillPattern (myContext, pattern, &alpha);

CGPatternRelease (pattern);

CGContextFillRect (myContext, rect);

CGContextRestoreGState (myContext);

}

繪制模板模式

與繪制著色模式類似,繪制模板模式也有5個(gè)步驟:

寫一個(gè)繪制模板模式單元格的回調(diào)函數(shù)

設(shè)置模板模式的顏色空間

設(shè)置模板模式的骨架(Anatomy)

指定模板模式作為填充或描邊模式

使用模板模式繪制

繪制模板模式與繪制著色模式的區(qū)別在于設(shè)置顏色信息。

寫一個(gè)繪制模板模式單元格的回調(diào)函數(shù)

繪制模板模式單元格的回調(diào)與前面描述的繪制顏色模式單元格類似。不同的是繪制模式單元格回調(diào)不需要指定顏色值。圖6-10中顯示的模式單元格即沒有從繪制回調(diào)中獲取顏色。

Figure 6-10 A stencil pattern cell

代碼清單6-5繪制了圖6-10中的模式單元格。可以看到代碼只是簡單地創(chuàng)建并填充了一個(gè)路徑,而沒有設(shè)置顏色。

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

#definePSIZE 16// size of the pattern cell

static void MyDrawStencilStar(void*info, CGContextRef myContext)

{

intk;

doubler, 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);

}

設(shè)置模板模式的顏色空間

模板模式要求我們?cè)O(shè)置一個(gè)模式顏色空間用于Quartz的繪制,如代碼清單6-6所示。

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

CGPatternRef pattern;

CGColorSpaceRef baseSpace;

CGColorSpaceRef patternSpace;

// 創(chuàng)建一個(gè)通用RGB顏色空間。

baseSpace = CGColorSpaceCreateWithName (kCGColorSpaceGenericRGB);

// 創(chuàng)建一個(gè)模式顏色空間。該顏色空間指定如何表示模式的顏色。后面要設(shè)置模式的顏色時(shí),必須使用這個(gè)顏色空間來進(jìn)行設(shè)置

patternSpace = CGColorSpaceCreatePattern (baseSpace);

// 設(shè)置顏色空間來在填充模式時(shí)使用

CGContextSetFillColorSpace (myContext, patternSpace);

// 釋放模式顏色空間

CGColorSpaceRelease(patternSpace);

// 釋放基礎(chǔ)顏色空間

CGColorSpaceRelease(baseSpace);

設(shè)置模板模式的骨架(Anatomy)

這一步與上面設(shè)置著色模式是一樣的,不同的是isColored參數(shù)需要傳遞false。

指定模板模式作為填充或描邊模式

我們可以調(diào)用CGContextSetFillPattern或者CGContextSetStrokePattern函數(shù)來使用模式進(jìn)行填充或描邊。Quartz可以將模式用于任何填充或描邊流程。

這兩個(gè)函數(shù)包含以下幾個(gè)參數(shù):

圖形上下文

先前創(chuàng)建的CGPattern對(duì)象

顏色組件的數(shù)組

由于模板模式在繪制回調(diào)中不提供顏色值,所以我們必須傳遞一個(gè)顏色給填充或描邊函數(shù)來告訴Quartz使用什么顏色。代碼清單6-7顯示了為模板模式設(shè)置顏色的例子。

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

使用模板模式繪制

在完成前面的步驟之后,我們就可以調(diào)用Quartz 2D函數(shù)來繪制了。我們的模式被當(dāng)作“涂料”。例如,可以調(diào)用CGContextStrokePath, CGContextFillPath, CGContextFillRect或其它函數(shù)來繪制。

完整示例

代碼清單6-8包含一個(gè)繪制模板模式的函數(shù)。這個(gè)函數(shù)包含了前面討論的所有步驟。

Listing 6-8 A function that paints a stencil pattern

#definePSIZE 16

void MyStencilPatternPainting(CGContextRef myContext,

constRect *windowRect)

{

CGPatternRef pattern;

CGColorSpaceRef baseSpace;

CGColorSpaceRef patternSpace;

staticconstCGFloat color[4] = {0,1,0,1};

staticconstCGPatternCallbacks callbacks = {0, &drawStar,NULL};

baseSpace = CGColorSpaceCreateDeviceRGB ();

patternSpace = CGColorSpaceCreatePattern (baseSpace);

CGContextSetFillColorSpace (myContext, patternSpace);

CGColorSpaceRelease (patternSpace);

CGColorSpaceRelease (baseSpace);

pattern = CGPatternCreate(NULL, CGRectMake(0,0, PSIZE, PSIZE),

CGAffineTransformIdentity, PSIZE, PSIZE,

kCGPatternTilingConstantSpacing,

false, &callbacks);

CGContextSetFillPattern (myContext, pattern, color);

CGPatternRelease (pattern);

CGContextFillRect (myContext,CGRectMake (0,0,PSIZE*20,PSIZE*20));

}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,836評(píng)論 6 540
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,275評(píng)論 3 428
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,904評(píng)論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,633評(píng)論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,368評(píng)論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,736評(píng)論 1 328
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,740評(píng)論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,919評(píng)論 0 289
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,481評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,235評(píng)論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,427評(píng)論 1 374
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,968評(píng)論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,656評(píng)論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,055評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,348評(píng)論 1 294
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,160評(píng)論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,380評(píng)論 2 379

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