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.
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.
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/>.
12 using System.Collections.Generic;
13 using Windows.Graphics.Display;
14 using Windows.UI.Xaml.Media;
15 using Windows.UI.Xaml.Media.Imaging;
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;
26 namespace FooEditEngine
28 class D2DRender : D2DRenderBase,IEditorRender
30 SurfaceImageSource SurfaceImage;
31 DXGI.ISurfaceImageSourceNative SurfaceImageNative;
33 D2D.DeviceContext D2DContext;
35 Size Size = new Size();
39 public D2DRender(FooTextBox textbox,Windows.UI.Xaml.Shapes.Rectangle rect,TextStore2 store)
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);
52 this.Size.Width = rect.ActualWidth;
53 this.Size.Height = rect.ActualHeight;
55 this.CreateSurface(rect, rect.ActualWidth, rect.ActualHeight);
57 base.PreDrawOneLine = D2DRender_PreDrawOneLine;
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;
73 void D2DRender_PreDrawOneLine(MyTextLayout layout,LineToIndexTable lti, int row, double x, double y)
75 using (Unlocker locker = this.store.LockDocument(false))
77 int lineIndex = lti.GetIndexFromLineNumber(row);
78 int lineLength = lti.GetLengthFromLineNumber(row);
79 foreach (TextDisplayAttribute attr in this.store.EnumAttributes(lineIndex, lineIndex + lineLength))
81 if (attr.startIndex == attr.endIndex)
83 int length = attr.endIndex - attr.startIndex;
84 int start = attr.startIndex - lineIndex;
86 HilightType type = HilightType.None;
87 Windows.UI.Color? color = null;
88 switch (attr.attribute.lsStyle)
90 case TF_DA_LINESTYLE.TF_LS_DOT:
91 type = HilightType.Dot;
92 color = this.Foreground;
94 case TF_DA_LINESTYLE.TF_LS_SOLID:
95 type = HilightType.Sold;
96 color = this.Foreground;
98 case TF_DA_LINESTYLE.TF_LS_DASH:
99 type = HilightType.Dash;
100 color = this.Foreground;
102 case TF_DA_LINESTYLE.TF_LS_SQUIGGLE:
103 type = HilightType.Squiggle;
104 color = this.Foreground;
108 if (attr.attribute.crBk.type != TF_DA_COLORTYPE.TF_CT_NONE)
110 type = HilightType.Select;
111 color = this.Hilight;
114 this.DrawMarkerEffect(layout, type, start, length, x, y, attr.attribute.fBoldLine, color);
119 void GetDpiHandler(out float dpix, out float dpiy)
121 dpix = (int)DisplayProperties.LogicalDpi;
122 dpiy = (int)DisplayProperties.LogicalDpi;
125 public bool Resize(Windows.UI.Xaml.Shapes.Rectangle rect, double width, double height)
127 if (this.Size.Width == width && this.Size.Height == height)
129 this.ReConstructDeviceResource(width, height);
130 this.CreateSurface(rect, width, height);
134 public bool IsCanDraw()
136 return this.Size.Height != 0 && this.Size.Width != 0;
139 public override void BeginDraw()
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);
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);
154 public override void EndDraw()
157 this.Surface.Dispose();
158 this.Bitmap.Dispose();
159 this.SurfaceImageNative.EndDraw();
162 void CreateSurface(Windows.UI.Xaml.Shapes.Rectangle rect, double width, double height)
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;
177 D2D.RenderTarget ConstructRenderHandler(D2D.Factory1 factory, D2D.RenderTargetProperties prop, double width, double height)
179 this.D2DDevice = new D2D.Device(factory,this.DXGIDevice);
180 this.D2DContext = new D2D.DeviceContext(this.D2DDevice, D2D.DeviceContextOptions.None);
181 return this.D2DContext;
184 void ConstructedResourceHandler()
188 void DestructRenderHandler()
190 if (this.D2DDevice != null)
191 this.D2DDevice.Dispose();
192 if (this.D2DContext != null)
193 this.D2DContext.Dispose();
196 void ReCreateTargetHandler()