comparison dwt/graphics/TextLayout.d @ 229:5ff96efb6f4b

Additions for forms
author Frank Benoit <benoit@tionex.de>
date Sat, 24 May 2008 08:37:28 +0200
parents b74b74ce5c7d
children c853f6513712
comparison
equal deleted inserted replaced
228:628e9518870e 229:5ff96efb6f4b
9 * IBM Corporation - initial API and implementation 9 * IBM Corporation - initial API and implementation
10 * Port to the D programming language: 10 * Port to the D programming language:
11 * Frank Benoit <benoit@tionex.de> 11 * Frank Benoit <benoit@tionex.de>
12 *******************************************************************************/ 12 *******************************************************************************/
13 module dwt.graphics.TextLayout; 13 module dwt.graphics.TextLayout;
14
15 import tango.util.log.Trace;
14 16
15 import dwt.DWT; 17 import dwt.DWT;
16 import dwt.DWTException; 18 import dwt.DWTException;
17 import dwt.internal.Compatibility; 19 import dwt.internal.Compatibility;
18 import dwt.internal.gdip.Gdip; 20 import dwt.internal.gdip.Gdip;
55 public final class TextLayout : Resource { 57 public final class TextLayout : Resource {
56 58
57 alias Resource.init_ init_; 59 alias Resource.init_ init_;
58 60
59 /++ 61 /++
60 DWT doku 62 + DWT doku
61 The styles has at minimum 2 member, each with a start. The last element is the end marker. 63 + The styles has at minimum 2 member, each with a start. The last element is the end marker.
62 ++/ 64 +
63 65 + invariant{
64 invariant{ 66 + assert( stylesCount >= 2 );
65 assert( stylesCount >= 2 ); 67 + assert( stylesCount <= styles.length );
66 assert( stylesCount <= styles.length ); 68 + assert( styles[stylesCount-1] );
67 assert( styles[stylesCount-1] ); 69 + assert( styles[stylesCount-1].start is text.length );
68 assert( styles[stylesCount-1].start is text.length ); 70 + }
69 } 71 +/
72
70 73
71 Font font; 74 Font font;
72 String text, segmentsText; 75 String text, segmentsText;
73 int lineSpacing; 76 int lineSpacing;
74 int ascent, descent; 77 int ascent, descent;
2258 auto hHeap = OS.GetProcessHeap(); 2261 auto hHeap = OS.GetProcessHeap();
2259 auto pItems = cast(SCRIPT_ITEM*)OS.HeapAlloc(hHeap, OS.HEAP_ZERO_MEMORY, MAX_ITEM * SCRIPT_ITEM.sizeof); 2262 auto pItems = cast(SCRIPT_ITEM*)OS.HeapAlloc(hHeap, OS.HEAP_ZERO_MEMORY, MAX_ITEM * SCRIPT_ITEM.sizeof);
2260 if (pItems is null) DWT.error(DWT.ERROR_NO_HANDLES); 2263 if (pItems is null) DWT.error(DWT.ERROR_NO_HANDLES);
2261 int pcItems; 2264 int pcItems;
2262 wchar[] chars = StrToWCHARs( segmentsText ); 2265 wchar[] chars = StrToWCHARs( segmentsText );
2266 Trace.formatln( "{} {}: segmentsText='{}' chars='{}'", __FILE__,__LINE__, segmentsText, chars );
2263 OS.ScriptItemize(chars.ptr, chars.length, MAX_ITEM, &scriptControl, &scriptState, pItems, &pcItems); 2267 OS.ScriptItemize(chars.ptr, chars.length, MAX_ITEM, &scriptControl, &scriptState, pItems, &pcItems);
2264 // if (hr is E_OUTOFMEMORY) //TODO handle it 2268 // if (hr is E_OUTOFMEMORY) //TODO handle it
2269
2270 // Translate the utf16 indices to utf8 indices
2271 Trace.formatln( "{} {}: pcItems={} chars.length={} segmentsText.length={}", __FILE__,__LINE__,pcItems, chars.length, segmentsText.length );
2272 int utf8idx = 0;
2273 SCRIPT_ITEM* si = pItems;
2274 foreach( uint utf16idx, char c; chars ){
2275 Trace.formatln( "{} {}: utf8idx={} utf16idx={} si.iCharPos={}", __FILE__,__LINE__,utf8idx, utf16idx, si.iCharPos );
2276 if( si.iCharPos is utf16idx ){
2277 si.iCharPos = utf8idx;
2278 si++;
2279 }
2280 utf8idx++;
2281 }
2265 2282
2266 StyleItem[] runs = merge(pItems, pcItems); 2283 StyleItem[] runs = merge(pItems, pcItems);
2267 OS.HeapFree(hHeap, 0, pItems); 2284 OS.HeapFree(hHeap, 0, pItems);
2268 return runs; 2285 return runs;
2269 } 2286 }
2276 StyleItem[] newStyles = new StyleItem[stylesCount]; 2293 StyleItem[] newStyles = new StyleItem[stylesCount];
2277 System.arraycopy(styles, 0, newStyles, 0, stylesCount); 2294 System.arraycopy(styles, 0, newStyles, 0, stylesCount);
2278 styles = newStyles; 2295 styles = newStyles;
2279 } 2296 }
2280 int count = 0, start = 0, end = segmentsText.length, itemIndex = 0, styleIndex = 0; 2297 int count = 0, start = 0, end = segmentsText.length, itemIndex = 0, styleIndex = 0;
2298 Trace.formatln( "{} {}: itemCount={} stylesCount={}", __FILE__,__LINE__,itemCount, stylesCount );
2281 StyleItem[] runs = new StyleItem[itemCount + stylesCount]; 2299 StyleItem[] runs = new StyleItem[itemCount + stylesCount];
2282 SCRIPT_ITEM* scriptItem = new SCRIPT_ITEM(); 2300 SCRIPT_ITEM* scriptItem = new SCRIPT_ITEM();
2283 bool linkBefore = false; 2301 bool linkBefore = false;
2302 Trace.formatln( "{} {}: start={} end={}", __FILE__,__LINE__,start, end );
2284 while (start < end) { 2303 while (start < end) {
2285 StyleItem item = new StyleItem(); 2304 StyleItem item = new StyleItem();
2286 item.start = start; 2305 item.start = start;
2287 item.style = styles[styleIndex].style; 2306 item.style = styles[styleIndex].style;
2307 Trace.formatln( "{} {}: count={}", __FILE__,__LINE__,count );
2288 runs[count++] = item; 2308 runs[count++] = item;
2289 OS.MoveMemory(scriptItem, (cast(void*)items) + itemIndex * SCRIPT_ITEM.sizeof, SCRIPT_ITEM.sizeof); 2309 OS.MoveMemory(scriptItem, (cast(void*)items) + itemIndex * SCRIPT_ITEM.sizeof, SCRIPT_ITEM.sizeof);
2290 item.analysis = scriptItem.a; 2310 item.analysis = scriptItem.a;
2291 if (linkBefore) { 2311 if (linkBefore) {
2292 item.analysis.fLinkBefore = true; 2312 item.analysis.fLinkBefore = true;
2311 if (itemLimit <= styleLimit) { 2331 if (itemLimit <= styleLimit) {
2312 itemIndex++; 2332 itemIndex++;
2313 start = itemLimit; 2333 start = itemLimit;
2314 } 2334 }
2315 item.length = start - item.start; 2335 item.length = start - item.start;
2336 Trace.formatln( "{} {}: start={} end={}", __FILE__,__LINE__,start, end );
2316 } 2337 }
2317 StyleItem item = new StyleItem(); 2338 StyleItem item = new StyleItem();
2318 item.start = end; 2339 item.start = end;
2319 OS.MoveMemory(scriptItem, (cast(void*)items) + itemCount * SCRIPT_ITEM.sizeof, SCRIPT_ITEM.sizeof); 2340 OS.MoveMemory(scriptItem, (cast(void*)items) + itemCount * SCRIPT_ITEM.sizeof, SCRIPT_ITEM.sizeof);
2320 item.analysis = scriptItem.a; 2341 item.analysis = scriptItem.a;
2342 Trace.formatln( "{} {}: count={}", __FILE__,__LINE__,count );
2321 runs[count++] = item; 2343 runs[count++] = item;
2322 if (runs.length !is count) { 2344 if (runs.length !is count) {
2323 StyleItem[] result = new StyleItem[count]; 2345 StyleItem[] result = new StyleItem[count];
2324 System.arraycopy(runs, 0, result, 0, count); 2346 System.arraycopy(runs, 0, result, 0, count);
2325 return result; 2347 return result;
2719 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li> 2741 * <li>ERROR_GRAPHIC_DISPOSED - if the receiver has been disposed</li>
2720 * </ul> 2742 * </ul>
2721 */ 2743 */
2722 public void setText (String text) { 2744 public void setText (String text) {
2723 checkLayout(); 2745 checkLayout();
2746
2724 //PORTING_CHANGE: allow null argument 2747 //PORTING_CHANGE: allow null argument
2725 //if (text is null) DWT.error(DWT.ERROR_NULL_ARGUMENT); 2748 //if (text is null) DWT.error(DWT.ERROR_NULL_ARGUMENT);
2726 if (text.equals(this.text)) return; 2749 if (text.equals(this.text)) return;
2727 freeRuns(); 2750 freeRuns();
2728 this.text = text; 2751 this.text = text;
2729 styles = new StyleItem[2]; 2752 styles = new StyleItem[2];
2730 styles[0] = new StyleItem(); 2753 styles[0] = new StyleItem();
2731 styles[1] = new StyleItem(); 2754 styles[1] = new StyleItem();
2732 styles[1].start = text.length; 2755 styles[1].start = text.length;
2733 stylesCount = 2; 2756 stylesCount = 2;
2757 Trace.formatln( "{} {}: text='{}'", __FILE__,__LINE__, text );
2734 } 2758 }
2735 2759
2736 /** 2760 /**
2737 * Sets the line width of the receiver, which determines how 2761 * Sets the line width of the receiver, which determines how
2738 * text should be wrapped and aligned. The default value is 2762 * text should be wrapped and aligned. The default value is