diff options
Diffstat (limited to 'bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/GC.java')
-rwxr-xr-x | bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/GC.java | 316 |
1 files changed, 111 insertions, 205 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/GC.java b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/GC.java index a19c4779fc..1066d50176 100755 --- a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/GC.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/GC.java @@ -738,7 +738,81 @@ static int /*long*/ createCGPathRef(NSBezierPath nsPath) { return 0; } - +void createLayout () { + NSSize size = new NSSize(); + size.width = Float.MAX_VALUE; + size.height = Float.MAX_VALUE; + NSTextStorage textStorage = (NSTextStorage)new NSTextStorage().alloc().init(); + NSLayoutManager layoutManager = (NSLayoutManager)new NSLayoutManager().alloc().init(); + layoutManager.setBackgroundLayoutEnabled(NSThread.isMainThread()); + NSTextContainer textContainer = (NSTextContainer)new NSTextContainer().alloc(); + textContainer = textContainer.initWithContainerSize(size); + textContainer.setLineFragmentPadding(0); + textStorage.addLayoutManager(layoutManager); + layoutManager.addTextContainer(textContainer); + layoutManager.release(); + textContainer.release(); + data.textContainer = textContainer; + data.layoutManager = layoutManager; + data.textStorage = textStorage; +} + +NSAttributedString createString(String string, int flags, boolean draw) { + NSMutableDictionary dict = ((NSMutableDictionary)new NSMutableDictionary().alloc()).initWithCapacity(5); + Font font = data.font; + dict.setObject(font.handle, OS.NSFontAttributeName); + font.addTraits(dict); + if (draw) { + Pattern pattern = data.foregroundPattern; + if (pattern != null) { + if (pattern.color != null) dict.setObject(pattern.color, OS.NSForegroundColorAttributeName); + } else { + NSColor fg = data.fg; + if (fg == null) { + float /*double*/ [] color = data.foreground; + fg = data.fg = NSColor.colorWithDeviceRed(color[0], color[1], color[2], data.alpha / 255f); + fg.retain(); + } + dict.setObject(fg, OS.NSForegroundColorAttributeName); + } + } + if ((flags & SWT.DRAW_TAB) == 0) { + dict.setObject(device.paragraphStyle, OS.NSParagraphStyleAttributeName); + } + int length = string.length(); + char[] chars = new char[length]; + string.getChars(0, length, chars, 0); + if ((flags & SWT.DRAW_MNEMONIC) !=0 || (flags & SWT.DRAW_DELIMITER) == 0) { + int i=0, j=0; + while (i < chars.length) { + char c = chars [j++] = chars [i++]; + switch (c) { + case '&': { + if ((flags & SWT.DRAW_MNEMONIC) != 0) { + if (i == chars.length) {continue;} + if (chars [i] == '&') {i++; continue;} + j--; + } + break; + } + case '\r': + case '\n': { + if ((flags & SWT.DRAW_DELIMITER) == 0) { + if (c == '\r' && i != chars.length && chars[i] == '\n') i++; + j--; + } + break; + } + } + } + length = j; + } + NSString str = ((NSString)new NSString().alloc()).initWithCharacters(chars, length); + NSAttributedString attribStr = ((NSAttributedString)new NSAttributedString().alloc()).initWithString(str, dict); + dict.release(); + str.release(); + return attribStr; +} NSBezierPath createNSBezierPath (int /*long*/ cgPath) { Callback callback = new Callback(this, "applierFunc", 2); @@ -818,6 +892,10 @@ void destroy() { image.memGC = null; image.createAlpha(); } + if (data.textStorage != null) data.textStorage.release(); + data.textStorage = null; + data.layoutManager = null; + data.textContainer = null; if (data.fg != null) data.fg.release(); if (data.bg != null) data.bg.release(); if (data.path != null) data.path.release(); @@ -1579,133 +1657,38 @@ public void drawText (String string, int x, int y, int flags) { case SWT.OFF: mode = false; break; case SWT.ON: mode = true; break; } - int /*long*/ context = handle.graphicsPort(); - OS.CGContextSaveGState(context); - OS.CGContextSetShouldAntialias(context, mode); - CGAffineTransform transform = new CGAffineTransform(); - transform.a = 1; - transform.d = -1; - Font font = data.font; - int /*long*/ fontID = font.handle.id; - if ((font.extraTraits & OS.NSItalicFontMask) != 0) { - transform.c = (float)Font.SYNTHETIC_ITALIC; - } - if ((font.extraTraits & OS.NSBoldFontMask) != 0) { - OS.CGContextSetTextDrawingMode(context, OS.kCGTextFillStroke); - OS.CGContextSetLineWidth(context, (float)(font.handle.pointSize() * -Font.SYNTHETIC_BOLD / 100f)); - } - OS.CGContextSetTextMatrix(context, transform); - char[] chars = new char[length]; - string.getChars(0, length, chars, 0); - if ((flags & SWT.DRAW_MNEMONIC) != 0 || (flags & SWT.DRAW_TAB) == 0) { - int i=0, j=0; - while (i < chars.length) { - char c = chars [j++] = chars [i++]; - switch (c) { - case '\t': { - if ((flags & SWT.DRAW_TAB) == 0) j--; - break; - } - case '&': { - if ((flags & SWT.DRAW_MNEMONIC) != 0) { - if (i == chars.length) {continue;} - if (chars [i] == '&') {i++; continue;} - j--; - } - break; - } - } - } - length = j; - } - int /*long*/ dict = OS.CFDictionaryCreateMutable(0, 2, OS.kCFTypeDictionaryKeyCallBacks(), OS.kCFTypeDictionaryValueCallBacks()); - OS.CFDictionaryAddValue(dict, OS.kCTFontAttributeName(), fontID); - int /*long*/ colorspace = OS.CGColorSpaceCreateDeviceRGB(); - float /*double*/ oldAlpha = data.foreground[3]; - data.foreground[3] = data.alpha / 255f; - int /*long*/ color = OS.CGColorCreate(colorspace, data.foreground); - data.foreground[3] = oldAlpha; - OS.CFDictionaryAddValue(dict, OS.kCTForegroundColorAttributeName(), color); - OS.CFRelease(color); - OS.CFRelease(colorspace); - int /*long*/ paragraphStyle = (data.style & SWT.RIGHT_TO_LEFT) != 0 ? device.paragraphStyleRTL : device.paragraphStyleLTR; - OS.CFDictionaryAddValue(dict, OS.kCTParagraphStyleAttributeName(), paragraphStyle); - int /*long*/ str = OS.CFStringCreateWithCharacters(0, chars, length); - int /*long*/ attrStr = OS.CFAttributedStringCreate(0, str, dict); - OS.CFRelease(dict); - OS.CFRelease(str); - float /*double*/ drawX = x, drawY = y; - float /*double*/ [] ascent = new float /*double*/ [1]; - float /*double*/ [] descent = new float /*double*/ [1]; - float /*double*/ [] leading = new float /*double*/ [1]; - float /*double*/ fontAscent = OS.CTFontGetAscent(fontID); - if ((flags & SWT.DRAW_DELIMITER) != 0) { - float /*double*/ fontDescent = OS.CTFontGetDescent(fontID); - float /*double*/ fontLeading = OS.CTFontGetLeading(fontID); - int /*long*/ typesetter = OS.CTTypesetterCreateWithAttributedString(attrStr); - int end = 0; - CFRange range = new CFRange(); - while (end < length) { - char c = chars[end++]; - switch (c) { - case '\r': - case '\n': { - range.length = end - range.location - 1; - if (c == '\r' && end != chars.length && chars[end] == '\n') end++; - if (range.length > 0) { - int /*long*/ line = OS.CTTypesetterCreateLine(typesetter, range); - drawText(context, flags, drawX, drawY, line, ascent, descent, leading, fontAscent); - OS.CFRelease(line); - drawY += ascent[0] + descent[0] + leading[0]; - } else { - drawY += fontAscent + fontDescent + fontLeading; - } - range.location = end; - } - } - } - if (range.location != end) { - range.length = end - range.location; - int /*long*/ line = OS.CTTypesetterCreateLine(typesetter, range); - drawText(context, flags, drawX, drawY, line, ascent, descent, leading, fontAscent); - OS.CFRelease(line); + handle.saveGraphicsState(); + handle.setShouldAntialias(mode); + if (data.textStorage == null) createLayout(); + NSAttributedString attribStr = createString(string, flags, true); + data.textStorage.setAttributedString(attribStr); + attribStr.release(); + NSPoint pt = new NSPoint(); + pt.x = x; + pt.y = y; + if ((flags & SWT.DRAW_TRANSPARENT) == 0) { + data.layoutManager.glyphRangeForTextContainer(data.textContainer); + NSRect rect = data.layoutManager.usedRectForTextContainer(data.textContainer); + rect.x = x; + rect.y = y; + NSColor bg = data.bg; + if (bg == null) { + float /*double*/ [] color = data.background; + bg = data.bg = NSColor.colorWithDeviceRed(color[0], color[1], color[2], data.alpha / 255f); + bg.retain(); } - OS.CFRelease(typesetter); - } else { - int /*long*/ line = OS.CTLineCreateWithAttributedString(attrStr); - drawText(context, flags, drawX, drawY, line, ascent, descent, leading, fontAscent); - OS.CFRelease(line); + bg.setFill(); + NSBezierPath.fillRect(rect); } - OS.CFRelease(attrStr); - OS.CGContextRestoreGState(context); + NSRange range = new NSRange(); + range.length = data.layoutManager.numberOfGlyphs(); + data.layoutManager.drawGlyphsForGlyphRange(range, pt); + handle.restoreGraphicsState(); } finally { uncheckGC(pool); } } -void drawText (int /*long*/ context, int flags, float /*double*/ x, float /*double*/ y, int /*long*/ line, float /*double*/ [] ascent, float /*double*/ [] descent, float /*double*/ [] leading, float /*double*/ fontAscent) { - double width = 0; - if ((flags & SWT.DRAW_DELIMITER) != 0 || (flags & SWT.DRAW_TRANSPARENT) == 0) { - width = OS.CTLineGetTypographicBounds(line, ascent, descent, leading); - } - if ((flags & SWT.DRAW_TRANSPARENT) == 0) { - CGRect rect = new CGRect(); - rect.origin.x = x; - rect.origin.y = y; - rect.size.width = (float)Math.ceil(width); - rect.size.height = (float)Math.ceil(ascent[0] + descent[0] + leading[0]); - OS.CGContextSaveGState(context); - float /*double*/ oldAlpha = data.background[3]; - data.background[3] = data.alpha / 255f; - OS.CGContextSetFillColor(context, data.background); - data.background[3] = oldAlpha; - OS.CGContextFillRect(context, rect); - OS.CGContextRestoreGState(context); - } - OS.CGContextSetTextPosition(context, x, y + fontAscent); - OS.CTLineDraw(line, context); -} - /** * Compares the argument to the receiver, and returns true * if they represent the <em>same</em> object using a class @@ -3927,90 +3910,13 @@ public Point textExtent(String string, int flags) { NSAutoreleasePool pool = checkGC(FONT); try { int length = string.length(); - Font font = data.font; - int /*long*/ fontID = font.handle.id; - if (length == 0) { - return new Point(0, (int)(0.5f + OS.CTFontGetAscent(fontID)) + (int)(0.5f + OS.CTFontGetDescent(fontID) + OS.CTFontGetLeading(fontID))); - } - char[] chars = new char[length]; - string.getChars(0, length, chars, 0); - if ((flags & SWT.DRAW_MNEMONIC) != 0 || (flags & SWT.DRAW_TAB) == 0) { - int i=0, j=0; - while (i < chars.length) { - char c = chars [j++] = chars [i++]; - switch (c) { - case '\t': { - if ((flags & SWT.DRAW_TAB) == 0) j--; - break; - } - case '&': { - if ((flags & SWT.DRAW_MNEMONIC) != 0) { - if (i == chars.length) {continue;} - if (chars [i] == '&') {i++; continue;} - j--; - } - break; - } - } - } - length = j; - } - int /*long*/ dict = OS.CFDictionaryCreateMutable(0, 1, OS.kCFTypeDictionaryKeyCallBacks(), OS.kCFTypeDictionaryValueCallBacks()); - OS.CFDictionaryAddValue(dict, OS.kCTFontAttributeName(), font.handle.id); - int /*long*/ paragraphStyle = (data.style & SWT.RIGHT_TO_LEFT) != 0 ? device.paragraphStyleRTL : device.paragraphStyleLTR; - OS.CFDictionaryAddValue(dict, OS.kCTParagraphStyleAttributeName(), paragraphStyle); - int /*long*/ str = OS.CFStringCreateWithCharacters(0, chars, length); - int /*long*/ attrStr = OS.CFAttributedStringCreate(0, str, dict); - OS.CFRelease(dict); - OS.CFRelease(str); - float /*double*/ [] ascent = new float /*double*/ [1]; - float /*double*/ [] descent = new float /*double*/ [1]; - float /*double*/ [] leading = new float /*double*/ [1]; - double width = 0, height = 0; - if ((flags & SWT.DRAW_DELIMITER) != 0) { - float /*double*/ fontAscent = OS.CTFontGetAscent(fontID); - float /*double*/ fontDescent = OS.CTFontGetDescent(fontID); - float /*double*/ fontLeading = OS.CTFontGetLeading(fontID); - int /*long*/ typesetter = OS.CTTypesetterCreateWithAttributedString(attrStr); - int end = 0; - CFRange range = new CFRange(); - while (end < length) { - char c = chars[end++]; - switch (c) { - case '\r': - case '\n': { - range.length = end - range.location - 1; - if (c == '\r' && end != chars.length && chars[end] == '\n') end++; - if (range.length > 0) { - int /*long*/ line = OS.CTTypesetterCreateLine(typesetter, range); - width = Math.max(width, OS.CTLineGetTypographicBounds(line, ascent, descent, leading)); - height += ascent[0] + descent[0] + leading[0]; - OS.CFRelease(line); - } else { - height += fontAscent + fontDescent + fontLeading; - } - range.location = end; - } - } - } - if (range.location != end) { - range.length = end - range.location; - int /*long*/ line = OS.CTTypesetterCreateLine(typesetter, range); - width = Math.max(width, OS.CTLineGetTypographicBounds(line, ascent, descent, leading)); - height += ascent[0] + descent[0] + leading[0]; - OS.CFRelease(line); - } else { - height += fontAscent + fontDescent + fontLeading; - } - OS.CFRelease(typesetter); - } else { - int /*long*/ line = OS.CTLineCreateWithAttributedString(attrStr); - width = OS.CTLineGetTypographicBounds(line, ascent, descent, leading); - height = ascent[0] + descent[0] + leading[0]; - OS.CFRelease(line); - } - OS.CFRelease(attrStr); - return new Point((int)Math.ceil(width), (int)Math.ceil(height)); + if (data.textStorage == null) createLayout(); + NSAttributedString attribStr = createString(length == 0 ? " " : string, flags, true); //$NON-NLS-1$ + data.textStorage.setAttributedString(attribStr); + attribStr.release(); + data.layoutManager.glyphRangeForTextContainer(data.textContainer); + NSRect rect = data.layoutManager.usedRectForTextContainer(data.textContainer); + return new Point(length == 0 ? 0 : (int)Math.ceil(rect.width), (int)Math.ceil(rect.height)); } finally { uncheckGC(pool); } |