OSDN Git Service

改行マークを表示できるようにした
[fooeditengine/FooEditEngine.git] / Windows / FooEditEngine / D2DTextRender.cs
1 /*
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.
5
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.
8
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/>.
10  */
11 using System;
12 using System.Collections.Generic;
13 using System.Linq;
14 using System.Text;
15 using System.Windows;
16 using System.Drawing;
17 using FooEditEngine;
18 using SharpDX;
19 using D2D = SharpDX.Direct2D1;
20 using DW = SharpDX.DirectWrite;
21 using DXGI = SharpDX.DXGI;
22 using System.Runtime.InteropServices;
23
24 namespace FooEditEngine.Windows
25 {
26
27     class D2DTextRender : IEditorRender, IDisposable
28     {
29         D2DRenderCommon common;
30         FooTextBox TextBox;
31         System.Drawing.Color ForegroundColor = SystemColors.ControlText,
32             BackgroundColor = SystemColors.Control,
33             HilightColor = System.Drawing.Color.DeepSkyBlue,
34             Keyword1Color = System.Drawing.Color.Blue,
35             Keyword2Color = System.Drawing.Color.DarkCyan,
36             LiteralColor = System.Drawing.Color.Brown,
37             UrlColor = System.Drawing.Color.Blue,
38             ControlCharColor = System.Drawing.Color.Gray,
39             CommentColor = System.Drawing.Color.Green,
40             InsertCaretColor = System.Drawing.Color.Black,
41             OverwriteCaretColor = System.Drawing.Color.Black,
42             LineMarkerColor = System.Drawing.Color.WhiteSmoke;
43         string fontName;
44         float fontSize;
45
46         public D2DTextRender(FooTextBox textbox)
47         {
48             this.TextBox = textbox;
49
50             textbox.SizeChanged += new EventHandler(textbox_SizeChanged);
51             textbox.FontChanged += new EventHandler(textbox_FontChanged);
52             textbox.HandleCreated += new EventHandler(textbox_HandleCreated);
53             textbox.HandleDestroyed += new EventHandler(textbox_HandleDestroyed);
54
55             Size size = textbox.Size;
56             this.common = new D2DRenderCommon();
57             this.common.ConstructRender = ConstructRenderHandler;
58             this.common.ConstrctedResource = ConstructedResourceHandler;
59             this.common.DestructRender = this.DestructRenderHandler;
60             this.common.GetDpi = this.GetDpiHandler;
61             this.common.ConstructDeviceResource(size.Width, size.Height);
62             this.fontName = textbox.Font.Name;
63             this.fontSize = textbox.Font.Size;
64             this.common.InitTextFormat(textbox.Font.Name, (float)textbox.Font.Size);
65         }
66
67         private void GetDpiHandler(out int dpix, out int dpiy)
68         {
69             IntPtr hDc = NativeMethods.GetDC(IntPtr.Zero);
70             dpix = NativeMethods.GetDeviceCaps(hDc, NativeMethods.LOGPIXELSX);
71             dpiy = NativeMethods.GetDeviceCaps(hDc, NativeMethods.LOGPIXELSY);
72             NativeMethods.ReleaseDC(IntPtr.Zero, hDc);
73         }
74
75         public event EventHandler ChangedRightToLeft;
76
77         void textbox_HandleDestroyed(object sender, EventArgs e)
78         {
79             this.common.DestructDeviceResource();
80         }
81
82         void textbox_HandleCreated(object sender, EventArgs e)
83         {
84             FooTextBox textbox = (FooTextBox)sender;
85             this.TextBox = textbox;
86             this.common.ConstructDeviceResource(textbox.Width, textbox.Height);
87         }
88
89         void textbox_FontChanged(object sender, EventArgs e)
90         {
91             FooTextBox textbox = (FooTextBox)sender;
92             Font font = textbox.Font;
93             this.fontName = font.Name;
94             this.fontSize = font.Size;
95             DW.FontWeight weigth = font.Bold ? DW.FontWeight.Bold : DW.FontWeight.Normal;
96             DW.FontStyle style = font.Italic ? DW.FontStyle.Italic : DW.FontStyle.Normal;
97             this.common.InitTextFormat(font.Name, font.Size,weigth,style);
98         }
99
100         void textbox_SizeChanged(object sender, EventArgs e)
101         {
102             FooTextBox textbox = (FooTextBox)sender;
103             this.common.ReConstructDeviceResource(this.TextBox.Width, this.TextBox.Height);
104         }
105
106         Color4 ToColor4(System.Drawing.Color color)
107         {
108             return new Color4(color.R / 255.0f, color.G / 255.0f, color.B / 255.0f, color.A / 255.0f);
109         }
110
111         public bool RightToLeft
112         {
113             get
114             {
115                 return this.common.RightToLeft;
116             }
117             set
118             {
119                 this.common.RightToLeft = value;
120                 this.ChangedRightToLeft(this, null);
121             }
122         }
123
124         public TextAntialiasMode TextAntialiasMode
125         {
126             get
127             {
128                 return this.common.TextAntialiasMode;
129             }
130             set
131             {
132                 this.common.TextAntialiasMode = value;
133             }
134         }
135
136         public System.Drawing.Color Foreground
137         {
138             get
139             {
140                 return this.ForegroundColor;
141             }
142             set
143             {
144                 this.ForegroundColor = value;
145                 this.common.Foreground = this.ToColor4(value);
146             }
147         }
148
149         public System.Drawing.Color Background
150         {
151             get
152             {
153                 return this.BackgroundColor;
154             }
155             set
156             {
157                 this.BackgroundColor = value;
158                 this.common.Background = this.ToColor4(value);
159             }
160         }
161
162         public System.Drawing.Color InsertCaret
163         {
164             get
165             {
166                 return this.InsertCaretColor;
167             }
168             set
169             {
170                 this.InsertCaretColor = value;
171                 this.common.InsertCaret = this.ToColor4(value);
172             }
173         }
174
175         public System.Drawing.Color OverwriteCaret
176         {
177             get
178             {
179                 return this.OverwriteCaretColor;
180             }
181             set
182             {
183                 this.OverwriteCaretColor = value;
184                 this.common.OverwriteCaret = this.ToColor4(value);
185             }
186         }
187
188         public System.Drawing.Color LineMarker
189         {
190             get
191             {
192                 return this.LineMarkerColor;
193             }
194             set
195             {
196                 this.LineMarkerColor = value;
197                 this.common.LineMarker = this.ToColor4(value);
198             }
199         }
200
201         public System.Drawing.Color ControlChar
202         {
203             get
204             {
205                 return this.ControlCharColor;
206             }
207             set
208             {
209                 this.ControlCharColor = value;
210                 this.common.ControlChar = this.ToColor4(value);
211             }
212         }
213
214         public System.Drawing.Color Url
215         {
216             get
217             {
218                 return this.UrlColor;
219             }
220             set
221             {
222                 this.UrlColor = value;
223                 this.common.Url = this.ToColor4(value);
224             }
225         }
226
227         public System.Drawing.Color Hilight
228         {
229             get
230             {
231                 return this.HilightColor;
232             }
233             set
234             {
235                 this.HilightColor = value;
236                 this.common.Hilight = this.ToColor4(this.HilightColor);
237             }
238         }
239
240         public System.Drawing.Color Comment
241         {
242             get
243             {
244                 return this.CommentColor;
245             }
246             set
247             {
248                 this.CommentColor = value;
249                 this.common.Comment = this.ToColor4(value);
250             }
251         }
252
253         public System.Drawing.Color Literal
254         {
255             get
256             {
257                 return this.LiteralColor;
258             }
259             set
260             {
261                 this.LiteralColor = value;
262                 this.common.Literal = this.ToColor4(value);
263             }
264         }
265
266         public System.Drawing.Color Keyword1
267         {
268             get
269             {
270                 return this.Keyword1Color;
271             }
272             set
273             {
274                 this.Keyword1Color = value;
275                 this.common.Keyword1 = this.ToColor4(value);
276             }
277         }
278
279         public System.Drawing.Color Keyword2
280         {
281             get
282             {
283                 return this.Keyword2Color;
284             }
285             set
286             {
287                 this.Keyword2Color = value;
288                 this.common.Keyword2 = this.ToColor4(value);
289             }
290         }
291
292         public Rectangle TextArea
293         {
294             get { return this.common.ClipRect; }
295             set { this.common.ClipRect = value; }
296         }
297
298         public double LineNemberWidth
299         {
300             get
301             {
302                 return this.common.LineNemberWidth;
303             }
304         }
305
306         public Size emSize
307         {
308             get
309             {
310                 return this.common.emSize;
311             }
312         }
313
314         public int TabWidthChar
315         {
316             get { return this.common.TabWidthChar; }
317             set
318             {
319                 if (value == 0)
320                     return;
321                 this.common.TabWidthChar = value;
322             }
323         }
324
325         public double FoldingWidth
326         {
327             get
328             {
329                 return this.common.FoldingWidth;
330             }
331         }
332
333         public bool ShowFullSpace
334         {
335             get
336             {
337                 return this.common.ShowFullSpace;
338             }
339             set
340             {
341                 this.common.ShowFullSpace = value;
342             }
343         }
344
345         public bool ShowHalfSpace
346         {
347             get
348             {
349                 return this.common.ShowHalfSpace;
350             }
351             set
352             {
353                 this.common.ShowHalfSpace = value;
354             }
355         }
356
357         public bool ShowTab
358         {
359             get
360             {
361                 return this.common.ShowTab;
362             }
363             set
364             {
365                 this.common.ShowTab = value;
366             }
367         }
368
369         public bool ShowLineBreak
370         {
371             get
372             {
373                 return this.common.ShowLineBreak;
374             }
375             set
376             {
377                 this.common.ShowLineBreak = value;
378             }
379         }
380
381         public event ChangedRenderResourceEventHandler ChangedRenderResource
382         {
383             add
384             {
385                 this.common.ChangedRenderResource += value;
386             }
387             remove
388             {
389                 this.common.ChangedRenderResource -= value;
390             }
391         }
392
393         public void DrawLine(Point from, Point to)
394         {
395             this.common.DrawLine(from, to);
396         }
397
398         public void DrawCachedBitmap(Rectangle rect)
399         {
400             this.common.DrawCachedBitmap(rect);
401         }
402
403         public void CacheContent()
404         {
405             this.common.CacheContent();
406         }
407
408         public bool IsVaildCache()
409         {
410             return this.common.IsVaildCache();
411         }
412
413         public void BeginDraw()
414         {
415             this.common.BegineDraw();
416         }
417
418         public void EndDraw()
419         {
420             this.common.EndDraw();
421         }
422
423         public void DrawString(string str, double x, double y, StringAlignment align, Size layoutRect)
424         {
425             this.common.DrawString(str, x, y,align,layoutRect);
426         }
427
428         public void FillRectangle(Rectangle rect, FillRectType type)
429         {
430             this.common.FillRectangle(rect, type);
431         }
432
433         public void DrawFoldingMark(bool expand, double x, double y)
434         {
435             this.common.DrawFoldingMark(expand, x, y);
436         }
437
438         public void FillBackground(Rectangle rect)
439         {
440             this.common.FillBackground(rect);
441         }
442
443         public void DrawOneLine(LineToIndexTable lti, int row, double x, double y, IEnumerable<Selection> SelectRanges)
444         {
445             this.common.DrawOneLine(lti,
446                 row,
447                 x,
448                 y,
449                 SelectRanges,
450                 null);
451         }
452
453         public ITextLayout CreateLaytout(string str, SyntaxInfo[] syntaxCollection, IEnumerable<Marker> MarkerRanges)
454         {
455             return this.common.CreateLaytout(str,syntaxCollection,MarkerRanges);
456         }
457
458         public List<LineToIndexTableData> BreakLine(Document doc, int startIndex, int endIndex, double wrapwidth)
459         {
460             return this.BreakLine(doc, startIndex, endIndex, wrapwidth);
461         }
462
463         public void Dispose()
464         {
465             this.common.Dispose();
466         }
467
468         D2D.WindowRenderTarget WindowRender;
469
470         D2D.RenderTarget ConstructRenderHandler(D2D.Factory factory, D2D.RenderTargetProperties prop, double width, double height)
471         {
472             D2D.HwndRenderTargetProperties hwndProp = new D2D.HwndRenderTargetProperties();
473             hwndProp.Hwnd = this.TextBox.Handle;
474             hwndProp.PixelSize = new SharpDX.Size2(this.TextBox.Size.Width,this.TextBox.Size.Height);
475             hwndProp.PresentOptions = D2D.PresentOptions.Immediately;
476             this.WindowRender = new D2D.WindowRenderTarget(factory,prop,hwndProp);
477             return this.WindowRender;
478         }
479
480         void ConstructedResourceHandler()
481         {
482             this.common.Foreground = this.ToColor4(this.ForegroundColor);
483             this.common.Background = this.ToColor4(this.BackgroundColor);
484             this.common.ControlChar = this.ToColor4(this.ControlCharColor);
485             this.common.Url = this.ToColor4(this.UrlColor);
486             this.common.Keyword1 = this.ToColor4(this.Keyword1Color);
487             this.common.Keyword2 = this.ToColor4(this.Keyword2Color);
488             this.common.Literal = this.ToColor4(this.LiteralColor);
489             this.common.Comment = this.ToColor4(this.CommentColor);
490             this.common.Hilight = this.ToColor4(this.HilightColor);
491             this.common.LineMarker = this.ToColor4(this.LineMarkerColor);
492             this.common.InsertCaret = this.ToColor4(this.InsertCaretColor);
493             this.common.OverwriteCaret = this.ToColor4(this.OverwriteCaretColor);
494         }
495
496         void DestructRenderHandler()
497         {
498             if (this.WindowRender != null)
499                 this.WindowRender.Dispose();
500         }
501     }
502
503     internal static class NativeMethods
504     {
505         public const int LOGPIXELSX = 88;
506         public const int LOGPIXELSY = 90;
507
508         [DllImport("gdi32.dll")]
509         public static extern int GetDeviceCaps(IntPtr hDc, int nIndex);
510
511         [DllImport("user32.dll")]
512         public static extern IntPtr GetDC(IntPtr hWnd);
513
514         [DllImport("user32.dll")]
515         public static extern int ReleaseDC(IntPtr hWnd, IntPtr hDc);
516     }
517 }