Example #1
0
        // ------------------------------------------------------------------
        // Calculates a page margin adjustment to eliminate free space if column width is not flexible
        // ------------------------------------------------------------------
        internal static double CalculatePageMarginAdjustment(StructuralCache structuralCache, double pageMarginWidth)
        {
            double pageMarginAdjustment = 0.0;

            DependencyObject o = structuralCache.Section.Element;

            if (o is FlowDocument)
            {
                ColumnPropertiesGroup columnProperties = new ColumnPropertiesGroup(o);

                if (!columnProperties.IsColumnWidthFlexible)
                {
                    double     lineHeight     = DynamicPropertyReader.GetLineHeightValue(o);
                    double     pageFontSize   = (double)structuralCache.PropertyOwner.GetValue(Block.FontSizeProperty);
                    FontFamily pageFontFamily = (FontFamily)structuralCache.PropertyOwner.GetValue(Block.FontFamilyProperty);

                    int ccol = PtsHelper.CalculateColumnCount(columnProperties, lineHeight, pageMarginWidth, pageFontSize, pageFontFamily, true);

                    double columnWidth;
                    double freeSpace;
                    double gap;

                    GetColumnMetrics(columnProperties, pageMarginWidth,
                                     pageFontSize, pageFontFamily, true, ccol,
                                     ref lineHeight, out columnWidth, out freeSpace, out gap);

                    pageMarginAdjustment = freeSpace;
                }
            }

            return(pageMarginAdjustment);
        }
Example #2
0
        /// <summary>
        /// Enable the TextEffect on the target. If the texteffect is
        /// already enabled, this will be a no-op.
        /// </summary>
        public void Enable()
        {
            TextEffectCollection textEffects = DynamicPropertyReader.GetTextEffects(_element);

            if (textEffects == null)
            {
                textEffects = new TextEffectCollection();

                // use it as reference to avoid creating a copy (Freezable pattern)
                _element.SetValue(TextElement.TextEffectsProperty, textEffects);
            }


            // check whether this instance is already enabled
            for (int i = 0; i < textEffects.Count; i++)
            {
                if (textEffects[i] == _effect)
                {
                    return; // no-op
                }
            }

            // use this as reference.
            textEffects.Add(_effect);
        }
Example #3
0
        // ------------------------------------------------------------------
        // Returns calculated column information -  count, width, gap and rule.
        // ------------------------------------------------------------------
        internal static void GetColumnMetrics(StructuralCache structuralCache, out int cColumns, out double width, out double gap, out double rule)
        {
            ColumnPropertiesGroup columnProperties = new ColumnPropertiesGroup(structuralCache.PropertyOwner);
            FontFamily            pageFontFamily   = (FontFamily)structuralCache.PropertyOwner.GetValue(Block.FontFamilyProperty);
            double    lineHeight   = DynamicPropertyReader.GetLineHeightValue(structuralCache.PropertyOwner);
            double    pageFontSize = (double)structuralCache.PropertyOwner.GetValue(Block.FontSizeProperty);
            Size      pageSize     = structuralCache.CurrentFormatContext.PageSize;
            Thickness pageMargin   = structuralCache.CurrentFormatContext.PageMargin;
            double    pageWidth    = pageSize.Width - (pageMargin.Left + pageMargin.Right);

            cColumns = PtsHelper.CalculateColumnCount(columnProperties, lineHeight, pageWidth, pageFontSize, pageFontFamily, true);

            double freeSpace;

            rule = columnProperties.ColumnRuleWidth;
            PtsHelper.GetColumnMetrics(columnProperties, pageWidth,
                                       pageFontSize, pageFontFamily, true, cColumns,
                                       ref lineHeight, out width, out freeSpace, out gap);

            if (columnProperties.IsColumnWidthFlexible && columnProperties.ColumnSpaceDistribution == ColumnSpaceDistribution.Between)
            {
                width += freeSpace / cColumns;
            }

            width = Math.Min(width, pageWidth);
        }
 // Token: 0x0600674C RID: 26444 RVA: 0x001CDE1C File Offset: 0x001CC01C
 protected void GetParaProperties(ref PTS.FSPAP fspap, bool ignoreElementProps)
 {
     if (!ignoreElementProps)
     {
         fspap.fKeepWithNext      = PTS.FromBoolean(DynamicPropertyReader.GetKeepWithNext(this._element));
         fspap.fBreakPageBefore   = ((this._element is Block) ? PTS.FromBoolean(this.StructuralCache.CurrentFormatContext.FinitePage && ((Block)this._element).BreakPageBefore) : PTS.FromBoolean(false));
         fspap.fBreakColumnBefore = ((this._element is Block) ? PTS.FromBoolean(((Block)this._element).BreakColumnBefore) : PTS.FromBoolean(false));
     }
 }
Example #5
0
        //-------------------------------------------------------------------
        //
        //  Protected Methods
        //
        //-------------------------------------------------------------------

        #region Protected Methods

        /// <summary>
        /// Retrieve PTS paragraph properties.
        /// </summary>
        /// <param name="fspap">
        /// Paragraph properties to initialize.
        /// </param>
        /// <param name="ignoreElementProps">
        /// Ignore element properties?
        /// </param>
        protected void GetParaProperties(ref PTS.FSPAP fspap, bool ignoreElementProps)
        {
            if (!ignoreElementProps)
            {
                fspap.fKeepWithNext = PTS.FromBoolean(DynamicPropertyReader.GetKeepWithNext(_element));
                // Can be broken only if Block.BreakPageBefore is set
                fspap.fBreakPageBefore = _element is Block?PTS.FromBoolean(StructuralCache.CurrentFormatContext.FinitePage && ((Block)_element).BreakPageBefore) : PTS.FromBoolean(false);

                // Can be broken only if Block.BreakColumnBefore is set
                fspap.fBreakColumnBefore = _element is Block?PTS.FromBoolean(((Block)_element).BreakColumnBefore) : PTS.FromBoolean(false);
            }
        }
        internal unsafe void GetSectionColumnInfo(uint fswdir, int ncol, PTS.FSCOLUMNINFO *pfscolinfo, out int ccol)
        {
            ColumnPropertiesGroup columnProperties = new ColumnPropertiesGroup(this.Element);
            Size       pageSize        = this._structuralCache.CurrentFormatContext.PageSize;
            double     lineHeightValue = DynamicPropertyReader.GetLineHeightValue(this.Element);
            Thickness  pageMargin      = this._structuralCache.CurrentFormatContext.PageMargin;
            double     pageFontSize    = (double)this._structuralCache.PropertyOwner.GetValue(TextElement.FontSizeProperty);
            FontFamily pageFontFamily  = (FontFamily)this._structuralCache.PropertyOwner.GetValue(TextElement.FontFamilyProperty);
            bool       finitePage      = this._structuralCache.CurrentFormatContext.FinitePage;

            ccol = ncol;
            PtsHelper.GetColumnsInfo(columnProperties, lineHeightValue, pageSize.Width - (pageMargin.Left + pageMargin.Right), pageFontSize, pageFontFamily, ncol, pfscolinfo, finitePage);
        }
Example #7
0
 // Token: 0x06006B22 RID: 27426 RVA: 0x001EEC70 File Offset: 0x001ECE70
 internal void GetTextProperties(int iArea, ref PTS.FSTXTPROPS fstxtprops)
 {
     fstxtprops.fswdir                              = PTS.FlowDirectionToFswdir((FlowDirection)base.Element.GetValue(FrameworkElement.FlowDirectionProperty));
     fstxtprops.dcpStartContent                     = 0;
     fstxtprops.fKeepTogether                       = PTS.FromBoolean(DynamicPropertyReader.GetKeepTogether(base.Element));
     fstxtprops.cMinLinesAfterBreak                 = DynamicPropertyReader.GetMinOrphanLines(base.Element);
     fstxtprops.cMinLinesBeforeBreak                = DynamicPropertyReader.GetMinWidowLines(base.Element);
     fstxtprops.fDropCap                            = 0;
     fstxtprops.fVerticalGrid                       = 0;
     fstxtprops.fOptimizeParagraph                  = PTS.FromBoolean(this.IsOptimalParagraph);
     fstxtprops.fAvoidHyphenationAtTrackBottom      = 0;
     fstxtprops.fAvoidHyphenationOnLastChainElement = 0;
     fstxtprops.cMaxConsecutiveHyphens              = int.MaxValue;
 }
Example #8
0
        // Token: 0x06004A31 RID: 18993 RVA: 0x0014F45C File Offset: 0x0014D65C
        internal static CultureInfo GetCulture(FrameworkElement element)
        {
            bool        flag;
            CultureInfo result;

            if (element.GetValueSource(FrameworkElement.LanguageProperty, null, out flag) != BaseValueSourceInternal.Default)
            {
                result = DynamicPropertyReader.GetCultureInfo(element);
            }
            else
            {
                result = CultureInfo.CurrentCulture;
            }
            return(result);
        }
        /// <summary> Disables the <see cref="T:System.Windows.Media.TextEffect" /> on the effect target. </summary>
        // Token: 0x06003927 RID: 14631 RVA: 0x00103270 File Offset: 0x00101470
        public void Disable()
        {
            TextEffectCollection textEffects = DynamicPropertyReader.GetTextEffects(this._element);

            if (textEffects != null)
            {
                for (int i = 0; i < textEffects.Count; i++)
                {
                    if (textEffects[i] == this._effect)
                    {
                        textEffects.RemoveAt(i);
                        return;
                    }
                }
            }
        }
        // Token: 0x06004132 RID: 16690 RVA: 0x0012A184 File Offset: 0x00128384
        public override TextSpan <CultureSpecificCharacterBufferRange> GetPrecedingText(int dcp)
        {
            CharacterBufferRange empty   = CharacterBufferRange.Empty;
            CultureInfo          culture = null;

            if (dcp > 0)
            {
                ITextPointer textPointer = this._owner.Host.TextContainer.CreatePointerAtOffset(dcp, LogicalDirection.Backward);
                int          num         = Math.Min(128, textPointer.GetTextRunLength(LogicalDirection.Backward));
                char[]       array       = new char[num];
                textPointer.GetTextInRun(LogicalDirection.Backward, array, 0, num);
                empty   = new CharacterBufferRange(array, 0, num);
                culture = DynamicPropertyReader.GetCultureInfo((Control)this._owner.Host);
            }
            return(new TextSpan <CultureSpecificCharacterBufferRange>(empty.Length, new CultureSpecificCharacterBufferRange(culture, empty)));
        }
Example #11
0
        /// <summary>
        /// Disable TextEffect on the target. If the texteffect is
        /// already disabled, this will be a no-op.
        /// </summary>
        public void Disable()
        {
            TextEffectCollection textEffects = DynamicPropertyReader.GetTextEffects(_element);

            if (textEffects != null)
            {
                for (int i = 0; i < textEffects.Count; i++)
                {
                    if (textEffects[i] == _effect)
                    {
                        // remove the exact instance of the effect from the collection
                        textEffects.RemoveAt(i);
                        return;
                    }
                }
            }
        }
        // Token: 0x06006A41 RID: 27201 RVA: 0x001E3E34 File Offset: 0x001E2034
        internal void GetSectionProperties(out int fNewPage, out uint fswdir, out int fApplyColumnBalancing, out int ccol, out int cSegmentDefinedColumnSpanAreas, out int cHeightDefinedColumnSpanAreas)
        {
            ColumnPropertiesGroup columnProperties = new ColumnPropertiesGroup(this.Element);
            Size       pageSize        = this._structuralCache.CurrentFormatContext.PageSize;
            double     lineHeightValue = DynamicPropertyReader.GetLineHeightValue(this.Element);
            Thickness  pageMargin      = this._structuralCache.CurrentFormatContext.PageMargin;
            double     pageFontSize    = (double)this._structuralCache.PropertyOwner.GetValue(TextElement.FontSizeProperty);
            FontFamily pageFontFamily  = (FontFamily)this._structuralCache.PropertyOwner.GetValue(TextElement.FontFamilyProperty);
            bool       finitePage      = this._structuralCache.CurrentFormatContext.FinitePage;

            fNewPage = 0;
            fswdir   = PTS.FlowDirectionToFswdir((FlowDirection)this._structuralCache.PropertyOwner.GetValue(FrameworkElement.FlowDirectionProperty));
            fApplyColumnBalancing = 0;
            ccol = PtsHelper.CalculateColumnCount(columnProperties, lineHeightValue, pageSize.Width - (pageMargin.Left + pageMargin.Right), pageFontSize, pageFontFamily, finitePage);
            cSegmentDefinedColumnSpanAreas = 0;
            cHeightDefinedColumnSpanAreas  = 0;
        }
Example #13
0
        /// <summary>
        /// Fetch the next run at element end edge position.
        /// ElementEndEdge; we can have 2 possibilities:
        /// (1) Close edge of element associated with the text paragraph,
        ///     create synthetic LineBreak run to end the current line.
        /// (2) End of inline element, hide CloseEdge character and continue
        /// </summary>
        /// <param name="position"></param>
        /// Position in current text array
        protected TextRun HandleElementEndEdge(StaticTextPointer position)
        {
            Invariant.Assert(position.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.ElementEnd, "TextPointer does not point to element end edge.");

            TextRun run;

            if (position.Parent == _paraClient.Paragraph.Element)
            {
                // (1) Close edge of element associated with the text paragraph,
                //     create synthetic LineBreak run to end the current line.
                run = new ParagraphBreakRun(_syntheticCharacterLength, PTS.FSFLRES.fsflrEndOfParagraph);
            }
            else
            {
                TextElement element = (TextElement)position.GetAdjacentElement(LogicalDirection.Forward);
                Debug.Assert(element != null, "Element should be here.");
                Inline           inline = (Inline)element;
                DependencyObject parent = inline.Parent;
                FlowDirection    parentFlowDirection = inline.FlowDirection;

                if (parent != null)
                {
                    parentFlowDirection = (FlowDirection)parent.GetValue(FrameworkElement.FlowDirectionProperty);
                }

                if (inline.FlowDirection != parentFlowDirection)
                {
                    run = new TextEndOfSegment(_elementEdgeCharacterLength);
                }
                else
                {
                    TextDecorationCollection textDecorations = DynamicPropertyReader.GetTextDecorations(inline);
                    if (textDecorations == null || textDecorations.Count == 0)
                    {
                        // (2) End of inline element, hide CloseEdge character and continue
                        run = new TextHidden(_elementEdgeCharacterLength);
                    }
                    else
                    {
                        run = new TextEndOfSegment(_elementEdgeCharacterLength);
                    }
                }
            }
            return(run);
        }
        /// <summary>Enables the <see cref="T:System.Windows.Media.TextEffect" /> on the target text. </summary>
        // Token: 0x06003926 RID: 14630 RVA: 0x00103210 File Offset: 0x00101410
        public void Enable()
        {
            TextEffectCollection textEffectCollection = DynamicPropertyReader.GetTextEffects(this._element);

            if (textEffectCollection == null)
            {
                textEffectCollection = new TextEffectCollection();
                this._element.SetValue(TextElement.TextEffectsProperty, textEffectCollection);
            }
            for (int i = 0; i < textEffectCollection.Count; i++)
            {
                if (textEffectCollection[i] == this._effect)
                {
                    return;
                }
            }
            textEffectCollection.Add(this._effect);
        }
Example #15
0
 // Token: 0x060068B9 RID: 26809 RVA: 0x001D8E68 File Offset: 0x001D7068
 internal static MbpInfo FromElement(DependencyObject o, double pixelsPerDip)
 {
     if (o is Block || o is AnchoredBlock || o is TableCell || o is ListItem)
     {
         MbpInfo mbpInfo         = new MbpInfo((TextElement)o);
         double  lineHeightValue = DynamicPropertyReader.GetLineHeightValue(o);
         if (mbpInfo.IsMarginAuto)
         {
             MbpInfo.ResolveAutoMargin(mbpInfo, o, lineHeightValue);
         }
         if (mbpInfo.IsPaddingAuto)
         {
             MbpInfo.ResolveAutoPadding(mbpInfo, o, lineHeightValue, pixelsPerDip);
         }
         return(mbpInfo);
     }
     return(MbpInfo._empty);
 }
Example #16
0
        /// <summary>
        /// Get text immediately before specified text source position. Return CharacterBufferRange
        /// containing this text.
        /// </summary>
        /// <param name="dcp">
        /// dcp of position relative to start of line
        /// </param>
        internal override TextSpan <CultureSpecificCharacterBufferRange> GetPrecedingText(int dcp)
        {
            // Parameter validation
            Invariant.Assert(dcp >= 0);

            int nonTextLength = 0;
            CharacterBufferRange precedingText = CharacterBufferRange.Empty;
            CultureInfo          culture       = null;

            if (dcp > 0)
            {
                // Create TextPointer at dcp, and pointer at paragraph start to compare
                ITextPointer startPosition = TextContainerHelper.GetTextPointerFromCP(_paraClient.Paragraph.StructuralCache.TextContainer, _cpPara, LogicalDirection.Forward);
                ITextPointer position      = TextContainerHelper.GetTextPointerFromCP(_paraClient.Paragraph.StructuralCache.TextContainer, _cpPara + dcp, LogicalDirection.Forward);

                // Move backward until we find a position at the end of a text run, or reach start of TextContainer
                while (position.GetPointerContext(LogicalDirection.Backward) != TextPointerContext.Text &&
                       position.CompareTo(startPosition) != 0)
                {
                    position.MoveByOffset(-1);
                    nonTextLength++;
                }


                // Return text in run. If it is at start of TextContainer this will return an empty string
                string precedingTextString = position.GetTextInRun(LogicalDirection.Backward);
                precedingText = new CharacterBufferRange(precedingTextString, 0, precedingTextString.Length);


                StaticTextPointer pointer = position.CreateStaticPointer();
                DependencyObject  element = (pointer.Parent != null) ? pointer.Parent : _paraClient.Paragraph.Element;
                culture = DynamicPropertyReader.GetCultureInfo(element);
            }

            return(new TextSpan <CultureSpecificCharacterBufferRange>(
                       nonTextLength + precedingText.Length,
                       new CultureSpecificCharacterBufferRange(culture, precedingText)
                       ));
        }
        // Token: 0x0600688F RID: 26767 RVA: 0x001D802C File Offset: 0x001D622C
        protected TextRun HandleElementEndEdge(StaticTextPointer position)
        {
            Invariant.Assert(position.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.ElementEnd, "TextPointer does not point to element end edge.");
            TextRun result;

            if (position.Parent == this._paraClient.Paragraph.Element)
            {
                result = new ParagraphBreakRun(LineBase._syntheticCharacterLength, PTS.FSFLRES.fsflrEndOfParagraph);
            }
            else
            {
                TextElement      textElement   = (TextElement)position.GetAdjacentElement(LogicalDirection.Forward);
                Inline           inline        = (Inline)textElement;
                DependencyObject parent        = inline.Parent;
                FlowDirection    flowDirection = inline.FlowDirection;
                if (parent != null)
                {
                    flowDirection = (FlowDirection)parent.GetValue(FrameworkElement.FlowDirectionProperty);
                }
                if (inline.FlowDirection != flowDirection)
                {
                    result = new TextEndOfSegment(LineBase._elementEdgeCharacterLength);
                }
                else
                {
                    TextDecorationCollection textDecorations = DynamicPropertyReader.GetTextDecorations(inline);
                    if (textDecorations == null || textDecorations.Count == 0)
                    {
                        result = new TextHidden(LineBase._elementEdgeCharacterLength);
                    }
                    else
                    {
                        result = new TextEndOfSegment(LineBase._elementEdgeCharacterLength);
                    }
                }
            }
            return(result);
        }
Example #18
0
        // ------------------------------------------------------------------
        // GetSectionProperties
        // ------------------------------------------------------------------

        /// <summary>
        /// Get section properties
        /// </summary>
        /// <param name="fNewPage">
        /// OUT: stop page before this section?
        /// </param>
        /// <param name="fswdir">
        /// OUT: direction of this section
        /// </param>
        /// <param name="fApplyColumnBalancing">
        /// OUT: apply column balancing to this section?
        /// </param>
        /// <param name="ccol">
        /// OUT: number of columns in the main text segment
        /// </param>
        /// <param name="cSegmentDefinedColumnSpanAreas">
        /// OUT: number of segment-defined columnspan areas
        /// </param>
        /// <param name="cHeightDefinedColumnSpanAreas">
        /// OUT: number of height-defined columnsapn areas
        /// </param>
        internal void GetSectionProperties(
            out int fNewPage,
            out uint fswdir,
            out int fApplyColumnBalancing,
            out int ccol,
            out int cSegmentDefinedColumnSpanAreas,
            out int cHeightDefinedColumnSpanAreas)
        {
            ColumnPropertiesGroup columnProperties = new ColumnPropertiesGroup(Element);
            Size       pageSize       = _structuralCache.CurrentFormatContext.PageSize;
            double     lineHeight     = DynamicPropertyReader.GetLineHeightValue(Element);
            Thickness  pageMargin     = _structuralCache.CurrentFormatContext.PageMargin;
            double     pageFontSize   = (double)_structuralCache.PropertyOwner.GetValue(Block.FontSizeProperty);
            FontFamily pageFontFamily = (FontFamily)_structuralCache.PropertyOwner.GetValue(Block.FontFamilyProperty);
            bool       enableColumns  = _structuralCache.CurrentFormatContext.FinitePage;

            fNewPage = PTS.False; // Since only one section is supported, don't force page break before.
            fswdir   = PTS.FlowDirectionToFswdir((FlowDirection)_structuralCache.PropertyOwner.GetValue(FrameworkElement.FlowDirectionProperty));
            fApplyColumnBalancing = PTS.False;
            ccol = PtsHelper.CalculateColumnCount(columnProperties, lineHeight, pageSize.Width - (pageMargin.Left + pageMargin.Right), pageFontSize, pageFontFamily, enableColumns);
            cSegmentDefinedColumnSpanAreas = 0;
            cHeightDefinedColumnSpanAreas  = 0;
        }
        // Token: 0x06007005 RID: 28677 RVA: 0x00202CF8 File Offset: 0x00200EF8
        private Thickness ComputePageMargin()
        {
            double    lineHeightValue = DynamicPropertyReader.GetLineHeightValue(this._document);
            Thickness pagePadding     = this._document.PagePadding;

            if (DoubleUtil.IsNaN(pagePadding.Left))
            {
                pagePadding.Left = lineHeightValue;
            }
            if (DoubleUtil.IsNaN(pagePadding.Top))
            {
                pagePadding.Top = lineHeightValue;
            }
            if (DoubleUtil.IsNaN(pagePadding.Right))
            {
                pagePadding.Right = lineHeightValue;
            }
            if (DoubleUtil.IsNaN(pagePadding.Bottom))
            {
                pagePadding.Bottom = lineHeightValue;
            }
            return(pagePadding);
        }
Example #20
0
        // Token: 0x06006942 RID: 26946 RVA: 0x001DCDB0 File Offset: 0x001DAFB0
        internal static double CalculatePageMarginAdjustment(StructuralCache structuralCache, double pageMarginWidth)
        {
            double           result  = 0.0;
            DependencyObject element = structuralCache.Section.Element;

            if (element is FlowDocument)
            {
                ColumnPropertiesGroup columnPropertiesGroup = new ColumnPropertiesGroup(element);
                if (!columnPropertiesGroup.IsColumnWidthFlexible)
                {
                    double     lineHeightValue = DynamicPropertyReader.GetLineHeightValue(element);
                    double     pageFontSize    = (double)structuralCache.PropertyOwner.GetValue(TextElement.FontSizeProperty);
                    FontFamily pageFontFamily  = (FontFamily)structuralCache.PropertyOwner.GetValue(TextElement.FontFamilyProperty);
                    int        cColumns        = PtsHelper.CalculateColumnCount(columnPropertiesGroup, lineHeightValue, pageMarginWidth, pageFontSize, pageFontFamily, true);
                    double     num;
                    double     num2;
                    double     num3;
                    PtsHelper.GetColumnMetrics(columnPropertiesGroup, pageMarginWidth, pageFontSize, pageFontFamily, true, cColumns, ref lineHeightValue, out num, out num2, out num3);
                    result = num2;
                }
            }
            return(result);
        }
Example #21
0
        /// <summary>
        /// Get text immediately before specified text source position.
        /// </summary>
        public override TextSpan <CultureSpecificCharacterBufferRange> GetPrecedingText(int dcp)
        {
            CharacterBufferRange precedingText = CharacterBufferRange.Empty;
            CultureInfo          culture       = null;

            if (dcp > 0)
            {
                // Create TextPointer at dcp
                ITextPointer position = _owner.Host.TextContainer.CreatePointerAtOffset(dcp, LogicalDirection.Backward);

                // Return text in run. If it is at start of TextContainer this will return an empty string.
                // Typically the caller requires just the preceding character.  Worst case is the entire
                // preceding sentence, which we approximate with a 128 char limit.
                int     runLength = Math.Min(128, position.GetTextRunLength(LogicalDirection.Backward));
                char [] text      = new char[runLength];
                position.GetTextInRun(LogicalDirection.Backward, text, 0, runLength);

                precedingText = new CharacterBufferRange(text, 0, runLength);
                culture       = DynamicPropertyReader.GetCultureInfo((Control)_owner.Host);
            }

            return(new TextSpan <CultureSpecificCharacterBufferRange>(
                       precedingText.Length, new CultureSpecificCharacterBufferRange(culture, precedingText)));
        }
        // Token: 0x06006864 RID: 26724 RVA: 0x001D6C0C File Offset: 0x001D4E0C
        internal override TextSpan <CultureSpecificCharacterBufferRange> GetPrecedingText(int dcp)
        {
            Invariant.Assert(dcp >= 0);
            int num = 0;
            CharacterBufferRange empty   = CharacterBufferRange.Empty;
            CultureInfo          culture = null;

            if (dcp > 0)
            {
                ITextPointer textPointerFromCP  = TextContainerHelper.GetTextPointerFromCP(this._paraClient.Paragraph.StructuralCache.TextContainer, this._cpPara, LogicalDirection.Forward);
                ITextPointer textPointerFromCP2 = TextContainerHelper.GetTextPointerFromCP(this._paraClient.Paragraph.StructuralCache.TextContainer, this._cpPara + dcp, LogicalDirection.Forward);
                while (textPointerFromCP2.GetPointerContext(LogicalDirection.Backward) != TextPointerContext.Text && textPointerFromCP2.CompareTo(textPointerFromCP) != 0)
                {
                    textPointerFromCP2.MoveByOffset(-1);
                    num++;
                }
                string textInRun = textPointerFromCP2.GetTextInRun(LogicalDirection.Backward);
                empty = new CharacterBufferRange(textInRun, 0, textInRun.Length);
                StaticTextPointer staticTextPointer = textPointerFromCP2.CreateStaticPointer();
                DependencyObject  element           = (staticTextPointer.Parent != null) ? staticTextPointer.Parent : this._paraClient.Paragraph.Element;
                culture = DynamicPropertyReader.GetCultureInfo(element);
            }
            return(new TextSpan <CultureSpecificCharacterBufferRange>(num + empty.Length, new CultureSpecificCharacterBufferRange(culture, empty)));
        }
        // Token: 0x0600688E RID: 26766 RVA: 0x001D7E38 File Offset: 0x001D6038
        protected TextRun HandleElementStartEdge(StaticTextPointer position)
        {
            Invariant.Assert(position.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.ElementStart, "TextPointer does not point to element start edge.");
            TextElement textElement = (TextElement)position.GetAdjacentElement(LogicalDirection.Forward);

            Invariant.Assert(!(textElement is Block), "We do not expect any Blocks inside Paragraphs");
            TextRun result;

            if (textElement is Figure || textElement is Floater)
            {
                int elementLength = TextContainerHelper.GetElementLength(this._paraClient.Paragraph.StructuralCache.TextContainer, textElement);
                result = new FloatingRun(elementLength, textElement is Figure);
                if (textElement is Figure)
                {
                    this._hasFigures = true;
                }
                else
                {
                    this._hasFloaters = true;
                }
            }
            else if (textElement is LineBreak)
            {
                int elementLength2 = TextContainerHelper.GetElementLength(this._paraClient.Paragraph.StructuralCache.TextContainer, textElement);
                result = new LineBreakRun(elementLength2, PTS.FSFLRES.fsflrSoftBreak);
            }
            else if (textElement.IsEmpty)
            {
                TextProperties textRunProperties = new TextProperties(textElement, position, false, true, this._paraClient.Paragraph.StructuralCache.TextFormatterHost.PixelsPerDip);
                char[]         array             = new char[LineBase._elementEdgeCharacterLength * 2];
                Invariant.Assert(LineBase._elementEdgeCharacterLength == 1, "Expected value of _elementEdgeCharacterLength is 1");
                array[0] = '​';
                array[1] = '​';
                result   = new TextCharacters(array, 0, array.Length, textRunProperties);
            }
            else
            {
                Inline                   inline          = (Inline)textElement;
                DependencyObject         parent          = inline.Parent;
                FlowDirection            flowDirection   = inline.FlowDirection;
                FlowDirection            flowDirection2  = flowDirection;
                TextDecorationCollection textDecorations = DynamicPropertyReader.GetTextDecorations(inline);
                if (parent != null)
                {
                    flowDirection2 = (FlowDirection)parent.GetValue(FrameworkElement.FlowDirectionProperty);
                }
                if (flowDirection != flowDirection2)
                {
                    if (textDecorations == null || textDecorations.Count == 0)
                    {
                        result = new TextSpanModifier(LineBase._elementEdgeCharacterLength, null, null, flowDirection);
                    }
                    else
                    {
                        result = new TextSpanModifier(LineBase._elementEdgeCharacterLength, textDecorations, inline.Foreground, flowDirection);
                    }
                }
                else if (textDecorations == null || textDecorations.Count == 0)
                {
                    result = new TextHidden(LineBase._elementEdgeCharacterLength);
                }
                else
                {
                    result = new TextSpanModifier(LineBase._elementEdgeCharacterLength, textDecorations, inline.Foreground);
                }
            }
            return(result);
        }
Example #24
0
        // Token: 0x060068A3 RID: 26787 RVA: 0x001D8324 File Offset: 0x001D6524
        private static FormattedText GetFormattedMarker(List list, double pixelsPerDip)
        {
            string        textToFormat = "";
            FormattedText result;

            if (ListMarkerSourceInfo.IsKnownSymbolMarkerStyle(list.MarkerStyle))
            {
                switch (list.MarkerStyle)
                {
                case TextMarkerStyle.Disc:
                    textToFormat = "\u009f";
                    break;

                case TextMarkerStyle.Circle:
                    textToFormat = "¡";
                    break;

                case TextMarkerStyle.Square:
                    textToFormat = "q";
                    break;

                case TextMarkerStyle.Box:
                    textToFormat = "§";
                    break;
                }
                Typeface modifiedTypeface = DynamicPropertyReader.GetModifiedTypeface(list, new FontFamily("Wingdings"));
                result = new FormattedText(textToFormat, DynamicPropertyReader.GetCultureInfo(list), list.FlowDirection, modifiedTypeface, list.FontSize, list.Foreground, pixelsPerDip);
            }
            else if (ListMarkerSourceInfo.IsKnownIndexMarkerStyle(list.MarkerStyle))
            {
                int startIndex = list.StartIndex;
                Invariant.Assert(startIndex > 0);
                int count = list.ListItems.Count;
                int num;
                if (2147483647 - count < startIndex)
                {
                    num = int.MaxValue;
                }
                else
                {
                    num = ((count == 0) ? startIndex : (startIndex + count - 1));
                }
                switch (list.MarkerStyle)
                {
                case TextMarkerStyle.LowerRoman:
                    textToFormat = ListMarkerSourceInfo.GetStringForLargestRomanMarker(startIndex, num, false);
                    break;

                case TextMarkerStyle.UpperRoman:
                    textToFormat = ListMarkerSourceInfo.GetStringForLargestRomanMarker(startIndex, num, true);
                    break;

                case TextMarkerStyle.LowerLatin:
                    textToFormat = ListMarkerSourceInfo.ConvertNumberToString(num, true, ListMarkerSourceInfo.LowerLatinNumerics);
                    break;

                case TextMarkerStyle.UpperLatin:
                    textToFormat = ListMarkerSourceInfo.ConvertNumberToString(num, true, ListMarkerSourceInfo.UpperLatinNumerics);
                    break;

                case TextMarkerStyle.Decimal:
                    textToFormat = ListMarkerSourceInfo.ConvertNumberToString(num, false, ListMarkerSourceInfo.DecimalNumerics);
                    break;
                }
                result = new FormattedText(textToFormat, DynamicPropertyReader.GetCultureInfo(list), list.FlowDirection, DynamicPropertyReader.GetTypeface(list), list.FontSize, list.Foreground, pixelsPerDip);
            }
            else
            {
                textToFormat = "\u009f";
                Typeface modifiedTypeface2 = DynamicPropertyReader.GetModifiedTypeface(list, new FontFamily("Wingdings"));
                result = new FormattedText(textToFormat, DynamicPropertyReader.GetCultureInfo(list), list.FlowDirection, modifiedTypeface2, list.FontSize, list.Foreground, pixelsPerDip);
            }
            return(result);
        }
Example #25
0
        /// <summary>
        /// Returns FormattedText for the largets marker in a list
        /// </summary>
        /// <param name="list">
        /// List element for which formatted marker is to be calculated
        /// </param>
        private static FormattedText GetFormattedMarker(List list)
        {
            string        markerString = "";
            FormattedText formattedMarker;

            if (IsKnownSymbolMarkerStyle(list.MarkerStyle))
            {
                switch (list.MarkerStyle)
                {
                case TextMarkerStyle.Disc:
                    markerString = "\x9f";
                    break;

                case TextMarkerStyle.Circle:
                    markerString = "\xa1";
                    break;

                case TextMarkerStyle.Square:
                    markerString = "\x71";
                    break;

                case TextMarkerStyle.Box:
                    markerString = "\xa7";
                    break;
                }

                // Create new formatted text with typeface using a symbol font, e.g. Wingdings
                Typeface typeface = DynamicPropertyReader.GetModifiedTypeface(list, new FontFamily("Wingdings"));

                formattedMarker = new FormattedText(markerString, DynamicPropertyReader.GetCultureInfo(list), list.FlowDirection,
                                                    typeface, list.FontSize, list.Foreground);
            }
            else if (IsKnownIndexMarkerStyle(list.MarkerStyle))
            {
                // Assume at least one element will be added and format accordingly
                int startIndex = list.StartIndex;
                Invariant.Assert(startIndex > 0);
                int size = list.ListItems.Count;
                int highestIndex;
                if (int.MaxValue - size < startIndex)
                {
                    // Highest index will exceed max value of int. Clamp to int.MaxValue
                    highestIndex = int.MaxValue;
                }
                else
                {
                    highestIndex = (size == 0) ? startIndex : startIndex + size - 1;
                }
                switch (list.MarkerStyle)
                {
                case TextMarkerStyle.Decimal:
                    markerString = ConvertNumberToString(highestIndex, false, DecimalNumerics);
                    break;

                case TextMarkerStyle.LowerLatin:
                    markerString = ConvertNumberToString(highestIndex, true, LowerLatinNumerics);
                    break;

                case TextMarkerStyle.UpperLatin:
                    markerString = ConvertNumberToString(highestIndex, true, UpperLatinNumerics);
                    break;

                case TextMarkerStyle.LowerRoman:
                    markerString = GetStringForLargestRomanMarker(startIndex, highestIndex, false);
                    break;

                case TextMarkerStyle.UpperRoman:
                    markerString = GetStringForLargestRomanMarker(startIndex, highestIndex, true);
                    break;
                }

                // Create new formatted text using List defaulls
                formattedMarker = new FormattedText(markerString, DynamicPropertyReader.GetCultureInfo(list), list.FlowDirection,
                                                    DynamicPropertyReader.GetTypeface(list), list.FontSize, list.Foreground);
            }
            else
            {
                // Assume a disc
                markerString = "\x9f";
                // Create new formatted text with typeface using a symbol font, e.g. Wingdings
                Typeface typeface = DynamicPropertyReader.GetModifiedTypeface(list, new FontFamily("Wingdings"));

                formattedMarker = new FormattedText(markerString, DynamicPropertyReader.GetCultureInfo(list), list.FlowDirection,
                                                    typeface, list.FontSize, list.Foreground);
            }

            return(formattedMarker);
        }
        internal unsafe void UpdateBottomlessPara(IntPtr pfspara, SubpageParaClient paraClient, int fSuppressTopSpace, uint fswdir, int urTrack, int durTrack, int vrTrack, MarginCollapsingState mcs, PTS.FSKCLEAR fskclearIn, int fInterruptable, out PTS.FSFMTRBL fsfmtrbl, out int dvrUsed, out PTS.FSBBOX fsbbox, out IntPtr pmcsclientOut, out PTS.FSKCLEAR fskclearOut, out int dvrTopSpace, out int fPageBecomesUninterruptable)
        {
            uint num  = PTS.FlowDirectionToFswdir((FlowDirection)base.Element.GetValue(FrameworkElement.FlowDirectionProperty));
            int  num2 = durTrack;
            int  urMargin;
            int  vrMargin = urMargin = 0;

            Invariant.Assert(base.Element is TableCell || base.Element is AnchoredBlock);
            fskclearIn = PTS.WrapDirectionToFskclear((WrapDirection)base.Element.GetValue(Block.ClearFloatersProperty));
            MbpInfo mbpInfo = MbpInfo.FromElement(base.Element, base.StructuralCache.TextFormatterHost.PixelsPerDip);

            if (num != fswdir)
            {
                PTS.FSRECT fsrect   = new PTS.FSRECT(urTrack, 0, durTrack, 0);
                PTS.FSRECT pageRect = base.StructuralCache.CurrentFormatContext.PageRect;
                PTS.Validate(PTS.FsTransformRectangle(fswdir, ref pageRect, ref fsrect, num, out fsrect));
                urTrack  = fsrect.u;
                durTrack = fsrect.du;
                mbpInfo.MirrorMargin();
            }
            num2 = Math.Max(1, num2 - (mbpInfo.MBPLeft + mbpInfo.MBPRight));
            MarginCollapsingState marginCollapsingState;
            int num3;

            MarginCollapsingState.CollapseTopMargin(base.PtsContext, mbpInfo, mcs, out marginCollapsingState, out num3);
            if (marginCollapsingState != null)
            {
                marginCollapsingState.Dispose();
                marginCollapsingState = null;
            }
            int durMargin = num2;
            ColumnPropertiesGroup columnProperties = new ColumnPropertiesGroup(this._element);
            double     lineHeightValue             = DynamicPropertyReader.GetLineHeightValue(this._element);
            double     pageFontSize   = (double)this._structuralCache.PropertyOwner.GetValue(TextElement.FontSizeProperty);
            FontFamily pageFontFamily = (FontFamily)this._structuralCache.PropertyOwner.GetValue(TextElement.FontFamilyProperty);
            int        num4           = PtsHelper.CalculateColumnCount(columnProperties, lineHeightValue, TextDpi.FromTextDpi(num2), pageFontSize, pageFontFamily, false);

            PTS.FSCOLUMNINFO[] array = new PTS.FSCOLUMNINFO[num4];
            fixed(PTS.FSCOLUMNINFO *ptr = array)
            {
                PtsHelper.GetColumnsInfo(columnProperties, lineHeightValue, TextDpi.FromTextDpi(num2), pageFontSize, pageFontFamily, num4, ptr, false);
            }

            base.StructuralCache.CurrentFormatContext.PushNewPageData(new Size(TextDpi.FromTextDpi(num2), TextDpi.MaxWidth), default(Thickness), true, false);
            fixed(PTS.FSCOLUMNINFO *ptr2 = array)
            {
                PTS.Validate(PTS.FsUpdateBottomlessSubpage(base.PtsContext.Context, pfspara, this._mainTextSegment.Handle, fSuppressTopSpace, fswdir, num2, urMargin, durMargin, vrMargin, num4, ptr2, 0, null, null, 0, null, null, PTS.FromBoolean(true), out fsfmtrbl, out dvrUsed, out fsbbox, out pmcsclientOut, out dvrTopSpace, out fPageBecomesUninterruptable), base.PtsContext);
            }

            base.StructuralCache.CurrentFormatContext.PopPageData();
            fskclearOut = PTS.FSKCLEAR.fskclearNone;
            if (fsfmtrbl != PTS.FSFMTRBL.fmtrblCollision)
            {
                if (pmcsclientOut != IntPtr.Zero)
                {
                    marginCollapsingState = (base.PtsContext.HandleToObject(pmcsclientOut) as MarginCollapsingState);
                    PTS.ValidateHandle(marginCollapsingState);
                    pmcsclientOut = IntPtr.Zero;
                }
                MarginCollapsingState marginCollapsingState2;
                int num5;
                MarginCollapsingState.CollapseBottomMargin(base.PtsContext, mbpInfo, marginCollapsingState, out marginCollapsingState2, out num5);
                pmcsclientOut = ((marginCollapsingState2 != null) ? marginCollapsingState2.Handle : IntPtr.Zero);
                if (marginCollapsingState != null)
                {
                    marginCollapsingState.Dispose();
                    marginCollapsingState = null;
                }
                if (PTS.ToBoolean(fsbbox.fDefined))
                {
                    dvrUsed  = Math.Max(dvrUsed, fsbbox.fsrc.dv + fsbbox.fsrc.v);
                    durTrack = Math.Max(durTrack, fsbbox.fsrc.du + fsbbox.fsrc.u);
                }
                dvrTopSpace    = ((mbpInfo.BPTop != 0) ? num3 : dvrTopSpace);
                dvrUsed       += num3 + mbpInfo.BPTop + (num5 + mbpInfo.BPBottom);
                fsbbox.fsrc.u  = urTrack + mbpInfo.MarginLeft;
                fsbbox.fsrc.v  = vrTrack + dvrTopSpace;
                fsbbox.fsrc.du = Math.Max(durTrack - (mbpInfo.MarginLeft + mbpInfo.MarginRight), 0);
                fsbbox.fsrc.dv = Math.Max(dvrUsed - dvrTopSpace, 0);
            }
            else
            {
                pfspara = IntPtr.Zero;
                dvrUsed = (dvrTopSpace = 0);
            }
            if (num != fswdir)
            {
                PTS.FSRECT pageRect2 = base.StructuralCache.CurrentFormatContext.PageRect;
                PTS.Validate(PTS.FsTransformBbox(num, ref pageRect2, ref fsbbox, fswdir, out fsbbox));
            }
            paraClient.SetChunkInfo(true, true);
        }
Example #27
0
        internal unsafe void UpdateBottomlessPara(
            IntPtr pfspara,                      // IN:  pointer to the para data
            SubpageParaClient paraClient,        // IN:
            int fSuppressTopSpace,               // IN:  suppress empty space at the top of the page
            uint fswdir,                         // IN:  current direction
            int urTrack,                         // IN:  u of bootomless rectangle to fill
            int durTrack,                        // IN:  du of bootomless rectangle to fill
            int vrTrack,                         // IN:  v of bootomless rectangle to fill
            MarginCollapsingState mcs,           // IN:  input margin collapsing state
            PTS.FSKCLEAR fskclearIn,             // IN:  clear property that must be satisfied
            int fInterruptable,                  // IN:  formatting can be interrupted
            out PTS.FSFMTRBL fsfmtrbl,           // OUT: result of formatting the paragraph
            out int dvrUsed,                     // OUT: vertical space used by the para
            out PTS.FSBBOX fsbbox,               // OUT: para BBox
            out IntPtr pmcsclientOut,            // OUT: margin collapsing state at the bottom
            out PTS.FSKCLEAR fskclearOut,        // OUT: ClearIn for the next paragraph
            out int dvrTopSpace,                 // OUT: top space due to collapsed margin
            out int fPageBecomesUninterruptable) // OUT: interruption is prohibited from now on
        {
            int     subpageWidth, urSubpageMargin, durSubpageMargin, vrSubpageMargin;
            int     cColumns;
            int     marginTop, marginBottom;
            MbpInfo mbp;
            MarginCollapsingState mcsSubpage, mcsBottom;

            PTS.FSCOLUMNINFO[] columnInfoCollection;
            uint fswdirSubpage = PTS.FlowDirectionToFswdir(((FlowDirection)Element.GetValue(FrameworkElement.FlowDirectionProperty)));

            // Initialize the subpage size and its margin.
            subpageWidth    = durTrack;
            urSubpageMargin = vrSubpageMargin = 0;

            // Set clear property
            Invariant.Assert(Element is TableCell || Element is AnchoredBlock);
            fskclearIn = PTS.WrapDirectionToFskclear((WrapDirection)Element.GetValue(Block.ClearFloatersProperty));

            // Take into account MBPs and modify subpage metrics,
            // and make sure that subpage is at least 1 unit wide (cannot measure at width <= 0)
            // NOTE: Do not suppress top space for bottomles pages.
            mbp = MbpInfo.FromElement(Element, StructuralCache.TextFormatterHost.PixelsPerDip);

            if (fswdirSubpage != fswdir)
            {
                PTS.FSRECT fsrcToFillSubpage = new PTS.FSRECT(urTrack, 0, durTrack, 0);
                PTS.FSRECT pageRect          = StructuralCache.CurrentFormatContext.PageRect;
                PTS.Validate(PTS.FsTransformRectangle(fswdir, ref pageRect, ref fsrcToFillSubpage, fswdirSubpage, out fsrcToFillSubpage));

                urTrack  = fsrcToFillSubpage.u;
                durTrack = fsrcToFillSubpage.du;

                mbp.MirrorMargin();
            }

            subpageWidth = Math.Max(1, subpageWidth - (mbp.MBPLeft + mbp.MBPRight));
            MarginCollapsingState.CollapseTopMargin(PtsContext, mbp, mcs, out mcsSubpage, out marginTop);
            // Destroy top margin collapsing state (not needed anymore).
            if (mcsSubpage != null)
            {
                mcsSubpage.Dispose();
                mcsSubpage = null;
            }
            durSubpageMargin = subpageWidth;

            // Initialize column info
            // For bottomles spara, limit line height to the height of the current format context in structural cache.
            ColumnPropertiesGroup columnProperties = new ColumnPropertiesGroup(_element);
            double     lineHeight     = DynamicPropertyReader.GetLineHeightValue(_element);
            double     pageFontSize   = (double)_structuralCache.PropertyOwner.GetValue(Block.FontSizeProperty);
            FontFamily pageFontFamily = (FontFamily)_structuralCache.PropertyOwner.GetValue(Block.FontFamilyProperty);

            // Get columns info, setting ownerIsFlowDocument flag to false. A flow document should not be formatted as a subpage and we
            // do not want default column widths to be set on TableCells and floaters
            cColumns             = PtsHelper.CalculateColumnCount(columnProperties, lineHeight, TextDpi.FromTextDpi(subpageWidth), pageFontSize, pageFontFamily, false);
            columnInfoCollection = new PTS.FSCOLUMNINFO[cColumns];
            fixed(PTS.FSCOLUMNINFO *rgColumnInfo = columnInfoCollection)
            {
                PtsHelper.GetColumnsInfo(columnProperties, lineHeight, TextDpi.FromTextDpi(subpageWidth), pageFontSize, pageFontFamily, cColumns, rgColumnInfo, false);
            }

            StructuralCache.CurrentFormatContext.PushNewPageData(new Size(TextDpi.FromTextDpi(subpageWidth), TextDpi.MaxWidth),
                                                                 new Thickness(),
                                                                 true,
                                                                 false);

            // Create subpage
            fixed(PTS.FSCOLUMNINFO *rgColumnInfo = columnInfoCollection)
            {
                PTS.Validate(PTS.FsUpdateBottomlessSubpage(PtsContext.Context, pfspara, _mainTextSegment.Handle, fSuppressTopSpace,
                                                           fswdir, subpageWidth, urSubpageMargin, durSubpageMargin, vrSubpageMargin,
                                                           cColumns, rgColumnInfo, 0, null, null, 0, null, null, PTS.FromBoolean(true),
                                                           out fsfmtrbl, out dvrUsed, out fsbbox, out pmcsclientOut, out dvrTopSpace,
                                                           out fPageBecomesUninterruptable), PtsContext);
            }

            StructuralCache.CurrentFormatContext.PopPageData();

            fskclearOut = PTS.FSKCLEAR.fskclearNone;

            if (fsfmtrbl != PTS.FSFMTRBL.fmtrblCollision)
            {
                // Bottom margin collapsing:
                // (1) retrieve mcs from the subtrack
                // (2) do margin collapsing; create a new margin collapsing state
                if (pmcsclientOut != IntPtr.Zero)
                {
                    mcsSubpage = PtsContext.HandleToObject(pmcsclientOut) as MarginCollapsingState;
                    PTS.ValidateHandle(mcsSubpage);
                    pmcsclientOut = IntPtr.Zero;
                }
                MarginCollapsingState.CollapseBottomMargin(PtsContext, mbp, mcsSubpage, out mcsBottom, out marginBottom);
                pmcsclientOut = (mcsBottom != null) ? mcsBottom.Handle : IntPtr.Zero;

                // Since MCS returned by PTS is never passed back, destroy MCS provided by PTS.
                // If necessary, new MCS is created and passed back to PTS.
                if (mcsSubpage != null)
                {
                    mcsSubpage.Dispose();
                    mcsSubpage = null;
                }

                if (PTS.ToBoolean(fsbbox.fDefined))
                {
                    // Workaround for PTS bug 860: get max of the page rect and
                    // bounding box of the page.
                    dvrUsed  = Math.Max(dvrUsed, fsbbox.fsrc.dv + fsbbox.fsrc.v);
                    durTrack = Math.Max(durTrack, fsbbox.fsrc.du + fsbbox.fsrc.u);
                }

                // Take into account MBPs and modify subtrack metrics
                dvrTopSpace = (mbp.BPTop != 0) ? marginTop : dvrTopSpace;
                dvrUsed    += (marginTop + mbp.BPTop) + (marginBottom + mbp.BPBottom);

                // Update bounding box
                fsbbox.fsrc.u  = urTrack + mbp.MarginLeft;
                fsbbox.fsrc.v  = vrTrack + dvrTopSpace;
                fsbbox.fsrc.du = Math.Max(durTrack - (mbp.MarginLeft + mbp.MarginRight), 0);
                fsbbox.fsrc.dv = Math.Max(dvrUsed - dvrTopSpace, 0);
            }
            else
            {
                Debug.Assert(pmcsclientOut == IntPtr.Zero);
                pfspara = IntPtr.Zero;
                dvrUsed = dvrTopSpace = 0;
            }


            if (fswdirSubpage != fswdir)
            {
                PTS.FSRECT pageRect = StructuralCache.CurrentFormatContext.PageRect;
                PTS.Validate(PTS.FsTransformBbox(fswdirSubpage, ref pageRect, ref fsbbox, fswdir, out fsbbox));
            }

            // Update information about first/last chunk. In bottomless scenario
            // paragraph is not broken, so there is only one chunk.
            paraClient.SetChunkInfo(true, true);
        }
Example #28
0
        internal unsafe void FormatParaFinite(
            SubpageParaClient paraClient,       // IN:
            IntPtr pbrkrecIn,                   // IN:  break record---use if !NULL
            int fBRFromPreviousPage,            // IN:  break record was created on previous page
            IntPtr footnoteRejector,            // IN:
            int fEmptyOk,                       // IN:  is it OK not to add anything?
            int fSuppressTopSpace,              // IN:  suppress empty space at the top of the page
            uint fswdir,                        // IN:  current direction
            ref PTS.FSRECT fsrcToFill,          // IN:  rectangle to fill
            MarginCollapsingState mcs,          // IN:  input margin collapsing state
            PTS.FSKCLEAR fskclearIn,            // IN:  clear property that must be satisfied
            PTS.FSKSUPPRESSHARDBREAKBEFOREFIRSTPARA fsksuppresshardbreakbeforefirstparaIn,
            // IN: suppress breaks at track start?
            out PTS.FSFMTR fsfmtr,              // OUT: result of formatting the paragraph
            out IntPtr pfspara,                 // OUT: pointer to the para data
            out IntPtr pbrkrecOut,              // OUT: pointer to the para break record
            out int dvrUsed,                    // OUT: vertical space used by the para
            out PTS.FSBBOX fsbbox,              // OUT: para BBox
            out IntPtr pmcsclientOut,           // OUT: margin collapsing state at the bottom
            out PTS.FSKCLEAR fskclearOut,       // OUT: ClearIn for the next paragraph
            out int dvrTopSpace)                // OUT: top space due to collapsed margin
        {
            uint fswdirSubpage = PTS.FlowDirectionToFswdir(((FlowDirection)Element.GetValue(FrameworkElement.FlowDirectionProperty)));

            int     subpageWidth, subpageHeight;
            int     cColumns;
            int     marginTop, marginBottom;
            MbpInfo mbp;
            MarginCollapsingState mcsSubpage, mcsBottom;

            PTS.FSRECT          fsrcSubpageMargin;
            PTS.FSCOLUMNINFO [] columnInfoCollection;

            // Currently it is possible to get MCS and BR in following situation:
            // At the end of the page there is a paragraph with delayed figure, so the figure
            // gets delayed to the next page. But part of the next paragraph fits in the page,
            // so it gets broken. PTS creates BR with delayed figure and broken para.
            // PTS will format the next page starting from delayed figure, which can produce MCS.
            // So when the next paragraph is continued from BR, it has MCS.
            // This problem is currently investigated by PTS team: PTSLS bug 915.
            // For now, MCS gets ignored here.
            //Debug.Assert(pbrkrecIn == IntPtr.Zero || mcs == null, "Broken paragraph cannot have margin collapsing state.");
            if (mcs != null && pbrkrecIn != IntPtr.Zero)
            {
                mcs = null;
            }

            // Initialize the subpage size and its margin.
            fsrcSubpageMargin = new PTS.FSRECT();
            subpageWidth      = fsrcToFill.du;
            subpageHeight     = fsrcToFill.dv;

            // Set clear property
            Invariant.Assert(Element is TableCell || Element is AnchoredBlock);
            fskclearIn = PTS.WrapDirectionToFskclear((WrapDirection)Element.GetValue(Block.ClearFloatersProperty));

            // Take into account MBPs and modify subpage metrics,
            // and make sure that subpage is at least 1 unit wide (cannot measure at width <= 0)
            marginTop  = 0;
            mcsSubpage = null;

            // Get MBP info. Since subpage height and width must be at least 1, the max size for MBP is subpage dimensions less 1
            mbp = MbpInfo.FromElement(Element, StructuralCache.TextFormatterHost.PixelsPerDip);

            if (fswdirSubpage != fswdir)
            {
                PTS.FSRECT pageRect = StructuralCache.CurrentFormatContext.PageRect;
                PTS.Validate(PTS.FsTransformRectangle(fswdir, ref pageRect, ref fsrcToFill, fswdirSubpage, out fsrcToFill));
                mbp.MirrorMargin();
            }

            subpageWidth = Math.Max(1, subpageWidth - (mbp.MBPLeft + mbp.MBPRight));
            if (pbrkrecIn == IntPtr.Zero)
            {
                // Top margin collapsing. If suppresing top space, top margin is always 0.
                MarginCollapsingState.CollapseTopMargin(PtsContext, mbp, mcs, out mcsSubpage, out marginTop);
                if (PTS.ToBoolean(fSuppressTopSpace))
                {
                    marginTop = 0;
                }
                subpageHeight = Math.Max(1, subpageHeight - (marginTop + mbp.BPTop));
                // Destroy top margin collapsing state (not needed anymore).
                if (mcsSubpage != null)
                {
                    mcsSubpage.Dispose();
                    mcsSubpage = null;
                }
            }
            else
            {
                Debug.Assert(fSuppressTopSpace == 1, "Top space should be always suppressed at the top of broken paragraph.");
            }
            fsrcSubpageMargin.du = subpageWidth;
            fsrcSubpageMargin.dv = subpageHeight;

            // Initialize column info
            ColumnPropertiesGroup columnProperties = new ColumnPropertiesGroup(_element);
            double     lineHeight     = DynamicPropertyReader.GetLineHeightValue(_element);
            double     pageFontSize   = (double)_structuralCache.PropertyOwner.GetValue(Block.FontSizeProperty);
            FontFamily pageFontFamily = (FontFamily)_structuralCache.PropertyOwner.GetValue(Block.FontFamilyProperty);

            // Get columns info, setting ownerIsFlowDocument flag to false. A flow document should not be formatted as a subpage and we
            // do not want default column widths to be set on TableCells and floaters
            cColumns             = PtsHelper.CalculateColumnCount(columnProperties, lineHeight, TextDpi.FromTextDpi(subpageWidth), pageFontSize, pageFontFamily, false);
            columnInfoCollection = new PTS.FSCOLUMNINFO[cColumns];
            fixed(PTS.FSCOLUMNINFO *rgColumnInfo = columnInfoCollection)
            {
                PtsHelper.GetColumnsInfo(columnProperties, lineHeight, TextDpi.FromTextDpi(subpageWidth), pageFontSize, pageFontFamily, cColumns, rgColumnInfo, false);
            }

            // Format subpage
            StructuralCache.CurrentFormatContext.PushNewPageData(new Size(TextDpi.FromTextDpi(subpageWidth), TextDpi.FromTextDpi(subpageHeight)),
                                                                 new Thickness(),
                                                                 false,
                                                                 true);

            fixed(PTS.FSCOLUMNINFO *rgColumnInfo = columnInfoCollection)
            {
                PTS.Validate(PTS.FsCreateSubpageFinite(PtsContext.Context, pbrkrecIn, fBRFromPreviousPage, _mainTextSegment.Handle,
                                                       footnoteRejector, fEmptyOk, fSuppressTopSpace, fswdir, subpageWidth, subpageHeight,
                                                       ref fsrcSubpageMargin, cColumns, rgColumnInfo, PTS.False,
                                                       0, null, null, 0, null, null, PTS.FromBoolean(false),
                                                       fsksuppresshardbreakbeforefirstparaIn,
                                                       out fsfmtr, out pfspara, out pbrkrecOut, out dvrUsed, out fsbbox, out pmcsclientOut, out dvrTopSpace), PtsContext);
            }

            StructuralCache.CurrentFormatContext.PopPageData();

            fskclearOut = PTS.FSKCLEAR.fskclearNone;

            if (PTS.ToBoolean(fsbbox.fDefined))
            {
                // Workaround for PTS bug 860: get max of the page rect and
                // bounding box of the page.
                dvrUsed       = Math.Max(dvrUsed, fsbbox.fsrc.dv + fsbbox.fsrc.v);
                fsrcToFill.du = Math.Max(fsrcToFill.du, fsbbox.fsrc.du + fsbbox.fsrc.u);
            }

            if (pbrkrecIn == IntPtr.Zero) // if first chunk
            {
                // Take into account MBPs and modify subpage metrics
                dvrTopSpace = (mbp.BPTop != 0) ? marginTop : dvrTopSpace;
                dvrUsed    += (marginTop + mbp.BPTop);
            }

            if (pmcsclientOut != IntPtr.Zero)
            {
                mcsSubpage = PtsContext.HandleToObject(pmcsclientOut) as MarginCollapsingState;
                PTS.ValidateHandle(mcsSubpage);
                pmcsclientOut = IntPtr.Zero;
            }

            // Initialize subpage metrics
            if (fsfmtr.kstop >= PTS.FSFMTRKSTOP.fmtrNoProgressOutOfSpace)   // No progress or collision
            {
                dvrUsed = dvrTopSpace = 0;
                //pbrkrecOut = IntPtr.Zero;
                //pfspara = IntPtr.Zero;
                //pmcsclientOut = IntPtr.Zero;
            }
            else
            {
                if (fsfmtr.kstop == PTS.FSFMTRKSTOP.fmtrGoalReached)
                {
                    // Bottom margin collapsing:
                    // (a) retrieve mcs from the subpage
                    // (b) do margin collapsing; create a new margin collapsing state
                    // There is no bottom margin collapsing if paragraph will be continued (output break record is not null).
                    MarginCollapsingState.CollapseBottomMargin(PtsContext, mbp, mcsSubpage, out mcsBottom, out marginBottom);
                    pmcsclientOut = (mcsBottom != null) ? mcsBottom.Handle : IntPtr.Zero;

                    if (pmcsclientOut == IntPtr.Zero) // if last chunk
                    {
                        dvrUsed += marginBottom + mbp.BPBottom;
                    }
                }

                // Update bounding box
                fsbbox.fsrc.u  = fsrcToFill.u + mbp.MarginLeft;
                fsbbox.fsrc.v  = fsrcToFill.v + dvrTopSpace;
                fsbbox.fsrc.du = Math.Max(fsrcToFill.du - (mbp.MarginLeft + mbp.MarginRight), 0);
                fsbbox.fsrc.dv = Math.Max(dvrUsed - dvrTopSpace, 0);
            }

            if (fswdirSubpage != fswdir)
            {
                PTS.FSRECT pageRect = StructuralCache.CurrentFormatContext.PageRect;
                PTS.Validate(PTS.FsTransformBbox(fswdirSubpage, ref pageRect, ref fsbbox, fswdir, out fsbbox));
            }


            // Since MCS returned by PTS is never passed back, destroy MCS provided by PTS.
            // If necessary, new MCS is created and passed back to PTS (see above).
            if (mcsSubpage != null)
            {
                mcsSubpage.Dispose();
                mcsSubpage = null;
            }


            // Update information about first/last chunk
            paraClient.SetChunkInfo(pbrkrecIn == IntPtr.Zero, pbrkrecOut == IntPtr.Zero);
        }
        internal unsafe void FormatParaFinite(SubpageParaClient paraClient, IntPtr pbrkrecIn, int fBRFromPreviousPage, IntPtr footnoteRejector, int fEmptyOk, int fSuppressTopSpace, uint fswdir, ref PTS.FSRECT fsrcToFill, MarginCollapsingState mcs, PTS.FSKCLEAR fskclearIn, PTS.FSKSUPPRESSHARDBREAKBEFOREFIRSTPARA fsksuppresshardbreakbeforefirstparaIn, out PTS.FSFMTR fsfmtr, out IntPtr pfspara, out IntPtr pbrkrecOut, out int dvrUsed, out PTS.FSBBOX fsbbox, out IntPtr pmcsclientOut, out PTS.FSKCLEAR fskclearOut, out int dvrTopSpace)
        {
            uint num = PTS.FlowDirectionToFswdir((FlowDirection)base.Element.GetValue(FrameworkElement.FlowDirectionProperty));

            if (mcs != null && pbrkrecIn != IntPtr.Zero)
            {
                mcs = null;
            }
            PTS.FSRECT fsrect = default(PTS.FSRECT);
            int        num2   = fsrcToFill.du;
            int        num3   = fsrcToFill.dv;

            Invariant.Assert(base.Element is TableCell || base.Element is AnchoredBlock);
            fskclearIn = PTS.WrapDirectionToFskclear((WrapDirection)base.Element.GetValue(Block.ClearFloatersProperty));
            int num4 = 0;
            MarginCollapsingState marginCollapsingState = null;
            MbpInfo mbpInfo = MbpInfo.FromElement(base.Element, base.StructuralCache.TextFormatterHost.PixelsPerDip);

            if (num != fswdir)
            {
                PTS.FSRECT pageRect = base.StructuralCache.CurrentFormatContext.PageRect;
                PTS.Validate(PTS.FsTransformRectangle(fswdir, ref pageRect, ref fsrcToFill, num, out fsrcToFill));
                mbpInfo.MirrorMargin();
            }
            num2 = Math.Max(1, num2 - (mbpInfo.MBPLeft + mbpInfo.MBPRight));
            if (pbrkrecIn == IntPtr.Zero)
            {
                MarginCollapsingState.CollapseTopMargin(base.PtsContext, mbpInfo, mcs, out marginCollapsingState, out num4);
                if (PTS.ToBoolean(fSuppressTopSpace))
                {
                    num4 = 0;
                }
                num3 = Math.Max(1, num3 - (num4 + mbpInfo.BPTop));
                if (marginCollapsingState != null)
                {
                    marginCollapsingState.Dispose();
                    marginCollapsingState = null;
                }
            }
            fsrect.du = num2;
            fsrect.dv = num3;
            ColumnPropertiesGroup columnProperties = new ColumnPropertiesGroup(this._element);
            double     lineHeightValue             = DynamicPropertyReader.GetLineHeightValue(this._element);
            double     pageFontSize   = (double)this._structuralCache.PropertyOwner.GetValue(TextElement.FontSizeProperty);
            FontFamily pageFontFamily = (FontFamily)this._structuralCache.PropertyOwner.GetValue(TextElement.FontFamilyProperty);
            int        num5           = PtsHelper.CalculateColumnCount(columnProperties, lineHeightValue, TextDpi.FromTextDpi(num2), pageFontSize, pageFontFamily, false);

            PTS.FSCOLUMNINFO[] array = new PTS.FSCOLUMNINFO[num5];
            fixed(PTS.FSCOLUMNINFO *ptr = array)
            {
                PtsHelper.GetColumnsInfo(columnProperties, lineHeightValue, TextDpi.FromTextDpi(num2), pageFontSize, pageFontFamily, num5, ptr, false);
            }

            base.StructuralCache.CurrentFormatContext.PushNewPageData(new Size(TextDpi.FromTextDpi(num2), TextDpi.FromTextDpi(num3)), default(Thickness), false, true);
            fixed(PTS.FSCOLUMNINFO *ptr2 = array)
            {
                PTS.Validate(PTS.FsCreateSubpageFinite(base.PtsContext.Context, pbrkrecIn, fBRFromPreviousPage, this._mainTextSegment.Handle, footnoteRejector, fEmptyOk, fSuppressTopSpace, fswdir, num2, num3, ref fsrect, num5, ptr2, 0, 0, null, null, 0, null, null, PTS.FromBoolean(false), fsksuppresshardbreakbeforefirstparaIn, out fsfmtr, out pfspara, out pbrkrecOut, out dvrUsed, out fsbbox, out pmcsclientOut, out dvrTopSpace), base.PtsContext);
            }

            base.StructuralCache.CurrentFormatContext.PopPageData();
            fskclearOut = PTS.FSKCLEAR.fskclearNone;
            if (PTS.ToBoolean(fsbbox.fDefined))
            {
                dvrUsed       = Math.Max(dvrUsed, fsbbox.fsrc.dv + fsbbox.fsrc.v);
                fsrcToFill.du = Math.Max(fsrcToFill.du, fsbbox.fsrc.du + fsbbox.fsrc.u);
            }
            if (pbrkrecIn == IntPtr.Zero)
            {
                dvrTopSpace = ((mbpInfo.BPTop != 0) ? num4 : dvrTopSpace);
                dvrUsed    += num4 + mbpInfo.BPTop;
            }
            if (pmcsclientOut != IntPtr.Zero)
            {
                marginCollapsingState = (base.PtsContext.HandleToObject(pmcsclientOut) as MarginCollapsingState);
                PTS.ValidateHandle(marginCollapsingState);
                pmcsclientOut = IntPtr.Zero;
            }
            if (fsfmtr.kstop >= PTS.FSFMTRKSTOP.fmtrNoProgressOutOfSpace)
            {
                dvrUsed = (dvrTopSpace = 0);
            }
            else
            {
                if (fsfmtr.kstop == PTS.FSFMTRKSTOP.fmtrGoalReached)
                {
                    MarginCollapsingState marginCollapsingState2;
                    int num6;
                    MarginCollapsingState.CollapseBottomMargin(base.PtsContext, mbpInfo, marginCollapsingState, out marginCollapsingState2, out num6);
                    pmcsclientOut = ((marginCollapsingState2 != null) ? marginCollapsingState2.Handle : IntPtr.Zero);
                    if (pmcsclientOut == IntPtr.Zero)
                    {
                        dvrUsed += num6 + mbpInfo.BPBottom;
                    }
                }
                fsbbox.fsrc.u  = fsrcToFill.u + mbpInfo.MarginLeft;
                fsbbox.fsrc.v  = fsrcToFill.v + dvrTopSpace;
                fsbbox.fsrc.du = Math.Max(fsrcToFill.du - (mbpInfo.MarginLeft + mbpInfo.MarginRight), 0);
                fsbbox.fsrc.dv = Math.Max(dvrUsed - dvrTopSpace, 0);
            }
            if (num != fswdir)
            {
                PTS.FSRECT pageRect2 = base.StructuralCache.CurrentFormatContext.PageRect;
                PTS.Validate(PTS.FsTransformBbox(num, ref pageRect2, ref fsbbox, fswdir, out fsbbox));
            }
            if (marginCollapsingState != null)
            {
                marginCollapsingState.Dispose();
                marginCollapsingState = null;
            }
            paraClient.SetChunkInfo(pbrkrecIn == IntPtr.Zero, pbrkrecOut == IntPtr.Zero);
        }
Example #30
0
        /// <summary>
        /// Return next TextRun at element edge start position
        /// </summary>
        /// <param name="position">
        /// Current position in text array
        /// </param>
        protected TextRun HandleElementStartEdge(StaticTextPointer position)
        {
            Invariant.Assert(position.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.ElementStart, "TextPointer does not point to element start edge.");

            //      In the future, handle visibility collapsed.
            TextRun     run     = null;
            TextElement element = (TextElement)position.GetAdjacentElement(LogicalDirection.Forward);

            Debug.Assert(element != null, "Cannot use ITextContainer that does not provide TextElement instances.");

            Invariant.Assert(!(element is Block), "We do not expect any Blocks inside Paragraphs");

            // Treat figure and floaters as special hidden runs.
            if (element is Figure || element is Floater)
            {
                // Get the length of the element
                int cch = TextContainerHelper.GetElementLength(_paraClient.Paragraph.StructuralCache.TextContainer, element);
                // Create special hidden run.
                run = new FloatingRun(cch, element is Figure);
                if (element is Figure)
                {
                    _hasFigures = true;
                }
                else
                {
                    _hasFloaters = true;
                }
            }
            else if (element is LineBreak)
            {
                int cch = TextContainerHelper.GetElementLength(_paraClient.Paragraph.StructuralCache.TextContainer, element);
                run = new LineBreakRun(cch, PTS.FSFLRES.fsflrSoftBreak);
            }
            else if (element.IsEmpty)
            {
                // Empty TextElement should affect line metrics.
                // TextFormatter does not support this feature right now, so as workaround
                // TextRun with ZERO WIDTH SPACE is used.
                TextProperties textProps = new TextProperties(element, position, false /* inline objects */, true /* get background */,
                                                              _paraClient.Paragraph.StructuralCache.TextFormatterHost.PixelsPerDip);

                char[] textBuffer = new char[_elementEdgeCharacterLength * 2];

                // Assert that _elementEdgeCharacterLength is 1 before we use hard-coded indices
                Invariant.Assert(_elementEdgeCharacterLength == 1, "Expected value of _elementEdgeCharacterLength is 1");

                textBuffer[0] = (char)0x200B;
                textBuffer[1] = (char)0x200B;

                run = new TextCharacters(textBuffer, 0, textBuffer.Length, textProps);
            }
            else
            {
                Inline           inline = (Inline)element;
                DependencyObject parent = inline.Parent;

                FlowDirection inlineFlowDirection = inline.FlowDirection;
                FlowDirection parentFlowDirection = inlineFlowDirection;

                TextDecorationCollection inlineTextDecorations = DynamicPropertyReader.GetTextDecorations(inline);

                if (parent != null)
                {
                    parentFlowDirection = (FlowDirection)parent.GetValue(FrameworkElement.FlowDirectionProperty);
                }

                if (inlineFlowDirection != parentFlowDirection)
                {
                    // Inline's flow direction is different from its parent. Need to create new TextSpanModifier with flow direction
                    if (inlineTextDecorations == null || inlineTextDecorations.Count == 0)
                    {
                        run = new TextSpanModifier(
                            _elementEdgeCharacterLength,
                            null,
                            null,
                            inlineFlowDirection
                            );
                    }
                    else
                    {
                        run = new TextSpanModifier(
                            _elementEdgeCharacterLength,
                            inlineTextDecorations,
                            inline.Foreground,
                            inlineFlowDirection
                            );
                    }
                }
                else
                {
                    if (inlineTextDecorations == null || inlineTextDecorations.Count == 0)
                    {
                        run = new TextHidden(_elementEdgeCharacterLength);
                    }
                    else
                    {
                        run = new TextSpanModifier(
                            _elementEdgeCharacterLength,
                            inlineTextDecorations,
                            inline.Foreground
                            );
                    }
                }
            }
            return(run);
        }