Code:
/ DotNET / DotNET / 8.0 / untmp / WIN_WINDOWS / lh_tools_devdiv_wpf / Windows / wcp / Shared / MS / Internal / MatrixUtil.cs / 1 / MatrixUtil.cs
//---------------------------------------------------------------------------- // // Copyright (C) Microsoft Corporation. All rights reserved. // // File: MatrixUtil.cs // // Description: This file contains the implementation of MatrixUtil, which // provides matrix multiply code. // // History: // 01/06/2004 : [....] - Created, most copied from wcp\core\system\windows\media\milutilities.cs // //--------------------------------------------------------------------------- using System; using System.Windows; using System.Windows.Media; using System.Diagnostics; using System.Security; using System.Security.Permissions; #if WINDOWS_BASE using MS.Internal.WindowsBase; #elif PRESENTATION_CORE using MS.Internal.PresentationCore; #elif PRESENTATIONFRAMEWORK using MS.Internal.PresentationFramework; #elif DRT using MS.Internal.Drt; #else #error Attempt to use FriendAccessAllowedAttribute from an unknown assembly. using MS.Internal.YourAssemblyName; #endif namespace MS.Internal { // MatrixTypes [System.Flags] internal enum MatrixTypes { TRANSFORM_IS_IDENTITY = 0, TRANSFORM_IS_TRANSLATION = 1, TRANSFORM_IS_SCALING = 2, TRANSFORM_IS_UNKNOWN = 4 } [FriendAccessAllowed] internal static class MatrixUtil { ////// TransformRect - Internal helper for perf /// /// The Rect to transform. /// The Matrix with which to transform the Rect. internal static void TransformRect(ref Rect rect, ref Matrix matrix) { if (rect.IsEmpty) { return; } MatrixTypes matrixType = matrix._type; // If the matrix is identity, don't worry. if (matrixType == MatrixTypes.TRANSFORM_IS_IDENTITY) { return; } // Scaling if (0 != (matrixType & MatrixTypes.TRANSFORM_IS_SCALING)) { rect._x *= matrix._m11; rect._y *= matrix._m22; rect._width *= matrix._m11; rect._height *= matrix._m22; // Ensure the width is always positive. For example, if there was a reflection about the // y axis followed by a translation into the visual area, the width could be negative. if (rect._width < 0.0) { rect._x += rect._width; rect._width = -rect._width; } // Ensure the height is always positive. For example, if there was a reflection about the // x axis followed by a translation into the visual area, the height could be negative. if (rect._height < 0.0) { rect._y += rect._height; rect._height = -rect._height; } } // Translation if (0 != (matrixType & MatrixTypes.TRANSFORM_IS_TRANSLATION)) { // X rect._x += matrix._offsetX; // Y rect._y += matrix._offsetY; } if (matrixType == MatrixTypes.TRANSFORM_IS_UNKNOWN) { // Al Bunny implementation. Point point0 = matrix.Transform(rect.TopLeft); Point point1 = matrix.Transform(rect.TopRight); Point point2 = matrix.Transform(rect.BottomRight); Point point3 = matrix.Transform(rect.BottomLeft); // Width and height is always positive here. rect._x = Math.Min(Math.Min(point0.X, point1.X), Math.Min(point2.X, point3.X)); rect._y = Math.Min(Math.Min(point0.Y, point1.Y), Math.Min(point2.Y, point3.Y)); rect._width = Math.Max(Math.Max(point0.X, point1.X), Math.Max(point2.X, point3.X)) - rect._x; rect._height = Math.Max(Math.Max(point0.Y, point1.Y), Math.Max(point2.Y, point3.Y)) - rect._y; } } ////// Multiplies two transformations, where the behavior is matrix1 *= matrix2. /// This code exists so that we can efficient combine matrices without copying /// the data around, since each matrix is 52 bytes. /// To reduce duplication and to ensure consistent behavior, this is the /// method which is used to implement Matrix * Matrix as well. /// internal static void MultiplyMatrix(ref Matrix matrix1, ref Matrix matrix2) { MatrixTypes type1 = matrix1._type; MatrixTypes type2 = matrix2._type; // Check for idents // If the second is ident, we can just return if (type2 == MatrixTypes.TRANSFORM_IS_IDENTITY) { return; } // If the first is ident, we can just copy the memory across. if (type1 == MatrixTypes.TRANSFORM_IS_IDENTITY) { matrix1 = matrix2; return; } // Optimize for translate case, where the second is a translate if (type2 == MatrixTypes.TRANSFORM_IS_TRANSLATION) { // 2 additions matrix1._offsetX += matrix2._offsetX; matrix1._offsetY += matrix2._offsetY; // If matrix 1 wasn't unknown we added a translation if (type1 != MatrixTypes.TRANSFORM_IS_UNKNOWN) { matrix1._type |= MatrixTypes.TRANSFORM_IS_TRANSLATION; } return; } // Check for the first value being a translate if (type1 == MatrixTypes.TRANSFORM_IS_TRANSLATION) { // Save off the old offsets double offsetX = matrix1._offsetX; double offsetY = matrix1._offsetY; // Copy the matrix matrix1 = matrix2; matrix1._offsetX = offsetX * matrix2._m11 + offsetY * matrix2._m21 + matrix2._offsetX; matrix1._offsetY = offsetX * matrix2._m12 + offsetY * matrix2._m22 + matrix2._offsetY; if (type2 == MatrixTypes.TRANSFORM_IS_UNKNOWN) { matrix1._type = MatrixTypes.TRANSFORM_IS_UNKNOWN; } else { matrix1._type = MatrixTypes.TRANSFORM_IS_SCALING | MatrixTypes.TRANSFORM_IS_TRANSLATION; } return; } // The following code combines the type of the transformations so that the high nibble // is "this"'s type, and the low nibble is mat's type. This allows for a switch rather // than nested switches. // trans1._type | trans2._type // 7 6 5 4 | 3 2 1 0 int combinedType = ((int)type1 << 4) | (int)type2; switch (combinedType) { case 34: // S * S // 2 multiplications matrix1._m11 *= matrix2._m11; matrix1._m22 *= matrix2._m22; return; case 35: // S * S|T matrix1._m11 *= matrix2._m11; matrix1._m22 *= matrix2._m22; matrix1._offsetX = matrix2._offsetX; matrix1._offsetY = matrix2._offsetY; // Transform set to Translate and Scale matrix1._type = MatrixTypes.TRANSFORM_IS_TRANSLATION | MatrixTypes.TRANSFORM_IS_SCALING; return; case 50: // S|T * S matrix1._m11 *= matrix2._m11; matrix1._m22 *= matrix2._m22; matrix1._offsetX *= matrix2._m11; matrix1._offsetY *= matrix2._m22; return; case 51: // S|T * S|T matrix1._m11 *= matrix2._m11; matrix1._m22 *= matrix2._m22; matrix1._offsetX = matrix2._m11 * matrix1._offsetX + matrix2._offsetX; matrix1._offsetY = matrix2._m22 * matrix1._offsetY + matrix2._offsetY; return; case 36: // S * U case 52: // S|T * U case 66: // U * S case 67: // U * S|T case 68: // U * U matrix1 = new Matrix( matrix1._m11 * matrix2._m11 + matrix1._m12 * matrix2._m21, matrix1._m11 * matrix2._m12 + matrix1._m12 * matrix2._m22, matrix1._m21 * matrix2._m11 + matrix1._m22 * matrix2._m21, matrix1._m21 * matrix2._m12 + matrix1._m22 * matrix2._m22, matrix1._offsetX * matrix2._m11 + matrix1._offsetY * matrix2._m21 + matrix2._offsetX, matrix1._offsetX * matrix2._m12 + matrix1._offsetY * matrix2._m22 + matrix2._offsetY); return; #if DEBUG default: Debug.Fail("Matrix multiply hit an invalid case: " + combinedType); break; #endif } } ////// Applies an offset to the specified matrix in place. /// internal static void PrependOffset( ref Matrix matrix, double offsetX, double offsetY) { if (matrix._type == MatrixTypes.TRANSFORM_IS_IDENTITY) { matrix = new Matrix(1, 0, 0, 1, offsetX, offsetY); matrix._type = MatrixTypes.TRANSFORM_IS_TRANSLATION; } else { // // / 1 0 0 \ / m11 m12 0 \ // | 0 1 0 | * | m21 m22 0 | // \ tx ty 1 / \ ox oy 1 / // // / m11 m12 0 \ // = | m21 m22 0 | // \ m11*tx+m21*ty+ox m12*tx + m22*ty + oy 1 / // matrix._offsetX += matrix._m11 * offsetX + matrix._m21 * offsetY; matrix._offsetY += matrix._m12 * offsetX + matrix._m22 * offsetY; // It just gained a translate if was a scale transform. Identity transform is handled above. Debug.Assert(matrix._type != MatrixTypes.TRANSFORM_IS_IDENTITY); if (matrix._type != MatrixTypes.TRANSFORM_IS_UNKNOWN) { matrix._type |= MatrixTypes.TRANSFORM_IS_TRANSLATION; } } } } } // 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
- ValueTypePropertyReference.cs
- ListControl.cs
- EnterpriseServicesHelper.cs
- QueryContinueDragEventArgs.cs
- BaseCollection.cs
- PrintingPermissionAttribute.cs
- UserNameServiceElement.cs
- SamlSubjectStatement.cs
- BaseServiceProvider.cs
- ColumnTypeConverter.cs
- InkCanvasSelectionAdorner.cs
- PreloadedPackages.cs
- SafePEFileHandle.cs
- ResourceReader.cs
- _ScatterGatherBuffers.cs
- BufferedGraphicsManager.cs
- WbmpConverter.cs
- ResourcesChangeInfo.cs
- LongTypeConverter.cs
- BitmapFrameEncode.cs
- XmlSchemaSet.cs
- BitmapMetadataBlob.cs
- ToolTipAutomationPeer.cs
- PartialTrustVisibleAssembly.cs
- StreamInfo.cs
- PartialList.cs
- unsafeIndexingFilterStream.cs
- ToolBarButtonClickEvent.cs
- FontSource.cs
- EventPropertyMap.cs
- DataGridViewCheckBoxColumn.cs
- InputLangChangeEvent.cs
- DragEvent.cs
- UnsafeNativeMethods.cs
- XmlLanguage.cs
- RSAPKCS1SignatureDeformatter.cs
- PasswordRecovery.cs
- TextRenderer.cs
- MbpInfo.cs
- FormViewDeletedEventArgs.cs
- AccessibleObject.cs
- PenLineJoinValidation.cs
- WindowsToolbarItemAsMenuItem.cs
- DBParameter.cs
- Number.cs
- SafeTimerHandle.cs
- SocketElement.cs
- ListBoxItem.cs
- nulltextnavigator.cs
- TemplateBuilder.cs
- CodeSubDirectoriesCollection.cs
- SqlInternalConnectionSmi.cs
- ManifestSignedXml.cs
- HelpEvent.cs
- MetadataArtifactLoader.cs
- AsymmetricAlgorithm.cs
- SoapMessage.cs
- XmlElementCollection.cs
- MethodBuilderInstantiation.cs
- AndCondition.cs
- ObjectDataSourceFilteringEventArgs.cs
- ListViewPagedDataSource.cs
- AffineTransform3D.cs
- DBNull.cs
- HotSpot.cs
- SerializableAttribute.cs
- SecurityDocument.cs
- SystemWebSectionGroup.cs
- TextAdaptor.cs
- IISMapPath.cs
- NativeObjectSecurity.cs
- SoapFault.cs
- InternalConfigEventArgs.cs
- PresentationTraceSources.cs
- SecurityPermission.cs
- Perspective.cs
- MailMessageEventArgs.cs
- _ConnectionGroup.cs
- DateTimeFormatInfoScanner.cs
- Clipboard.cs
- RowUpdatingEventArgs.cs
- SizeAnimation.cs
- DropDownList.cs
- TimeEnumHelper.cs
- QilScopedVisitor.cs
- SqlClientPermission.cs
- XLinq.cs
- BamlLocalizableResourceKey.cs
- PropertyEmitter.cs
- AppDomain.cs
- ReferencedCategoriesDocument.cs
- HMACSHA384.cs
- HtmlInputImage.cs
- ProfilePropertySettingsCollection.cs
- _CommandStream.cs
- DesignerSerializerAttribute.cs
- ServiceModelExtensionElement.cs
- AssemblyResourceLoader.cs
- RegexGroup.cs
- DropDownList.cs