comparison dwt/graphics/TextLayout.d @ 37:642f460a0908

Fixed a lot of compile errors, a "hello world" app compiles now
author Jacob Carlborg <doob@me.com> <jacob.carlborg@gmail.com>
date Fri, 10 Oct 2008 12:29:48 +0200
parents db5a898b2119
children d8635bb48c7c
comparison
equal deleted inserted replaced
36:db5a898b2119 37:642f460a0908
27 import dwt.internal.cocoa.NSString; 27 import dwt.internal.cocoa.NSString;
28 import dwt.internal.cocoa.NSTextContainer; 28 import dwt.internal.cocoa.NSTextContainer;
29 import dwt.internal.cocoa.NSTextStorage; 29 import dwt.internal.cocoa.NSTextStorage;
30 import dwt.internal.cocoa.OS; 30 import dwt.internal.cocoa.OS;
31 31
32 import tango.text.convert.Format;
33
32 import dwt.dwthelper.utils; 34 import dwt.dwthelper.utils;
33 import dwt.graphics.Color; 35 import dwt.graphics.Color;
34 import dwt.graphics.Device; 36 import dwt.graphics.Device;
35 import dwt.graphics.Font; 37 import dwt.graphics.Font;
36 import dwt.graphics.FontMetrics; 38 import dwt.graphics.FontMetrics;
40 import dwt.graphics.Point; 42 import dwt.graphics.Point;
41 import dwt.graphics.Rectangle; 43 import dwt.graphics.Rectangle;
42 import dwt.graphics.Region; 44 import dwt.graphics.Region;
43 import dwt.graphics.Resource; 45 import dwt.graphics.Resource;
44 import dwt.graphics.TextStyle; 46 import dwt.graphics.TextStyle;
47 import dwt.internal.cocoa.CGFloat;
48 import dwt.internal.cocoa.NSInteger;
49 import dwt.internal.cocoa.NSText;
45 50
46 /** 51 /**
47 * <code>TextLayout</code> is a graphic object that represents 52 * <code>TextLayout</code> is a graphic object that represents
48 * styled text. 53 * styled text.
49 * <p> 54 * <p>
82 static class StyleItem { 87 static class StyleItem {
83 TextStyle style; 88 TextStyle style;
84 int start; 89 int start;
85 90
86 public String toString () { 91 public String toString () {
87 return "StyleItem {" + start + ", " + style + "}"; 92 return Format("StyleItem {{}{}{}{}" , start , ", " , style , "}");
88 } 93 }
89 } 94 }
90 95
91 // static final int TAB_COUNT = 32; 96 // static final int TAB_COUNT = 32;
92 // static final char ZWS = '\u200B'; 97 // static final char ZWS = '\u200B';
130 NSString str = NSString.stringWith(text); 135 NSString str = NSString.stringWith(text);
131 textStorage = (cast(NSTextStorage)(new NSTextStorage()).alloc()); 136 textStorage = (cast(NSTextStorage)(new NSTextStorage()).alloc());
132 textStorage.initWithString_(str); 137 textStorage.initWithString_(str);
133 layoutManager = cast(NSLayoutManager)(new NSLayoutManager()).alloc().init(); 138 layoutManager = cast(NSLayoutManager)(new NSLayoutManager()).alloc().init();
134 textContainer = cast(NSTextContainer)(new NSTextContainer()).alloc(); 139 textContainer = cast(NSTextContainer)(new NSTextContainer()).alloc();
135 NSSize size = new NSSize(); 140 NSSize size = NSSize();
136 size.width = wrapWidth !is -1 ? wrapWidth : Float.MAX_VALUE; 141 size.width = wrapWidth !is -1 ? wrapWidth : Float.MAX_VALUE;
137 size.height = Float.MAX_VALUE; 142 size.height = Float.MAX_VALUE;
138 textContainer.initWithContainerSize(size); 143 textContainer.initWithContainerSize(size);
139 textStorage.addLayoutManager(layoutManager); 144 textStorage.addLayoutManager(layoutManager);
140 layoutManager.addTextContainer(textContainer); 145 layoutManager.addTextContainer(textContainer);
141 146
142 textStorage.beginEditing(); 147 textStorage.beginEditing();
143 Font defaultFont = font !is null ? font : device.systemFont; 148 Font defaultFont = font !is null ? font : device.systemFont;
144 NSRange range = new NSRange(); 149 NSRange range = NSRange();
145 range.length = str.length(); 150 range.length = str.length();
146 textStorage.addAttribute(OS.NSFontAttributeName(), defaultFont.handle, range); 151 textStorage.addAttribute(OS.NSFontAttributeName(), defaultFont.handle, range);
147 152
148 NSMutableParagraphStyle paragraph = cast(NSMutableParagraphStyle)(new NSMutableParagraphStyle()).alloc().init(); 153 NSMutableParagraphStyle paragraph = cast(NSMutableParagraphStyle)(new NSMutableParagraphStyle()).alloc().init();
149 int align_ = OS.NSLeftTextAlignment; 154 NSTextAlignment align_ = NSLeftTextAlignment;
150 if (justify) { 155 if (justify) {
151 align_ = OS.NSJustifiedTextAlignment; 156 align_ = NSJustifiedTextAlignment;
152 } else { 157 } else {
153 switch (alignment) { 158 switch (alignment) {
154 case DWT.CENTER: 159 case DWT.CENTER:
155 align_ = OS.NSCenterTextAlignment; 160 align_ = NSCenterTextAlignment;
156 break; 161 break;
157 case DWT.RIGHT: 162 case DWT.RIGHT:
158 align_ = OS.NSRightTextAlignment; 163 align_ = NSRightTextAlignment;
159 } 164 }
160 } 165 }
161 paragraph.setAlignment(align_); 166 paragraph.setAlignment(align_);
162 paragraph.setLineSpacing(spacing); 167 paragraph.setLineSpacing(spacing);
163 paragraph.setFirstLineHeadIndent(indent); 168 paragraph.setFirstLineHeadIndent(indent);
184 textStorage.addAttribute(OS.NSForegroundColorAttributeName(), color, range); 189 textStorage.addAttribute(OS.NSForegroundColorAttributeName(), color, range);
185 } 190 }
186 Color background = style.background; 191 Color background = style.background;
187 if (background !is null) { 192 if (background !is null) {
188 NSColor color = NSColor.colorWithDeviceRed(background.handle[0], background.handle[1], background.handle[2], 1); 193 NSColor color = NSColor.colorWithDeviceRed(background.handle[0], background.handle[1], background.handle[2], 1);
189 textStorage.addAttribute(OS.NSBackgroundColorAttributeName(), color, range); 194 textStorage.addAttribute(OS.NSBackgroundColorAttributeName, color, range);
190 } 195 }
191 if (style.strikeout) { 196 if (style.strikeout) {
192 textStorage.addAttribute(OS.NSStrikethroughStyleAttributeName(), NSNumber.numberWithInt(OS.NSUnderlineStyleSingle), range); 197 textStorage.addAttribute(OS.NSStrikethroughStyleAttributeName(), NSNumber.numberWithInt(OS.NSUnderlineStyleSingle), range);
193 Color strikeColor = style.strikeoutColor; 198 Color strikeColor = style.strikeoutColor;
194 if (strikeColor !is null) { 199 if (strikeColor !is null) {
227 232
228 textContainer.setLineFragmentPadding(0); 233 textContainer.setLineFragmentPadding(0);
229 layoutManager.glyphRangeForTextContainer(textContainer); 234 layoutManager.glyphRangeForTextContainer(textContainer);
230 235
231 int numberOfLines, index, numberOfGlyphs = layoutManager.numberOfGlyphs(); 236 int numberOfLines, index, numberOfGlyphs = layoutManager.numberOfGlyphs();
232 int rangePtr = OS.malloc(NSRange.sizeof); 237 NSRangePointer rangePtr = cast(NSRangePointer) OS.malloc(NSRange.sizeof);
233 NSRange lineRange = new NSRange(); 238 NSRange lineRange = NSRange();
234 for (numberOfLines = 0, index = 0; index < numberOfGlyphs; numberOfLines++){ 239 for (numberOfLines = 0, index = 0; index < numberOfGlyphs; numberOfLines++){
235 layoutManager.lineFragmentUsedRectForGlyphAtIndex_effectiveRange_withoutAdditionalLayout_(index, rangePtr, true); 240 layoutManager.lineFragmentUsedRectForGlyphAtIndex_effectiveRange_withoutAdditionalLayout_(index, rangePtr, true);
236 OS.memmove(lineRange, rangePtr, NSRange.sizeof); 241 OS.memmove(&lineRange, rangePtr, NSRange.sizeof);
237 index = lineRange.location + lineRange.length; 242 index = lineRange.location + lineRange.length;
238 } 243 }
239 if (numberOfLines is 0) numberOfLines++; 244 if (numberOfLines is 0) numberOfLines++;
240 int[] offsets = new int[numberOfLines + 1]; 245 int[] offsets = new int[numberOfLines + 1];
241 NSRect[] bounds = new NSRect[numberOfLines]; 246 NSRect[] bounds = new NSRect[numberOfLines];
242 for (numberOfLines = 0, index = 0; index < numberOfGlyphs; numberOfLines++){ 247 for (numberOfLines = 0, index = 0; index < numberOfGlyphs; numberOfLines++){
243 bounds[numberOfLines] = layoutManager.lineFragmentUsedRectForGlyphAtIndex_effectiveRange_withoutAdditionalLayout_(index, rangePtr, true); 248 bounds[numberOfLines] = layoutManager.lineFragmentUsedRectForGlyphAtIndex_effectiveRange_withoutAdditionalLayout_(index, rangePtr, true);
244 OS.memmove(lineRange, rangePtr, NSRange.sizeof); 249 OS.memmove(&lineRange, rangePtr, NSRange.sizeof);
245 offsets[numberOfLines] = lineRange.location; 250 offsets[numberOfLines] = lineRange.location;
246 index = lineRange.location + lineRange.length; 251 index = lineRange.location + lineRange.length;
247 } 252 }
248 if (numberOfLines is 0) { 253 if (numberOfLines is 0) {
249 Font font = this.font !is null ? this.font : device.systemFont; 254 Font font = this.font !is null ? this.font : device.systemFont;
250 NSFont nsFont = font.handle; 255 NSFont nsFont = font.handle;
251 bounds[0] = new NSRect(); 256 bounds[0] = NSRect();
252 bounds[0].height = Math.max(layoutManager.defaultLineHeightForFont(nsFont), ascent + descent); 257 bounds[0].height = Math.max(layoutManager.defaultLineHeightForFont(nsFont), ascent + descent);
253 } 258 }
254 OS.free(rangePtr); 259 OS.free(rangePtr);
255 offsets[numberOfLines] = textStorage.length(); 260 offsets[numberOfLines] = textStorage.length();
256 this.lineOffsets = offsets; 261 this.lineOffsets = offsets;
342 if (selectionBackground !is null && selectionBackground.isDisposed()) DWT.error(DWT.ERROR_INVALID_ARGUMENT); 347 if (selectionBackground !is null && selectionBackground.isDisposed()) DWT.error(DWT.ERROR_INVALID_ARGUMENT);
343 gc.checkGC(GC.CLIPPING | GC.TRANSFORM | GC.FOREGROUND); 348 gc.checkGC(GC.CLIPPING | GC.TRANSFORM | GC.FOREGROUND);
344 // float[] foreground = gc.data.foreground; 349 // float[] foreground = gc.data.foreground;
345 // NSColor color = NSColor.colorWithDeviceRed(foreground[0], foreground[1], foreground[2], foreground[3]); 350 // NSColor color = NSColor.colorWithDeviceRed(foreground[0], foreground[1], foreground[2], foreground[3]);
346 // textStorage.setForegroundColor(color); 351 // textStorage.setForegroundColor(color);
347 NSPoint pt = new NSPoint(); 352 NSPoint pt = NSPoint();
348 pt.x = x; 353 pt.x = x;
349 pt.y = y; 354 pt.y = y;
350 NSRange range = new NSRange(); 355 NSRange range = NSRange();
351 range.length = layoutManager.numberOfGlyphs(); 356 range.length = layoutManager.numberOfGlyphs();
352 bool hasSelection = selectionStart <= selectionEnd && selectionStart !is -1 && selectionEnd !is -1; 357 bool hasSelection = selectionStart <= selectionEnd && selectionStart !is -1 && selectionEnd !is -1;
353 NSRange selectionRange = null; 358 NSRange* selectionRange = null;
354 if (hasSelection) { 359 if (hasSelection) {
355 selectionRange = new NSRange(); 360 selectionRange = new NSRange();
356 selectionRange.location = selectionStart; 361 selectionRange.location = selectionStart;
357 selectionRange.length = selectionEnd - selectionStart + 1; 362 selectionRange.length = selectionEnd - selectionStart + 1;
358 if (selectionBackground is null) selectionBackground = device.getSystemColor(DWT.COLOR_LIST_SELECTION); 363 if (selectionBackground is null) selectionBackground = device.getSystemColor(DWT.COLOR_LIST_SELECTION);
359 NSColor selectionColor = NSColor.colorWithDeviceRed(selectionBackground.handle[0], selectionBackground.handle[1], selectionBackground.handle[2], selectionBackground.handle[3]); 364 NSColor selectionColor = NSColor.colorWithDeviceRed(selectionBackground.handle[0], selectionBackground.handle[1], selectionBackground.handle[2], selectionBackground.handle[3]);
360 layoutManager.addTemporaryAttribute(OS.NSBackgroundColorAttributeName, selectionColor, selectionRange); 365 layoutManager.addTemporaryAttribute(OS.NSBackgroundColorAttributeName, selectionColor, *selectionRange);
361 } 366 }
362 //TODO draw selection for flags (LAST_LINE_SELECTION and FULL_SELECTION) 367 //TODO draw selection for flags (LAST_LINE_SELECTION and FULL_SELECTION)
363 if (range.length > 0) { 368 if (range.length > 0) {
364 layoutManager.drawBackgroundForGlyphRange(range, pt); 369 layoutManager.drawBackgroundForGlyphRange(range, pt);
365 layoutManager.drawGlyphsForGlyphRange(range, pt); 370 layoutManager.drawGlyphsForGlyphRange(range, pt);
366 } 371 }
367 if (selectionRange !is null) { 372 if (selectionRange !is null) {
368 layoutManager.removeTemporaryAttribute(OS.NSBackgroundColorAttributeName, selectionRange); 373 layoutManager.removeTemporaryAttribute(OS.NSBackgroundColorAttributeName, *selectionRange);
369 } 374 }
370 } 375 }
371 376
372 void freeRuns() { 377 void freeRuns() {
373 if (textStorage is null) return; 378 if (textStorage is null) return;
465 if (start > end) return new Rectangle(0, 0, 0, 0); 470 if (start > end) return new Rectangle(0, 0, 0, 0);
466 start = Math.min(Math.max(0, start), length - 1); 471 start = Math.min(Math.max(0, start), length - 1);
467 end = Math.min(Math.max(0, end), length - 1); 472 end = Math.min(Math.max(0, end), length - 1);
468 start = translateOffset(start); 473 start = translateOffset(start);
469 end = translateOffset(end); 474 end = translateOffset(end);
470 NSRange range = new NSRange(); 475 NSRange range = NSRange();
471 range.location = layoutManager.glyphIndexForCharacterAtIndex(start); 476 range.location = layoutManager.glyphIndexForCharacterAtIndex(start);
472 range.length = layoutManager.glyphIndexForCharacterAtIndex(end + 1) - range.location; 477 range.length = layoutManager.glyphIndexForCharacterAtIndex(end + 1) - range.location;
473 NSRect rect = layoutManager.boundingRectForGlyphRange(range, textContainer); 478 NSRect rect = layoutManager.boundingRectForGlyphRange(range, textContainer);
474 return new Rectangle(cast(int)rect.x, cast(int)rect.y, cast(int)Math.ceil(rect.width), cast(int)Math.ceil(rect.height)); 479 return new Rectangle(cast(int)rect.x, cast(int)rect.y, cast(int)Math.ceil(rect.width), cast(int)Math.ceil(rect.height));
475 } 480 }
705 computeRuns(); 710 computeRuns();
706 int length = text.length(); 711 int length = text.length();
707 if (!(0 <= offset && offset <= length)) DWT.error(DWT.ERROR_INVALID_RANGE); 712 if (!(0 <= offset && offset <= length)) DWT.error(DWT.ERROR_INVALID_RANGE);
708 if (length is 0) return new Point(0, 0); 713 if (length is 0) return new Point(0, 0);
709 offset = translateOffset(offset); 714 offset = translateOffset(offset);
710 int glyphIndex = layoutManager.glyphIndexForCharacterAtIndex(offset); 715 NSUInteger glyphIndex = layoutManager.glyphIndexForCharacterAtIndex(offset);
711 NSRect rect = layoutManager.lineFragmentUsedRectForGlyphAtIndex_effectiveRange_(glyphIndex, 0); 716 NSRect rect = layoutManager.lineFragmentUsedRectForGlyphAtIndex_effectiveRange_(glyphIndex, null);
712 NSPoint point = layoutManager.locationForGlyphAtIndex(glyphIndex); 717 NSPoint point = layoutManager.locationForGlyphAtIndex(glyphIndex);
713 if (trailing) { 718 if (trailing) {
714 NSRange range = new NSRange(); 719 NSRange range = NSRange();
715 range.location = glyphIndex; 720 range.location = glyphIndex;
716 range.length = 1; 721 range.length = 1;
717 NSRect bounds = layoutManager.boundingRectForGlyphRange(range, textContainer); 722 NSRect bounds = layoutManager.boundingRectForGlyphRange(range, textContainer);
718 point.x += bounds.width; 723 point.x += bounds.width;
719 } 724 }
834 checkLayout(); 839 checkLayout();
835 computeRuns(); 840 computeRuns();
836 if (trailing !is null && trailing.length < 1) DWT.error(DWT.ERROR_INVALID_ARGUMENT); 841 if (trailing !is null && trailing.length < 1) DWT.error(DWT.ERROR_INVALID_ARGUMENT);
837 int length = text.length(); 842 int length = text.length();
838 if (length is 0) return 0; 843 if (length is 0) return 0;
839 NSPoint pt = new NSPoint(); 844 NSPoint pt = NSPoint();
840 pt.x = x; 845 pt.x = x;
841 pt.y = y; 846 pt.y = y;
842 float[] partialFration = new float[1]; 847 CGFloat partialFration;
843 int glyphIndex = layoutManager.glyphIndexForPoint_inTextContainer_fractionOfDistanceThroughGlyph_(pt, textContainer, partialFration); 848 NSUInteger glyphIndex = layoutManager.glyphIndexForPoint_inTextContainer_fractionOfDistanceThroughGlyph_(pt, textContainer, &partialFration);
844 int offset = layoutManager.characterIndexForGlyphAtIndex(glyphIndex); 849 int offset = layoutManager.characterIndexForGlyphAtIndex(glyphIndex);
845 if (trailing !is null) trailing[0] = Math.round(partialFration[0]); 850 if (trailing !is null) trailing[0] = cast(int) Math.round(partialFration);
846 return Math.min(untranslateOffset(offset), length - 1); 851 return Math.min(untranslateOffset(offset), length - 1);
847 } 852 }
848 853
849 /** 854 /**
850 * Returns the orientation of the receiver. 855 * Returns the orientation of the receiver.
1445 * 1450 *
1446 * @return a string representation of the receiver 1451 * @return a string representation of the receiver
1447 */ 1452 */
1448 public String toString () { 1453 public String toString () {
1449 if (isDisposed()) return "TextLayout {*DISPOSED*}"; 1454 if (isDisposed()) return "TextLayout {*DISPOSED*}";
1450 return "TextLayout {" + text + "}"; 1455 return "TextLayout {" ~ text ~ "}";
1451 } 1456 }
1452 1457
1453 /* 1458 /*
1454 * Translate a client offset to an internal offset 1459 * Translate a client offset to an internal offset
1455 */ 1460 */