changeset 30:1e14cb29290a

TextLayout
author Frank Benoit <benoit@tionex.de>
date Mon, 28 Jan 2008 02:37:23 +0100
parents 16332d261df7
children 92c102dd64a3
files dwt/dwthelper/utils.d dwt/graphics/TextLayout.d dwt/internal/win32/OS.d dwt/internal/win32/WINAPI.d dwt/internal/win32/WINTYPES.d
diffstat 5 files changed, 370 insertions(+), 249 deletions(-) [+]
line wrap: on
line diff
--- a/dwt/dwthelper/utils.d	Mon Jan 28 00:27:56 2008 +0100
+++ b/dwt/dwthelper/utils.d	Mon Jan 28 02:37:23 2008 +0100
@@ -93,7 +93,7 @@
 }
 
 public wchar[] toCharArray( char[] str ){
-    return StrToWCHARs( str );
+    return toString16( str );
 }
 
 public bool endsWith( char[] src, char[] pattern ){
--- a/dwt/graphics/TextLayout.d	Mon Jan 28 00:27:56 2008 +0100
+++ b/dwt/graphics/TextLayout.d	Mon Jan 28 02:37:23 2008 +0100
@@ -31,6 +31,7 @@
 
 import tango.text.convert.Format;
 import dwt.dwthelper.utils;
+import dwt.dwthelper.System;
 
 /**
  * <code>TextLayout</code> is a graphic object that represents
@@ -64,7 +65,7 @@
     StyleItem[] allRuns;
     StyleItem[][] runs;
     int[] lineOffset, lineY, lineWidth;
-    int mLangFontLink2;
+    void* mLangFontLink2;
 
     static const wchar LTR_MARK = '\u200E', RTL_MARK = '\u200F';
     static const int SCRIPT_VISATTR_SIZEOF = 2;
@@ -93,12 +94,12 @@
 
         /*Place info (malloc when the run is placed) */
         int* advances;
-        int* goffsets;
-        int* width;
-        int* ascent;
-        int* descent;
-        int* leading;
-        int* x;
+        GOFFSET* goffsets;
+        int width;
+        int ascent;
+        int descent;
+        int leading;
+        int x;
 
         /* Justify info (malloc during computeRuns) */
         int* justify;
@@ -106,7 +107,7 @@
         /* ScriptBreak */
         SCRIPT_LOGATTR* psla;
 
-        int* fallbackFont;
+        HFONT fallbackFont;
 
     void free() {
         auto hHeap = OS.GetProcessHeap();
@@ -145,13 +146,16 @@
             psla = null;
         }
         if (fallbackFont !is null) {
-            if (mLangFontLink2 !is 0) {
+            if (mLangFontLink2 !is null) {
                 /* ReleaseFont() */
-                OS.VtblCall(8, mLangFontLink2, fallbackFont);
+                OS.VtblCall(8, mLangFontLink2, cast(int)fallbackFont);
             }
             fallbackFont = null;
         }
-        width = ascent = descent = x = 0;
+        width = 0;
+        ascent = 0;
+        descent = 0;
+        x = 0;
         lineBreak = softBreak = false;
     }
     public char[] toString () {
@@ -184,26 +188,25 @@
     styles[0] = new StyleItem();
     styles[1] = new StyleItem();
     text = ""; //$NON-NLS-1$
-    int[] ppv = new int[1];
-    OS.OleInitialize(0);
-    if (OS.CoCreateInstance(CLSID_CMultiLanguage, 0, OS.CLSCTX_INPROC_SERVER, IID_IMLangFontLink2, ppv) is OS.S_OK) {
-        mLangFontLink2 = ppv[0];
+    void* ppv;
+    OS.OleInitialize(null);
+    if (OS.CoCreateInstance(CLSID_CMultiLanguage.ptr, null, OS.CLSCTX_INPROC_SERVER, IID_IMLangFontLink2.ptr, cast(void*)&ppv) is OS.S_OK) {
+        mLangFontLink2 = ppv;
     }
     if (device.tracking) device.new_Object(this);
 }
 
 void breakRun(StyleItem run) {
-    if (run.psla !is 0) return;
-    char[] chars = new char[run.length];
-    segmentsText.getChars(run.start, run.start + run.length, chars, 0);
-    int hHeap = OS.GetProcessHeap();
-    run.psla = OS.HeapAlloc(hHeap, OS.HEAP_ZERO_MEMORY, SCRIPT_LOGATTR.sizeof * chars.length);
-    if (run.psla is 0) DWT.error(DWT.ERROR_NO_HANDLES);
-    OS.ScriptBreak(chars, chars.length, run.analysis, run.psla);
+    if (run.psla !is null) return;
+    wchar[] chars = StrToWCHARs( segmentsText[ run.start .. run.start + run.length ] );
+    auto hHeap = OS.GetProcessHeap();
+    run.psla = cast(SCRIPT_LOGATTR*)OS.HeapAlloc(hHeap, OS.HEAP_ZERO_MEMORY, SCRIPT_LOGATTR.sizeof * chars.length);
+    if (run.psla is null) DWT.error(DWT.ERROR_NO_HANDLES);
+    OS.ScriptBreak(chars.ptr, chars.length, &run.analysis, run.psla);
 }
 
-void checkItem (int hDC, StyleItem item) {
-    if (item.fallbackFont !is 0) {
+void checkItem (HDC hDC, StyleItem item) {
+    if (item.fallbackFont !is null) {
         /*
         * Feature in Windows. The fallback font returned by the MLang service
         * can be disposed by some other client running in the same thread.
@@ -212,7 +215,7 @@
         * font was disposed and reshape the run.
         */
         LOGFONT logFont;
-        if (OS.GetObject(item.fallbackFont, LOGFONT.sizeof, &logFont) is 0) {
+        if (OS.GetObject( item.fallbackFont, LOGFONT.sizeof, &logFont) is 0) {
             item.free();
             OS.SelectObject(hDC, getItemFont(item));
             shape(hDC, item);
@@ -230,16 +233,16 @@
 */
 void computeRuns (GC gc) {
     if (runs !is null) return;
-    int hDC = gc !is null ? gc.handle : device.internal_new_GC(null);
-    int srcHdc = OS.CreateCompatibleDC(hDC);
+    auto hDC = gc !is null ? gc.handle : device.internal_new_GC(null);
+    auto srcHdc = OS.CreateCompatibleDC(hDC);
     allRuns = itemize();
     for (int i=0; i<allRuns.length - 1; i++) {
         StyleItem run = allRuns[i];
         OS.SelectObject(srcHdc, getItemFont(run));
         shape(srcHdc, run);
     }
-    SCRIPT_LOGATTR logAttr = new SCRIPT_LOGATTR();
-    SCRIPT_PROPERTIES properties = new SCRIPT_PROPERTIES();
+    SCRIPT_LOGATTR* logAttr;
+    SCRIPT_PROPERTIES* properties;
     int lineWidth = indent, lineStart = 0, lineCount = 1;
     for (int i=0; i<allRuns.length - 1; i++) {
         StyleItem run = allRuns[i];
@@ -288,7 +291,7 @@
             if (run.style !is null && run.style.metrics !is null) {
                 piDx[0] = run.width;
             } else {
-                OS.ScriptGetLogicalWidths(run.analysis, run.length, run.glyphCount, run.advances, run.clusters, run.visAttrs, piDx);
+                OS.ScriptGetLogicalWidths(&run.analysis, run.length, run.glyphCount, run.advances, run.clusters, run.visAttrs, piDx.ptr);
             }
             int width = 0, maxWidth = wrapWidth - lineWidth;
             while (width + piDx[start] < maxWidth) {
@@ -299,7 +302,8 @@
             while (i >= lineStart) {
                 breakRun(run);
                 while (start >= 0) {
-                    OS.MoveMemory(logAttr, run.psla + (start * SCRIPT_LOGATTR.sizeof), SCRIPT_LOGATTR.sizeof);
+                    logAttr = run.psla + start;
+                    //OS.MoveMemory(logAttr, run.psla + (start * SCRIPT_LOGATTR.sizeof), SCRIPT_LOGATTR.sizeof);
                     if (logAttr.fSoftBreak || logAttr.fWhiteSpace) break;
                     start--;
                 }
@@ -311,13 +315,15 @@
                 */
                 if (start is 0 && i !is lineStart && !run.tab) {
                     if (logAttr.fSoftBreak && !logAttr.fWhiteSpace) {
-                        OS.MoveMemory(properties, device.scripts[run.analysis.eScript], SCRIPT_PROPERTIES.sizeof);
+                        properties = device.scripts[run.analysis.eScript];
+                        //OS.MoveMemory(properties, device.scripts[run.analysis.eScript], SCRIPT_PROPERTIES.sizeof);
                         int langID = properties.langid;
                         StyleItem pRun = allRuns[i - 1];
-                        OS.MoveMemory(properties, device.scripts[pRun.analysis.eScript], SCRIPT_PROPERTIES.sizeof);
+                        //OS.MoveMemory(properties, device.scripts[pRun.analysis.eScript], SCRIPT_PROPERTIES.sizeof);
                         if (properties.langid is langID || langID is OS.LANG_NEUTRAL || properties.langid is OS.LANG_NEUTRAL) {
                             breakRun(pRun);
-                            OS.MoveMemory(logAttr, pRun.psla + ((pRun.length - 1) * SCRIPT_LOGATTR.sizeof), SCRIPT_LOGATTR.sizeof);
+                            logAttr = pRun.psla + (pRun.length - 1);
+                            //OS.MoveMemory(logAttr, pRun.psla + ((pRun.length - 1) * SCRIPT_LOGATTR.sizeof), SCRIPT_LOGATTR.sizeof);
                             if (!logAttr.fWhiteSpace) start = -1;
                         }
                     }
@@ -335,7 +341,8 @@
             }
             breakRun(run);
             while (start < run.length) {
-                OS.MoveMemory(logAttr, run.psla + (start * SCRIPT_LOGATTR.sizeof), SCRIPT_LOGATTR.sizeof);
+                logAttr = run.psla + start;
+                //OS.MoveMemory(logAttr, run.psla + (start * SCRIPT_LOGATTR.sizeof), SCRIPT_LOGATTR.sizeof);
                 if (!logAttr.fWhiteSpace) break;
                 start++;
             }
@@ -369,7 +376,7 @@
         }
     }
     lineWidth = 0;
-    runs = new StyleItem[lineCount][];
+    runs = new StyleItem[][](lineCount);
     lineOffset = new int[lineCount + 1];
     lineY = new int[lineCount + 1];
     this.lineWidth = new int[lineCount];
@@ -407,14 +414,14 @@
                         lineWidth += indent;
                     }
                 }
-                int hHeap = OS.GetProcessHeap();
+                auto hHeap = OS.GetProcessHeap();
                 int newLineWidth = 0;
                 for (int j = 0; j < runs[line].length; j++) {
                     StyleItem item = runs[line][j];
                     int iDx = item.width * wrapWidth / lineWidth;
                     if (iDx !is item.width) {
-                        item.justify = OS.HeapAlloc(hHeap, OS.HEAP_ZERO_MEMORY, item.glyphCount * 4);
-                        if (item.justify is 0) DWT.error(DWT.ERROR_NO_HANDLES);
+                        item.justify = cast(int*)OS.HeapAlloc(hHeap, OS.HEAP_ZERO_MEMORY, item.glyphCount * 4);
+                        if (item.justify is null) DWT.error(DWT.ERROR_NO_HANDLES);
                         OS.ScriptJustify(item.visAttrs, item.advances, item.glyphCount, iDx - item.width, 2, item.justify);
                         item.width = iDx;
                     }
@@ -446,7 +453,7 @@
             descent = Math.max(0, this.descent);
         }
     }
-    if (srcHdc !is 0) OS.DeleteDC(srcHdc);
+    if (srcHdc !is null) OS.DeleteDC(srcHdc);
     if (gc is null) device.internal_dispose_GC(hDC, null);
 }
 
@@ -466,10 +473,10 @@
     lineOffset = null;
     lineY = null;
     lineWidth = null;
-    if (mLangFontLink2 !is 0) {
+    if (mLangFontLink2 !is null) {
         /* Release() */
         OS.VtblCall(2, mLangFontLink2);
-        mLangFontLink2 = 0;
+        mLangFontLink2 = null;
     }
     OS.OleUninitialize();
     if (device.tracking) device.dispose_Object(this);
@@ -552,29 +559,29 @@
     if (gc.isDisposed()) DWT.error(DWT.ERROR_INVALID_ARGUMENT);
     if (selectionForeground !is null && selectionForeground.isDisposed()) DWT.error(DWT.ERROR_INVALID_ARGUMENT);
     if (selectionBackground !is null && selectionBackground.isDisposed()) DWT.error(DWT.ERROR_INVALID_ARGUMENT);
-    int length = text.length();
+    int length = text.length;
     if (length is 0 && flags is 0) return;
-    int hdc = gc.handle;
+    auto hdc = gc.handle;
     Rectangle clip = gc.getClipping();
     GCData data = gc.data;
-    int gdipGraphics = data.gdipGraphics;
-    int foreground = data.foreground;
-    int alpha = data.alpha;
-    bool gdip = gdipGraphics !is 0 && (alpha !is 0xFF || data.foregroundPattern !is null);
-    int clipRgn = 0;
+    auto gdipGraphics = data.gdipGraphics;
+    auto foreground = data.foreground;
+    auto alpha = data.alpha;
+    bool gdip = gdipGraphics !is null && (alpha !is 0xFF || data.foregroundPattern !is null);
+    HRGN clipRgn;
     float[] lpXform = null;
-    Rect gdipRect = new Rect();
-    if (gdipGraphics !is 0 && !gdip) {
-        int matrix = Gdip.Matrix_new(1, 0, 0, 1, 0, 0);
-        if (matrix is 0) DWT.error(DWT.ERROR_NO_HANDLES);
+    Gdip.Rect gdipRect;
+    if (gdipGraphics !is null && !gdip) {
+        auto matrix = Gdip.Matrix_new(1, 0, 0, 1, 0, 0);
+        if (matrix is null) DWT.error(DWT.ERROR_NO_HANDLES);
         Gdip.Graphics_GetTransform(gdipGraphics, matrix);
-        int identity = gc.identity();
-        Gdip.Matrix_Invert(identity);
-        Gdip.Matrix_Multiply(matrix, identity, Gdip.MatrixOrderAppend);
-        Gdip.Matrix_delete(identity);
+        auto identity_ = gc.identity();
+        Gdip.Matrix_Invert(identity_);
+        Gdip.Matrix_Multiply(matrix, identity_, Gdip.MatrixOrderAppend);
+        Gdip.Matrix_delete(identity_);
         if (!Gdip.Matrix_IsIdentity(matrix)) {
             lpXform = new float[6];
-            Gdip.Matrix_GetElements(matrix, lpXform);
+            Gdip.Matrix_GetElements(matrix, lpXform.ptr);
         }
         Gdip.Matrix_delete(matrix);
         if ((data.style & DWT.MIRRORED) !is 0 && lpXform !is null) {
@@ -582,7 +589,7 @@
             lpXform = null;
         } else {
             Gdip.Graphics_SetPixelOffsetMode(gdipGraphics, Gdip.PixelOffsetModeNone);
-            int rgn = Gdip.Region_new();
+            auto rgn = Gdip.Region_new();
             Gdip.Graphics_GetClip(gdipGraphics, rgn);
             if (!Gdip.Region_IsInfinite(rgn, gdipGraphics)) {
                 clipRgn = Gdip.Region_GetHRGN(rgn, gdipGraphics);
@@ -592,7 +599,8 @@
             hdc = Gdip.Graphics_GetHDC(gdipGraphics);
         }
     }
-    int foregroundBrush = 0, state = 0;
+    Gdip.Brush* foregroundBrush;
+    int state = 0;
     if (gdip) {
         gc.checkGC(GC.FOREGROUND);
         foregroundBrush = gc.getFgBrush();
@@ -603,9 +611,9 @@
         }
         if (lpXform !is null) {
             OS.SetGraphicsMode(hdc, OS.GM_ADVANCED);
-            OS.SetWorldTransform(hdc, lpXform);
+            OS.SetWorldTransform(hdc, cast(XFORM*)lpXform.ptr);
         }
-        if (clipRgn !is 0) {
+        if (clipRgn !is null) {
             OS.SelectClipRgn(hdc, clipRgn);
             OS.DeleteObject(clipRgn);
         }
@@ -619,20 +627,23 @@
         selectionStart = translateOffset(selectionStart);
         selectionEnd = translateOffset(selectionEnd);
     }
-    RECT rect = new RECT();
-    int selBrush = 0, selPen = 0, selBrushFg = 0;
+    RECT rect;
+    void* selBrush;
+    void* selPen;
+    void* selBrushFg;
+
     if (hasSelection || (flags & DWT.LAST_LINE_SELECTION) !is 0) {
         if (gdip) {
-            int bg = selectionBackground.handle;
-            int argb = ((alpha & 0xFF) << 24) | ((bg >> 16) & 0xFF) | (bg & 0xFF00) | ((bg & 0xFF) << 16);
-            int color = Gdip.Color_new(argb);
+            auto bg = selectionBackground.handle;
+            auto argb = ((alpha & 0xFF) << 24) | ((bg >> 16) & 0xFF) | (bg & 0xFF00) | ((bg & 0xFF) << 16);
+            auto color = Gdip.Color_new(argb);
             selBrush = Gdip.SolidBrush_new(color);
             Gdip.Color_delete(color);
-            int fg = selectionForeground.handle;
+            auto fg = selectionForeground.handle;
             argb = ((alpha & 0xFF) << 24) | ((fg >> 16) & 0xFF) | (fg & 0xFF00) | ((fg & 0xFF) << 16);
             color = Gdip.Color_new(argb);
             selBrushFg = Gdip.SolidBrush_new(color);
-            selPen = Gdip.Pen_new(selBrushFg, 1);
+            selPen = Gdip.Pen_new( cast(Gdip.Brush*)selBrushFg, 1);
             Gdip.Color_delete(color);
         } else {
             selBrush = OS.CreateSolidBrush(selectionBackground.handle);
@@ -669,7 +680,7 @@
                     width = (lineHeight - lineSpacing) / 3;
                 }
                 if (gdip) {
-                    Gdip.Graphics_FillRectangle(gdipGraphics, selBrush, drawX + lineWidth[line], drawY, width, lineHeight - lineSpacing);
+                    Gdip.Graphics_FillRectangle(gdipGraphics, cast(Gdip.Brush*)selBrush, drawX + lineWidth[line], drawY, width, lineHeight - lineSpacing);
                 } else {
                     OS.SelectObject(hdc, selBrush);
                     OS.PatBlt(hdc, drawX + lineWidth[line], drawY, width, lineHeight - lineSpacing, OS.PATCOPY);
@@ -693,25 +704,25 @@
                     bool fullSelection = hasSelection && selectionStart <= run.start && selectionEnd >= end;
                     if (fullSelection) {
                         if (gdip) {
-                            Gdip.Graphics_FillRectangle(gdipGraphics, selBrush, drawX, drawY, run.width, lineHeight - lineSpacing);
+                            Gdip.Graphics_FillRectangle(gdipGraphics, cast(Gdip.Brush*)selBrush, drawX, drawY, run.width, lineHeight - lineSpacing);
                         } else {
                             OS.SelectObject(hdc, selBrush);
                             OS.PatBlt(hdc, drawX, drawY, run.width, lineHeight - lineSpacing, OS.PATCOPY);
                         }
                     } else {
                         if (run.style !is null && run.style.background !is null) {
-                            int bg = run.style.background.handle;
+                            auto bg = run.style.background.handle;
                             int drawRunY = drawY + (baseline - run.ascent);
                             if (gdip) {
                                 int argb = ((alpha & 0xFF) << 24) | ((bg >> 16) & 0xFF) | (bg & 0xFF00) | ((bg & 0xFF) << 16);
-                                int color = Gdip.Color_new(argb);
-                                int brush = Gdip.SolidBrush_new(color);
-                                Gdip.Graphics_FillRectangle(gdipGraphics, brush, drawX, drawRunY, run.width, run.ascent + run.descent);
+                                auto color = Gdip.Color_new(argb);
+                                auto brush = Gdip.SolidBrush_new(color);
+                                Gdip.Graphics_FillRectangle(gdipGraphics, cast(Gdip.Brush*)brush, drawX, drawRunY, run.width, run.ascent + run.descent);
                                 Gdip.Color_delete(color);
                                 Gdip.SolidBrush_delete(brush);
                             } else {
-                                int hBrush = OS.CreateSolidBrush (bg);
-                                int oldBrush = OS.SelectObject(hdc, hBrush);
+                                auto hBrush = OS.CreateSolidBrush (bg);
+                                auto oldBrush = OS.SelectObject(hdc, hBrush);
                                 OS.PatBlt(hdc, drawX, drawRunY, run.width, run.ascent + run.descent, OS.PATCOPY);
                                 OS.SelectObject(hdc, oldBrush);
                                 OS.DeleteObject(hBrush);
@@ -723,18 +734,18 @@
                             int selEnd = Math.min(selectionEnd, end) - run.start;
                             int cChars = run.length;
                             int gGlyphs = run.glyphCount;
-                            int[] piX = new int[1];
-                            int advances = run.justify !is 0 ? run.justify : run.advances;
-                            OS.ScriptCPtoX(selStart, false, cChars, gGlyphs, run.clusters, run.visAttrs, advances, run.analysis, piX);
-                            int runX = (orientation & DWT.RIGHT_TO_LEFT) !is 0 ? run.width - piX[0] : piX[0];
+                            int piX;
+                            int* advances = run.justify !is null ? run.justify : run.advances;
+                            OS.ScriptCPtoX(selStart, false, cChars, gGlyphs, run.clusters, run.visAttrs, advances, &run.analysis, &piX);
+                            int runX = (orientation & DWT.RIGHT_TO_LEFT) !is 0 ? run.width - piX : piX;
                             rect.left = drawX + runX;
                             rect.top = drawY;
-                            OS.ScriptCPtoX(selEnd, true, cChars, gGlyphs, run.clusters, run.visAttrs, advances, run.analysis, piX);
-                            runX = (orientation & DWT.RIGHT_TO_LEFT) !is 0 ? run.width - piX[0] : piX[0];
+                            OS.ScriptCPtoX(selEnd, true, cChars, gGlyphs, run.clusters, run.visAttrs, advances, &run.analysis, &piX);
+                            runX = (orientation & DWT.RIGHT_TO_LEFT) !is 0 ? run.width - piX : piX;
                             rect.right = drawX + runX;
                             rect.bottom = drawY + lineHeight - lineSpacing;
                             if (gdip) {
-                                Gdip.Graphics_FillRectangle(gdipGraphics, selBrush, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top);
+                                Gdip.Graphics_FillRectangle(gdipGraphics, cast(Gdip.Brush*)selBrush, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top);
                             } else {
                                 OS.SelectObject(hdc, selBrush);
                                 OS.PatBlt(hdc, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, OS.PATCOPY);
@@ -763,25 +774,25 @@
                         int selEnd = Math.min(selectionEnd, end) - run.start;
                         int cChars = run.length;
                         int gGlyphs = run.glyphCount;
-                        int[] piX = new int[1];
-                        int advances = run.justify !is 0 ? run.justify : run.advances;
-                        OS.ScriptCPtoX(selStart, false, cChars, gGlyphs, run.clusters, run.visAttrs, advances, run.analysis, piX);
-                        int runX = (orientation & DWT.RIGHT_TO_LEFT) !is 0 ? run.width - piX[0] : piX[0];
+                        int piX;
+                        int* advances = run.justify !is null ? run.justify : run.advances;
+                        OS.ScriptCPtoX(selStart, false, cChars, gGlyphs, run.clusters, run.visAttrs, advances, &run.analysis, &piX);
+                        int runX = (orientation & DWT.RIGHT_TO_LEFT) !is 0 ? run.width - piX : piX;
                         rect.left = drawX + runX;
                         rect.top = drawY;
-                        OS.ScriptCPtoX(selEnd, true, cChars, gGlyphs, run.clusters, run.visAttrs, advances, run.analysis, piX);
-                        runX = (orientation & DWT.RIGHT_TO_LEFT) !is 0 ? run.width - piX[0] : piX[0];
+                        OS.ScriptCPtoX(selEnd, true, cChars, gGlyphs, run.clusters, run.visAttrs, advances, &run.analysis, &piX);
+                        runX = (orientation & DWT.RIGHT_TO_LEFT) !is 0 ? run.width - piX : piX;
                         rect.right = drawX + runX;
                         rect.bottom = drawY + lineHeight;
                     }
                     if (gdip) {
                         OS.BeginPath(hdc);
-                        OS.ScriptTextOut(hdc, run.psc, drawX, drawRunY, 0, null, run.analysis , 0, 0, run.glyphs, run.glyphCount, run.advances, run.justify, run.goffsets);
+                        OS.ScriptTextOut(hdc, run.psc, drawX, drawRunY, 0, null, &run.analysis , null, 0, run.glyphs, run.glyphCount, run.advances, run.justify, run.goffsets);
                         OS.EndPath(hdc);
                         int count = OS.GetPath(hdc, null, null, 0);
                         int[] points = new int[count*2];
-                        byte[] types = new byte[count];
-                        OS.GetPath(hdc, points, types, count);
+                        ubyte[] types = new ubyte[count];
+                        OS.GetPath(hdc, cast(POINT*)points.ptr, types.ptr, count);
                         for (int typeIndex = 0; typeIndex < types.length; typeIndex++) {
                             int newType = 0;
                             int type = types[typeIndex] & 0xFF;
@@ -793,17 +804,17 @@
                             if ((type & OS.PT_CLOSEFIGURE) !is 0) newType |= Gdip.PathPointTypeCloseSubpath;
                             types[typeIndex] = cast(byte)newType;
                         }
-                        int path = Gdip.GraphicsPath_new(points, types, count, Gdip.FillModeAlternate);
-                        if (path is 0) DWT.error(DWT.ERROR_NO_HANDLES);
-                        int brush = foregroundBrush;
+                        auto path = Gdip.GraphicsPath_new(cast(Gdip.Point*)points.ptr, cast(byte*)types.ptr, count, Gdip.FillModeAlternate);
+                        if (path is null) DWT.error(DWT.ERROR_NO_HANDLES);
+                        auto brush = foregroundBrush;
                         if (fullSelection) {
-                            brush = selBrushFg;
+                            brush = cast(Gdip.Brush*)selBrushFg;
                         } else {
                             if (run.style !is null && run.style.foreground !is null) {
-                                int fg = run.style.foreground.handle;
+                                auto fg = run.style.foreground.handle;
                                 int argb = ((alpha & 0xFF) << 24) | ((fg >> 16) & 0xFF) | (fg & 0xFF00) | ((fg & 0xFF) << 16);
-                                int color = Gdip.Color_new(argb);
-                                brush = Gdip.SolidBrush_new(color);
+                                auto color = Gdip.Color_new(argb);
+                                brush = cast(Gdip.Brush*)Gdip.SolidBrush_new(color);
                                 Gdip.Color_delete(color);
                             }
                         }
@@ -814,7 +825,7 @@
                             gdipRect.Width = rect.right - rect.left;
                             gdipRect.Height = rect.bottom - rect.top;
                             gstate = Gdip.Graphics_Save(gdipGraphics);
-                            Gdip.Graphics_SetClip(gdipGraphics, gdipRect, Gdip.CombineModeExclude);
+                            Gdip.Graphics_SetClip(gdipGraphics, &gdipRect, Gdip.CombineModeExclude);
                         }
                         int antialias = Gdip.Graphics_GetSmoothingMode(gdipGraphics), textAntialias = 0;
                         int mode = Gdip.Graphics_GetTextRenderingHint(data.gdipGraphics);
@@ -839,7 +850,7 @@
                         }
                         Gdip.Graphics_SetSmoothingMode(gdipGraphics, antialias);
                         if (run.style !is null && (run.style.underline || run.style.strikeout)) {
-                            int newPen = hasSelection ? selPen : Gdip.Pen_new(brush, 1);
+                            auto newPen = hasSelection ? cast(Gdip.Pen*)selPen : Gdip.Pen_new(brush, 1);
                             Gdip.Graphics_SetPixelOffsetMode(gdipGraphics, Gdip.PixelOffsetModeNone);
                             if (run.style.underline) {
                                 int underlineY = drawY + baseline + 1 - run.style.rise;
@@ -855,26 +866,26 @@
                         if (partialSelection) {
                             Gdip.Graphics_Restore(gdipGraphics, gstate);
                             gstate = Gdip.Graphics_Save(gdipGraphics);
-                            Gdip.Graphics_SetClip(gdipGraphics, gdipRect, Gdip.CombineModeIntersect);
+                            Gdip.Graphics_SetClip(gdipGraphics, &gdipRect, Gdip.CombineModeIntersect);
                             Gdip.Graphics_SetSmoothingMode(gdipGraphics, textAntialias);
-                            Gdip.Graphics_FillPath(gdipGraphics, selBrushFg, path);
+                            Gdip.Graphics_FillPath(gdipGraphics, cast(Gdip.Brush*)selBrushFg, path);
                             Gdip.Graphics_SetSmoothingMode(gdipGraphics, antialias);
                             if (run.style !is null && (run.style.underline || run.style.strikeout)) {
                                 Gdip.Graphics_SetPixelOffsetMode(gdipGraphics, Gdip.PixelOffsetModeNone);
                                 if (run.style.underline) {
                                     int underlineY = drawY + baseline + 1 - run.style.rise;
-                                    Gdip.Graphics_DrawLine(gdipGraphics, selPen, rect.left, underlineY, rect.right, underlineY);
+                                    Gdip.Graphics_DrawLine(gdipGraphics, cast(Gdip.Pen*)selPen, rect.left, underlineY, rect.right, underlineY);
                                 }
                                 if (run.style.strikeout) {
                                     int strikeoutY = drawRunY + run.leading + (run.ascent - run.style.rise) / 2;
-                                    Gdip.Graphics_DrawLine(gdipGraphics, selPen, rect.left, strikeoutY, rect.right, strikeoutY);
+                                    Gdip.Graphics_DrawLine(gdipGraphics, cast(Gdip.Pen*)selPen, rect.left, strikeoutY, rect.right, strikeoutY);
                                 }
                                 Gdip.Graphics_SetPixelOffsetMode(gdipGraphics, Gdip.PixelOffsetModeHalf);
                             }
                             Gdip.Graphics_Restore(gdipGraphics, gstate);
                         }
                         Gdip.GraphicsPath_delete(path);
-                        if (brush !is selBrushFg && brush !is foregroundBrush) Gdip.SolidBrush_delete(brush);
+                        if (brush !is selBrushFg && brush !is foregroundBrush) Gdip.SolidBrush_delete(cast(Gdip.SolidBrush*)brush);
                     }  else {
                         int fg = foreground;
                         if (fullSelection) {
@@ -883,18 +894,18 @@
                             if (run.style !is null && run.style.foreground !is null) fg = run.style.foreground.handle;
                         }
                         OS.SetTextColor(hdc, fg);
-                        OS.ScriptTextOut(hdc, run.psc, drawX + offset, drawRunY, 0, null, run.analysis , 0, 0, run.glyphs, run.glyphCount, run.advances, run.justify, run.goffsets);
+                        OS.ScriptTextOut(hdc, run.psc, drawX + offset, drawRunY, 0, null, &run.analysis , null, 0, run.glyphs, run.glyphCount, run.advances, run.justify, run.goffsets);
                         if (run.style !is null && (run.style.underline || run.style.strikeout)) {
-                            int newPen = hasSelection && fg is selectionForeground.handle ? selPen : OS.CreatePen(OS.PS_SOLID, 1, fg);
-                            int oldPen = OS.SelectObject(hdc, newPen);
+                            auto newPen = hasSelection && fg is selectionForeground.handle ? cast(HPEN)selPen : OS.CreatePen(OS.PS_SOLID, 1, fg);
+                            auto oldPen = OS.SelectObject(hdc, newPen);
                             if (run.style.underline) {
                                 int underlineY = drawY + baseline + 1 - run.style.rise;
-                                OS.MoveToEx(hdc, drawX, underlineY, 0);
+                                OS.MoveToEx(hdc, drawX, underlineY, null);
                                 OS.LineTo(hdc, drawX + run.width, underlineY);
                             }
                             if (run.style.strikeout) {
                                 int strikeoutY = drawRunY + run.leading + (run.ascent - run.style.rise) / 2;
-                                OS.MoveToEx(hdc, drawX, strikeoutY, 0);
+                                OS.MoveToEx(hdc, drawX, strikeoutY, null);
                                 OS.LineTo(hdc, drawX + run.width, strikeoutY);
                             }
                             OS.SelectObject(hdc, oldPen);
@@ -902,17 +913,17 @@
                         }
                         if (partialSelection && fg !is selectionForeground.handle) {
                             OS.SetTextColor(hdc, selectionForeground.handle);
-                            OS.ScriptTextOut(hdc, run.psc, drawX + offset, drawRunY, OS.ETO_CLIPPED, rect, run.analysis , 0, 0, run.glyphs, run.glyphCount, run.advances, run.justify, run.goffsets);
+                            OS.ScriptTextOut(hdc, run.psc, drawX + offset, drawRunY, OS.ETO_CLIPPED, &rect, &run.analysis , null, 0, run.glyphs, run.glyphCount, run.advances, run.justify, run.goffsets);
                             if (run.style !is null && (run.style.underline || run.style.strikeout)) {
-                                int oldPen = OS.SelectObject(hdc, selPen);
+                                auto oldPen = OS.SelectObject(hdc, selPen);
                                 if (run.style.underline) {
                                     int underlineY = drawY + baseline + 1 - run.style.rise;
-                                    OS.MoveToEx(hdc, rect.left, underlineY, 0);
+                                    OS.MoveToEx(hdc, rect.left, underlineY, null);
                                     OS.LineTo(hdc, rect.right, underlineY);
                                 }
                                 if (run.style.strikeout) {
                                     int strikeoutY = drawRunY + run.leading + (run.ascent - run.style.rise) / 2;
-                                    OS.MoveToEx(hdc, rect.left, strikeoutY, 0);
+                                    OS.MoveToEx(hdc, rect.left, strikeoutY, null);
                                     OS.LineTo(hdc, rect.right, strikeoutY);
                                 }
                                 OS.SelectObject(hdc, oldPen);
@@ -925,14 +936,14 @@
         }
     }
     if (gdip) {
-        if (selBrush !is 0) Gdip.SolidBrush_delete(selBrush);
-        if (selBrushFg !is 0) Gdip.SolidBrush_delete(selBrushFg);
-        if (selPen !is 0) Gdip.Pen_delete(selPen);
+        if (selBrush !is null) Gdip.SolidBrush_delete(cast(Gdip.SolidBrush*)selBrush);
+        if (selBrushFg !is null) Gdip.SolidBrush_delete(cast(Gdip.SolidBrush*)selBrushFg);
+        if (selPen !is null) Gdip.Pen_delete(cast(Gdip.Pen*)selPen);
     } else {
         OS.RestoreDC(hdc, state);
-        if (gdipGraphics !is 0) Gdip.Graphics_ReleaseHDC(gdipGraphics, hdc);
-        if (selBrush !is 0) OS.DeleteObject (selBrush);
-        if (selPen !is 0) OS.DeleteObject (selPen);
+        if (gdipGraphics !is null) Gdip.Graphics_ReleaseHDC(gdipGraphics, hdc);
+        if (selBrush !is null) OS.DeleteObject (selBrush);
+        if (selPen !is null) OS.DeleteObject (selPen);
     }
 }
 
@@ -1022,7 +1033,7 @@
 public Rectangle getBounds (int start, int end) {
     checkLayout();
     computeRuns(null);
-    int length = text.length();
+    int length = text.length;
     if (length is 0) return new Rectangle(0, 0, 0, 0);
     if (start > end) return new Rectangle(0, 0, 0, 0);
     start = Math.min(Math.max(0, start), length - 1);
@@ -1045,10 +1056,10 @@
                 GlyphMetrics metrics = run.style.metrics;
                 cx = metrics.width * (start - run.start);
             } else if (!run.tab) {
-                int[] piX = new int[1];
-                int advances = run.justify !is 0 ? run.justify : run.advances;
-                OS.ScriptCPtoX(start - run.start, false, run.length, run.glyphCount, run.clusters, run.visAttrs, advances, run.analysis, piX);
-                cx = isRTL ? run.width - piX[0] : piX[0];
+                int piX;
+                int* advances = run.justify !is null ? run.justify : run.advances;
+                OS.ScriptCPtoX(start - run.start, false, run.length, run.glyphCount, run.clusters, run.visAttrs, advances, &run.analysis, &piX);
+                cx = isRTL ? run.width - piX : piX;
             }
             if (run.analysis.fRTL ^ isRTL) {
                 runTrail = run.x + cx;
@@ -1062,10 +1073,10 @@
                 GlyphMetrics metrics = run.style.metrics;
                 cx = metrics.width * (end - run.start + 1);
             } else if (!run.tab) {
-                int[] piX = new int[1];
-                int advances = run.justify !is 0 ? run.justify : run.advances;
-                OS.ScriptCPtoX(end - run.start, true, run.length, run.glyphCount, run.clusters, run.visAttrs, advances, run.analysis, piX);
-                cx = isRTL ? run.width - piX[0] : piX[0];
+                int piX;
+                int* advances = run.justify !is null ? run.justify : run.advances;
+                OS.ScriptCPtoX(end - run.start, true, run.length, run.glyphCount, run.clusters, run.visAttrs, advances, &run.analysis, &piX);
+                cx = isRTL ? run.width - piX : piX;
             }
             if (run.analysis.fRTL ^ isRTL) {
                 runLead = run.x + cx;
@@ -1151,8 +1162,8 @@
     return justify;
 }
 
-int getItemFont (StyleItem item) {
-    if (item.fallbackFont !is 0) return item.fallbackFont;
+HFONT getItemFont (StyleItem item) {
+    if (item.fallbackFont !is null) return cast(HFONT) item.fallbackFont;
     if (item.style !is null && item.style.font !is null) {
         return item.style.font.handle;
     }
@@ -1179,7 +1190,7 @@
 public int getLevel (int offset) {
     checkLayout();
     computeRuns(null);
-    int length = text.length();
+    int length = text.length;
     if (!(0 <= offset && offset <= length)) DWT.error(DWT.ERROR_INVALID_RANGE);
     offset = translateOffset(offset);
     for (int i=1; i<allRuns.length; i++) {
@@ -1277,7 +1288,7 @@
 public int getLineIndex (int offset) {
     checkLayout();
     computeRuns(null);
-    int length = text.length();
+    int length = text.length;
     if (!(0 <= offset && offset <= length)) DWT.error(DWT.ERROR_INVALID_RANGE);
     offset = translateOffset(offset);
     for (int line=0; line<runs.length; line++) {
@@ -1305,8 +1316,8 @@
     checkLayout();
     computeRuns(null);
     if (!(0 <= lineIndex && lineIndex < runs.length)) DWT.error(DWT.ERROR_INVALID_RANGE);
-    int hDC = device.internal_new_GC(null);
-    int srcHdc = OS.CreateCompatibleDC(hDC);
+    auto hDC = device.internal_new_GC(null);
+    auto srcHdc = OS.CreateCompatibleDC(hDC);
     TEXTMETRIC lptm;
     OS.SelectObject(srcHdc, font !is null ? font.handle : device.systemFont);
     OS.GetTextMetrics(srcHdc, &lptm);
@@ -1316,7 +1327,7 @@
     int ascent = Math.max(lptm.tmAscent, this.ascent);
     int descent = Math.max(lptm.tmDescent, this.descent);
     int leading = lptm.tmInternalLeading;
-    if (text.length() !is 0) {
+    if (text.length !is 0) {
         StyleItem[] lineRuns = runs[lineIndex];
         for (int i = 0; i<lineRuns.length; i++) {
             StyleItem run = lineRuns[i];
@@ -1332,7 +1343,7 @@
     lptm.tmHeight = ascent + descent;
     lptm.tmInternalLeading = leading;
     lptm.tmAveCharWidth = 0;
-    return FontMetrics.win32_new(lptm);
+    return FontMetrics.win32_new(&lptm);
 }
 
 /**
@@ -1375,9 +1386,9 @@
 public Point getLocation (int offset, bool trailing) {
     checkLayout();
     computeRuns(null);
-    int length = text.length();
+    int length = text.length;
     if (!(0 <= offset && offset <= length)) DWT.error(DWT.ERROR_INVALID_RANGE);
-    length = segmentsText.length();
+    length = segmentsText.length;
     offset = translateOffset(offset);
     int line;
     for (line=0; line<runs.length; line++) {
@@ -1405,13 +1416,13 @@
                     int runOffset = offset - run.start;
                     int cChars = run.length;
                     int gGlyphs = run.glyphCount;
-                    int[] piX = new int[1];
-                    int advances = run.justify !is 0 ? run.justify : run.advances;
-                    OS.ScriptCPtoX(runOffset, trailing, cChars, gGlyphs, run.clusters, run.visAttrs, advances, run.analysis, piX);
+                    int piX;
+                    int* advances = run.justify !is null ? run.justify : run.advances;
+                    OS.ScriptCPtoX(runOffset, trailing, cChars, gGlyphs, run.clusters, run.visAttrs, advances, &run.analysis, &piX);
                     if ((orientation & DWT.RIGHT_TO_LEFT) !is 0) {
-                        result = new Point(width + (run.width - piX[0]), lineY[line]);
+                        result = new Point(width + (run.width - piX), lineY[line]);
                     } else {
-                        result = new Point(width + piX[0], lineY[line]);
+                        result = new Point(width + piX, lineY[line]);
                     }
                 }
                 break;
@@ -1450,16 +1461,16 @@
 
 int _getOffset(int offset, int movement, bool forward) {
     computeRuns(null);
-    int length = text.length();
+    int length = text.length;
     if (!(0 <= offset && offset <= length)) DWT.error(DWT.ERROR_INVALID_RANGE);
     if (forward && offset is length) return length;
     if (!forward && offset is 0) return 0;
     int step = forward ? 1 : -1;
     if ((movement & DWT.MOVEMENT_CHAR) !is 0) return offset + step;
-    length = segmentsText.length();
+    length = segmentsText.length;
     offset = translateOffset(offset);
-    SCRIPT_LOGATTR logAttr = new SCRIPT_LOGATTR();
-    SCRIPT_PROPERTIES properties = new  SCRIPT_PROPERTIES();
+    SCRIPT_LOGATTR* logAttr;
+    SCRIPT_PROPERTIES* properties;
     int i = forward ? 0 : allRuns.length - 1;
     offset = validadeOffset(offset, step);
     do {
@@ -1467,12 +1478,12 @@
         if (run.start <= offset && offset < run.start + run.length) {
             if (run.lineBreak && !run.softBreak) return untranslateOffset(run.start);
             if (run.tab) return untranslateOffset(run.start);
-            OS.MoveMemory(properties, device.scripts[run.analysis.eScript], SCRIPT_PROPERTIES.sizeof);
+            properties = device.scripts[run.analysis.eScript];
             bool isComplex = properties.fNeedsCaretInfo || properties.fNeedsWordBreaking;
             if (isComplex) breakRun(run);
             while (run.start <= offset && offset < run.start + run.length) {
                 if (isComplex) {
-                    OS.MoveMemory(logAttr, run.psla + ((offset - run.start) * SCRIPT_LOGATTR.sizeof), SCRIPT_LOGATTR.sizeof);
+                    logAttr = run.psla + (offset - run.start);
                 }
                 switch (movement) {
                     case DWT.MOVEMENT_CLUSTER: {
@@ -1516,7 +1527,7 @@
         }
         i += step;
     } while (0 <= i && i < allRuns.length - 1 && 0 <= offset && offset < length);
-    return forward ? text.length() : 0;
+    return forward ? text.length : 0;
 }
 
 /**
@@ -1606,15 +1617,15 @@
             }
             int cChars = run.length;
             int cGlyphs = run.glyphCount;
-            int[] piCP = new int[1];
-            int[] piTrailing = new int[1];
+            int piCP;
+            int piTrailing;
             if ((orientation & DWT.RIGHT_TO_LEFT) !is 0) {
                 xRun = run.width - xRun;
             }
-            int advances = run.justify !is 0 ? run.justify : run.advances;
-            OS.ScriptXtoCP(xRun, cChars, cGlyphs, run.clusters, run.visAttrs, advances, run.analysis, piCP, piTrailing);
-            if (trailing !is null) trailing[0] = piTrailing[0];
-            return untranslateOffset(run.start + piCP[0]);
+            int* advances = run.justify !is null ? run.justify : run.advances;
+            OS.ScriptXtoCP(xRun, cChars, cGlyphs, run.clusters, run.visAttrs, advances, &run.analysis, &piCP, &piTrailing);
+            if (trailing !is null) trailing[0] = piTrailing;
+            return untranslateOffset(run.start + piCP);
         }
         width += run.width;
     }
@@ -1710,7 +1721,7 @@
     if (segments is null) return text;
     int nSegments = segments.length;
     if (nSegments <= 1) return text;
-    int length = text.length();
+    int length = text.length;
     if (length is 0) return text;
     if (nSegments is 2) {
         if (segments[0] is 0 && segments[1] is length) return text;
@@ -1719,7 +1730,7 @@
     text.getChars(0, length, oldChars, 0);
     char[] newChars = new char[length + nSegments];
     int charCount = 0, segmentCount = 0;
-    char separator = orientation is DWT.RIGHT_TO_LEFT ? RTL_MARK : LTR_MARK;
+    wchar separator = orientation is DWT.RIGHT_TO_LEFT ? RTL_MARK : LTR_MARK;
     while (charCount < length) {
         if (segmentCount < nSegments && charCount is segments[segmentCount]) {
             newChars[charCount + segmentCount++] = separator;
@@ -1731,7 +1742,7 @@
         segments[segmentCount] = charCount;
         newChars[charCount + segmentCount++] = separator;
     }
-    return new char[](newChars, 0, Math.min(charCount + segmentCount, newChars.length));
+    return newChars[ 0 .. Math.min(charCount + segmentCount, newChars.length)].dup;
 }
 
 /**
@@ -1763,7 +1774,7 @@
  */
 public TextStyle getStyle (int offset) {
     checkLayout();
-    int length = text.length();
+    int length = text.length;
     if (!(0 <= offset && offset < length)) DWT.error(DWT.ERROR_INVALID_RANGE);
     for (int i=1; i<styles.length; i++) {
         if (styles[i].start > offset) {
@@ -1866,29 +1877,28 @@
  */
 StyleItem[] itemize () {
     segmentsText = getSegmentsText();
-    int length = segmentsText.length();
-    SCRIPT_CONTROL scriptControl = new SCRIPT_CONTROL();
-    SCRIPT_STATE scriptState = new SCRIPT_STATE();
+    int length = segmentsText.length;
+    SCRIPT_CONTROL scriptControl;
+    SCRIPT_STATE scriptState;
     final int MAX_ITEM = length + 1;
 
     if ((orientation & DWT.RIGHT_TO_LEFT) !is 0) {
         scriptState.uBidiLevel = 1;
         scriptState.fArabicNumContext = true;
-        SCRIPT_DIGITSUBSTITUTE psds = new SCRIPT_DIGITSUBSTITUTE();
-        OS.ScriptRecordDigitSubstitution(OS.LOCALE_USER_DEFAULT, psds);
-        OS.ScriptApplyDigitSubstitution(psds, scriptControl, scriptState);
+        SCRIPT_DIGITSUBSTITUTE psds;
+        OS.ScriptRecordDigitSubstitution(OS.LOCALE_USER_DEFAULT, &psds);
+        OS.ScriptApplyDigitSubstitution(&psds, &scriptControl, &scriptState);
     }
 
-    int hHeap = OS.GetProcessHeap();
-    int pItems = OS.HeapAlloc(hHeap, OS.HEAP_ZERO_MEMORY, MAX_ITEM * SCRIPT_ITEM.sizeof);
-    if (pItems is 0) DWT.error(DWT.ERROR_NO_HANDLES);
-    int[] pcItems = new int[1];
-    char[] chars = new char[length];
-    segmentsText.getChars(0, length, chars, 0);
-    OS.ScriptItemize(chars, length, MAX_ITEM, scriptControl, scriptState, pItems, pcItems);
+    auto hHeap = OS.GetProcessHeap();
+    auto pItems = cast(SCRIPT_ITEM*)OS.HeapAlloc(hHeap, OS.HEAP_ZERO_MEMORY, MAX_ITEM * SCRIPT_ITEM.sizeof);
+    if (pItems is null) DWT.error(DWT.ERROR_NO_HANDLES);
+    int pcItems;
+    wchar[] chars = StrToWCHARs( segmentsText );
+    OS.ScriptItemize(chars.ptr, chars.length, MAX_ITEM, &scriptControl, &scriptState, pItems, &pcItems);
 //  if (hr is E_OUTOFMEMORY) //TODO handle it
 
-    StyleItem[] runs = merge(pItems, pcItems[0]);
+    StyleItem[] runs = merge(pItems, pcItems);
     OS.HeapFree(hHeap, 0, pItems);
     return runs;
 }
@@ -1896,24 +1906,24 @@
 /*
  *  Merge styles ranges and script items
  */
-StyleItem[] merge (int items, int itemCount) {
-    int count = 0, start = 0, end = segmentsText.length(), itemIndex = 0, styleIndex = 0;
+StyleItem[] merge (SCRIPT_ITEM* items, int itemCount) {
+    int count = 0, start = 0, end = segmentsText.length, itemIndex = 0, styleIndex = 0;
     StyleItem[] runs = new StyleItem[itemCount + styles.length];
-    SCRIPT_ITEM scriptItem = new SCRIPT_ITEM();
+    SCRIPT_ITEM* scriptItem;
     bool linkBefore = false;
     while (start < end) {
         StyleItem item = new StyleItem();
         item.start = start;
         item.style = styles[styleIndex].style;
         runs[count++] = item;
-        OS.MoveMemory(scriptItem, items + itemIndex * SCRIPT_ITEM.sizeof, SCRIPT_ITEM.sizeof);
+        scriptItem = items + itemIndex;
         item.analysis = scriptItem.a;
         if (linkBefore) {
             item.analysis.fLinkBefore = true;
             linkBefore = false;
         }
-        scriptItem.a = new SCRIPT_ANALYSIS();
-        OS.MoveMemory(scriptItem, items + (itemIndex + 1) * SCRIPT_ITEM.sizeof, SCRIPT_ITEM.sizeof);
+        //scriptItem.a = new SCRIPT_ANALYSIS();
+        scriptItem = items + (itemIndex + 1);
         int itemLimit = scriptItem.iCharPos;
         int styleLimit = translateOffset(styles[styleIndex + 1].start);
         if (styleLimit <= itemLimit) {
@@ -1936,7 +1946,7 @@
     }
     StyleItem item = new StyleItem();
     item.start = end;
-    OS.MoveMemory(scriptItem, items + itemCount * SCRIPT_ITEM.sizeof, SCRIPT_ITEM.sizeof);
+    scriptItem = items + itemCount;
     item.analysis = scriptItem.a;
     runs[count++] = item;
     if (runs.length !is count) {
@@ -1951,10 +1961,10 @@
  *  Reorder the run
  */
 StyleItem[] reorder (StyleItem[] runs, bool terminate) {
-    int length = runs.length;
-    if (length <= 1) return runs;
-    byte[] bidiLevels = new byte[length];
-    for (int i=0; i<length; i++) {
+    int length_ = runs.length;
+    if (length_ <= 1) return runs;
+    ubyte[] bidiLevels = new ubyte[length_];
+    for (int i=0; i<length_; i++) {
         bidiLevels[i] = cast(byte)(runs[i].analysis.s.uBidiLevel & 0x1F);
     }
     /*
@@ -1963,22 +1973,22 @@
     * break to be reorder to the middle of the line. The fix is to set
     * the level to zero to prevent it to be reordered.
     */
-    StyleItem lastRun = runs[length - 1];
+    StyleItem lastRun = runs[length_ - 1];
     if (lastRun.lineBreak && !lastRun.softBreak) {
-        bidiLevels[length - 1] = 0;
+        bidiLevels[length_ - 1] = 0;
     }
-    int[] log2vis = new int[length];
-    OS.ScriptLayout(length, bidiLevels, null, log2vis);
-    StyleItem[] result = new StyleItem[length];
-    for (int i=0; i<length; i++) {
+    int[] log2vis = new int[length_];
+    OS.ScriptLayout(length_, bidiLevels.ptr, null, log2vis.ptr);
+    StyleItem[] result = new StyleItem[length_];
+    for (int i=0; i<length_; i++) {
         result[log2vis[i]] = runs[i];
     }
     if ((orientation & DWT.RIGHT_TO_LEFT) !is 0) {
-        if (terminate) length--;
-        for (int i = 0; i < length / 2 ; i++) {
+        if (terminate) length_--;
+        for (int i = 0; i < length_ / 2 ; i++) {
             StyleItem tmp = result[i];
-            result[i] = result[length - i - 1];
-            result[length - i - 1] = tmp;
+            result[i] = result[length_ - i - 1];
+            result[length_ - i - 1] = tmp;
         }
     }
     return result;
@@ -2086,7 +2096,7 @@
     checkLayout();
     if (font !is null && font.isDisposed()) DWT.error(DWT.ERROR_INVALID_ARGUMENT);
     if (this.font is font) return;
-    if (font !is null && font.equals(this.font)) return;
+    if (font !is null && font ==/*eq*/ this.font) return;
     freeRuns();
     this.font = font;
 }
@@ -2221,11 +2231,11 @@
  */
 public void setStyle (TextStyle style, int start, int end) {
     checkLayout();
-    int length = text.length();
-    if (length is 0) return;
+    int length_ = text.length;
+    if (length_ is 0) return;
     if (start > end) return;
-    start = Math.min(Math.max(0, start), length - 1);
-    end = Math.min(Math.max(0, end), length - 1);
+    start = Math.min(Math.max(0, start), length_ - 1);
+    end = Math.min(Math.max(0, end), length_ - 1);
     int low = -1;
     int high = styles.length;
     while (high - low > 1) {
@@ -2242,7 +2252,7 @@
             if (style is null) {
                 if (item.style is null) return;
             } else {
-                if (style.equals(item.style)) return;
+                if (style ==/*eq*/ item.style) return;
             }
         }
     }
@@ -2332,13 +2342,13 @@
 public void setText (char[] text) {
     checkLayout();
     if (text is null) DWT.error(DWT.ERROR_NULL_ARGUMENT);
-    if (text.equals(this.text)) return;
+    if (text==/*eq*/this.text) return;
     freeRuns();
     this.text = text;
     styles = new StyleItem[2];
     styles[0] = new StyleItem();
     styles[1] = new StyleItem();
-    styles[1].start = text.length();
+    styles[1].start = text.length;
 }
 
 /**
@@ -2365,25 +2375,25 @@
     this.wrapWidth = width;
 }
 
-bool shape (int hdc, StyleItem run, char[] chars, int[] glyphCount, int maxGlyphs) {
-    int hr = OS.ScriptShape(hdc, run.psc, chars, chars.length, maxGlyphs, run.analysis, run.glyphs, run.clusters, run.visAttrs, glyphCount);
+bool shape (HDC hdc, StyleItem run, char[] chars, int[] glyphCount, int maxGlyphs) {
+    wchar[] wchars = StrToWCHARs( chars );
+    auto hr = OS.ScriptShape(hdc, run.psc, wchars.ptr, wchars.length, maxGlyphs, &run.analysis, run.glyphs, run.clusters, run.visAttrs, glyphCount.ptr);
     run.glyphCount = glyphCount[0];
     if (hr !is OS.USP_E_SCRIPT_NOT_IN_FONT) {
-        SCRIPT_FONTPROPERTIES fp = new SCRIPT_FONTPROPERTIES ();
+        SCRIPT_FONTPROPERTIES fp;
         fp.cBytes = SCRIPT_FONTPROPERTIES.sizeof;
-        OS.ScriptGetFontProperties(hdc, run.psc, fp);
-        short[] glyphs = new short[glyphCount[0]];
-        OS.MoveMemory(glyphs, run.glyphs, glyphs.length * 2);
+        OS.ScriptGetFontProperties(hdc, run.psc, &fp);
+        ushort[] glyphs = run.glyphs[ 0 .. glyphCount[0] ];
         int i;
         for (i = 0; i < glyphs.length; i++) {
             if (glyphs[i] is fp.wgDefault) break;
         }
         if (i is glyphs.length) return true;
     }
-    if (run.psc !is 0) {
+    if (run.psc !is null) {
         OS.ScriptFreeCache(run.psc);
         glyphCount[0] = 0;
-        OS.MoveMemory(run.psc, glyphCount, 4);
+        *cast(int*)run.psc = 0;
     }
     run.glyphCount = 0;
     return false;
@@ -2396,49 +2406,50 @@
     int[] buffer = new int[1];
     char[] chars = new char[run.length];
     segmentsText.getChars(run.start, run.start + run.length, chars, 0);
+    wchar[] wchars = StrToWCHARs( chars );
     int maxGlyphs = (chars.length * 3 / 2) + 16;
-    int hHeap = OS.GetProcessHeap();
-    run.glyphs = OS.HeapAlloc(hHeap, OS.HEAP_ZERO_MEMORY, maxGlyphs * 2);
-    if (run.glyphs is 0) DWT.error(DWT.ERROR_NO_HANDLES);
-    run.clusters = OS.HeapAlloc(hHeap, OS.HEAP_ZERO_MEMORY, maxGlyphs * 2);
-    if (run.clusters is 0) DWT.error(DWT.ERROR_NO_HANDLES);
-    run.visAttrs = OS.HeapAlloc(hHeap, OS.HEAP_ZERO_MEMORY, maxGlyphs * SCRIPT_VISATTR_SIZEOF);
-    if (run.visAttrs is 0) DWT.error(DWT.ERROR_NO_HANDLES);
-    run.psc = OS.HeapAlloc(hHeap, OS.HEAP_ZERO_MEMORY, 4);
-    if (run.psc is 0) DWT.error(DWT.ERROR_NO_HANDLES);
+    auto hHeap = OS.GetProcessHeap();
+    run.glyphs = cast(ushort*)OS.HeapAlloc(hHeap, OS.HEAP_ZERO_MEMORY, maxGlyphs * 2);
+    if (run.glyphs is null) DWT.error(DWT.ERROR_NO_HANDLES);
+    run.clusters = cast(WORD*)OS.HeapAlloc(hHeap, OS.HEAP_ZERO_MEMORY, maxGlyphs * 2);
+    if (run.clusters is null) DWT.error(DWT.ERROR_NO_HANDLES);
+    run.visAttrs = cast(SCRIPT_VISATTR*)OS.HeapAlloc(hHeap, OS.HEAP_ZERO_MEMORY, maxGlyphs * SCRIPT_VISATTR_SIZEOF);
+    if (run.visAttrs is null) DWT.error(DWT.ERROR_NO_HANDLES);
+    run.psc = cast(SCRIPT_CACHE*)OS.HeapAlloc(hHeap, OS.HEAP_ZERO_MEMORY, 4);
+    if (run.psc is null) DWT.error(DWT.ERROR_NO_HANDLES);
     if (!shape(hdc, run, chars, buffer,  maxGlyphs)) {
-        if (mLangFontLink2 !is 0) {
-            int[] dwCodePages = new int[1];
-            int[] cchCodePages = new int[1];
+        if (mLangFontLink2 !is null) {
+            int dwCodePages;
+            int cchCodePages;
             /* GetStrCodePages() */
-            OS.VtblCall(4, mLangFontLink2, chars, chars.length, 0, dwCodePages, cchCodePages);
-            int[] hNewFont = new int[1];
+            OS.VtblCall(4, mLangFontLink2, cast(int)wchars.ptr, wchars.length, 0, cast(int)&dwCodePages, cast(int)&cchCodePages);
+            HFONT hNewFont;
             /* MapFont() */
-            if (OS.VtblCall(10, mLangFontLink2, hdc, dwCodePages[0], chars[0], hNewFont) is OS.S_OK) {
-                int hFont = OS.SelectObject(hdc, hNewFont[0]);
+            if (OS.VtblCall(10, mLangFontLink2, cast(int)hdc, dwCodePages, cast(int)wchars[0], cast(int)hNewFont) is OS.S_OK) {
+                auto hFont = OS.SelectObject(hdc, hNewFont);
                 if (shape(hdc, run, chars, buffer, maxGlyphs)) {
-                    run.fallbackFont = hNewFont[0];
+                    run.fallbackFont = hNewFont;
                 } else {
                     /* ReleaseFont() */
-                    OS.VtblCall(8, mLangFontLink2, hNewFont[0]);
+                    OS.VtblCall(8, mLangFontLink2, cast(int)hNewFont);
                     OS.SelectObject(hdc, hFont);
-                    SCRIPT_PROPERTIES properties = new SCRIPT_PROPERTIES();
-                    OS.MoveMemory(properties, device.scripts[run.analysis.eScript], SCRIPT_PROPERTIES.sizeof);
+                    SCRIPT_PROPERTIES* properties;
+                    properties = device.scripts[run.analysis.eScript];
                     if (properties.fPrivateUseArea) {
                         run.analysis.fNoGlyphIndex = true;
                     }
-                    OS.ScriptShape(hdc, run.psc, chars, chars.length, maxGlyphs, run.analysis, run.glyphs, run.clusters, run.visAttrs, buffer);
+                    OS.ScriptShape(hdc, run.psc, wchars.ptr, wchars.length, maxGlyphs, &run.analysis, run.glyphs, run.clusters, run.visAttrs, buffer.ptr);
                     run.glyphCount = buffer[0];
                 }
             }
         }
     }
-    int[] abc = new int[3];
-    run.advances = OS.HeapAlloc(hHeap, OS.HEAP_ZERO_MEMORY, run.glyphCount * 4);
-    if (run.advances is 0) DWT.error(DWT.ERROR_NO_HANDLES);
-    run.goffsets = OS.HeapAlloc(hHeap, OS.HEAP_ZERO_MEMORY, run.glyphCount * GOFFSET_SIZEOF);
-    if (run.goffsets is 0) DWT.error(DWT.ERROR_NO_HANDLES);
-    OS.ScriptPlace(hdc, run.psc, run.glyphs, run.glyphCount, run.visAttrs, run.analysis, run.advances, run.goffsets, abc);
+    ABC abc;
+    run.advances = cast(int*)OS.HeapAlloc(hHeap, OS.HEAP_ZERO_MEMORY, run.glyphCount * 4);
+    if (run.advances is null) DWT.error(DWT.ERROR_NO_HANDLES);
+    run.goffsets = cast(GOFFSET*)OS.HeapAlloc(hHeap, OS.HEAP_ZERO_MEMORY, run.glyphCount * GOFFSET_SIZEOF);
+    if (run.goffsets is null) DWT.error(DWT.ERROR_NO_HANDLES);
+    OS.ScriptPlace(hdc, run.psc, run.glyphs, run.glyphCount, run.visAttrs, &run.analysis, run.advances, run.goffsets, &abc);
     if (run.style !is null && run.style.metrics !is null) {
         GlyphMetrics metrics = run.style.metrics;
         /*
@@ -2451,7 +2462,7 @@
         run.descent = metrics.descent;
         run.leading = 0;
     } else {
-        run.width = abc[0] + abc[1] + abc[2];
+        run.width = abc.abcA + abc.abcB + abc.abcC;
         TEXTMETRIC lptm;
         OS.GetTextMetrics(hdc, &lptm);
         run.ascent = lptm.tmAscent;
@@ -2492,10 +2503,10 @@
     if (segments is null) return offset;
     int nSegments = segments.length;
     if (nSegments <= 1) return offset;
-    int length = text.length();
-    if (length is 0) return offset;
+    int length_ = text.length;
+    if (length_ is 0) return offset;
     if (nSegments is 2) {
-        if (segments[0] is 0 && segments[1] is length) return offset;
+        if (segments[0] is 0 && segments[1] is length_) return offset;
     }
     for (int i = 0; i < nSegments && offset - i >= segments[i]; i++) {
         offset++;
@@ -2507,10 +2518,10 @@
     if (segments is null) return offset;
     int nSegments = segments.length;
     if (nSegments <= 1) return offset;
-    int length = text.length();
-    if (length is 0) return offset;
+    int length_ = text.length;
+    if (length_ is 0) return offset;
     if (nSegments is 2) {
-        if (segments[0] is 0 && segments[1] is length) return offset;
+        if (segments[0] is 0 && segments[1] is length_) return offset;
     }
     for (int i = 0; i < nSegments && offset > segments[i]; i++) {
         offset--;
--- a/dwt/internal/win32/OS.d	Mon Jan 28 00:27:56 2008 +0100
+++ b/dwt/internal/win32/OS.d	Mon Jan 28 02:37:23 2008 +0100
@@ -19,6 +19,26 @@
 import dwt.internal.C;
 import dwt.internal.Library;
 
+
+
+// declare of Callback functions
+extern (Windows)
+{
+alias int function() Function0;
+alias int function(void*) Function1;
+alias int function(void*, int) Function2;
+alias int function(void*, int, int) Function3;
+alias int function(void*, int, int, int) Function4;
+alias int function(void*, int, int, int, int) Function5;
+alias int function(void*, int, int, int, int, int) Function6;
+alias int function(void*, int, int, int, int, int, int) Function7;
+alias int function(void*, int, int, int, int, int, int, int) Function8;
+alias int function(void*, int, int, int, int, int, int, int, int) Function9;
+}
+
+
+
+
 public class OS : C {
 
     private static int getNOTIFYICONDATAA_V2_SIZE (){
@@ -4012,6 +4032,7 @@
 alias WINAPI.Arc Arc;
 alias WINAPI.BeginDeferWindowPos BeginDeferWindowPos;
 alias WINAPI.BeginPaint BeginPaint;
+alias STDWIN.BeginPath BeginPath;
 alias WINAPI.BitBlt BitBlt;
 alias WINAPI.BringWindowToTop BringWindowToTop;
 alias WINAPI.CallNextHookEx CallNextHookEx;
@@ -4109,6 +4130,7 @@
 alias WINAPI.EndDoc EndDoc;
 alias WINAPI.EndPage EndPage;
 alias WINAPI.EndPaint EndPaint;
+alias STDWIN.EndPath EndPath;
 alias WINAPI.EnumDisplayMonitors EnumDisplayMonitors;
 alias WINAPI.EnumFontFamiliesA EnumFontFamiliesA;
 alias WINAPI.EnumFontFamiliesExA EnumFontFamiliesExA;
@@ -4206,6 +4228,7 @@
 alias WINAPI.GetMonitorInfoA GetMonitorInfoA;
 alias WINAPI.GetMonitorInfoW GetMonitorInfoW;
 alias WINAPI.GetNearestPaletteIndex GetNearestPaletteIndex;
+alias STDWIN.GetPath GetPath;
 alias WINAPI.GetObjectA GetObjectA;
 alias WINAPI.GetObjectW GetObjectW;
 alias WINAPI.GetOpenFileNameA GetOpenFileNameA;
@@ -4403,6 +4426,7 @@
 }
 alias WINAPI.SaveDC SaveDC;
 alias WINAPI.ScreenToClient ScreenToClient;
+alias WINAPI.ScriptApplyDigitSubstitution ScriptApplyDigitSubstitution;
 alias WINAPI.ScriptBreak ScriptBreak;
 alias WINAPI.ScriptCPtoX ScriptCPtoX;
 alias WINAPI.ScriptCacheGetHeight ScriptCacheGetHeight;
@@ -4411,8 +4435,10 @@
 alias WINAPI.ScriptGetLogicalWidths ScriptGetLogicalWidths;
 alias WINAPI.ScriptGetProperties ScriptGetProperties;
 alias WINAPI.ScriptItemize ScriptItemize;
+alias WINAPI.ScriptJustify ScriptJustify;
 alias WINAPI.ScriptLayout ScriptLayout;
 alias WINAPI.ScriptPlace ScriptPlace;
+alias WINAPI.ScriptRecordDigitSubstitution ScriptRecordDigitSubstitution;
 alias WINAPI.ScriptShape ScriptShape;
 alias WINAPI.ScriptTextOut ScriptTextOut;
 alias WINAPI.ScriptXtoCP ScriptXtoCP;
@@ -4628,6 +4654,60 @@
 static void OleUninitialize(){
     WINAPI.OleUninitialize();
 }
+/**
+ * <Shawn Liu>
+ * VtbCall partially kept, use VtbCall instead of automation can promote performace
+ * and VtbCall doesn't need prototype of interface declaration
+ */
+
+public static int VtblCall(int fnNumber, void* ppVtbl) {
+    Function1 fn = cast(Function1)(*cast(int **)ppVtbl)[fnNumber];
+    return fn(ppVtbl);
+}
+
+public static int VtblCall(int fnNumber, void* ppVtbl, int arg0){
+    Function2 fn = cast(Function2)(*cast(int **)ppVtbl)[fnNumber];
+    return fn(ppVtbl, arg0);
+}
+
+public static int VtblCall(int fnNumber, void* ppVtbl, int arg0, int arg1){
+    Function3 fn = cast(Function3)(*cast(int **)ppVtbl)[fnNumber];
+    return fn(ppVtbl, arg0, arg1);
+}
+
+public static int VtblCall(int fnNumber, void* ppVtbl, int arg0, int arg1, int arg2){
+    Function4 fn = cast(Function4)(*cast(int **)ppVtbl)[fnNumber];
+    return fn(ppVtbl, arg0, arg1, arg2);
+}
+public static int VtblCall(int fnNumber, void* ppVtbl, int arg0, int arg1, int arg2, int arg3){
+    Function5 fn = cast(Function5)(*cast(int **)ppVtbl)[fnNumber];
+    return fn(ppVtbl, arg0, arg1, arg2, arg3);
+}
+
+public static int VtblCall(int fnNumber, void* ppVtbl, int arg0, int arg1, int arg2, int arg3, int arg4){
+    Function6 fn = cast(Function6)(*cast(int **)ppVtbl)[fnNumber];
+    return fn(ppVtbl, arg0, arg1, arg2, arg3, arg4);
+}
+
+public static int VtblCall(int fnNumber, void* ppVtbl, int arg0, int arg1, int arg2, int arg3, int arg4, int arg5){
+    Function7 fn = cast(Function7)(*cast(int **)ppVtbl)[fnNumber];
+    return fn(ppVtbl, arg0, arg1, arg2, arg3, arg4, arg5);
+}
+
+public static int VtblCall(int fnNumber, void* ppVtbl, int arg0, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6){
+    Function8 fn = cast(Function8)(*cast(int **)ppVtbl)[fnNumber];
+    return fn(ppVtbl, arg0, arg1, arg2, arg3, arg4, arg5, arg6);
+}
+
+public static int VtblCall(int fnNumber, void* ppVtbl, int arg0, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7){
+    Function9 fn = cast(Function9)(*cast(int **)ppVtbl)[fnNumber];
+    return fn(ppVtbl, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
+}
+
+public static int CoCreateInstance(
+    byte* rclsid, void* pUnkOuter, int dwClsContext, byte* riid, void* ppv
+);
+
 
 } // END of OS
 
--- a/dwt/internal/win32/WINAPI.d	Mon Jan 28 00:27:56 2008 +0100
+++ b/dwt/internal/win32/WINAPI.d	Mon Jan 28 02:37:23 2008 +0100
@@ -41,7 +41,24 @@
   UINT crTransparent  // color to make transparent
 );
 int IIDFromString (wchar* lpsz, byte* lpiid);
+HRESULT ScriptJustify(
+  SCRIPT_VISATTR* psva,
+  int* piAdvance,
+  int cGlyphs,
+  int iDx,
+  int iMinKashida,
+  int* piJustify
+);
 
+HRESULT ScriptRecordDigitSubstitution(
+  LCID Locale,
+  SCRIPT_DIGITSUBSTITUTE* psds
+);
+HRESULT ScriptApplyDigitSubstitution(
+  SCRIPT_DIGITSUBSTITUTE* psds,
+  SCRIPT_CONTROL* psc,
+  SCRIPT_STATE* pss
+);
 }
 
 
--- a/dwt/internal/win32/WINTYPES.d	Mon Jan 28 00:27:56 2008 +0100
+++ b/dwt/internal/win32/WINTYPES.d	Mon Jan 28 02:37:23 2008 +0100
@@ -15,6 +15,19 @@
 alias WNDCLASS   WNDCLASSA;
 alias WNDCLASSA* LPWNDCLASSA;
 
+alias TCLSID *REFCLSID;
+
+interface IUnknown{
+}
+
+alias IUnknown LPUNKNOWN;
+
+struct SCRIPT_DIGITSUBSTITUTE {
+  ushort NationalDigitLanguage;
+  ushort TraditionalDigitLanguage;
+  DWORD DigitSubstitute;
+  DWORD dwReserved;
+}
 
 // ....