Exemplo n.º 1
0
        /// <summary>
        /// Analyzes the text using each of the analyzers and returns 
        /// their results as a series of runs.
        /// </summary>
        public void GenerateResults(TextAnalyzer textAnalyzer, out Run[] runs, out LineBreakpoint[] breakpoints)
        {
            // Initially start out with one result that covers the entire range.
            // This result will be subdivided by the analysis processes.
            LinkedRun initialRun = new LinkedRun()
            {
                nextRunIndex = 0,
                textStart = 0,
                textLength = text_.Length,
                bidiLevel = (readingDirection_ == ReadingDirection.RightToLeft) ? 1 : 0
            };
            runs_ = new List<LinkedRun>();
            runs_.Add(initialRun);

            breakpoints_ = new List<LineBreakpoint>();

            textAnalyzer.AnalyzeLineBreakpoints(this, 0, text_.Length, this);
            textAnalyzer.AnalyzeBidi(this, 0, text_.Length, this);
            textAnalyzer.AnalyzeScript(this, 0, text_.Length, this);
            textAnalyzer.AnalyzeNumberSubstitution(this, 0, text_.Length, this);
             //Call each of the analyzers in sequence, recording their results.
            breakpoints = new LineBreakpoint[breakpoints_.Count];
            breakpoints_.CopyTo(breakpoints);

            // Resequence the resulting runs in order before returning to caller.
            runs = new Run[runs_.Count];
            int nextRunIndex = 0;
            for (int i = 0; i < runs_.Count; i++)
            {
                runs[i] = runs_[nextRunIndex].AsRun;
                nextRunIndex = runs_[nextRunIndex].nextRunIndex;
            }
        }
Exemplo n.º 2
0
        /// <summary>
        ///   This constructor initializes a new instance of this class.
        /// </summary>
        /// <param name="factory"> This parameter references the DirectWrite factory. </param>
        public Analyzer(Factory factory)
        {
            Contract.Requires(factory != null);

            _Characters = new CharacterProperties[0];

            _TextAnalyzer = new TextAnalyzer(factory);
        }
Exemplo n.º 3
0
        public TextAnalyzer(FontDevice fontDevice, TextTextShaper textShaper)
        {
            Contract.Requires(fontDevice != null);

            _TextAnalyzer = new SharpDX.DirectWrite.TextAnalyzer(fontDevice.Factory);

            _TextShaper = textShaper;
        }
Exemplo n.º 4
0
        /// <summary>
        /// Initializes a new instance of the <see cref="NeovimControl"/> class.
        /// </summary>
        /// <param name="parent">The parent control.</param>
        /// <param name="neovimClient">the neovim client.</param>
        public NeovimControl(IElement parent, NeovimClient.NeovimClient neovimClient)
            : base(parent)
        {
            this.neovimClient              = neovimClient;
            this.neovimClient.Redraw      += this.Invalidate;
            this.neovimClient.FontChanged += this.OnFontChanged;

            this.textAnalyzer        = new DWrite.TextAnalyzer(this.factoryDWrite);
            this.cursorEffects       = new CursorEffects(this.DeviceContext);
            this.brushCache          = new BrushCache();
            this.scriptAnalysesCache = new ScriptAnalysesCache();
            this.fontCache           = new FontCache(this.factoryDWrite);

            this.textParam = new TextLayoutParameters(
                this.factoryDWrite,
                "Consolas",
                11,
                false,
                false,
                false,
                false,
                this.Factory.DesktopDpi);
        }
Exemplo n.º 5
0
        protected override void Dispose(bool disposing)
        {
            if(disposing)
            {
                _TextAnalyzer.Dispose();

                _TextAnalyzer = null;
            }

            base.Dispose(disposing);
        }
Exemplo n.º 6
0
        protected void ShapeGlyphRun(TextAnalyzer textAnalyzer, int runIndex, ref int glyphStart)
        {
            // Shapes a single run of text into glyphs.
            // Alternately, you could iteratively interleave shaping and line
            // breaking to reduce the number glyphs held onto at once. It's simpler
            // for this demostration to just do shaping and line breaking as two
            // separate processes, but realize that this does have the consequence that
            // certain advanced fonts containing line specific features (like Gabriola)
            // will shape as if the line is not broken.

            Run run = runs_[runIndex];
            int textStart = run.textStart;
            int textLength = run.textLength;
            int maxGlyphCount = glyphIndices_.Length - glyphStart;
            int actualGlyphCount = 0;

            run.glyphStart = glyphStart;
            run.glyphCount = 0;

            if (textLength == 0)
                return;// Nothing to do..

            // Allocate space for shaping to fill with glyphs and other information,
            // with about as many glyphs as there are text characters. We'll actually
            // need more glyphs than codepoints if they are decomposed into separate
            // glyphs, or fewer glyphs than codepoints if multiple are substituted
            // into a single glyph. In any case, the shaping process will need some
            // room to apply those rules to even make that determintation.

            if (textLength > maxGlyphCount)
            {
                maxGlyphCount = EstimateGlyphCount(textLength);
                int totalGlyphsArrayCount = glyphStart + maxGlyphCount;
                short[] Resized_glyphIndices_ = new short[totalGlyphsArrayCount];
                glyphIndices_.CopyTo(Resized_glyphIndices_, 0);
                glyphIndices_ = Resized_glyphIndices_;
            }


            ShapingTextProperties[] textProps = new ShapingTextProperties[textLength];
            ShapingGlyphProperties[] glyphProps = new ShapingGlyphProperties[maxGlyphCount];

            // Get the glyphs from the text, retrying if needed.
            int tries = 0;
            while (tries < 2)// We'll give it two chances.
            {
                short[] call_glyphClusters_ = new short[glyphClusters_.Length - textStart];
                short[] call_glyphIndices_ = new short[glyphIndices_.Length - glyphStart];

                bool isDone = false;
                try
                {
                    textAnalyzer.GetGlyphs(
                        text_.Substring(textStart, textLength),
                        textLength,
                        fontFace_,
                        run.isSideways,
                        (run.bidiLevel % 2 == 1),
                        run.script,
                        localName_,
                        run.isNumberSubstituted ? numberSubstitution_ : null,
                        null,
                        null,
                        maxGlyphCount,
                        call_glyphClusters_,
                        textProps,
                        call_glyphIndices_,
                        glyphProps,
                        out actualGlyphCount);
                    Array.Copy(call_glyphClusters_, 0, glyphClusters_, textStart, call_glyphClusters_.Length);
                    Array.Copy(call_glyphIndices_, 0, glyphIndices_, glyphStart, call_glyphIndices_.Length);
                    isDone = true;
                }
                finally
                {
                    tries++;
                    // Try again using a larger buffer.
                    maxGlyphCount = EstimateGlyphCount(maxGlyphCount);
                    int totalGlyphsArrayCount = glyphStart + maxGlyphCount;

                    glyphProps = new ShapingGlyphProperties[maxGlyphCount];
                    glyphIndices_ = new short[totalGlyphsArrayCount];
                }
                if (isDone)
                    break;
            }

            // Get the placement of the all the glyphs.
            if (glyphAdvances_.Length < glyphStart + actualGlyphCount)
            {
                float[] Resized_glyphAdvances_ = new float[glyphStart + actualGlyphCount];
                glyphAdvances_.CopyTo(Resized_glyphAdvances_, 0);
                glyphAdvances_ = Resized_glyphAdvances_;
            }
            if (glyphOffsets_.Length < glyphStart + actualGlyphCount)
            {
                GlyphOffset[] Resized_glyphOffsets_ = new GlyphOffset[glyphStart + actualGlyphCount];
                glyphOffsets_.CopyTo(Resized_glyphOffsets_, 0);
                glyphOffsets_ = Resized_glyphOffsets_;
            }

            short[] call2_glyphClusters_ = new short[glyphClusters_.Length - textStart];
            Array.Copy(glyphClusters_, textStart, call2_glyphClusters_, 0, call2_glyphClusters_.Length);
            short[] call2_glyphIndices_ = new short[glyphIndices_.Length - glyphStart];
            Array.Copy(glyphIndices_, glyphStart, call2_glyphIndices_, 0, call2_glyphIndices_.Length);
            float[] call2_glyphAdvances_ = new float[glyphAdvances_.Length - glyphStart];
            Array.Copy(glyphAdvances_, glyphStart, call2_glyphAdvances_, 0, call2_glyphAdvances_.Length);
            GlyphOffset[] call2_glyphOffsets_ = new GlyphOffset[glyphOffsets_.Length - glyphStart];
            Array.Copy(glyphOffsets_, glyphStart, call2_glyphOffsets_, 0, call2_glyphOffsets_.Length);

            textAnalyzer.GetGlyphPlacements(
                text_.Substring(textStart, textLength),
                call2_glyphClusters_,
                textProps,
                textLength,
                call2_glyphIndices_,
                glyphProps,
                actualGlyphCount,
                fontFace_,
                fontEmSize_,
                run.isSideways,
                run.bidiLevel % 2 == 1,
                run.script,
                localName_,
                null,
                null,
                call2_glyphAdvances_,
                call2_glyphOffsets_);
            //call2_glyphClusters_.CopyTo(glyphClusters_, textStart);
            call2_glyphAdvances_.CopyTo(glyphAdvances_, glyphStart);
            call2_glyphOffsets_.CopyTo(glyphOffsets_, glyphStart);

            // Certain fonts, like Batang, contain glyphs for hidden control
            // and formatting characters. So we'll want to explicitly force their
            // advance to zero.
            if (run.script.Shapes == ScriptShapes.NoVisual)
            {
                for (int i = glyphStart; i < glyphStart + actualGlyphCount; i++)
                    glyphAdvances_[i] = 0;
            }

            // Set the final glyph count of this run and advance the starting glyph.
            run.glyphCount = actualGlyphCount;
            runs_[runIndex] = run;
            glyphStart += actualGlyphCount;
        }
Exemplo n.º 7
0
        protected void ShapeGlyphRuns(TextAnalyzer textAnalyzer)
        {
            // Shapes all the glyph runs in the layout.

            // Estimate the maximum number of glyph indices needed to hold a string.
            int estimatedGlyphCount = EstimateGlyphCount(text_.Length);

            glyphIndices_ = new short[estimatedGlyphCount];
            glyphOffsets_ = new GlyphOffset[estimatedGlyphCount];
            glyphAdvances_ = new float[estimatedGlyphCount];
            glyphClusters_ = new short[text_.Length];

            int glyphStart = 0;

            // Shape each run separately. This is needed whenever script, locale,
            // or reading direction changes.
            for (int runIndex = 0; runIndex < runs_.Length; runIndex++)
            {
                ShapeGlyphRun(textAnalyzer, runIndex, ref glyphStart);
            }

            short[] resized_glyphIndices_ = new short[glyphStart];
            Array.Copy(glyphIndices_, 0, resized_glyphIndices_, 0, glyphStart);
            glyphIndices_ = resized_glyphIndices_;

            GlyphOffset[] resized_glyphOffsets_ = new GlyphOffset[glyphStart];
            Array.Copy(glyphOffsets_, 0, resized_glyphOffsets_, 0, glyphStart);
            glyphOffsets_ = resized_glyphOffsets_;

            float[] resized_glyphAdvances_ = new float[glyphStart];
            Array.Copy(glyphAdvances_, 0, resized_glyphAdvances_, 0, glyphStart);
            glyphAdvances_ = resized_glyphAdvances_;

        }
Exemplo n.º 8
0
        public void AnalyzeText(String text)
        {
            // Perform analysis on the given text, converting text to glyphs.

            // Analyzes the given text and keeps the results for later reflow.
            isTextAnalysisComplete_ = false;

            // Need a font face to determine metrics.
            if (fontFace_ == null)
                throw new Exception("FlowLayout: Need a font face to determine metrics.");

            text_ = text;

            // Query for the text analyzer's interface.
            TextAnalyzer textAnalyzer = new TextAnalyzer(dwriteFactory_);

            // Record the analyzer's results.
            TextAnalysis textAnalysis = new TextAnalysis(text_, localName_, readingDirection_, numberSubstitution_);
            textAnalysis.GenerateResults(textAnalyzer, out runs_, out breakpoints_);

            // Convert the entire text to glyphs.
            ShapeGlyphRuns(textAnalyzer);

            isTextAnalysisComplete_ = true;

            textAnalyzer.Dispose();
        }