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
- XmlSignatureManifest.cs
- HiddenField.cs
- PropertyHelper.cs
- SplitterCancelEvent.cs
- ProxyManager.cs
- FontInfo.cs
- RenameRuleObjectDialog.cs
- DataGridViewAutoSizeModeEventArgs.cs
- ImageAnimator.cs
- SizeChangedInfo.cs
- TextSearch.cs
- OdbcException.cs
- DeclarativeCatalogPart.cs
- EffectiveValueEntry.cs
- controlskin.cs
- MessageBox.cs
- QueryOutputWriter.cs
- _NestedSingleAsyncResult.cs
- DynamicPropertyHolder.cs
- RoutedEvent.cs
- XmlMapping.cs
- RTLAwareMessageBox.cs
- ContextBase.cs
- WebBrowserSiteBase.cs
- HtmlGenericControl.cs
- CommonXSendMessage.cs
- WebBrowsableAttribute.cs
- SettingsProviderCollection.cs
- _HTTPDateParse.cs
- KeysConverter.cs
- UnsafeNativeMethods.cs
- WebBrowserEvent.cs
- TimersDescriptionAttribute.cs
- DataGridViewCellValueEventArgs.cs
- SegmentInfo.cs
- FormViewDeleteEventArgs.cs
- StrokeSerializer.cs
- WindowsComboBox.cs
- CustomCredentialPolicy.cs
- DefaultDialogButtons.cs
- Size.cs
- ListViewDeletedEventArgs.cs
- PixelShader.cs
- FormViewDeleteEventArgs.cs
- BitmapSource.cs
- SQLInt64Storage.cs
- RectKeyFrameCollection.cs
- HwndStylusInputProvider.cs
- StringFormat.cs
- DataGridCellInfo.cs
- RegexWorker.cs
- ErrorHandler.cs
- StreamInfo.cs
- LookupBindingPropertiesAttribute.cs
- SystemException.cs
- ToolStripDropDownClosedEventArgs.cs
- TypeToken.cs
- InlineUIContainer.cs
- BamlLocalizerErrorNotifyEventArgs.cs
- odbcmetadatafactory.cs
- DataGridDefaultColumnWidthTypeConverter.cs
- CSharpCodeProvider.cs
- OracleFactory.cs
- base64Transforms.cs
- rsa.cs
- ConfigurationSection.cs
- IERequestCache.cs
- SessionState.cs
- SequenceFullException.cs
- KeyboardEventArgs.cs
- DataGridItemCollection.cs
- AudioDeviceOut.cs
- TrustSection.cs
- BindingList.cs
- dsa.cs
- GridViewDeletedEventArgs.cs
- DataControlImageButton.cs
- HtmlInputButton.cs
- FontStretches.cs
- HttpHeaderCollection.cs
- ILGenerator.cs
- ListItemCollection.cs
- _LocalDataStore.cs
- GlyphInfoList.cs
- ReaderOutput.cs
- LOSFormatter.cs
- SwitchAttribute.cs
- BindToObject.cs
- CompiledAction.cs
- QueueNameHelper.cs
- ListBindableAttribute.cs
- XsdValidatingReader.cs
- FacetValues.cs
- TemplateKey.cs
- DrawingState.cs
- StorageSetMapping.cs
- DataGridCaption.cs
- cache.cs
- Geometry3D.cs
- ExpandableObjectConverter.cs