Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Core / CSharp / MS / Internal / TextFormatting / TextShapeableCharacters.cs / 1599983 / TextShapeableCharacters.cs
//------------------------------------------------------------------------ // // Microsoft Windows Client Platform // Copyright (C) Microsoft Corporation // // File: TextShapeableCharacters.cs // // Contents: Implementation of text shapeable symbols for characters // // Spec: http://team/sites/Avalon/Specs/Text%20Formatting%20API.doc // // Created: 1-2-2004 Worachai Chaoweeraprasit (wchao) // History: 1-19-2004 garyyyang: Change the class to internal // //----------------------------------------------------------------------- using System; using System.Diagnostics; using System.Globalization; using System.Collections; using System.Collections.Generic; using System.Security; using System.Windows; using System.Windows.Markup; // for XmlLanguage using System.Windows.Media; using MS.Internal; using MS.Internal.FontCache; using MS.Internal.TextFormatting; using MS.Internal.Shaping; using MS.Internal.Text.TextInterface; namespace System.Windows.Media.TextFormatting { ////// A specialized TextShapeableSymbols implemented by TextFormatter to represent /// a collection of glyphs from a physical typeface. /// internal sealed class TextShapeableCharacters : TextShapeableSymbols { private CharacterBufferRange _characterBufferRange; private TextFormattingMode _textFormattingMode; private bool _isSideways; private TextRunProperties _properties; private double _emSize; // after-scaled private ItemProps _textItem; private ShapeTypeface _shapeTypeface; private bool _nullShape; #region Constructors ////// Construct a shapeable characters object /// ////// The shapeTypeface parameter can be null if and only if CheckFastPathNominalGlyphs /// has previously returned true. /// internal TextShapeableCharacters( CharacterBufferRange characterRange, TextRunProperties properties, double emSize, ItemProps textItem, ShapeTypeface shapeTypeface, bool nullShape, TextFormattingMode textFormattingMode, bool isSideways ) { _isSideways = isSideways; _textFormattingMode = textFormattingMode; _characterBufferRange = characterRange; _properties = properties; _emSize = emSize; _textItem = textItem; _shapeTypeface = shapeTypeface; _nullShape = nullShape; } #endregion #region TextRun implementation ////// Character reference /// public sealed override CharacterBufferReference CharacterBufferReference { get { return _characterBufferRange.CharacterBufferReference; } } ////// Character length of the run /// public sealed override int Length { get { return _characterBufferRange.Length; } } ////// A set of properties shared by every characters in the run /// public sealed override TextRunProperties Properties { get { return _properties; } } #endregion #region TextShapeableSymbols implementation ////// Compute a shaped glyph run object from specified glyph-based info /// internal sealed override GlyphRun ComputeShapedGlyphRun( Point origin, char[] characterString, ushort[] clusterMap, ushort[] glyphIndices, IListglyphAdvances, IList glyphOffsets, bool rightToLeft, bool sideways ) { Invariant.Assert(_shapeTypeface != null); Invariant.Assert(glyphIndices != null); // Device fonts are only used through the LS non-glyphed code path. Only when a DigitCulture is set // will a potential device font be ignored and come through shaping. Invariant.Assert(_shapeTypeface.DeviceFont == null || _textItem.DigitCulture != null); bool[] caretStops = null; if ( clusterMap != null && (HasExtendedCharacter || NeedsCaretInfo) ) { caretStops = new bool[clusterMap.Length + 1]; // caret stops at cluster boundaries, the first and the last entries are always set caretStops[0] = true; caretStops[clusterMap.Length] = true; ushort lastGlyph = clusterMap[0]; for (int i = 1; i < clusterMap.Length; i++) { ushort glyph = clusterMap[i]; if (glyph != lastGlyph) { caretStops[i] = true; lastGlyph = glyph; } } } return GlyphRun.TryCreate( _shapeTypeface.GlyphTypeface, (rightToLeft ? 1 : 0), sideways, _emSize, glyphIndices, origin, glyphAdvances, glyphOffsets, characterString, null, clusterMap, caretStops, XmlLanguage.GetLanguage(CultureMapper.GetSpecificCulture(_properties.CultureInfo).IetfLanguageTag), _textFormattingMode ); } private GlyphTypeface GetGlyphTypeface(out bool nullFont) { GlyphTypeface glyphTypeface; if (_shapeTypeface == null) { // We're in the optimized path where the GlyphTypeface depends only // on the Typeface, not on the particular input characters. Typeface typeface = _properties.Typeface; // Get the GlyphTypeface. glyphTypeface = typeface.TryGetGlyphTypeface(); // If Typeface does not specify *any* valid font family, then we use // the GlyphTypeface for Arial but only to display missing glyphs. nullFont = typeface.NullFont; } else { // Font linking has mapped the input to a specific GlyphTypeface. glyphTypeface = _shapeTypeface.GlyphTypeface; // If font linking could not find *any* physical font family, then we // use the GlyphTypeface for Arial but only to display missing glyphs. nullFont = _nullShape; } Invariant.Assert(glyphTypeface != null); return glyphTypeface; } /// /// Compute unshaped glyph run object from the specified character-based info /// internal sealed override GlyphRun ComputeUnshapedGlyphRun( Point origin, char[] characterString, IListcharacterAdvances ) { bool nullFont; GlyphTypeface glyphTypeface = GetGlyphTypeface(out nullFont); Invariant.Assert(glyphTypeface != null); return glyphTypeface.ComputeUnshapedGlyphRun( origin, new CharacterBufferRange( characterString, 0, // offsetToFirstChar characterString.Length ), characterAdvances, _emSize, _properties.FontHintingEmSize, nullFont, CultureMapper.GetSpecificCulture(_properties.CultureInfo), (_shapeTypeface == null || _shapeTypeface.DeviceFont == null) ? null : _shapeTypeface.DeviceFont.Name, _textFormattingMode ); } /// /// Draw glyph run to the drawing surface /// internal sealed override void Draw( DrawingContext drawingContext, Brush foregroundBrush, GlyphRun glyphRun ) { if (drawingContext == null) throw new ArgumentNullException("drawingContext"); glyphRun.EmitBackground(drawingContext, _properties.BackgroundBrush); drawingContext.DrawGlyphRun( foregroundBrush != null ? foregroundBrush : _properties.ForegroundBrush, glyphRun ); } internal override double EmSize { get { return _emSize; } } internal override MS.Internal.Text.TextInterface.ItemProps ItemProps { get { return _textItem; } } ////// Get advance widths of unshaped characters /// ////// Critical: This code deals with pointers and calls SC methods like GetAdvanceWidthsUnshaped /// [SecurityCritical] internal sealed override unsafe void GetAdvanceWidthsUnshaped( char* characterString, int characterLength, double scalingFactor, int* advanceWidthsUnshaped ) { if (!IsShapingRequired) { if ( (_shapeTypeface != null) && (_shapeTypeface.DeviceFont != null)) { // Use device font to compute advance widths _shapeTypeface.DeviceFont.GetAdvanceWidths( characterString, characterLength, _emSize * scalingFactor, advanceWidthsUnshaped ); } else { bool nullFont; GlyphTypeface glyphTypeface = GetGlyphTypeface(out nullFont); Invariant.Assert(glyphTypeface != null); glyphTypeface.GetAdvanceWidthsUnshaped( characterString, characterLength, _emSize, scalingFactor, advanceWidthsUnshaped, nullFont, _textFormattingMode, _isSideways ); } } else { GlyphTypeface glyphTypeface = _shapeTypeface.GlyphTypeface; Invariant.Assert(glyphTypeface != null); Invariant.Assert(characterLength > 0); CharacterBufferRange newBuffer = new CharacterBufferRange(characterString, characterLength); MS.Internal.Text.TextInterface.GlyphMetrics[] glyphMetrics = BufferCache.GetGlyphMetrics(characterLength); glyphTypeface.GetGlyphMetricsOptimized(newBuffer, _emSize, _textFormattingMode, _isSideways, glyphMetrics ); double designToEm = _emSize * scalingFactor / glyphTypeface.DesignEmHeight; for (int i = 0; i < characterLength; i++) { advanceWidthsUnshaped[i] = (int)Math.Round(glyphMetrics[i].AdvanceWidth * designToEm); } BufferCache.ReleaseGlyphMetrics(glyphMetrics); } } ////// This is needed to decide whether we should pass a max cluster size to LS. /// We pass a max cluster size to LS to perform line breaking correctly. /// Passing a max cluster size larger than necessary will have impact on perf. /// internal sealed override bool NeedsMaxClusterSize { get { // We will need to pass a max cluster size to LS if: // 1) the script is not Latin (hence more likely to formed into ligature) // 2) or the run contains combining mark or extended characters if (!_textItem.IsLatin || _textItem.HasCombiningMark || _textItem.HasExtendedCharacter ) { return true; } return false; } } ////// Return value indicates whether two runs can shape together /// internal sealed override bool CanShapeTogether( TextShapeableSymbols shapeable ) { TextShapeableCharacters charShape = shapeable as TextShapeableCharacters; if (charShape == null) return false; return _shapeTypeface.Equals(charShape._shapeTypeface) // Extended characters need to be shaped by surrogate shaper. They cannot be shaped together with non-exteneded characters. && (_textItem.HasExtendedCharacter) == (charShape._textItem.HasExtendedCharacter) && _emSize == charShape._emSize && ( _properties.CultureInfo == null ? charShape._properties.CultureInfo == null : _properties.CultureInfo.Equals(charShape._properties.CultureInfo) ) && _nullShape == charShape._nullShape && (_textItem.CanShapeTogether(charShape._textItem)); } ////// Indicate whether run cannot be treated as simple characters because shaping is required. /// /// The following cases use simple rendering without shaping: /// o No _shapeTypeface. This happens in very simple rendering cases. /// o Non-Unicode (i.e. symbol) fonts. /// o When using a device font. /// /// Note that the presence of a device font in _shapeTypeface.DeviceFont implies use of /// a device font in all cases except where digit substitution applies. This special /// case occurs because the cached result per codepoint of TypefaceMap must include the device font /// for non-western digits in order to support device font rendering of the non-Western /// digit Unicode codepoints. The device font is not used however when the non-Western digits /// are displayed as a result of digit substitution from backing store Western digits. /// internal sealed override bool IsShapingRequired { get { return (_shapeTypeface != null) // Can't use shaping without a shape typeface && ( (_shapeTypeface.DeviceFont == null) // Can't use shaping when rendering with a device font || (_textItem.DigitCulture != null)) // -- unless substituting digits && (!IsSymbol); // Can't use shaping for symbol (non-Unicode) fonts } } ////// A Boolean value indicates whether additional info is required for caret positioning /// internal sealed override bool NeedsCaretInfo { get { return (_textItem.HasCombiningMark) || (_textItem.NeedsCaretInfo); } } ////// A Boolean value indicates whether run has extended character /// internal sealed override bool HasExtendedCharacter { get { return _textItem.HasExtendedCharacter; } } ////// Run height /// internal sealed override double Height { get { return _properties.Typeface.LineSpacing(_properties.FontRenderingEmSize, 1, Util.PixelsPerDip, _textFormattingMode); } } ////// Distance from top to baseline /// internal sealed override double Baseline { get { return _properties.Typeface.Baseline(_properties.FontRenderingEmSize, 1, Util.PixelsPerDip, _textFormattingMode); } } ////// Distance from baseline to underline position relative to TextRunProperties.FontRenderingEmSize /// internal sealed override double UnderlinePosition { get { return _properties.Typeface.UnderlinePosition; } } ////// Underline thickness relative to TextRunProperties.FontRenderingEmSize /// internal sealed override double UnderlineThickness { get { return _properties.Typeface.UnderlineThickness; } } ////// Distance from baseline to strike-through position relative to TextRunProperties.FontRenderingEmSize /// internal sealed override double StrikethroughPosition { get { return _properties.Typeface.StrikethroughPosition; } } ////// strike-through thickness relative to TextRunProperties.FontRenderingEmSize /// internal sealed override double StrikethroughThickness { get { return _properties.Typeface.StrikethroughThickness; } } #endregion ////// Whether all characters in this run are non-Unicode character (symbol) /// internal bool IsSymbol { get { if (_shapeTypeface != null) return _shapeTypeface.GlyphTypeface.Symbol; return _properties.Typeface.Symbol; } } internal override GlyphTypeface GlyphTypeFace { get { if (_shapeTypeface != null) return _shapeTypeface.GlyphTypeface; return _properties.Typeface.TryGetGlyphTypeface(); } } ////// Returns maximum possible cluster size for the run. Normally, this /// is 8 characters, but Indic scripts require this to be 15. /// internal const ushort DefaultMaxClusterSize = 8; private const ushort IndicMaxClusterSize = 15; internal sealed override ushort MaxClusterSize { get { if (_textItem.IsIndic) { return IndicMaxClusterSize; } return DefaultMaxClusterSize; } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. //------------------------------------------------------------------------ // // Microsoft Windows Client Platform // Copyright (C) Microsoft Corporation // // File: TextShapeableCharacters.cs // // Contents: Implementation of text shapeable symbols for characters // // Spec: http://team/sites/Avalon/Specs/Text%20Formatting%20API.doc // // Created: 1-2-2004 Worachai Chaoweeraprasit (wchao) // History: 1-19-2004 garyyyang: Change the class to internal // //----------------------------------------------------------------------- using System; using System.Diagnostics; using System.Globalization; using System.Collections; using System.Collections.Generic; using System.Security; using System.Windows; using System.Windows.Markup; // for XmlLanguage using System.Windows.Media; using MS.Internal; using MS.Internal.FontCache; using MS.Internal.TextFormatting; using MS.Internal.Shaping; using MS.Internal.Text.TextInterface; namespace System.Windows.Media.TextFormatting { ////// A specialized TextShapeableSymbols implemented by TextFormatter to represent /// a collection of glyphs from a physical typeface. /// internal sealed class TextShapeableCharacters : TextShapeableSymbols { private CharacterBufferRange _characterBufferRange; private TextFormattingMode _textFormattingMode; private bool _isSideways; private TextRunProperties _properties; private double _emSize; // after-scaled private ItemProps _textItem; private ShapeTypeface _shapeTypeface; private bool _nullShape; #region Constructors ////// Construct a shapeable characters object /// ////// The shapeTypeface parameter can be null if and only if CheckFastPathNominalGlyphs /// has previously returned true. /// internal TextShapeableCharacters( CharacterBufferRange characterRange, TextRunProperties properties, double emSize, ItemProps textItem, ShapeTypeface shapeTypeface, bool nullShape, TextFormattingMode textFormattingMode, bool isSideways ) { _isSideways = isSideways; _textFormattingMode = textFormattingMode; _characterBufferRange = characterRange; _properties = properties; _emSize = emSize; _textItem = textItem; _shapeTypeface = shapeTypeface; _nullShape = nullShape; } #endregion #region TextRun implementation ////// Character reference /// public sealed override CharacterBufferReference CharacterBufferReference { get { return _characterBufferRange.CharacterBufferReference; } } ////// Character length of the run /// public sealed override int Length { get { return _characterBufferRange.Length; } } ////// A set of properties shared by every characters in the run /// public sealed override TextRunProperties Properties { get { return _properties; } } #endregion #region TextShapeableSymbols implementation ////// Compute a shaped glyph run object from specified glyph-based info /// internal sealed override GlyphRun ComputeShapedGlyphRun( Point origin, char[] characterString, ushort[] clusterMap, ushort[] glyphIndices, IListglyphAdvances, IList glyphOffsets, bool rightToLeft, bool sideways ) { Invariant.Assert(_shapeTypeface != null); Invariant.Assert(glyphIndices != null); // Device fonts are only used through the LS non-glyphed code path. Only when a DigitCulture is set // will a potential device font be ignored and come through shaping. Invariant.Assert(_shapeTypeface.DeviceFont == null || _textItem.DigitCulture != null); bool[] caretStops = null; if ( clusterMap != null && (HasExtendedCharacter || NeedsCaretInfo) ) { caretStops = new bool[clusterMap.Length + 1]; // caret stops at cluster boundaries, the first and the last entries are always set caretStops[0] = true; caretStops[clusterMap.Length] = true; ushort lastGlyph = clusterMap[0]; for (int i = 1; i < clusterMap.Length; i++) { ushort glyph = clusterMap[i]; if (glyph != lastGlyph) { caretStops[i] = true; lastGlyph = glyph; } } } return GlyphRun.TryCreate( _shapeTypeface.GlyphTypeface, (rightToLeft ? 1 : 0), sideways, _emSize, glyphIndices, origin, glyphAdvances, glyphOffsets, characterString, null, clusterMap, caretStops, XmlLanguage.GetLanguage(CultureMapper.GetSpecificCulture(_properties.CultureInfo).IetfLanguageTag), _textFormattingMode ); } private GlyphTypeface GetGlyphTypeface(out bool nullFont) { GlyphTypeface glyphTypeface; if (_shapeTypeface == null) { // We're in the optimized path where the GlyphTypeface depends only // on the Typeface, not on the particular input characters. Typeface typeface = _properties.Typeface; // Get the GlyphTypeface. glyphTypeface = typeface.TryGetGlyphTypeface(); // If Typeface does not specify *any* valid font family, then we use // the GlyphTypeface for Arial but only to display missing glyphs. nullFont = typeface.NullFont; } else { // Font linking has mapped the input to a specific GlyphTypeface. glyphTypeface = _shapeTypeface.GlyphTypeface; // If font linking could not find *any* physical font family, then we // use the GlyphTypeface for Arial but only to display missing glyphs. nullFont = _nullShape; } Invariant.Assert(glyphTypeface != null); return glyphTypeface; } /// /// Compute unshaped glyph run object from the specified character-based info /// internal sealed override GlyphRun ComputeUnshapedGlyphRun( Point origin, char[] characterString, IListcharacterAdvances ) { bool nullFont; GlyphTypeface glyphTypeface = GetGlyphTypeface(out nullFont); Invariant.Assert(glyphTypeface != null); return glyphTypeface.ComputeUnshapedGlyphRun( origin, new CharacterBufferRange( characterString, 0, // offsetToFirstChar characterString.Length ), characterAdvances, _emSize, _properties.FontHintingEmSize, nullFont, CultureMapper.GetSpecificCulture(_properties.CultureInfo), (_shapeTypeface == null || _shapeTypeface.DeviceFont == null) ? null : _shapeTypeface.DeviceFont.Name, _textFormattingMode ); } /// /// Draw glyph run to the drawing surface /// internal sealed override void Draw( DrawingContext drawingContext, Brush foregroundBrush, GlyphRun glyphRun ) { if (drawingContext == null) throw new ArgumentNullException("drawingContext"); glyphRun.EmitBackground(drawingContext, _properties.BackgroundBrush); drawingContext.DrawGlyphRun( foregroundBrush != null ? foregroundBrush : _properties.ForegroundBrush, glyphRun ); } internal override double EmSize { get { return _emSize; } } internal override MS.Internal.Text.TextInterface.ItemProps ItemProps { get { return _textItem; } } ////// Get advance widths of unshaped characters /// ////// Critical: This code deals with pointers and calls SC methods like GetAdvanceWidthsUnshaped /// [SecurityCritical] internal sealed override unsafe void GetAdvanceWidthsUnshaped( char* characterString, int characterLength, double scalingFactor, int* advanceWidthsUnshaped ) { if (!IsShapingRequired) { if ( (_shapeTypeface != null) && (_shapeTypeface.DeviceFont != null)) { // Use device font to compute advance widths _shapeTypeface.DeviceFont.GetAdvanceWidths( characterString, characterLength, _emSize * scalingFactor, advanceWidthsUnshaped ); } else { bool nullFont; GlyphTypeface glyphTypeface = GetGlyphTypeface(out nullFont); Invariant.Assert(glyphTypeface != null); glyphTypeface.GetAdvanceWidthsUnshaped( characterString, characterLength, _emSize, scalingFactor, advanceWidthsUnshaped, nullFont, _textFormattingMode, _isSideways ); } } else { GlyphTypeface glyphTypeface = _shapeTypeface.GlyphTypeface; Invariant.Assert(glyphTypeface != null); Invariant.Assert(characterLength > 0); CharacterBufferRange newBuffer = new CharacterBufferRange(characterString, characterLength); MS.Internal.Text.TextInterface.GlyphMetrics[] glyphMetrics = BufferCache.GetGlyphMetrics(characterLength); glyphTypeface.GetGlyphMetricsOptimized(newBuffer, _emSize, _textFormattingMode, _isSideways, glyphMetrics ); double designToEm = _emSize * scalingFactor / glyphTypeface.DesignEmHeight; for (int i = 0; i < characterLength; i++) { advanceWidthsUnshaped[i] = (int)Math.Round(glyphMetrics[i].AdvanceWidth * designToEm); } BufferCache.ReleaseGlyphMetrics(glyphMetrics); } } ////// This is needed to decide whether we should pass a max cluster size to LS. /// We pass a max cluster size to LS to perform line breaking correctly. /// Passing a max cluster size larger than necessary will have impact on perf. /// internal sealed override bool NeedsMaxClusterSize { get { // We will need to pass a max cluster size to LS if: // 1) the script is not Latin (hence more likely to formed into ligature) // 2) or the run contains combining mark or extended characters if (!_textItem.IsLatin || _textItem.HasCombiningMark || _textItem.HasExtendedCharacter ) { return true; } return false; } } ////// Return value indicates whether two runs can shape together /// internal sealed override bool CanShapeTogether( TextShapeableSymbols shapeable ) { TextShapeableCharacters charShape = shapeable as TextShapeableCharacters; if (charShape == null) return false; return _shapeTypeface.Equals(charShape._shapeTypeface) // Extended characters need to be shaped by surrogate shaper. They cannot be shaped together with non-exteneded characters. && (_textItem.HasExtendedCharacter) == (charShape._textItem.HasExtendedCharacter) && _emSize == charShape._emSize && ( _properties.CultureInfo == null ? charShape._properties.CultureInfo == null : _properties.CultureInfo.Equals(charShape._properties.CultureInfo) ) && _nullShape == charShape._nullShape && (_textItem.CanShapeTogether(charShape._textItem)); } ////// Indicate whether run cannot be treated as simple characters because shaping is required. /// /// The following cases use simple rendering without shaping: /// o No _shapeTypeface. This happens in very simple rendering cases. /// o Non-Unicode (i.e. symbol) fonts. /// o When using a device font. /// /// Note that the presence of a device font in _shapeTypeface.DeviceFont implies use of /// a device font in all cases except where digit substitution applies. This special /// case occurs because the cached result per codepoint of TypefaceMap must include the device font /// for non-western digits in order to support device font rendering of the non-Western /// digit Unicode codepoints. The device font is not used however when the non-Western digits /// are displayed as a result of digit substitution from backing store Western digits. /// internal sealed override bool IsShapingRequired { get { return (_shapeTypeface != null) // Can't use shaping without a shape typeface && ( (_shapeTypeface.DeviceFont == null) // Can't use shaping when rendering with a device font || (_textItem.DigitCulture != null)) // -- unless substituting digits && (!IsSymbol); // Can't use shaping for symbol (non-Unicode) fonts } } ////// A Boolean value indicates whether additional info is required for caret positioning /// internal sealed override bool NeedsCaretInfo { get { return (_textItem.HasCombiningMark) || (_textItem.NeedsCaretInfo); } } ////// A Boolean value indicates whether run has extended character /// internal sealed override bool HasExtendedCharacter { get { return _textItem.HasExtendedCharacter; } } ////// Run height /// internal sealed override double Height { get { return _properties.Typeface.LineSpacing(_properties.FontRenderingEmSize, 1, Util.PixelsPerDip, _textFormattingMode); } } ////// Distance from top to baseline /// internal sealed override double Baseline { get { return _properties.Typeface.Baseline(_properties.FontRenderingEmSize, 1, Util.PixelsPerDip, _textFormattingMode); } } ////// Distance from baseline to underline position relative to TextRunProperties.FontRenderingEmSize /// internal sealed override double UnderlinePosition { get { return _properties.Typeface.UnderlinePosition; } } ////// Underline thickness relative to TextRunProperties.FontRenderingEmSize /// internal sealed override double UnderlineThickness { get { return _properties.Typeface.UnderlineThickness; } } ////// Distance from baseline to strike-through position relative to TextRunProperties.FontRenderingEmSize /// internal sealed override double StrikethroughPosition { get { return _properties.Typeface.StrikethroughPosition; } } ////// strike-through thickness relative to TextRunProperties.FontRenderingEmSize /// internal sealed override double StrikethroughThickness { get { return _properties.Typeface.StrikethroughThickness; } } #endregion ////// Whether all characters in this run are non-Unicode character (symbol) /// internal bool IsSymbol { get { if (_shapeTypeface != null) return _shapeTypeface.GlyphTypeface.Symbol; return _properties.Typeface.Symbol; } } internal override GlyphTypeface GlyphTypeFace { get { if (_shapeTypeface != null) return _shapeTypeface.GlyphTypeface; return _properties.Typeface.TryGetGlyphTypeface(); } } ////// Returns maximum possible cluster size for the run. Normally, this /// is 8 characters, but Indic scripts require this to be 15. /// internal const ushort DefaultMaxClusterSize = 8; private const ushort IndicMaxClusterSize = 15; internal sealed override ushort MaxClusterSize { get { if (_textItem.IsIndic) { return IndicMaxClusterSize; } return DefaultMaxClusterSize; } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- XPathCompileException.cs
- XmlSecureResolver.cs
- EventSourceCreationData.cs
- PageStatePersister.cs
- RenderData.cs
- DesignerToolboxInfo.cs
- PartialList.cs
- IgnorePropertiesAttribute.cs
- XmlCountingReader.cs
- VisualBasicSettings.cs
- ConsoleKeyInfo.cs
- CustomLineCap.cs
- UserInitiatedNavigationPermission.cs
- CodeExpressionCollection.cs
- SignalGate.cs
- WeakReference.cs
- OrderPreservingSpoolingTask.cs
- ProgramNode.cs
- GridViewEditEventArgs.cs
- LinqDataSourceEditData.cs
- AuthenticationModuleElementCollection.cs
- Select.cs
- Semaphore.cs
- Condition.cs
- DbDataReader.cs
- ContractInstanceProvider.cs
- TransportContext.cs
- QilCloneVisitor.cs
- _NTAuthentication.cs
- SocketException.cs
- XmlChildNodes.cs
- Compiler.cs
- ApplicationManager.cs
- ApplicationManager.cs
- DataTable.cs
- GroupBox.cs
- StylusPointPropertyInfo.cs
- GridEntry.cs
- GetRecipientListRequest.cs
- ILGenerator.cs
- MenuItemBinding.cs
- SecurityPermission.cs
- AssociationSetEnd.cs
- InputLangChangeRequestEvent.cs
- FragmentQueryProcessor.cs
- ModelPropertyCollectionImpl.cs
- OptimizedTemplateContentHelper.cs
- TrackBarRenderer.cs
- DataTableTypeConverter.cs
- PropertyExpression.cs
- SqlConnectionStringBuilder.cs
- Semaphore.cs
- RadioButton.cs
- DataViewManager.cs
- PenThreadWorker.cs
- FormViewDeletedEventArgs.cs
- DateTimeConstantAttribute.cs
- SQLResource.cs
- TemplateBindingExtensionConverter.cs
- DispatcherHookEventArgs.cs
- SecurityException.cs
- CodeSnippetCompileUnit.cs
- DrawingAttributes.cs
- HScrollProperties.cs
- CustomSignedXml.cs
- ListViewItem.cs
- WorkflowOperationAsyncResult.cs
- TemplatePartAttribute.cs
- HtmlLink.cs
- StyleSelector.cs
- tibetanshape.cs
- DPCustomTypeDescriptor.cs
- Conditional.cs
- ListMarkerSourceInfo.cs
- UIntPtr.cs
- VisualStyleTypesAndProperties.cs
- DateTimeFormatInfoScanner.cs
- Style.cs
- EntityType.cs
- ContextMenu.cs
- Automation.cs
- MailWebEventProvider.cs
- PackWebRequestFactory.cs
- RuntimeArgumentHandle.cs
- DataRowIndexBuffer.cs
- DisableDpiAwarenessAttribute.cs
- HttpModuleActionCollection.cs
- ConnectionPoint.cs
- AutomationIdentifier.cs
- WindowsGraphics2.cs
- FileEnumerator.cs
- IUnknownConstantAttribute.cs
- AlternateView.cs
- CollectionViewProxy.cs
- StructuralCache.cs
- UpdateTranslator.cs
- baseshape.cs
- MenuItemBinding.cs
- CacheDict.cs
- CodeConditionStatement.cs