简体   繁体   English

在 NSLayoutManager 中获取完全位于给定矩形中的一系列字形

[英]Getting a range of glyphs lying wholly in the given rect in NSLayoutManager

I'm trying to retrieve a glyph range for the given bounds in NSLayoutManager .我正在尝试检索NSLayoutManager中给定边界的字形范围。 The built-in methods return the range for glyphs that are wholly or partially lying inside the bounds, and I need to find out which actually fit it.内置方法返回完全或部分位于边界内的字形范围,我需要找出真正适合它的字形。

For example:例如:

在此处输入图像描述

let glyphRange = textView.layoutManager!.glyphRange(forBoundingRect: scrollView.contentView.bounds, in: textView.textContainer!)
let charRange = textView.layoutManager!.characterRange(forGlyphRange: glyphRange, actualGlyphRange: nil)

let range = Range(charRange, in: string)

string[range] now produces a substring up to "not listening to explanations useless" . string[range]现在产生一个 substring 到"not listening to explanations useless"

I've tried creating a substring and removing stuff word by word, until the height of the string fits my needs, but that becomes very slow.我尝试创建一个 substring 并逐字删除内容,直到字符串的高度符合我的需要,但这变得非常慢。 I'm writing a method (for both macOS and iOS) which has to take care of hundreds of such calculations in a very short time.我正在编写一个方法(适用于 macOS 和 iOS),它必须在很短的时间内处理数百个这样的计算。

How could I return the range for glyphs wholly inside the bounds?我怎样才能返回完全在边界内的字形范围?

This can be achieved by enumerating line fragments.这可以通过枚举行片段来实现。 They are already laid out, so it comes with not much extra cost.它们已经布置好,因此不需要太多额外费用。

let desiredHeight = 300
var height = 0.0
textView.layoutManager!.enumerateLineFragments(forGlyphRange: glyphRange) { rect, usedRect, container, range, stop in
    if usedRect.height + usedRect.origin.y <= desiredHeight {
        height += usedRect.height 
    }
}

let newBounds = NSRect(x: 0, y:0, width: width, height: height)
let newGlyphRange = textView.layoutManager!.glyphRange(forBoundingRect: scrollView.contentView.bounds, in: textView.textContainer!)
let newCharRange = textView.layoutManager!.characterRange(forGlyphRange: newGlyphRange, actualGlyphRange: nil)

let newRange = Range(newCharRange, in: string)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM