protected override void OnRender(DrawingContext drawingContext) { if (myRun == null) return; Point offset = Point.Empty; float slack = Width - myRun.Width; if (myTextAlignment == TextAlignment.Right) offset.X = slack; else if (myTextAlignment == TextAlignment.Center) offset.X = slack / 2; drawingContext.PushTranslate(offset.X, offset.Y); drawingContext.DrawGlyphRun(ForeBrush, myRun); drawingContext.Pop(); }
/// <summary>Draws the text glyph in the specified target area.</summary> /// <param name="dc">The drawing context to draw on.</param> /// <param name="foreground">The text foreground brush.</param> /// <param name="targetArea">The target area where the text is to be drawn (according to the specified alignment).</param> /// <param name="alignment">Indicates how to align the text with respect to the target area.</param> public void Draw(DrawingContext dc, Brush foreground, Rect targetArea, TextAlign alignment) { if (IsEmpty || targetArea.IsEmpty || foreground == null) return; // compute bounds var bounds = _computeBounds(targetArea, alignment); dc.PushTranslate(bounds.X + SharpnessVector.X, bounds.Y + SharpnessVector.Y); if (TextOverflow == TextOverflow.Ignore || Width <= bounds.Width) { // ignore overflow - use original glyph run and draw it without clipping _drawGlyphRun(dc, _fullRun, foreground); } else if (TextOverflow == TextOverflow.Clip) { // clip overflow - use original glyph run but clip it to fit bounds var clipRect = new RectangleGeometry(new Rect(new Point(), bounds.Size)); clipRect.Freeze(); dc.PushClip(clipRect); _drawGlyphRun(dc, _fullRun, foreground); dc.Pop(); } else { // trim overflow - create a trimmed glyph run that fits the bounds and cache it for next invocation // (the caching of the trimmed glyph is effective only if the width does not change - e.g., when drawing the same glyph in a different color) if (_trimmedWidth.CertainlyDifferent(bounds.Width)) { var result = _buildGlyph(false, bounds.Width); _trimmedRun = (result != null ? result.GlyphRun : null); _trimmedWidth = bounds.Width; } _drawGlyphRun(dc, _trimmedRun, foreground); } dc.Pop(); }
/// <summary/> protected override void OnRender(DrawingContext dc) { base.OnRender(dc); if (TickCount <= 0 || Foreground == null) return; double cx, cy, r0, r1; if (!ComputeBoundingCircles(out cx, out cy, out r0, out r1)) return; var a0 = StartAngle; var a1 = EndAngle; Gauge.NormalizeAngularRange(ref a0, ref a1); if (a0.AlmostEquals(a1)) return; var typeface = new Typeface(FontFamily, FontStyle, FontWeight, FontStretch); var fontsize = this.IsDefaultValue(FontSizeProperty) ? (r1 - r0) : FontSize; var format = StringFormat.Nvl("{0}"); Action<double, double> drawText = (double n, double a) => { var text = new FormattedText(format.Substitute(n), CultureInfo.CurrentUICulture, FlowDirection.LeftToRight, typeface, fontsize, Foreground); var tw = text.Width; var th = text.Height; var tb = fontsize - text.Baseline; if (!IsRotated) { var arad = a / 180.0 * Math.PI; dc.PushRotate(-a, cx, cy - r1 + th / 2.0); dc.PushTranslate(-Math.Sin(arad) * tw / 2.0, Math.Cos(arad) * th / 2.0); } dc.DrawText(text, new Point(cx - tw / 2.0, cy - r1 + tb)); if (!IsRotated) { dc.Pop(); dc.Pop(); } }; var pen = GetStrokePen(); if (TickCount == 1) { dc.PushRotate((a1 + a0) / 2.0, cx, cy); drawText((Maximum + Minimum) / 2.0, 0); dc.Pop(); } else { var v0 = Minimum; var v1 = Maximum; Gauge.NormalizeRange(ref v0, ref v1); var angleDelta = (a1 - a0) / (TickCount - 1); var valueDelta = (v1 - v0) / (TickCount - 1); for (var i = 0; i < TickCount; i++) { if (SkipCount > 0 && (i % SkipCount) == 0) continue; dc.PushRotate(a0 + i * angleDelta, cx, cy); drawText(v0 + i * valueDelta, a0 + i * angleDelta); dc.Pop(); } } }
internal void Render(Control control, DrawingContext context) { OnRender(context); myIsVisualValid = true; if (myChildren == null) return; foreach (Control child in myChildren) { context.PushTranslate(child.myLeft, child.myTop); child.Render(child, context); context.Pop(); } }