vade
vade

Reputation: 772

TextKit2 TextLayoutFragments bounds are incorrect for backgrounds when custom drawing?

Im working with TextKit 2 (which im relatively new at) and trying to understand why custom drawing attributed strings with background colors isnt working correctly (the origins are incorrectly set, see the attached image)

Im drawing text via NSTextLayoutManager (TextKit2) to a NSBitmapImageRep like so: (note, I handle the flippedness, etc, in the context with no problems)

if let context = NSGraphicsContext(bitmapImageRep: self.textImageRep!)
        {
            NSGraphicsContext.current = context
            
            let rect = NSRect(origin: .zero, size: self.outputSize)
            NSColor.clear.set()
            rect.fill()
            
            // Flip the context
            context.cgContext.saveGState()
            
            context.cgContext.translateBy(x: 0, y: self.outputSize.height)
            context.cgContext.scaleBy(x: 1.0, y: -1.0)

            let textOrigin = CGPoint(x: 0.0, y: 0.0 )
            
            let titleRect = CGRect(origin: textOrigin, size: self.themeTextContainer.size)
            NSColor.orange.withAlphaComponent(1).set()
            titleRect.fill()

            self.layoutManager.enumerateTextLayoutFragments(from: nil, using: { textLayoutFragment in

                // Get the fragment's rendering bounds
                let fragmentBounds = textLayoutFragment.layoutFragmentFrame

                print("fragmentBounds: \(fragmentBounds)")
                // Render the fragment into the context
                
                textLayoutFragment.draw(at: fragmentBounds.origin, in: context.cgContext)
                
                return true
            })
           
            context.cgContext.restoreGState()
        }
        
        NSGraphicsContext.restoreGraphicsState()

However if I try to draw the following Attributed string which has background colors set, i get the results pictured below:

        let titleParagraphStyle = NSMutableParagraphStyle()
        titleParagraphStyle.alignment = .center
        titleParagraphStyle.lineBreakMode = .byWordWrapping
        titleParagraphStyle.lineBreakStrategy = .standard
        
        var range = NSMakeRange(0, self.attributedProgrammingBlockTitle.length)
        self.attributedProgrammingBlockTitle.addAttribute(.foregroundColor, value: NSColor(red: 243.0/255.0, green: 97.0/255.0, blue: 97.0/255.0, alpha: 1.0), range:range)
        self.attributedProgrammingBlockTitle.addAttribute(.backgroundColor, value: NSColor.cyan, range:range)
        self.attributedProgrammingBlockTitle.addAttribute(.font, value: NSFont.systemFont(ofSize: 64), range:range)
        self.attributedProgrammingBlockTitle.addAttribute(.paragraphStyle, value:titleParagraphStyle, range:range)

        range = NSMakeRange(0, self.attributedThemeTitle.length)
        self.attributedThemeTitle.addAttribute(.foregroundColor, value: NSColor.white, range:range )
        self.attributedThemeTitle.addAttribute(.backgroundColor, value: NSColor.purple, range:range)
        self.attributedThemeTitle.addAttribute(.font, value: NSFont.systemFont(ofSize: 48), range:range)
        self.attributedThemeTitle.addAttribute(.paragraphStyle, value:NSParagraphStyle.default, range:range)

        range = NSMakeRange(0, self.attributedText.length)
        self.attributedText.addAttribute(.foregroundColor, value: NSColor.white, range:range )
        self.attributedText.addAttribute(.backgroundColor, value: NSColor.yellow, range:range)
        self.attributedText.addAttribute(.font, value: NSFont.systemFont(ofSize: 36), range:range)
        self.attributedText.addAttribute(.paragraphStyle, value:NSParagraphStyle.default, range:range)

        let allText = NSMutableAttributedString()
        
        allText.append(self.attributedProgrammingBlockTitle)
        allText.append(NSAttributedString(string: "\n\r"))
        allText.append(self.attributedThemeTitle)
        allText.append(NSAttributedString(string: "\n\r"))
        allText.append(self.attributedText)

        
        self.textStorage.textStorage?.beginEditing()
        self.textStorage.textStorage?.setAttributedString(allText)
        self.textStorage.textStorage?.endEditing()

        self.layoutManager.ensureLayout(for: self.layoutManager.documentRange)

enter image description here

Upvotes: 0

Views: 18

Answers (0)

Related Questions