2 * Copyright (C) 2013 FooProject
3 * * 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
4 * the Free Software Foundation; either version 3 of the License, or (at your option) any later version.
6 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
7 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
9 You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.
12 using System.Collections.Generic;
14 using D2D = SharpDX.Direct2D1;
15 using DW = SharpDX.DirectWrite;
17 namespace FooEditEngine
19 sealed class InlineManager
22 DW.TextFormat _Format;
24 MultiSet<char, InlineChar> InlineChars = new MultiSet<char, InlineChar>();
25 MultiSet<double, InlineTab> InlineTabs = null;
26 ColorBrushCollection Brushes;
28 const int DuplicateCount = 2; //1だとDirectWriteが一つにまとめてしまう
30 public InlineManager(DW.Factory factory, DW.TextFormat format, Color4 fore, ColorBrushCollection brushes)
32 this.Factory = factory;
33 this._Format = format;
35 this.Brushes = brushes;
38 public bool ContainsSymbol(char c)
41 return this.InlineTabs != null && this.InlineTabs.Count > 0;
42 return this.InlineChars.ContainsKey(c);
45 public void AddSymbol(char c, char alt)
49 this.InlineTabs = new MultiSet<double, InlineTab>();
53 for (int i = 0; i < DuplicateCount; i++)
55 this.InlineChars.Add(c, new InlineChar(this.Factory, this.Format, this.Brushes, this.Fore, alt));
60 public void RemoveSymbol(char c)
63 this.InlineTabs = null;
65 this.InlineChars.Remove(c);
77 this.Format = this._Format;
81 public DW.TextFormat Format
91 this.TabWidth = this._TabWidth;
97 public double TabWidth
101 return this._TabWidth;
105 this._TabWidth = value;
106 if (this.InlineTabs != null)
107 this.InlineTabs.Clear();
111 public DW.InlineObject Get(MyTextLayout layout, int index, string str)
113 if (str[index] == '\t')
115 if (this.InlineTabs == null)
117 double x = layout.GetColPostionFromIndex(index);
118 if (layout.RightToLeft)
119 x = layout.MaxWidth - x;
121 if (index > 0 && str[index - 1] == '\t')
122 width = this._TabWidth;
124 width = this._TabWidth - x % this._TabWidth;
125 List<InlineTab> collection;
126 if (!this.InlineTabs.TryGet(width, out collection))
128 collection = new List<InlineTab>();
129 for (int i = 0; i < DuplicateCount; i++)
130 collection.Add(new InlineTab(this.Brushes, this.Fore, width, layout.Height));
131 this.InlineTabs.Add(width, collection);
133 return collection[index % DuplicateCount];
138 if (this.InlineChars.ContainsKey(c) == false)
140 return this.InlineChars.Get(c, index % DuplicateCount);
146 if (this.InlineChars != null)
147 this.InlineChars.Clear();
148 if (this.InlineTabs != null)
149 this.InlineTabs.Clear();
152 public void ReGenerate()
154 List<KeyValuePair<char, char>> list = new List<KeyValuePair<char, char>>(this.InlineChars.Count);
155 foreach (KeyValuePair<char, InlineChar> kv in this.InlineChars.EnumrateKeyAndFirstValue())
156 list.Add(new KeyValuePair<char, char>(kv.Key, kv.Value.AlternativeChar));
158 this.InlineChars.Clear();
160 if (this.InlineTabs != null)
161 this.InlineTabs.Clear();
163 foreach (KeyValuePair<char, char> kv in list)
164 for (int i = 0; i < DuplicateCount; i++)
165 this.InlineChars.Add(kv.Key, new InlineChar(this.Factory, this.Format, this.Brushes, this.Fore, kv.Value));
169 sealed class MultiSet<T, J>
170 where J : IDisposable
172 Dictionary<T, List<J>> Collection = new Dictionary<T, List<J>>();
174 public void Add(T key, List<J> collection)
176 if (this.Collection.ContainsKey(key) == false)
177 this.Collection.Add(key, collection);
180 public void Add(T key, J value)
182 if (this.Collection.ContainsKey(key) == false)
183 this.Collection.Add(key, new List<J>());
184 this.Collection[key].Add(value);
191 return this.Collection.Count;
195 public bool ContainsKey(T key)
197 return this.Collection.ContainsKey(key);
200 public bool TryGet(T key, out List<J> value)
202 return this.Collection.TryGetValue(key, out value);
205 public J Get(T key, int index)
207 return this.Collection[key][index];
210 public void Remove(T key)
212 if (this.Collection.ContainsKey(key) == false)
214 foreach (J value in this.Collection[key])
216 this.Collection.Remove(key);
221 foreach (List<J> list in this.Collection.Values)
222 foreach (J value in list)
224 this.Collection.Clear();
227 public IEnumerable<KeyValuePair<T, J>> EnumrateKeyAndFirstValue()
229 foreach (KeyValuePair<T, List<J>> kv in this.Collection)
230 yield return new KeyValuePair<T, J>(kv.Key, kv.Value[0]);