/* * Copyright (C) 2013 FooProject * * 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 * the Free Software Foundation; either version 3 of the License, or (at your option) any later version. * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ using System; using System.Threading.Tasks; using System.Printing; using System.Windows; using System.Windows.Xps; using Shapes = System.Windows.Shapes; using System.Collections.Generic; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Documents.Serialization; using System.Windows.Media; namespace FooEditEngine.WPF { /// /// イベントデータ /// public sealed class ParseCommandEventArgs { /// /// 印刷中のページ番号 /// public int PageNumber; /// /// ページ範囲内で許容されている最大の番号 /// public int MaxPageNumber; /// /// 処理前の文字列 /// public string Original; /// /// コンストラクター /// /// 印刷中のページ番号 /// 印刷すべき最大のページ番号 /// 処理前の文字列 public ParseCommandEventArgs(int nowPage,int maxPage,string org) { this.PageNumber = nowPage; this.MaxPageNumber = maxPage; this.Original = org; } } /// /// コマンド処理用デリゲート /// /// 送信元のクラス /// イベントデータ /// 処理後の文字列 public delegate string ParseCommandHandler(object sender,ParseCommandEventArgs e); /// /// 印刷用のクラス /// public class FooPrintText { /// /// コンストラクター /// public FooPrintText() { this.ParseHF = new ParseCommandHandler((s, e) => { return e.Original; }); } /// /// 印刷する最小のページ番号 /// public int StartPage { get; set; } /// /// 印刷する最大のページ番号 /// public int EndPage { get; set; } /// /// 印刷する領域の大きさ /// public System.Windows.Rect PageRect { get; set; } /// /// 対象となるドキュメント /// public Document Document { get; set; } /// /// レタリング時のフロー方向を示す /// public FlowDirection FlowDirection { get; set; } /// /// 行番号を表示するかどうか /// public bool DrawLineNumber { get; set; } /// /// ハイパーリンクに下線を引くなら真 /// public bool MarkURL { get; set; } /// /// デフォルトの文字ブラシ /// public System.Windows.Media.Color Foreground { get; set; } /// /// URLを表すブラシ /// public System.Windows.Media.Color URL { get; set; } /// /// キーワード1を表すブラシ /// public System.Windows.Media.Color Keyword1 { get; set; } /// /// キーワード2を表すブラシ /// public System.Windows.Media.Color Keyword2 { get; set; } /// /// コメントを表すブラシ /// public System.Windows.Media.Color Comment { get; set; } /// /// 文字リテラルを表すブラシ /// public System.Windows.Media.Color Litral { get; set; } /// /// 印刷に使用するフォント /// public FontFamily Font { get; set; } /// /// フォントサイズ /// public double FontSize { get; set; } /// /// 折り返しの方法を指定する /// public LineBreakMethod LineBreakMethod { get; set; } /// /// 折り返した時の文字数を指定する /// public int LineBreakCharCount { get; set; } /// /// ヘッダー /// public string Header { get; set; } /// /// フッター /// public string Footer { get; set; } /// /// シンタックスハイライター /// public IHilighter Hilighter { get; set; } /// /// 余白 /// public Padding Padding { get; set; } /// /// ヘッダーやフッターを処理する /// public ParseCommandHandler ParseHF; /// /// 印刷する /// /// プリントダイアログ public void Print(PrintDialog pd) { if (this.Font == null || this.Document == null) throw new InvalidOperationException(); WPFRender render = new WPFRender(this.Font, this.FontSize); render.Foreground = this.Foreground; render.Comment = this.Comment; render.Keyword1 = this.Keyword1; render.Keyword2 = this.Keyword2; render.Literal = this.Litral; render.Url = this.URL; render.RightToLeft = this.FlowDirection == System.Windows.FlowDirection.RightToLeft; render.Printing = true; Document documentSnap = new Document(this.Document); documentSnap.LayoutLines.Render = render; PrintableView view = new PrintableView(documentSnap, render,this.Padding); view.Header = this.Header; view.Footer = this.Footer; view.PageBound = this.PageRect; view.Hilighter = this.Hilighter; documentSnap.LineBreak = this.LineBreakMethod; documentSnap.LineBreakCharCount = this.LineBreakCharCount; documentSnap.DrawLineNumber = this.DrawLineNumber; documentSnap.UrlMark = this.MarkURL; view.PerfomLayouts(); try { FixedDocument fd = new FixedDocument(); fd.DocumentPaginator.PageSize = this.PageRect.Size; int currentPage = 0; bool result = false; while (!result) { if (this.EndPage != -1 && currentPage > this.EndPage) break; if (this.StartPage == -1 || currentPage >= this.StartPage) { PageContent pc = new PageContent(); FixedPage fp = new FixedPage(); fp.Width = this.PageRect.Width; fp.Height = this.PageRect.Height; pc.Child = fp; view.Header = this.ParseHF(this, new ParseCommandEventArgs(currentPage, this.EndPage, this.Header)); view.Footer = this.ParseHF(this, new ParseCommandEventArgs(currentPage, this.EndPage, this.Footer)); DrawingVisual dv = new DrawingVisual(); using (DrawingContext dc = dv.RenderOpen()) { render.SetDrawingContext(dc); view.Draw(view.PageBound); } VisualHost host = new VisualHost(); host.AddVisual(dv); fp.Children.Add(host); fd.Pages.Add(pc); } result = view.TryPageDown(); currentPage++; } pd.PrintDocument(fd.DocumentPaginator,""); } catch (PrintingCanceledException) { } finally { view.Dispose(); } } } class VisualHost : FrameworkElement { private List fVisuals; public VisualHost() { fVisuals = new List(); } protected override Visual GetVisualChild(int index) { return fVisuals[index]; } protected override int VisualChildrenCount { get { return fVisuals.Count; } } public void AddVisual(Visual visual) { fVisuals.Add(visual); base.AddVisualChild(visual); } public void RemoveVisual(Visual visual) { fVisuals.Remove(visual); base.RemoveVisualChild(visual); } } }