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(); } }
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 }