Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / wpf / src / Core / CSharp / MS / Internal / Shaping / ShaperBuffers.cs / 1 / 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
- OdbcConnectionHandle.cs
- NamedPermissionSet.cs
- HashCodeCombiner.cs
- PageEventArgs.cs
- DecryptedHeader.cs
- DBAsyncResult.cs
- InternalRelationshipCollection.cs
- StylusPointProperty.cs
- HTTPNotFoundHandler.cs
- DrawingContextWalker.cs
- ObjectSet.cs
- SessionStateContainer.cs
- DebugHandleTracker.cs
- oledbmetadatacolumnnames.cs
- InfoCardMasterKey.cs
- DataGridViewTextBoxCell.cs
- MSAANativeProvider.cs
- UndoManager.cs
- WinHttpWebProxyFinder.cs
- FixedSOMTextRun.cs
- AstNode.cs
- BindingNavigator.cs
- HashCodeCombiner.cs
- FilterException.cs
- MultiPageTextView.cs
- WhileDesigner.cs
- DataGridViewCellValueEventArgs.cs
- IPipelineRuntime.cs
- WebPartConnectionsConnectVerb.cs
- LifetimeServices.cs
- PanelDesigner.cs
- MetadataItemEmitter.cs
- XmlAtomicValue.cs
- HttpGetProtocolImporter.cs
- StringResourceManager.cs
- DataGridItemAttachedStorage.cs
- SchemaElementDecl.cs
- ManagementEventWatcher.cs
- ProfileParameter.cs
- ValidationEventArgs.cs
- EventNotify.cs
- FlowDocumentFormatter.cs
- MarkedHighlightComponent.cs
- RunClient.cs
- NotImplementedException.cs
- TraceListener.cs
- EdmFunction.cs
- ButtonAutomationPeer.cs
- CompilerErrorCollection.cs
- EntityDataReader.cs
- CompoundFileIOPermission.cs
- Point.cs
- PassportAuthentication.cs
- CachedBitmap.cs
- PropertyMapper.cs
- DetailsViewDeletedEventArgs.cs
- OleDbFactory.cs
- ExpandableObjectConverter.cs
- XmlSchemaComplexContentRestriction.cs
- DataGridViewAutoSizeColumnModeEventArgs.cs
- DelegateTypeInfo.cs
- TextTreeTextBlock.cs
- Int32AnimationBase.cs
- PathGradientBrush.cs
- Tuple.cs
- WmpBitmapDecoder.cs
- OleDbMetaDataFactory.cs
- DataGridViewCellPaintingEventArgs.cs
- NotifyInputEventArgs.cs
- HtmlMeta.cs
- ObjectTag.cs
- SerialPort.cs
- ThousandthOfEmRealPoints.cs
- DescendentsWalker.cs
- SchemaImporterExtension.cs
- Selection.cs
- BasicAsyncResult.cs
- ToolStripItemEventArgs.cs
- SerializerDescriptor.cs
- DrawingContextDrawingContextWalker.cs
- ConfigXmlSignificantWhitespace.cs
- WebBrowserSiteBase.cs
- path.cs
- RichTextBoxAutomationPeer.cs
- EntityContainer.cs
- PageEventArgs.cs
- DataRecordInternal.cs
- ControllableStoryboardAction.cs
- _ConnectStream.cs
- StringValueSerializer.cs
- ToolboxService.cs
- RenderingBiasValidation.cs
- TriState.cs
- IdentityModelStringsVersion1.cs
- CaseInsensitiveComparer.cs
- WindowsFormsHelpers.cs
- GroupBox.cs
- DataGridViewComboBoxEditingControl.cs
- DataGridViewCellEventArgs.cs
- ContractTypeNameElement.cs