From e8eaed2e1f7e1a28020e88273a47b730c332db80 Mon Sep 17 00:00:00 2001 From: David Richardson Date: Sat, 24 Oct 2026 12:50:16 -0600 Subject: [PATCH] AppKit: Correct vertical sizing calculation for resizable CPTextView instances Vertically resizable CPTextView instances previously calculated frame heights using metrics from the first character, second-to-last character, and extra line fragment, omitting the bounding box of the final character. Consequently, trailing elements such as bottom-anchored image attachments were clipped, and vertical scroll bars failed to match content bounds following scaling or layout updates. * AppKit/CPTextView/CPTextView.j: - Include the final character's bounding rectangle when computing view height to fit text. * Tests/Manual/TextEditor/WORKLIST.md: - Mark wide image fitting tests as completed. CPTextView containers now fully display trailing content and maintain accurate vertical scroll bar scaling. --- AppKit/CPTextView/CPTextView.j | 4 ++++ Tests/Manual/TextEditor/WORKLIST.md | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/AppKit/CPTextView/CPTextView.j b/AppKit/CPTextView/CPTextView.j index 04132395c..0c4f4491d 100644 --- a/AppKit/CPTextView/CPTextView.j +++ b/AppKit/CPTextView/CPTextView.j @@ -2658,6 +2658,10 @@ Sets the selection to a range of characters in response to user action. maxSize = [self maxSize], rect = CGRectUnion([_layoutManager boundingRectForGlyphRange:CPMakeRange(0, 1) inTextContainer:_textContainer], [_layoutManager boundingRectForGlyphRange:CPMakeRange(MAX(0, [_layoutManager numberOfCharacters] - 2), 1) inTextContainer:_textContainer]); + + // The last character can be taller than its line's text, as an image attachment at the end + // of the text is, so the view also fits it. + rect = CGRectUnion(rect, [_layoutManager boundingRectForGlyphRange:CPMakeRange(MAX(0, [_layoutManager numberOfCharacters] - 1), 1) inTextContainer:_textContainer]); if ([_layoutManager extraLineFragmentTextContainer] === _textContainer) rect = CGRectUnion(rect, [_layoutManager extraLineFragmentRect]); diff --git a/Tests/Manual/TextEditor/WORKLIST.md b/Tests/Manual/TextEditor/WORKLIST.md index cf38cfae0..651d380ac 100644 --- a/Tests/Manual/TextEditor/WORKLIST.md +++ b/Tests/Manual/TextEditor/WORKLIST.md @@ -15,7 +15,7 @@ TextEditor is a document-based test application and a tutorial. When the app use ### Text features not yet supported -- **Images in text are not fully tested or complete.** `CPTextAttachment` holds an image as one attachment character, and Edit > Insert Image… and Command-V with an image on the clipboard insert images. Not yet tested: several images inserted at once, fitting a wide image to the text width when the window is resized, copying, pasting and undoing an image within the document, and pasting a screenshot. Not yet implemented: dropping image files on the text view, which needs file access in the drag pasteboard (`_CPDOMDataTransferPasteboard`); pasting images with Edit > Paste from the menu, which reads plain text only; and RTF `\pict` and Markdown `![]()`, so an image is lost when text is copied to another application as RTF. +- **Images in text are not fully tested or complete.** `CPTextAttachment` holds an image as one attachment character, and Edit > Insert Image… and Command-V with an image on the clipboard insert images. Not yet tested: several images inserted at once, copying, pasting and undoing an image within the document, and pasting a screenshot. Not yet implemented: dropping image files on the text view, which needs file access in the drag pasteboard (`_CPDOMDataTransferPasteboard`); pasting images with Edit > Paste from the menu, which reads plain text only; and RTF `\pict` and Markdown `![]()`, so an image is lost when text is copied to another application as RTF. - **Lists are not read from or written to RTF.** `CPTextList` and `textLists` in `CPParagraphStyle` now exist, but the RTF parser and producer do not handle `\listtable`, `\listoverridetable`, `\ls` and `\ilvl`. A list copied as RTF keeps its marker text and indents, but loses its list structure. CPMarkdownParser also writes "- item" as the literal text " • item", with no list. ### Text view @@ -84,4 +84,5 @@ How the text system works, for the entries below: `CPTextView` does not use CSS - Typing at the end of styled text, and the font panel, use the style of the character before the insertion point. - Edit > Copy, Cut and Paste from the menu: plain text moves to and from other applications through the system clipboard; text copied and pasted within the application keeps its style. Command-V pastes text copied in another application, not an earlier copy within the application. - Edit > Insert Image…: a JPEG or PNG image is inserted inside the text and at the end of the text. +- A wide image fits the text width, and scales with the window without growing beyond its natural size. At the end of the text it is not clipped, and the scroll bars follow it. - Builds with both the legacy toolchain and capp-build.