Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / wpf / src / Core / CSharp / System / Windows / Media / Effects / BitmapEffectState.cs / 1 / BitmapEffectState.cs
//----------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// File: BitmapEffectState.cs
//
// Description: This file contains the implementation of BitmapEffectState.
// This is the base class for holding the bitmap effect state.
//
// History:
// 07/25/2005 : [....] - Created it.
//
//---------------------------------------------------------------------------
using System;
using System.Windows.Threading;
using MS.Win32;
using System.Security;
using System.Security.Permissions;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Composition;
using System.Windows.Media.Imaging;
using System.Diagnostics;
using System.Collections;
using System.Collections.Generic;
using MS.Internal;
using System.Resources;
using MS.Utility;
using System.Runtime.InteropServices;
using MS.Internal.PresentationCore;
using SR = MS.Internal.PresentationCore.SR;
using SRID = MS.Internal.PresentationCore.SRID;
namespace System.Windows.Media.Effects
{
internal class BitmapEffectState
{
public BitmapEffectState()
{
}
internal BitmapEffect BitmapEffect
{
get { return _bitmapEffect; }
set { _bitmapEffect = value; }
}
internal BitmapEffectInput BitmapEffectInput
{
get { return _bitmapEffectInput; }
set { _bitmapEffectInput = value; }
}
///
/// Calculates the bitmap effect bounds given a bounding box
///
///
///
internal Rect GetBounds(Rect bbox)
{
if (_bitmapEffect == null)
{
return bbox;
}
BitmapEffectInput bitmapEffectInput = (_bitmapEffectInput != null) ?
_bitmapEffectInput :
new BitmapEffectInput();
return _bitmapEffect.TransformRect(bitmapEffectInput, bbox, false /* fInverse */);
}
///
/// Transforms a point for hit testing
///
///
///
///
///
internal bool TransformHitPoint(Rect bounds, Point inPoint, out Point outPoint)
{
outPoint = inPoint;
if (_bitmapEffect == null)
{
return false;
}
BitmapEffectInput bitmapEffectInput = (_bitmapEffectInput != null) ?
_bitmapEffectInput :
new BitmapEffectInput();
_bitmapEffect.VisualBounds = bounds;
return _bitmapEffect.TransformPoint(bitmapEffectInput, inPoint, out outPoint, true);
}
///
/// This method extracts the scale matrix out of the matrix passed in
///
/// the matrix to decompose
/// the scale matrix
private Matrix ExtractScaleMatrix(Matrix matrix)
{
Vector transformedUnitX = matrix.Transform(new Vector(1.0, 0.0));
Vector transformedUnitY = matrix.Transform(new Vector(0.0, 1.0));
return Matrix.CreateScaling(
transformedUnitX.Length,
transformedUnitY.Length);
}
///
/// This methods renders the visual to a bitmap, then applies
/// the effect to the rendered bitmap, and sets the content
/// of the visual to be the resulting bitmap
///
///
/// SecurityCritical: This is code that retrieves the WicSourceHandle which is critical
/// SecurityTreatAsSafe: The inputs are safe and WicSourceHandle is not given out.
///
[SecurityCritical, SecurityTreatAsSafe]
protected BitmapSource GetEffectOutput(Visual visual, ref RenderTargetBitmap renderBitmap, Matrix worldTransform, Rect windowClip, out Matrix finalTransform)
{
BitmapSource outputImage = null;
finalTransform = worldTransform;
if (worldTransform.HasInverse)
{
// Compute the bounding box of the visual and its descendants
// NOTE: PushEffect could have empty bounds if there is nothing
// drawn between the PushEffect and Pop calls
Rect bounds = visual.VisualContentBounds;
bounds.Union(visual.VisualDescendantBounds);
Matrix scaleMatrix = ExtractScaleMatrix(worldTransform);
Matrix effectMatrix = scaleMatrix;
effectMatrix.OffsetX = worldTransform.OffsetX;
effectMatrix.OffsetY = worldTransform.OffsetY;
// this is to handle RTL scenarios
Matrix flipMatrix = Matrix.CreateScaling(worldTransform.M11 / Math.Abs(worldTransform.M11),
worldTransform.M22 / Math.Abs(worldTransform.M22));
if (!flipMatrix.IsIdentity)
bounds.Transform(flipMatrix);
// apply the scale transform to the bounds
bounds.Transform(effectMatrix);
// clip to the size of the screen + windowClip
bounds.Intersect(GetClipRect(windowClip));
if (!flipMatrix.IsIdentity)
bounds.Transform(flipMatrix);
if (!bounds.IsEmpty)
{
// round to the nearest integer
// we want to make sure everything is pixel aligned otherwise we
// potentially get blurring, see bug 1245106
bounds.Width = Math.Ceiling(bounds.Right) - Math.Floor(bounds.Left);
bounds.Height = Math.Ceiling(bounds.Bottom) - Math.Floor(bounds.Top);
bounds.X = Math.Floor(bounds.X);
bounds.Y = Math.Floor(bounds.Y);
// start drawing at 0,0
effectMatrix.Translate(-bounds.X*flipMatrix.M11, -bounds.Y*flipMatrix.M22);
int width = (int)bounds.Width;
int height = (int)bounds.Height;
// if the bounds have either 0 height or 0 width,
// we don't want to render anything
// This is because you cannot create an empty image.
if (width > 0 && height > 0)
{
if (renderBitmap == null ||
renderBitmap.PixelWidth != width ||
renderBitmap.PixelHeight != height)
{
renderBitmap = new RenderTargetBitmap(width,
height,
DefaultDevicePixelsPerInch,
DefaultDevicePixelsPerInch,
PixelFormats.Pbgra32);
}
renderBitmap.RenderForBitmapEffect(visual, effectMatrix, windowClip);
if (_bitmapEffect != null)
{
// Push our worldTransform into the render context. This will make an interop
// call into the unmanaged render context object.
_bitmapEffect.RenderContext.Transform = worldTransform;
// set up the input
BitmapEffectInput bitmapEffectInput = (_bitmapEffectInput != null) ?
_bitmapEffectInput :
new BitmapEffectInput();
if (bitmapEffectInput.Input == BitmapEffectInput.ContextInputSource ||
bitmapEffectInput.Input == null)
{
bitmapEffectInput = bitmapEffectInput.CloneCurrentValue();
bitmapEffectInput.Input = renderBitmap;
}
else if (scaleMatrix.IsIdentity == false)
{
bitmapEffectInput.Input = new TransformedBitmap(bitmapEffectInput.Input, new MatrixTransform(scaleMatrix));
}
if (bitmapEffectInput.AreaToApplyEffectUnits == BrushMappingMode.Absolute)
{
Rect area = bitmapEffectInput.AreaToApplyEffect;
area.Transform(scaleMatrix);
bitmapEffectInput.AreaToApplyEffect = area;
}
// Run the effect
outputImage = _bitmapEffect.GetOutput(bitmapEffectInput);
// Get back our final transformation (i.e. the one the effect graph
// updated, since it may have offset the output image).
finalTransform = _bitmapEffect.RenderContext.Transform;
}
else
{
outputImage = new UnmanagedBitmapWrapper(renderBitmap.WicSourceHandle);
finalTransform = Matrix.Identity;
}
// transform back the image, because the world transform will
// be applied to the visual again
//
// This is equivalent to - EffectOffset*BoundsOffset*WorldInverse
// EffectOffset is the potential offset needed if an effect expands the
// bounds
// BoundsOffset is to draw the image where necessary since we translated it
// to be drawn at (0,0)
// WorldInverse is necessary since we already applied the world transform
effectMatrix.Invert();
finalTransform = Matrix.CreateTranslation(finalTransform._offsetX, finalTransform._offsetY) * effectMatrix;
}
}
}
return outputImage;
}
///
/// SecurityCritical: This is code that calls into native unmanaged methods
/// SecurityTreatAsSafe: This data is not unsecure and the elevation has a SUC on it.
///
private static Rect ScreenRect
{
[SecurityCritical, SecurityTreatAsSafe]
get
{
if (_screenRect.IsEmpty)
{
_screenRect = new Rect(
UnsafeNativeMethods.GetSystemMetrics(NativeMethods.SM_XVIRTUALSCREEN),
UnsafeNativeMethods.GetSystemMetrics(NativeMethods.SM_YVIRTUALSCREEN),
UnsafeNativeMethods.GetSystemMetrics(NativeMethods.SM_CXVIRTUALSCREEN),
UnsafeNativeMethods.GetSystemMetrics(NativeMethods.SM_CYVIRTUALSCREEN));
}
return _screenRect;
}
}
///
/// Computes the window clip used to clip the visual bounds against
///
private Rect GetClipRect(Rect rect)
{
Rect clipRect = BitmapEffectState.ScreenRect;
clipRect.Union(rect);
clipRect.X -= WindowClipPadding;
clipRect.Y -= WindowClipPadding;
clipRect.Width += WindowClipPadding;
clipRect.Height += WindowClipPadding;
return clipRect;
}
#region Fields
protected BitmapEffect _bitmapEffect;
protected BitmapEffectInput _bitmapEffectInput;
protected static Rect _screenRect = Rect.Empty;
private const int WindowClipPadding = 100;
internal const double DefaultDevicePixelsPerInch = 96.0;
#endregion
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//----------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// File: BitmapEffectState.cs
//
// Description: This file contains the implementation of BitmapEffectState.
// This is the base class for holding the bitmap effect state.
//
// History:
// 07/25/2005 : [....] - Created it.
//
//---------------------------------------------------------------------------
using System;
using System.Windows.Threading;
using MS.Win32;
using System.Security;
using System.Security.Permissions;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Composition;
using System.Windows.Media.Imaging;
using System.Diagnostics;
using System.Collections;
using System.Collections.Generic;
using MS.Internal;
using System.Resources;
using MS.Utility;
using System.Runtime.InteropServices;
using MS.Internal.PresentationCore;
using SR = MS.Internal.PresentationCore.SR;
using SRID = MS.Internal.PresentationCore.SRID;
namespace System.Windows.Media.Effects
{
internal class BitmapEffectState
{
public BitmapEffectState()
{
}
internal BitmapEffect BitmapEffect
{
get { return _bitmapEffect; }
set { _bitmapEffect = value; }
}
internal BitmapEffectInput BitmapEffectInput
{
get { return _bitmapEffectInput; }
set { _bitmapEffectInput = value; }
}
///
/// Calculates the bitmap effect bounds given a bounding box
///
///
///
internal Rect GetBounds(Rect bbox)
{
if (_bitmapEffect == null)
{
return bbox;
}
BitmapEffectInput bitmapEffectInput = (_bitmapEffectInput != null) ?
_bitmapEffectInput :
new BitmapEffectInput();
return _bitmapEffect.TransformRect(bitmapEffectInput, bbox, false /* fInverse */);
}
///
/// Transforms a point for hit testing
///
///
///
///
///
internal bool TransformHitPoint(Rect bounds, Point inPoint, out Point outPoint)
{
outPoint = inPoint;
if (_bitmapEffect == null)
{
return false;
}
BitmapEffectInput bitmapEffectInput = (_bitmapEffectInput != null) ?
_bitmapEffectInput :
new BitmapEffectInput();
_bitmapEffect.VisualBounds = bounds;
return _bitmapEffect.TransformPoint(bitmapEffectInput, inPoint, out outPoint, true);
}
///
/// This method extracts the scale matrix out of the matrix passed in
///
/// the matrix to decompose
/// the scale matrix
private Matrix ExtractScaleMatrix(Matrix matrix)
{
Vector transformedUnitX = matrix.Transform(new Vector(1.0, 0.0));
Vector transformedUnitY = matrix.Transform(new Vector(0.0, 1.0));
return Matrix.CreateScaling(
transformedUnitX.Length,
transformedUnitY.Length);
}
///
/// This methods renders the visual to a bitmap, then applies
/// the effect to the rendered bitmap, and sets the content
/// of the visual to be the resulting bitmap
///
///
/// SecurityCritical: This is code that retrieves the WicSourceHandle which is critical
/// SecurityTreatAsSafe: The inputs are safe and WicSourceHandle is not given out.
///
[SecurityCritical, SecurityTreatAsSafe]
protected BitmapSource GetEffectOutput(Visual visual, ref RenderTargetBitmap renderBitmap, Matrix worldTransform, Rect windowClip, out Matrix finalTransform)
{
BitmapSource outputImage = null;
finalTransform = worldTransform;
if (worldTransform.HasInverse)
{
// Compute the bounding box of the visual and its descendants
// NOTE: PushEffect could have empty bounds if there is nothing
// drawn between the PushEffect and Pop calls
Rect bounds = visual.VisualContentBounds;
bounds.Union(visual.VisualDescendantBounds);
Matrix scaleMatrix = ExtractScaleMatrix(worldTransform);
Matrix effectMatrix = scaleMatrix;
effectMatrix.OffsetX = worldTransform.OffsetX;
effectMatrix.OffsetY = worldTransform.OffsetY;
// this is to handle RTL scenarios
Matrix flipMatrix = Matrix.CreateScaling(worldTransform.M11 / Math.Abs(worldTransform.M11),
worldTransform.M22 / Math.Abs(worldTransform.M22));
if (!flipMatrix.IsIdentity)
bounds.Transform(flipMatrix);
// apply the scale transform to the bounds
bounds.Transform(effectMatrix);
// clip to the size of the screen + windowClip
bounds.Intersect(GetClipRect(windowClip));
if (!flipMatrix.IsIdentity)
bounds.Transform(flipMatrix);
if (!bounds.IsEmpty)
{
// round to the nearest integer
// we want to make sure everything is pixel aligned otherwise we
// potentially get blurring, see bug 1245106
bounds.Width = Math.Ceiling(bounds.Right) - Math.Floor(bounds.Left);
bounds.Height = Math.Ceiling(bounds.Bottom) - Math.Floor(bounds.Top);
bounds.X = Math.Floor(bounds.X);
bounds.Y = Math.Floor(bounds.Y);
// start drawing at 0,0
effectMatrix.Translate(-bounds.X*flipMatrix.M11, -bounds.Y*flipMatrix.M22);
int width = (int)bounds.Width;
int height = (int)bounds.Height;
// if the bounds have either 0 height or 0 width,
// we don't want to render anything
// This is because you cannot create an empty image.
if (width > 0 && height > 0)
{
if (renderBitmap == null ||
renderBitmap.PixelWidth != width ||
renderBitmap.PixelHeight != height)
{
renderBitmap = new RenderTargetBitmap(width,
height,
DefaultDevicePixelsPerInch,
DefaultDevicePixelsPerInch,
PixelFormats.Pbgra32);
}
renderBitmap.RenderForBitmapEffect(visual, effectMatrix, windowClip);
if (_bitmapEffect != null)
{
// Push our worldTransform into the render context. This will make an interop
// call into the unmanaged render context object.
_bitmapEffect.RenderContext.Transform = worldTransform;
// set up the input
BitmapEffectInput bitmapEffectInput = (_bitmapEffectInput != null) ?
_bitmapEffectInput :
new BitmapEffectInput();
if (bitmapEffectInput.Input == BitmapEffectInput.ContextInputSource ||
bitmapEffectInput.Input == null)
{
bitmapEffectInput = bitmapEffectInput.CloneCurrentValue();
bitmapEffectInput.Input = renderBitmap;
}
else if (scaleMatrix.IsIdentity == false)
{
bitmapEffectInput.Input = new TransformedBitmap(bitmapEffectInput.Input, new MatrixTransform(scaleMatrix));
}
if (bitmapEffectInput.AreaToApplyEffectUnits == BrushMappingMode.Absolute)
{
Rect area = bitmapEffectInput.AreaToApplyEffect;
area.Transform(scaleMatrix);
bitmapEffectInput.AreaToApplyEffect = area;
}
// Run the effect
outputImage = _bitmapEffect.GetOutput(bitmapEffectInput);
// Get back our final transformation (i.e. the one the effect graph
// updated, since it may have offset the output image).
finalTransform = _bitmapEffect.RenderContext.Transform;
}
else
{
outputImage = new UnmanagedBitmapWrapper(renderBitmap.WicSourceHandle);
finalTransform = Matrix.Identity;
}
// transform back the image, because the world transform will
// be applied to the visual again
//
// This is equivalent to - EffectOffset*BoundsOffset*WorldInverse
// EffectOffset is the potential offset needed if an effect expands the
// bounds
// BoundsOffset is to draw the image where necessary since we translated it
// to be drawn at (0,0)
// WorldInverse is necessary since we already applied the world transform
effectMatrix.Invert();
finalTransform = Matrix.CreateTranslation(finalTransform._offsetX, finalTransform._offsetY) * effectMatrix;
}
}
}
return outputImage;
}
///
/// SecurityCritical: This is code that calls into native unmanaged methods
/// SecurityTreatAsSafe: This data is not unsecure and the elevation has a SUC on it.
///
private static Rect ScreenRect
{
[SecurityCritical, SecurityTreatAsSafe]
get
{
if (_screenRect.IsEmpty)
{
_screenRect = new Rect(
UnsafeNativeMethods.GetSystemMetrics(NativeMethods.SM_XVIRTUALSCREEN),
UnsafeNativeMethods.GetSystemMetrics(NativeMethods.SM_YVIRTUALSCREEN),
UnsafeNativeMethods.GetSystemMetrics(NativeMethods.SM_CXVIRTUALSCREEN),
UnsafeNativeMethods.GetSystemMetrics(NativeMethods.SM_CYVIRTUALSCREEN));
}
return _screenRect;
}
}
///
/// Computes the window clip used to clip the visual bounds against
///
private Rect GetClipRect(Rect rect)
{
Rect clipRect = BitmapEffectState.ScreenRect;
clipRect.Union(rect);
clipRect.X -= WindowClipPadding;
clipRect.Y -= WindowClipPadding;
clipRect.Width += WindowClipPadding;
clipRect.Height += WindowClipPadding;
return clipRect;
}
#region Fields
protected BitmapEffect _bitmapEffect;
protected BitmapEffectInput _bitmapEffectInput;
protected static Rect _screenRect = Rect.Empty;
private const int WindowClipPadding = 100;
internal const double DefaultDevicePixelsPerInch = 96.0;
#endregion
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- SmiMetaData.cs
- ListParaClient.cs
- PageContentAsyncResult.cs
- GreenMethods.cs
- RowSpanVector.cs
- PopupRootAutomationPeer.cs
- DesigntimeLicenseContextSerializer.cs
- PermissionSetTriple.cs
- Walker.cs
- SecurityContext.cs
- ClientUrlResolverWrapper.cs
- templategroup.cs
- ExtentCqlBlock.cs
- PackagePart.cs
- SecurityVerifiedMessage.cs
- versioninfo.cs
- PlainXmlSerializer.cs
- SerialStream.cs
- SQLInt64.cs
- CheckBoxStandardAdapter.cs
- ListMarkerSourceInfo.cs
- TypeEnumerableViewSchema.cs
- LexicalChunk.cs
- ChangeToolStripParentVerb.cs
- PrintSchema.cs
- wgx_commands.cs
- WebConfigurationHost.cs
- ModuleConfigurationInfo.cs
- RootBuilder.cs
- XmlAttributeCollection.cs
- CuspData.cs
- OleCmdHelper.cs
- AutoGeneratedFieldProperties.cs
- BindingWorker.cs
- ListViewDataItem.cs
- ScrollBar.cs
- SizeIndependentAnimationStorage.cs
- Double.cs
- SafeFindHandle.cs
- CheckBoxFlatAdapter.cs
- QilParameter.cs
- IsolatedStorageFileStream.cs
- ThicknessAnimation.cs
- ScrollBar.cs
- AnchoredBlock.cs
- TileBrush.cs
- ElementProxy.cs
- XmlSchemaCompilationSettings.cs
- SystemIPInterfaceProperties.cs
- RegisteredScript.cs
- Matrix3DValueSerializer.cs
- Win32Native.cs
- GatewayIPAddressInformationCollection.cs
- SocketPermission.cs
- WsatServiceCertificate.cs
- SessionState.cs
- ApplicationServicesHostFactory.cs
- CollectionChangeEventArgs.cs
- AutomationPatternInfo.cs
- SessionStateContainer.cs
- XmlBinaryWriter.cs
- MembershipValidatePasswordEventArgs.cs
- PublisherIdentityPermission.cs
- TextRangeEdit.cs
- ColumnWidthChangingEvent.cs
- DataPointer.cs
- SelectionEditor.cs
- _PooledStream.cs
- EntityParameter.cs
- DeviceFilterEditorDialog.cs
- Mapping.cs
- InvalidPropValue.cs
- EnumValidator.cs
- OutOfMemoryException.cs
- COSERVERINFO.cs
- StateInitializationDesigner.cs
- XPathConvert.cs
- ScrollBarAutomationPeer.cs
- TraceProvider.cs
- XmlRawWriterWrapper.cs
- EntityWrapper.cs
- LinkedResourceCollection.cs
- HttpCachePolicy.cs
- WindowsRichEdit.cs
- ToolBarTray.cs
- ParameterDataSourceExpression.cs
- SignerInfo.cs
- MetadataException.cs
- LoginCancelEventArgs.cs
- MouseButtonEventArgs.cs
- OSFeature.cs
- Common.cs
- BitmapFrameEncode.cs
- Function.cs
- SystemColors.cs
- LiteralControl.cs
- HttpCapabilitiesBase.cs
- DataGridViewAdvancedBorderStyle.cs
- DisplayToken.cs
- LocalizabilityAttribute.cs