public override PathGeometry Build(SvgTextContentElement element, string text, double x, double y) { ComputeMeasurement(text, x, y); _textWidth = 0; if (_glyphRun == null) { return(new PathGeometry()); } // Approximate the width of the text... Rect designRect = _glyphRun.ComputeAlignmentBox(); designRect.Offset(_glyphRunOrigin.X, _glyphRunOrigin.Y); _textWidth = Math.Max(0, designRect.Right); PathGeometry pathGeometry = null; var geometry = _glyphRun.BuildGeometry(); if (geometry is PathGeometry) { pathGeometry = (PathGeometry)geometry; } else { pathGeometry = new PathGeometry(); pathGeometry.AddGeometry(geometry); } return(pathGeometry); }
//-------------------------------------------------------------------- // // Public Properties // //--------------------------------------------------------------------- #region Static methods public static FixedSOMElement CreateFixedSOMElement(FixedPage page, UIElement uiElement, FixedNode fixedNode, int startIndex, int endIndex) { FixedSOMElement element = null; if (uiElement is Glyphs) { Glyphs glyphs = uiElement as Glyphs; if (glyphs.UnicodeString.Length > 0) { GlyphRun glyphRun = glyphs.ToGlyphRun(); Rect alignmentBox = glyphRun.ComputeAlignmentBox(); alignmentBox.Offset(glyphs.OriginX, glyphs.OriginY); GeneralTransform transform = glyphs.TransformToAncestor(page); if (startIndex < 0) { startIndex = 0; } if (endIndex < 0) { endIndex = glyphRun.Characters == null ? 0 : glyphRun.Characters.Count; } element = FixedSOMTextRun.Create(alignmentBox, transform, glyphs, fixedNode, startIndex, endIndex, false); } } else if (uiElement is Image) { element = FixedSOMImage.Create(page, uiElement as Image, fixedNode); } else if (uiElement is Path) { element = FixedSOMImage.Create(page, uiElement as Path, fixedNode); } return(element); }
private void ComputeBounds() { _LayoutBounds = _native.ComputeAlignmentBox().ToUGRect(); if (HorizontalAlignment != UGHorizontalAlignment.Left) { if (HorizontalAlignment == UGHorizontalAlignment.Right) { _LayoutBounds.X = Math.Max(0F, _requestedSize.Width - _LayoutBounds.Width); } else if (HorizontalAlignment == UGHorizontalAlignment.Center) { _LayoutBounds.X = Math.Max(0F, (_requestedSize.Width - _LayoutBounds.Width) / 2F); } } if (VerticalAlignment != UGVerticalAlignment.Top) { if (VerticalAlignment == UGVerticalAlignment.Bottom) { _LayoutBounds.Y = Math.Max(0F, _requestedSize.Height - _LayoutBounds.Height); } else if (VerticalAlignment == UGVerticalAlignment.Center) { _LayoutBounds.Y = Math.Max(0F, (_requestedSize.Height - _LayoutBounds.Height) / 2F); } } else { _LayoutBounds.Y = 0F; } }
/// <summary> /// Gets the vector that must be added to the atom position to center the glyph /// </summary> /// <param name="glyphRun">Run of text for atom symbol</param> /// <param name="symbolSize">Size of symbol in DIPs</param> /// <returns>Vector to be added to atom pos</returns> public static Vector GetOffsetVector(GlyphRun glyphRun, double symbolSize) { Rect rect = glyphRun.ComputeAlignmentBox(); Vector offset = new Vector(-rect.Width / 2, glyphRun.GlyphTypeface.CapsHeight * symbolSize / 2); return(offset); }
public override Size MeasureText(SvgTextContentElement element, string text, bool canBeWhitespace = true) { ComputeMeasurement(text, 0, 0); if (_glyphRun == null) { return(new Size(0, 0)); } Rect designRect = _glyphRun.ComputeAlignmentBox(); //designRect.Offset(_glyphRunOrigin.X, _glyphRunOrigin.Y); _textWidth = Math.Max(0, designRect.Right); return(new Size(Math.Max(0, designRect.Right), Math.Max(0, designRect.Bottom))); }
// Token: 0x06002D3B RID: 11579 RVA: 0x000CC368 File Offset: 0x000CA568 internal Rect ComputeDesignRect() { Glyphs glyphs = this._element as Glyphs; if (glyphs == null) { Image image = this._element as Image; if (image != null && image.Source != null) { return new Rect(0.0, 0.0, image.Width, image.Height); } Path path = this._element as Path; if (path != null) { return path.Data.Bounds; } return Rect.Empty; } else { GlyphRun measurementGlyphRun = glyphs.MeasurementGlyphRun; if (measurementGlyphRun == null || this._gBeginOffset >= this._gEndOffset) { return Rect.Empty; } Rect result = measurementGlyphRun.ComputeAlignmentBox(); result.Offset(glyphs.OriginX, glyphs.OriginY); int num = (measurementGlyphRun.Characters == null) ? 0 : measurementGlyphRun.Characters.Count; double num2 = measurementGlyphRun.GetDistanceFromCaretCharacterHit(new CharacterHit(this._gBeginOffset, 0)); double num3; if (this._gEndOffset == num) { num3 = measurementGlyphRun.GetDistanceFromCaretCharacterHit(new CharacterHit(num - 1, 1)); } else { num3 = measurementGlyphRun.GetDistanceFromCaretCharacterHit(new CharacterHit(this._gEndOffset, 0)); } if (num3 < num2) { double num4 = num2; num2 = num3; num3 = num4; } double width = num3 - num2; if ((measurementGlyphRun.BidiLevel & 1) != 0) { result.X = glyphs.OriginX - num3; } else { result.X = glyphs.OriginX + num2; } result.Width = width; return result; } }
private void ComputeMeasurement(string text, double OriginX, double OriginY) { _unicodeString = text; _glyphRun = null; ParseGlyphRunProperties(); if (_glyphRun != null) { return; } bool leftToRight = ((BidiLevel & 1) == 0); bool haveOriginX = !double.IsNaN(OriginX); bool haveOriginY = !double.IsNaN(OriginY); bool measurementGlyphRunOriginValid = false; Rect alignmentRect = new Rect(); if (haveOriginX && haveOriginY && leftToRight) { _glyphRun = CreateGlyphRun(new Point(OriginX, OriginY), this.Language); measurementGlyphRunOriginValid = true; } else { _glyphRun = CreateGlyphRun(new Point(), this.Language); // compute alignment box for origins alignmentRect = _glyphRun.ComputeAlignmentBox(); } if (haveOriginX) { _glyphRunOrigin.X = OriginX; } else { _glyphRunOrigin.X = leftToRight ? 0 : alignmentRect.Width; } if (haveOriginY) { _glyphRunOrigin.Y = OriginY; } else { _glyphRunOrigin.Y = -alignmentRect.Y; } if (!measurementGlyphRunOriginValid) { _glyphRun = CreateGlyphRun(_glyphRunOrigin, this.Language); } }
public override void DrawString(string str, RFont font, RColor color, RPoint point, RSize size, bool rtl) { var colorConv = ((BrushAdapter)_adapter.GetSolidBrush(color)).Brush; bool glyphRendered = false; GlyphTypeface glyphTypeface = ((FontAdapter)font).GlyphTypeface; if (glyphTypeface != null) { double width = 0; ushort[] glyphs = new ushort[str.Length]; double[] widths = new double[str.Length]; int i = 0; for (; i < str.Length; i++) { ushort glyph; if (!glyphTypeface.CharacterToGlyphMap.TryGetValue(str[i], out glyph)) { break; } glyphs[i] = glyph; width += glyphTypeface.AdvanceWidths[glyph]; widths[i] = 96d / 72d * font.Size * glyphTypeface.AdvanceWidths[glyph]; } if (i >= str.Length) { point.Y += glyphTypeface.Baseline * font.Size * 96d / 72d; point.X += rtl ? 96d / 72d * font.Size * width : 0; glyphRendered = true; var glyphRun = new GlyphRun(glyphTypeface, rtl ? 1 : 0, false, 96d / 72d * font.Size, glyphs, Utils.ConvertRound(point), widths, null, null, null, null, null, null); var rect = glyphRun.ComputeAlignmentBox(); var guidelines = new GuidelineSet(); guidelines.GuidelinesX.Add(rect.Left); guidelines.GuidelinesX.Add(rect.Right); guidelines.GuidelinesY.Add(rect.Top); guidelines.GuidelinesY.Add(rect.Bottom); _g.PushGuidelineSet(guidelines); _g.DrawGlyphRun(colorConv, glyphRun); _g.Pop(); } } if (!glyphRendered) { var formattedText = new FormattedText(str, CultureInfo.CurrentCulture, rtl ? FlowDirection.RightToLeft : FlowDirection.LeftToRight, ((FontAdapter)font).Font, 96d / 72d * font.Size, colorConv); point.X += rtl ? formattedText.Width : 0; _g.DrawText(formattedText, Utils.ConvertRound(point)); } }
// Token: 0x06002EF1 RID: 12017 RVA: 0x000D3FAC File Offset: 0x000D21AC private ITextPointer _SnapToText(Point point) { FixedNode[] line = this.Container.FixedTextBuilder.GetLine(this.PageIndex, point); ITextPointer textPointer; if (line != null && line.Length != 0) { double num = double.MaxValue; double xoffset = 0.0; Glyphs glyphs = null; FixedNode fixedNode = line[0]; foreach (FixedNode fixedNode2 in line) { Glyphs glyphsElement = this.FixedPage.GetGlyphsElement(fixedNode2); GeneralTransform generalTransform = this.FixedPage.TransformToDescendant(glyphsElement); Point inPoint = point; if (generalTransform != null) { generalTransform.TryTransform(inPoint, out inPoint); } GlyphRun glyphRun = glyphsElement.ToGlyphRun(); Rect rect = glyphRun.ComputeAlignmentBox(); rect.Offset(glyphsElement.OriginX, glyphsElement.OriginY); double num2 = Math.Max(0.0, (inPoint.X > rect.X) ? (inPoint.X - rect.Right) : (rect.X - inPoint.X)); double num3 = Math.Max(0.0, (inPoint.Y > rect.Y) ? (inPoint.Y - rect.Bottom) : (rect.Y - inPoint.Y)); double num4 = num2 + num3; if (glyphs == null || num4 < num) { num = num4; glyphs = glyphsElement; fixedNode = fixedNode2; xoffset = inPoint.X; } } int offset; LogicalDirection edge; this._GlyphRunHitTest(glyphs, xoffset, out offset, out edge); FixedPosition fixedPosition = new FixedPosition(fixedNode, offset); textPointer = this._CreateTextPointer(fixedPosition, edge); } else if (point.Y < this.FixedPage.Height / 2.0) { textPointer = ((ITextPointer)this.Start).CreatePointer(LogicalDirection.Forward); textPointer.MoveToInsertionPosition(LogicalDirection.Forward); } else { textPointer = ((ITextPointer)this.End).CreatePointer(LogicalDirection.Backward); textPointer.MoveToInsertionPosition(LogicalDirection.Backward); } return(textPointer); }
// Token: 0x06002EF4 RID: 12020 RVA: 0x000D4420 File Offset: 0x000D2620 internal static Rect _GetGlyphRunDesignRect(Glyphs g, int charStart, int charEnd) { GlyphRun glyphRun = g.ToGlyphRun(); if (glyphRun == null) { return(Rect.Empty); } Rect result = glyphRun.ComputeAlignmentBox(); result.Offset(glyphRun.BaselineOrigin.X, glyphRun.BaselineOrigin.Y); int num = 0; if (glyphRun.Characters != null) { num = glyphRun.Characters.Count; } else if (g.UnicodeString != null) { num = g.UnicodeString.Length; } if (charStart > num) { charStart = num; } else if (charStart < 0) { charStart = 0; } if (charEnd > num) { charEnd = num; } else if (charEnd < 0) { charEnd = 0; } double num2 = FixedTextView._GetDistanceToCharacter(glyphRun, charStart); double num3 = FixedTextView._GetDistanceToCharacter(glyphRun, charEnd); double width = num3 - num2; if ((glyphRun.BidiLevel & 1) != 0) { result.X = glyphRun.BaselineOrigin.X - num3; } else { result.X = glyphRun.BaselineOrigin.X + num2; } result.Width = width; return(result); }
public static string ToText(this FrameworkElement root) { var builder = new StringBuilder(); foreach (var visual in root.GetSelfAndDescendants().OfType <DrawingVisual>()) { GlyphRun previousRun = null; // Order runs first vertically (Y), then horizontally (X). foreach (var currentRun in visual.Drawing .GetSelfAndDescendants() .OfType <GlyphRunDrawing>() .Select(glyph => glyph.GlyphRun) .OrderBy(run => run.BaselineOrigin.Y) .ThenBy(run => run.BaselineOrigin.X)) { if (previousRun != null) { // If base-line of current text segment is left from base-line of previous text segment, then assume that it is new line. if (currentRun.BaselineOrigin.X <= previousRun.BaselineOrigin.X) { builder.AppendLine(); } else { Rect currentRect = currentRun.ComputeAlignmentBox(); Rect previousRect = previousRun.ComputeAlignmentBox(); double spaceWidth = currentRun.BaselineOrigin.X + currentRect.Left - previousRun.BaselineOrigin.X - previousRect.Right; double spaceHeight = (currentRect.Height + previousRect.Height) / 2; // If space between successive text segments has width greater than a sixth of its height, then assume that it is a word (add a space). if (spaceWidth > spaceHeight / 6) { builder.Append(' '); } } } builder.Append(currentRun.Characters.ToArray()); previousRun = currentRun; } } return(builder.ToString()); }
private GlyphRun GetGlyphRun() { if (_native == null) { var glyphTypeface = _textFormat.Native; var fontSize = _textFormat.FontSize; var length = _textString.Length; var glyphIndices = new ushort[length]; var advanceWidths = new double[length]; var totalWidth = 0.0; var height = 0.0; for (var i = 0; i < length; ++i) { glyphTypeface.CharacterToGlyphMap.TryGetValue(_textString[i], out var glyphIndex); glyphIndices[i] = glyphIndex; var width = fontSize * glyphTypeface.AdvanceWidths[glyphIndex]; advanceWidths[i] = width; totalWidth += width; height = Math.Max(height, glyphTypeface.AdvanceHeights[glyphIndex]); } _native = new GlyphRun( glyphTypeface, 0, false, fontSize, glyphIndices, new Point(0, Math.Round(fontSize * glyphTypeface.Baseline)), advanceWidths, null, null, null, null, null, null); _LayoutBounds = _native.ComputeAlignmentBox().ToUGRect(); ComputeBounds(); } return(_native); }
// If return false, nothing has been modified, which implies out of page boundary // The input of suggestedX is in the VisualRoot's cooridnate system private bool _GetNextLineGlyphs(ref FixedPosition fixedp, ref LogicalDirection edge, double suggestedX, LogicalDirection scanDir) { int count = 1; int pageIndex = fixedp.Page; bool moved = false; FixedNode[] fixedNodes = Container.FixedTextBuilder.GetNextLine(fixedp.Node, (scanDir == LogicalDirection.Forward), ref count); if (fixedNodes != null && fixedNodes.Length > 0) { FixedPage page = Container.FixedDocument.SyncGetPage(pageIndex, false); // This line contains multiple Glyhs. Scan backward // util we hit the first one whose OriginX is smaller // then suggestedX; if (Double.IsInfinity(suggestedX)) { suggestedX = 0; } Point topOfPage = new Point(suggestedX, 0); Point secondPoint = new Point(suggestedX, 1000); FixedNode hitNode = fixedNodes[0]; Glyphs hitGlyphs = null; double closestDistance = Double.MaxValue; double xoffset = 0; for (int i = fixedNodes.Length - 1; i >= 0; i--) { FixedNode node = fixedNodes[i]; Glyphs g = page.GetGlyphsElement(node); if (g != null) { GeneralTransform transform = page.TransformToDescendant(g); Point pt1 = topOfPage; Point pt2 = secondPoint; if (transform != null) { transform.TryTransform(pt1, out pt1); transform.TryTransform(pt2, out pt2); } double invSlope = (pt2.X - pt1.X) / (pt2.Y - pt1.Y); double xoff, distance; GlyphRun run = g.ToGlyphRun(); Rect box = run.ComputeAlignmentBox(); box.Offset(g.OriginX, g.OriginY); if (invSlope > 1000 || invSlope < -1000) { // special case for vertical text xoff = 0; distance = (pt1.Y > box.Y) ? (pt1.Y - box.Bottom) : (box.Y - pt1.Y); } else { double centerY = (box.Top + box.Bottom) / 2; xoff = pt1.X + invSlope * (centerY - pt1.Y); distance = (xoff > box.X) ? (xoff - box.Right) : (box.X - xoff); } if (distance < closestDistance) { closestDistance = distance; xoffset = xoff; hitNode = node; hitGlyphs = g; if (distance <= 0) { break; } } } } Debug.Assert(hitGlyphs != null); int charIdx; _GlyphRunHitTest(hitGlyphs, xoffset, out charIdx, out edge); fixedp = new FixedPosition(hitNode, charIdx); moved = true; } return(moved); }
private ITextPointer _SnapToText(Point point) { ITextPointer itp = null; FixedNode[] fixedNodes = Container.FixedTextBuilder.GetLine(this.PageIndex, point); if (fixedNodes != null && fixedNodes.Length > 0) { double closestDistance = Double.MaxValue; double xoffset = 0; Glyphs closestGlyphs = null; FixedNode closestNode = fixedNodes[0]; foreach (FixedNode node in fixedNodes) { Glyphs startGlyphs = this.FixedPage.GetGlyphsElement(node); GeneralTransform tranToGlyphs = this.FixedPage.TransformToDescendant(startGlyphs); Point transformedPt = point; if (tranToGlyphs != null) { tranToGlyphs.TryTransform(transformedPt, out transformedPt); } GlyphRun run = startGlyphs.ToGlyphRun(); Rect alignmentRect = run.ComputeAlignmentBox(); alignmentRect.Offset(startGlyphs.OriginX, startGlyphs.OriginY); double horizontalDistance = Math.Max(0, (transformedPt.X > alignmentRect.X) ? (transformedPt.X - alignmentRect.Right) : (alignmentRect.X - transformedPt.X)); double verticalDistance = Math.Max(0, (transformedPt.Y > alignmentRect.Y) ? (transformedPt.Y - alignmentRect.Bottom) : (alignmentRect.Y - transformedPt.Y)); double manhattanDistance = horizontalDistance + verticalDistance; if (closestGlyphs == null || manhattanDistance < closestDistance) { closestDistance = manhattanDistance; closestGlyphs = startGlyphs; closestNode = node; xoffset = transformedPt.X; } } int index; LogicalDirection dir; _GlyphRunHitTest(closestGlyphs, xoffset, out index, out dir); FixedPosition fixedp = new FixedPosition(closestNode, index); itp = _CreateTextPointer(fixedp, dir); Debug.Assert(itp != null); } else { // // That condition is only possible when there is no line in the page // if (point.Y < this.FixedPage.Height / 2) { itp = ((ITextPointer)this.Start).CreatePointer(LogicalDirection.Forward); itp.MoveToInsertionPosition(LogicalDirection.Forward); } else { itp = ((ITextPointer)this.End).CreatePointer(LogicalDirection.Backward); itp.MoveToInsertionPosition(LogicalDirection.Backward); } } return(itp); }
// char index == -1 implies end of run. internal static Rect _GetGlyphRunDesignRect(Glyphs g, int charStart, int charEnd) { GlyphRun run = g.ToGlyphRun(); if (run == null) { return(Rect.Empty); } Rect designRect = run.ComputeAlignmentBox(); designRect.Offset(run.BaselineOrigin.X, run.BaselineOrigin.Y); int charCount = 0; if (run.Characters != null) { charCount = run.Characters.Count; } else if (g.UnicodeString != null) { charCount = g.UnicodeString.Length; } if (charStart > charCount) { //Extra space was added at the end of the run for contiguity Debug.Assert(charStart - charCount == 1); charStart = charCount; } else if (charStart < 0) { //This is a reversed run charStart = 0; } if (charEnd > charCount) { //Extra space was added at the end of the run for contiguity Debug.Assert(charEnd - charCount == 1); charEnd = charCount; } else if (charEnd < 0) { //This is a reversed run charEnd = 0; } double x1 = _GetDistanceToCharacter(run, charStart); double x2 = _GetDistanceToCharacter(run, charEnd); double width = x2 - x1; if ((run.BidiLevel & 1) != 0) { // right to left designRect.X = run.BaselineOrigin.X - x2; } else { designRect.X = run.BaselineOrigin.X + x1; } designRect.Width = width; return(designRect); }
//Processes the Glyphs element, create one or more text runs out of it, add to containing text line and text box private void _ProcessGlyphsElement(Glyphs glyphs, FixedNode node) { Debug.Assert(glyphs != null); string s = glyphs.UnicodeString; if (s.Length == 0 || glyphs.FontRenderingEmSize <= 0) { return; } //Multiple table cells separated by wide spaces should be identified GlyphRun glyphRun = glyphs.ToGlyphRun(); if (glyphRun == null) { //Could not create a GlyphRun out of this Glyphs element //Some key properties might be missing/invalid return; } Rect alignmentBox = glyphRun.ComputeAlignmentBox(); alignmentBox.Offset(glyphs.OriginX, glyphs.OriginY); GlyphTypeface typeFace = glyphRun.GlyphTypeface; GeneralTransform trans = glyphs.TransformToAncestor(_fixedPage); int charIndex = -1; double advWidth = 0; double cumulativeAdvWidth = 0; int lastAdvWidthIndex = 0; int textRunStartIndex = 0; double lastX = alignmentBox.Left; int glyphIndex = charIndex; do { charIndex = s.IndexOf(" ", charIndex + 1, s.Length - charIndex - 1, StringComparison.Ordinal); if (charIndex >= 0) { if (glyphRun.ClusterMap != null && glyphRun.ClusterMap.Count > 0) { glyphIndex = glyphRun.ClusterMap[charIndex]; } else { glyphIndex = charIndex; } //Advance width of the space character in the font double advFont = typeFace.AdvanceWidths[glyphRun.GlyphIndices[glyphIndex]] * glyphRun.FontRenderingEmSize; double advSpecified = glyphRun.AdvanceWidths[glyphIndex]; if ((advSpecified / advFont) > 2) { //Are these seperated by a vertical line? advWidth = 0; for (int i = lastAdvWidthIndex; i < glyphIndex; i++) { advWidth += glyphRun.AdvanceWidths[i]; } cumulativeAdvWidth += advWidth; lastAdvWidthIndex = glyphIndex + 1; if (_lines.IsVerticallySeparated(glyphRun.BaselineOrigin.X + cumulativeAdvWidth, alignmentBox.Top, glyphRun.BaselineOrigin.X + cumulativeAdvWidth + advSpecified, alignmentBox.Bottom)) { //Create a new FixedTextRun Rect boundingRect = new Rect(lastX, alignmentBox.Top, advWidth + advFont, alignmentBox.Height); int endIndex = charIndex; if ((charIndex == 0 || s[charIndex - 1] == ' ') && (charIndex != s.Length - 1)) { endIndex = charIndex + 1; } _CreateTextRun(boundingRect, trans, glyphs, node, textRunStartIndex, endIndex); lastX = lastX + advWidth + advSpecified; textRunStartIndex = charIndex + 1; } cumulativeAdvWidth += advSpecified; } } } while (charIndex >= 0 && charIndex < s.Length - 1); if (textRunStartIndex < s.Length) { //Last text run //For non-partitioned elements this will be the whole Glyphs element Rect boundingRect = new Rect(lastX, alignmentBox.Top, alignmentBox.Right - lastX, alignmentBox.Height); _CreateTextRun(boundingRect, trans, glyphs, node, textRunStartIndex, s.Length); } }
private WriteableBitmap GetWriteableBitmapDWrite() { Rect boundBox = _run.ComputeInkBoundingBox(); Rect alignBox = _run.ComputeAlignmentBox(); alignBox.X = boundBox.X; alignBox.Width = boundBox.Width; Int32Rect transformedAlign = Round(_transform.TransformBounds(alignBox)); TranslateTransform translate = new TranslateTransform(-Round(transformedAlign.X), -Round(alignBox.Y)); MatrixTransform finalTransform = new MatrixTransform(_transform.Value * translate.Value); uint width = (uint)transformedAlign.Width; uint height = (uint)transformedAlign.Height; DWrite.IDWriteFactory factory = DWrite.CreateFactory(DWrite.FactoryType.Shared); DWrite.IDWriteGdiInterop interop = factory.GetGdiInterop(); DWrite.IDWriteFontFile font = factory.CreateFontFileReference(_typeface.FontUri.LocalPath, IntPtr.Zero); bool isSupported; DWrite.FontFileType fileType; DWrite.FontFaceType faceType; uint faceCount; font.Analyze(out isSupported, out fileType, out faceType, out faceCount); DWrite.IDWriteFontFace face = factory.CreateFontFace(faceType, 1, new DWrite.IDWriteFontFile[] { font }, 0, (DWrite.FontSimulations)_typeface.StyleSimulations); DWrite.GlyphRun run = new DWrite.GlyphRun(_run.GlyphIndices[0]); run.EmSize = (float)_run.FontRenderingEmSize; run.FontFace = face; DWrite.IDWriteRenderingParams pars = factory.CreateCustomRenderingParams(1, 0, 0, DWrite.PixelGeometry.Flat, _antialiasLevel == AntialiasingLevel.None ? DWrite.RenderingMode.Aliased : DWrite.RenderingMode.GdiClassic); DWrite.Matrix matrix = (DWrite.Matrix)finalTransform.Value; IntPtr screenDC = User32.GetScreenDC(); pass: DWrite.IDWriteBitmapRenderTarget target = interop.CreateBitmapRenderTarget(screenDC, width, height); target.SetPixelsPerDip(1); target.SetCurrentTransform(ref matrix); if (!Target1Failed) { try { DWrite.IDWriteBitmapRenderTarget1 target1 = (DWrite.IDWriteBitmapRenderTarget1)target; target1.SetTextAntialiasMode(DWrite.TextAntialiasMode.GrayScale); } catch (COMException) { Target1Failed = true; } } Win32.Rect rect = target.DrawGlyphRun(0, 0, DWrite.MeasuringMode.GdiClassic, ref run, pars, 0xFFFFFF); if (rect.Right > width || rect.Bottom > height) { if (finalTransform.Matrix.Determinant == 1.0 && finalTransform.Matrix.M11 == 1 && finalTransform.Matrix.M12 == 0) // translation { // if translation was requested, we need to preserve absolute dimensions width = (uint)rect.Right; height = (uint)rect.Bottom; } else { // baseline coordinates are subject to transformation, but we need translation width = (uint)(rect.Right - rect.Left); height = (uint)(rect.Bottom - rect.Top); matrix.OffsetX += -rect.Left; matrix.OffsetY += -rect.Top; } // no easy way to measure ahead goto pass; } User32.ReleaseScreenDC(screenDC); IntPtr memoryDC = target.GetMemoryDC(); IntPtr hBitmap = Gdi32.GetCurrentObject(memoryDC, Gdi32.ObjectType.Bitmap); BitmapSource bitmap = Imaging.CreateBitmapSourceFromHBitmap(hBitmap, IntPtr.Zero, System.Windows.Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions()); if (Target1Failed) { return(new WriteableBitmap(new FormatConvertedBitmap(bitmap, PixelFormats.Bgr24, null, 0))); } else { return(new WriteableBitmap(bitmap)); } // DWrite will clean-up the bitmap/memory DC // GC will clean-up DWrite }
// Token: 0x06002DF9 RID: 11769 RVA: 0x000CEA3C File Offset: 0x000CCC3C private void _ProcessGlyphsElement(Glyphs glyphs, FixedNode node) { string unicodeString = glyphs.UnicodeString; if (unicodeString.Length == 0 || glyphs.FontRenderingEmSize <= 0.0) { return; } GlyphRun glyphRun = glyphs.ToGlyphRun(); if (glyphRun == null) { return; } Rect rect = glyphRun.ComputeAlignmentBox(); rect.Offset(glyphs.OriginX, glyphs.OriginY); GlyphTypeface glyphTypeface = glyphRun.GlyphTypeface; GeneralTransform trans = glyphs.TransformToAncestor(this._fixedPage); int num = -1; double num2 = 0.0; int num3 = 0; int num4 = 0; double num5 = rect.Left; do { num = unicodeString.IndexOf(" ", num + 1, unicodeString.Length - num - 1, StringComparison.Ordinal); if (num >= 0) { int num6; if (glyphRun.ClusterMap != null && glyphRun.ClusterMap.Count > 0) { num6 = (int)glyphRun.ClusterMap[num]; } else { num6 = num; } double num7 = glyphTypeface.AdvanceWidths[glyphRun.GlyphIndices[num6]] * glyphRun.FontRenderingEmSize; double num8 = glyphRun.AdvanceWidths[num6]; if (num8 / num7 > 2.0) { double num9 = 0.0; for (int i = num3; i < num6; i++) { num9 += glyphRun.AdvanceWidths[i]; } num2 += num9; num3 = num6 + 1; if (this._lines.IsVerticallySeparated(glyphRun.BaselineOrigin.X + num2, rect.Top, glyphRun.BaselineOrigin.X + num2 + num8, rect.Bottom)) { Rect boundingRect = new Rect(num5, rect.Top, num9 + num7, rect.Height); int endIndex = num; if ((num == 0 || unicodeString[num - 1] == ' ') && num != unicodeString.Length - 1) { endIndex = num + 1; } this._CreateTextRun(boundingRect, trans, glyphs, node, num4, endIndex); num5 = num5 + num9 + num8; num4 = num + 1; } num2 += num8; } } }while (num >= 0 && num < unicodeString.Length - 1); if (num4 < unicodeString.Length) { Rect boundingRect2 = new Rect(num5, rect.Top, rect.Right - num5, rect.Height); this._CreateTextRun(boundingRect2, trans, glyphs, node, num4, unicodeString.Length); } }
internal void RenderFixedNode(DrawingContext dc) { // //Iterate through fix node to draw red dotted line // CultureInfo EnglishCulture = System.Windows.Markup.TypeConverterHelper.InvariantEnglishUS; int lineCount = _lineResults.Length; if (lineCount == 0) { return; } FixedNode fixedStartPage = _lineResults[0].Start; FixedNode fixedEndPage = _lineResults[lineCount - 1].End; FixedNode[] fixedNodes = _fixedTextBuilder.FixedFlowMap.FixedOrderGetRangeNodes(fixedStartPage, fixedEndPage); FixedPage fp = _fixedTextBuilder.FixedTextContainer.FixedDocument.GetFixedPage(PageIndex); FormattedText ft; Point prevTextPoint = new Point(0, 0); DpiScale dpi = fp.GetDpi(); foreach (FixedNode currentFixedNode in fixedNodes) { if (currentFixedNode.Page == FixedFlowMap.FixedOrderStartPage) { prevTextPoint.X = prevTextPoint.Y = 0; ft = new FormattedText("FixedOrderStartPage", EnglishCulture, FlowDirection.LeftToRight, new Typeface("Courier New"), 8, Brushes.DarkViolet, dpi.PixelsPerDip); dc.DrawText(ft, prevTextPoint); continue; } if (currentFixedNode.Page == FixedFlowMap.FixedOrderEndPage) { prevTextPoint.X = fp.Width - 100; prevTextPoint.Y = fp.Height - 10; ft = new FormattedText("FixedOrderEndPage", EnglishCulture, FlowDirection.LeftToRight, new Typeface("Courier New"), 8, Brushes.DarkViolet, dpi.PixelsPerDip); dc.DrawText(ft, prevTextPoint); continue; } if (currentFixedNode[1] == FixedFlowMap.FixedOrderStartVisual || currentFixedNode[1] == FixedFlowMap.FixedOrderEndVisual) { prevTextPoint.X = 2; prevTextPoint.Y = prevTextPoint.Y + 10; String outputString = currentFixedNode[1] == FixedFlowMap.FixedOrderStartVisual ? "FixedOrderStartVisual" : "FixedOrderEndVisual"; ft = new FormattedText(outputString, EnglishCulture, FlowDirection.LeftToRight, new Typeface("Courier New"), 8, Brushes.DarkViolet, dpi.PixelsPerDip); dc.DrawText(ft, prevTextPoint); continue; } DependencyObject dependencyObject = fp.GetElement(currentFixedNode); Image image = dependencyObject as Image; if (image != null) { GeneralTransform transform = image.TransformToAncestor(fp); // You can't use GetContentBounds inside OnRender Rect boundingRect = new Rect(0, 0, image.Width, image.Height); Rect imageRect = transform.TransformBounds(boundingRect); if (!imageRect.IsEmpty) { // Image might overlap, inflate the box. imageRect.Inflate(1, 1); Pen pen = new Pen(Brushes.DarkMagenta, 1.5); DrawRectOutline(dc, pen, imageRect); prevTextPoint.X = imageRect.Right; prevTextPoint.Y = imageRect.Bottom - 10; } else { prevTextPoint.X = 2; prevTextPoint.Y = prevTextPoint.Y + 10; } ft = new FormattedText(currentFixedNode.ToString(), EnglishCulture, FlowDirection.LeftToRight, new Typeface("Courier New"), 8, Brushes.DarkViolet, dpi.PixelsPerDip); dc.DrawText(ft, prevTextPoint); continue; } Path path = dependencyObject as Path; if (path != null) { GeneralTransform transform = path.TransformToAncestor(fp); // You can't use GetContentBounds inside OnRender Rect boundingRect = path.Data.Bounds; Rect imageRect = transform.TransformBounds(boundingRect); if (!imageRect.IsEmpty) { // Image might overlap, inflate the box. imageRect.Inflate(1, 1); Pen pen = new Pen(Brushes.DarkMagenta, 1.5); DrawRectOutline(dc, pen, imageRect); prevTextPoint.X = imageRect.Right; prevTextPoint.Y = imageRect.Bottom - 10; } else { prevTextPoint.X = 2; prevTextPoint.Y = prevTextPoint.Y + 10; } ft = new FormattedText(currentFixedNode.ToString(), EnglishCulture, FlowDirection.LeftToRight, new Typeface("Courier New"), 8, Brushes.DarkViolet, dpi.PixelsPerDip); dc.DrawText(ft, prevTextPoint); continue; } Glyphs glyphs = dependencyObject as Glyphs; if (glyphs != null) { GlyphRun run = glyphs.ToGlyphRun(); if (run != null) { Rect glyphBox = run.ComputeAlignmentBox(); glyphBox.Offset(glyphs.OriginX, glyphs.OriginY); GeneralTransform transform = glyphs.TransformToAncestor(fp); // // Draw it using the dotted red line // Pen pen = new Pen(Brushes.Red, 0.5); Transform t = transform.AffineTransform; if (t != null) { dc.PushTransform(t); } else { dc.PushTransform(Transform.Identity); } DrawRectOutline(dc, pen, glyphBox); prevTextPoint.X = glyphBox.Right; prevTextPoint.Y = glyphBox.Bottom; transform.TryTransform(prevTextPoint, out prevTextPoint); dc.Pop(); // transform } else { prevTextPoint.X = 2; prevTextPoint.Y = prevTextPoint.Y + 10; } ft = new FormattedText(currentFixedNode.ToString(), EnglishCulture, FlowDirection.LeftToRight, new Typeface("Courier New"), 8, Brushes.DarkViolet, dpi.PixelsPerDip); dc.DrawText(ft, prevTextPoint); continue; } // // For anything else, there is this code to draw ... // prevTextPoint.X = 2; prevTextPoint.Y = prevTextPoint.Y + 10; ft = new FormattedText(currentFixedNode.ToString(), EnglishCulture, FlowDirection.LeftToRight, new Typeface("Courier New"), 8, Brushes.DarkViolet, dpi.PixelsPerDip); dc.DrawText(ft, prevTextPoint); } }
//determines whether and where a rectangle intersects a Glyphs private bool IntersectGlyphs(Glyphs g, double top, double left, double bottom, double right, out int begin, out int end, out bool includeEnd, out double baseline, out double height) { begin = 0; end = 0; includeEnd = false; GlyphRun run = g.ToGlyphRun(); Rect boundingRect = run.ComputeAlignmentBox(); boundingRect.Offset(run.BaselineOrigin.X, run.BaselineOrigin.Y); //useful for same line detection baseline = run.BaselineOrigin.Y; height = boundingRect.Height; double centerLine = boundingRect.Y + .5 * boundingRect.Height; GeneralTransform t = g.TransformToAncestor(_page); Point pt1; t.TryTransform(new Point(boundingRect.Left, centerLine), out pt1); Point pt2; t.TryTransform(new Point(boundingRect.Right, centerLine), out pt2); double dStart, dEnd; bool cross = false; if (pt1.X < left) { if (pt2.X < left) { return(false); } cross = true; } else if (pt1.X > right) { if (pt2.X > right) { return(false); } cross = true; } else if (pt2.X < left || pt2.X > right) { cross = true; } if (cross) { double d1 = (left - pt1.X) / (pt2.X - pt1.X); double d2 = (right - pt1.X) / (pt2.X - pt1.X); if (d2 > d1) { dStart = d1; dEnd = d2; } else { dStart = d2; dEnd = d1; } } else { dStart = 0; dEnd = 1; } cross = false; if (pt1.Y < top) { if (pt2.Y < top) { return(false); } cross = true; } else if (pt1.Y > bottom) { if (pt2.Y > bottom) { return(false); } cross = true; } else if (pt2.Y < top || pt2.Y > bottom) { cross = true; } if (cross) { double d1 = (top - pt1.Y) / (pt2.Y - pt1.Y); double d2 = (bottom - pt1.Y) / (pt2.Y - pt1.Y); if (d2 > d1) { if (d1 > dStart) { dStart = d1; } if (d2 < dEnd) { dEnd = d2; } } else { if (d2 > dStart) { dStart = d2; } if (d1 < dEnd) { dEnd = d1; } } } dStart = boundingRect.Left + boundingRect.Width * dStart; dEnd = boundingRect.Left + boundingRect.Width * dEnd; bool leftToRight = ((run.BidiLevel & 1) == 0); begin = GlyphRunHitTest(run, dStart, leftToRight); end = GlyphRunHitTest(run, dEnd, leftToRight); if (begin > end) { int temp = begin; begin = end; end = temp; } Debug.Assert(end >= begin); int characterCount = (run.Characters == null) ? 0 : run.Characters.Count; includeEnd = (end == characterCount); return(true); }
public override void RenderText(SvgTextContentElement element, ref Point ctp, string text, double rotate, WpfTextPlacement placement) { if (string.IsNullOrWhiteSpace(text)) { return; } int vertOrientation = -1; int horzOrientation = -1; string orientationText = element.GetPropertyValue("glyph-orientation-vertical"); if (!string.IsNullOrWhiteSpace(orientationText)) { double orientationValue = 0; if (double.TryParse(orientationText, out orientationValue)) { vertOrientation = (int)orientationValue; } } orientationText = element.GetPropertyValue("glyph-orientation-horizontal"); if (!string.IsNullOrWhiteSpace(orientationText)) { double orientationValue = 0; if (double.TryParse(orientationText, out orientationValue)) { horzOrientation = (int)orientationValue; } } Point startPoint = ctp; IList <WpfTextRun> textRunList = WpfTextRun.BreakWords(text, vertOrientation, horzOrientation); for (int tr = 0; tr < textRunList.Count; tr++) { // For unknown reasons, FormattedText will split a text like "-70%" into two parts "-" // and "70%". We provide a shift to account for the split... double baselineShiftX = 0; double baselineShiftY = 0; WpfTextRun textRun = textRunList[tr]; DrawingGroup verticalGroup = new DrawingGroup(); DrawingContext verticalContext = verticalGroup.Open(); DrawingContext currentContext = _drawContext; _drawContext = verticalContext; this.DrawSingleLineText(element, ref ctp, textRun, rotate, placement); verticalContext.Close(); _drawContext = currentContext; if (verticalGroup.Children.Count == 1) { DrawingGroup textGroup = verticalGroup.Children[0] as DrawingGroup; if (textGroup != null) { verticalGroup = textGroup; } } string runText = textRun.Text; int charCount = runText.Length; double totalHeight = 0; DrawingCollection drawings = verticalGroup.Children; int itemCount = drawings != null ? drawings.Count : 0; for (int i = 0; i < itemCount; i++) { Drawing textDrawing = drawings[i]; DrawingGroup textGroup = textDrawing as DrawingGroup; if (vertOrientation == -1) { if (textGroup != null) { for (int j = 0; j < textGroup.Children.Count; j++) { GlyphRunDrawing glyphDrawing = textGroup.Children[j] as GlyphRunDrawing; if (glyphDrawing != null) { if (textRun.IsLatin) { GlyphRun glyphRun = glyphDrawing.GlyphRun; IList <ushort> glyphIndices = glyphRun.GlyphIndices; IDictionary <ushort, double> allGlyphWeights = glyphRun.GlyphTypeface.AdvanceWidths; double lastAdvanceWeight = allGlyphWeights[glyphIndices[glyphIndices.Count - 1]] * glyphRun.FontRenderingEmSize; totalHeight += glyphRun.ComputeAlignmentBox().Width + lastAdvanceWeight / 2d; } else { totalHeight += ChangeGlyphOrientation(glyphDrawing, baselineShiftX, baselineShiftY, false); } } } } else { GlyphRunDrawing glyphDrawing = textDrawing as GlyphRunDrawing; if (glyphDrawing != null) { if (textRun.IsLatin) { GlyphRun glyphRun = glyphDrawing.GlyphRun; IList <UInt16> glyphIndices = glyphRun.GlyphIndices; IDictionary <ushort, double> allGlyphWeights = glyphRun.GlyphTypeface.AdvanceWidths; double lastAdvanceWeight = allGlyphWeights[glyphIndices[glyphIndices.Count - 1]] * glyphRun.FontRenderingEmSize; totalHeight += glyphRun.ComputeAlignmentBox().Width + lastAdvanceWeight / 2d; } else { totalHeight += ChangeGlyphOrientation(glyphDrawing, baselineShiftX, baselineShiftY, false); } } } } else if (vertOrientation == 0) { if (textGroup != null) { for (int j = 0; j < textGroup.Children.Count; j++) { GlyphRunDrawing glyphDrawing = textGroup.Children[j] as GlyphRunDrawing; if (glyphDrawing != null) { baselineShiftX = ChangeGlyphOrientation(glyphDrawing, baselineShiftX, baselineShiftY, textRun.IsLatin); totalHeight += baselineShiftX; } } } else { GlyphRunDrawing glyphDrawing = textDrawing as GlyphRunDrawing; if (textDrawing != null) { totalHeight += ChangeGlyphOrientation(glyphDrawing, baselineShiftX, baselineShiftY, textRun.IsLatin); } } } else { throw new NotImplementedException(); } } if (!this.IsMeasuring) { _drawContext.DrawDrawing(verticalGroup); } if (tr < textRunList.Count) { ctp.X = startPoint.X; ctp.Y = startPoint.Y + totalHeight; startPoint.Y += totalHeight; } } }
// Token: 0x06002EF2 RID: 12018 RVA: 0x000D4194 File Offset: 0x000D2394 private bool _GetNextLineGlyphs(ref FixedPosition fixedp, ref LogicalDirection edge, double suggestedX, LogicalDirection scanDir) { int num = 1; int page = fixedp.Page; bool result = false; FixedNode[] nextLine = this.Container.FixedTextBuilder.GetNextLine(fixedp.Node, scanDir == LogicalDirection.Forward, ref num); if (nextLine != null && nextLine.Length != 0) { FixedPage fixedPage = this.Container.FixedDocument.SyncGetPage(page, false); if (double.IsInfinity(suggestedX)) { suggestedX = 0.0; } Point point = new Point(suggestedX, 0.0); Point point2 = new Point(suggestedX, 1000.0); FixedNode fixedNode = nextLine[0]; Glyphs g = null; double num2 = double.MaxValue; double xoffset = 0.0; for (int i = nextLine.Length - 1; i >= 0; i--) { FixedNode fixedNode2 = nextLine[i]; Glyphs glyphsElement = fixedPage.GetGlyphsElement(fixedNode2); if (glyphsElement != null) { GeneralTransform generalTransform = fixedPage.TransformToDescendant(glyphsElement); Point inPoint = point; Point inPoint2 = point2; if (generalTransform != null) { generalTransform.TryTransform(inPoint, out inPoint); generalTransform.TryTransform(inPoint2, out inPoint2); } double num3 = (inPoint2.X - inPoint.X) / (inPoint2.Y - inPoint.Y); GlyphRun glyphRun = glyphsElement.ToGlyphRun(); Rect rect = glyphRun.ComputeAlignmentBox(); rect.Offset(glyphsElement.OriginX, glyphsElement.OriginY); double num4; double num5; if (num3 > 1000.0 || num3 < -1000.0) { num4 = 0.0; num5 = ((inPoint.Y > rect.Y) ? (inPoint.Y - rect.Bottom) : (rect.Y - inPoint.Y)); } else { double num6 = (rect.Top + rect.Bottom) / 2.0; num4 = inPoint.X + num3 * (num6 - inPoint.Y); num5 = ((num4 > rect.X) ? (num4 - rect.Right) : (rect.X - num4)); } if (num5 < num2) { num2 = num5; xoffset = num4; fixedNode = fixedNode2; g = glyphsElement; if (num5 <= 0.0) { break; } } } } int offset; this._GlyphRunHitTest(g, xoffset, out offset, out edge); fixedp = new FixedPosition(fixedNode, offset); result = true; } return(result); }
//-------------------------------------------------------------------- // // Public Properties // //--------------------------------------------------------------------- //-------------------------------------------------------------------- // // Public Events // //--------------------------------------------------------------------- //-------------------------------------------------------------------- // // Internal Methods // //--------------------------------------------------------------------- #region Internal Methods // Compute the rectangle that covers this highlight internal Rect ComputeDesignRect() { Glyphs g = _element as Glyphs; if (g == null) { Image im = _element as Image; if (im != null && im.Source != null) { return(new Rect(0, 0, im.Width, im.Height)); } else { Path p = _element as Path; if (p != null) { return(p.Data.Bounds); } } return(Rect.Empty); } GlyphRun run = g.MeasurementGlyphRun; // g.ToGlyphRun(); if (run == null || _gBeginOffset >= _gEndOffset) { return(Rect.Empty); } Rect designRect = run.ComputeAlignmentBox(); designRect.Offset(g.OriginX, g.OriginY); int chrct = (run.Characters == null ? 0 : run.Characters.Count); Debug.Assert(_gBeginOffset >= 0); Debug.Assert(_gEndOffset <= chrct); double x1, x2, width; x1 = run.GetDistanceFromCaretCharacterHit(new CharacterHit(_gBeginOffset, 0)); if (_gEndOffset == chrct) { x2 = run.GetDistanceFromCaretCharacterHit(new CharacterHit(chrct - 1, 1)); } else { x2 = run.GetDistanceFromCaretCharacterHit(new CharacterHit(_gEndOffset, 0)); } if (x2 < x1) { double temp = x1; x1 = x2; x2 = temp; } width = x2 - x1; if ((run.BidiLevel & 1) != 0) { // right to left designRect.X = g.OriginX - x2; } else { designRect.X = g.OriginX + x1; } designRect.Width = width; #if DEBUG DocumentsTrace.FixedTextOM.Highlight.Trace(string.Format("DesignBound {0}", designRect)); #endif return(designRect); }
private void Test2() { //Glyph系クラス GlyphRun glyphRun; GlyphRunDrawing glyphRunDrawing; Glyphs glyphs; GlyphTypeface glyphTypeface; FontFamily fontFamily = new FontFamily("Meiryo UI"); var typefaces = fontFamily.GetTypefaces(); Uri myFontUri = null; foreach (var face in typefaces) { face.TryGetGlyphTypeface(out GlyphTypeface gType); myFontUri = gType.FontUri; break; } glyphs = new(); glyphs.FontUri = myFontUri; glyphs.FontRenderingEmSize = 100; //glyphs.StyleSimulations = StyleSimulations.BoldItalicSimulation; glyphs.UnicodeString = "(ゆっくり)"; glyphs.Fill = Brushes.MediumOrchid; //glyphs.BidiLevel = 1; //glyphs.IsSideways = true; GlyphRun gRun = glyphs.ToGlyphRun(); var chars = gRun.Characters; var clustre = gRun.ClusterMap; var box = gRun.ComputeAlignmentBox(); var inkBox = gRun.ComputeInkBoundingBox(); var dfName = gRun.DeviceFontName; var inside = gRun.GetCaretCharacterHitFromDistance(100, out bool isindside); var hit = gRun.GetNextCaretCharacterHit(new System.Windows.Media.TextFormatting.CharacterHit()); var gInd = gRun.GlyphIndices; var gOffset = gRun.GlyphOffsets; var gTypeface = gRun.GlyphTypeface; MyGrid.Children.Add(glyphs); DrawingVisual dv = new(); //dv.Offset = new Vector(0, -100); using (var dc = dv.RenderOpen()) { //dc.DrawRectangle(Brushes.MediumBlue, null, new Rect(0, 0, 500, 500)); //dc.DrawRectangle(Brushes.MediumBlue, null, new Rect(0, 0, box.Width, box.Height)); dc.DrawGlyphRun(Brushes.MediumAquamarine, gRun); } Rect r3 = dv.Drawing.Bounds; Rect r = dv.ContentBounds; Rect r2 = dv.DescendantBounds; var geo = gRun.BuildGeometry(); Rect rectGeo1 = geo.Bounds; Rect rectGeo2 = geo.GetRenderBounds(null); RenderTargetBitmap bitmap = new((int)box.Width, (int)box.Height, 96, 96, PixelFormats.Pbgra32); bitmap.Render(dv); glyphRunDrawing = new(Brushes.MediumAquamarine, gRun); MyGrid.Background = new DrawingBrush(glyphRunDrawing); //Glyphs //FontUri フォント //FontRenderingEmSize フォントサイズみたいなもの //StyleSimulations 太字と斜体の指定 //BidiLevel 文字を並べる向きの指定、0or偶数で左から、奇数で右からになる //ToGlyphRun() GlyphRun作成 //GlyphRun クラス (System.Windows.Media) | Microsoft Docs //https://docs.microsoft.com/ja-jp/dotnet/api/system.windows.media.glyphrun?view=net-6.0 // 同じ描画スタイルが設定され、サイズ、フォント、およびフォントの書体が同じである一連のグリフを表します。 //GlyphRunDrawingと組み合わせて使う //プロパティ //AdvanceWidths //グリフ インデックスに対応するアドバンス幅を表す Double 値の一覧を取得または設定します。 //BaselineOrigin Point //GlyphRun のベースライン原点を取得または設定します。 //BidiLevel Int32 //GlyphRun の双方向の入れ子レベルを取得または設定します。 //CaretStops bool //GlyphRun を表す Unicode で UTF16 コード ポイント毎にキャレット ストップがあるかどうかを決定する Boolean 値の一覧を取得または設定します。 //Characters List<Char> //GlyphRun の Unicode を表す UTF16 コード ポイントの一覧を取得または設定します。 //ClusterMap List<Uint16> //GlyphRun の文字をグリフ インデックスにマップする UInt16 値の一覧を取得または設定します。 //DeviceFontName string //GlyphRun が最適化される対象の、デバイス固有のフォントを取得または設定します。 //FontRenderingEmSize double //GlyphRun のレンダリングに使用する全角サイズを取得または設定します。 //GlyphIndices list<Uint16> //描画物理フォントのグリフ インデックスを表す UInt16 値の配列を取得または設定します。 //GlyphOffsets List<point> //GlyphRun のグリフのオフセットを表す Point 値の配列を取得または設定します。 //GlyphTypeface GlyphTypeface //GlyphTypeface の GlyphRun を取得または設定します。 //IsHitTestable bool //GlyphRun 内に有効なキャレット文字ヒットがあるかどうかを示す値を取得します。 //IsSideways bool //グリフを回転するかどうかを示す値を取得または設定します。 //Language XmlLanguage //XmlLanguage の GlyphRun を取得または設定します。 //PixelsPerDip Single //テキストを表示する PixelsPerDip を取得または設定します。 //メソッド //BuildGeometry // GlyphRunのジオメトリを取得します。 //ComputeAlignmentBox Rect // GlyphRunの配置ボックスを取得します。 //ComputeInkBoundingBox Rect // GlyphRunのインク境界ボックスを取得します。 //GetCaretCharacterHitFromDistance(Double, Boolean) CharacterHitグリフラン内でヒットした文字に関する情報を表します。 // GlyphRunのキャレットの文字ヒットを表すCharacterHit値を取得します。 //GetDistanceFromCaretCharacterHit(CharacterHit) double // GlyphRunの前縁から、指定された文字ヒットを含むキャレットストップの前縁または後縁までのオフセットを取得します。 //GetNextCaretCharacterHit(CharacterHit) CharacterHit // GlyphRunで論理方向にヒットした次の有効なキャレット文字を取得します。 //GetPreviousCaretCharacterHit(CharacterHit) CharacterHit // GlyphRunで論理方向にヒットした前の有効なキャレット文字を取得します。 }
// Token: 0x0600350F RID: 13583 RVA: 0x000F0670 File Offset: 0x000EE870 private bool IntersectGlyphs(Glyphs g, double top, double left, double bottom, double right, out int begin, out int end, out bool includeEnd, out double baseline, out double height) { begin = 0; end = 0; includeEnd = false; GlyphRun glyphRun = g.ToGlyphRun(); Rect rect = glyphRun.ComputeAlignmentBox(); rect.Offset(glyphRun.BaselineOrigin.X, glyphRun.BaselineOrigin.Y); baseline = glyphRun.BaselineOrigin.Y; height = rect.Height; double y = rect.Y + 0.5 * rect.Height; GeneralTransform generalTransform = g.TransformToAncestor(this._page); Point point; generalTransform.TryTransform(new Point(rect.Left, y), out point); Point point2; generalTransform.TryTransform(new Point(rect.Right, y), out point2); bool flag = false; if (point.X < left) { if (point2.X < left) { return(false); } flag = true; } else if (point.X > right) { if (point2.X > right) { return(false); } flag = true; } else if (point2.X < left || point2.X > right) { flag = true; } double num3; double num4; if (flag) { double num = (left - point.X) / (point2.X - point.X); double num2 = (right - point.X) / (point2.X - point.X); if (num2 > num) { num3 = num; num4 = num2; } else { num3 = num2; num4 = num; } } else { num3 = 0.0; num4 = 1.0; } flag = false; if (point.Y < top) { if (point2.Y < top) { return(false); } flag = true; } else if (point.Y > bottom) { if (point2.Y > bottom) { return(false); } flag = true; } else if (point2.Y < top || point2.Y > bottom) { flag = true; } if (flag) { double num5 = (top - point.Y) / (point2.Y - point.Y); double num6 = (bottom - point.Y) / (point2.Y - point.Y); if (num6 > num5) { if (num5 > num3) { num3 = num5; } if (num6 < num4) { num4 = num6; } } else { if (num6 > num3) { num3 = num6; } if (num5 < num4) { num4 = num5; } } } num3 = rect.Left + rect.Width * num3; num4 = rect.Left + rect.Width * num4; bool ltr = (glyphRun.BidiLevel & 1) == 0; begin = this.GlyphRunHitTest(glyphRun, num3, ltr); end = this.GlyphRunHitTest(glyphRun, num4, ltr); if (begin > end) { int num7 = begin; begin = end; end = num7; } int num8 = (glyphRun.Characters == null) ? 0 : glyphRun.Characters.Count; includeEnd = (end == num8); return(true); }