/* * Copyright (C) 2013 FooProject * * 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 * the Free Software Foundation; either version 3 of the License, or (at your option) any later version. * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ using System; using System.Collections.Generic; using Windows.Graphics.Display; using Windows.UI.Xaml.Media; using Windows.UI.Xaml.Media.Imaging; using SharpDX; using DXGI = SharpDX.DXGI; using D2D = SharpDX.Direct2D1; using D3D = SharpDX.Direct3D; using D3D11 = SharpDX.Direct3D11; using FooEditEngine.Metro; using DotNetTextStore; using DotNetTextStore.UnmanagedAPI.TSF; using DotNetTextStore.UnmanagedAPI.WinDef; namespace FooEditEngine { sealed class D2DRender : D2DRenderBase,IEditorRender { SurfaceImageSource SurfaceImage; DXGI.ISurfaceImageSourceNative SurfaceImageNative; D2D.Device D2DDevice; D2D.DeviceContext D2DContext; D2D.Bitmap1 Bitmap; Size Size = new Size(); DXGI.Surface Surface; TextStore2 store; public D2DRender(FooTextBox textbox,Windows.UI.Xaml.Shapes.Rectangle rect,TextStore2 store) : base() { this.ConstructDeviceResource(rect.ActualWidth,rect.ActualHeight); this.InitTextFormat(textbox.FontFamily, textbox.FontSize); this.store = store; this.Size.Width = rect.ActualWidth; this.Size.Height = rect.ActualHeight; this.CreateSurface(rect, rect.ActualWidth, rect.ActualHeight); base.PreDrawOneLine = D2DRender_PreDrawOneLine; this.Foreground = D2DRenderBase.ToColor4( textbox.Foreground); this.Background = D2DRenderBase.ToColor4(textbox.Background); this.Hilight = D2DRenderBase.ToColor4(textbox.Hilight); this.Keyword1 = D2DRenderBase.ToColor4(textbox.Keyword1); this.Keyword2 = D2DRenderBase.ToColor4(textbox.Keyword2); this.Literal = D2DRenderBase.ToColor4(textbox.Literal); this.Url = D2DRenderBase.ToColor4(textbox.URL); this.ControlChar = D2DRenderBase.ToColor4(textbox.ControlChar); this.Comment = D2DRenderBase.ToColor4(textbox.Comment); this.InsertCaret = D2DRenderBase.ToColor4(textbox.InsertCaret); this.OverwriteCaret = D2DRenderBase.ToColor4(textbox.OverwriteCaret); this.LineMarker = D2DRenderBase.ToColor4(textbox.LineMarker); this.UpdateArea = D2DRenderBase.ToColor4(textbox.UpdateArea); this.LineNumber = D2DRenderBase.ToColor4(textbox.LineNumber); } void D2DRender_PreDrawOneLine(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)) { 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.Foreground; break; case TF_DA_LINESTYLE.TF_LS_SOLID: type = HilightType.Sold; color = this.Foreground; break; case TF_DA_LINESTYLE.TF_LS_DASH: type = HilightType.Dash; color = this.Foreground; break; case TF_DA_LINESTYLE.TF_LS_SQUIGGLE: type = HilightType.Squiggle; color = this.Foreground; break; } if (attr.attribute.crBk.type != TF_DA_COLORTYPE.TF_CT_NONE) { type = HilightType.Select; color = this.Hilight; } this.DrawMarkerEffect(layout, type, start, length, x, y, attr.attribute.fBoldLine, color); } } } public override void GetDpi(out float dpix, out float dpiy) { Util.GetDpi(out dpix, out dpiy); } public bool Resize(Windows.UI.Xaml.Shapes.Rectangle rect, double width, double height) { if (this.Size.Width == width && this.Size.Height == height) return false; this.ReConstructDeviceResource(width, height); this.CreateSurface(rect, width, height); return true; } public bool IsCanDraw() { return this.Size.Height != 0 && this.Size.Width != 0; } public void DrawContent(EditView view,bool IsEnabled,Rectangle updateRect) { SharpDX.Mathematics.Interop.RawPoint offset; this.Surface = this.SurfaceImageNative.BeginDraw( new SharpDX.Rectangle(0, 0, (int)this.Size.Width, (int)this.Size.Height), out offset); float dpix, dpiy; this.GetDpi(out dpix, out dpiy); D2D.BitmapProperties1 prop = new D2D.BitmapProperties1(new D2D.PixelFormat(DXGI.Format.B8G8R8A8_UNorm, D2D.AlphaMode.Premultiplied), dpix, dpiy, D2D.BitmapOptions.Target | D2D.BitmapOptions.CannotDraw); this.Bitmap = new D2D.Bitmap1(this.D2DContext, this.Surface, prop); this.D2DContext.Target = this.Bitmap; this.D2DContext.Transform = Matrix3x2.Translation(offset.X, offset.Y); base.BegineDraw(); if (IsEnabled) view.Draw(updateRect); else this.FillBackground(updateRect); base.EndDraw(); this.Surface.Dispose(); this.Bitmap.Dispose(); this.SurfaceImageNative.EndDraw(); } void CreateSurface(Windows.UI.Xaml.Shapes.Rectangle rect, double width, double height) { if (this.SurfaceImageNative != null) this.SurfaceImageNative.Dispose(); this.SurfaceImage = new SurfaceImageSource((int)width, (int)height); this.SurfaceImageNative = ComObject.As(this.SurfaceImage); this.SurfaceImageNative.Device = this.DXGIDevice; this.Size.Width = width; this.Size.Height = height; ImageBrush brush = new ImageBrush(); brush.ImageSource = this.SurfaceImage; rect.Fill = brush; } protected override D2D.RenderTarget ConstructRender(D2D.Factory1 factory, D2D.RenderTargetProperties prop, double width, double height) { this.D2DDevice = new D2D.Device(factory,this.DXGIDevice); this.D2DContext = new D2D.DeviceContext(this.D2DDevice, D2D.DeviceContextOptions.None); return this.D2DContext; } protected override void ConstrctedResource() { } protected override void DestructRender() { if (this.D2DDevice != null) this.D2DDevice.Dispose(); if (this.D2DContext != null) this.D2DContext.Dispose(); } protected override void ReCreateTarget() { } } }