/* * 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, Padding margin) : base (doc,r,margin) { } public string Header { get; set; } public string Footer { get; set; } public override void Draw(Rectangle updateRect, bool force = false) { if (this.LayoutLines.Count == 0) return; if (this.Hilighter != null) this.Hilighter.Reset(); Point pos = this.render.TextArea.TopLeft; 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, new Size(render.TextArea.Width - this.GetRealtiveX(AreaType.TextArea),render.FooterHeight)); 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.Document.DrawLineNumber) this.render.DrawString((i + 1).ToString(), this.PageBound.X + this.GetRealtiveX(AreaType.LineNumberArea), pos.Y, StringAlignment.Right, lineNumberSize); pos.Y += lineHeight; } //フッターを印刷する if (this.Footer != null && this.Footer != string.Empty) { pos.Y = render.TextArea.Bottom; this.render.DrawString(this.Footer, pos.X, pos.Y, StringAlignment.Center, new Size(render.TextArea.Width - this.GetRealtiveX(AreaType.TextArea), render.FooterHeight)); } return; } 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.Document.DrawLineNumber) { if (this.render.RightToLeft) x = this.Padding.Left; else x = this.render.LineNemberWidth + this.render.emSize.Width + this.Padding.Left + this.LineNumberMargin; width = this.PageBound.Width - this.render.LineNemberWidth - this.render.emSize.Width - this.Padding.Right - this.Padding.Left - this.LineNumberMargin; } else { x = this.Padding.Left; width = this.PageBound.Width - this.Padding.Right - this.Padding.Left; } y = this.Padding.Top; height = this.PageBound.Height - this.Padding.Bottom - this.Padding.Top; if (width < 0) width = 0; if (height < 0) height = 0; IPrintableTextRender render = (IPrintableTextRender)this.render; if (this.Footer != null && this.Footer != string.Empty) height -= render.FooterHeight; if (this.Header != null && this.Header != string.Empty) height -= render.HeaderHeight; 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.render.TextArea.Height) break; } this.LineCountOnScreen = Math.Max(i - this.Src.Row - 1, 0); //ループを抜けると+1されている } enum AreaType { LineNumberArea, TextArea } double GetRealtiveX(AreaType type) { switch (type) { case AreaType.LineNumberArea: if (this.Document.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 - this.LineNumberMargin; case AreaType.TextArea: return this.render.TextArea.X; } throw new ArgumentOutOfRangeException(); } } }