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
- ControlAdapter.cs
- ScrollBar.cs
- MasterPageCodeDomTreeGenerator.cs
- ProviderCommandInfoUtils.cs
- CurrencyWrapper.cs
- XmlAtomicValue.cs
- LicenseProviderAttribute.cs
- httpstaticobjectscollection.cs
- DefaultCompensation.cs
- Scalars.cs
- Vertex.cs
- HostingEnvironmentSection.cs
- ParameterToken.cs
- FactoryGenerator.cs
- TextReturnReader.cs
- PageSettings.cs
- XmlSchemaSimpleType.cs
- SerializationInfoEnumerator.cs
- RootNamespaceAttribute.cs
- Canvas.cs
- CurrencyWrapper.cs
- PasswordBox.cs
- TemplateContentLoader.cs
- ChineseLunisolarCalendar.cs
- DbProviderFactoriesConfigurationHandler.cs
- ArraySegment.cs
- SortQuery.cs
- XamlFilter.cs
- ApplicationContext.cs
- Route.cs
- Stack.cs
- QilPatternVisitor.cs
- ClassicBorderDecorator.cs
- ApplicationProxyInternal.cs
- ConfigurationStrings.cs
- Certificate.cs
- AddressUtility.cs
- CachedPathData.cs
- SamlAction.cs
- Win32Exception.cs
- DesignerForm.cs
- ProfileBuildProvider.cs
- RepeatInfo.cs
- TableLayoutPanelResizeGlyph.cs
- HelpProvider.cs
- TextParentUndoUnit.cs
- DbModificationClause.cs
- CacheDependency.cs
- ActionFrame.cs
- DecimalConstantAttribute.cs
- SettingsAttributeDictionary.cs
- RSAOAEPKeyExchangeDeformatter.cs
- SafeNativeMethods.cs
- ActiveDocumentEvent.cs
- SpnegoTokenAuthenticator.cs
- ScriptResourceHandler.cs
- ChineseLunisolarCalendar.cs
- NodeFunctions.cs
- GB18030Encoding.cs
- ClientUIRequest.cs
- ProfileProvider.cs
- SQLDoubleStorage.cs
- StatusBarPanelClickEvent.cs
- DiscardableAttribute.cs
- WebPartMovingEventArgs.cs
- MatrixTransform3D.cs
- FormsAuthenticationUser.cs
- ExtentCqlBlock.cs
- ProfileGroupSettings.cs
- MdiWindowListItemConverter.cs
- FormsAuthenticationConfiguration.cs
- DataRecord.cs
- TTSVoice.cs
- SelectionWordBreaker.cs
- SettingsPropertyWrongTypeException.cs
- JournalEntryListConverter.cs
- Enlistment.cs
- CoreSwitches.cs
- FunctionNode.cs
- CodeTypeParameter.cs
- PersonalizableTypeEntry.cs
- StringValidatorAttribute.cs
- ParallelDesigner.cs
- MouseOverProperty.cs
- RectKeyFrameCollection.cs
- HwndSourceKeyboardInputSite.cs
- QueueProcessor.cs
- ContextQuery.cs
- EntityDescriptor.cs
- SmtpSection.cs
- AdobeCFFWrapper.cs
- NamedObject.cs
- CriticalHandle.cs
- DeleteHelper.cs
- SocketElement.cs
- RoutedEventArgs.cs
- _ConnectOverlappedAsyncResult.cs
- KeyPullup.cs
- filewebresponse.cs
- QilPatternVisitor.cs