/* * 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; namespace FooEditEngine { sealed class PrintableView : ViewBase { public PrintableView(Document doc, IPrintableTextRender r) : base (doc,r) { } public string Header { get; set; } public string Footer { get; set; } public override void Draw(Rectangle updateRect) { if (this.LayoutLines.Count == 0) return; if (this.Hilighter != null) this.Hilighter.Reset(); Point pos = base.PageBound.Location; pos.X -= Src.X; int endRow = Math.Min(this.LayoutLines.Count - 1, Src.Row + this.LineCountOnScreen - 1); Size lineNumberSize = new Size(this.render.LineNemberWidth, this.render.TextArea.Height); IPrintableTextRender render = (IPrintableTextRender)this.render; //ヘッダーを印刷する if (this.Header != null && this.Header != string.Empty) { this.render.DrawString(this.Header, pos.X, pos.Y, StringAlignment.Center,this.PageBound.Size); pos.Y += (int)render.HeaderHeight; } //レイアウト行を印刷する for (int i = Src.Row; i <= endRow; i++) { double lineHeight = this.LayoutLines.GetLayout(i).Height; this.render.DrawOneLine(this.LayoutLines,i, pos.X + this.render.TextArea.X, pos.Y, null); if (this.DrawLineNumber) this.render.DrawString(i.ToString(), this.PageBound.X + this.GetRealtiveX(AreaType.LineNumberArea), pos.Y, StringAlignment.Right, lineNumberSize); pos.Y += lineHeight; } //フッターを印刷する if (this.Footer != null && this.Footer != string.Empty) { this.render.DrawString(this.Footer, pos.X, pos.Y, StringAlignment.Center, this.PageBound.Size); pos.Y += (int)render.FooterHeight; } } public bool TryPageDown() { return base.TryScroll(this.Src.X, this.Src.Row + this.LineCountOnScreen); } protected override void CalculateClipRect() { double x, y, width, height; if (this.DrawLineNumber) { if (this.render.RightToLeft) x = 0; else x = this.render.LineNemberWidth + this.render.emSize.Width; y = 0; width = this.PageBound.Width - this.render.LineNemberWidth - this.render.emSize.Width; height = this.PageBound.Height; } else { if (this.render.RightToLeft) x = 0; else x = 0; y = 0; width = this.PageBound.Width; height = this.PageBound.Height; } if (width < 0) width = 0; if (height < 0) height = 0; this.render.TextArea = new Rectangle(x, y, width, height); } public override void CalculateLineCountOnScreen() { if (this.LayoutLines.Count == 0) return; double y = 0; int i = this.Src.Row; for (; true; i++) { int row = i < this.LayoutLines.Count ? i : this.LayoutLines.Count - 1; ITextLayout layout = this.LayoutLines.GetLayout(row); double lineHeight = layout.Height; y += lineHeight; if (y >= this.PageBound.Height) break; } this.LineCountOnScreen = Math.Max(i - this.Src.Row - 1, 0); if (this.Footer != null && this.Footer != string.Empty) this.LineCountOnScreen--; if (this.Header != null && this.Header != string.Empty) this.LineCountOnScreen--; } enum AreaType { LineNumberArea, TextArea } double GetRealtiveX(AreaType type) { switch (type) { case AreaType.LineNumberArea: if (this.DrawLineNumber == false) throw new InvalidOperationException(); if (this.render.RightToLeft) return this.PageBound.TopRight.X - this.render.LineNemberWidth; else return this.render.TextArea.X - this.render.LineNemberWidth - this.render.emSize.Width; case AreaType.TextArea: return this.render.TextArea.X; } throw new ArgumentOutOfRangeException(); } } }