Mercurial > projects > dwt-mac
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 */ |