Code:
/ 4.0 / 4.0 / untmp / 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.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- OpCopier.cs
- PrintController.cs
- ContractMapping.cs
- TypeBrowser.xaml.cs
- WrappedIUnknown.cs
- Sentence.cs
- NativeMethods.cs
- IDQuery.cs
- ComplexType.cs
- HtmlEncodedRawTextWriter.cs
- NetStream.cs
- StorageEndPropertyMapping.cs
- QueryBranchOp.cs
- Stroke2.cs
- WrappedKeySecurityToken.cs
- RtfToXamlLexer.cs
- TextElementEnumerator.cs
- BamlRecordHelper.cs
- ParameterToken.cs
- DocumentCollection.cs
- WindowsStreamSecurityElement.cs
- FileChangesMonitor.cs
- DictionaryEntry.cs
- ScriptMethodAttribute.cs
- InheritanceRules.cs
- EncodingTable.cs
- WeakEventManager.cs
- ListViewGroupCollectionEditor.cs
- SigningCredentials.cs
- IPHostEntry.cs
- DiagnosticStrings.cs
- ErrorTableItemStyle.cs
- CustomAttribute.cs
- AssociatedControlConverter.cs
- XPathParser.cs
- Compiler.cs
- MSAAWinEventWrap.cs
- XPathNavigatorKeyComparer.cs
- AuthenticationModuleElement.cs
- CopyNodeSetAction.cs
- PartialArray.cs
- StringFormat.cs
- DesignerInterfaces.cs
- State.cs
- TrackingMemoryStreamFactory.cs
- HasCopySemanticsAttribute.cs
- TreeIterator.cs
- XMLSchema.cs
- CustomServiceCredentials.cs
- OleDbPropertySetGuid.cs
- HandleTable.cs
- InheritanceService.cs
- Assert.cs
- SourceFileInfo.cs
- OracleRowUpdatedEventArgs.cs
- ExecutionContext.cs
- brushes.cs
- FrameworkContextData.cs
- PerfCounters.cs
- COAUTHINFO.cs
- XmlDocumentSerializer.cs
- DynamicRouteExpression.cs
- SerializationException.cs
- SqlTypesSchemaImporter.cs
- Identity.cs
- DesignBindingPicker.cs
- VirtualizingPanel.cs
- ObjectQueryState.cs
- HostingPreferredMapPath.cs
- OdbcUtils.cs
- DesignObjectWrapper.cs
- OdbcErrorCollection.cs
- SplineQuaternionKeyFrame.cs
- DataGridViewCellFormattingEventArgs.cs
- DocumentPageTextView.cs
- MembershipValidatePasswordEventArgs.cs
- OdbcError.cs
- ThumbAutomationPeer.cs
- FragmentNavigationEventArgs.cs
- NavigationProgressEventArgs.cs
- TextCompositionEventArgs.cs
- ConfigXmlComment.cs
- Array.cs
- ResourcePermissionBaseEntry.cs
- CollectionViewSource.cs
- StorageComplexPropertyMapping.cs
- CalendarAutomationPeer.cs
- ApplicationInfo.cs
- WasHttpModulesInstallComponent.cs
- RegexWorker.cs
- BindingSourceDesigner.cs
- DBDataPermissionAttribute.cs
- CompositeFontInfo.cs
- XmlSerializerSection.cs
- XmlSubtreeReader.cs
- HttpConfigurationContext.cs
- EnumMember.cs
- OfTypeExpression.cs
- TabletDevice.cs
- LogStore.cs