Example #1
0
        internal static void UpdateTrackVisuals(
            PtsContext ptsContext,
            VisualCollection visualCollection,
            PTS.FSKUPDATE fskupdInherited,
            ref PTS.FSTRACKDESCRIPTION trackDesc)
        {
            PTS.FSKUPDATE fskupd = trackDesc.fsupdinf.fskupd;
            if (trackDesc.fsupdinf.fskupd == PTS.FSKUPDATE.fskupdInherited)
            {
                fskupd = fskupdInherited;
            }

            // If there is no change, visual information is valid
            if (fskupd == PTS.FSKUPDATE.fskupdNoChange) { return; }
            ErrorHandler.Assert(fskupd != PTS.FSKUPDATE.fskupdShifted, ErrorHandler.UpdateShiftedNotValid);

            bool emptyTrack = (trackDesc.pfstrack == IntPtr.Zero);
            if (!emptyTrack)
            {
                // Get track details
                PTS.FSTRACKDETAILS trackDetails;
                PTS.Validate(PTS.FsQueryTrackDetails(ptsContext.Context, trackDesc.pfstrack, out trackDetails));

                emptyTrack = (trackDetails.cParas == 0);
                if (!emptyTrack)
                {
                    // Get list of paragraphs
                    PTS.FSPARADESCRIPTION[] arrayParaDesc;
                    ParaListFromTrack(ptsContext, trackDesc.pfstrack, ref trackDetails, out arrayParaDesc);

                    // Update visuals for list of paragraphs
                    UpdateParaListVisuals(ptsContext, visualCollection, fskupd, arrayParaDesc);
                }
            }

            // There is possibility to get empty track. (example: large figures)
            if (emptyTrack)
            {
                // There is no content, remove all existing children visuals.
                visualCollection.Clear();
            }
        }
Example #2
0
        private void SyncUpdateDeferredLineVisuals(VisualCollection lineVisuals, ref PTS.FSTEXTDETAILSFULL textDetails, bool ignoreUpdateInfo) 
        { 
            Debug.Assert(!PTS.ToBoolean(textDetails.fLinesComposite));
 
            try
            {
                if (!PTS.ToBoolean(textDetails.fUpdateInfoForLinesPresent) || ignoreUpdateInfo)
                { 
                    // _lineIndexFirstVisual will be updated based on the size of this list, so clearing is sufficient here.
                    lineVisuals.Clear(); 
                } 
                else if (_lineIndexFirstVisual != -1)
                { 
                    PTS.FSLINEDESCRIPTIONSINGLE[] arrayLineDesc;
                    PtsHelper.LineListSimpleFromTextPara(PtsContext, _paraHandle.Value, ref textDetails, out arrayLineDesc);

                    int lineIndexToBeginRemoval = textDetails.cLinesBeforeChange; 
                    int cLinesToRemove = textDetails.cLinesChanged - textDetails.dcLinesChanged;
                    int insertionIndex = -1; 
 
                    // Shift lines before change
                    if(textDetails.dvrShiftBeforeChange != 0) 
                    {
                        int countVisualsShiftBeforeChange = Math.Min(Math.Max(lineIndexToBeginRemoval - _lineIndexFirstVisual, 0), lineVisuals.Count);
                        for(int index = 0; index < countVisualsShiftBeforeChange; index++)
                        { 
                            // Shift line's visual
                            ContainerVisual lineVisual = (ContainerVisual) lineVisuals[index]; 
                            Vector offset = lineVisual.Offset; 
                            offset.Y += TextDpi.FromTextDpi(textDetails.dvrShiftBeforeChange);
                            lineVisual.Offset = offset; 
                        }
                    }

                    // If the line index to begin removal is before our first visual, then the overlap will look like 
                    //      |---------------|  (Committed visual range)
                    // |------|                (Range to remove) 
                    if (lineIndexToBeginRemoval < _lineIndexFirstVisual) 
                    {
                        // Determine the amount of overlap, and remove. 
                        int actualLinesToRemove = Math.Min(Math.Max(lineIndexToBeginRemoval - _lineIndexFirstVisual + cLinesToRemove, 0), lineVisuals.Count);

                        if (actualLinesToRemove > 0)
                        { 
                            lineVisuals.RemoveRange(0, actualLinesToRemove);
                        } 
 
                        if (lineVisuals.Count == 0)
                        { 
                            lineVisuals.Clear();
                            _lineIndexFirstVisual = -1;
                        }
                        else 
                        {
                            insertionIndex = 0; 
                            _lineIndexFirstVisual = lineIndexToBeginRemoval; 
                        }
                    } 
                    else if (lineIndexToBeginRemoval < _lineIndexFirstVisual + lineVisuals.Count)
                    {
                        // Else case for overlap
                        //  |---------------|  (Committed visual range) 
                        //       |-----|                (Range to remove)
                        // Or 
                        //  |---------------| 
                        //           |--------------|
 
                        // Removing from the middle
                        int actualLinesToRemove = Math.Min(cLinesToRemove, lineVisuals.Count - (lineIndexToBeginRemoval - _lineIndexFirstVisual));

                        lineVisuals.RemoveRange(lineIndexToBeginRemoval - _lineIndexFirstVisual, actualLinesToRemove); 

                        insertionIndex = lineIndexToBeginRemoval - _lineIndexFirstVisual; // Insertion index is relative to committed visual range 
                    } 

                    int shiftIndex = -1; 

                    if (insertionIndex != -1)
                    {
                        // Add new lines 
                        // Insertion must occur at some point along our committed visual range
                        Debug.Assert(insertionIndex >= 0 && insertionIndex <= lineVisuals.Count); 
 
                        for (int index = textDetails.cLinesBeforeChange; index < textDetails.cLinesBeforeChange + textDetails.cLinesChanged; index++)
                        { 
                            PTS.FSLINEDESCRIPTIONSINGLE lineDesc = arrayLineDesc[index];

                            ContainerVisual lineVisual = CreateLineVisual(ref arrayLineDesc[index], Paragraph.ParagraphStartCharacterPosition);
 
                            lineVisuals.Insert(insertionIndex + (index - textDetails.cLinesBeforeChange), lineVisual);
                            lineVisual.Offset = new Vector(TextDpi.FromTextDpi(lineDesc.urStart), TextDpi.FromTextDpi(lineDesc.vrStart)); 
                        } 

                        shiftIndex = insertionIndex + textDetails.cLinesChanged; 
                    }

                    // Any committed visuals after our inserted section must be shifted
                    if (shiftIndex != -1) 
                    {
                        // Shift remaining lines 
                        for (int index = shiftIndex; index < lineVisuals.Count; index++) 
                        {
                            // Shift line's visual 
                            ContainerVisual lineVisual = (ContainerVisual) lineVisuals[index];
                            Vector offset = lineVisual.Offset;
                            offset.Y += TextDpi.FromTextDpi(textDetails.dvrShiftAfterChange);
                            lineVisual.Offset = offset; 
                        }
                    } 
                } 
            }
 
            finally
            {
                // If no visuals, committed range is nonexistant, so -1
                if (lineVisuals.Count == 0) 
                {
                    _lineIndexFirstVisual = -1; 
                } 
            }
 
#if VERIFY_VISUALS
            // Verify our visuals are in-[....] with the actual line visuals.
            VerifyVisuals(ref textDetails);
#endif 
        }