1
// Copyright (c) 2009 Daniel Grunwald
3
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
4
// software and associated documentation files (the "Software"), to deal in the Software
5
// without restriction, including without limitation the rights to use, copy, modify, merge,
6
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
7
// to whom the Software is furnished to do so, subject to the following conditions:
9
// The above copyright notice and this permission notice shall be included in all copies or
10
// substantial portions of the Software.
12
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
13
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
15
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
16
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
17
// DEALINGS IN THE SOFTWARE.
21
using System.Text.RegularExpressions;
23
using System.Windows.Controls;
24
using System.Windows.Media;
25
using System.Windows.Media.Imaging;
27
using ICSharpCode.AvalonEdit.Document;
28
using ICSharpCode.AvalonEdit.Rendering;
30
namespace $rootnamespace$.AvalonEdit.Sample
33
/// This class can be used to embed images inside AvalonEdit like this: <img src="Images/Save.png"/>
35
public class ImageElementGenerator : VisualLineElementGenerator
37
readonly static Regex imageRegex = new Regex(@"<img src=""([\.\/\w\d]+)""/?>",
38
RegexOptions.IgnoreCase);
39
readonly string basePath;
41
public ImageElementGenerator(string basePath)
44
throw new ArgumentNullException("basePath");
45
this.basePath = basePath;
48
Match FindMatch(int startOffset)
50
// fetch the end offset of the VisualLine being generated
51
int endOffset = CurrentContext.VisualLine.LastDocumentLine.EndOffset;
52
TextDocument document = CurrentContext.Document;
53
string relevantText = document.GetText(startOffset, endOffset - startOffset);
54
return imageRegex.Match(relevantText);
58
/// Gets the first offset >= startOffset where the generator wants to construct
60
/// Return -1 to signal no interest.
62
public override int GetFirstInterestedOffset(int startOffset)
64
Match m = FindMatch(startOffset);
65
return m.Success ? (startOffset + m.Index) : -1;
69
/// Constructs an element at the specified offset.
70
/// May return null if no element should be constructed.
72
public override VisualLineElement ConstructElement(int offset)
74
Match m = FindMatch(offset);
75
// check whether there's a match exactly at offset
76
if (m.Success && m.Index == 0) {
77
BitmapImage bitmap = LoadBitmap(m.Groups[1].Value);
79
Image image = new Image();
80
image.Source = bitmap;
81
image.Width = bitmap.PixelWidth;
82
image.Height = bitmap.PixelHeight;
83
// Pass the length of the match to the 'documentLength' parameter
84
// of InlineObjectElement.
85
return new InlineObjectElement(m.Length, image);
91
BitmapImage LoadBitmap(string fileName)
93
// TODO: add some kind of cache to avoid reloading the image whenever the
94
// VisualLine is reconstructed
96
string fullFileName = Path.Combine(basePath, fileName);
97
if (File.Exists(fullFileName)) {
98
BitmapImage bitmap = new BitmapImage(new Uri(fullFileName));
102
} catch (ArgumentException) {
103
// invalid filename syntax
104
} catch (IOException) {