/* * 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 System.Linq; using System.Text; using System.Windows; using System.Drawing; using FooEditEngine; using SharpDX; using D2D = SharpDX.Direct2D1; using DW = SharpDX.DirectWrite; using DXGI = SharpDX.DXGI; using System.Runtime.InteropServices; namespace FooEditEngine.Windows { class D2DTextRender : IEditorRender, IDisposable { D2DRenderCommon common; FooTextBox TextBox; System.Drawing.Color ForegroundColor = SystemColors.ControlText, BackgroundColor = SystemColors.Control, HilightColor = System.Drawing.Color.DeepSkyBlue, Keyword1Color = System.Drawing.Color.Blue, Keyword2Color = System.Drawing.Color.DarkCyan, LiteralColor = System.Drawing.Color.Brown, UrlColor = System.Drawing.Color.Blue, ControlCharColor = System.Drawing.Color.Gray, CommentColor = System.Drawing.Color.Green, InsertCaretColor = System.Drawing.Color.Black, OverwriteCaretColor = System.Drawing.Color.Black, LineMarkerColor = System.Drawing.Color.WhiteSmoke, UpdateAreaColor = System.Drawing.Color.MediumSeaGreen; string fontName; float fontSize; public D2DTextRender(FooTextBox textbox) { this.TextBox = textbox; textbox.SizeChanged += new EventHandler(textbox_SizeChanged); textbox.FontChanged += new EventHandler(textbox_FontChanged); textbox.HandleCreated += new EventHandler(textbox_HandleCreated); textbox.HandleDestroyed += new EventHandler(textbox_HandleDestroyed); Size size = textbox.Size; this.common = new D2DRenderCommon(); this.common.ConstructRender = ConstructRenderHandler; this.common.ConstrctedResource = ConstructedResourceHandler; this.common.DestructRender = this.DestructRenderHandler; this.common.GetDpi = this.GetDpiHandler; this.common.ConstructDeviceResource(size.Width, size.Height); this.fontName = textbox.Font.Name; this.fontSize = textbox.Font.Size; this.common.InitTextFormat(textbox.Font.Name, (float)textbox.Font.Size); } public void GetDpiHandler(out float dpix, out float dpiy) { IntPtr hDc = NativeMethods.GetDC(IntPtr.Zero); dpix = NativeMethods.GetDeviceCaps(hDc, NativeMethods.LOGPIXELSX); dpiy = NativeMethods.GetDeviceCaps(hDc, NativeMethods.LOGPIXELSY); NativeMethods.ReleaseDC(IntPtr.Zero, hDc); } public event EventHandler ChangedRightToLeft; void textbox_HandleDestroyed(object sender, EventArgs e) { this.common.DestructDeviceResource(); } void textbox_HandleCreated(object sender, EventArgs e) { FooTextBox textbox = (FooTextBox)sender; this.TextBox = textbox; this.common.ConstructDeviceResource(textbox.Width, textbox.Height); } void textbox_FontChanged(object sender, EventArgs e) { FooTextBox textbox = (FooTextBox)sender; Font font = textbox.Font; this.fontName = font.Name; this.fontSize = font.Size; DW.FontWeight weigth = font.Bold ? DW.FontWeight.Bold : DW.FontWeight.Normal; DW.FontStyle style = font.Italic ? DW.FontStyle.Italic : DW.FontStyle.Normal; this.common.InitTextFormat(font.Name, font.Size,weigth,style); } void textbox_SizeChanged(object sender, EventArgs e) { FooTextBox textbox = (FooTextBox)sender; this.common.ReConstructDeviceResource(this.TextBox.Width, this.TextBox.Height); } Color4 ToColor4(System.Drawing.Color color) { return new Color4(color.R / 255.0f, color.G / 255.0f, color.B / 255.0f, color.A / 255.0f); } public bool RightToLeft { get { return this.common.RightToLeft; } set { this.common.RightToLeft = value; this.ChangedRightToLeft(this, null); } } public TextAntialiasMode TextAntialiasMode { get { return this.common.TextAntialiasMode; } set { this.common.TextAntialiasMode = value; } } public System.Drawing.Color Foreground { get { return this.ForegroundColor; } set { this.ForegroundColor = value; this.common.Foreground = this.ToColor4(value); } } public System.Drawing.Color UpdateArea { get { return this.UpdateArea; } set { this.UpdateArea = value; this.common.UpdateArea = this.ToColor4(value); } } public System.Drawing.Color Background { get { return this.BackgroundColor; } set { this.BackgroundColor = value; this.common.Background = this.ToColor4(value); } } public System.Drawing.Color InsertCaret { get { return this.InsertCaretColor; } set { this.InsertCaretColor = value; this.common.InsertCaret = this.ToColor4(value); } } public System.Drawing.Color OverwriteCaret { get { return this.OverwriteCaretColor; } set { this.OverwriteCaretColor = value; this.common.OverwriteCaret = this.ToColor4(value); } } public System.Drawing.Color LineMarker { get { return this.LineMarkerColor; } set { this.LineMarkerColor = value; this.common.LineMarker = this.ToColor4(value); } } public System.Drawing.Color ControlChar { get { return this.ControlCharColor; } set { this.ControlCharColor = value; this.common.ControlChar = this.ToColor4(value); } } public System.Drawing.Color Url { get { return this.UrlColor; } set { this.UrlColor = value; this.common.Url = this.ToColor4(value); } } public System.Drawing.Color Hilight { get { return this.HilightColor; } set { this.HilightColor = value; this.common.Hilight = this.ToColor4(this.HilightColor); } } public System.Drawing.Color Comment { get { return this.CommentColor; } set { this.CommentColor = value; this.common.Comment = this.ToColor4(value); } } public System.Drawing.Color Literal { get { return this.LiteralColor; } set { this.LiteralColor = value; this.common.Literal = this.ToColor4(value); } } public System.Drawing.Color Keyword1 { get { return this.Keyword1Color; } set { this.Keyword1Color = value; this.common.Keyword1 = this.ToColor4(value); } } public System.Drawing.Color Keyword2 { get { return this.Keyword2Color; } set { this.Keyword2Color = value; this.common.Keyword2 = this.ToColor4(value); } } public Rectangle TextArea { get { return this.common.ClipRect; } set { this.common.ClipRect = value; } } public double LineNemberWidth { get { return this.common.LineNemberWidth; } } public Size emSize { get { return this.common.emSize; } } public int TabWidthChar { get { return this.common.TabWidthChar; } set { if (value == 0) return; this.common.TabWidthChar = value; } } public double FoldingWidth { get { return this.common.FoldingWidth; } } public bool ShowFullSpace { get { return this.common.ShowFullSpace; } set { this.common.ShowFullSpace = value; } } public bool ShowHalfSpace { get { return this.common.ShowHalfSpace; } set { this.common.ShowHalfSpace = value; } } public bool ShowTab { get { return this.common.ShowTab; } set { this.common.ShowTab = value; } } public bool ShowLineBreak { get { return this.common.ShowLineBreak; } set { this.common.ShowLineBreak = value; } } public event ChangedRenderResourceEventHandler ChangedRenderResource { add { this.common.ChangedRenderResource += value; } remove { this.common.ChangedRenderResource -= value; } } public void DrawLine(Point from, Point to) { this.common.DrawLine(from, to); } public void DrawCachedBitmap(Rectangle rect) { this.common.DrawCachedBitmap(rect); } public void CacheContent() { this.common.CacheContent(); } public bool IsVaildCache() { return this.common.IsVaildCache(); } public void BeginDraw() { this.common.BegineDraw(); } public void EndDraw() { this.common.EndDraw(); } public void DrawString(string str, double x, double y, StringAlignment align, Size layoutRect) { this.common.DrawString(str, x, y,align,layoutRect); } public void FillRectangle(Rectangle rect, FillRectType type) { this.common.FillRectangle(rect, type); } public void DrawFoldingMark(bool expand, double x, double y) { this.common.DrawFoldingMark(expand, x, y); } public void FillBackground(Rectangle rect) { this.common.FillBackground(rect); } public void DrawOneLine(LineToIndexTable lti, int row, double x, double y, IEnumerable SelectRanges) { this.common.DrawOneLine(lti, row, x, y, SelectRanges, null); } public ITextLayout CreateLaytout(string str, SyntaxInfo[] syntaxCollection, IEnumerable MarkerRanges) { return this.common.CreateLaytout(str,syntaxCollection,MarkerRanges); } public List BreakLine(Document doc, LineToIndexTable layoutLineCollection, int startIndex, int endIndex, double wrapwidth) { return this.common.BreakLine(doc,layoutLineCollection, startIndex, endIndex, wrapwidth); } public void Dispose() { this.common.Dispose(); } D2D.WindowRenderTarget WindowRender; D2D.RenderTarget ConstructRenderHandler(D2D.Factory factory, D2D.RenderTargetProperties prop, double width, double height) { D2D.HwndRenderTargetProperties hwndProp = new D2D.HwndRenderTargetProperties(); hwndProp.Hwnd = this.TextBox.Handle; hwndProp.PixelSize = new SharpDX.Size2(this.TextBox.Size.Width,this.TextBox.Size.Height); hwndProp.PresentOptions = D2D.PresentOptions.Immediately; this.WindowRender = new D2D.WindowRenderTarget(factory,prop,hwndProp); return this.WindowRender; } void ConstructedResourceHandler() { this.common.Foreground = this.ToColor4(this.ForegroundColor); this.common.Background = this.ToColor4(this.BackgroundColor); this.common.ControlChar = this.ToColor4(this.ControlCharColor); this.common.Url = this.ToColor4(this.UrlColor); this.common.Keyword1 = this.ToColor4(this.Keyword1Color); this.common.Keyword2 = this.ToColor4(this.Keyword2Color); this.common.Literal = this.ToColor4(this.LiteralColor); this.common.Comment = this.ToColor4(this.CommentColor); this.common.Hilight = this.ToColor4(this.HilightColor); this.common.LineMarker = this.ToColor4(this.LineMarkerColor); this.common.InsertCaret = this.ToColor4(this.InsertCaretColor); this.common.OverwriteCaret = this.ToColor4(this.OverwriteCaretColor); this.common.UpdateArea = this.ToColor4(this.UpdateAreaColor); } void DestructRenderHandler() { if (this.WindowRender != null) this.WindowRender.Dispose(); } } internal static class NativeMethods { public const int LOGPIXELSX = 88; public const int LOGPIXELSY = 90; [DllImport("gdi32.dll")] public static extern int GetDeviceCaps(IntPtr hDc, int nIndex); [DllImport("user32.dll")] public static extern IntPtr GetDC(IntPtr hWnd); [DllImport("user32.dll")] public static extern int ReleaseDC(IntPtr hWnd, IntPtr hDc); } }