Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Core / CSharp / MS / Internal / Shaping / ShaperBuffers.cs / 1305600 / ShaperBuffers.cs
//---------------------------------------------------------------------- // // Microsoft Windows Client Platform // Copyright (C) Microsoft Corporation, 2001 // // File: ShaperBuffers.cs // // Contents: base shaping engine buffers // // Created: 10-22-2003 // //----------------------------------------------------------------------- using System; using System.Security; using System.Security.Permissions; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using MS.Internal.FontCache; using MS.Internal.FontFace; using System.Windows.Media; using System.Windows.Media.TextFormatting; using MS.Internal.PresentationCore; using MS.Utility; namespace MS.Internal.Shaping { ////// ShaperBuffers encapsulates the shapers non-volatile, non-shareabld buffers /// ////// This class owns several buffers that need to live as long as there's a /// shaping engine that uses them. Each shaping engine "owns" one of these, but /// the actual mapping/number of ShaperBuffers instances depends /// on the THREAD_SAFE_SHAPERS constant in BaseShape.cs. If THREAD_SAFE_SHAPERS /// is defined, there's one ShaperBuffers for each thread created in the /// WCP process space. If not defined, each shaping engine has its own /// ShaperBuffers object. In this latter case, the owner of the ShapeManager /// that owns the shaping engine is responsible for guaranteeing thread safety (everything /// else in the shape engines is reentrant, but each ShaperBuffers is not. /// /// A ShaperBuffers is created whenever a IShaper interface method of a /// shaper is called and its member ShaperBuffers is null (ie, the first time /// a shaper's IShaper interface is invoked). It exists till the shaper is destroyed. /// internal class ShaperBuffers { ////// ShaperBuffers - constructor /// ////// Critical: This code accepts checked pointers and extracts /// unsafe pointers. /// public ShaperBuffers(ushort charCount, ushort glyphCount) { // the charCount is used to provide an initial size for the // various buffers used by the shaper(s). These may // grow over the shaper's life _glyphInfoList = new GlyphInfoList((glyphCount > charCount ? glyphCount : charCount), 16, false); _charMap = new UshortList(charCount, 16); _layoutWorkspace = new OpenTypeLayoutWorkspace(); _charMap.SetRange(0,charCount); if (glyphCount > 0) { _glyphInfoList.SetRange(0,glyphCount); } } ~ShaperBuffers() { _glyphInfoList = null; _charMap = null; _layoutWorkspace = null; _textFeatures = null; } // I have laid these out alphabetically. If a particular variable has // an accessor with a different name than the variable, I've added a // comment in the position of the variable... public UshortList CharMap { get { return _charMap; } } public GlyphInfoList GlyphInfoList { get { return _glyphInfoList; } set { _glyphInfoList = value; } } ////// ShaperBuffers.Initialize - initializer for GetGlyphs. /// ////// Called by every shaper's GetGlyph method (indirectly - /// this function is actually called by the ShapingWorkspace.Initialize /// method (which is called from IShaper.GetGlyphs)). /// public bool Initialize(ushort charCount, ushort glyphCount) { if (charCount <= 0) { return false; } // clear charmap and resize it if (_charMap.Length > 0) { _charMap.Remove(0, _charMap.Length); } _charMap.Insert(0, charCount); Debug.Assert(_charMap.Length == charCount); // clear glyphinfolist if (_glyphInfoList.Length > 0) { _glyphInfoList.Remove(0, _glyphInfoList.Length); } if (glyphCount > 0) { _glyphInfoList.Insert(0, glyphCount); } Debug.Assert(_glyphInfoList.Length == glyphCount); return true; } ////// ShaperBuffers.InitializeFeatureList - initializer for GetGlyphs. /// /// Requested new array size /// number of features to copy into new array ////// Called by pertinent shaper's GetGlyph method; ie, those shapers /// that need to create a text dependent list of features /// (e.g. Arabic, Mongolian). /// The "keep" count takes priority over "size" if there's already an /// array, so if size size is less than keep, the resized array has at /// least keep elements. It is possible to create a 0 sized array. /// public bool InitializeFeatureList(ushort size, ushort keep) { if (_textFeatures == null) { _textFeatures = new ShaperFeaturesList(); if (_textFeatures == null) { return false; } _textFeatures.Initialize(size); } else { _textFeatures.Resize(size, keep); } return true; } public OpenTypeLayoutWorkspace LayoutWorkspace { get { return _layoutWorkspace; } } // NextIx; see CurrentCharIx public ShaperFeaturesList TextFeatures { get { return _textFeatures; } } // these are one per shaping engine (or per thread) and are kept around // between calls (ie, we allocate these once for the lifetime of this // ShapingWorkspace instance) private UshortList _charMap; private GlyphInfoList _glyphInfoList; private OpenTypeLayoutWorkspace _layoutWorkspace; private ShaperFeaturesList _textFeatures; } internal class ShaperFeaturesList { public int FeaturesCount { get { return _featuresCount; } } public Feature[] Features { get { return _features; } } public int NextIx { get { return _featuresCount; } } public uint CurrentTag { get { return _featuresCount == 0 ? 0 : _features[_featuresCount - 1].Tag;} } public int Length { get { return _featuresCount; } } public void SetFeatureParameter (ushort featureIx, uint paramValue) { Invariant.Assert ( _featuresCount > featureIx ); _features[featureIx].Parameter = paramValue; } ////// ShaperFeateruList.Initialize - initializer for GetGlyphs. /// ////// Called by pertinent shaper's GetGlyph method (indirectly - /// this function is actually called by the /// ShaperBuffers.InitializeFeatureList method which is /// called by those shapers that need to create a text dependent /// list of features (e.g. Arabic, Mongolian). /// internal bool Initialize (ushort newSize) { if (_features == null || newSize > _features.Length || newSize == 0) { Feature[] newArray = new Feature[newSize]; if (newArray != null) { _features = newArray; } } _featuresCount = 0; _minimumAddCount = 3; // add space for init,med,final whenever we need to actually resize array return _features != null; } ////// ShaperFeateruList.Resize - used to change the size of the features array /// /// Requested new array size /// number of features to copy into new array ////// Used locally for each AddFeature, and by ShaperBuffers.InitializeFeatureList. /// May be called from a shaping engine. /// The "keepCount" count takes priority over "newSize" if there's already an /// array, so if size is less than keep, the resized array has at least keep elements. /// internal bool Resize (ushort newSize, ushort keepCount) { _featuresCount = keepCount; // if (_features != null && _features.Length != 0 && keepCount > 0 && _features.Length >= keepCount) { // make sure keep count is no bigger than current // array size ushort currentLength = (ushort)_features.Length; // make sure new size is at least as big as keep count if (newSize < keepCount) { newSize = keepCount; } // if new size is bigger than the current array, create // a new array if (newSize > currentLength) { // always use minimum leap for adding to array if (newSize < (currentLength + _minimumAddCount)) { newSize = (ushort)(currentLength + _minimumAddCount); } Feature[] newArray = new Feature[newSize]; if (newArray == null) { // can't create new array, leave (at least we still // have our current array) return false; } // Our client wants us to keep the first "keepCount" entries. // so copy them now. for (int i = 0; i < keepCount; ++i) { newArray[i] = _features[i]; } _features = newArray; } } else { // nothing to keep, or currently no array so initialize return Initialize(newSize); } return true; } ////// ShaperFeateruList.AddFeature - add a feature to the array /// /// new feature to add ////// This is aimed at allowing shaping engines to add features /// to the array (generally used for required, all character /// features added at the start of shaping) /// internal void AddFeature (Feature feature) { if ( _featuresCount == _features.Length ) { // need more space, so resize the array if (!Resize((ushort)(_featuresCount + 1),_featuresCount)) { return; // can't resize array, fail quietly (not going // to apply this feature!) } } _features[_featuresCount] = feature; ++_featuresCount; } ////// ShaperFeateruList.AddFeature - add a feature to the array /// ////// An alternative to adding an already created feature. /// internal void AddFeature (ushort startIndex, ushort length, uint featureTag, uint parameter) { if ( _featuresCount == _features.Length ) { // need more space if (!Resize((ushort)(_featuresCount + 1),_featuresCount)) { return; } } if (_features[_featuresCount] != null) { _features[_featuresCount].Tag = featureTag; _features[_featuresCount].StartIndex = startIndex; _features[_featuresCount].Length = length; _features[_featuresCount].Parameter = parameter; } else { _features[_featuresCount] = new Feature(startIndex,length,featureTag,parameter); } ++_featuresCount; } ////// ShaperFeateruList.AddFeature - add a feature to the array /// ////// This variation of "AddFeature" is used by the shaper state /// machines for adding each new feature. /// internal void AddFeature (ushort charIx, uint featureTag ) { if (featureTag == 1) // "NotShaped" { return; } if (_featuresCount > 0) // if previous feature exists { // see if this feature can just be subsumed in the latest feature ushort latestFeatureIx = (ushort)(_featuresCount - 1); if ((featureTag == 0 || featureTag == _features[latestFeatureIx].Tag) && (_features[latestFeatureIx].StartIndex + _features[latestFeatureIx].Length) == charIx) { _features[latestFeatureIx].Length += 1; } else { // can't be added to previous feature, so add one. AddFeature(charIx, 1, (featureTag == 0 ? _features[latestFeatureIx].Tag : featureTag), 1); } } else if (featureTag != 0) // cant' be "Same" (there's no feature yet) { AddFeature(charIx,1,featureTag,1); } } ////// ShaperFeateruList.UpdatePreviousShapedChar - adjust previous char's tag /// ////// This is used by the shaper state machines for modifying the /// feature tag of the previous character. /// internal void UpdatePreviousShapedChar (uint featureTag) { if (featureTag <= 1) // nothing to do if "NotShaped" or "Same" { return; } if (_featuresCount > 0) { // see if this feature can just be subsumed in the latest feature ushort latestFeatureIx = (ushort)(_featuresCount - 1); if (_features[latestFeatureIx].Tag != featureTag) { // the previous char's feature just applied to // it, so update its tag and we're done _features[latestFeatureIx].Tag = featureTag; } } } private ushort _minimumAddCount; private ushort _featuresCount; private Feature[] _features; } } // 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, 2001 // // File: ShaperBuffers.cs // // Contents: base shaping engine buffers // // Created: 10-22-2003 // //----------------------------------------------------------------------- using System; using System.Security; using System.Security.Permissions; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using MS.Internal.FontCache; using MS.Internal.FontFace; using System.Windows.Media; using System.Windows.Media.TextFormatting; using MS.Internal.PresentationCore; using MS.Utility; namespace MS.Internal.Shaping { ////// ShaperBuffers encapsulates the shapers non-volatile, non-shareabld buffers /// ////// This class owns several buffers that need to live as long as there's a /// shaping engine that uses them. Each shaping engine "owns" one of these, but /// the actual mapping/number of ShaperBuffers instances depends /// on the THREAD_SAFE_SHAPERS constant in BaseShape.cs. If THREAD_SAFE_SHAPERS /// is defined, there's one ShaperBuffers for each thread created in the /// WCP process space. If not defined, each shaping engine has its own /// ShaperBuffers object. In this latter case, the owner of the ShapeManager /// that owns the shaping engine is responsible for guaranteeing thread safety (everything /// else in the shape engines is reentrant, but each ShaperBuffers is not. /// /// A ShaperBuffers is created whenever a IShaper interface method of a /// shaper is called and its member ShaperBuffers is null (ie, the first time /// a shaper's IShaper interface is invoked). It exists till the shaper is destroyed. /// internal class ShaperBuffers { ////// ShaperBuffers - constructor /// ////// Critical: This code accepts checked pointers and extracts /// unsafe pointers. /// public ShaperBuffers(ushort charCount, ushort glyphCount) { // the charCount is used to provide an initial size for the // various buffers used by the shaper(s). These may // grow over the shaper's life _glyphInfoList = new GlyphInfoList((glyphCount > charCount ? glyphCount : charCount), 16, false); _charMap = new UshortList(charCount, 16); _layoutWorkspace = new OpenTypeLayoutWorkspace(); _charMap.SetRange(0,charCount); if (glyphCount > 0) { _glyphInfoList.SetRange(0,glyphCount); } } ~ShaperBuffers() { _glyphInfoList = null; _charMap = null; _layoutWorkspace = null; _textFeatures = null; } // I have laid these out alphabetically. If a particular variable has // an accessor with a different name than the variable, I've added a // comment in the position of the variable... public UshortList CharMap { get { return _charMap; } } public GlyphInfoList GlyphInfoList { get { return _glyphInfoList; } set { _glyphInfoList = value; } } ////// ShaperBuffers.Initialize - initializer for GetGlyphs. /// ////// Called by every shaper's GetGlyph method (indirectly - /// this function is actually called by the ShapingWorkspace.Initialize /// method (which is called from IShaper.GetGlyphs)). /// public bool Initialize(ushort charCount, ushort glyphCount) { if (charCount <= 0) { return false; } // clear charmap and resize it if (_charMap.Length > 0) { _charMap.Remove(0, _charMap.Length); } _charMap.Insert(0, charCount); Debug.Assert(_charMap.Length == charCount); // clear glyphinfolist if (_glyphInfoList.Length > 0) { _glyphInfoList.Remove(0, _glyphInfoList.Length); } if (glyphCount > 0) { _glyphInfoList.Insert(0, glyphCount); } Debug.Assert(_glyphInfoList.Length == glyphCount); return true; } ////// ShaperBuffers.InitializeFeatureList - initializer for GetGlyphs. /// /// Requested new array size /// number of features to copy into new array ////// Called by pertinent shaper's GetGlyph method; ie, those shapers /// that need to create a text dependent list of features /// (e.g. Arabic, Mongolian). /// The "keep" count takes priority over "size" if there's already an /// array, so if size size is less than keep, the resized array has at /// least keep elements. It is possible to create a 0 sized array. /// public bool InitializeFeatureList(ushort size, ushort keep) { if (_textFeatures == null) { _textFeatures = new ShaperFeaturesList(); if (_textFeatures == null) { return false; } _textFeatures.Initialize(size); } else { _textFeatures.Resize(size, keep); } return true; } public OpenTypeLayoutWorkspace LayoutWorkspace { get { return _layoutWorkspace; } } // NextIx; see CurrentCharIx public ShaperFeaturesList TextFeatures { get { return _textFeatures; } } // these are one per shaping engine (or per thread) and are kept around // between calls (ie, we allocate these once for the lifetime of this // ShapingWorkspace instance) private UshortList _charMap; private GlyphInfoList _glyphInfoList; private OpenTypeLayoutWorkspace _layoutWorkspace; private ShaperFeaturesList _textFeatures; } internal class ShaperFeaturesList { public int FeaturesCount { get { return _featuresCount; } } public Feature[] Features { get { return _features; } } public int NextIx { get { return _featuresCount; } } public uint CurrentTag { get { return _featuresCount == 0 ? 0 : _features[_featuresCount - 1].Tag;} } public int Length { get { return _featuresCount; } } public void SetFeatureParameter (ushort featureIx, uint paramValue) { Invariant.Assert ( _featuresCount > featureIx ); _features[featureIx].Parameter = paramValue; } ////// ShaperFeateruList.Initialize - initializer for GetGlyphs. /// ////// Called by pertinent shaper's GetGlyph method (indirectly - /// this function is actually called by the /// ShaperBuffers.InitializeFeatureList method which is /// called by those shapers that need to create a text dependent /// list of features (e.g. Arabic, Mongolian). /// internal bool Initialize (ushort newSize) { if (_features == null || newSize > _features.Length || newSize == 0) { Feature[] newArray = new Feature[newSize]; if (newArray != null) { _features = newArray; } } _featuresCount = 0; _minimumAddCount = 3; // add space for init,med,final whenever we need to actually resize array return _features != null; } ////// ShaperFeateruList.Resize - used to change the size of the features array /// /// Requested new array size /// number of features to copy into new array ////// Used locally for each AddFeature, and by ShaperBuffers.InitializeFeatureList. /// May be called from a shaping engine. /// The "keepCount" count takes priority over "newSize" if there's already an /// array, so if size is less than keep, the resized array has at least keep elements. /// internal bool Resize (ushort newSize, ushort keepCount) { _featuresCount = keepCount; // if (_features != null && _features.Length != 0 && keepCount > 0 && _features.Length >= keepCount) { // make sure keep count is no bigger than current // array size ushort currentLength = (ushort)_features.Length; // make sure new size is at least as big as keep count if (newSize < keepCount) { newSize = keepCount; } // if new size is bigger than the current array, create // a new array if (newSize > currentLength) { // always use minimum leap for adding to array if (newSize < (currentLength + _minimumAddCount)) { newSize = (ushort)(currentLength + _minimumAddCount); } Feature[] newArray = new Feature[newSize]; if (newArray == null) { // can't create new array, leave (at least we still // have our current array) return false; } // Our client wants us to keep the first "keepCount" entries. // so copy them now. for (int i = 0; i < keepCount; ++i) { newArray[i] = _features[i]; } _features = newArray; } } else { // nothing to keep, or currently no array so initialize return Initialize(newSize); } return true; } ////// ShaperFeateruList.AddFeature - add a feature to the array /// /// new feature to add ////// This is aimed at allowing shaping engines to add features /// to the array (generally used for required, all character /// features added at the start of shaping) /// internal void AddFeature (Feature feature) { if ( _featuresCount == _features.Length ) { // need more space, so resize the array if (!Resize((ushort)(_featuresCount + 1),_featuresCount)) { return; // can't resize array, fail quietly (not going // to apply this feature!) } } _features[_featuresCount] = feature; ++_featuresCount; } ////// ShaperFeateruList.AddFeature - add a feature to the array /// ////// An alternative to adding an already created feature. /// internal void AddFeature (ushort startIndex, ushort length, uint featureTag, uint parameter) { if ( _featuresCount == _features.Length ) { // need more space if (!Resize((ushort)(_featuresCount + 1),_featuresCount)) { return; } } if (_features[_featuresCount] != null) { _features[_featuresCount].Tag = featureTag; _features[_featuresCount].StartIndex = startIndex; _features[_featuresCount].Length = length; _features[_featuresCount].Parameter = parameter; } else { _features[_featuresCount] = new Feature(startIndex,length,featureTag,parameter); } ++_featuresCount; } ////// ShaperFeateruList.AddFeature - add a feature to the array /// ////// This variation of "AddFeature" is used by the shaper state /// machines for adding each new feature. /// internal void AddFeature (ushort charIx, uint featureTag ) { if (featureTag == 1) // "NotShaped" { return; } if (_featuresCount > 0) // if previous feature exists { // see if this feature can just be subsumed in the latest feature ushort latestFeatureIx = (ushort)(_featuresCount - 1); if ((featureTag == 0 || featureTag == _features[latestFeatureIx].Tag) && (_features[latestFeatureIx].StartIndex + _features[latestFeatureIx].Length) == charIx) { _features[latestFeatureIx].Length += 1; } else { // can't be added to previous feature, so add one. AddFeature(charIx, 1, (featureTag == 0 ? _features[latestFeatureIx].Tag : featureTag), 1); } } else if (featureTag != 0) // cant' be "Same" (there's no feature yet) { AddFeature(charIx,1,featureTag,1); } } ////// ShaperFeateruList.UpdatePreviousShapedChar - adjust previous char's tag /// ////// This is used by the shaper state machines for modifying the /// feature tag of the previous character. /// internal void UpdatePreviousShapedChar (uint featureTag) { if (featureTag <= 1) // nothing to do if "NotShaped" or "Same" { return; } if (_featuresCount > 0) { // see if this feature can just be subsumed in the latest feature ushort latestFeatureIx = (ushort)(_featuresCount - 1); if (_features[latestFeatureIx].Tag != featureTag) { // the previous char's feature just applied to // it, so update its tag and we're done _features[latestFeatureIx].Tag = featureTag; } } } private ushort _minimumAddCount; private ushort _featuresCount; private Feature[] _features; } } // 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
- UrlPropertyAttribute.cs
- DataServiceRequest.cs
- Point3DValueSerializer.cs
- _NtlmClient.cs
- BaseTemplateParser.cs
- httpstaticobjectscollection.cs
- WeakReferenceEnumerator.cs
- SemanticAnalyzer.cs
- SystemResources.cs
- ListViewTableRow.cs
- ButtonAutomationPeer.cs
- QueryReaderSettings.cs
- GlobalizationSection.cs
- ParserStreamGeometryContext.cs
- TrackingProfileDeserializationException.cs
- XmlBufferedByteStreamReader.cs
- ScrollData.cs
- ListControlDesigner.cs
- DataPagerFieldCommandEventArgs.cs
- ThreadInterruptedException.cs
- CodeIdentifier.cs
- PropertyGridView.cs
- Stylesheet.cs
- NullRuntimeConfig.cs
- DocumentPaginator.cs
- xmlformatgeneratorstatics.cs
- DesignerUtility.cs
- DbDataSourceEnumerator.cs
- TraceSwitch.cs
- AsymmetricKeyExchangeDeformatter.cs
- RetrieveVirtualItemEventArgs.cs
- RSAOAEPKeyExchangeDeformatter.cs
- ExceptionList.cs
- BuilderPropertyEntry.cs
- AutomationPatternInfo.cs
- XmlException.cs
- DefaultPrintController.cs
- NumericUpDown.cs
- WebPartVerbCollection.cs
- ControlIdConverter.cs
- ComMethodElement.cs
- XamlGridLengthSerializer.cs
- SubpageParagraph.cs
- TextChange.cs
- ArcSegment.cs
- updateconfighost.cs
- SchemaImporterExtensionElementCollection.cs
- QueryPageSettingsEventArgs.cs
- HandlerFactoryWrapper.cs
- ListSortDescription.cs
- AuthenticationManager.cs
- WS2007HttpBindingElement.cs
- SingleObjectCollection.cs
- QuaternionAnimation.cs
- DragEventArgs.cs
- ServiceAuthorizationElement.cs
- DoubleAnimationUsingPath.cs
- BindMarkupExtensionSerializer.cs
- BitmapData.cs
- WaitHandleCannotBeOpenedException.cs
- activationcontext.cs
- FtpRequestCacheValidator.cs
- Binding.cs
- QilPatternFactory.cs
- FloaterParagraph.cs
- XmlElementList.cs
- DocumentXmlWriter.cs
- TraceHandler.cs
- PnrpPermission.cs
- prompt.cs
- ExpandSegment.cs
- ClientSideQueueItem.cs
- SQLGuid.cs
- JoinTreeNode.cs
- FrameworkElementFactoryMarkupObject.cs
- Section.cs
- EncodingDataItem.cs
- BorderGapMaskConverter.cs
- SQLCharsStorage.cs
- FormatterServices.cs
- AutoResetEvent.cs
- BitmapEncoder.cs
- UInt32Converter.cs
- Clipboard.cs
- Keyboard.cs
- GenericEnumConverter.cs
- ApplicationTrust.cs
- BrushValueSerializer.cs
- KeyValueSerializer.cs
- CapabilitiesState.cs
- VirtualDirectoryMapping.cs
- AttachedPropertyBrowsableForTypeAttribute.cs
- KnownTypes.cs
- UnknownWrapper.cs
- rsa.cs
- TableLayoutSettings.cs
- WaitHandleCannotBeOpenedException.cs
- OdbcConnectionStringbuilder.cs
- InternalUserCancelledException.cs
- TreeWalkHelper.cs