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