comparison dwt/graphics/TextLayout.d @ 60:62202ce0039f

Updated and fixed many modules to 3.514
author Jacob Carlborg <doob@me.com>
date Mon, 22 Dec 2008 15:10:19 +0100
parents cfa563df4fdd
children 1a0129cab08e
comparison
equal deleted inserted replaced
59:83b0ad9d9238 60:62202ce0039f
48 import dwt.graphics.Point; 48 import dwt.graphics.Point;
49 import dwt.graphics.Rectangle; 49 import dwt.graphics.Rectangle;
50 import dwt.graphics.Region; 50 import dwt.graphics.Region;
51 import dwt.graphics.Resource; 51 import dwt.graphics.Resource;
52 import dwt.graphics.TextStyle; 52 import dwt.graphics.TextStyle;
53 import dwt.internal.c.Carbon; 53 import Carbon = dwt.internal.c.Carbon;
54 import dwt.internal.cocoa.NSText; 54 import dwt.internal.cocoa.NSText;
55 import dwt.internal.objc.cocoa.Cocoa; 55 import dwt.internal.objc.cocoa.Cocoa;
56 56
57 /** 57 /**
58 * <code>TextLayout</code> is a graphic object that represents 58 * <code>TextLayout</code> is a graphic object that represents
92 int orientation; 92 int orientation;
93 93
94 int[] lineOffsets; 94 int[] lineOffsets;
95 NSRect[] lineBounds; 95 NSRect[] lineBounds;
96 96
97 static final int UNDERLINE_THICK = 1 << 16; 97 static const int UNDERLINE_THICK = 1 << 16;
98 98
99 static class StyleItem { 99 static class StyleItem {
100 TextStyle style; 100 TextStyle style;
101 int start; 101 int start;
102 102
147 int width = 2 * height; // must be even 147 int width = 2 * height; // must be even
148 int peaks = Compatibility.ceil(right - left, width); 148 int peaks = Compatibility.ceil(right - left, width);
149 if (peaks is 0 && right - left > 2) { 149 if (peaks is 0 && right - left > 2) {
150 peaks = 1; 150 peaks = 1;
151 } 151 }
152 int length = ((2 * peaks) + 1) * 2; 152 int length_ = ((2 * peaks) + 1) * 2;
153 if (length < 0) return new float[0]; 153 if (length_ < 0) return new float[0];
154 154
155 float[] coordinates = new float[length]; 155 float[] coordinates = new float[length_];
156 for (int i = 0; i < peaks; i++) { 156 for (int i = 0; i < peaks; i++) {
157 int index = 4 * i; 157 int index = 4 * i;
158 coordinates[index] = left + (width * i); 158 coordinates[index] = left + (width * i);
159 coordinates[index+1] = bottom; 159 coordinates[index+1] = bottom;
160 coordinates[index+2] = coordinates[index] + width / 2; 160 coordinates[index+2] = coordinates[index] + width / 2;
161 coordinates[index+3] = top; 161 coordinates[index+3] = top;
162 } 162 }
163 coordinates[length-2] = left + (width * peaks); 163 coordinates[length_-2] = left + (width * peaks);
164 coordinates[length-1] = bottom; 164 coordinates[length_-1] = bottom;
165 return coordinates; 165 return coordinates;
166 } 166 }
167 167
168 void computeRuns() { 168 void computeRuns() {
169 if (textStorage !is null) return; 169 if (textStorage !is null) return;
184 NSRange range = NSRange(); 184 NSRange range = NSRange();
185 range.length = str.length(); 185 range.length = str.length();
186 textStorage.addAttribute(OS.NSFontAttributeName, defaultFont.handle, range); 186 textStorage.addAttribute(OS.NSFontAttributeName, defaultFont.handle, range);
187 187
188 NSMutableParagraphStyle paragraph = cast(NSMutableParagraphStyle)(new NSMutableParagraphStyle()).alloc().init(); 188 NSMutableParagraphStyle paragraph = cast(NSMutableParagraphStyle)(new NSMutableParagraphStyle()).alloc().init();
189 NSTextAlignment align_ = NSLeftTextAlignment; 189 NSTextAlignment align_ = OS.NSLeftTextAlignment;
190 if (justify) { 190 if (justify) {
191 align_ = NSJustifiedTextAlignment; 191 align_ = OS.NSJustifiedTextAlignment;
192 } else { 192 } else {
193 switch (alignment) { 193 switch (alignment) {
194 case DWT.CENTER: 194 case DWT.CENTER:
195 align_ = NSCenterTextAlignment; 195 align_ = OS.NSCenterTextAlignment;
196 break; 196 break;
197 case DWT.RIGHT: 197 case DWT.RIGHT:
198 align_ = NSRightTextAlignment; 198 align_ = OS.NSRightTextAlignment;
199 } 199 }
200 } 200 }
201 paragraph.setAlignment(align_); 201 paragraph.setAlignment(align_);
202 paragraph.setLineSpacing(spacing); 202 paragraph.setLineSpacing(spacing);
203 paragraph.setFirstLineHeadIndent(indent); 203 paragraph.setFirstLineHeadIndent(indent);
285 layoutManager.glyphRangeForTextContainer(textContainer); 285 layoutManager.glyphRangeForTextContainer(textContainer);
286 286
287 int numberOfLines; 287 int numberOfLines;
288 NSUInteger numberOfGlyphs = layoutManager.numberOfGlyphs(), index; 288 NSUInteger numberOfGlyphs = layoutManager.numberOfGlyphs(), index;
289 NSRangePointer rangePtr = cast(NSRangePointer) OS.malloc(NSRange.sizeof); 289 NSRangePointer rangePtr = cast(NSRangePointer) OS.malloc(NSRange.sizeof);
290 NSRange lineRange = NSRange();
290 for (numberOfLines = 0, index = 0; index < numberOfGlyphs; numberOfLines++){ 291 for (numberOfLines = 0, index = 0; index < numberOfGlyphs; numberOfLines++){
291 layoutManager.lineFragmentUsedRectForGlyphAtIndex(index, rangePtr, true); 292 layoutManager.lineFragmentUsedRectForGlyphAtIndex(index, rangePtr, true);
292 OS.memmove(&lineRange, rangePtr, NSRange.sizeof); 293 OS.memmove(&lineRange, rangePtr, NSRange.sizeof);
293 index = lineRange.location + lineRange.length; 294 index = lineRange.location + lineRange.length;
294 } 295 }
295 if (numberOfLines is 0) numberOfLines++; 296 if (numberOfLines is 0) numberOfLines++;
296 int[] offsets = new int[numberOfLines + 1]; 297 int[] offsets = new int[numberOfLines + 1];
297 NSRect[] bounds = new NSRect[numberOfLines]; 298 NSRect[] bounds = new NSRect[numberOfLines];
298 for (numberOfLines = 0, index = 0; index < numberOfGlyphs; numberOfLines++){ 299 for (numberOfLines = 0, index = 0; index < numberOfGlyphs; numberOfLines++){
299 bounds[numberOfLines] = layoutManager.lineFragmentUsedRectForGlyphAtIndex(index, rangePtr, true); 300 bounds[numberOfLines] = layoutManager.lineFragmentUsedRectForGlyphAtIndex(index, rangePtr, true);
300 if (numberOfLines < bounds.length - 1) bounds[numberOfLines].height -= spacing; 301 if (numberOfLines < bounds.length - 1) bounds[numberOfLines].height = bounds[numberOfLines].height - spacing;
301 OS.memmove(&lineRange, rangePtr, NSRange.sizeof); 302 OS.memmove(&lineRange, rangePtr, NSRange.sizeof);
302 offsets[numberOfLines] = cast(int)/*64*/lineRange.location; 303 offsets[numberOfLines] = cast(int)/*64*/lineRange.location;
303 index = lineRange.location + lineRange.length; 304 index = lineRange.location + lineRange.length;
304 } 305 }
305 if (numberOfLines is 0) { 306 if (numberOfLines is 0) {
413 if (hasSelection || (flags & DWT.LAST_LINE_SELECTION) !is 0) { 414 if (hasSelection || (flags & DWT.LAST_LINE_SELECTION) !is 0) {
414 if (selectionBackground is null) selectionBackground = device.getSystemColor(DWT.COLOR_LIST_SELECTION); 415 if (selectionBackground is null) selectionBackground = device.getSystemColor(DWT.COLOR_LIST_SELECTION);
415 selectionColor = NSColor.colorWithDeviceRed(selectionBackground.handle[0], selectionBackground.handle[1], selectionBackground.handle[2], selectionBackground.handle[3]); 416 selectionColor = NSColor.colorWithDeviceRed(selectionBackground.handle[0], selectionBackground.handle[1], selectionBackground.handle[2], selectionBackground.handle[3]);
416 } 417 }
417 if (hasSelection) { 418 if (hasSelection) {
418 selectionRange = NSRange(); 419 selectionRange = &NSRange();
419 selectionRange.location = selectionStart; 420 selectionRange.location = selectionStart;
420 selectionRange.length = selectionEnd - selectionStart + 1; 421 selectionRange.length = selectionEnd - selectionStart + 1;
421 layoutManager.addTemporaryAttribute(OS.NSBackgroundColorAttributeName, selectionColor, *selectionRange); 422 layoutManager.addTemporaryAttribute(OS.NSBackgroundColorAttributeName, selectionColor, *selectionRange);
422 } 423 }
423 //TODO draw selection for flags (DELIMITER_SELECTION) 424 //TODO draw selection for flags (DELIMITER_SELECTION)
476 switch (style.underlineStyle) { 477 switch (style.underlineStyle) {
477 case DWT.UNDERLINE_ERROR: { 478 case DWT.UNDERLINE_ERROR: {
478 path.setLineWidth(2f); 479 path.setLineWidth(2f);
479 path.setLineCapStyle(OS.NSRoundLineCapStyle); 480 path.setLineCapStyle(OS.NSRoundLineCapStyle);
480 path.setLineJoinStyle(OS.NSRoundLineJoinStyle); 481 path.setLineJoinStyle(OS.NSRoundLineJoinStyle);
481 path.setLineDash([1, 3f], 2, 0); 482 path.setLineDash([1f, 3f].ptr, 2, cast(Carbon.CGFloat) 0);
482 point.x = underlineX; 483 point.x = underlineX;
483 point.y = underlineY + 0.5f; 484 point.y = underlineY + 0.5f;
484 path.moveToPoint(point); 485 path.moveToPoint(point);
485 point.x = underlineX + rect.width; 486 point.x = underlineX + rect.width;
486 point.y = underlineY + 0.5f; 487 point.y = underlineY + 0.5f;
523 range.location = layoutManager.glyphIndexForCharacterAtIndex(Math.max(lineStart, start)); 524 range.location = layoutManager.glyphIndexForCharacterAtIndex(Math.max(lineStart, start));
524 range.length = layoutManager.glyphIndexForCharacterAtIndex(Math.min(lineEnd, end) + 1) - range.location; 525 range.length = layoutManager.glyphIndexForCharacterAtIndex(Math.min(lineEnd, end) + 1) - range.location;
525 if (range.length > 0) { 526 if (range.length > 0) {
526 gc.handle.saveGraphicsState(); 527 gc.handle.saveGraphicsState();
527 NSRect rect = layoutManager.boundingRectForGlyphRange(range, textContainer); 528 NSRect rect = layoutManager.boundingRectForGlyphRange(range, textContainer);
528 rect.x += pt.x + 0.5f; 529 rect.x = rect.x + pt.x + 0.5f;
529 rect.y += pt.y + 0.5f; 530 rect.y = rect.y + pt.y + 0.5f;
530 rect.width -= 0.5f; 531 rect.width = rect.width - 0.5f;
531 rect.height -= 0.5f; 532 rect.height = rect.height - 0.5f;
532 float[] color = null; 533 Carbon.CGFloat[] color = null;
533 if (style.borderColor !is null) color = style.borderColor.handle; 534 if (style.borderColor !is null) color = style.borderColor.handle;
534 if (color is null && style.foreground !is null) color = style.foreground.handle; 535 if (color is null && style.foreground !is null) color = style.foreground.handle;
535 if (color !is null) { 536 if (color !is null) {
536 NSColor.colorWithDeviceRed(color[0], color[1], color[2], color[3]).setStroke(); 537 NSColor.colorWithDeviceRed(color[0], color[1], color[2], color[3]).setStroke();
537 } 538 }
538 int width = 1; 539 int width = 1;
539 float[] dashes = null; 540 Carbon.CGFloat[] dashes = null;
540 switch (style.borderStyle) { 541 switch (style.borderStyle) {
541 case DWT.BORDER_SOLID: break; 542 case DWT.BORDER_SOLID: break;
542 case DWT.BORDER_DASH: dashes = width !is 0 ? GC.LINE_DASH : GC.LINE_DASH_ZERO; break; 543 case DWT.BORDER_DASH: dashes = width !is 0 ? GC.LINE_DASH : GC.LINE_DASH_ZERO; break;
543 case DWT.BORDER_DOT: dashes = width !is 0 ? GC.LINE_DOT : GC.LINE_DOT_ZERO; break; 544 case DWT.BORDER_DOT: dashes = width !is 0 ? GC.LINE_DOT : GC.LINE_DOT_ZERO; break;
544 } 545 }
545 NSBezierPath path = NSBezierPath.bezierPath(); 546 NSBezierPath path = NSBezierPath.bezierPath();
546 path.setLineDash(dashes, dashes !is null ? dashes.length : 0, 0); 547 path.setLineDash(dashes.ptr, dashes !is null ? dashes.length : 0, 0);
547 path.appendBezierPathWithRect(rect); 548 path.appendBezierPathWithRect(rect);
548 path.stroke(); 549 path.stroke();
549 gc.handle.restoreGraphicsState(); 550 gc.handle.restoreGraphicsState();
550 } 551 }
551 } 552 }
968 int length = text.length(); 969 int length = text.length();
969 if (!(0 <= offset && offset <= length)) DWT.error(DWT.ERROR_INVALID_RANGE); 970 if (!(0 <= offset && offset <= length)) DWT.error(DWT.ERROR_INVALID_RANGE);
970 if (length is 0) return new Point(0, 0); 971 if (length is 0) return new Point(0, 0);
971 offset = translateOffset(offset); 972 offset = translateOffset(offset);
972 NSUInteger glyphIndex = layoutManager.glyphIndexForCharacterAtIndex(offset); 973 NSUInteger glyphIndex = layoutManager.glyphIndexForCharacterAtIndex(offset);
973 NSRect rect = layoutManager.lineFragmentUsedRectForGlyphAtIndex_effectiveRange_(glyphIndex, null); 974 NSRect rect = layoutManager.lineFragmentUsedRectForGlyphAtIndex(glyphIndex, null);
974 NSPoint point = layoutManager.locationForGlyphAtIndex(glyphIndex); 975 NSPoint point = layoutManager.locationForGlyphAtIndex(glyphIndex);
975 if (trailing) { 976 if (trailing) {
976 NSRange range = NSRange(); 977 NSRange range = NSRange();
977 range.location = glyphIndex; 978 range.location = glyphIndex;
978 range.length = 1; 979 range.length = 1;
1117 int length = text.length(); 1118 int length = text.length();
1118 if (length is 0) return 0; 1119 if (length is 0) return 0;
1119 NSPoint pt = NSPoint(); 1120 NSPoint pt = NSPoint();
1120 pt.x = x; 1121 pt.x = x;
1121 pt.y = y; 1122 pt.y = y;
1122 CGFloat partialFration; 1123 Carbon.CGFloat partialFration;
1123 NSUInteger glyphIndex = layoutManager.glyphIndexForPoint(pt, textContainer, &partialFration); 1124 NSUInteger glyphIndex = layoutManager.glyphIndexForPoint(pt, textContainer, &partialFration);
1124 NSUInteger offset = layoutManager.characterIndexForGlyphAtIndex(glyphIndex); 1125 NSUInteger offset = layoutManager.characterIndexForGlyphAtIndex(glyphIndex);
1125 if (trailing !is null) trailing[0] = cast(int) Math.round(partialFration); 1126 if (trailing !is null) trailing[0] = cast(int) Math.round(partialFration);
1126 return Math.min(untranslateOffset(cast(int)/*64*/offset), length - 1); 1127 return Math.min(untranslateOffset(cast(int)/*64*/offset), length - 1);
1127 } finally { 1128 } finally {