OSDN Git Service

rtlモードで行番号の位置がおかしかった
[fooeditengine/FooEditEngine.git] / Common / PrintableView.cs
1 /*\r
2  * Copyright (C) 2013 FooProject\r
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\r
4  * the Free Software Foundation; either version 3 of the License, or (at your option) any later version.\r
5 \r
6  * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of \r
7  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.\r
8 \r
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/>.\r
10  */\r
11 using System;\r
12 \r
13 namespace FooEditEngine\r
14 {\r
15     sealed class PrintableView : ViewBase\r
16     {\r
17         public PrintableView(Document doc, IPrintableTextRender r, Padding margin)\r
18             : base (doc,r,margin)\r
19         {\r
20         }\r
21 \r
22         public string Header\r
23         {\r
24             get;\r
25             set;\r
26         }\r
27 \r
28         public string Footer\r
29         {\r
30             get;\r
31             set;\r
32         }\r
33 \r
34         public override void Draw(Rectangle updateRect)\r
35         {\r
36             if (this.LayoutLines.Count == 0)\r
37                 return;\r
38 \r
39             if (this.Hilighter != null)\r
40                 this.Hilighter.Reset();\r
41 \r
42             Point pos = this.render.TextArea.TopLeft;\r
43             pos.X -= Src.X;\r
44 \r
45             int endRow = Math.Min(this.LayoutLines.Count - 1, Src.Row + this.LineCountOnScreen - 1);\r
46 \r
47             Size lineNumberSize = new Size(this.render.LineNemberWidth, this.render.TextArea.Height);\r
48 \r
49             IPrintableTextRender render = (IPrintableTextRender)this.render;\r
50 \r
51             //ヘッダーを印刷する\r
52             if (this.Header != null && this.Header != string.Empty)\r
53             {\r
54                 this.render.DrawString(this.Header, pos.X, pos.Y, StringAlignment.Center,\r
55                     new Size(render.TextArea.Width - this.GetRealtiveX(AreaType.TextArea),render.FooterHeight));\r
56 \r
57                 pos.Y += (int)render.HeaderHeight;\r
58             }\r
59 \r
60             //レイアウト行を印刷する\r
61             for (int i = Src.Row; i <= endRow; i++)\r
62             {\r
63                 double lineHeight = this.LayoutLines.GetLayout(i).Height;\r
64 \r
65                 this.render.DrawOneLine(this.LayoutLines,i, pos.X + this.render.TextArea.X, pos.Y, null);\r
66 \r
67                 if (this.DrawLineNumber)\r
68                     this.render.DrawString((i + 1).ToString(), this.PageBound.X + this.GetRealtiveX(AreaType.LineNumberArea), pos.Y, StringAlignment.Right, lineNumberSize);\r
69 \r
70                 pos.Y += lineHeight;\r
71             }\r
72 \r
73             //フッターを印刷する\r
74             if (this.Footer != null && this.Footer != string.Empty)\r
75             {\r
76                 pos.Y = render.TextArea.Bottom;\r
77                 this.render.DrawString(this.Footer, pos.X, pos.Y, StringAlignment.Center,\r
78                     new Size(render.TextArea.Width - this.GetRealtiveX(AreaType.TextArea), render.FooterHeight));\r
79             }\r
80         }\r
81 \r
82         public bool TryPageDown()\r
83         {\r
84             return base.TryScroll(this.Src.X, this.Src.Row + this.LineCountOnScreen);\r
85         }\r
86 \r
87         protected override void CalculateClipRect()\r
88         {\r
89             double x, y, width, height;\r
90 \r
91             if (this.DrawLineNumber)\r
92             {\r
93                 if (this.render.RightToLeft)\r
94                     x = this.Padding.Left;\r
95                 else\r
96                     x = this.render.LineNemberWidth + this.render.emSize.Width + this.Padding.Left + this.LineNumberMargin;\r
97                 width = this.PageBound.Width - this.render.LineNemberWidth - this.render.emSize.Width - this.Padding.Right - this.Padding.Left - this.LineNumberMargin;\r
98             }\r
99             else\r
100             {\r
101                 x = this.Padding.Left;\r
102                 width = this.PageBound.Width  - this.Padding.Right - this.Padding.Left;\r
103             }\r
104 \r
105             y = this.Padding.Top;\r
106             height = this.PageBound.Height - this.Padding.Bottom - this.Padding.Top;\r
107 \r
108             if (width < 0)\r
109                 width = 0;\r
110 \r
111             if (height < 0)\r
112                 height = 0;\r
113 \r
114             IPrintableTextRender render = (IPrintableTextRender)this.render;\r
115 \r
116             if (this.Footer != null && this.Footer != string.Empty)\r
117                 height -= render.FooterHeight;\r
118             if (this.Header != null && this.Header != string.Empty)\r
119                 height -= render.HeaderHeight;\r
120 \r
121             this.render.TextArea = new Rectangle(x, y, width, height);\r
122         }\r
123 \r
124         public override void CalculateLineCountOnScreen()\r
125         {\r
126             if (this.LayoutLines.Count == 0)\r
127                 return;\r
128 \r
129             double y = 0;\r
130             int i = this.Src.Row;\r
131             for (; true; i++)\r
132             {\r
133                 int row = i < this.LayoutLines.Count ? i : this.LayoutLines.Count - 1;\r
134 \r
135                 ITextLayout layout = this.LayoutLines.GetLayout(row);\r
136 \r
137                 double lineHeight = layout.Height;\r
138 \r
139                 y += lineHeight;\r
140 \r
141                 if (y >= this.render.TextArea.Height)\r
142                     break;\r
143             }\r
144             this.LineCountOnScreen = Math.Max(i - this.Src.Row - 1, 0); //ループを抜けると+1されている\r
145         }\r
146 \r
147         enum AreaType\r
148         {\r
149             LineNumberArea,\r
150             TextArea\r
151         }\r
152 \r
153         double GetRealtiveX(AreaType type)\r
154         {\r
155             switch (type)\r
156             {\r
157                 case AreaType.LineNumberArea:\r
158                     if (this.DrawLineNumber == false)\r
159                         throw new InvalidOperationException();\r
160                     if (this.render.RightToLeft)\r
161                         return this.PageBound.TopRight.X - this.render.LineNemberWidth;\r
162                     else\r
163                         return this.render.TextArea.X - this.render.LineNemberWidth - this.render.emSize.Width - this.LineNumberMargin;\r
164                 case AreaType.TextArea:\r
165                     return this.render.TextArea.X;\r
166             }\r
167             throw new ArgumentOutOfRangeException();\r
168         }\r
169     }\r
170 }\r