2012-04-08 28 views
3

幾個帖子指出了從CTFramesetterSuggestFrameSizeWithConstraints獲取確切高度的困難,在這裏,(framesetter post),@Chris DeSalvo給出了看起來像確定性修正的內容:使用正確的行間距添加段落樣式設置調整。爲框架設定器提供正確的行間距調整

DeSalvo通過從其lineHeight中移除UIFont的上升和下降獲得他的「領先」。我想知道如何比較CTFontGetLeading

我喜歡這個創建字體的工作:

CTFontRef fontr = CTFontCreateWithName((CFStringRef)@"Helvetica Neue", 16.0f, NULL); 
UIFont *font = [UIFont fontWithName:@"Helvetica Neue" size:16.0f]; 

值有很大差異:

  • 0.448 CTFontGetLeading
  • 2.360 DeSalvo公式:UIFont lineHeight是 - 伸+伸

以下是一些其他UIFont值:

  • 21.000 UIFont的lineHeight是
  • 15.232 UIFont的上升段(從基線的y座標)
  • -3.408 UIFont的伸(從基線的y座標)
  • 08.368 UIFont的X字高

這裏是Ken Thomases詢問的CTFont值:

  • 11.568001 CTFontGetCapHeight
  • 08.368 CTFontGetXHeight
  • -15.216001,-7.696001,38.352001,24.928001 CTFontGetBoundingBox
  • 15.232 CTFontGetAscent
  • 03.408 CTFontGetDescent(類REF寫着「縮放字體下降度量縮放根據的點大小和矩陣字體引用」 - 這顯然意味着它是Y的絕對值從基線座標)

我注意到,UIFont以前有一個屬性專門爲?‘龍頭’,但它已被棄用,我們是 建議改爲使用lineHeight。因此,UIFont認爲對於相同的字體是和CTFontRef .448?有些事不對。

三個問題:

  1. 是「龍頭」真的是什麼意思kCTParagraphStyleSpecifierLineSpacingAdjustment?
  2. 如果是這樣,我應該使用哪種方法/公式來獲取它?
  3. 如果不是,我應該使用什麼行間距調整?
+0

我不認爲有人建議使用'lineHeight'作爲一個下拉更換爲主導。相反,我認爲這個建議是停止關注領先並考慮線高。也就是說,我無法調和CTFontGetLeading和公式之間的區別。其他CTFontGet ...函數給出了什麼(上升,邊界框高度,下降,頂點高度,X高度)? – 2012-04-09 16:13:22

+0

好主意。我已經將這些CTFontGet值添加到了問題中。我沒有看到任何會產生0.448的組合。我想知道在考慮* inter * -line間距時,我們如何考慮線高度,特別是當線高度被簡單定義爲「文本線的高度」時? – Wienke 2012-04-10 01:42:24

+0

您是否嘗試過設置'kCTParagraphStyleSpecifierMinimumLineHeight'而不是行間距調整?至少你對此有一定的價值。 – 2012-04-10 02:10:11

回答

0

答案的3個問題我上面有:

  1. 是「龍頭」真的是什麼意思kCTParagraphStyleSpecifierLineSpacingAdjustment。或者無論如何,它按預期工作。
  2. 使用CTFontGetLeading(fontRef)來獲取字體的正常開頭,或者插入任何你選擇的值(作爲CGFloat)。
  3. N/A。

答案1和2的工作:在你的屬性串的paragraphStyle屬性指定一家領先的值將啓用Core文本framesetter來計算其高度正好

有兩點需要說明:

  1. 如果您嘗試計算高度遞增,每次一個字符串,包含初始換行符每串,framesetter將考慮換行代表整個行,不只是領先。如果您想要連接字符串的高度,則必須將該連接饋送到框架設置器。當然,您可以跟蹤增量高度差異,但是無法避免讓搭架人員重新計算較早的字符串尺寸。
  2. CATextLayer忽略間距調整(和其他屬性)。如果根據確切的字符串高度構圖是個問題,則必須直接繪製CALayer。

還有一個謎團:UIFont的棄用領先是怎麼回事?領導和lineHeight是兩個截然不同的東西。

0

我也碰到了這一點,這裏是一個真正的項目工作的代碼:

// When you create an attributed string the default paragraph style has a leading 
// of 0.0. Create a paragraph style that will set the line adjustment equal to 
// the leading value of the font. This logic will ensure that the measured 
// height for a given paragraph of attributed text will be accurate wrt the font. 

- (void) applyParagraphAttributes:(CFMutableAttributedStringRef)mAttributedString 
{ 
    CGFloat leading = CTFontGetLeading(self.plainTextFont); 

    CTParagraphStyleSetting paragraphSettings[1] = { 
    kCTParagraphStyleSpecifierLineSpacingAdjustment, sizeof (CGFloat), &leading 
    }; 

    CTParagraphStyleRef paragraphStyle = CTParagraphStyleCreate(paragraphSettings, 1); 

    CFRange textRange = CFRangeMake(0, [self length]); 

    CFStringRef keys[] = { kCTParagraphStyleAttributeName }; 
    CFTypeRef values[] = { paragraphStyle }; 

    CFDictionaryRef attrValues = CFDictionaryCreate(kCFAllocatorDefault, 
                (const void**)&keys, 
                (const void**)&values, 
                sizeof(keys)/sizeof(keys[0]), 
                &kCFTypeDictionaryKeyCallBacks, 
                &kCFTypeDictionaryValueCallBacks); 

    BOOL clearOtherAttributes = FALSE; 
    CFAttributedStringSetAttributes(mAttributedString, textRange, attrValues, (Boolean)clearOtherAttributes); 
    CFRelease(attrValues); 

    CFRelease(paragraphStyle); 

    self.stringRange = textRange; 

    return; 
}