OSDN Git Service

スクロール時にキャレットまで動かすとメモリーを食うし、遅くなるのでキャレットを動かさないようにした
[fooeditengine/FooEditEngine.git] / Core / PrintableView.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
13 namespace FooEditEngine
14 {
15     sealed class PrintableView : ViewBase
16     {
17         public PrintableView(Document doc, IPrintableTextRender r, Padding margin)
18             : base (doc,r,margin)
19         {
20         }
21
22         public string Header
23         {
24             get;
25             set;
26         }
27
28         public string Footer
29         {
30             get;
31             set;
32         }
33
34         public override void Draw(Rectangle updateRect, bool force = false)
35         {
36             if (this.LayoutLines.Count == 0)
37                 return;
38
39             if (this.Hilighter != null)
40                 this.Hilighter.Reset();
41
42             Point pos = this.render.TextArea.TopLeft;
43             pos.X = Src.X;
44             pos.Y = 0;
45
46             IPrintableTextRender render = (IPrintableTextRender)this.render;
47
48             //ヘッダーを印刷する
49             if (this.Header != null && this.Header != string.Empty)
50             {
51                 this.render.DrawString(this.Header, pos.X, pos.Y, StringAlignment.Center,
52                     new Size(render.TextArea.Width - this.GetRealtiveX(AreaType.TextArea), render.FooterHeight));
53                 pos.Y += (int)render.HeaderHeight;
54             }
55
56             //レイアウト行を印刷する
57             Rectangle contentArea = new Rectangle(pos.X, pos.Y, this.PageBound.Width, this.render.TextArea.Height);
58             this.render.BeginClipRect(contentArea);
59
60             Size lineNumberSize = new Size(this.render.LineNemberWidth, this.render.TextArea.Height);
61             for (int i = Src.Row; pos.Y <= this.render.TextArea.Bottom; i++)
62             {
63                 if (i >= this.LayoutLines.Count)
64                     break;
65
66                 double layoutHeight = this.LayoutLines.GetLayout(i).Height;
67
68                 this.render.DrawOneLine(this.Document, this.LayoutLines, i, pos.X + this.render.TextArea.X, pos.Y + this.Src.OffsetY);
69                 if (this.Document.DrawLineNumber)
70                     this.render.DrawString((i + 1).ToString(), this.PageBound.X + this.GetRealtiveX(AreaType.LineNumberArea), pos.Y + this.Src.OffsetY, StringAlignment.Right, lineNumberSize);
71
72                 pos.Y += layoutHeight;
73
74             }
75
76             this.render.EndClipRect();
77
78             //フッターを印刷する
79             if (this.Footer != null && this.Footer != string.Empty)
80             {
81                 pos.Y = render.TextArea.Bottom;
82                 this.render.DrawString(this.Footer, pos.X, pos.Y, StringAlignment.Center,
83                     new Size(render.TextArea.Width - this.GetRealtiveX(AreaType.TextArea), render.FooterHeight));
84             }
85
86             return;
87         }
88
89         public bool TryPageDown()
90         {
91             double alignedPage = (int)(this.render.TextArea.Height / this.render.emSize.Height) * this.render.emSize.Height;
92             return base.TryScroll(this.Src.X, alignedPage);
93         }
94
95         protected override void CalculateClipRect()
96         {
97             double x, y, width, height;
98
99             if (this.Document.DrawLineNumber)
100             {
101                 if (this.render.RightToLeft)
102                     x = this.Padding.Left;
103                 else
104                     x = this.render.LineNemberWidth + this.render.emSize.Width + this.Padding.Left + this.LineNumberMargin;
105                 width = this.PageBound.Width - this.render.LineNemberWidth - this.render.emSize.Width - this.Padding.Right - this.Padding.Left - this.LineNumberMargin;
106             }
107             else
108             {
109                 x = this.Padding.Left;
110                 width = this.PageBound.Width  - this.Padding.Right - this.Padding.Left;
111             }
112
113             y = this.Padding.Top;
114             height = this.PageBound.Height - this.Padding.Bottom - this.Padding.Top;
115
116             if (width < 0)
117                 width = 0;
118
119             if (height < 0)
120                 height = 0;
121
122             IPrintableTextRender render = (IPrintableTextRender)this.render;
123
124             if (this.Footer != null && this.Footer != string.Empty)
125                 height -= render.FooterHeight;
126             if (this.Header != null && this.Header != string.Empty)
127                 height -= render.HeaderHeight;
128
129             this.render.TextArea = new Rectangle(x, y, width, height);
130         }
131
132         public override void CalculateLineCountOnScreen()
133         {
134         }
135
136         enum AreaType
137         {
138             LineNumberArea,
139             TextArea
140         }
141
142         double GetRealtiveX(AreaType type)
143         {
144             switch (type)
145             {
146                 case AreaType.LineNumberArea:
147                     if (this.Document.DrawLineNumber == false)
148                         throw new InvalidOperationException();
149                     if (this.render.RightToLeft)
150                         return this.PageBound.TopRight.X - this.render.LineNemberWidth;
151                     else
152                         return this.render.TextArea.X - this.render.LineNemberWidth - this.render.emSize.Width - this.LineNumberMargin;
153                 case AreaType.TextArea:
154                     return this.render.TextArea.X;
155             }
156             throw new ArgumentOutOfRangeException();
157         }
158     }
159 }