コード例 #1
0
ファイル: TextParaClient.cs プロジェクト: sjyanxin/WPFSource
        private ITextPointer NextCaretUnitPositionFromDcpCompositeLines(
            int dcp,
            ITextPointer position,
            LogicalDirection direction, 
            ref PTS.FSTEXTDETAILSFULL textDetails)
        { 
            ErrorHandler.Assert(!PTS.ToBoolean(textDetails.fDropCapPresent), ErrorHandler.NotSupportedDropCap); 

            // Get list of lines 
            PTS.FSLINEDESCRIPTIONCOMPOSITE [] arrayLineDesc;
            PtsHelper.LineListCompositeFromTextPara(PtsContext, _paraHandle.Value, ref textDetails, out arrayLineDesc);

            // Declare next position and set it to initial position 
            ITextPointer nextCaretPosition = position;
 
            // First iterate through lines 
            for (int index = 0; index < arrayLineDesc.Length; index++)
            { 
                PTS.FSLINEDESCRIPTIONCOMPOSITE lineDesc = arrayLineDesc[index];
                if (lineDesc.cElements == 0) { continue; }

                // Get list of line elements. 
                PTS.FSLINEELEMENT [] arrayLineElement;
                PtsHelper.LineElementListFromCompositeLine(PtsContext, ref lineDesc, out arrayLineElement); 
 
                for (int elIndex = 0; elIndex < arrayLineElement.Length; elIndex++)
                { 
                    PTS.FSLINEELEMENT element = arrayLineElement[elIndex];

                    // 'dcp' needs to be within line range. If position points to dcpLim,
                    // it means that the next line starts from such position, hence go to the next line. 
                    if (   ((element.dcpFirst <= dcp) && (element.dcpLim > dcp))
                        || ((element.dcpLim == dcp) && (elIndex == arrayLineElement.Length - 1) && (index == arrayLineDesc.Length - 1))) 
                    { 
                        if (dcp == element.dcpFirst && direction == LogicalDirection.Backward)
                        { 
                            // Beginning of element.
                            if (dcp == 0)
                            {
                                // Assert that this is first elment on first line 
                                Debug.Assert(index == 0);
                                Debug.Assert(elIndex == 0); 
                                return position; 
                            }
                            else 
                            {
                                if (elIndex > 0)
                                {
                                    // Beginning of element, but not of line 
                                    --elIndex;
                                    element = arrayLineElement[elIndex]; 
                                } 
                                else
                                { 
                                    // There must be at least one line above this
                                    Debug.Assert(index > 0);

                                    // Go to previous line 
                                    --index;
                                    lineDesc = arrayLineDesc[index]; 
                                    if (lineDesc.cElements == 0) 
                                    {
                                        // Stay in same position 
                                        return position;
                                    }
                                    else
                                    { 

                                        // Get list of line elements. 
                                        PtsHelper.LineElementListFromCompositeLine(PtsContext, ref lineDesc, out arrayLineElement); 
                                        element = arrayLineElement[arrayLineElement.Length - 1];
                                    } 
                                }
                            }
                        }
                        else if (dcp >= element.dcpLim - 1 && direction == LogicalDirection.Forward) 
                        {
                            if (dcp == element.dcpLim) 
                            { 
                                // End of paragraph
                                Debug.Assert(elIndex == arrayLineElement.Length - 1); 
                                Debug.Assert(index == arrayLineDesc.Length - 1);
                                return position;
                            }
                            else if (dcp == element.dcpLim - 1 && elIndex == arrayLineElement.Length - 1 && index == arrayLineDesc.Length - 1) 
                            {
                                // Special end character does not belong to line 
                                return position; 
                            }
                        } 

                        // Create and format line
                        Line line = new Line(Paragraph.StructuralCache.TextFormatterHost, this, Paragraph.ParagraphStartCharacterPosition);
                        Line.FormattingContext ctx = new Line.FormattingContext(false, PTS.ToBoolean(element.fClearOnLeft), PTS.ToBoolean(element.fClearOnRight), TextParagraph.TextRunCache); 

                        if(IsOptimalParagraph) 
                        { 
                            ctx.LineFormatLengthTarget = element.dcpLim - element.dcpFirst;
                        } 

                        TextParagraph.FormatLineCore(line, element.pfsbreakreclineclient, ctx, element.dcpFirst, element.dur, PTS.ToBoolean(lineDesc.fTreatedAsFirst), element.dcpFirst);

                        // Assert that number of characters in Text line is the same as our expected length 
                        Invariant.Assert(line.SafeLength == element.dcpLim - element.dcpFirst, "Line length is out of [....]");
 
                        // Create CharacterHit from dcp, and get next 
                        CharacterHit charHit = new CharacterHit(dcp, 0);
                        CharacterHit nextCharacterHit; 
                        if (direction == LogicalDirection.Forward)
                        {
                            nextCharacterHit = line.GetNextCaretCharacterHit(charHit);
                        } 
                        else
                        { 
                            nextCharacterHit = line.GetPreviousCaretCharacterHit(charHit); 
                        }
 
                        LogicalDirection logicalDirection;
                        if ((nextCharacterHit.FirstCharacterIndex + nextCharacterHit.TrailingLength == element.dcpLim) && direction == LogicalDirection.Forward)
                        {
                            // Going forward brought us to the end of a line, context must be forward for next line 
                            if (index == arrayLineDesc.Length - 1)
                            { 
                                // last line so context must stay backward 
                                logicalDirection = LogicalDirection.Backward;
                            } 
                            else
                            {
                                // It is a new element, on the same line or a new one. Either way it;s forward context
                                logicalDirection = LogicalDirection.Forward; 
                            }
                        } 
                        else if ((nextCharacterHit.FirstCharacterIndex + nextCharacterHit.TrailingLength == element.dcpFirst) && direction == LogicalDirection.Backward) 
                        {
                            // Going forward brought us to the start of a line, context must be backward for previous line 
                            if (index == 0)
                            {
                                // First line, so we will stay forward
                                logicalDirection = LogicalDirection.Forward; 
                            }
                            else 
                            { 
                                // Either the previous element or last element on previous line, context is backward
                                logicalDirection = LogicalDirection.Backward; 
                            }
                        }
                        else
                        { 
                            logicalDirection = (nextCharacterHit.TrailingLength > 0) ? LogicalDirection.Backward : LogicalDirection.Forward;
                        } 
                        nextCaretPosition = GetTextPosition(nextCharacterHit.FirstCharacterIndex + nextCharacterHit.TrailingLength, logicalDirection); 

                        // Dispose the line 
                        line.Dispose();
                        return nextCaretPosition;
                    }
                } 
            }
            return nextCaretPosition; 
        } 
コード例 #2
0
ファイル: TextParaClient.cs プロジェクト: sjyanxin/WPFSource
        private ITextPointer NextCaretUnitPositionFromDcpSimpleLines(
            int dcp,
            ITextPointer position,
            LogicalDirection direction, 
            ref PTS.FSTEXTDETAILSFULL textDetails)
        { 
            ErrorHandler.Assert(!PTS.ToBoolean(textDetails.fDropCapPresent), ErrorHandler.NotSupportedDropCap); 

            // Get list of lines 
            PTS.FSLINEDESCRIPTIONSINGLE[] arrayLineDesc;
            PtsHelper.LineListSimpleFromTextPara(PtsContext, _paraHandle.Value, ref textDetails, out arrayLineDesc);

            // Declare next position and set it to initial position 
            ITextPointer nextCaretPosition = position;
 
            // First iterate through lines 
            for (int index = 0; index < arrayLineDesc.Length; index++)
            { 
                PTS.FSLINEDESCRIPTIONSINGLE lineDesc = arrayLineDesc[index];

                // 'dcp' needs to be within line range. If position points to dcpLim,
                // it means that the next line starts from such position, hence go to the next line. 
                if (((lineDesc.dcpFirst <= dcp) && (lineDesc.dcpLim > dcp))
                    || ((lineDesc.dcpLim == dcp) && (index == arrayLineDesc.Length - 1))) 
                { 
                    if (dcp == lineDesc.dcpFirst && direction == LogicalDirection.Backward)
                    { 
                        // Go to previous line
                        if (index == 0)
                        {
                            return position; 
                        }
                        else 
                        { 
                            // Update dcp, lineDesc
                            Debug.Assert(index > 0); 
                            --index;
                            lineDesc = arrayLineDesc[index];
                        }
                    } 
                    else if (dcp >= lineDesc.dcpLim - 1 && direction == LogicalDirection.Forward)
                    { 
                        // If we are at the last line there will be a fake marker for this, so we return 
                        if (index == arrayLineDesc.Length - 1)
                        { 
                            return position;
                        }
                    }
 
                    // Create and format line
                    Line line = new Line(Paragraph.StructuralCache.TextFormatterHost, this, Paragraph.ParagraphStartCharacterPosition); 
                    Line.FormattingContext ctx = new Line.FormattingContext(false, PTS.ToBoolean(lineDesc.fClearOnLeft), PTS.ToBoolean(lineDesc.fClearOnRight), TextParagraph.TextRunCache); 

                    if(IsOptimalParagraph) 
                    {
                        ctx.LineFormatLengthTarget = lineDesc.dcpLim - lineDesc.dcpFirst;
                    }
 
                    TextParagraph.FormatLineCore(line, lineDesc.pfsbreakreclineclient, ctx, lineDesc.dcpFirst, lineDesc.dur, PTS.ToBoolean(lineDesc.fTreatedAsFirst), lineDesc.dcpFirst);
 
                    // Assert that number of characters in Text line is the same as our expected length 
                    Invariant.Assert(line.SafeLength == lineDesc.dcpLim - lineDesc.dcpFirst, "Line length is out of [....]");
 
                    // Create CharacterHit
                    CharacterHit charHit = new CharacterHit(dcp, 0);

                    // Get previous caret position from the line 
                    // Determine logical direction for next caret index and create TextPointer from it
                    CharacterHit nextCharacterHit; 
                    if (direction == LogicalDirection.Forward) 
                    {
                        nextCharacterHit = line.GetNextCaretCharacterHit(charHit); 
                    }
                    else
                    {
                        nextCharacterHit = line.GetPreviousCaretCharacterHit(charHit); 
                    }
 
                    LogicalDirection logicalDirection; 
                    if ((nextCharacterHit.FirstCharacterIndex + nextCharacterHit.TrailingLength == lineDesc.dcpLim) && direction == LogicalDirection.Forward)
                    { 
                        // Going forward brought us to the end of a line, context must be forward for next line
                        if (index == arrayLineDesc.Length - 1)
                        {
                            // last line so context must stay backward 
                            logicalDirection = LogicalDirection.Backward;
                        } 
                        else 
                        {
                            logicalDirection = LogicalDirection.Forward; 
                        }
                    }
                    else if ((nextCharacterHit.FirstCharacterIndex + nextCharacterHit.TrailingLength == lineDesc.dcpFirst) && direction == LogicalDirection.Backward)
                    { 
                        // Going forward brought us to the start of a line, context must be backward for previous line
                        if (index == 0) 
                        { 
                            // First line, so we will stay forward
                            logicalDirection = LogicalDirection.Forward; 
                        }
                        else
                        {
                            logicalDirection = LogicalDirection.Backward; 
                        }
                    } 
                    else 
                    {
                        logicalDirection = (nextCharacterHit.TrailingLength > 0) ? LogicalDirection.Backward : LogicalDirection.Forward; 
                    }
                    nextCaretPosition = GetTextPosition(nextCharacterHit.FirstCharacterIndex + nextCharacterHit.TrailingLength, logicalDirection);

                    // Dispose the line 
                    line.Dispose();
                    break; 
                } 
            }
            return nextCaretPosition; 
        }