List <FormattingSpan> EvaluateFormattingSpans( CanvasTextAnalyzer textAnalyzer, IReadOnlyList <KeyValuePair <CanvasCharacterRange, CanvasScaledFont> > fontRuns, IReadOnlyList <KeyValuePair <CanvasCharacterRange, CanvasAnalyzedScript> > scriptRuns, IReadOnlyList <KeyValuePair <CanvasCharacterRange, CanvasAnalyzedBidi> > bidiRuns, out float maxLineSpacing) { maxLineSpacing = 0; // // Divide up our text space into spans of uniform font face, script and bidi. // List <FormattingSpan> formattingSpans = new List <FormattingSpan>(); FormattingSpanHelper formattingSpanHelper = new FormattingSpanHelper(fontRuns, scriptRuns, bidiRuns); while (!formattingSpanHelper.IsDone()) { var scriptProperties = textAnalyzer.GetScriptProperties(formattingSpanHelper.Script); float fontSize = desiredFontSize * formattingSpanHelper.ScaledFont.ScaleFactor; FormattingSpan formattingSpan = new FormattingSpan(); int[] clusterMap; bool[] isShapedAlone; CanvasGlyphShaping[] glyphShaping; // Evaluate which glyphs comprise the text. formattingSpan.Glyphs = textAnalyzer.GetGlyphs( formattingSpanHelper.Range, formattingSpanHelper.ScaledFont.FontFace, fontSize, false, // isSideways formattingSpanHelper.Bidi.ResolvedLevel % 2 == 1, formattingSpanHelper.Script, "", null, null, out clusterMap, out isShapedAlone, out glyphShaping); formattingSpan.FontFace = formattingSpanHelper.ScaledFont.FontFace; formattingSpan.FontSize = fontSize; formattingSpan.Script = formattingSpanHelper.Script; formattingSpan.ClusterMap = clusterMap; formattingSpan.GlyphShaping = glyphShaping; formattingSpan.Range = formattingSpanHelper.Range; formattingSpan.BidiLevel = formattingSpanHelper.Bidi.ResolvedLevel; formattingSpan.NeedsAdditionalJustificationCharacters = scriptProperties.JustificationCharacter != null; formattingSpans.Add(formattingSpan); // // For text which contains non-uniform font faces, CanvasTextLayout takes the maximum of // all of line spacings and applies it as the overall line spacing. We do the same thing, here. // maxLineSpacing = System.Math.Max(maxLineSpacing, GetLineSpacing(formattingSpan.FontFace, fontSize)); formattingSpanHelper.MoveNext(); } return(formattingSpans); }
List <FormattingSpan> EvaluateFormattingSpans( CanvasTextAnalyzer textAnalyzer, IReadOnlyList <KeyValuePair <CanvasCharacterRange, CanvasScaledFont> > fontRuns, IReadOnlyList <KeyValuePair <CanvasCharacterRange, CanvasAnalyzedScript> > scriptRuns, out float maxLineSpacing) { maxLineSpacing = 0; List <FormattingSpan> formattingSpans = new List <FormattingSpan>(); // // Divide up our text space into spans of uniform font face and uniform script. // foreach (var scriptRun in scriptRuns) { var scriptProperties = textAnalyzer.GetScriptProperties(scriptRun.Value); bool isRightToLeft = IsRightToLeft(scriptProperties.IsoScriptNumber); foreach (var fontRun in fontRuns) { int fontMatchEnd = fontRun.Key.CharacterIndex + fontRun.Key.CharacterCount; int scriptEnd = scriptRun.Key.CharacterIndex + scriptRun.Key.CharacterCount; if (fontRun.Key.CharacterIndex > scriptEnd) { continue; } if (fontMatchEnd < scriptRun.Key.CharacterIndex) { continue; } int rangeStart = System.Math.Max(fontRun.Key.CharacterIndex, scriptRun.Key.CharacterIndex); int rangeEnd = System.Math.Min(fontMatchEnd, scriptEnd); int length = rangeEnd - rangeStart; float fontSize = desiredFontSize * fontRun.Value.ScaleFactor; FormattingSpan formattingSpan = new FormattingSpan(); formattingSpan.IsRightToLeft = isRightToLeft; int[] clusterMap; bool[] isShapedAlone; CanvasGlyphShaping[] glyphShaping; CanvasCharacterRange range = new CanvasCharacterRange { CharacterIndex = rangeStart, CharacterCount = length }; // Evaluate which glyphs comprise the text. formattingSpan.Glyphs = textAnalyzer.GetGlyphs( range, fontRun.Value.FontFace, fontSize, false, // isSideways formattingSpan.IsRightToLeft, scriptRun.Value, "", null, null, out clusterMap, out isShapedAlone, out glyphShaping); formattingSpan.FontFace = fontRun.Value.FontFace; formattingSpan.FontSize = fontSize; formattingSpan.Script = scriptRun.Value; formattingSpan.ClusterMap = clusterMap; formattingSpan.GlyphShaping = glyphShaping; formattingSpan.Range = range; formattingSpan.NeedsAdditionalJustificationCharacters = scriptProperties.JustificationCharacter != null; formattingSpans.Add(formattingSpan); // // For text which contains non-uniform font faces, CanvasTextLayout takes the maximum of // all of line spacings and applies it as the overall line spacing. We do the same thing, here. // maxLineSpacing = System.Math.Max(maxLineSpacing, GetLineSpacing(formattingSpan.FontFace, fontSize)); } } return(formattingSpans); }