internal LsErr GetRunStrikethroughInfo( IntPtr pols, // Line Layout context Plsrun plsrun, // plsrun ref LsHeights lsHeights, // run height LsTFlow textFlow, // text flow direction ref LsStInfo stInfo // [out] result strikethrough info ) { LsErr lserr = LsErr.None; LSRun lsrun = null; try { lsrun = Draw.CurrentLine.GetRun(plsrun); Debug.Assert( !TextStore.IsContent(plsrun) || lsrun.Type == Plsrun.Text || lsrun.Type == Plsrun.InlineObject, "Invalid run" ); stInfo = new LsStInfo(); double strikeThroughPositionInEm; double strikeThroughThicknessInEm; GetLSRunStrikethroughMetrics(lsrun, out strikeThroughPositionInEm, out strikeThroughThicknessInEm); stInfo.cNumberOfLines = 1; stInfo.dvpLowerStrikethroughOffset = (int)Math.Round(lsrun.EmSize * strikeThroughPositionInEm); stInfo.dvpLowerStrikethroughSize = (int)Math.Round(lsrun.EmSize * strikeThroughThicknessInEm); Debug.Assert(stInfo.dvpLowerStrikethroughSize >= 0); if (stInfo.dvpLowerStrikethroughSize <= 0) stInfo.dvpLowerStrikethroughSize = 1; } catch (Exception e) { SaveException(e, plsrun, lsrun); lserr = LsErr.ClientAbort; } catch { SaveNonCLSException("GetRunStrikethroughInfo", plsrun, lsrun); lserr = LsErr.ClientAbort; } return lserr; }
internal LsErr GetRunUnderlineInfo( IntPtr pols, // Line Layout context Plsrun plsrun, // plsrun ref LsHeights lsHeights, // run height LsTFlow textFlow, // text flow direction ref LsULInfo ulInfo // [out] result underline info ) { LsErr lserr = LsErr.None; LSRun lsrun = null; try { lsrun = Draw.CurrentLine.GetRun(plsrun); Debug.Assert( !TextStore.IsContent(plsrun) || lsrun.Type == Plsrun.Text || lsrun.Type == Plsrun.InlineObject, "Invalid run" ); ulInfo = new LsULInfo(); double underlinePositionInEm; double underlineThicknessInEm; if (lsrun.Shapeable != null) { underlinePositionInEm = lsrun.Shapeable.UnderlinePosition; underlineThicknessInEm = lsrun.Shapeable.UnderlineThickness; } else { underlinePositionInEm = lsrun.RunProp.Typeface.UnderlinePosition; underlineThicknessInEm = lsrun.RunProp.Typeface.UnderlineThickness; } ulInfo.cNumberOfLines = 1; ulInfo.dvpFirstUnderlineOffset = (int)Math.Round(lsrun.EmSize * -underlinePositionInEm); ulInfo.dvpFirstUnderlineSize = (int)Math.Round(lsrun.EmSize * underlineThicknessInEm); Debug.Assert(ulInfo.dvpFirstUnderlineSize >= 0); if (ulInfo.dvpFirstUnderlineSize <= 0) ulInfo.dvpFirstUnderlineSize = 1; } catch (Exception e) { SaveException(e, plsrun, lsrun); lserr = LsErr.ClientAbort; } catch { SaveNonCLSException("GetAutoNumberInfo", plsrun, lsrun); lserr = LsErr.ClientAbort; } return lserr; }
internal unsafe LsErr EnumTab( IntPtr pols, // pointer to context Plsrun plsrun, // plsrun int cpFirst, // first cp of the dnode run char *pwchText, // a single tab character char tabLeader, // a single tab leader character LsTFlow lstFlow, // flow direction int fReverseOrder, // flag for reverse order enumeration int fGeometryProvided, // flag for providing geometry information ref LSPOINT pptStart, // [in] logical start of the run (iff geometryProvided) ref LsHeights heights, // [in] height (iff geometryProvided) int dupRun // width of the run ) { if (cpFirst < 0) { return LsErr.None; } LsErr lserr = LsErr.None; LSRun lsrun = null; try { TextMetrics.FullTextLine currentLine = Draw.CurrentLine; lsrun = currentLine.GetRun(plsrun); GlyphRun glyphRun = null; if (lsrun.Type == Plsrun.Text) { int charWidth = 0; lsrun.Shapeable.GetAdvanceWidthsUnshaped( &tabLeader, 1, TextFormatterImp.ToIdeal, &charWidth ); glyphRun = ComputeUnshapedGlyphRun( lsrun, lstFlow, currentLine.Formatter, false, // glyph run origin not provided at enumeration time pptStart, charWidth, 1, &tabLeader, &charWidth, currentLine.IsJustified ); } if (glyphRun != null) { IndexedGlyphRuns.Add( new IndexedGlyphRun( currentLine.GetExternalCp(cpFirst), 1, // dcp is 1 for a Tab character glyphRun ) ); } } catch (Exception e) { SaveException(e, plsrun, lsrun); lserr = LsErr.ClientAbort; } catch { SaveNonCLSException("EnumTab", plsrun, lsrun); lserr = LsErr.ClientAbort; } return lserr; }
internal unsafe LsErr EnumText( IntPtr pols, // ls context Plsrun plsrun, // plsrun int cpFirst, // first cp of the ls dnode int dcp, // dcp of the dnode char *pwchText, // characters for glyph run int cchText, // length of characters LsTFlow lstFlow, // flow direction int fReverseOrder, // flag for reverse order enumeration int fGeometryProvided, // flag for providing geometry ref LSPOINT pptStart, // [in] logical start of the run ref LsHeights pheights, // [in] height (iff geometryProvided) int dupRun, // width of the run int glyphBaseRun, // flag for glyph based run int *piCharAdvances, // character advance widths (iff !glyphBaseRun) ushort *puClusterMap, // cluster map (iff glyphBaseRun) ushort *characterProperties, // character properties (iff glyphBaseRun) ushort *puGlyphs, // glyph indices (iff glyphBaseRun) int *piJustifiedGlyphAdvances, // glyph advances (iff glyphBaseRun) GlyphOffset *piiGlyphOffsets, // glyph offsets (iff glyphBaseRun) uint *piGlyphProperties, // glyph properties (iff glyphProperties) int glyphCount // glyph count ) { Debug.Assert(fGeometryProvided == 0, "Line enumeration doesn't need geometry information"); if (cpFirst < 0) { return LsErr.None; } LsErr lserr = LsErr.None; LSRun lsrun = null; try { TextMetrics.FullTextLine currentLine = Draw.CurrentLine; lsrun = currentLine.GetRun(plsrun); GlyphRun glyphRun = null; if (glyphBaseRun != 0) { if (glyphCount > 0) { glyphRun = ComputeShapedGlyphRun( lsrun, currentLine.Formatter, false, // glyph run origin not provided pptStart, cchText, pwchText, puClusterMap, glyphCount, puGlyphs, piJustifiedGlyphAdvances, piiGlyphOffsets, currentLine.IsJustified ); } } else if (cchText > 0) { dupRun = 0; for (int i = 0; i < cchText; i++) { dupRun += piCharAdvances[i]; } glyphRun = ComputeUnshapedGlyphRun( lsrun, lstFlow, currentLine.Formatter, false, // glyph run origin not provided at enumeration pptStart, dupRun, cchText, pwchText, piCharAdvances, currentLine.IsJustified ); } if (glyphRun != null) { IndexedGlyphRuns.Add( new IndexedGlyphRun( currentLine.GetExternalCp(cpFirst), dcp, glyphRun ) ); } } catch (Exception e) { SaveException(e, plsrun, lsrun); lserr = LsErr.ClientAbort; } catch { SaveNonCLSException("EnumText", plsrun, lsrun); lserr = LsErr.ClientAbort; } return lserr; }
internal unsafe LsErr DrawGlyphs( IntPtr pols, // Line Layout context Plsrun plsrun, // plsrun char* pwchText, // character string ushort* puClusterMap, // character-to-cluster map ushort* puCharProperties, // character properties int charCount, // character count ushort* puGlyphs, // glyph indices int* piJustifiedGlyphAdvances, // justified glyph advances int* piGlyphAdvances, // original ideal glyph advances GlyphOffset* piiGlyphOffsets, // glyph offsets uint* piGlyphProperties, // glyph properties LsExpType* plsExpType, // glyph expansion types int glyphCount, // glyph count LsTFlow textFlow, // text flow uint displayMode, // draw transparent or opaque ref LSPOINT ptRun, // [in] display position (at baseline) ref LsHeights lsHeights, // [in] run height metrics int runWidth, // run overall advance width ref LSRECT clippingRect // [in] clipping rectangle if any applied ) { LsErr lserr = LsErr.None; LSRun lsrun = null; try { TextMetrics.FullTextLine currentLine = Draw.CurrentLine; lsrun = currentLine.GetRun(plsrun); Debug.Assert(TextStore.IsContent(plsrun) && lsrun.Shapeable != null); GlyphRun glyphRun = ComputeShapedGlyphRun( lsrun, currentLine.Formatter, true, // origin of the glyph run provided at drawing time ptRun, charCount, pwchText, puClusterMap, glyphCount, puGlyphs, piJustifiedGlyphAdvances, piiGlyphOffsets, currentLine.IsJustified ); if (glyphRun != null) { DrawingContext drawingContext = Draw.DrawingContext; Draw.SetGuidelineY(glyphRun.BaselineOrigin.Y); try { _boundingBox.Union( lsrun.DrawGlyphRun( drawingContext, null, // draw with the run's foreground glyphRun ) ); } finally { Draw.UnsetGuidelineY(); } } } catch (Exception e) { SaveException(e, plsrun, lsrun); lserr = LsErr.ClientAbort; } catch { SaveNonCLSException("DrawGlyphs", plsrun, lsrun); lserr = LsErr.ClientAbort; } return lserr; }
internal unsafe LsErr DrawTextRun( IntPtr pols, // Line Layout context Plsrun plsrun, // plsrun ref LSPOINT ptText, // [in] text origin char* pwchText, // character string int* piCharAdvances, // char advance widths int cchText, // text length LsTFlow textFlow, // text flow uint displayMode, // draw in transparent or opaque ref LSPOINT ptRun, // [in] run origin ref LsHeights lsHeights, // [in] run height int dupRun, // run length ref LSRECT clipRect // [in] from DisplayLine's clip rectangle param ) { LsErr lserr = LsErr.None; LSRun lsrun = null; try { TextMetrics.FullTextLine currentLine = Draw.CurrentLine; lsrun = currentLine.GetRun(plsrun); GlyphRun glyphRun = ComputeUnshapedGlyphRun( lsrun, textFlow, currentLine.Formatter, true, // origin of the glyph run provided at drawing time ptText, dupRun, cchText, pwchText, piCharAdvances, currentLine.IsJustified ); if (glyphRun != null) { DrawingContext drawingContext = Draw.DrawingContext; Draw.SetGuidelineY(glyphRun.BaselineOrigin.Y); try { _boundingBox.Union( lsrun.DrawGlyphRun( drawingContext, null, // draw with the run's foreground brush glyphRun ) ); } finally { Draw.UnsetGuidelineY(); } } } catch (Exception e) { SaveException(e, plsrun, lsrun); lserr = LsErr.ClientAbort; } catch { SaveNonCLSException("DrawTextRun", plsrun, lsrun); lserr = LsErr.ClientAbort; } return lserr; }