//------------------------------------------------------ // // Public Properties // //------------------------------------------------------ private static void GlyphRunPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { GlyphRunDrawing target = ((GlyphRunDrawing)d); GlyphRun oldV = (GlyphRun)e.OldValue; GlyphRun newV = (GlyphRun)e.NewValue; System.Windows.Threading.Dispatcher dispatcher = target.Dispatcher; if (dispatcher != null) { DUCE.IResource targetResource = (DUCE.IResource)target; using (CompositionEngineLock.Acquire()) { int channelCount = targetResource.GetChannelCount(); for (int channelIndex = 0; channelIndex < channelCount; channelIndex++) { DUCE.Channel channel = targetResource.GetChannel(channelIndex); Debug.Assert(!channel.IsOutOfBandChannel); Debug.Assert(!targetResource.GetHandle(channel).IsNull); target.ReleaseResource(oldV, channel); target.AddRefResource(newV, channel); } } } target.PropertyChanged(GlyphRunProperty); }
public static ImageSource ToFontAwesomeIcon(this string text, Brush foreBrush, FontStyle fontStyle, FontWeight fontWeight, FontStretch fontStretch) { var fontFamily = new FontFamily("/GitWorkItems;component/Resources/#FontAwesome"); if (fontFamily != null && !String.IsNullOrEmpty(text)) { //premier essai, on charge la police directement Typeface typeface = new Typeface(fontFamily, fontStyle, fontWeight, fontStretch); GlyphTypeface glyphTypeface; if (!typeface.TryGetGlyphTypeface(out glyphTypeface)) { //si ça ne fonctionne pas (et pour le mode design dans certains cas) on ajoute l'uri pack://application typeface = new Typeface(new FontFamily(new Uri("pack://application:,,,"), fontFamily.Source), fontStyle, fontWeight, fontStretch); if (!typeface.TryGetGlyphTypeface(out glyphTypeface)) throw new InvalidOperationException("No glyphtypeface found"); } //détermination des indices/tailles des caractères dans la police ushort[] glyphIndexes = new ushort[text.Length]; double[] advanceWidths = new double[text.Length]; for (int n = 0; n < text.Length; n++) { ushort glyphIndex; try { glyphIndex = glyphTypeface.CharacterToGlyphMap[text[n]]; } catch (Exception) { glyphIndex = 42; } glyphIndexes[n] = glyphIndex; double width = glyphTypeface.AdvanceWidths[glyphIndex] * 1.0; advanceWidths[n] = width; } try { //création de l'objet DrawingImage (compatible avec Imagesource) à partir d'un glyphrun GlyphRun gr = new GlyphRun(glyphTypeface, 0, false, 1.0, glyphIndexes, new Point(0, 0), advanceWidths, null, null, null, null, null, null); GlyphRunDrawing glyphRunDrawing = new GlyphRunDrawing(foreBrush, gr); return new DrawingImage(glyphRunDrawing); } catch (Exception ex) { // ReSharper disable LocalizableElement Console.WriteLine("Error in generating Glyphrun : " + ex.Message); // ReSharper restore LocalizableElement } } return null; }
private static void ForegroundBrushPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { // The first change to the default value of a mutable collection property (e.g. GeometryGroup.Children) // will promote the property value from a default value to a local value. This is technically a sub-property // change because the collection was changed and not a new collection set (GeometryGroup.Children. // Add versus GeometryGroup.Children = myNewChildrenCollection). However, we never marshalled // the default value to the compositor. If the property changes from a default value, the new local value // needs to be marshalled to the compositor. We detect this scenario with the second condition // e.OldValueSource != e.NewValueSource. Specifically in this scenario the OldValueSource will be // Default and the NewValueSource will be Local. if (e.IsASubPropertyChange && (e.OldValueSource == e.NewValueSource)) { return; } GlyphRunDrawing target = ((GlyphRunDrawing)d); Brush oldV = (Brush)e.OldValue; Brush newV = (Brush)e.NewValue; System.Windows.Threading.Dispatcher dispatcher = target.Dispatcher; if (dispatcher != null) { DUCE.IResource targetResource = (DUCE.IResource)target; using (CompositionEngineLock.Acquire()) { int channelCount = targetResource.GetChannelCount(); for (int channelIndex = 0; channelIndex < channelCount; channelIndex++) { DUCE.Channel channel = targetResource.GetChannel(channelIndex); Debug.Assert(!channel.IsOutOfBandChannel); Debug.Assert(!targetResource.GetHandle(channel).IsNull); target.ReleaseResource(oldV, channel); target.AddRefResource(newV, channel); } } } target.PropertyChanged(ForegroundBrushProperty); }
static GraphViewWpf() { var glyphRun = BuildGlyphRun(" Busy with rendering..."); var glyphRunDrawing = new GlyphRunDrawing(Brushes.Lavender, glyphRun); var tileBrush = new DrawingBrush(); tileBrush.Drawing = glyphRunDrawing; tileBrush.Viewbox = new Rect(0, 0, glyphRunDrawing.Bounds.Right * 1.1, glyphRunDrawing.Bounds.Bottom * 1.5); tileBrush.ViewboxUnits = BrushMappingMode.Absolute; tileBrush.Viewport = glyphRunDrawing.Bounds; tileBrush.ViewportUnits = BrushMappingMode.Absolute; tileBrush.TileMode = TileMode.Tile; var drawingRectangle = new RectangleGeometry(new Rect(0, 0, 2000, 2000)); var drawing = new GeometryDrawing(tileBrush, null, drawingRectangle); _busyWithRenderingDrawing = new DrawingImage(drawing); }
private double ChangeGlyphOrientation(GlyphRunDrawing glyphDrawing, double baselineShiftX, double baselineShiftY, bool isLatin) { if (glyphDrawing == null) { return 0; } GlyphRun glyphRun = glyphDrawing.GlyphRun; GlyphRun verticalRun = new GlyphRun(); ISupportInitialize glyphInit = verticalRun; glyphInit.BeginInit(); verticalRun.IsSideways = true; List<double> advancedHeights = null; double totalHeight = 0; IList<UInt16> glyphIndices = glyphRun.GlyphIndices; int advancedCount = glyphIndices.Count; //{ // double textHeight = glyphRun.ComputeInkBoundingBox().Height + glyphRun.ComputeAlignmentBox().Height; // textHeight = textHeight / 2.0d; // totalHeight = advancedCount * textHeight; // advancedHeights = new List<double>(advancedCount); // for (int k = 0; k < advancedCount; k++) // { // advancedHeights.Add(textHeight); // } //} advancedHeights = new List<double>(advancedCount); IDictionary<ushort, double> allGlyphHeights = glyphRun.GlyphTypeface.AdvanceHeights; double fontSize = glyphRun.FontRenderingEmSize; for (int k = 0; k < advancedCount; k++) { double tempValue = allGlyphHeights[glyphIndices[k]] * fontSize; advancedHeights.Add(tempValue); totalHeight += tempValue; } Point baselineOrigin = glyphRun.BaselineOrigin; if (isLatin) { baselineOrigin.X += baselineShiftX; baselineOrigin.Y += baselineShiftY; } //verticalRun.AdvanceWidths = glyphRun.AdvanceWidths; verticalRun.AdvanceWidths = advancedHeights; verticalRun.BaselineOrigin = baselineOrigin; verticalRun.BidiLevel = glyphRun.BidiLevel; verticalRun.CaretStops = glyphRun.CaretStops; verticalRun.Characters = glyphRun.Characters; verticalRun.ClusterMap = glyphRun.ClusterMap; verticalRun.DeviceFontName = glyphRun.DeviceFontName; verticalRun.FontRenderingEmSize = glyphRun.FontRenderingEmSize; verticalRun.GlyphIndices = glyphRun.GlyphIndices; verticalRun.GlyphOffsets = glyphRun.GlyphOffsets; verticalRun.GlyphTypeface = glyphRun.GlyphTypeface; verticalRun.Language = glyphRun.Language; glyphInit.EndInit(); glyphDrawing.GlyphRun = verticalRun; return totalHeight; }
private static ImageSource CreateGlyph(string text, FontFamily fontFamily, FontStyle fontStyle, FontWeight fontWeight, FontStretch fontStretch, Brush foreBrush) { if (fontFamily != null && !string.IsNullOrEmpty(text)) { var typeface = new Typeface(fontFamily, fontStyle, fontWeight, fontStretch); GlyphTypeface glyphTypeface; if (!typeface.TryGetGlyphTypeface(out glyphTypeface)) { throw Log.ErrorAndCreateException<InvalidOperationException>("No glyph type face found"); } var glyphIndexes = new ushort[text.Length]; var advanceWidths = new double[text.Length]; for (var i = 0; i < text.Length; i++) { ushort glyphIndex; try { var key = text[i]; if (!glyphTypeface.CharacterToGlyphMap.TryGetValue(key, out glyphIndex)) { glyphIndex = 42; } } catch (Exception) { glyphIndex = 42; } glyphIndexes[i] = glyphIndex; var width = glyphTypeface.AdvanceWidths[glyphIndex] * 1.0; advanceWidths[i] = width; } try { var glyphRun = new GlyphRun(glyphTypeface, 0, false, RenderingEmSize, glyphIndexes, new Point(0, 0), advanceWidths, null, null, null, null, null, null); var glyphRunDrawing = new GlyphRunDrawing(foreBrush, glyphRun); //TextOptions.SetTextRenderingMode(glyphRunDrawing, TextRenderingMode.Aliased); var drawingImage = new DrawingImage(glyphRunDrawing); //TextOptions.SetTextRenderingMode(drawingImage, TextRenderingMode.Aliased); return drawingImage; } catch (Exception ex) { Log.Error(ex, "Error in generating Glyphrun"); } } return null; }
private bool HitTestDrawing(GlyphRunDrawing drawing, Point pt) { if (drawing != null && drawing.Bounds.Contains(pt)) { return true; } return false; }
private static ImageSource GetImage(sd.FontFamily fontFamily) { const double height = 1; const double width = 2; const double fontSize = 1; var drawingGroup = new DrawingGroup(); var outerGeometry = new RectangleGeometry(new Rect(0, 0, width, height)); var geometryDrawing = new GeometryDrawing() { Geometry = outerGeometry }; geometryDrawing.Pen = new Pen(Brushes.Transparent, 0); drawingGroup.Children.Add(geometryDrawing); Typeface typeface = new Typeface(fontFamily.Name); GlyphTypeface glyphTypeFace; if (!typeface.TryGetGlyphTypeface(out glyphTypeFace)) glyphTypeFace = null; if (null != glyphTypeFace) { var glyphRun = new GlyphRun(); ((System.ComponentModel.ISupportInitialize)glyphRun).BeginInit(); glyphRun.GlyphTypeface = glyphTypeFace; glyphRun.FontRenderingEmSize = fontSize; var textChars = GetDisplayText(glyphTypeFace); glyphRun.Characters = textChars; ushort[] glyphIndices = new ushort[textChars.Length]; double[] advanceWidths = new double[textChars.Length]; for (int i = 0; i < textChars.Length; ++i) { int codePoint = textChars[i]; ushort glyphIndex = glyphTypeFace.CharacterToGlyphMap[codePoint]; double glyphWidht = glyphTypeFace.AdvanceWidths[glyphIndex]; glyphIndices[i] = glyphIndex; advanceWidths[i] = glyphWidht * fontSize; } if (glyphIndices.Length > 0) { glyphRun.GlyphIndices = glyphIndices; glyphRun.AdvanceWidths = advanceWidths; glyphRun.BaselineOrigin = new Point(0, glyphTypeFace.Baseline * fontSize); ((System.ComponentModel.ISupportInitialize)glyphRun).EndInit(); var glyphRunDrawing = new GlyphRunDrawing(Brushes.Black, glyphRun); drawingGroup.Children.Add(glyphRunDrawing); } } drawingGroup.ClipGeometry = outerGeometry; DrawingImage geometryImage = new DrawingImage(drawingGroup); // Freeze the DrawingImage for performance benefits. geometryImage.Freeze(); return geometryImage; }
/// <summary> /// Draw a GlyphRun. /// </summary> /// <param name="foregroundBrush">Foreground brush to draw GlyphRun with. </param> /// <param name="glyphRun"> The GlyphRun to draw. </param> /// <exception cref="ObjectDisposedException"> /// This call is illegal if this object has already been closed or disposed. /// </exception> public override void DrawGlyphRun(Brush foregroundBrush, GlyphRun glyphRun) { #if DEBUG MediaTrace.DrawingContextOp.Trace("DrawGlyphRun(constant)"); #endif // // Verify that parameters & state are valid // VerifyApiNonstructuralChange(); if (foregroundBrush == null || glyphRun == null) { return; } // Add a GlyphRunDrawing to the Drawing graph GlyphRunDrawing glyphRunDrawing = new GlyphRunDrawing(); // // We may need to opt-out of inheritance through the new Freezable. // This is controlled by this.CanBeInheritanceContext. // glyphRunDrawing.CanBeInheritanceContext = CanBeInheritanceContext; glyphRunDrawing.ForegroundBrush = foregroundBrush; glyphRunDrawing.GlyphRun = glyphRun; SetupNewFreezable( glyphRunDrawing, foregroundBrush.IsFrozen ); AddDrawing(glyphRunDrawing); }