OSDN Git Service

フォルダー名を変更した
[fooeditengine/FooEditEngine.git] / Metro / FooEditEngine / Print / DocumentSource.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 using Windows.Graphics.Printing;\r
13 using System.Runtime.InteropServices;\r
14 using Windows.UI;\r
15 using FooEditEngine.Metro;\r
16 \r
17 namespace FooEditEngine\r
18 {\r
19     /// <summary>\r
20     /// イベントデータ\r
21     /// </summary>\r
22     public sealed class ParseCommandEventArgs\r
23     {\r
24         /// <summary>\r
25         /// 印刷中のページ番号\r
26         /// </summary>\r
27         public int PageNumber;\r
28         /// <summary>\r
29         /// ページ範囲内で許容されている最大の番号\r
30         /// </summary>\r
31         public int MaxPageNumber;\r
32         /// <summary>\r
33         /// 処理前の文字列\r
34         /// </summary>\r
35         public string Original;\r
36         /// <summary>\r
37         /// コンストラクター\r
38         /// </summary>\r
39         /// <param name="nowPage">印刷中のページ番号</param>\r
40         /// <param name="maxPage">印刷すべき最大のページ番号</param>\r
41         /// <param name="org">処理前の文字列</param>\r
42         public ParseCommandEventArgs(int nowPage, int maxPage, string org)\r
43         {\r
44             this.PageNumber = nowPage;\r
45             this.MaxPageNumber = maxPage;\r
46             this.Original = org;\r
47         }\r
48     }\r
49 \r
50     /// <summary>\r
51     /// コマンド処理用デリゲート\r
52     /// </summary>\r
53     /// <param name="sender">送信元のクラス</param>\r
54     /// <param name="e">イベントデータ</param>\r
55     /// <returns>処理後の文字列</returns>\r
56     public delegate string ParseCommandHandler(object sender, ParseCommandEventArgs e);\r
57 \r
58     sealed class PrintableViewFactory\r
59     {\r
60         Color foreground, comment, keyword1, keyword2, literal, url;\r
61         string fontName;\r
62         double fontSize;\r
63         Document document;\r
64         LineBreakMethod lineBreakMethod;\r
65         int lineBreakCharCount, tabCount;\r
66         bool drawLineNumber, urlMark;\r
67         IHilighter hilighter;\r
68         public PrintableViewFactory(FooTextBox textbox)\r
69         {\r
70             this.foreground = textbox.Foreground;\r
71             this.comment = textbox.Comment;\r
72             this.keyword1 = textbox.Keyword1;\r
73             this.keyword2 = textbox.Keyword2;\r
74             this.literal = textbox.Literal;\r
75             this.url = textbox.URL;\r
76             this.fontName = textbox.FontFamily.Source;\r
77             this.fontSize = textbox.FontSize;\r
78             this.tabCount = textbox.TabChars;\r
79             this.document = new Document(textbox.Document);\r
80             this.lineBreakMethod = textbox.LineBreakMethod;\r
81             this.lineBreakCharCount = textbox.LineBreakCharCount;\r
82             this.drawLineNumber = textbox.DrawLineNumber;\r
83             this.urlMark = textbox.MarkURL;\r
84             this.hilighter = textbox.Hilighter;\r
85         }\r
86         public D2DRenderBase CreateRender(PrintPageDescription pagedesc, IPrintDocumentPackageTarget docPackageTarget)\r
87         {\r
88             D2DRenderBase render;\r
89             Size size = new Size(pagedesc.ImageableRect.Width, pagedesc.ImageableRect.Height);\r
90             if (docPackageTarget == null)\r
91                 render = new D2DPrintPreviewRender(this.fontName, this.fontSize, size, Math.Min(pagedesc.DpiX, pagedesc.DpiY));\r
92             else\r
93                 render = new D2DPrintRender(this.fontName, this.fontSize, size, Math.Min(pagedesc.DpiX, pagedesc.DpiY), docPackageTarget);\r
94             render.Foreground = this.foreground;\r
95             render.Comment = this.comment;\r
96             render.Keyword1 = this.keyword1;\r
97             render.Keyword2 = this.keyword2;\r
98             render.Literal = this.literal;\r
99             render.Url = this.url;\r
100             return render;\r
101         }\r
102         public PrintableView CreateView(PrintPageDescription pagedesc, D2DRenderBase render, string header, string footer)\r
103         {\r
104 \r
105             PrintableView view = new PrintableView(this.document, (IPrintableTextRender)render);\r
106             view.TabStops = this.tabCount;\r
107             view.LineBreak = this.lineBreakMethod == LineBreakMethod.None ? LineBreakMethod.PageBound : this.lineBreakMethod;\r
108             view.LineBreakCharCount = this.lineBreakCharCount;\r
109             view.DrawLineNumber = this.drawLineNumber;\r
110             view.Header = header;\r
111             view.Footer = footer;\r
112             view.UrlMark = this.urlMark;\r
113             view.PageBound = new Rectangle(pagedesc.ImageableRect.X, pagedesc.ImageableRect.Y, pagedesc.ImageableRect.Width, pagedesc.ImageableRect.Height);\r
114             view.Hilighter = this.hilighter;\r
115             view.PerfomLayouts();\r
116 \r
117             return view;\r
118         }\r
119     }\r
120 \r
121     sealed class DocumentSource : IPrintDocumentPageSource, IPrintPreviewPageCollection, IPrintDocumentSource\r
122     {\r
123         IPrintPreviewDxgiPackageTarget dxgiPreviewTarget;\r
124         bool paginateCalled = false;\r
125         Size imageRect;\r
126         PrintableViewFactory factory;\r
127         D2DPrintPreviewRender previewRender;\r
128         PrintableView previewView;\r
129 \r
130         public ParseCommandHandler ParseHF;\r
131         public string Header = string.Empty;\r
132         public string Fotter = string.Empty;\r
133 \r
134         public DocumentSource(FooTextBox textbox)\r
135         {\r
136             this.factory = new PrintableViewFactory(textbox);\r
137             this.ParseHF = (s, e) => { return e.Original; };\r
138         }\r
139 \r
140         public void GetPreviewPageCollection(IPrintDocumentPackageTarget docPackageTarget,out IPrintPreviewPageCollection docPageCollection)\r
141         {\r
142             Guid guid = new Guid(PreviewPackageIds.IID_PREVIEWPACKAGETARGET_DXGI);\r
143             IntPtr target;\r
144             docPackageTarget.GetPackageTarget(guid, guid, out target);\r
145             this.dxgiPreviewTarget = (IPrintPreviewDxgiPackageTarget)Marshal.GetObjectForIUnknown(target);\r
146             docPageCollection = (IPrintPreviewPageCollection)this;\r
147         }\r
148 \r
149         public void MakeDocument(object printTaskOptions, IPrintDocumentPackageTarget docPackageTarget)\r
150         {\r
151             PrintTaskOptions options = (PrintTaskOptions)printTaskOptions;\r
152             PrintPageDescription pagedesc = options.GetPageDescription(1);\r
153 \r
154             D2DRenderBase render = this.factory.CreateRender(pagedesc, docPackageTarget);\r
155             PrintableView view = this.factory.CreateView(pagedesc, render, this.Header, this.Fotter);\r
156 \r
157             bool result = false;\r
158             int currentPage = 0;\r
159 \r
160             while (!result)\r
161             {\r
162                 if(!string.IsNullOrEmpty(this.Header))\r
163                     view.Header = this.ParseHF(this, new ParseCommandEventArgs(currentPage, -1, this.Header));\r
164                 if (!string.IsNullOrEmpty(this.Fotter))\r
165                     view.Footer = this.ParseHF(this, new ParseCommandEventArgs(currentPage, -1, this.Fotter));\r
166 \r
167                 render.BeginDraw();\r
168                 view.Draw(view.PageBound);\r
169                 render.EndDraw();\r
170                 result = view.TryPageDown();\r
171                 currentPage++;\r
172             }\r
173 \r
174             render.Dispose();\r
175             view.Dispose();\r
176         }\r
177 \r
178         public void Paginate(uint currentJobPage, object printTaskOptions)\r
179         {\r
180             PrintTaskOptions options = (PrintTaskOptions)printTaskOptions;\r
181             PrintPageDescription pagedesc = options.GetPageDescription(currentJobPage);\r
182 \r
183             this.imageRect = new Size(pagedesc.ImageableRect.Width, pagedesc.ImageableRect.Height);\r
184 \r
185             this.previewRender = (D2DPrintPreviewRender)this.factory.CreateRender(pagedesc, null);\r
186             this.previewView = this.factory.CreateView(pagedesc, this.previewRender, this.Header, this.Fotter);\r
187 \r
188             int maxPage = 1;\r
189             while (!this.previewView.TryPageDown())\r
190                 maxPage++;\r
191 \r
192             this.dxgiPreviewTarget.SetJobPageCount(PageCountType.FinalPageCount, (uint)maxPage);\r
193 \r
194             this.dxgiPreviewTarget.InvalidatePreview();\r
195 \r
196             this.paginateCalled = true;\r
197         }\r
198 \r
199         public void MakePage(uint desiredJobPage, float width, float height)\r
200         {\r
201             if (width <= 0 || height <= 0)\r
202                 throw new COMException("", 0x70057/*E_INVALIDARG*/);\r
203             if (!this.paginateCalled)\r
204                 return;\r
205             if (desiredJobPage == 0xFFFFFFFF)\r
206                 desiredJobPage = 1;\r
207 \r
208             this.previewView.TryScroll(0, 0);   //元に戻さないとページ番号が変わった時に正しく動作しない\r
209 \r
210             for (int i = 1; i < desiredJobPage; i++)\r
211                 this.previewView.TryPageDown();\r
212 \r
213             this.previewRender.BeginDraw();\r
214             this.previewView.Draw(this.previewView.PageBound);\r
215             this.previewRender.EndDraw(this.dxgiPreviewTarget,desiredJobPage);\r
216         }\r
217 \r
218         public void Dispose()\r
219         {\r
220             if (this.previewView != null)\r
221                 this.previewView.Dispose();\r
222             if (this.previewRender != null)\r
223                 this.previewRender.Dispose();\r
224         }\r
225     }\r
226 }\r