Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Core / CSharp / System / Windows / Media / Effects / Effect.cs / 1305600 / Effect.cs
//------------------------------------------------------------------------------ // Microsoft Avalon // Copyright (c) Microsoft Corporation, 2005 // // File: Effect.cs //----------------------------------------------------------------------------- using System; using System.Diagnostics; using System.Windows; using System.Windows.Media; using System.Security; using System.Security.Permissions; using SecurityHelper=MS.Internal.SecurityHelper; namespace System.Windows.Media.Effects { ////// Effect /// ////// We have the Inheritance demand, because we don't want /// third parties to be able to subclass Effect in the partial trust scenario /// [UIPermissionAttribute(SecurityAction.InheritanceDemand, Window = UIPermissionWindow.AllWindows)] public abstract partial class Effect { static Effect() { // Let the ImplicitInput be a very obscure brush, and treat it as // the implicit input if the exact color matches. Note that this // color will be matched in native code that recognized // ImplicitInput, so don't change. // This specific brush is used as a placeholder for the implicit input // texture. This is a little hacky, but *way* easier than adding a new // Brush subclass for the implicit input and having it work properly // as a real brush. ImplicitInput = new ImplicitInputBrush(); ImplicitInput.Freeze(); } /// Represents the Sampler-destined shader input that comes from /// context. Like the representation of the UIElement when a /// UIElement.Effect is applied. Intended to be set into an input of a /// ShaderEffect. [System.ComponentModel.BrowsableAttribute(false)] public static Brush ImplicitInput { get; private set; } ////// Default constructor for an Effect. /// protected Effect() { // Effects are never allowed in partial trust scenarios. So demand // UIWindow permission immediately in the ctor and get it // over with. SecurityHelper.DemandUIWindowPermission(); } ////// Takes in content bounds, and returns the bounds of the rendered /// output of that content after the Effect is applied. /// internal abstract Rect GetRenderBounds(Rect contentBounds); ////// Input will get transformed through the inverse of this transform. /// TransformToAncestor/Descendant will also go through this. /// Override to modify from the identity transform. Should expect /// incoming coordinates to be in the [0-1] range, and outgoing points /// should map to [0-1] as well. The Inverse property should return a /// GeneralTransform that does the inverse mapping. /// The inverse maps a point from after the effect was applied to the /// point that it came from before the effect. The non-inverse maps /// where a point before the effect is applied goes after the effect is /// applied. /// internal protected virtual GeneralTransform EffectMapping { get { return Transform.Identity; } } // The GeneralTransform returned by Effect is in unit space. The // invocation of GeneralTransform is in world space. This method // returns a GeneralTransform that maps between the two. internal GeneralTransform CoerceToUnitSpaceGeneralTransform(GeneralTransform gt, Rect worldBounds) { GeneralTransform result; // First, if the gt is identity, just return it straight away. if (gt == Transform.Identity) { result = Transform.Identity; } else { // Maintain an MRU cache of GeneralTransforms with exactly one in // it. May want to extend in the future. Note that this will // thrash if the effect is used on multiple elements with different // sizes, but that's not our sweetspot. if (_mruWorldBounds != worldBounds || _mruInnerGeneralTransform != gt) { _mruWorldBounds = worldBounds; _mruInnerGeneralTransform = gt; _mruWorldSpaceGeneralTransform = new UnitSpaceCoercingGeneralTransform(worldBounds, gt); } result = _mruWorldSpaceGeneralTransform; } return result; } internal static Point UnitToWorld(Point unitPoint, Rect worldBounds) { return new Point( worldBounds.Left + unitPoint.X * worldBounds.Width, worldBounds.Top + unitPoint.Y * worldBounds.Height); } internal static Point? WorldToUnit(Point worldPoint, Rect worldBounds) { if (worldBounds.Width == 0 || worldBounds.Height == 0) { return null; } return new Point( (worldPoint.X - worldBounds.Left) / worldBounds.Width, (worldPoint.Y - worldBounds.Top) / worldBounds.Height); } internal static Rect UnitToWorld(Rect unitRect, Rect worldBounds) { return new Rect(UnitToWorld(unitRect.TopLeft, worldBounds), UnitToWorld(unitRect.BottomRight, worldBounds)); } internal static Rect? WorldToUnit(Rect worldRect, Rect worldBounds) { Point? tl = WorldToUnit(worldRect.TopLeft, worldBounds); Point? br = WorldToUnit(worldRect.BottomRight, worldBounds); if (tl == null || br == null) { return null; } return new Rect(tl.Value, br.Value); } // Private GeneralTransform subclass that's all about transforming from // and to the unit square. private class UnitSpaceCoercingGeneralTransform : GeneralTransform { public UnitSpaceCoercingGeneralTransform(Rect worldBounds, GeneralTransform innerTransform) { _worldBounds = worldBounds; _innerTransform = innerTransform; _isInverse = false; } public override GeneralTransform Inverse { get { if (_inverseTransform == null) { // We can cache the clone because the _worldBounds and // inner transform won't change. _inverseTransform = (UnitSpaceCoercingGeneralTransform)this.Clone(); _inverseTransform._isInverse = !_isInverse; } return _inverseTransform; } } public override Rect TransformBounds(Rect rect) { // Since this doesn't rotate or skew, we can just pass each // point to the point transformer. Point topLeftResult = new Point(); Point bottomRightResult = new Point(); bool ok = TryTransform(rect.TopLeft, out topLeftResult) && TryTransform(rect.BottomRight, out bottomRightResult); if (!ok) { return Rect.Empty; } return new Rect(topLeftResult, bottomRightResult); } public override bool TryTransform(Point inPoint, out Point result) { bool ok = false; result = new Point(); // Both the normal and the inverse require the point to first be // translated from world space to unit space. Point? unitSpace = Effect.WorldToUnit(inPoint, _worldBounds); if (unitSpace != null) { // Now just run through the normal or the inverse version of the // inner effect. GeneralTransform innerToUse = GetCorrectInnerTransform(); Point unitResult; if (innerToUse.TryTransform(unitSpace.Value, out unitResult)) { // Both the normal and the inverse require the unit-space result // to be converted back to world space result = Effect.UnitToWorld(unitResult, _worldBounds); ok = true; } } return ok; } protected override Freezable CreateInstanceCore() { return new UnitSpaceCoercingGeneralTransform(_worldBounds, _innerTransform) { _isInverse = _isInverse }; } private GeneralTransform GetCorrectInnerTransform() { GeneralTransform result; if (_isInverse) { if (_innerTransformInverse == null) { // Cache the inverse so it doesn't get new'd up all the // time. _innerTransformInverse = _innerTransform.Inverse; } result = _innerTransformInverse; } else { result = _innerTransform; } return result; } private readonly Rect _worldBounds; private readonly GeneralTransform _innerTransform; private GeneralTransform _innerTransformInverse = null; private bool _isInverse; private UnitSpaceCoercingGeneralTransform _inverseTransform = null; } // Stores the "cache" of bounds x inner transform -> world space transform. private Rect _mruWorldBounds = Rect.Empty; private GeneralTransform _mruInnerGeneralTransform = null; private GeneralTransform _mruWorldSpaceGeneralTransform; } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. //------------------------------------------------------------------------------ // Microsoft Avalon // Copyright (c) Microsoft Corporation, 2005 // // File: Effect.cs //----------------------------------------------------------------------------- using System; using System.Diagnostics; using System.Windows; using System.Windows.Media; using System.Security; using System.Security.Permissions; using SecurityHelper=MS.Internal.SecurityHelper; namespace System.Windows.Media.Effects { ////// Effect /// ////// We have the Inheritance demand, because we don't want /// third parties to be able to subclass Effect in the partial trust scenario /// [UIPermissionAttribute(SecurityAction.InheritanceDemand, Window = UIPermissionWindow.AllWindows)] public abstract partial class Effect { static Effect() { // Let the ImplicitInput be a very obscure brush, and treat it as // the implicit input if the exact color matches. Note that this // color will be matched in native code that recognized // ImplicitInput, so don't change. // This specific brush is used as a placeholder for the implicit input // texture. This is a little hacky, but *way* easier than adding a new // Brush subclass for the implicit input and having it work properly // as a real brush. ImplicitInput = new ImplicitInputBrush(); ImplicitInput.Freeze(); } /// Represents the Sampler-destined shader input that comes from /// context. Like the representation of the UIElement when a /// UIElement.Effect is applied. Intended to be set into an input of a /// ShaderEffect. [System.ComponentModel.BrowsableAttribute(false)] public static Brush ImplicitInput { get; private set; } ////// Default constructor for an Effect. /// protected Effect() { // Effects are never allowed in partial trust scenarios. So demand // UIWindow permission immediately in the ctor and get it // over with. SecurityHelper.DemandUIWindowPermission(); } ////// Takes in content bounds, and returns the bounds of the rendered /// output of that content after the Effect is applied. /// internal abstract Rect GetRenderBounds(Rect contentBounds); ////// Input will get transformed through the inverse of this transform. /// TransformToAncestor/Descendant will also go through this. /// Override to modify from the identity transform. Should expect /// incoming coordinates to be in the [0-1] range, and outgoing points /// should map to [0-1] as well. The Inverse property should return a /// GeneralTransform that does the inverse mapping. /// The inverse maps a point from after the effect was applied to the /// point that it came from before the effect. The non-inverse maps /// where a point before the effect is applied goes after the effect is /// applied. /// internal protected virtual GeneralTransform EffectMapping { get { return Transform.Identity; } } // The GeneralTransform returned by Effect is in unit space. The // invocation of GeneralTransform is in world space. This method // returns a GeneralTransform that maps between the two. internal GeneralTransform CoerceToUnitSpaceGeneralTransform(GeneralTransform gt, Rect worldBounds) { GeneralTransform result; // First, if the gt is identity, just return it straight away. if (gt == Transform.Identity) { result = Transform.Identity; } else { // Maintain an MRU cache of GeneralTransforms with exactly one in // it. May want to extend in the future. Note that this will // thrash if the effect is used on multiple elements with different // sizes, but that's not our sweetspot. if (_mruWorldBounds != worldBounds || _mruInnerGeneralTransform != gt) { _mruWorldBounds = worldBounds; _mruInnerGeneralTransform = gt; _mruWorldSpaceGeneralTransform = new UnitSpaceCoercingGeneralTransform(worldBounds, gt); } result = _mruWorldSpaceGeneralTransform; } return result; } internal static Point UnitToWorld(Point unitPoint, Rect worldBounds) { return new Point( worldBounds.Left + unitPoint.X * worldBounds.Width, worldBounds.Top + unitPoint.Y * worldBounds.Height); } internal static Point? WorldToUnit(Point worldPoint, Rect worldBounds) { if (worldBounds.Width == 0 || worldBounds.Height == 0) { return null; } return new Point( (worldPoint.X - worldBounds.Left) / worldBounds.Width, (worldPoint.Y - worldBounds.Top) / worldBounds.Height); } internal static Rect UnitToWorld(Rect unitRect, Rect worldBounds) { return new Rect(UnitToWorld(unitRect.TopLeft, worldBounds), UnitToWorld(unitRect.BottomRight, worldBounds)); } internal static Rect? WorldToUnit(Rect worldRect, Rect worldBounds) { Point? tl = WorldToUnit(worldRect.TopLeft, worldBounds); Point? br = WorldToUnit(worldRect.BottomRight, worldBounds); if (tl == null || br == null) { return null; } return new Rect(tl.Value, br.Value); } // Private GeneralTransform subclass that's all about transforming from // and to the unit square. private class UnitSpaceCoercingGeneralTransform : GeneralTransform { public UnitSpaceCoercingGeneralTransform(Rect worldBounds, GeneralTransform innerTransform) { _worldBounds = worldBounds; _innerTransform = innerTransform; _isInverse = false; } public override GeneralTransform Inverse { get { if (_inverseTransform == null) { // We can cache the clone because the _worldBounds and // inner transform won't change. _inverseTransform = (UnitSpaceCoercingGeneralTransform)this.Clone(); _inverseTransform._isInverse = !_isInverse; } return _inverseTransform; } } public override Rect TransformBounds(Rect rect) { // Since this doesn't rotate or skew, we can just pass each // point to the point transformer. Point topLeftResult = new Point(); Point bottomRightResult = new Point(); bool ok = TryTransform(rect.TopLeft, out topLeftResult) && TryTransform(rect.BottomRight, out bottomRightResult); if (!ok) { return Rect.Empty; } return new Rect(topLeftResult, bottomRightResult); } public override bool TryTransform(Point inPoint, out Point result) { bool ok = false; result = new Point(); // Both the normal and the inverse require the point to first be // translated from world space to unit space. Point? unitSpace = Effect.WorldToUnit(inPoint, _worldBounds); if (unitSpace != null) { // Now just run through the normal or the inverse version of the // inner effect. GeneralTransform innerToUse = GetCorrectInnerTransform(); Point unitResult; if (innerToUse.TryTransform(unitSpace.Value, out unitResult)) { // Both the normal and the inverse require the unit-space result // to be converted back to world space result = Effect.UnitToWorld(unitResult, _worldBounds); ok = true; } } return ok; } protected override Freezable CreateInstanceCore() { return new UnitSpaceCoercingGeneralTransform(_worldBounds, _innerTransform) { _isInverse = _isInverse }; } private GeneralTransform GetCorrectInnerTransform() { GeneralTransform result; if (_isInverse) { if (_innerTransformInverse == null) { // Cache the inverse so it doesn't get new'd up all the // time. _innerTransformInverse = _innerTransform.Inverse; } result = _innerTransformInverse; } else { result = _innerTransform; } return result; } private readonly Rect _worldBounds; private readonly GeneralTransform _innerTransform; private GeneralTransform _innerTransformInverse = null; private bool _isInverse; private UnitSpaceCoercingGeneralTransform _inverseTransform = null; } // Stores the "cache" of bounds x inner transform -> world space transform. private Rect _mruWorldBounds = Rect.Empty; private GeneralTransform _mruInnerGeneralTransform = null; private GeneralTransform _mruWorldSpaceGeneralTransform; } } // 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
- InternalControlCollection.cs
- Vars.cs
- Track.cs
- ByteStreamBufferedMessageData.cs
- DesignerOptionService.cs
- XamlToRtfParser.cs
- ServiceObjectContainer.cs
- PageBuildProvider.cs
- CacheMemory.cs
- NavigationHelper.cs
- Simplifier.cs
- KnownIds.cs
- ListControlBoundActionList.cs
- ResourceSetExpression.cs
- DiffuseMaterial.cs
- TimerEventSubscriptionCollection.cs
- ModelChangedEventArgsImpl.cs
- DataGridViewDataErrorEventArgs.cs
- CSharpCodeProvider.cs
- EFAssociationProvider.cs
- ActivityExecutionFilter.cs
- SymDocumentType.cs
- BooleanKeyFrameCollection.cs
- ProcessModuleCollection.cs
- WebBaseEventKeyComparer.cs
- PointConverter.cs
- DataGridViewAutoSizeModeEventArgs.cs
- ViewStateException.cs
- UrlMappingsSection.cs
- CodeParameterDeclarationExpressionCollection.cs
- TracingConnectionListener.cs
- CombinedGeometry.cs
- QueryCreatedEventArgs.cs
- LoginUtil.cs
- PackUriHelper.cs
- JournalEntryStack.cs
- DataGridViewSortCompareEventArgs.cs
- SystemMulticastIPAddressInformation.cs
- DropShadowEffect.cs
- HttpCacheVaryByContentEncodings.cs
- XmlSchemaImport.cs
- SymbolMethod.cs
- ShutDownListener.cs
- ZipIOCentralDirectoryFileHeader.cs
- UnsettableComboBox.cs
- ProbeDuplex11AsyncResult.cs
- OrthographicCamera.cs
- CaseInsensitiveOrdinalStringComparer.cs
- safemediahandle.cs
- NamespaceImport.cs
- ExpandableObjectConverter.cs
- DeflateStream.cs
- EntitySqlQueryCacheEntry.cs
- DescendantQuery.cs
- ISAPIRuntime.cs
- SecureUICommand.cs
- DataServiceProviderMethods.cs
- TableCellCollection.cs
- GraphicsPathIterator.cs
- AppDomainShutdownMonitor.cs
- WebEncodingValidator.cs
- RegisterInfo.cs
- Identifier.cs
- TabPanel.cs
- IListConverters.cs
- DataGridViewCellStyle.cs
- XsdDuration.cs
- Grid.cs
- Collection.cs
- TabControlEvent.cs
- PropertyGridCommands.cs
- SqlDeflator.cs
- ProfileService.cs
- PropertySourceInfo.cs
- _SslState.cs
- SupportsEventValidationAttribute.cs
- ToolboxItemAttribute.cs
- GenericAuthenticationEventArgs.cs
- TransformationRules.cs
- FaultDesigner.cs
- HtmlSelectionListAdapter.cs
- ProviderMetadata.cs
- MD5CryptoServiceProvider.cs
- _ListenerResponseStream.cs
- GenericWebPart.cs
- WindowsGraphicsCacheManager.cs
- ObjectItemCollection.cs
- EntityViewGenerationConstants.cs
- XXXInfos.cs
- AdapterDictionary.cs
- NavigationCommands.cs
- JpegBitmapDecoder.cs
- SiteOfOriginPart.cs
- CodeExporter.cs
- HandlerMappingMemo.cs
- AspNetHostingPermission.cs
- PropertyPathWorker.cs
- Rights.cs
- ObjectDataSourceEventArgs.cs
- SystemWebCachingSectionGroup.cs