Code:
/ DotNET / DotNET / 8.0 / untmp / WIN_WINDOWS / lh_tools_devdiv_wpf / Windows / wcp / Core / MS / Internal / Shaping / latinshape.cs / 2 / latinshape.cs
//+------------------------------------------------------------------------ // // Microsoft Windows Client Platform // Copyright (C) Microsoft Corporation, 2001 // // File: LatinShape.cs // // Contents: Combining marks/ Latin OT shaping engine // // Contact: [....] // // Created: 10-21-2003 // //----------------------------------------------------------------------- using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using MS.Internal; using MS.Internal.FontCache; using System.Security; using System.Security.Permissions; using System.Windows.Media; using System.Windows.Media.TextFormatting; namespace MS.Internal.Shaping { ////// The Latin/Cyrillic/Greek Shaping Engine - (shapes Latin text) /// ////// The IShaper and IShapingEngine interfaces are implemented to /// provide the shaping methods for Latin/Cyrillic/Greek Scripts. /// This engine incorporates combining marks shaping, which is /// not dependent on the font being OpenType. /// internal class LatinShape : BaseShape { #region Data members // // See static LatinShape() constructor for notes and initialization. // // Two-dimensional array [_combiningCharsIndexesTableLength][_combiningCharsIndexesTableSegmentLength] ////// Critical - Holds a pointer object /// [SecurityCritical] private unsafe static readonly ushort* _combiningCharsIndexes; private static readonly int _combiningCharsIndexesTableLength; private static readonly int _combiningCharsIndexesTableSegmentLength; ////// Critical - Holds a pointer object /// [SecurityCritical] private unsafe static readonly ushort* _combiningMarkIndexes; private static readonly int _combiningMarkIndexesTableLength; ////// Critical - Holds a pointer object /// [SecurityCritical] private unsafe static readonly char* _combiningChars; private static readonly int _combiningCharsBaseCount; private static readonly int _combiningCharsMarkCount; private static readonly ScriptTags[] _supportedScripts; const char InvalidCombinationChar = '\u0000'; const ushort InvalidBaseIndex = 0; const ushort InvalidMarkIndex = 0xffff; #endregion //-------------------------------------- // // Constructors // //-------------------------------------- #region Constructors ////// Critical -This code calls into unsafe code and stores pointers /// Safe - This constructor doesn't expose any of the unsafe pointers. /// [SecurityCritical, SecurityTreatAsSafe] unsafe static LatinShape() { Classification.CombiningMarksClassificationData classification; Classification.GetCombiningMarksClassificationData(out classification); _combiningCharsIndexes = (ushort*)classification.CombiningCharsIndexes; _combiningCharsIndexesTableLength = classification.CombiningCharsIndexesTableLength; _combiningCharsIndexesTableSegmentLength = classification.CombiningCharsIndexesTableSegmentLength; _combiningMarkIndexes = (ushort*)classification.CombiningMarkIndexes; _combiningMarkIndexesTableLength = classification.CombiningMarkIndexesTableLength; _combiningChars = (char*)classification.CombinationChars; _combiningCharsBaseCount = classification.CombinationCharsBaseCount; _combiningCharsMarkCount = classification.CombinationCharsMarkCount; _supportedScripts = new ScriptTags[] { ScriptTags.Armenian, ScriptTags.Bopomofo, ScriptTags.Braille, ScriptTags.Buhid, // * ScriptTags.CanadianSyllabics, ScriptTags.Cherokee, ScriptTags.CJKIdeographic, ScriptTags.Coptic, ScriptTags.Cyrillic, ScriptTags.Ethiopic, ScriptTags.Georgian, ScriptTags.Glagolitic, ScriptTags.Greek, ScriptTags.Hanunoo, // * ScriptTags.Hiragana, // ScriptTags.Katakana, // this is here for reference only - tag has same value as "Hiragana" ScriptTags.Latin, ScriptTags.Ogham, ScriptTags.Runic, ScriptTags.Tagalog, // * ScriptTags.Tagbanwa, // * ScriptTags.TaiLe, ScriptTags.Tifinagh, ScriptTags.Yi // * For V2 Philippine scripts will require separate engine // to handle combining marks in case of incorrect input }; } ////// Constructor for the Latin Open Type Shaping Engine. /// internal LatinShape() { } #endregion //-------------------------------------- // // Internal Methods // //-------------------------------------- #region Internal methods ////// HebrewShape.SupportedScripts - /// IShapingEngine member override /// ///Our supported scripts (Hebrew, Thaana). public override ScriptTags[] SupportedScripts { get { return _supportedScripts; } } ////// LatinShape.OnLoadFont - IShapingEngine method override. /// ////// We override the base implementation because this shaper /// has work to do even if the font doesn't support our /// script. (Combining marks support is not OpenType feature /// dependent) /// /// Script of interest. /// Font face being loaded /// font specific info for the shaper ///True if font supports script. ////// Critical - This method reads into raw font table bits. /// Safe - This method doesn't expose any critical data. /// [SecurityCritical, SecurityTreatAsSafe] public override bool OnLoadFont( ScriptTags scriptTag, GlyphTypeface fontFace, out object shapeFontFaceInfo ) { // Create a font client for this script. (LatinShape doesn't have // its own CharClassifier and will support fonts that have no OpenType // script support, so use the "no OT support" constructor... ShaperFontClient fontClient = new ShaperFontClient(fontFace); // Now check if script support does exist in font if (OpenTypeLayout.FindScript(fontClient,(uint)scriptTag) != TagInfoFlags.None) { fontClient.IsScriptSupportedByFont = true; } // we don't care if script support is in font cause we support // combining marks even if the font doesn't support our script, // so we always return "true" shapeFontFaceInfo = fontClient; return true; } ////// LatinShape.GetGlyphs - Latin implementation of the GetGlyphs() helper function. /// /// shaping currentRun /// Text item ///number of glyphs ////// Critical - calls critical code, unsafe code /// [SecurityCritical] unsafe protected override int GetGlyphs ( ref ShapingWorkspace currentRun, Item item ) { // no pre-substitution shaping, just cmap lookup. ushort currGlyph; CharShapeInfo currShape; ushort marksCount; while ( GetNextGlyph (ref currentRun, out currGlyph, out currShape, out marksCount) ) { if (marksCount < 2) { currentRun.SetGlyphPropertiesUsingGlyph(currShape, currGlyph); } else { // we need to replace the base glyph (already added) with // this new composite glyph currentRun.PreviousGlyph = currGlyph; currentRun.AddLigatureChars(-1,marksCount); } } return currentRun.GlyphsCount; } #endregion //-------------------------------------- // // Private Methods // //-------------------------------------- #region Combining mark methods ////// Index of the mark char in the combination lookup table /// ////// Critical - Dereferences a pointer which is stored without any validation /// Safe - This method returns classification data which is safe. /// [SecurityCritical, SecurityTreatAsSafe] private unsafe ushort GetMarkIndex(char markChar) { int markCharCode = markChar-0x300; if (markCharCode<0 || markCharCode>=_combiningMarkIndexesTableLength) return InvalidMarkIndex; return _combiningMarkIndexes[markCharCode]; } ////// Critical - Dereferences a pointer which is stored without any validation /// Safe - This method returns classification data which is safe. /// [SecurityCritical, SecurityTreatAsSafe] private unsafe ushort GetBaseIndex(char baseChar) { ushort baseCharCode = (ushort)baseChar; ushort secondLevelIndex = _combiningCharsIndexes[ //0 * _combiningCharsIndexesTableLength + :first segment baseCharCode/_combiningCharsIndexesTableSegmentLength]; Invariant.Assert(secondLevelIndex < _combiningCharsIndexesTableLength); return _combiningCharsIndexes[secondLevelIndex*_combiningCharsIndexesTableSegmentLength + baseCharCode%_combiningCharsIndexesTableSegmentLength]; } ////// Get combination character from combination lookup table /// ////// Critical - Dereferences a pointer which is stored without any validation /// Safe - This method returns classification data which is safe. /// [SecurityCritical, SecurityTreatAsSafe] private unsafe char GetCombinationChar(ushort baseCharCode, ushort markCharCode) { Invariant.Assert(baseCharCode < _combiningCharsBaseCount && markCharCode < _combiningCharsMarkCount); return _combiningChars[baseCharCode*_combiningCharsMarkCount + markCharCode]; } ////// Critical - Uses unsafe accessors/functions /// [SecurityCritical] private unsafe bool GetNextGlyph( ref ShapingWorkspace currentRun, out ushort currGlyph, out CharShapeInfo currShape, out ushort marksCount ) { // assume this isn't a combining mark (good assumption) marksCount = 0; char currChar; bool isNextValid = currentRun.GetNextCharProperties (out currChar, out currGlyph, out currShape); if ( isNextValid ) { ushort markIndex = GetMarkIndex( currChar ); if ( markIndex != InvalidMarkIndex && (currShape & CharShapeInfo.IsUnicodeLayoutControl) == 0) { marksCount=1; // this is a valid mark (it may form a combination) currShape = CharShapeInfo.NoFlagsSet; // this is a combining mark ushort baseIndex = GetBaseIndex(currentRun.PreviousChar); if (baseIndex != InvalidBaseIndex) { // base is a base, so check for combination char char baseAndMarkOneChar=GetCombinationChar(baseIndex,markIndex); ushort baseAndMarkOneGlyph = currentRun.CharConverter.ToGlyph(baseAndMarkOneChar); if ( baseAndMarkOneGlyph != 0 ) { // base + mark form a combination char. Let's see if we're // lucky (can we use the next char(s) to form a combination // char?) ushort markTwoIndex = GetMarkIndex(currentRun.GetChar((ushort)(currentRun.CurrentCharIx + 1))); if (markTwoIndex == InvalidMarkIndex) { // nope, the next char isn't a mark, so we're done (we found a // glyph for this combination char) marksCount = 2; currShape |= CharShapeInfo.IsStartOfCluster; currGlyph = baseAndMarkOneGlyph; } else { // next char is a mark, does it form a combination? ushort baseAndMarkOneIndex = GetBaseIndex(baseAndMarkOneChar); char baseAndBothMarksChar = GetCombinationChar(baseAndMarkOneIndex, markTwoIndex); if (baseAndBothMarksChar != InvalidCombinationChar) { // base + both marks does form a combination char. Does // font have the right glyph? ushort baseAndBothMarksGlyph = currentRun.CharConverter.ToGlyph(baseAndBothMarksChar); if (baseAndBothMarksGlyph != 0) { // we have a winner! ("base + 2 marks" has a glyph) If there's not yet // another mark in the character stream, send the combo glyph back. If // there is another mark, don't send combo glyph. ushort markThreeIndex = GetMarkIndex(currentRun.GetChar((ushort)(currentRun.CurrentCharIx + 2))); if (markThreeIndex == InvalidMarkIndex) { marksCount = 3; currShape |= CharShapeInfo.IsStartOfCluster; currGlyph = baseAndBothMarksGlyph; } } } } } } } } return isNextValid; } #endregion } } // 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
- ViewCellSlot.cs
- X500Name.cs
- UserControlBuildProvider.cs
- TextTabProperties.cs
- CertificateManager.cs
- EventProxy.cs
- MaskDescriptors.cs
- SettingsPropertyValueCollection.cs
- ArraySubsetEnumerator.cs
- SafeHandles.cs
- RadioButtonAutomationPeer.cs
- FileEnumerator.cs
- XmlArrayItemAttribute.cs
- FixedStringLookup.cs
- ListBase.cs
- SourceLineInfo.cs
- EntityEntry.cs
- OutputScope.cs
- srgsitem.cs
- ManifestBasedResourceGroveler.cs
- InlineUIContainer.cs
- DataGridViewCellConverter.cs
- QilChoice.cs
- FileDialogCustomPlacesCollection.cs
- Exceptions.cs
- WebSysDescriptionAttribute.cs
- LOSFormatter.cs
- BamlResourceDeserializer.cs
- FixedPageProcessor.cs
- ReadOnlyCollection.cs
- MSAAWinEventWrap.cs
- MarshalByRefObject.cs
- AffineTransform3D.cs
- ISAPIApplicationHost.cs
- relpropertyhelper.cs
- Tile.cs
- CharEnumerator.cs
- _RequestCacheProtocol.cs
- TreeIterator.cs
- EmptyControlCollection.cs
- InvalidOperationException.cs
- EraserBehavior.cs
- DataTableNewRowEvent.cs
- LinearKeyFrames.cs
- DeploymentSection.cs
- ImageMap.cs
- DefaultTextStore.cs
- DynamicActionMessageFilter.cs
- streamingZipPartStream.cs
- LocatorGroup.cs
- Pair.cs
- securitycriticaldataClass.cs
- PropertyGridView.cs
- ApplicationDirectory.cs
- DispatcherObject.cs
- DataGridViewRowsAddedEventArgs.cs
- ParallelActivityDesigner.cs
- SelectorItemAutomationPeer.cs
- SecurityManager.cs
- View.cs
- Accessible.cs
- PeerName.cs
- NameSpaceExtractor.cs
- OracleCommandSet.cs
- AssertFilter.cs
- RequestBringIntoViewEventArgs.cs
- COM2Enum.cs
- DataGrid.cs
- MemberBinding.cs
- ServiceNotStartedException.cs
- FixedSOMTableRow.cs
- ReversePositionQuery.cs
- FontFamilyIdentifier.cs
- BridgeDataRecord.cs
- FormViewModeEventArgs.cs
- InternalPermissions.cs
- DataServiceResponse.cs
- TextParagraphProperties.cs
- MessageEnumerator.cs
- CompoundFileStorageReference.cs
- IgnoreSection.cs
- validation.cs
- DataTable.cs
- SchemaElementLookUpTable.cs
- NamespaceDisplay.xaml.cs
- ListViewUpdateEventArgs.cs
- HttpListenerResponse.cs
- GeometryDrawing.cs
- ImageAnimator.cs
- ListViewUpdatedEventArgs.cs
- CodeEventReferenceExpression.cs
- RequiredFieldValidator.cs
- InvalidComObjectException.cs
- wgx_render.cs
- OutputScopeManager.cs
- MimeImporter.cs
- XmlSchemaGroupRef.cs
- ValidationRule.cs
- XmlReflectionImporter.cs
- FileChangesMonitor.cs