Mixing CTRunDraw and drawAtPoint
<p>I wrote a module that provides several methods to render text and create PDF files. Now I find that using Core Text along with higher level text rendering messes up the size of the Core Text layout. The later is mainly displayed too large.</p>

<p><em>Scenario:</em></p>

<ul>
<li>Create a PDF context</li>
<li>Beginn a page</li>
<li>Render text via <code>CTRunDraw</code> (B) *</li>
<li>End a page</li>
<li>Close PDF context</li>
<li>Save PDF</li>
</ul>

<p>*) This gets rendered properly, as expected. <em>But only as long as I don’t draw</em> any text using a <code>NSAttributedString</code> and <code>drawAtPoint_</code> (A) before.</p>

<p>This means, both methods work perfectly on their own, but the core text drawing gets too large when they both come together.</p>

<p>Is there something to take care of when saving and restoring the graphics context? I tried almost anything. I can put some code here, but it’s quite a lot and in a complex setup, so if you can specify what you exactly want to see, please let me know.</p>

<p><strong>(A)</strong> The high level text drawing:</p>

<pre><code>class Text(object):

    def __init__(self, text="", font="Monaco", fontSize=12, position=None ):
        self.text = text
        self.font = font
        self.fontSize = fontSize
        self.position = position
        self.fontRGBColor = 0, 1, 1, 1

    def drawText(self):
        textAttributes = {}
        textAttributes[NSFontAttributeName] = NSFont.fontWithName_size_( self.font, self.fontSize )
        textAttributes[NSForegroundColorAttributeName] = NSColor.colorWithCalibratedRed_green_blue_alpha_( *self.fontRGBColor )
        textAttributedString = NSAttributedString.alloc().initWithString_attributes_( self.text, textAttributes )
        textAttributedString.drawAtPoint_((self.position[0], self.position[1]))
</code></pre>

<p><strong>(B)</strong> The core text method:</p>

<pre><code>class TextBox(object):
    def __init__(self):
        self.font = "Monaco"
        self.fontSize = 12
        self.text = "This is my Text"
        self.fontColor = 0, 1, 1, 0, 0.75

        self.pdfContext = NSGraphicsContext.currentContext().graphicsPort()


    def drawTextBox(self):
        CGContextSaveGState(self.pdfContext)

        myBounds = (0, 0), (100, 100)
        posX, posY = myBounds[0]
        width, height = myBounds[1]

        self.fontObject = NSFont.fontWithName_size_(self.font, self.fontSize)
        self.fontAttributes = {}
        self.fontAttributes[NSFontAttributeName] = self.fontObject
        self.fontAttributes[NSForegroundColorAttributeName] = NSColor.colorWithDeviceCyan_magenta_yellow_black_alpha_(*self.fontColor)

        TextBoxWithFeaturesAttributedString = NSMutableAttributedString.alloc().initWithString_attributes_(self.text, self.fontAttributes)
        setter = CTFramesetterCreateWithAttributedString(TextBoxWithFeaturesAttributedString)
        path = CGPathCreateMutable()

        CGPathAddRect(path, None, CGRectMake(0, 0, width, height))
        box = CTFramesetterCreateFrame(setter, (0, 0), path, None)
        ctLines = CTFrameGetLines(box)
        origins = CTFrameGetLineOrigins(box, (0, len(ctLines)), None)

        for i, (originX, originY) in enumerate(origins):
            ctLine = ctLines[i]
            bounds = CTLineGetImageBounds(ctLine, self.pdfContext)
            if bounds.size.width == 0:
                continue
            ctRuns = CTLineGetGlyphRuns(ctLine)
            for ctRun in ctRuns:
                CGContextSetTextPosition(self.pdfContext, posX + originX, posY + originY)
                CTRunDraw(ctRun, self.pdfContext, (0, 0))

        CGContextRestoreGState(self.pdfContext)
</code></pre>

<p>Many thanks and appreciations in advance.</p>