/*
* 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);
}
}
}