OSDN Git Service

初コミット
[fooeditengine/FooEditEngine.git] / Metro / FooEditEngnine / Direct2D / D2DRender.cs
1 /*
2  * Copyright (C) 2013 FooProject
3  * * This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by
4  * the Free Software Foundation; either version 3 of the License, or (at your option) any later version.
5
6  * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of 
7  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
8
9 You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.
10  */
11 using System;
12 using System.Collections.Generic;
13 using Windows.Graphics.Display;
14 using Windows.UI.Xaml.Media;
15 using Windows.UI.Xaml.Media.Imaging;
16 using SharpDX;
17 using DXGI = SharpDX.DXGI;
18 using D2D = SharpDX.Direct2D1;
19 using D3D = SharpDX.Direct3D;
20 using D3D11 = SharpDX.Direct3D11;
21 using FooEditEngine.Metro;
22 using DotNetTextStore;
23 using DotNetTextStore.UnmanagedAPI.TSF;
24 using DotNetTextStore.UnmanagedAPI.WinDef;
25
26 namespace FooEditEngine
27 {
28     class D2DRender : D2DRenderBase,ITextRender
29     {
30         SurfaceImageSource SurfaceImage;
31         DXGI.ISurfaceImageSourceNative SurfaceImageNative;
32         D2D.Device D2DDevice;
33         D2D.DeviceContext D2DContext;
34         D2D.Bitmap1 Bitmap;
35         Size Size = new Size();
36         DXGI.Surface Surface;
37         TextStore2 store;
38
39         public D2DRender(FooTextBox textbox,Windows.UI.Xaml.Shapes.Rectangle rect,TextStore2 store)
40             : base()
41         {
42             base.ConstructRender = this.ConstructRenderHandler;
43             base.ConstrctedResource = this.ConstructedResourceHandler;
44             base.DestructRender = this.DestructRenderHandler;
45             base.ReCreateTarget = this.ReCreateTargetHandler;
46             base.GetDpi = this.GetDpiHandler;
47             this.ConstructDeviceResource(rect.ActualWidth,rect.ActualHeight);
48             this.InitTextFormat(textbox.FontFamily, textbox.FontSize);
49
50             this.store = store;
51
52             this.Size.Width = rect.ActualWidth;
53             this.Size.Height = rect.ActualHeight;
54
55             this.CreateSurface(rect, rect.ActualWidth, rect.ActualHeight);
56
57             base.PreDrawOneLine = D2DRender_PreDrawOneLine;
58
59             this.Foreground = textbox.Foreground;
60             this.Background = textbox.Background;
61             this.Hilight = textbox.Hilight;
62             this.Keyword1 = textbox.Keyword1;
63             this.Keyword2 = textbox.Keyword2;
64             this.Literal = textbox.Literal;
65             this.Url = textbox.URL;
66             this.ControlChar = textbox.ControlChar;
67             this.Comment = textbox.Comment;
68             this.InsertCaret = textbox.InsertCaret;
69             this.OverwriteCaret = textbox.OverwriteCaret;
70             this.LineMarker = textbox.LineMarker;
71         }
72
73         void D2DRender_PreDrawOneLine(MyTextLayout layout,LineToIndexTable lti, int row, double x, double y)
74         {
75             using (Unlocker locker = this.store.LockDocument(false))
76             {
77                 int lineIndex = lti.GetIndexFromLineNumber(row);
78                 int lineLength = lti.GetLengthFromLineNumber(row);
79                 foreach (TextDisplayAttribute attr in this.store.EnumAttributes(lineIndex, lineIndex + lineLength))
80                 {
81                     if (attr.startIndex == attr.endIndex)
82                         continue;
83                     int length = attr.endIndex - attr.startIndex;
84                     int start = attr.startIndex - lineIndex;
85
86                     HilightType type = HilightType.None;
87                     Windows.UI.Color? color = null;
88                     switch (attr.attribute.lsStyle)
89                     {
90                         case TF_DA_LINESTYLE.TF_LS_DOT:
91                             type = HilightType.Dot;
92                             color = this.Foreground;
93                             break;
94                         case TF_DA_LINESTYLE.TF_LS_SOLID:
95                             type = HilightType.Sold;
96                             color = this.Foreground;
97                             break;
98                         case TF_DA_LINESTYLE.TF_LS_DASH:
99                             type = HilightType.Dash;
100                             color = this.Foreground;
101                             break;
102                         case TF_DA_LINESTYLE.TF_LS_SQUIGGLE:
103                             type = HilightType.Squiggle;
104                             color = this.Foreground;
105                             break;
106                     }
107
108                     if (attr.attribute.crBk.type != TF_DA_COLORTYPE.TF_CT_NONE)
109                     {
110                         type = HilightType.Select;
111                         color = this.Hilight;
112                     }
113
114                     this.DrawMarkerEffect(layout, type, start, length, x, y, attr.attribute.fBoldLine, color);
115                 }
116             }
117         }
118
119         void GetDpiHandler(out int dpix, out int dpiy)
120         {
121             dpix = (int)DisplayProperties.LogicalDpi;
122             dpiy = (int)DisplayProperties.LogicalDpi;
123         }
124
125         public bool Resize(Windows.UI.Xaml.Shapes.Rectangle rect, double width, double height)
126         {
127             if (this.Size.Width == width && this.Size.Height == height)
128                 return false;
129             this.ReConstructDeviceResource(width, height);
130             this.CreateSurface(rect, width, height);
131             return true;
132         }
133
134         public bool IsCanDraw()
135         {
136             return this.Size.Height != 0 && this.Size.Width != 0;
137         }
138
139         public override void BeginDraw()
140         {
141             SharpDX.Point offset;
142             this.Surface = this.SurfaceImageNative.BeginDraw(
143                 new SharpDX.Rectangle(0, 0, (int)this.Size.Width, (int)this.Size.Height), out offset);
144             int dpix, dpiy;
145             this.GetDpiHandler(out dpix, out dpiy);
146             D2D.BitmapProperties1 prop = new D2D.BitmapProperties1(new D2D.PixelFormat(DXGI.Format.B8G8R8A8_UNorm, D2D.AlphaMode.Premultiplied),
147                     dpix, dpiy, D2D.BitmapOptions.Target | D2D.BitmapOptions.CannotDraw);
148             this.Bitmap = new D2D.Bitmap1(this.D2DContext, this.Surface, prop);
149             this.D2DContext.Target = this.Bitmap;
150             this.D2DContext.Transform = Matrix3x2.Translation(offset.X,offset.Y);
151             base.BeginDraw();
152         }
153
154         public override void EndDraw()
155         {
156             base.EndDraw();
157             this.Surface.Dispose();
158             this.Bitmap.Dispose();
159             this.SurfaceImageNative.EndDraw();
160         }
161
162         void CreateSurface(Windows.UI.Xaml.Shapes.Rectangle rect, double width, double height)
163         {
164             if (this.SurfaceImageNative != null)
165                 this.SurfaceImageNative.Dispose();
166             this.SurfaceImage = new SurfaceImageSource((int)width, (int)height);
167             this.SurfaceImageNative = ComObject.As<DXGI.ISurfaceImageSourceNative>(this.SurfaceImage);
168             this.SurfaceImageNative.Device = this.DXGIDevice;
169             this.Size.Width = width;
170             this.Size.Height = height;
171             ImageBrush brush = new ImageBrush();
172             brush.ImageSource = this.SurfaceImage;
173             rect.Fill = brush;
174         }
175
176
177         D2D.RenderTarget ConstructRenderHandler(D2D.Factory1 factory, D2D.RenderTargetProperties prop, double width, double height)
178         {
179             this.D2DDevice = new D2D.Device(factory,this.DXGIDevice);
180             this.D2DContext = new D2D.DeviceContext(this.D2DDevice, D2D.DeviceContextOptions.None);
181             return this.D2DContext;
182         }
183
184         void ConstructedResourceHandler()
185         {
186         }
187
188         void DestructRenderHandler()
189         {
190             if (this.D2DDevice != null)
191                 this.D2DDevice.Dispose();
192             if (this.D2DContext != null)
193                 this.D2DContext.Dispose();
194         }
195
196         void ReCreateTargetHandler()
197         {
198         }
199     }
200 }