OSDN Git Service

行を生成するメソッドをLineToIndexTableに移動した
[fooeditengine/FooEditEngine.git] / Metro / FooEditEngine / 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     sealed class D2DRender : D2DRenderBase,IEditorRender
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             this.ConstructDeviceResource(rect.ActualWidth,rect.ActualHeight);
43             this.InitTextFormat(textbox.FontFamily, textbox.FontSize);
44
45             this.store = store;
46
47             this.Size.Width = rect.ActualWidth;
48             this.Size.Height = rect.ActualHeight;
49
50             this.CreateSurface(rect, rect.ActualWidth, rect.ActualHeight);
51
52             base.PreDrawOneLine = D2DRender_PreDrawOneLine;
53
54             this.Foreground = D2DRenderBase.ToColor4( textbox.Foreground);
55             this.Background = D2DRenderBase.ToColor4(textbox.Background);
56             this.Hilight = D2DRenderBase.ToColor4(textbox.Hilight);
57             this.Keyword1 = D2DRenderBase.ToColor4(textbox.Keyword1);
58             this.Keyword2 = D2DRenderBase.ToColor4(textbox.Keyword2);
59             this.Literal = D2DRenderBase.ToColor4(textbox.Literal);
60             this.Url = D2DRenderBase.ToColor4(textbox.URL);
61             this.ControlChar = D2DRenderBase.ToColor4(textbox.ControlChar);
62             this.Comment = D2DRenderBase.ToColor4(textbox.Comment);
63             this.InsertCaret = D2DRenderBase.ToColor4(textbox.InsertCaret);
64             this.OverwriteCaret = D2DRenderBase.ToColor4(textbox.OverwriteCaret);
65             this.LineMarker = D2DRenderBase.ToColor4(textbox.LineMarker);
66             this.UpdateArea = D2DRenderBase.ToColor4(textbox.UpdateArea);
67             this.LineNumber = D2DRenderBase.ToColor4(textbox.LineNumber);
68         }
69
70         void D2DRender_PreDrawOneLine(MyTextLayout layout,LineToIndexTable lti, int row, double x, double y)
71         {
72             using (Unlocker locker = this.store.LockDocument(false))
73             {
74                 int lineIndex = lti.GetIndexFromLineNumber(row);
75                 int lineLength = lti.GetLengthFromLineNumber(row);
76                 foreach (TextDisplayAttribute attr in this.store.EnumAttributes(lineIndex, lineIndex + lineLength))
77                 {
78                     if (attr.startIndex == attr.endIndex)
79                         continue;
80                     int length = attr.endIndex - attr.startIndex;
81                     int start = attr.startIndex - lineIndex;
82
83                     HilightType type = HilightType.None;
84                     Color4? color = null;
85                     switch (attr.attribute.lsStyle)
86                     {
87                         case TF_DA_LINESTYLE.TF_LS_DOT:
88                             type = HilightType.Dot;
89                             color = this.Foreground;
90                             break;
91                         case TF_DA_LINESTYLE.TF_LS_SOLID:
92                             type = HilightType.Sold;
93                             color = this.Foreground;
94                             break;
95                         case TF_DA_LINESTYLE.TF_LS_DASH:
96                             type = HilightType.Dash;
97                             color = this.Foreground;
98                             break;
99                         case TF_DA_LINESTYLE.TF_LS_SQUIGGLE:
100                             type = HilightType.Squiggle;
101                             color = this.Foreground;
102                             break;
103                     }
104
105                     if (attr.attribute.crBk.type != TF_DA_COLORTYPE.TF_CT_NONE)
106                     {
107                         type = HilightType.Select;
108                         color = this.Hilight;
109                     }
110
111                     this.DrawMarkerEffect(layout, type, start, length, x, y, attr.attribute.fBoldLine, color);
112                 }
113             }
114         }
115
116         public override void GetDpi(out float dpix, out float dpiy)
117         {
118             Util.GetDpi(out dpix, out dpiy);
119         }
120
121         public bool Resize(Windows.UI.Xaml.Shapes.Rectangle rect, double width, double height)
122         {
123             if (this.Size.Width == width && this.Size.Height == height)
124                 return false;
125             this.ReConstructDeviceResource(width, height);
126             this.CreateSurface(rect, width, height);
127             return true;
128         }
129
130         public bool IsCanDraw()
131         {
132             return this.Size.Height != 0 && this.Size.Width != 0;
133         }
134
135         public void DrawContent(EditView view,bool IsEnabled,Rectangle updateRect)
136         {
137             SharpDX.Mathematics.Interop.RawPoint offset;
138             this.Surface = this.SurfaceImageNative.BeginDraw(
139                 new SharpDX.Rectangle(0, 0, (int)this.Size.Width, (int)this.Size.Height), out offset);
140             float dpix, dpiy;
141             this.GetDpi(out dpix, out dpiy);
142             D2D.BitmapProperties1 prop = new D2D.BitmapProperties1(new D2D.PixelFormat(DXGI.Format.B8G8R8A8_UNorm, D2D.AlphaMode.Premultiplied),
143                     dpix, dpiy, D2D.BitmapOptions.Target | D2D.BitmapOptions.CannotDraw);
144             this.Bitmap = new D2D.Bitmap1(this.D2DContext, this.Surface, prop);
145             this.D2DContext.Target = this.Bitmap;
146             this.D2DContext.Transform = Matrix3x2.Translation(offset.X, offset.Y);
147             base.BegineDraw();
148
149             if (IsEnabled)
150                 view.Draw(updateRect);
151             else
152                 this.FillBackground(updateRect);
153
154             base.EndDraw();
155             this.Surface.Dispose();
156             this.Bitmap.Dispose();
157             this.SurfaceImageNative.EndDraw();
158         }
159
160         void CreateSurface(Windows.UI.Xaml.Shapes.Rectangle rect, double width, double height)
161         {
162             if (this.SurfaceImageNative != null)
163                 this.SurfaceImageNative.Dispose();
164             this.SurfaceImage = new SurfaceImageSource((int)width, (int)height);
165             this.SurfaceImageNative = ComObject.As<DXGI.ISurfaceImageSourceNative>(this.SurfaceImage);
166             this.SurfaceImageNative.Device = this.DXGIDevice;
167             this.Size.Width = width;
168             this.Size.Height = height;
169             ImageBrush brush = new ImageBrush();
170             brush.ImageSource = this.SurfaceImage;
171             rect.Fill = brush;
172         }
173
174         protected override D2D.RenderTarget ConstructRender(D2D.Factory1 factory, D2D.RenderTargetProperties prop, double width, double height)
175         {
176             this.D2DDevice = new D2D.Device(factory,this.DXGIDevice);
177             this.D2DContext = new D2D.DeviceContext(this.D2DDevice, D2D.DeviceContextOptions.None);
178             return this.D2DContext;
179         }
180
181         protected override void ConstrctedResource()
182         {
183         }
184
185         protected override void DestructRender()
186         {
187             if (this.D2DDevice != null)
188                 this.D2DDevice.Dispose();
189             if (this.D2DContext != null)
190                 this.D2DContext.Dispose();
191         }
192
193         protected override void ReCreateTarget()
194         {
195         }
196     }
197 }