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;
16 using System.Windows.Controls;
17 using System.Windows.Media;
18 using System.Windows.Interop;
20 using DotNetTextStore;
21 using DotNetTextStore.UnmanagedAPI.TSF;
22 using DotNetTextStore.UnmanagedAPI.WinDef;
24 using D2D = SharpDX.Direct2D1;
25 using DW = SharpDX.DirectWrite;
26 using D3D10 = SharpDX.Direct3D10;
27 using D3D9 = SharpDX.Direct3D9;
28 using DXGI = SharpDX.DXGI;
30 namespace FooEditEngine.WPF
32 sealed class D2DRender : D2DRenderCommon, IEditorRender
34 DotNetTextStore.TextStore store;
35 D3D10.Texture2D texture;
39 D3D9.Surface surface9;
40 D2D.RenderTarget render;
42 FontFamily fontFamily;
43 FontWeight fontWeigth;
47 public D2DRender(FooTextBox textbox, double width, double height,Image image)
49 this.fontFamily = textbox.FontFamily;
50 this.fontSize = textbox.FontSize;
51 this.fontWeigth = textbox.FontWeight;
52 this.fontStyle = textbox.FontStyle;
53 this.Foreground = ToColor4(textbox.Foreground);
54 this.Background = ToColor4(textbox.Background);
55 this.ControlChar = ToColor4(textbox.ControlChar);
56 this.Hilight = ToColor4(textbox.Hilight);
57 this.Comment = ToColor4(textbox.Comment);
58 this.Url = ToColor4(textbox.URL);
59 this.Keyword1 = ToColor4(textbox.Keyword1);
60 this.Keyword2 = ToColor4(textbox.Keyword2);
61 this.Literal = ToColor4(textbox.Literal);
62 this.InsertCaret = ToColor4(textbox.InsertCaret);
63 this.OverwriteCaret = ToColor4(textbox.OverwriteCaret);
64 this.LineMarker = ToColor4(textbox.LineMarker);
65 this.UpdateArea = ToColor4(textbox.UpdateArea);
66 this.LineNumber = ToColor4(textbox.LineNumber);
67 this.store = textbox.TextStore;
71 this.ConstructDeviceResource(width, height);
72 this.InitTextFormat(this.fontFamily.Source, (float)this.fontSize, this.GetDWFontWeigth(this.fontWeigth), this.GetDWFontStyle(this.fontStyle));
74 this.imageSource = new D3DImage();
75 this.imageSource.Lock();
76 this.imageSource.SetBackBuffer(D3DResourceType.IDirect3DSurface9, this.surface9.NativePointer); //設定しないとロード時に例外が発生する
77 this.imageSource.Unlock();
79 image.Source = this.imageSource;
82 public FontFamily FontFamily
84 get { return this.fontFamily; }
87 this.fontFamily = value;
88 this.InitTextFormat(this.fontFamily.Source, (float)this.fontSize, this.GetDWFontWeigth(this.fontWeigth), this.GetDWFontStyle(this.fontStyle));
89 this.TabWidthChar = this.TabWidthChar;
93 public double FontSize
95 get { return this.fontSize; }
98 this.fontSize = value;
99 this.InitTextFormat(this.fontFamily.Source, (float)value, this.GetDWFontWeigth(this.fontWeigth), this.GetDWFontStyle(this.fontStyle));
100 this.TabWidthChar = this.TabWidthChar;
104 public FontWeight FontWeigth
108 return this.fontWeigth;
112 this.fontWeigth = value;
113 this.InitTextFormat(this.fontFamily.Source, (float)this.fontSize, this.GetDWFontWeigth(value),this.GetDWFontStyle(this.fontStyle));
117 public FontStyle FontStyle
121 return this.fontStyle;
125 this.fontStyle = value;
126 this.InitTextFormat(this.fontFamily.Source, (float)this.fontSize, this.GetDWFontWeigth(this.fontWeigth), this.GetDWFontStyle(this.fontStyle));
130 public static Color4 ToColor4(System.Windows.Media.Color color)
132 return new Color4(color.R / 255.0f, color.G / 255.0f, color.B / 255.0f, color.A / 255.0f);
135 public bool Resize(double width, double height)
137 if (Math.Floor(width) != Math.Floor(this.imageSource.Width) || Math.Floor(height) != Math.Floor(this.imageSource.Height))
139 this.ReConstructDeviceResource(width, height);
140 this.imageSource.Lock();
141 this.imageSource.SetBackBuffer(D3DResourceType.IDirect3DSurface9, this.surface9.NativePointer);
142 this.imageSource.Unlock();
148 public override void BegineDraw()
153 public override void EndDraw()
158 if (this.imageSource.IsFrontBufferAvailable)
160 this.imageSource.Lock();
161 this.imageSource.SetBackBuffer(D3DResourceType.IDirect3DSurface9, this.surface9.NativePointer);
162 this.imageSource.AddDirtyRect(new Int32Rect(0, 0, (int)this.imageSource.Width, (int)this.imageSource.Height));
163 this.imageSource.Unlock();
167 public void DrawOneLine(LineToIndexTable lti, int row, double x, double y, IEnumerable<Selection> SelectRanges)
169 PreDrawOneLineHandler PreDrawOneLine = (layout) => {
170 using (Unlocker locker = this.store.LockDocument(false))
172 int lineIndex = lti.GetIndexFromLineNumber(row);
173 int lineLength = lti.GetLengthFromLineNumber(row);
174 foreach (TextDisplayAttribute attr in this.store.EnumAttributes(lineIndex,lineIndex + lineLength))
176 if (attr.startIndex == attr.endIndex)
178 int length = attr.endIndex - attr.startIndex;
179 int start = attr.startIndex - lineIndex;
181 HilightType type = HilightType.None;
182 Color4? color = null;
183 switch (attr.attribute.lsStyle)
185 case TF_DA_LINESTYLE.TF_LS_DOT:
186 type = HilightType.Dot;
187 color = this.GetColor4(attr.attribute.crLine);
189 case TF_DA_LINESTYLE.TF_LS_SOLID:
190 type = HilightType.Sold;
191 color = this.GetColor4(attr.attribute.crLine);
193 case TF_DA_LINESTYLE.TF_LS_DASH:
194 type = HilightType.Dash;
195 color = this.GetColor4(attr.attribute.crLine);
197 case TF_DA_LINESTYLE.TF_LS_SQUIGGLE:
198 type = HilightType.Squiggle;
199 color = this.GetColor4(attr.attribute.crLine);
203 if (attr.attribute.crBk.type != TF_DA_COLORTYPE.TF_CT_NONE)
205 type = HilightType.Select;
206 color = this.GetColor4(attr.attribute.crBk);
209 this.DrawMarkerEffect(layout, type, start, length,x,y,attr.attribute.fBoldLine,color);
211 color = this.GetColor4(attr.attribute.crText);
214 this.SetTextColor(layout, start, length, color);
215 layout.Invaild = true;
220 base.DrawOneLine(lti,
228 private Color4? GetColor4(TF_DA_COLOR cr)
233 case TF_DA_COLORTYPE.TF_CT_SYSCOLOR:
234 colorref = new COLORREF(NativeMethods.GetSysColor((int)cr.indexOrColorRef));
236 case TF_DA_COLORTYPE.TF_CT_COLORREF:
237 colorref = new COLORREF(cr.indexOrColorRef);
242 return new Color4(colorref.R / 255.0f, colorref.G / 255.0f, colorref.B / 255.0f, 1);
245 public override void Dispose()
248 this.DestructDevice();
251 DW.FontStyle GetDWFontStyle(FontStyle style)
253 return (DW.FontStyle)Enum.Parse(typeof(DW.FontStyle), style.ToString());
256 DW.FontWeight GetDWFontWeigth(FontWeight weigth)
258 return (DW.FontWeight)Enum.Parse(typeof(DW.FontWeight), weigth.ToString());
261 public override void DrawCachedBitmap(Rectangle rect)
263 if (this.render == null || this.render.IsDisposed)
265 render.DrawBitmap(this.cachedBitMap, rect, 1.0f, D2D.BitmapInterpolationMode.Linear, rect);
268 public override void CacheContent()
270 if (this.render == null || this.cachedBitMap == null || this.cachedBitMap.IsDisposed || this.render.IsDisposed)
273 this.cachedBitMap.CopyFromRenderTarget(this.render, new SharpDX.Point(), new SharpDX.Rectangle(0, 0, (int)this.renderSize.Width, (int)this.renderSize.Height));
274 this.hasCache = true;
279 D3D10.FeatureLevel[] levels = new D3D10.FeatureLevel[]{D3D10.FeatureLevel.Level_10_1,
280 D3D10.FeatureLevel.Level_10_0,
281 D3D10.FeatureLevel.Level_9_3,
282 D3D10.FeatureLevel.Level_9_2,
283 D3D10.FeatureLevel.Level_9_1};
284 foreach (D3D10.FeatureLevel level in levels)
288 this.device = new D3D10.Device1(D3D10.DriverType.Hardware, D3D10.DeviceCreationFlags.BgraSupport,level);
296 if (this.device == null)
297 throw new PlatformNotSupportedException("DirectX10デバイスの作成に失敗しました");
299 IntPtr DesktopWnd = NativeMethods.GetDesktopWindow();
300 D3D9.Direct3DEx d3dex = new D3D9.Direct3DEx();
302 D3D9.PresentParameters param = new D3D9.PresentParameters();
303 param.Windowed = true;
304 param.SwapEffect = D3D9.SwapEffect.Discard;
305 param.DeviceWindowHandle = DesktopWnd;
306 param.PresentationInterval = D3D9.PresentInterval.Default;
310 this.device9 = new D3D9.DeviceEx(
313 D3D9.DeviceType.Hardware,
315 D3D9.CreateFlags.HardwareVertexProcessing | D3D9.CreateFlags.Multithreaded | D3D9.CreateFlags.FpuPreserve,
322 this.device9 = new D3D9.DeviceEx(
325 D3D9.DeviceType.Hardware,
327 D3D9.CreateFlags.SoftwareVertexProcessing | D3D9.CreateFlags.Multithreaded | D3D9.CreateFlags.FpuPreserve,
332 throw new PlatformNotSupportedException("DirectX9デバイスの作成に失敗しました");
341 void DestructDevice()
343 if (this.device != null)
345 this.device.Dispose();
348 if (this.device9 != null)
350 this.device9.Dispose();
355 protected override void ReCreateTarget()
357 System.Diagnostics.Debug.WriteLine("ReCreatedDevice");
358 this.DestructDevice();
360 this.ReConstructDeviceResource();
363 protected override D2D.RenderTarget ConstructRender(D2D.Factory factory, D2D.RenderTargetProperties prop, double width, double height)
365 D3D10.Texture2DDescription desc = new D3D10.Texture2DDescription();
366 desc.Width = (int)width;
367 desc.Height = (int)height;
370 desc.Format = DXGI.Format.B8G8R8A8_UNorm;
371 desc.SampleDescription = new DXGI.SampleDescription(1, 0);
372 desc.Usage = D3D10.ResourceUsage.Default;
373 desc.BindFlags = D3D10.BindFlags.RenderTarget | D3D10.BindFlags.ShaderResource;
374 desc.CpuAccessFlags = D3D10.CpuAccessFlags.None;
375 desc.OptionFlags = D3D10.ResourceOptionFlags.Shared;
376 this.texture = new D3D10.Texture2D(this.device, desc);
378 this.surface = this.texture.QueryInterface<DXGI.Surface>();
380 DXGI.Resource resource = this.texture.QueryInterface<DXGI.Resource>();
381 IntPtr handel = resource.SharedHandle;
382 D3D9.Texture texture = new D3D9.Texture(
384 this.texture.Description.Width,
385 this.texture.Description.Height,
387 D3D9.Usage.RenderTarget,
388 D3D9.Format.A8R8G8B8,
391 this.surface9 = texture.GetSurfaceLevel(0);
395 this.render = new D2D.RenderTarget(factory, this.surface, prop);
399 protected override void ConstrctedResource()
403 public double GetScale()
406 this.GetDpi(out dpi, out dpi);
410 public override void GetDpi(out float dpix, out float dpiy)
412 IntPtr hDc = NativeMethods.GetDC(IntPtr.Zero);
413 dpix = NativeMethods.GetDeviceCaps(hDc, NativeMethods.LOGPIXELSX);
414 dpiy = NativeMethods.GetDeviceCaps(hDc, NativeMethods.LOGPIXELSY);
415 NativeMethods.ReleaseDC(IntPtr.Zero, hDc);
418 protected override void DestructRender()
420 if (this.texture != null)
421 this.texture.Dispose();
422 if (this.surface != null)
423 this.surface.Dispose();
424 if (this.surface9 != null)
425 this.surface9.Dispose();
426 if (this.render != null)
427 this.render.Dispose();