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/>.
13 using D2D = SharpDX.Direct2D1;
14 using DW = SharpDX.DirectWrite;
16 namespace FooEditEngine
18 sealed class CustomTextRenderer : CallbackBase, DW.TextRenderer
20 D2D.RenderTarget render;
21 ColorBrushCollection brushes;
22 StrokeCollection strokes;
24 public CustomTextRenderer(D2D.RenderTarget render, ColorBrushCollection brushes,StrokeCollection strokes,Color4 defalut)
27 this.DefaultFore = defalut;
28 this.brushes = brushes;
29 this.strokes = strokes;
32 public Color4 DefaultFore
38 #region TextRenderer Members
40 public Result DrawGlyphRun(object clientDrawingContext, float baselineOriginX, float baselineOriginY, D2D.MeasuringMode measuringMode, DW.GlyphRun glyphRun, DW.GlyphRunDescription glyphRunDescription, ComObject clientDrawingEffect)
42 D2D.SolidColorBrush foreBrush = this.brushes.Get(this.DefaultFore);
43 bool isDrawGlyphRun = true;
44 if (clientDrawingEffect != null)
46 var drawingForeBrush = clientDrawingEffect as D2D.SolidColorBrush;
47 var selectedEffect = clientDrawingEffect as SelectedEffect;
48 var drawingEffect = clientDrawingEffect as DrawingEffect;
50 if (drawingForeBrush != null)
52 foreBrush = drawingForeBrush;
54 else if(selectedEffect != null)
56 foreBrush = this.brushes.Get(selectedEffect.Fore);
58 else if (drawingEffect != null)
60 if (drawingEffect.Stroke == HilightType.Url)
61 foreBrush = this.brushes.Get(drawingEffect.Fore);
66 render.DrawGlyphRun(new Vector2(baselineOriginX, baselineOriginY),
71 return SharpDX.Result.Ok;
74 RectangleF GetGlyphBound(DW.GlyphRun myGlyphRun, float baselineOriginX, float baselineOriginY,bool underline = false)
76 RectangleF bounds = new RectangleF();
78 DW.FontMetrics fontMetrics = myGlyphRun.FontFace.Metrics;
80 float ascentPixel = myGlyphRun.FontSize * fontMetrics.Ascent / fontMetrics.DesignUnitsPerEm;
81 float dscentPixel = underline ?
82 myGlyphRun.FontSize * (fontMetrics.Descent + fontMetrics.LineGap + fontMetrics.UnderlinePosition) / fontMetrics.DesignUnitsPerEm :
83 myGlyphRun.FontSize * (fontMetrics.Descent + fontMetrics.LineGap) / fontMetrics.DesignUnitsPerEm;
85 float right = baselineOriginX;
87 int glyphCount = myGlyphRun.Advances.Length;
89 for (int i = 0; i < glyphCount; i++)
91 if (myGlyphRun.BidiLevel % 2 == 1)
92 right -= myGlyphRun.Advances[i];
94 right += myGlyphRun.Advances[i];
97 bounds.Left = baselineOriginX;
100 else if (myGlyphRun.Advances.Length == 1)
101 bounds.Right = baselineOriginX + myGlyphRun.Advances[0];
103 bounds.Right = bounds.Left;
104 bounds.Top = baselineOriginY - ascentPixel;
105 bounds.Bottom = baselineOriginY + dscentPixel;
110 public Result DrawInlineObject(object clientDrawingContext, float originX, float originY, DW.InlineObject inlineObject, bool isSideways, bool isRightToLeft, ComObject clientDrawingEffect)
112 inlineObject.Draw(this.render, this, originX, originY, isSideways, isRightToLeft, clientDrawingEffect);
116 public Result DrawStrikethrough(object clientDrawingContext, float baselineOriginX, float baselineOriginY, ref DW.Strikethrough strikethrough, ComObject clientDrawingEffect)
118 D2D.SolidColorBrush foreBrush = this.brushes.Get(this.DefaultFore);
119 DrawingEffect effect = clientDrawingEffect as DrawingEffect;
120 if (clientDrawingEffect != null && clientDrawingEffect != null)
122 foreBrush = this.brushes.Get(effect.Fore);
126 render.DrawLine(new Vector2(baselineOriginX, baselineOriginY + strikethrough.Offset),
127 new Vector2(baselineOriginX + strikethrough.Width - 1, baselineOriginY + strikethrough.Offset),
129 GetThickness(strikethrough.Thickness));
134 public Result DrawUnderline(object clientDrawingContext, float baselineOriginX, float baselineOriginY, ref DW.Underline underline, ComObject clientDrawingEffect)
136 D2D.SolidColorBrush foreBrush = this.brushes.Get(this.DefaultFore);
137 DrawingEffect effect = clientDrawingEffect as DrawingEffect;
138 if (clientDrawingEffect != null && effect != null)
140 foreBrush = this.brushes.Get(effect.Fore);
141 float thickness = effect.isBoldLine ? D2DRenderCommon.BoldThickness : D2DRenderCommon.NormalThickness;
142 if (effect.Stroke == HilightType.Squiggle)
144 SquilleLineMarker marker = new D2DSquilleLineMarker(this.render, this.brushes.Get(effect.Fore), this.strokes.Get(this.render,effect.Stroke), 1);
146 baselineOriginX, baselineOriginY + underline.Offset,
147 underline.Width, underline.RunHeight
152 LineMarker marker = new LineMarker(this.render, this.brushes.Get(effect.Fore), this.strokes.Get(this.render,effect.Stroke), GetThickness(thickness));
154 baselineOriginX, baselineOriginY + underline.Offset,
161 render.DrawLine(new Vector2(baselineOriginX, baselineOriginY + underline.Offset),
162 new Vector2(baselineOriginX + underline.Width - 1, baselineOriginY + underline.Offset),
164 GetThickness(underline.Thickness));
167 return SharpDX.Result.Ok;
172 #region PixelSnapping Members
174 public SharpDX.Mathematics.Interop.RawMatrix3x2 GetCurrentTransform(object clientDrawingContext)
176 SharpDX.Mathematics.Interop.RawMatrix3x2 d2Dmatrix = render.Transform;
180 public float GetPixelsPerDip(object clientDrawingContext)
182 return render.PixelSize.Width / 96f;
185 public bool IsPixelSnappingDisabled(object clientDrawingContext)
192 float GetThickness(float thickness)
194 if (this.render.AntialiasMode == D2D.AntialiasMode.Aliased)
195 return (int)(thickness + 0.5);