diff options
author | culler <culler> | 2020-04-15 14:50:25 (GMT) |
---|---|---|
committer | culler <culler> | 2020-04-15 14:50:25 (GMT) |
commit | f098336486ba362a5b694d93a949fe6e8b23891a (patch) | |
tree | 4743af7c26b1997d307402b569087d726ec8b725 | |
parent | dde225234751ae9a30fa720114257cdd352250b7 (diff) | |
parent | b4f276f52906366f518ba93803324d4e78db4f8e (diff) | |
download | tk-f098336486ba362a5b694d93a949fe6e8b23891a.zip tk-f098336486ba362a5b694d93a949fe6e8b23891a.tar.gz tk-f098336486ba362a5b694d93a949fe6e8b23891a.tar.bz2 |
Fix [89354dae31]: Avoid clipping in Aqua TkpDrawCharsInContext. Clipping does not work and is also inefficient.
-rw-r--r-- | macosx/tkMacOSXFont.c | 51 |
1 files changed, 29 insertions, 22 deletions
diff --git a/macosx/tkMacOSXFont.c b/macosx/tkMacOSXFont.c index c3b0b66..2d8168d 100644 --- a/macosx/tkMacOSXFont.c +++ b/macosx/tkMacOSXFont.c @@ -1243,19 +1243,19 @@ DrawCharsInContext( NSMutableDictionary *attributes; NSAttributedString *attributedString; CTTypesetterRef typesetter; - CFIndex start, len; - CTLineRef line; + CFIndex start, length; + CTLineRef line, full=nil; MacDrawable *macWin = (MacDrawable *) drawable; TkMacOSXDrawingContext drawingContext; CGContextRef context; CGColorRef fg; NSFont *nsFont; CGAffineTransform t; - int h; + CGFloat width, height, textX = (CGFloat) x, textY = (CGFloat) y; - if (rangeStart < 0 || rangeLength <= 0 || - rangeStart + rangeLength > numBytes || - !TkMacOSXSetupDrawingContext(drawable, gc, 1, &drawingContext)) { + if (rangeStart < 0 || rangeLength <= 0 || + rangeStart + rangeLength > numBytes || + !TkMacOSXSetupDrawingContext(drawable, gc, 1, &drawingContext)) { return; } string = TkUtfToNSString((const char *)source, numBytes); @@ -1275,29 +1275,36 @@ DrawCharsInContext( attributes:attributes]; typesetter = CTTypesetterCreateWithAttributedString( (CFAttributedStringRef)attributedString); - x += macWin->xOff; - y += macWin->yOff; - h = drawingContext.portBounds.size.height; - y = h - y; - t = CGAffineTransformMake(1.0, 0.0, 0.0, -1.0, 0.0, h); + textX += (CGFloat) macWin->xOff; + textY += (CGFloat) macWin->yOff; + height = drawingContext.portBounds.size.height; + textY = height - textY; + t = CGAffineTransformMake(1.0, 0.0, 0.0, -1.0, 0.0, height); if (angle != 0.0) { - t = CGAffineTransformTranslate(CGAffineTransformRotate( - CGAffineTransformTranslate(t, x, y), angle*PI/180.0), -x, -y); + t = CGAffineTransformTranslate( + CGAffineTransformRotate( + CGAffineTransformTranslate(t, textX, textY), angle*PI/180.0), + -textX, -textY); } CGContextConcatCTM(context, t); - CGContextSetTextPosition(context, x, y); start = Tcl_NumUtfChars(source, rangeStart); - len = Tcl_NumUtfChars(source, rangeStart + rangeLength); + length = Tcl_NumUtfChars(source, rangeStart + rangeLength) - start; + line = CTTypesetterCreateLine(typesetter, CFRangeMake(start, length)); if (start > 0) { - CGRect clipRect = CGRectInfinite, startBounds; - line = CTTypesetterCreateLine(typesetter, CFRangeMake(0, start)); - startBounds = CTLineGetImageBounds(line, context); - CFRelease(line); - clipRect.origin.x = startBounds.origin.x + startBounds.size.width; - CGContextClipToRect(context, clipRect); + /* + * We are only drawing part of the string. To compute the x coordinate + * of the part we are drawing we subtract its typographical length from + * the typographical length of the full string. This accounts for the + * kerning after the initial part of the string. + */ + + full = CTTypesetterCreateLine(typesetter, CFRangeMake(0, start + length)); + width = CTLineGetTypographicBounds(full, NULL, NULL, NULL); + CFRelease(full); + textX += (width - CTLineGetTypographicBounds(line, NULL, NULL, NULL)); } - line = CTTypesetterCreateLine(typesetter, CFRangeMake(0, len)); + CGContextSetTextPosition(context, textX, textY); CTLineDraw(line, context); CFRelease(line); CFRelease(typesetter); |