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