/*
* 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);
}
}