/// <summary> /// Compile feature set from the linked list of LSRuns. /// TypographyProperties should be either all null or all not-null. /// First is used for internal purposes, also can be used by simple clients. /// </summary> internal static void CompileFeatureSet( TextRunTypographyProperties textRunTypographyProperties, uint totalLength, out DWriteFontFeature[][] fontFeatures, out uint[] fontFeatureRanges ) { // // Quick check for null properties // Run properties should be all null or all not null // if (textRunTypographyProperties == null) { fontFeatures = null; fontFeatureRanges = null; } else { // End of quick check. We will process custom features now. fontFeatures = new DWriteFontFeature[1][]; fontFeatureRanges = new uint[1]; fontFeatures[0] = CreateDWriteFontFeatures(textRunTypographyProperties); fontFeatureRanges[0] = totalLength; } }
internal static unsafe void CompileFeatureSet( LSRun[] lsruns, int *pcchRuns, uint totalLength, out DWriteFontFeature[][] fontFeatures, out uint[] fontFeatureRanges ) { Debug.Assert(lsruns != null && lsruns.Length > 0 && lsruns[0] != null); // // Quick check for null properties // Run properties should be all null or all not null // if (lsruns[0].RunProp.TypographyProperties == null) { for (int i = 1; i < lsruns.Length; i++) { if (lsruns[i].RunProp.TypographyProperties != null) { throw new ArgumentException(SR.Get(SRID.CompileFeatureSet_InvalidTypographyProperties)); } } fontFeatures = null; fontFeatureRanges = null; return; } //End of quick check. We will process custom features now. fontFeatures = new DWriteFontFeature[lsruns.Length][]; fontFeatureRanges = new uint[lsruns.Length]; for (int i = 0; i < lsruns.Length; i++) { TextRunTypographyProperties properties = lsruns[i].RunProp.TypographyProperties; fontFeatures[i] = CreateDWriteFontFeatures(properties); fontFeatureRanges[i] = checked ((uint)pcchRuns[i]); } }
/// <summary> /// Construct a formatted run /// </summary> public FormattedTextSymbols( GlyphingCache glyphingCache, TextRun textSymbols, CharacterBufferRange chars, bool rightToLeft, double scalingFactor, float pixelsPerDip, TextFormattingMode textFormattingMode, bool isSideways ) { _textFormattingMode = textFormattingMode; _isSideways = isSideways; ITextSymbols symbols = textSymbols as ITextSymbols; Debug.Assert(symbols != null); // break down a single text run into pieces IList <TextShapeableSymbols> shapeables = symbols.GetTextShapeableSymbols( glyphingCache, chars.CharacterBufferReference, chars.Length, rightToLeft, // This is a bool indicating the RTL // based on the bidi level of text (if applicable). // For FormattedTextSymbols it is equal to paragraph flow direction. rightToLeft, // This is the flow direction of the paragraph as // specified by the user. DWrite needs the paragraph // flow direction of the paragraph // while WPF algorithms need the RTL of the text based on // Bidi if possible. null, // cultureInfo null, // textModifierScope _textFormattingMode, _isSideways ); Debug.Assert(shapeables != null && shapeables.Count > 0); _rightToLeft = rightToLeft; _glyphs = new Glyphs[shapeables.Count]; CharacterBuffer charBuffer = chars.CharacterBuffer; int offsetToFirstChar = chars.OffsetToFirstChar; int i = 0; int ich = 0; while (i < shapeables.Count) { TextShapeableSymbols current = shapeables[i] as TextShapeableSymbols; Debug.Assert(current != null); int cch = current.Length; int j; // make a separate character buffer for glyphrun persistence char[] charArray = new char[cch]; for (j = 0; j < cch; j++) { charArray[j] = charBuffer[offsetToFirstChar + ich + j]; } if (current.IsShapingRequired) { ushort[] clusterMap; ushort[] glyphIndices; int[] glyphAdvances; GlyphOffset[] glyphOffsets; // Note that we dont check for the chance of having multiple // shapeables shaped together here since we're dealing with // single-style text. There is virtually no chance to require // for adjacent runs to shape together. We rely on TextSymbols // to reduce duplication of the itemized shapeables for performance. unsafe { fixed(char *fixedCharArray = &charArray[0]) { MS.Internal.Text.TextInterface.TextAnalyzer textAnalyzer = MS.Internal.FontCache.DWriteFactory.Instance.CreateTextAnalyzer(); GlyphTypeface glyphTypeface = current.GlyphTypeFace; DWriteFontFeature[][] fontFeatures; uint[] fontFeatureRanges; uint unsignedCch = checked ((uint)cch); //LSRun.CompileFeatureSet(current.Properties.TypographyProperties, unsignedCch, out fontFeatures, out fontFeatureRanges); fontFeatures = new DWriteFontFeature[0][]; fontFeatureRanges = new uint[0]; textAnalyzer.GetGlyphsAndTheirPlacements( new IntPtr(fixedCharArray), unsignedCch, glyphTypeface.FontDWrite, glyphTypeface.BlankGlyphIndex, false, // no sideway support yet /************************************************************************************************/ // Should we break down the runs to know whats the Bidi for every range of characters? rightToLeft, current.Properties.CultureInfo, /************************************************************************************************/ fontFeatures, fontFeatureRanges, current.Properties.FontRenderingEmSize, scalingFactor, pixelsPerDip, _textFormattingMode, current.ItemProps, out clusterMap, out glyphIndices, out glyphAdvances, out glyphOffsets ); } _glyphs[i] = new Glyphs( current, charArray, glyphAdvances, clusterMap, glyphIndices, glyphOffsets, scalingFactor ); } } else { // shaping not required, // bypass glyphing process altogether int[] nominalAdvances = new int[charArray.Length]; unsafe { fixed(char *fixedCharArray = &charArray[0]) fixed(int *fixedNominalAdvances = &nominalAdvances[0]) { current.GetAdvanceWidthsUnshaped( fixedCharArray, cch, scalingFactor, // format resolution specified per em, fixedNominalAdvances ); } } _glyphs[i] = new Glyphs( current, charArray, nominalAdvances, scalingFactor ); } i++; ich += cch; } }
internal static unsafe void CompileFeatureSet( LSRun[] lsruns, int* pcchRuns, uint totalLength, out DWriteFontFeature[][] fontFeatures, out uint[] fontFeatureRanges ) { Debug.Assert(lsruns != null && lsruns.Length > 0 && lsruns[0] != null); // // Quick check for null properties // Run properties should be all null or all not null // if (lsruns[0].RunProp.TypographyProperties == null) { for (int i = 1; i < lsruns.Length; i++) { if (lsruns[i].RunProp.TypographyProperties != null) { throw new ArgumentException(SR.Get(SRID.CompileFeatureSet_InvalidTypographyProperties)); } } fontFeatures = null; fontFeatureRanges = null; return; } //End of quick check. We will process custom features now. fontFeatures = new DWriteFontFeature[lsruns.Length][]; fontFeatureRanges = new uint[lsruns.Length]; for (int i = 0; i < lsruns.Length; i++) { TextRunTypographyProperties properties = lsruns[i].RunProp.TypographyProperties; fontFeatures[i] = CreateDWriteFontFeatures(properties); fontFeatureRanges[i] = checked((uint)pcchRuns[i]); } }
public void AddFontFeature(DWriteFontFeature fontFeature) { this.handle.AddFontFeature(fontFeature); }