|
|
|
@ -855,6 +855,38 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
|
|
|
|
|
|
|
OWSMessageTextView *bodyTextView = [self configureBodyTextView];
|
|
|
|
|
CGSize textSize = CGSizeCeil([bodyTextView sizeThatFits:CGSizeMake(maxTextWidth, CGFLOAT_MAX)]);
|
|
|
|
|
|
|
|
|
|
// "Compact" layout to reduce "widows",
|
|
|
|
|
// e.g. last lines with only a single word.
|
|
|
|
|
//
|
|
|
|
|
// After measuring the size of the text, we try to find smaller widths
|
|
|
|
|
// in which the text will fit without adding any height, by wrapping
|
|
|
|
|
// more text onto the last line. We use a binary search.
|
|
|
|
|
if (textSize.width > 0 && textSize.height > 0) {
|
|
|
|
|
NSUInteger upperBound = (NSUInteger)textSize.width;
|
|
|
|
|
NSUInteger lowerBound = 1;
|
|
|
|
|
// The more iterations we perform in our binary search,
|
|
|
|
|
// the more accurate the result, but the more expensive
|
|
|
|
|
// layout becomes.
|
|
|
|
|
const int kMaxIterations = 5;
|
|
|
|
|
for (int i = 0; i < kMaxIterations; i++) {
|
|
|
|
|
NSUInteger resizeWidth = (upperBound + lowerBound) / 2;
|
|
|
|
|
if (resizeWidth >= upperBound || resizeWidth <= lowerBound) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
CGSize resizeSize = CGSizeCeil([bodyTextView sizeThatFits:CGSizeMake(resizeWidth, CGFLOAT_MAX)]);
|
|
|
|
|
BOOL success
|
|
|
|
|
= (resizeSize.width > 0 && resizeSize.width <= resizeWidth && resizeSize.height <= textSize.height);
|
|
|
|
|
if (success) {
|
|
|
|
|
// Success.
|
|
|
|
|
textSize = resizeSize;
|
|
|
|
|
upperBound = (NSUInteger)textSize.width;
|
|
|
|
|
} else {
|
|
|
|
|
// Failure.
|
|
|
|
|
lowerBound = resizeWidth;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
textSize.width = MIN(textSize.width, maxTextWidth);
|
|
|
|
|
CGSize result = textSize;
|
|
|
|
|
|
|
|
|
|