2011-10-07 25 views
0

這可能嗎?基本上,我有一堆NSAttributedString對象和相應的CTLine對象。我想在drawRect階段之前獲得圖像邊界。所以在這一點上,沒有什麼可以借鑑的。然後,我將使用這些圖像邊界來確定我需要爲繪圖創建的內容。編輯:另一種尺寸的測量可能會工作得很好。但調用名爲CTLineGetTypographicBounds的函數只會返回寬度。如果我傳遞上升和下降浮點地址,他們會回到零。CTLine或NSAttributedString - 獲取沒有圖形上下文的圖像邊界?

編輯:給定的答案在MacOS中效果很好。任何人都可以在iOS?

回答

2

如果您正在開發iOS6 +。您可以使用下面的方法:

CTLineRef line; 
// Create the line... 

CGRect bounds = CTLineGetBoundsWithOptions(line, kCTLineBoundsUseGlyphPathBounds); 
// use bounds... 

這是給出了同樣的邊界作爲CTLineGetImageBounds()假設你有沒有在你的環境中應用的變換,但不要求的上下文。對於iOS 5及以下版本,您需要使用Иван描述的方法。

CTLineGetTypographicBounds()給了我一個不同於這個函數或圖像邊界的寬度。我不知道爲什麼。返回的上升和下降是那些字體,而不是在CTLineRef.

+0

CTLineGetTypographicBounds()給出的寬度是提前寬度(從印刷原點到印刷原點的距離)。這與圖像邊界不同,因爲對於(幾乎所有)字母,字形將延伸超出前進寬度或比其更窄。 –

2

是的,你可以,但不是那麼容易。

你應該,一般採用CTLineGetTypographicBounds()這對我來說,確實返回上升血統領先,但有點搞砸了 - 「上升」等於總高度(即什麼應該是上升+下降)和'下降'總是字體的最大下降 - 無論你是否降序字符。

其他方式是檢索CTRun(S)從所述線路(CTLineGetGlyphRuns),則獲得的字形陣列(CTRunGetGlyphsCTRunGetGlyphsPtr),然後使用CTFontGetBoundingRectsForGlyphsCTFontGetAdvancesForGlyphs構建提供您需要的信息。

編輯: 我剛剛發現這個方法: 「- (的NSRect)boundingRectWithSize:(NSSize)大小選項:(NSStringDrawingOptions)選項」 的NSAttributedString這似乎做正是所需要的。

希望,這是有益的...通過CTLineGetTypographicBounds()返回

+0

中顯示的字符嗯,我想知道它是否可以取決於你是否在iOS或macOS?我在iOS工作,他們總是零。蘋果公司有一些Mac的示例代碼,它們返回非零值。 –

2

界限不一樣的圖像邊界。正如名字(和Иван的答案)所表明的那樣,上升等是爲字體定義的,並且不會根據字符串而改變。例如,如果您想要查找正確的行高(如果您有多行文本),則可以使用它,因爲行高通常不應取決於您使用的確切字符。

CTLineGetImageBounds()另一方面,返回精確適合圖像的邊界。例如,如果你想圍繞一行畫一個盒子,這就是你所需要的。

CTLineGetImageBounds()需要一個上下文,因爲可能有文本轉換和類似的東西。如果您不想擔心這一點,只需使用虛擬上下文。例如:

CTLineRef line; 

// create the line... 

UIGraphicsBeginImageContext(CGSizeMake(1, 1)); 
CGContextRef context = UIGraphicsGetCurrentContext(); 
CGContextSetTextPosition(context, 0, 0); 
CGRect bounds = CTLineGetImageBounds(line, context); 
UIGraphicsEndImageContext(); 

// use bounds... 
0

另一種方法是使用CTFontGetGlyphsForCharacters(),然後調用CTFontGetBoundingRectsForGlyphs()與字形排列,你從第一功能得到的字符串轉換字形。後一個函數返回「字形運行的總體邊界矩形」,所以不必擔心必須對單個邊界矩陣進行處理。如果在iOS中成功使用這兩個函數。

如果你這樣做,記住字形和字符之間的映射並不總是一一對應的,特別是當字符串有非英文字符時。