/* * 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.Collections.Generic; namespace FooEditEngine { /// /// 点を表す構造体 /// public struct Point { /// /// X座標 /// public double X; /// /// Y座標 /// public double Y; /// /// コンストラクター /// /// X座標 /// Y座標 public Point(double x, double y) { this.X = x; this.Y = y; } /// /// 比較演算子を実装します /// /// 比較される方 /// 比較対象 /// 条件を満たすなら真 public static bool operator ==(Point a, Point b) { return a.Equals(b); } /// /// 比較演算子を実装します /// /// 比較される方 /// 比較対象 /// 条件を満たすなら真 public static bool operator !=(Point a, Point b) { return !a.Equals(b); } /// /// 一致するかどうか /// /// 比較対象 /// 一致するなら真 public override bool Equals(object o) { Point b = (Point)o; return this.X == b.X && this.Y == b.Y; } /// /// ハッシュを返す /// /// ハッシュを返す public override int GetHashCode() { int result = this.X.GetHashCode(); result ^= this.Y.GetHashCode(); return result; } /// /// 一定の倍率で拡大する /// /// 倍率 /// public Point Scale(double scale) { this.X *= scale; this.Y *= scale; return this; } /// /// 一定方向に移動する /// /// 移動量X /// 移動量Y /// public Point Offset(double x_offset, double y_offset) { this.X += x_offset; this.Y += y_offset; return this; } #if WINFORM public static implicit operator Point(System.Drawing.Point p) { return new Point(p.X, p.Y); } public static implicit operator System.Drawing.Point(Point p) { return new System.Drawing.Point((int)p.X, (int)p.Y); } public static implicit operator SharpDX.Mathematics.Interop.RawVector2(Point p) { return new SharpDX.Mathematics.Interop.RawVector2((float)p.X, (float)p.Y); } #endif #if WPF public static implicit operator Point(System.Windows.Point p) { return new Point(p.X, p.Y); } public static implicit operator System.Windows.Point(Point p) { return new System.Windows.Point(p.X, p.Y); } public static implicit operator SharpDX.Mathematics.Interop.RawVector2(Point p) { return new SharpDX.Mathematics.Interop.RawVector2((float)p.X, (float)p.Y); } #endif #if METRO || WINDOWS_UWP public static implicit operator Point(Windows.Foundation.Point p) { return new Point(p.X, p.Y); } public static implicit operator Windows.Foundation.Point(Point p) { return new Windows.Foundation.Point(p.X, p.Y); } public static implicit operator SharpDX.Mathematics.Interop.RawVector2(Point p) { return new SharpDX.Mathematics.Interop.RawVector2((float)p.X, (float)p.Y); } #endif } struct Size { public double Width; public double Height; public Size(double width, double height) { this.Width = width; this.Height = height; } /// /// 比較演算子を実装します /// /// 比較される方 /// 比較対象 /// 条件を満たすなら真 public static bool operator ==(Size a, Size b) { return a.Equals(b); } /// /// 比較演算子を実装します /// /// 比較される方 /// 比較対象 /// 条件を満たすなら真 public static bool operator !=(Size a, Size b) { return !a.Equals(b); } /// /// 一致するかどうか /// /// 比較対象 /// 一致するなら真 public override bool Equals(object o) { Size b = (Size)o; return this.Width == b.Width && this.Height == b.Height; } /// /// ハッシュを返す /// /// ハッシュを返す public override int GetHashCode() { int result = this.Height.GetHashCode(); result ^= this.Width.GetHashCode(); return result; } #if WINFORM public static implicit operator Size(System.Drawing.Size p) { return new Size(p.Width, p.Height); } public static implicit operator System.Drawing.Size(Size p) { return new System.Drawing.Size((int)p.Width, (int)p.Height); } #endif #if WPF public static implicit operator Size(System.Windows.Size p) { return new Size(p.Width, p.Height); } public static implicit operator System.Windows.Size(Size p) { return new System.Windows.Size(p.Width, p.Height); } #endif #if METRO || WINDOWS_UWP public static implicit operator Size(Windows.Foundation.Size p) { return new Size(p.Width, p.Height); } public static implicit operator Windows.Foundation.Size(Size p) { return new Windows.Foundation.Size(p.Width, p.Height); } #endif } struct Rectangle { public Point Location; public Size Size; public Point TopLeft { get { return this.Location; } } public Point TopRight { get { return new Point(this.Right, this.Location.Y); } } public Point BottomLeft { get { return new Point(this.Location.X, this.Bottom); } } public Point BottomRight { get { return new Point(this.Right, this.Bottom); } } public double Right { get { return this.X + this.Width; } } public double Bottom { get { return this.Y + this.Height; } } public double Height { get { return this.Size.Height; } set { this.Size.Height = value; } } public double Width { get { return this.Size.Width; } set { this.Size.Width = value; } } public double X { get { return this.Location.X; } } public double Y { get { return this.Location.Y; } } public Rectangle(double x, double y, double width, double height) { this.Location = new Point(x, y); this.Size = new Size(width, height); } public Rectangle(Point leftTop, Point bottomRight) { this.Location = leftTop; this.Size = new Size(bottomRight.X - leftTop.X, bottomRight.Y - leftTop.Y); } /// /// どの領域も指さないことを表す /// public static Rectangle Empty = new Rectangle(0, 0, 0, 0); /// /// 任意の点が領域内にあるなら真を返す /// /// /// public bool IsHit(Point p) { if (p.X >= this.TopLeft.X && p.Y >= this.TopLeft.Y && p.X <= this.BottomRight.X && p.Y <= this.BottomRight.Y) return true; return false; } /// /// 比較演算子を実装します /// /// 比較される方 /// 比較対象 /// 条件を満たすなら真 public static bool operator ==(Rectangle a, Rectangle b) { return a.Equals(b); } /// /// 比較演算子を実装します /// /// 比較される方 /// 比較対象 /// 条件を満たすなら真 public static bool operator !=(Rectangle a, Rectangle b) { return !a.Equals(b); } /// /// 一致するかどうか /// /// 比較対象 /// 一致するなら真 public override bool Equals(object o) { Rectangle b = (Rectangle)o; return this.Location.Equals(b.Location) && this.Size.Equals(b.Size); } /// /// ハッシュを返す /// /// ハッシュを返す public override int GetHashCode() { int result = this.Location.GetHashCode(); result ^= this.Size.GetHashCode(); return result; } #if WINFORM public static implicit operator Rectangle(System.Drawing.Rectangle p) { return new Rectangle(p.X,p.Y,p.Width,p.Height); } public static implicit operator System.Drawing.Rectangle(Rectangle p) { return new System.Drawing.Rectangle((int)p.X, (int)p.Y, (int)p.Width, (int)p.Height); } public static implicit operator SharpDX.Mathematics.Interop.RawRectangleF(Rectangle p) { return new SharpDX.Mathematics.Interop.RawRectangleF((float)p.X, (float)p.Y, (float)p.BottomRight.X, (float)p.BottomRight.Y); } #endif #if WPF public static implicit operator Rectangle(System.Windows.Rect p) { return new Rectangle(p.X,p.Y,p.Width,p.Height); } public static implicit operator System.Windows.Rect(Rectangle p) { return new System.Windows.Rect(p.X, p.Y, p.Width, p.Height); } public static implicit operator SharpDX.Mathematics.Interop.RawRectangleF(Rectangle p) { return new SharpDX.Mathematics.Interop.RawRectangleF((float)p.X, (float)p.Y, (float)p.BottomRight.X, (float)p.BottomRight.Y); } #endif #if METRO || WINDOWS_UWP public static implicit operator Rectangle(Windows.Foundation.Rect p) { return new Rectangle(p.X, p.Y, p.Width, p.Height); } public static implicit operator Windows.Foundation.Rect(Rectangle p) { return new Windows.Foundation.Rect(p.X, p.Y, p.Width, p.Height); } public static implicit operator SharpDX.Mathematics.Interop.RawRectangleF(Rectangle p) { return new SharpDX.Mathematics.Interop.RawRectangleF((float)p.X, (float)p.Y, (float)p.BottomRight.X, (float)p.BottomRight.Y); } #endif } /// /// 色構造体 /// public struct Color: IEqualityComparer { /// /// アルファ成分 /// public byte A; /// /// 赤成分 /// public byte R; /// /// 緑成分 /// public byte G; /// /// 青成分 /// public byte B; /// /// コンストラクター /// /// A成分 /// R成分 /// G成分 /// B成分 public Color(byte a = 255, byte r = 0, byte g = 0, byte b = 0) { this.A = a; this.R = r; this.B = b; this.G = g; } /// /// 等しいかどうかを調べます /// /// 比較される方 /// 比較する方 /// 等しいなら真。そうでなければ偽 public bool Equals(Color x, Color y) { return x.A == y.A && x.R == y.R && x.G == y.G && x.B == y.B; } /// /// ハッシュを得ます /// /// Colorオブジェクト /// ハッシュ public int GetHashCode(Color obj) { return this.A ^ this.R ^ this.B ^ this.G; } /// /// 一致するかどうか /// /// 比較対象 /// 一致するなら真 public override bool Equals(object o) { Color b = (Color)o; return this.Equals(this,b); } /// /// ハッシュを返す /// /// ハッシュを返す public override int GetHashCode() { return this.GetHashCode(this); } } enum AlignDirection { Forward, Back, } enum ResourceType { Font, Brush, Antialias, InlineChar, } enum FillRectType { OverwriteCaret, InsertCaret, InsertPoint, LineMarker, UpdateArea, } enum StringColorType { Forground, LineNumber, } class ChangedRenderRsourceEventArgs : EventArgs { public ResourceType type; public ChangedRenderRsourceEventArgs(ResourceType type) { this.type = type; } } delegate void ChangedRenderResourceEventHandler(object sender, ChangedRenderRsourceEventArgs e); interface ITextRender { /// /// 右から左に表示するなら真 /// bool RightToLeft { get; set; } /// /// ドキュメントを表示する領域 /// Rectangle TextArea { get; set; } /// /// 行番号の幅 /// double LineNemberWidth { get; } /// /// タブの文字数 /// int TabWidthChar { get; set; } /// /// 全角スペースを表示するかどうか /// bool ShowFullSpace { get; set; } /// /// 半角スペースを表示するかどうか /// bool ShowHalfSpace { get; set; } /// /// TABを表示するかどうか /// bool ShowTab { get; set; } /// /// 改行を表示するかどうか /// bool ShowLineBreak { get; set; } /// /// 1文字当たりの高さと幅 /// Size emSize { get; } /// /// 保持しているリソースに変化があったことを通知する /// event ChangedRenderResourceEventHandler ChangedRenderResource; /// /// RightToLeftの値が変わったことを通知する /// event EventHandler ChangedRightToLeft; /// /// 文字列を表示する /// /// 文字列 /// x座標 /// y座標 /// 書式方向 /// レイアウト領域 /// 色 void DrawString(string str, double x, double y, StringAlignment align, Size layoutRect,StringColorType colorType = StringColorType.Forground); /// /// 行を表示する /// /// LineToIndexオブジェクト /// 行 /// 行の左上を表すX座標 /// 行の左上を表すY座標 /// 選択領域を保持しているコレクション。選択領域の開始位置は行の先頭を0とする相対位置としてください(位置が-1の場合表示されません) void DrawOneLine(LineToIndexTable lti, int row, double x, double y, IEnumerable SelectRanges); /// /// 行を折り返す /// /// ドキュメント /// レイアウトライン /// 開始インデックス /// 終了インデックス /// 折り返しの幅 /// 行のリスト List BreakLine(Document doc,LineToIndexTable layoutLineCollection, int startIndex, int endIndex, double wrapwidth); /// /// レイアウトを生成する /// /// 文字列 /// ITextLayoutオブジェクト /// ハイライト関連の情報を保持しているコレクション /// マーカーを保持しているコレクション。マーカーの開始位置は行の先頭を0とする相対位置としてください(位置が-1の場合表示しないこと) ITextLayout CreateLaytout(string str, SyntaxInfo[] syntaxCollection, IEnumerable MarkerRanges); /// /// グリッパーを描く /// /// 中心点 /// 半径 void DrawGripper(Point p, double radius); /// /// クリッピングを開始します /// /// クリッピングする範囲 void BeginClipRect(Rectangle rect); /// /// クリッピングを終了します /// void EndClipRect(); } interface IEditorRender : ITextRender { /// /// フォールティングエリアの幅 /// double FoldingWidth { get; } /// /// キャッシュされたビットマップを描写する /// /// 描く領域 void DrawCachedBitmap(Rectangle rect); /// /// 線を描く /// /// 開始座標 /// 修了座標 void DrawLine(Point from, Point to); /// /// 描写したものをキャッシュする /// void CacheContent(); /// /// キャッシュが存在するなら真を返し、そうでないなら偽を返す /// bool IsVaildCache(); /// /// 四角形を描く /// /// /// void FillRectangle(Rectangle rect,FillRectType type); /// /// ツリーに使用するマークを描く /// /// 展開済みなら真 /// x座標 /// y座標 void DrawFoldingMark(bool expand, double x, double y); /// /// 背景を塗りつぶす /// /// 塗りつぶすべき領域 void FillBackground(Rectangle rect); } enum StringAlignment { Left, Center, Right, } interface IPrintableTextRender : ITextRender { /// /// ヘッダーの高さ /// float HeaderHeight { get; } /// /// フッターの高さ /// float FooterHeight { get; } } }