示例#1
0
        // This method returns the current glyph run.
        GlyphRun BeginGlyphRun(Rect rectangle, float advance, LayoutBox currentLayoutBox, FormattingSpan formattingSpan, int lineNumber)
        {
            GlyphRun glyphRun = new GlyphRun();

            glyphRun.FormattingSpan = formattingSpan;

            glyphRun.Glyphs = new List <CanvasGlyph>();
            currentLayoutBox.AddGlyphRun(glyphRun);

            return(glyphRun);
        }
示例#2
0
        //
        // Returns the current glyph run, or null if there's no more layout boxes.
        //
        GlyphRun BeginNewLayoutBox(ref int rectangleIndex, List <Rect> rectangles, ref float glyphRunAdvance, ref int wordsPerLine, FormattingSpan formattingSpan, List <LayoutBox> layoutBoxes)
        {
            rectangleIndex++;
            if (rectangleIndex >= rectangles.Count)
            {
                return(null);
            }

            LayoutBox layoutBox = new LayoutBox(rectangles[rectangleIndex]);

            layoutBoxes.Add(layoutBox);

            glyphRunAdvance = 0;
            wordsPerLine    = 0;

            GlyphRun newGlyphRun = BeginGlyphRun(rectangles[rectangleIndex], glyphRunAdvance, layoutBox, formattingSpan, rectangleIndex);

            return(newGlyphRun);
        }
示例#3
0
        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);
        }
示例#4
0
        //
        // Returns the current glyph run, or null if there's no more layout boxes.
        //
        GlyphRun BeginNewLayoutBox(ref int rectangleIndex, List <Rect> rectangles, ref float glyphRunAdvance, ref int wordsPerLine, FormattingSpan formattingSpan, List <GlyphRun> glyphRuns)
        {
            rectangleIndex++;
            if (rectangleIndex >= rectangles.Count)
            {
                return(null);
            }

            glyphRunAdvance = 0;
            wordsPerLine    = 0;

            return(BeginGlyphRun(rectangles[rectangleIndex], glyphRunAdvance, glyphRuns, formattingSpan, rectangleIndex));
        }
示例#5
0
        // This method returns the current glyph run.
        GlyphRun BeginGlyphRun(Rect rectangle, float advance, List <GlyphRun> glyphRuns, FormattingSpan formattingSpan, int lineNumber)
        {
            GlyphRun glyphRun = new GlyphRun();

            glyphRun.FormattingSpan = formattingSpan;

            float glyphRunXPosition = formattingSpan.IsRightToLeft ? (float)rectangle.Right - advance : (float)rectangle.Left + advance;

            glyphRun.Position   = new System.Numerics.Vector2(glyphRunXPosition, (float)rectangle.Bottom);
            glyphRun.Glyphs     = new List <CanvasGlyph>();
            glyphRun.LineNumber = lineNumber;
            glyphRuns.Add(glyphRun);

            return(glyphRun);
        }
示例#6
0
        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);
        }
        //
        // Returns false if there's no more layout boxes.
        //
        bool BeginNewLayoutBox(ref int rectangleIndex, List <Rect> rectangles, ref float glyphRunAdvance, ref int wordsPerLine, FormattingSpan formattingSpan, List <GlyphRun> glyphRuns)
        {
            rectangleIndex++;
            if (rectangleIndex >= rectangles.Count)
            {
                return(false);
            }

            glyphRunAdvance = 0;
            wordsPerLine    = 0;

            BeginGlyphRun(rectangles[rectangleIndex], glyphRunAdvance, glyphRuns, formattingSpan.FontFace, formattingSpan.FontSize, formattingSpan.IsRightToLeft);

            return(true);
        }