-
Notifications
You must be signed in to change notification settings - Fork 806
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve perf for CTFramesetterSuggestFrameSizeWithConstraints #1603
Changes from 6 commits
1191d4a
914dc37
550dd01
c3bbc8f
16d3b26
5f9610b
df0f4f7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -25,6 +25,7 @@ | |
#import <StringHelpers.h> | ||
#import <vector> | ||
#import <iterator> | ||
#import <numeric> | ||
|
||
using namespace std; | ||
using namespace Microsoft::WRL; | ||
|
@@ -522,4 +523,61 @@ HRESULT STDMETHODCALLTYPE GetPixelsPerDip(_In_opt_ void* clientDrawingContext, _ | |
} | ||
|
||
return frame; | ||
} | ||
|
||
static CGSize _DWriteGetFrameSize(CFAttributedStringRef string, CFRange range, CGSize maxSize, CFRange* fitRange) { | ||
CGSize ret = CGSizeZero; | ||
|
||
// Treat range.length of 0 as unlimited length | ||
if (range.length == 0L) { | ||
range.length = CFAttributedStringGetLength(string) - range.location; | ||
} | ||
|
||
// No text to draw, just return CGSizeZero | ||
if (!string || range.length <= 0L) { | ||
return ret; | ||
} | ||
|
||
ComPtr<IDWriteTextLayout> textLayout; | ||
if (FAILED(__DWriteTextLayoutCreate(string, range, { CGPointZero, maxSize }, &textLayout))) { | ||
return ret; | ||
} | ||
|
||
DWRITE_TEXT_METRICS textMetrics; | ||
if (FAILED(textLayout->GetMetrics(&textMetrics))) { | ||
return ret; | ||
} | ||
|
||
// TODO:: find more precise value than 1.0 to increase width by to fully enclose frame | ||
ret.width = std::min(maxSize.width, textMetrics.widthIncludingTrailingWhitespace + 1.0f); | ||
ret.height = std::min(maxSize.height, textMetrics.height); | ||
|
||
if (fitRange) { | ||
*fitRange = { range.location, 0L }; | ||
uint32_t lineCount = 0; | ||
|
||
// Should return E_NOT_SUFFICIENT_BUFFER and popluate lineCount | ||
if (textLayout->GetLineMetrics(nullptr, 0, &lineCount) != E_NOT_SUFFICIENT_BUFFER) { | ||
return ret; | ||
} | ||
|
||
std::vector<DWRITE_LINE_METRICS> metrics(lineCount); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
since this is about performance, use array rather than a vector here (you will have a slight gain) #Closed There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
if (FAILED(textLayout->GetLineMetrics(metrics.data(), lineCount, &lineCount))) { | ||
return ret; | ||
} | ||
|
||
float totalHeight = 0; | ||
CFIndex endPos = range.location; | ||
for (auto metric : metrics) { | ||
totalHeight += metric.baseline; | ||
if (totalHeight > ret.height) { | ||
break; | ||
} | ||
endPos += metric.length; | ||
} | ||
|
||
fitRange->length = endPos; | ||
} | ||
|
||
return ret; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"If the length portion of the range is set to 0, then the framesetter continues to add lines until it runs out of text or space."
This does not seem to match that behaviour #Closed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wut? #Closed