OSDN Git Service

レンダーターゲットをクラス変数として持たせておく意味はない
[fooeditengine/FooEditEngine.git] / WPF / FooEditEngine / Direct2D / D2DRender.cs
index f8c57f0..e12f559 100644 (file)
@@ -15,6 +15,7 @@ using System.Text;
 using System.Windows;
 using System.Windows.Controls;
 using System.Windows.Media;
+using System.Windows.Input;
 using System.Windows.Interop;
 using FooEditEngine;
 using DotNetTextStore;
@@ -23,7 +24,7 @@ using DotNetTextStore.UnmanagedAPI.WinDef;
 using SharpDX;
 using D2D = SharpDX.Direct2D1;
 using DW = SharpDX.DirectWrite;
-using D3D10 = SharpDX.Direct3D10;
+using D3D11 = SharpDX.Direct3D11;
 using D3D9 = SharpDX.Direct3D9;
 using DXGI = SharpDX.DXGI;
 
@@ -32,19 +33,18 @@ namespace FooEditEngine.WPF
     sealed class D2DRender : D2DRenderCommon, IEditorRender
     {
         DotNetTextStore.TextStore store;
-        D3D10.Texture2D texture;
+        D3D11.Texture2D texture;
         DXGI.Surface surface;
-        D3D10.Device device;
+        D3D11.Device device;
         D3D9.Device device9;
         D3D9.Surface surface9;
-        D2D.RenderTarget render;
         double fontSize;
         FontFamily fontFamily;
         FontWeight fontWeigth;
         FontStyle fontStyle;
         D3DImage imageSource;
 
-        public D2DRender(FooTextBox textbox, double width, double height,Image image)
+        public D2DRender(FooTextBox textbox, double width, double height, Image image)
         {
             this.fontFamily = textbox.FontFamily;
             this.fontSize = textbox.FontSize;
@@ -64,11 +64,12 @@ namespace FooEditEngine.WPF
             this.LineMarker = ToColor4(textbox.LineMarker);
             this.UpdateArea = ToColor4(textbox.UpdateArea);
             this.LineNumber = ToColor4(textbox.LineNumber);
+            this.HilightForeground = ToColor4(textbox.HilightForeground);
             this.store = textbox.TextStore;
 
             this.CreateDevice();
 
-            this.ConstructDeviceResource(width, height);
+            this.ConstructRenderAndResource(width, height);
             this.InitTextFormat(this.fontFamily.Source, (float)this.fontSize, this.GetDWFontWeigth(this.fontWeigth), this.GetDWFontStyle(this.fontStyle));
 
             this.imageSource = new D3DImage();
@@ -110,7 +111,7 @@ namespace FooEditEngine.WPF
             set
             {
                 this.fontWeigth = value;
-                this.InitTextFormat(this.fontFamily.Source, (float)this.fontSize, this.GetDWFontWeigth(value),this.GetDWFontStyle(this.fontStyle));
+                this.InitTextFormat(this.fontFamily.Source, (float)this.fontSize, this.GetDWFontWeigth(value), this.GetDWFontStyle(this.fontStyle));
             }
         }
 
@@ -136,7 +137,7 @@ namespace FooEditEngine.WPF
         {
             if (Math.Floor(width) != Math.Floor(this.imageSource.Width) || Math.Floor(height) != Math.Floor(this.imageSource.Height))
             {
-                this.ReConstructDeviceResource(width, height);
+                this.ReConstructRenderAndResource(width, height);
                 this.imageSource.Lock();
                 this.imageSource.SetBackBuffer(D3DResourceType.IDirect3DSurface9, this.surface9.NativePointer);
                 this.imageSource.Unlock();
@@ -145,90 +146,106 @@ namespace FooEditEngine.WPF
             return false;
         }
 
-        public override void BegineDraw()
+        public void ReConstructRenderAndResource(double width, double height)
         {
-            base.BegineDraw();
+            this.DestructRenderAndResource();
+            this.ConstructRenderAndResource(width, height);
         }
 
-        public override void EndDraw()
+        public void DrawContent(EditView view, bool IsEnabled, Rectangle updateRect)
         {
-            base.EndDraw();
-            this.device.Flush();
-
             if (this.imageSource.IsFrontBufferAvailable)
             {
                 this.imageSource.Lock();
                 this.imageSource.SetBackBuffer(D3DResourceType.IDirect3DSurface9, this.surface9.NativePointer);
-                this.imageSource.AddDirtyRect(new Int32Rect(0, 0, (int)this.imageSource.Width, (int)this.imageSource.Height));
+
+                base.BegineDraw();
+                if (IsEnabled)
+                    view.Draw(updateRect);
+                else
+                    this.FillBackground(updateRect);
+                base.EndDraw();
+                this.device.ImmediateContext.Flush();
+
+                this.imageSource.AddDirtyRect(new Int32Rect(0, 0, (int)this.imageSource.PixelWidth, (int)this.imageSource.PixelHeight));
                 this.imageSource.Unlock();
             }
         }
 
-        public void DrawOneLine(LineToIndexTable lti, int row, double x, double y, IEnumerable<Selection> SelectRanges)
+        public void DrawOneLine(Document doc, LineToIndexTable lti, int row, double x, double y)
         {
-            PreDrawOneLineHandler PreDrawOneLine = (layout) => {
-                using (Unlocker locker = this.store.LockDocument(false))
+            PreDrawOneLineHandler PreDrawOneLine = null;
+
+            if (InputMethod.Current.ImeState == InputMethodState.On)
+                PreDrawOneLine = this.DrawImeConversionLine;
+
+            base.DrawOneLine(doc,
+                lti,
+                row,
+                x,
+                y,
+                PreDrawOneLine
+                );
+        }
+
+        private void DrawImeConversionLine(MyTextLayout layout, LineToIndexTable lti, int row, double x, double y)
+        {
+            using (Unlocker locker = this.store.LockDocument(false))
+            {
+                int lineIndex = lti.GetIndexFromLineNumber(row);
+                int lineLength = lti.GetLengthFromLineNumber(row);
+                foreach (TextDisplayAttribute attr in this.store.EnumAttributes(lineIndex, lineIndex + lineLength))
                 {
-                    int lineIndex = lti.GetIndexFromLineNumber(row);
-                    int lineLength = lti.GetLengthFromLineNumber(row);
-                    foreach (TextDisplayAttribute attr in this.store.EnumAttributes(lineIndex,lineIndex + lineLength))
+                    if (attr.startIndex == attr.endIndex)
+                        continue;
+                    int length = attr.endIndex - attr.startIndex;
+                    int start = attr.startIndex - lineIndex;
+
+                    HilightType type = HilightType.None;
+                    Color4? color = null;
+                    switch (attr.attribute.lsStyle)
                     {
-                        if (attr.startIndex == attr.endIndex)
-                            continue;
-                        int length = attr.endIndex - attr.startIndex;
-                        int start = attr.startIndex - lineIndex;
-
-                        HilightType type = HilightType.None;
-                        Color4? color = null;
-                        switch (attr.attribute.lsStyle)
-                        {
-                            case TF_DA_LINESTYLE.TF_LS_DOT:
-                                type = HilightType.Dot;
-                                color = this.GetColor4(attr.attribute.crLine);
-                                break;
-                            case TF_DA_LINESTYLE.TF_LS_SOLID:
-                                type = HilightType.Sold;
-                                color = this.GetColor4(attr.attribute.crLine);
-                                break;
-                            case TF_DA_LINESTYLE.TF_LS_DASH:
-                                type = HilightType.Dash;
-                                color = this.GetColor4(attr.attribute.crLine);
-                                break;
-                            case TF_DA_LINESTYLE.TF_LS_SQUIGGLE:
-                                type = HilightType.Squiggle;
-                                color = this.GetColor4(attr.attribute.crLine);
-                                break;
-                        }
-
-                        if (attr.attribute.crBk.type != TF_DA_COLORTYPE.TF_CT_NONE)
-                        {
-                            type = HilightType.Select;
-                            color = this.GetColor4(attr.attribute.crBk);
-                        }
-
-                        this.DrawMarkerEffect(layout, type, start, length,x,y,attr.attribute.fBoldLine,color);
-
-                        color = this.GetColor4(attr.attribute.crText);
-                        if (color != null)
-                        {
-                            this.SetTextColor(layout, start, length, color);
-                            layout.Invaild = true;
-                        }
+                        case TF_DA_LINESTYLE.TF_LS_DOT:
+                            type = HilightType.Dot;
+                            color = this.GetColor4(attr.attribute.crLine);
+                            break;
+                        case TF_DA_LINESTYLE.TF_LS_SOLID:
+                            type = HilightType.Sold;
+                            color = this.GetColor4(attr.attribute.crLine);
+                            break;
+                        case TF_DA_LINESTYLE.TF_LS_DASH:
+                            type = HilightType.Dash;
+                            color = this.GetColor4(attr.attribute.crLine);
+                            break;
+                        case TF_DA_LINESTYLE.TF_LS_SQUIGGLE:
+                            type = HilightType.Squiggle;
+                            color = this.GetColor4(attr.attribute.crLine);
+                            break;
+                    }
+
+                    if (attr.attribute.crBk.type != TF_DA_COLORTYPE.TF_CT_NONE)
+                    {
+                        type = HilightType.Select;
+                        color = this.GetColor4(attr.attribute.crBk);
+                    }
+
+                    this.DrawMarkerEffect(layout, type, start, length, x, y, attr.attribute.fBoldLine, color);
+
+                    color = this.GetColor4(attr.attribute.crText);
+                    if (color != null)
+                    {
+                        this.SetTextColor(layout, start, length, color);
+                        layout.Invaild = true;
                     }
                 }
-            };
-            base.DrawOneLine(lti,
-                row,
-                x,
-                y,
-                SelectRanges,
-                PreDrawOneLine);
+            }
+
         }
 
         private Color4? GetColor4(TF_DA_COLOR cr)
         {
             COLORREF colorref;
-            switch(cr.type)
+            switch (cr.type)
             {
                 case TF_DA_COLORTYPE.TF_CT_SYSCOLOR:
                     colorref = new COLORREF(NativeMethods.GetSysColor((int)cr.indexOrColorRef));
@@ -242,12 +259,6 @@ namespace FooEditEngine.WPF
             return new Color4(colorref.R / 255.0f, colorref.G / 255.0f, colorref.B / 255.0f, 1);
         }
 
-        public override void Dispose()
-        {
-            base.Dispose();
-            this.DestructDevice();
-        }
-
         DW.FontStyle GetDWFontStyle(FontStyle style)
         {
             return (DW.FontStyle)Enum.Parse(typeof(DW.FontStyle), style.ToString());
@@ -260,7 +271,7 @@ namespace FooEditEngine.WPF
 
         public override void DrawCachedBitmap(Rectangle rect)
         {
-            if (this.render == null || this.render.IsDisposed)
+            if (this.render == null || this.render.IsDisposed || this.cachedBitMap == null || this.cachedBitMap.IsDisposed)
                 return;
             render.DrawBitmap(this.cachedBitMap, rect, 1.0f, D2D.BitmapInterpolationMode.Linear, rect);
         }
@@ -269,23 +280,25 @@ namespace FooEditEngine.WPF
         {
             if (this.render == null || this.cachedBitMap == null || this.cachedBitMap.IsDisposed || this.render.IsDisposed)
                 return;
-            //render.Flush();
+            render.Flush();
             this.cachedBitMap.CopyFromRenderTarget(this.render, new SharpDX.Point(), new SharpDX.Rectangle(0, 0, (int)this.renderSize.Width, (int)this.renderSize.Height));
             this.hasCache = true;
         }
 
         void CreateDevice()
         {
-            D3D10.FeatureLevel[] levels = new D3D10.FeatureLevel[]{D3D10.FeatureLevel.Level_10_1,
-                D3D10.FeatureLevel.Level_10_0,
-                D3D10.FeatureLevel.Level_9_3,
-                D3D10.FeatureLevel.Level_9_2,
-                D3D10.FeatureLevel.Level_9_1};
-            foreach (D3D10.FeatureLevel level in levels)
+            SharpDX.Direct3D.FeatureLevel[] levels = new SharpDX.Direct3D.FeatureLevel[]{
+                SharpDX.Direct3D.FeatureLevel.Level_11_0,
+                SharpDX.Direct3D.FeatureLevel.Level_10_1,
+                SharpDX.Direct3D.FeatureLevel.Level_10_0,
+                SharpDX.Direct3D.FeatureLevel.Level_9_3,
+                SharpDX.Direct3D.FeatureLevel.Level_9_2,
+                SharpDX.Direct3D.FeatureLevel.Level_9_1};
+            foreach (var level in levels)
             {
                 try
                 {
-                    this.device = new D3D10.Device1(D3D10.DriverType.Hardware, D3D10.DeviceCreationFlags.BgraSupport,level);
+                    this.device = new D3D11.Device(SharpDX.Direct3D.DriverType.Hardware, D3D11.DeviceCreationFlags.BgraSupport, level);
                     break;
                 }
                 catch
@@ -352,28 +365,30 @@ namespace FooEditEngine.WPF
             }
         }
 
-        protected override void ReCreateTarget()
+        public void ConstructRenderAndResource(double width, double height)
         {
-            System.Diagnostics.Debug.WriteLine("ReCreatedDevice");
-            this.DestructDevice();
-            this.CreateDevice();
-            this.ReConstructDeviceResource();
-        }
-
-        protected override D2D.RenderTarget ConstructRender(D2D.Factory factory, D2D.RenderTargetProperties prop, double width, double height)
-        {
-            D3D10.Texture2DDescription desc = new D3D10.Texture2DDescription();
+            float dpiX, dpiY;
+            this.GetDpi(out dpiX, out dpiY);
+            D2D.RenderTargetProperties prop = new D2D.RenderTargetProperties(
+                D2D.RenderTargetType.Default,
+                new D2D.PixelFormat(DXGI.Format.B8G8R8A8_UNorm, D2D.AlphaMode.Premultiplied),
+                dpiX,
+                dpiY,
+                D2D.RenderTargetUsage.None,
+                D2D.FeatureLevel.Level_DEFAULT);
+
+            D3D11.Texture2DDescription desc = new D3D11.Texture2DDescription();
             desc.Width = (int)width;
             desc.Height = (int)height;
             desc.MipLevels = 1;
             desc.ArraySize = 1;
             desc.Format = DXGI.Format.B8G8R8A8_UNorm;
             desc.SampleDescription = new DXGI.SampleDescription(1, 0);
-            desc.Usage = D3D10.ResourceUsage.Default;
-            desc.BindFlags = D3D10.BindFlags.RenderTarget | D3D10.BindFlags.ShaderResource;
-            desc.CpuAccessFlags = D3D10.CpuAccessFlags.None;
-            desc.OptionFlags = D3D10.ResourceOptionFlags.Shared;
-            this.texture = new D3D10.Texture2D(this.device, desc);
+            desc.Usage = D3D11.ResourceUsage.Default;
+            desc.BindFlags = D3D11.BindFlags.RenderTarget | D3D11.BindFlags.ShaderResource;
+            desc.CpuAccessFlags = D3D11.CpuAccessFlags.None;
+            desc.OptionFlags = D3D11.ResourceOptionFlags.Shared;
+            this.texture = new D3D11.Texture2D(this.device, desc);
 
             this.surface = this.texture.QueryInterface<DXGI.Surface>();
 
@@ -392,31 +407,29 @@ namespace FooEditEngine.WPF
             resource.Dispose();
             texture.Dispose();
 
-            this.render = new D2D.RenderTarget(factory, this.surface, prop);
-            return this.render;
-        }
+            this.render = new D2D.RenderTarget(D2DRenderShared.D2DFactory, this.surface, prop);
 
-        protected override void ConstrctedResource()
-        {
-        }
+            D2D.BitmapProperties bmpProp = new D2D.BitmapProperties();
+            bmpProp.DpiX = dpiX;
+            bmpProp.DpiY = dpiY;
+            bmpProp.PixelFormat = new D2D.PixelFormat(DXGI.Format.B8G8R8A8_UNorm, D2D.AlphaMode.Premultiplied);
+            this.cachedBitMap = new D2D.Bitmap(this.render, new SharpDX.Size2((int)width, (int)height), bmpProp);
+            this.hasCache = false;
 
-        public double GetScale()
-        {
-            float dpi;
-            this.GetDpi(out dpi, out dpi);
-            return dpi / 96.0;
-        }
+            this.textRender = new CustomTextRenderer(this.Brushes, this.Strokes, this.Foreground);
 
-        public override void GetDpi(out float dpix, out float dpiy)
-        {
-            IntPtr hDc = NativeMethods.GetDC(IntPtr.Zero);
-            dpix = NativeMethods.GetDeviceCaps(hDc, NativeMethods.LOGPIXELSX);
-            dpiy = NativeMethods.GetDeviceCaps(hDc, NativeMethods.LOGPIXELSY);
-            NativeMethods.ReleaseDC(IntPtr.Zero, hDc);
+            this.renderSize = new Size(width, height);
         }
 
-        protected override void DestructRender()
+        public void DestructRenderAndResource()
         {
+            this.hasCache = false;
+            if (this.cachedBitMap != null)
+                this.cachedBitMap.Dispose();
+            this.Brushes.Clear();
+            this.Strokes.Clear();
+            if (this.textRender != null)
+                this.textRender.Dispose();
             if (this.texture != null)
                 this.texture.Dispose();
             if (this.surface != null)
@@ -426,5 +439,22 @@ namespace FooEditEngine.WPF
             if (this.render != null)
                 this.render.Dispose();
         }
+
+        public override void GetDpi(out float dpix, out float dpiy)
+        {
+            var dpiXProperty = typeof(SystemParameters).GetProperty("DpiX", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static);
+            var dpiYProperty = typeof(SystemParameters).GetProperty("Dpi", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static);
+
+            dpix = (int)dpiXProperty.GetValue(null, null);
+            dpiy = (int)dpiYProperty.GetValue(null, null);
+        }
+
+        protected override void Dispose(bool dispose)
+        {
+            base.Dispose(dispose);
+            this.DestructRenderAndResource();
+            this.DestructDevice();
+        }
+
     }
 }