~ubuntu-branches/ubuntu/oneiric/pdfmod/oneiric

« back to all changes in this revision

Viewing changes to lib/PdfSharp/PdfSharp.Drawing/XMatrix.cs

  • Committer: Bazaar Package Importer
  • Author(s): Chow Loong Jin
  • Date: 2010-09-29 17:34:49 UTC
  • mfrom: (2.1.1 experimental)
  • Revision ID: james.westby@ubuntu.com-20100929173449-4ezagrzettatjk36
Tags: 0.9.0-1
* New upstream release
* debian/copyright: Document PdfSharp.SharpZipLib/*
* Drop all patches: committed upstream
* No change bump of Standards-Version from 3.8.4 to 3.9.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
3
3
// Authors:
4
4
//   Stefan Lange (mailto:Stefan.Lange@pdfsharp.com)
5
5
//
6
 
// Copyright (c) 2005-2008 empira Software GmbH, Cologne (Germany)
 
6
// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
7
7
//
8
8
// http://www.pdfsharp.com
9
9
// http://sourceforge.net/projects/pdfsharp
42
42
#endif
43
43
using PdfSharp.Internal;
44
44
 
45
 
#pragma warning disable 1591
46
 
 
 
45
// ReSharper disable RedundantNameQualifier
47
46
namespace PdfSharp.Drawing
48
47
{
49
 
#if true
50
48
  /// <summary>
51
49
  /// Represents a 3-by-3 matrix that represents an affine 2D transformation.
52
50
  /// </summary>
96
94
    }
97
95
 
98
96
    /// <summary>
 
97
    /// Fixes a bug that XMatrixTypes.Identity is not handled correctly in some cases.
 
98
    /// </summary>
 
99
    // HACK: Fixes a bug that XMatrixTypes.Identity is not handled correctly in some cases.
 
100
    // TODO: Eliminate this function.
 
101
    void InitIdentity()
 
102
    {
 
103
      Debug.Assert(this.type == XMatrixTypes.Identity);
 
104
      this.m11 = 1;
 
105
      this.m22 = 1;
 
106
      Debug.Assert(this.m12 == 0);
 
107
      Debug.Assert(this.m21 == 0);
 
108
      Debug.Assert(this.offsetX == 0);
 
109
      Debug.Assert(this.offsetY == 0);
 
110
    }
 
111
 
 
112
    /// <summary>
99
113
    /// Gets a value indicating whether this matrix instance is the identity matrix.
100
114
    /// </summary>
101
115
    public bool IsIdentity
129
143
    {
130
144
      if (this.type == XMatrixTypes.Identity)
131
145
        return new double[] { 1, 0, 0, 1, 0, 0 };
132
 
      return new double[] { this.m11, this.m12, this.m21, this.m22, this.offsetX, this.OffsetY };
 
146
      return new double[] { this.m11, this.m12, this.m21, this.m22, this.offsetX, this.offsetY };
133
147
    }
134
148
 
135
149
    /// <summary>
137
151
    /// </summary>
138
152
    public static XMatrix operator *(XMatrix trans1, XMatrix trans2)
139
153
    {
140
 
      MatrixUtil.MultiplyMatrix(ref trans1, ref trans2);
 
154
      MatrixHelper.MultiplyMatrix(ref trans1, ref trans2);
141
155
      return trans1;
142
156
    }
143
157
 
146
160
    /// </summary>
147
161
    public static XMatrix Multiply(XMatrix trans1, XMatrix trans2)
148
162
    {
149
 
      MatrixUtil.MultiplyMatrix(ref trans1, ref trans2);
 
163
      MatrixHelper.MultiplyMatrix(ref trans1, ref trans2);
150
164
      return trans1;
151
165
    }
152
166
 
189
203
    /// </summary>
190
204
    public void Multiply(XMatrix matrix, XMatrixOrder order)
191
205
    {
 
206
      // HACK in Multiply
 
207
      if (this.type == XMatrixTypes.Identity)
 
208
        InitIdentity();
 
209
 
192
210
      // Must use properties, the fields can be invalid if the matrix is identity matrix.
193
211
      double t11 = M11;
194
212
      double t12 = M12;
249
267
    {
250
268
      if (this.type == XMatrixTypes.Identity)
251
269
      {
252
 
        this.SetMatrix(1, 0, 0, 1, offsetX, offsetY, XMatrixTypes.Translation);
 
270
        SetMatrix(1, 0, 0, 1, offsetX, offsetY, XMatrixTypes.Translation);
253
271
      }
254
272
      else if (this.type == XMatrixTypes.Unknown)
255
273
      {
277
295
    /// </summary>
278
296
    public void Translate(double offsetX, double offsetY, XMatrixOrder order)
279
297
    {
 
298
      // HACK in Translate
 
299
      if (this.type == XMatrixTypes.Identity)
 
300
        InitIdentity();
 
301
 
280
302
      if (order == XMatrixOrder.Append)
281
303
      {
282
304
        this.offsetX += offsetX;
321
343
    /// </summary>
322
344
    public void Scale(double scaleX, double scaleY, XMatrixOrder order)
323
345
    {
 
346
      // HACK in Scale
 
347
      if (this.type == XMatrixTypes.Identity)
 
348
        InitIdentity();
 
349
 
324
350
      if (order == XMatrixOrder.Append)
325
351
      {
326
352
        this.m11 *= scaleX;
374
400
      Scale(scaleXY, scaleXY, order);
375
401
    }
376
402
 
 
403
    /// <summary>
 
404
    /// Function is obsolete.
 
405
    /// </summary>
377
406
    [Obsolete("Use ScaleAtAppend or ScaleAtPrepend explicitly, because in GDI+ and WPF the defaults are contrary.", true)]
378
407
    public void ScaleAt(double scaleX, double scaleY, double centerX, double centerY)
379
408
    {
397
426
      this = CreateScaling(scaleX, scaleY, centerX, centerY) * this;
398
427
    }
399
428
 
 
429
    /// <summary>
 
430
    /// Function is obsolete.
 
431
    /// </summary>
400
432
    [Obsolete("Use RotateAppend or RotatePrepend explicitly, because in GDI+ and WPF the defaults are contrary.", true)]
401
433
    public void Rotate(double angle)
402
434
    {
428
460
    /// </summary>
429
461
    public void Rotate(double angle, XMatrixOrder order)
430
462
    {
 
463
      // HACK in Rotate
 
464
      if (this.type == XMatrixTypes.Identity)
 
465
        InitIdentity();
 
466
 
431
467
      angle = angle * Calc.Deg2Rad;
432
468
      double cos = Math.Cos(angle);
433
469
      double sin = Math.Sin(angle);
460
496
      DeriveMatrixType();
461
497
    }
462
498
 
 
499
    /// <summary>
 
500
    /// Function is obsolete.
 
501
    /// </summary>
463
502
    [Obsolete("Use RotateAtAppend or RotateAtPrepend explicitly, because in GDI+ and WPF the defaults are contrary.", true)]
464
503
    public void RotateAt(double angle, double centerX, double centerY)
465
504
    {
534
573
      DeriveMatrixType();
535
574
    }
536
575
 
 
576
    /// <summary>
 
577
    /// Function is obsolete.
 
578
    /// </summary>
537
579
    [Obsolete("Use ShearAppend or ShearPrepend explicitly, because in GDI+ and WPF the defaults are contrary.", true)]
538
580
    public void Shear(double shearX, double shearY)
539
581
    {
562
604
    /// </summary>
563
605
    public void Shear(double shearX, double shearY, XMatrixOrder order)
564
606
    {
 
607
      // HACK in Shear
 
608
      if (this.type == XMatrixTypes.Identity)
 
609
        InitIdentity();
 
610
 
565
611
      double t11 = this.m11;
566
612
      double t12 = this.m12;
567
613
      double t21 = this.m21;
587
633
      DeriveMatrixType();
588
634
    }
589
635
 
 
636
    /// <summary>
 
637
    /// Function is obsolete.
 
638
    /// </summary>
590
639
    [Obsolete("Use SkewAppend or SkewPrepend explicitly, because in GDI+ and WPF the defaults are contrary.", true)]
591
640
    public void Skew(double skewX, double skewY)
592
641
    {
622
671
    public XPoint Transform(XPoint point)
623
672
    {
624
673
      XPoint point2 = point;
625
 
      this.MultiplyPoint(ref point2.x, ref point2.y);
 
674
      MultiplyPoint(ref point2.x, ref point2.y);
626
675
      return point2;
627
676
    }
628
677
 
635
684
      {
636
685
        int count = points.Length;
637
686
        for (int idx = 0; idx < count; idx++)
638
 
          this.MultiplyPoint(ref points[idx].x, ref points[idx].y);
 
687
          MultiplyPoint(ref points[idx].x, ref points[idx].y);
639
688
      }
640
689
    }
641
690
 
647
696
      if (points == null)
648
697
        throw new ArgumentNullException("points");
649
698
 
 
699
      if (IsIdentity)
 
700
        return;
 
701
 
650
702
      int count = points.Length;
651
703
      for (int idx = 0; idx < count; idx++)
652
704
      {
709
761
    public XVector Transform(XVector vector)
710
762
    {
711
763
      XVector vector2 = vector;
712
 
      this.MultiplyVector(ref vector2.x, ref vector2.y);
 
764
      MultiplyVector(ref vector2.x, ref vector2.y);
713
765
      return vector2;
714
766
    }
715
767
 
722
774
      {
723
775
        int count = vectors.Length;
724
776
        for (int idx = 0; idx < count; idx++)
725
 
          this.MultiplyVector(ref vectors[idx].x, ref vectors[idx].y);
 
777
          MultiplyVector(ref vectors[idx].x, ref vectors[idx].y);
726
778
      }
727
779
    }
728
780
 
736
788
      if (points == null)
737
789
        throw new ArgumentNullException("points");
738
790
 
 
791
      if (IsIdentity)
 
792
        return;
 
793
 
739
794
      int count = points.Length;
740
795
      for (int idx = 0; idx < count; idx++)
741
796
      {
781
836
    /// </summary>
782
837
    public void Invert()
783
838
    {
784
 
      double determinant = this.Determinant;
 
839
      double determinant = Determinant;
785
840
      if (DoubleUtil.IsZero(determinant))
786
841
        throw new InvalidOperationException("NotInvertible"); //SR.Get(SRID.Transform_NotInvertible, new object[0]));
787
842
 
810
865
        default:
811
866
          {
812
867
            double detInvers = 1.0 / determinant;
813
 
            this.SetMatrix(this.m22 * detInvers, -this.m12 * detInvers, -this.m21 * detInvers, this.m11 * detInvers, (this.m21 * this.offsetY - this.offsetX * this.m22) * detInvers, (this.offsetX * this.m12 - this.m11 * this.offsetY) * detInvers, XMatrixTypes.Unknown);
 
868
            SetMatrix(this.m22 * detInvers, -this.m12 * detInvers, -this.m21 * detInvers, this.m11 * detInvers, (this.m21 * this.offsetY - this.offsetX * this.m22) * detInvers, (this.offsetX * this.m12 - this.m11 * this.offsetY) * detInvers, XMatrixTypes.Unknown);
814
869
            break;
815
870
          }
816
871
      }
970
1025
        (float)this.offsetX, (float)this.offsetY);
971
1026
    }
972
1027
 
 
1028
    /// <summary>
 
1029
    /// Obsolete, will be deleted.
 
1030
    /// </summary>
973
1031
    [Obsolete("Use ToGdiMatrix.")]
974
1032
    public System.Drawing.Drawing2D.Matrix ToGdipMatrix()
975
1033
    {
994
1052
    /// </summary>
995
1053
    public static explicit operator System.Drawing.Drawing2D.Matrix(XMatrix matrix)
996
1054
    {
 
1055
      if (matrix.IsIdentity)
 
1056
        return new System.Drawing.Drawing2D.Matrix();
 
1057
 
997
1058
      return new System.Drawing.Drawing2D.Matrix(
998
1059
        (float)matrix.m11, (float)matrix.m12,
999
1060
        (float)matrix.m21, (float)matrix.m22,
1007
1068
    /// </summary>
1008
1069
    public static explicit operator System.Windows.Media.Matrix(XMatrix matrix)
1009
1070
    {
 
1071
      if (matrix.IsIdentity)
 
1072
        return new System.Windows.Media.Matrix();
 
1073
 
1010
1074
      return new System.Windows.Media.Matrix(
1011
1075
        matrix.m11, matrix.m12,
1012
1076
        matrix.m21, matrix.m22,
1092
1156
    /// </summary>
1093
1157
    public override int GetHashCode()
1094
1158
    {
1095
 
      if (this.IsDistinguishedIdentity)
 
1159
      if (IsDistinguishedIdentity)
1096
1160
        return 0;
1097
 
      return this.M11.GetHashCode() ^ this.M12.GetHashCode() ^ this.M21.GetHashCode() ^ this.M22.GetHashCode() ^ this.OffsetX.GetHashCode() ^ this.OffsetY.GetHashCode();
 
1161
      return M11.GetHashCode() ^ M12.GetHashCode() ^ M21.GetHashCode() ^ M22.GetHashCode() ^ OffsetX.GetHashCode() ^ OffsetY.GetHashCode();
1098
1162
    }
1099
1163
 
1100
1164
    /// <summary>
1103
1167
    public static XMatrix Parse(string source)
1104
1168
    {
1105
1169
      XMatrix identity;
1106
 
      IFormatProvider cultureInfo = CultureInfo.GetCultureInfo("en-us");
 
1170
      IFormatProvider cultureInfo = CultureInfo.InvariantCulture; //.GetCultureInfo("en-us");
1107
1171
      TokenizerHelper helper = new TokenizerHelper(source, cultureInfo);
1108
1172
      string str = helper.NextTokenRequired();
1109
 
      if (str == "Identity")
1110
 
        identity = Identity;
1111
 
      else
1112
 
        identity = new XMatrix(Convert.ToDouble(str, cultureInfo), Convert.ToDouble(helper.NextTokenRequired(), cultureInfo), Convert.ToDouble(helper.NextTokenRequired(), cultureInfo), Convert.ToDouble(helper.NextTokenRequired(), cultureInfo), Convert.ToDouble(helper.NextTokenRequired(), cultureInfo), Convert.ToDouble(helper.NextTokenRequired(), cultureInfo));
 
1173
      identity = str == "Identity" ? Identity : 
 
1174
        new XMatrix(Convert.ToDouble(str, cultureInfo), Convert.ToDouble(helper.NextTokenRequired(), cultureInfo), Convert.ToDouble(helper.NextTokenRequired(), cultureInfo), Convert.ToDouble(helper.NextTokenRequired(), cultureInfo), Convert.ToDouble(helper.NextTokenRequired(), cultureInfo), Convert.ToDouble(helper.NextTokenRequired(), cultureInfo));
1113
1175
      helper.LastTokenRequired();
1114
1176
      return identity;
1115
1177
    }
1119
1181
    /// </summary>
1120
1182
    public override string ToString()
1121
1183
    {
1122
 
      return this.ConvertToString(null, null);
 
1184
      return ConvertToString(null, null);
1123
1185
    }
1124
1186
 
1125
1187
    /// <summary>
1127
1189
    /// </summary>
1128
1190
    public string ToString(IFormatProvider provider)
1129
1191
    {
1130
 
      return this.ConvertToString(null, provider);
 
1192
      return ConvertToString(null, provider);
1131
1193
    }
1132
1194
 
1133
1195
    /// <summary>
1135
1197
    /// </summary>
1136
1198
    string IFormattable.ToString(string format, IFormatProvider provider)
1137
1199
    {
1138
 
      return this.ConvertToString(format, provider);
 
1200
      return ConvertToString(format, provider);
1139
1201
    }
1140
1202
 
1141
1203
    internal string ConvertToString(string format, IFormatProvider provider)
1142
1204
    {
1143
 
      if (this.IsIdentity)
 
1205
      if (IsIdentity)
1144
1206
        return "Identity";
1145
1207
 
1146
1208
      char numericListSeparator = TokenizerHelper.GetNumericListSeparator(provider);
1252
1314
      return matrix;
1253
1315
    }
1254
1316
 
 
1317
    /// <summary>
 
1318
    /// Sets the matrix.
 
1319
    /// </summary>
 
1320
    // ReSharper disable ParameterHidesMember
1255
1321
    void SetMatrix(double m11, double m12, double m21, double m22, double offsetX, double offsetY, XMatrixTypes type)
 
1322
    // ReSharper restore ParameterHidesMember
1256
1323
    {
1257
1324
      this.m11 = m11;
1258
1325
      this.m12 = m12;
1303
1370
    double offsetY;
1304
1371
    XMatrixTypes type;
1305
1372
    int padding;
1306
 
    const int c_identityHashCode = 0;
1307
 
    static XMatrix s_identity;
 
1373
    static readonly XMatrix s_identity;
1308
1374
 
1309
1375
    /// <summary>
1310
1376
    /// Internal matrix helper.
1311
1377
    /// </summary>
1312
 
    internal static class MatrixUtil
 
1378
    internal static class MatrixHelper
1313
1379
    {
1314
 
      // Fast mutiplication taking matrx type into account. Reflected from WPF.
 
1380
      // Fast mutiplication taking matrix type into account. Reflectored from WPF.
1315
1381
      internal static void MultiplyMatrix(ref XMatrix matrix1, ref XMatrix matrix2)
1316
1382
      {
1317
1383
        XMatrixTypes type1 = matrix1.type;
1319
1385
        if (type2 != XMatrixTypes.Identity)
1320
1386
        {
1321
1387
          if (type1 == XMatrixTypes.Identity)
1322
 
          {
1323
1388
            matrix1 = matrix2;
1324
 
          }
1325
1389
          else if (type2 == XMatrixTypes.Translation)
1326
1390
          {
1327
1391
            matrix1.offsetX += matrix2.offsetX;
1343
1407
          }
1344
1408
          else
1345
1409
          {
1346
 
            //switch (((((int)types) << 4) | types2))
1347
1410
            switch ((((int)type1) << 4) | (int)type2)
1348
1411
            {
1349
1412
              case 0x22:
1452
1515
      }
1453
1516
    }
1454
1517
  }
1455
 
 
1456
 
#else
1457
 
  // Old code, delete end of 2008
1458
 
 
1459
 
  /// <summary>
1460
 
  /// Represents a 3-by-3 matrix that represents an affine 2D transformation.
1461
 
  /// </summary>
1462
 
  [DebuggerDisplay("({M11}, {M12}, {M21}, {M22}, {OffsetX}, {OffsetY})")]
1463
 
  public struct XMatrix
1464
 
  {
1465
 
    // TODO: In Windows 6.0 the type System.Windows.Media.Matrix is a much more
1466
 
    // sophisticated implementation of a matrix -> enhance this implementation
1467
 
 
1468
 
    // is struct now and must be initializes with Matrix.Identity
1469
 
    //    /// <summary>
1470
 
    //    /// Initializes a new instance of the Matrix class as the identity matrix.
1471
 
    //    /// </summary>
1472
 
    //    public XMatrix()
1473
 
    //    {
1474
 
    //      Reset();
1475
 
    //    }
1476
 
 
1477
 
    static XMatrix()
1478
 
    {
1479
 
      XMatrix.identity = new XMatrix(1, 0, 0, 1, 0, 0);
1480
 
    }
1481
 
 
1482
 
    ///// <summary>
1483
 
    ///// Initializes a new instance of the Matrix class with the specified matrix.
1484
 
    ///// </summary>
1485
 
    //public XMatrix(Matrix matrix)
1486
 
    //{
1487
 
    //  float[] elements = matrix.Elements;
1488
 
    //  this.m11 = elements[0];
1489
 
    //  this.m12 = elements[1];
1490
 
    //  this.m21 = elements[2];
1491
 
    //  this.m22 = elements[3];
1492
 
    //  this.mdx = elements[4];
1493
 
    //  this.mdy = elements[5];
1494
 
    //}
1495
 
 
1496
 
#if GDI
1497
 
    /// <summary>
1498
 
    /// Initializes a new instance of the Matrix class to the transform defined by the specified rectangle and 
1499
 
    /// array of points.
1500
 
    /// </summary>
1501
 
    public XMatrix(Rectangle rect, System.Drawing.Point[] plgpts)
1502
 
      : this(new XRect(rect.X, rect.Y, rect.Width, rect.Height),
1503
 
      new XPoint[3] { new XPoint(plgpts[0]), new XPoint(plgpts[1]), new XPoint(plgpts[2]) })
1504
 
    { }
1505
 
#endif
1506
 
 
1507
 
#if WPF
1508
 
    /// <summary>
1509
 
    /// Initializes a new instance of the Matrix class to the transform defined by the specified rectangle and 
1510
 
    /// array of points.
1511
 
    /// </summary>
1512
 
    public XMatrix(Rect rect, System.Windows.Point[] plgpts)
1513
 
      : this(new XRect(rect.X, rect.Y, rect.Width, rect.Height),
1514
 
      new XPoint[3] { new XPoint(plgpts[0]), new XPoint(plgpts[1]), new XPoint(plgpts[2]) })
1515
 
    { }
1516
 
#endif
1517
 
 
1518
 
#if GDI
1519
 
    /// <summary>
1520
 
    /// Initializes a new instance of the Matrix class to the transform defined by the specified rectangle and 
1521
 
    /// array of points.
1522
 
    /// </summary>
1523
 
    public XMatrix(RectangleF rect, PointF[] plgpts)
1524
 
      : this(new XRect(rect.X, rect.Y, rect.Width, rect.Height),
1525
 
      new XPoint[3] { new XPoint(plgpts[0]), new XPoint(plgpts[1]), new XPoint(plgpts[2]) })
1526
 
    {
1527
 
    }
1528
 
#endif
1529
 
 
1530
 
#if GDI
1531
 
    /// <summary>
1532
 
    /// Initializes a new instance of the <see cref="XMatrix"/> class.
1533
 
    /// </summary>
1534
 
    public XMatrix(XRect rect, XPoint[] plgpts)
1535
 
    {
1536
 
      // TODO
1537
 
#if true
1538
 
      // Lazy solution... left as an exercise :-)
1539
 
      System.Drawing.Drawing2D.Matrix matrix = new System.Drawing.Drawing2D.Matrix(
1540
 
        new RectangleF((float)rect.X, (float)rect.Y, (float)rect.Width, (float)rect.Height),
1541
 
        new PointF[3]{new PointF((float)plgpts[0].X, (float)plgpts[0].Y),
1542
 
                      new PointF((float)plgpts[1].X, (float)plgpts[1].Y), 
1543
 
                      new PointF((float)plgpts[2].X, (float)plgpts[2].Y)});
1544
 
      float[] elements = matrix.Elements;
1545
 
      this.m11 = elements[0];
1546
 
      this.m12 = elements[1];
1547
 
      this.m21 = elements[2];
1548
 
      this.m22 = elements[3];
1549
 
      this.mdx = elements[4];
1550
 
      this.mdy = elements[5];
1551
 
#else
1552
 
      // TODO work out the formulas for each value...
1553
 
      this.m11 = 0;
1554
 
      this.m12 = 0;
1555
 
      this.m21 = 0;
1556
 
      this.m22 = 0;
1557
 
      this.mdx = 0;
1558
 
      this.mdy = 0;
1559
 
      throw new NotImplementedException("TODO");
1560
 
#endif
1561
 
    }
1562
 
#endif
1563
 
 
1564
 
    /// <summary>
1565
 
    /// Initializes a new instance of the Matrix class with the specified points.
1566
 
    /// </summary>
1567
 
    public XMatrix(double m11, double m12, double m21, double m22, double offsetX, double offsetY)
1568
 
    {
1569
 
      this.m11 = m11;
1570
 
      this.m12 = m12;
1571
 
      this.m21 = m21;
1572
 
      this.m22 = m22;
1573
 
      this.mdx = offsetX;
1574
 
      this.mdy = offsetY;
1575
 
    }
1576
 
 
1577
 
    /// <summary>
1578
 
    /// Returns the hash code for this instance.
1579
 
    /// </summary>
1580
 
    public override int GetHashCode()
1581
 
    {
1582
 
      return base.GetHashCode();
1583
 
    }
1584
 
 
1585
 
    /// <summary>
1586
 
    /// Indicates whether this instance and a specified object are equal.
1587
 
    /// </summary>
1588
 
    public override bool Equals(object obj)
1589
 
    {
1590
 
      if (obj is XMatrix)
1591
 
      {
1592
 
        XMatrix matrix = (XMatrix)obj;
1593
 
        return this.m11 == matrix.m11 && this.m12 == matrix.m12 && this.m21 == matrix.m21 &&
1594
 
          this.m22 == matrix.m22 && this.mdx == matrix.mdx && this.mdy == matrix.mdy;
1595
 
      }
1596
 
      return false;
1597
 
    }
1598
 
 
1599
 
    /// <summary>
1600
 
    /// Inverts this XMatrix object. Throws an exception if the matrix is not invertible.
1601
 
    /// </summary>
1602
 
    public void Invert()
1603
 
    {
1604
 
      double det = this.m11 * this.m22 - this.m12 * this.m21;
1605
 
      if (det == 0.0)
1606
 
        throw new InvalidOperationException("Matrix is singular and cannot be inverted.");
1607
 
 
1608
 
      double i11 = this.m22 / det;
1609
 
      double i12 = -this.m12 / det;
1610
 
      double i21 = -this.m21 / det;
1611
 
      double i22 = this.m11 / det;
1612
 
      double idx = (this.m21 * this.mdy - this.m22 * this.mdx) / det;
1613
 
      double idy = (this.m12 * this.mdx - this.m11 * this.mdy) / det;
1614
 
 
1615
 
      this.m11 = i11;
1616
 
      this.m12 = i12;
1617
 
      this.m21 = i21;
1618
 
      this.m22 = i22;
1619
 
      this.mdx = idx;
1620
 
      this.mdy = idy;
1621
 
    }
1622
 
 
1623
 
    /// <summary>
1624
 
    /// Multiplies this matrix with the specified matrix.
1625
 
    /// </summary>
1626
 
    [Obsolete("Use MultiplyAppend or MultiplyPrepend explicitly, because in GDI+ and WPF the defaults are contrary.", true)]
1627
 
    public void Multiply(XMatrix matrix)
1628
 
    {
1629
 
      throw new InvalidOperationException("Temporarily out of order.");
1630
 
    }
1631
 
 
1632
 
    /// <summary>
1633
 
    /// Multiplies this matrix with the specified matrix.
1634
 
    /// </summary>
1635
 
    public void MultiplyAppend(XMatrix matrix)
1636
 
    {
1637
 
      Multiply(matrix, XMatrixOrder.Append);
1638
 
    }
1639
 
 
1640
 
    /// <summary>
1641
 
    /// Multiplies this matrix with the specified matrix.
1642
 
    /// </summary>
1643
 
    public void MultiplyPrepend(XMatrix matrix)
1644
 
    {
1645
 
      Multiply(matrix, XMatrixOrder.Prepend);
1646
 
    }
1647
 
 
1648
 
    /// <summary>
1649
 
    /// Multiplies this matrix with the specified matrix.
1650
 
    /// </summary>
1651
 
    public void Multiply(XMatrix matrix, XMatrixOrder order)
1652
 
    {
1653
 
      double t11 = this.m11;
1654
 
      double t12 = this.m12;
1655
 
      double t21 = this.m21;
1656
 
      double t22 = this.m22;
1657
 
      double tdx = this.mdx;
1658
 
      double tdy = this.mdy;
1659
 
 
1660
 
      if (order == XMatrixOrder.Append)
1661
 
      {
1662
 
        this.m11 = t11 * matrix.m11 + t12 * matrix.m21;
1663
 
        this.m12 = t11 * matrix.m12 + t12 * matrix.m22;
1664
 
        this.m21 = t21 * matrix.m11 + t22 * matrix.m21;
1665
 
        this.m22 = t21 * matrix.m12 + t22 * matrix.m22;
1666
 
        this.mdx = tdx * matrix.m11 + tdy * matrix.m21 + matrix.mdx;
1667
 
        this.mdy = tdx * matrix.m12 + tdy * matrix.m22 + matrix.mdy;
1668
 
      }
1669
 
      else
1670
 
      {
1671
 
        this.m11 = t11 * matrix.m11 + t21 * matrix.m12;
1672
 
        this.m12 = t12 * matrix.m11 + t22 * matrix.m12;
1673
 
        this.m21 = t11 * matrix.m21 + t21 * matrix.m22;
1674
 
        this.m22 = t12 * matrix.m21 + t22 * matrix.m22;
1675
 
        this.mdx = t11 * matrix.mdx + t21 * matrix.mdy + tdx;
1676
 
        this.mdy = t12 * matrix.mdx + t22 * matrix.mdy + tdy;
1677
 
      }
1678
 
    }
1679
 
 
1680
 
    /// <summary>
1681
 
    /// Translates the matrix with the specified offsets.
1682
 
    /// </summary>
1683
 
    [Obsolete("Use TranslateAppend or TranslatePrepend explicitly, because in GDI+ and WPF the defaults are contrary.", true)]
1684
 
    public void Translate(double offsetX, double offsetY)
1685
 
    {
1686
 
      throw new InvalidOperationException("Temporarily out of order.");
1687
 
    }
1688
 
 
1689
 
    /// <summary>
1690
 
    /// Translates the matrix with the specified offsets.
1691
 
    /// </summary>
1692
 
    public void TranslateAppend(double offsetX, double offsetY)
1693
 
    {
1694
 
      Translate(offsetX, offsetY, XMatrixOrder.Append);
1695
 
    }
1696
 
 
1697
 
    /// <summary>
1698
 
    /// Translates the matrix with the specified offsets.
1699
 
    /// </summary>
1700
 
    public void TranslatePrepend(double offsetX, double offsetY)
1701
 
    {
1702
 
      Translate(offsetX, offsetY, XMatrixOrder.Prepend);
1703
 
    }
1704
 
 
1705
 
    /// <summary>
1706
 
    /// Translates the matrix with the specified offsets.
1707
 
    /// </summary>
1708
 
    public void Translate(double offsetX, double offsetY, XMatrixOrder order)
1709
 
    {
1710
 
      if (order == XMatrixOrder.Append)
1711
 
      {
1712
 
        this.mdx += offsetX;
1713
 
        this.mdy += offsetY;
1714
 
      }
1715
 
      else
1716
 
      {
1717
 
        this.mdx += offsetX * this.m11 + offsetY * this.m21;
1718
 
        this.mdy += offsetX * this.m12 + offsetY * this.m22;
1719
 
      }
1720
 
    }
1721
 
 
1722
 
    /// <summary>
1723
 
    /// Scales the matrix with the specified scalars.
1724
 
    /// </summary>
1725
 
    [Obsolete("Use ScaleAppend or ScalePrepend explicitly, because in GDI+ and WPF the defaults are contrary.", true)]
1726
 
    public void Scale(double scaleX, double scaleY)
1727
 
    {
1728
 
      throw new InvalidOperationException("Temporarily out of order.");
1729
 
    }
1730
 
 
1731
 
    /// <summary>
1732
 
    /// Scales the matrix with the specified scalars.
1733
 
    /// </summary>
1734
 
    public void ScaleAppend(double scaleX, double scaleY)
1735
 
    {
1736
 
      Scale(scaleX, scaleY, XMatrixOrder.Append);
1737
 
    }
1738
 
 
1739
 
    /// <summary>
1740
 
    /// Scales the matrix with the specified scalars.
1741
 
    /// </summary>
1742
 
    public void ScalePrepend(double scaleX, double scaleY)
1743
 
    {
1744
 
      Scale(scaleX, scaleY, XMatrixOrder.Prepend);
1745
 
    }
1746
 
 
1747
 
    /// <summary>
1748
 
    /// Scales the matrix with the specified scalars.
1749
 
    /// </summary>
1750
 
    public void Scale(double scaleX, double scaleY, XMatrixOrder order)
1751
 
    {
1752
 
      if (order == XMatrixOrder.Append)
1753
 
      {
1754
 
        this.m11 *= scaleX;
1755
 
        this.m12 *= scaleY;
1756
 
        this.m21 *= scaleX;
1757
 
        this.m22 *= scaleY;
1758
 
        this.mdx *= scaleX;
1759
 
        this.mdy *= scaleY;
1760
 
      }
1761
 
      else
1762
 
      {
1763
 
        this.m11 *= scaleX;
1764
 
        this.m12 *= scaleX;
1765
 
        this.m21 *= scaleY;
1766
 
        this.m22 *= scaleY;
1767
 
      }
1768
 
    }
1769
 
 
1770
 
    /// <summary>
1771
 
    /// Scales the matrix with the specified scalar.
1772
 
    /// </summary>
1773
 
    [Obsolete("Use ScaleAppend or ScalePrepend explicitly, because in GDI+ and WPF the defaults are contrary.", true)]
1774
 
    public void Scale(double scaleXY)
1775
 
    {
1776
 
      throw new InvalidOperationException("Temporarily out of order.");
1777
 
    }
1778
 
 
1779
 
    /// <summary>
1780
 
    /// Scales the matrix with the specified scalar.
1781
 
    /// </summary>
1782
 
    public void ScaleAppend(double scaleXY)
1783
 
    {
1784
 
      Scale(scaleXY, scaleXY, XMatrixOrder.Append);
1785
 
    }
1786
 
 
1787
 
    /// <summary>
1788
 
    /// Scales the matrix with the specified scalar.
1789
 
    /// </summary>
1790
 
    public void ScalePrepend(double scaleXY)
1791
 
    {
1792
 
      Scale(scaleXY, scaleXY, XMatrixOrder.Prepend);
1793
 
    }
1794
 
 
1795
 
    /// <summary>
1796
 
    /// Scales the matrix with the specified scalar.
1797
 
    /// </summary>
1798
 
    public void Scale(double scaleXY, XMatrixOrder order)
1799
 
    {
1800
 
      Scale(scaleXY, scaleXY, order);
1801
 
    }
1802
 
 
1803
 
    /// <summary>
1804
 
    /// Rotates the matrix with the specified angle.
1805
 
    /// </summary>
1806
 
    [Obsolete("Use RotateAppend or RotatePrepend explicitly, because in GDI+ and WPF the defaults are contrary.", true)]
1807
 
    public void Rotate(double angle)
1808
 
    {
1809
 
      throw new InvalidOperationException("Temporarily out of order.");
1810
 
    }
1811
 
 
1812
 
    /// <summary>
1813
 
    /// Rotates the matrix with the specified angle.
1814
 
    /// </summary>
1815
 
    public void RotateAppend(double angle)
1816
 
    {
1817
 
      Rotate(angle, XMatrixOrder.Append);
1818
 
    }
1819
 
 
1820
 
    /// <summary>
1821
 
    /// Rotates the matrix with the specified angle.
1822
 
    /// </summary>
1823
 
    public void RotatePrepend(double angle)
1824
 
    {
1825
 
      Rotate(angle, XMatrixOrder.Prepend);
1826
 
    }
1827
 
 
1828
 
    /// <summary>
1829
 
    /// Rotates the matrix with the specified angle.
1830
 
    /// </summary>
1831
 
    public void Rotate(double angle, XMatrixOrder order)
1832
 
    {
1833
 
      angle = angle * Calc.Deg2Rad;
1834
 
      double cos = Math.Cos(angle);
1835
 
      double sin = Math.Sin(angle);
1836
 
      if (order == XMatrixOrder.Append)
1837
 
      {
1838
 
        double t11 = this.m11;
1839
 
        double t12 = this.m12;
1840
 
        double t21 = this.m21;
1841
 
        double t22 = this.m22;
1842
 
        double tdx = this.mdx;
1843
 
        double tdy = this.mdy;
1844
 
        this.m11 = t11 * cos - t12 * sin;
1845
 
        this.m12 = t11 * sin + t12 * cos;
1846
 
        this.m21 = t21 * cos - t22 * sin;
1847
 
        this.m22 = t21 * sin + t22 * cos;
1848
 
        this.mdx = tdx * cos - tdy * sin;
1849
 
        this.mdy = tdx * sin + tdy * cos;
1850
 
      }
1851
 
      else
1852
 
      {
1853
 
        double t11 = this.m11;
1854
 
        double t12 = this.m12;
1855
 
        double t21 = this.m21;
1856
 
        double t22 = this.m22;
1857
 
        this.m11 = t11 * cos + t21 * sin;
1858
 
        this.m12 = t12 * cos + t22 * sin;
1859
 
        this.m21 = -t11 * sin + t21 * cos;
1860
 
        this.m22 = -t12 * sin + t22 * cos;
1861
 
      }
1862
 
    }
1863
 
 
1864
 
    /// <summary>
1865
 
    /// Rotates the matrix with the specified angle at the specified point.
1866
 
    /// </summary>
1867
 
    [Obsolete("Use RotateAtAppend or RotateAtPrepend explicitly, because in GDI+ and WPF the defaults are contrary.", true)]
1868
 
    public void RotateAt(double angle, XPoint point)
1869
 
    {
1870
 
      throw new InvalidOperationException("Temporarily out of order.");
1871
 
    }
1872
 
 
1873
 
    /// <summary>
1874
 
    /// Rotates the matrix with the specified angle at the specified point.
1875
 
    /// </summary>
1876
 
    public void RotateAtAppend(double angle, XPoint point)
1877
 
    {
1878
 
      RotateAt(angle, point, XMatrixOrder.Append);
1879
 
    }
1880
 
 
1881
 
    /// <summary>
1882
 
    /// Rotates the matrix with the specified angle at the specified point.
1883
 
    /// </summary>
1884
 
    public void RotateAtPrepend(double angle, XPoint point)
1885
 
    {
1886
 
      RotateAt(angle, point, XMatrixOrder.Prepend);
1887
 
    }
1888
 
 
1889
 
    /// <summary>
1890
 
    /// Rotates the matrix with the specified angle at the specified point.
1891
 
    /// </summary>
1892
 
    public void RotateAt(double angle, XPoint point, XMatrixOrder order)
1893
 
    {
1894
 
      // TODO: check code
1895
 
      if (order == XMatrixOrder.Prepend)
1896
 
      {
1897
 
        this.Translate(point.X, point.Y, order);
1898
 
        this.Rotate(angle, order);
1899
 
        this.Translate(-point.X, -point.Y, order);
1900
 
      }
1901
 
      else
1902
 
      {
1903
 
        throw new NotImplementedException("RotateAt with XMatrixOrder.Append");
1904
 
      }
1905
 
    }
1906
 
 
1907
 
    /// <summary>
1908
 
    /// Shears the matrix with the specified scalars.
1909
 
    /// </summary>
1910
 
    [Obsolete("Use ShearAppend or ShearPrepend explicitly, because in GDI+ and WPF the defaults are contrary.", true)]
1911
 
    public void Shear(double shearX, double shearY)
1912
 
    {
1913
 
      throw new InvalidOperationException("Temporarily out of order.");
1914
 
    }
1915
 
 
1916
 
    /// <summary>
1917
 
    /// Shears the matrix with the specified scalars.
1918
 
    /// </summary>
1919
 
    public void ShearAppend(double shearX, double shearY)
1920
 
    {
1921
 
      Shear(shearX, shearY, XMatrixOrder.Append);
1922
 
    }
1923
 
 
1924
 
    /// <summary>
1925
 
    /// Shears the matrix with the specified scalars.
1926
 
    /// </summary>
1927
 
    public void ShearPrepend(double shearX, double shearY)
1928
 
    {
1929
 
      Shear(shearX, shearY, XMatrixOrder.Prepend);
1930
 
    }
1931
 
 
1932
 
    /// <summary>
1933
 
    /// Shears the matrix with the specified scalars.
1934
 
    /// </summary>
1935
 
    public void Shear(double shearX, double shearY, XMatrixOrder order)
1936
 
    {
1937
 
      double t11 = this.m11;
1938
 
      double t12 = this.m12;
1939
 
      double t21 = this.m21;
1940
 
      double t22 = this.m22;
1941
 
      double tdx = this.mdx;
1942
 
      double tdy = this.mdy;
1943
 
      if (order == XMatrixOrder.Append)
1944
 
      {
1945
 
        this.m11 += shearX * t12;
1946
 
        this.m12 += shearY * t11;
1947
 
        this.m21 += shearX * t22;
1948
 
        this.m22 += shearY * t21;
1949
 
        this.mdx += shearX * tdy;
1950
 
        this.mdy += shearY * tdx;
1951
 
      }
1952
 
      else
1953
 
      {
1954
 
        this.m11 += shearY * t21;
1955
 
        this.m12 += shearY * t22;
1956
 
        this.m21 += shearX * t11;
1957
 
        this.m22 += shearX * t12;
1958
 
      }
1959
 
    }
1960
 
 
1961
 
#if GDI
1962
 
    /// <summary>
1963
 
    /// Multiplies all points of the specified array with the this matrix.
1964
 
    /// </summary>
1965
 
    public void TransformPoints(System.Drawing.Point[] points)
1966
 
    {
1967
 
      if (points == null)
1968
 
        throw new ArgumentNullException("points");
1969
 
 
1970
 
      if (IsIdentity)
1971
 
        return;
1972
 
 
1973
 
      int count = points.Length;
1974
 
      for (int idx = 0; idx < count; idx++)
1975
 
      {
1976
 
        double x = points[idx].X;
1977
 
        double y = points[idx].Y;
1978
 
        points[idx].X = (int)(x * this.m11 + y * this.m21 + this.mdx);
1979
 
        points[idx].Y = (int)(x * this.m12 + y * this.m22 + this.mdy);
1980
 
      }
1981
 
    }
1982
 
#endif
1983
 
 
1984
 
#if WPF
1985
 
    /// <summary>
1986
 
    /// Multiplies all points of the specified array with the this matrix.
1987
 
    /// </summary>
1988
 
    public void TransformPoints(System.Windows.Point[] points)
1989
 
    {
1990
 
      if (points == null)
1991
 
        throw new ArgumentNullException("points");
1992
 
 
1993
 
      if (IsIdentity)
1994
 
        return;
1995
 
 
1996
 
      int count = points.Length;
1997
 
      for (int idx = 0; idx < count; idx++)
1998
 
      {
1999
 
        double x = points[idx].X;
2000
 
        double y = points[idx].Y;
2001
 
        points[idx].X = (int)(x * this.m11 + y * this.m21 + this.mdx);
2002
 
        points[idx].Y = (int)(x * this.m12 + y * this.m22 + this.mdy);
2003
 
      }
2004
 
    }
2005
 
#endif
2006
 
 
2007
 
    /// <summary>
2008
 
    /// Multiplies all points of the specified array with the this matrix.
2009
 
    /// </summary>
2010
 
    public void TransformPoints(XPoint[] points)
2011
 
    {
2012
 
      if (points == null)
2013
 
        throw new ArgumentNullException("points");
2014
 
 
2015
 
      int count = points.Length;
2016
 
      for (int idx = 0; idx < count; idx++)
2017
 
      {
2018
 
        double x = points[idx].X;
2019
 
        double y = points[idx].Y;
2020
 
        points[idx].X = x * this.m11 + y * this.m21 + this.mdx;
2021
 
        points[idx].Y = x * this.m12 + y * this.m22 + this.mdy;
2022
 
      }
2023
 
    }
2024
 
 
2025
 
    /// <summary>
2026
 
    /// Multiplies all vectors of the specified array with the this matrix. The translation elements 
2027
 
    /// of this matrix (third row) are ignored.
2028
 
    /// </summary>
2029
 
    public void TransformVectors(XPoint[] points)
2030
 
    {
2031
 
      if (points == null)
2032
 
        throw new ArgumentNullException("points");
2033
 
 
2034
 
      int count = points.Length;
2035
 
      for (int idx = 0; idx < count; idx++)
2036
 
      {
2037
 
        double x = points[idx].X;
2038
 
        double y = points[idx].Y;
2039
 
        points[idx].X = x * this.m11 + y * this.m21;
2040
 
        points[idx].Y = x * this.m12 + y * this.m22;
2041
 
      }
2042
 
    }
2043
 
 
2044
 
    public XVector Transform(XVector vector)
2045
 
    {
2046
 
      return new XVector();
2047
 
    }
2048
 
 
2049
 
#if GDI
2050
 
    /// <summary>
2051
 
    /// Multiplies all vectors of the specified array with the this matrix. The translation elements 
2052
 
    /// of this matrix (third row) are ignored.
2053
 
    /// </summary>
2054
 
    public void TransformVectors(PointF[] points)
2055
 
    {
2056
 
      if (points == null)
2057
 
        throw new ArgumentNullException("points");
2058
 
 
2059
 
      int count = points.Length;
2060
 
      for (int idx = 0; idx < count; idx++)
2061
 
      {
2062
 
        double x = points[idx].X;
2063
 
        double y = points[idx].Y;
2064
 
        points[idx].X = (float)(x * this.m11 + y * this.m21 + this.mdx);
2065
 
        points[idx].Y = (float)(x * this.m12 + y * this.m22 + this.mdy);
2066
 
      }
2067
 
    }
2068
 
#endif
2069
 
 
2070
 
    /// <summary>
2071
 
    /// Gets an array of double values that represents the elements of this matrix.
2072
 
    /// </summary>
2073
 
    public double[] Elements
2074
 
    {
2075
 
      get
2076
 
      {
2077
 
        double[] elements = new double[6];
2078
 
        elements[0] = this.m11;
2079
 
        elements[1] = this.m12;
2080
 
        elements[2] = this.m21;
2081
 
        elements[3] = this.m22;
2082
 
        elements[4] = this.mdx;
2083
 
        elements[5] = this.mdy;
2084
 
        return elements;
2085
 
      }
2086
 
    }
2087
 
 
2088
 
    /// <summary>
2089
 
    /// Gets a value from the matrix.
2090
 
    /// </summary>
2091
 
    public double M11
2092
 
    {
2093
 
      get { return this.m11; }
2094
 
      set { this.m11 = value; }
2095
 
    }
2096
 
 
2097
 
    /// <summary>
2098
 
    /// Gets a value from the matrix.
2099
 
    /// </summary>
2100
 
    public double M12
2101
 
    {
2102
 
      get { return this.m12; }
2103
 
      set { this.m12 = value; }
2104
 
    }
2105
 
 
2106
 
    /// <summary>
2107
 
    /// Gets a value from the matrix.
2108
 
    /// </summary>
2109
 
    public double M21
2110
 
    {
2111
 
      get { return this.m21; }
2112
 
      set { this.m21 = value; }
2113
 
    }
2114
 
 
2115
 
    /// <summary>
2116
 
    /// Gets a value from the matrix.
2117
 
    /// </summary>
2118
 
    public double M22
2119
 
    {
2120
 
      get { return this.m22; }
2121
 
      set { this.m22 = value; }
2122
 
    }
2123
 
 
2124
 
    /// <summary>
2125
 
    /// Gets the x translation value.
2126
 
    /// </summary>
2127
 
    public double OffsetX
2128
 
    {
2129
 
      get { return this.mdx; }
2130
 
      set { this.mdx = value; }
2131
 
    }
2132
 
 
2133
 
    /// <summary>
2134
 
    /// Gets the y translation value.
2135
 
    /// </summary>
2136
 
    public double OffsetY
2137
 
    {
2138
 
      get { return this.mdy; }
2139
 
      set { this.mdy = value; }
2140
 
    }
2141
 
 
2142
 
#if GDI
2143
 
    /// <summary>
2144
 
    /// Converts this matrix to a System.Drawing.Drawing2D.Matrix object.
2145
 
    /// </summary>
2146
 
    public System.Drawing.Drawing2D.Matrix ToGdiMatrix()
2147
 
    {
2148
 
      return new System.Drawing.Drawing2D.Matrix((float)this.m11, (float)this.m12, (float)this.m21, (float)this.m22,
2149
 
        (float)this.mdx, (float)this.mdy);
2150
 
    }
2151
 
#endif
2152
 
 
2153
 
#if WPF
2154
 
    /// <summary>
2155
 
    /// Converts this matrix to a System.Drawing.Drawing2D.Matrix object.
2156
 
    /// </summary>
2157
 
    public System.Windows.Media.Matrix ToWpfMatrix()
2158
 
    {
2159
 
      return new System.Windows.Media.Matrix(this.m11, this.m12, this.m21, this.m22, this.mdx, this.mdy);
2160
 
    }
2161
 
#endif
2162
 
 
2163
 
    /// <summary>
2164
 
    /// Indicates whether this matrix is the identity matrix.
2165
 
    /// </summary>
2166
 
    public bool IsIdentity
2167
 
    {
2168
 
      get { return this.m11 == 1 && this.m12 == 0 && this.m21 == 0 && this.m22 == 1 && this.mdx == 0 && this.mdy == 0; }
2169
 
    }
2170
 
 
2171
 
    /// <summary>
2172
 
    /// Indicates whether this matrix is invertible, i. e. its determinant is not zero.
2173
 
    /// </summary>
2174
 
    public bool IsInvertible
2175
 
    {
2176
 
      get { return this.m11 * this.m22 - this.m12 * this.m21 != 0; }
2177
 
    }
2178
 
 
2179
 
#if GDI
2180
 
    /// <summary>
2181
 
    /// Explicitly converts a XMatrix to a Matrix.
2182
 
    /// </summary>
2183
 
    public static explicit operator System.Drawing.Drawing2D.Matrix(XMatrix matrix)
2184
 
    {
2185
 
      return new System.Drawing.Drawing2D.Matrix(
2186
 
        (float)matrix.m11, (float)matrix.m12,
2187
 
        (float)matrix.m21, (float)matrix.m22,
2188
 
        (float)matrix.mdx, (float)matrix.mdy);
2189
 
    }
2190
 
#endif
2191
 
 
2192
 
#if WPF
2193
 
    /// <summary>
2194
 
    /// Explicitly converts a XMatrix to a Matrix.
2195
 
    /// </summary>
2196
 
    public static explicit operator System.Windows.Media.Matrix(XMatrix matrix)
2197
 
    {
2198
 
      return new System.Windows.Media.Matrix(
2199
 
        matrix.m11, matrix.m12,
2200
 
        matrix.m21, matrix.m22,
2201
 
        matrix.mdx, matrix.mdy);
2202
 
    }
2203
 
#endif
2204
 
 
2205
 
#if GDI
2206
 
    /// <summary>
2207
 
    /// Implicitly converts a Matrix to an XMatrix.
2208
 
    /// </summary>
2209
 
    public static implicit operator XMatrix(System.Drawing.Drawing2D.Matrix matrix)
2210
 
    {
2211
 
      float[] elements = matrix.Elements;
2212
 
      return new XMatrix(elements[0], elements[1], elements[2], elements[3], elements[4], elements[5]);
2213
 
    }
2214
 
#endif
2215
 
 
2216
 
#if WPF
2217
 
    /// <summary>
2218
 
    /// Implicitly converts a Matrix to an XMatrix.
2219
 
    /// </summary>
2220
 
    public static implicit operator XMatrix(System.Windows.Media.Matrix matrix)
2221
 
    {
2222
 
      return new XMatrix(matrix.M11, matrix.M12, matrix.M21, matrix.M22, matrix.OffsetX, matrix.OffsetY);
2223
 
    }
2224
 
#endif
2225
 
 
2226
 
    /// <summary>
2227
 
    /// Gets an identity matrix.
2228
 
    /// </summary>
2229
 
    public static XMatrix Identity
2230
 
    {
2231
 
      get { return XMatrix.identity; }
2232
 
    }
2233
 
 
2234
 
    /// <summary>
2235
 
    /// Determines whether to matrices are equal.
2236
 
    /// </summary>
2237
 
    public static bool operator ==(XMatrix matrix1, XMatrix matrix2)
2238
 
    {
2239
 
      return
2240
 
        matrix1.m11 == matrix2.m11 &&
2241
 
        matrix1.m12 == matrix2.m12 &&
2242
 
        matrix1.m21 == matrix2.m21 &&
2243
 
        matrix1.m22 == matrix2.m22 &&
2244
 
        matrix1.mdx == matrix2.mdx &&
2245
 
        matrix1.mdy == matrix2.mdy;
2246
 
    }
2247
 
 
2248
 
    /// <summary>
2249
 
    /// Determines whether to matrices are not equal.
2250
 
    /// </summary>
2251
 
    public static bool operator !=(XMatrix matrix1, XMatrix matrix2)
2252
 
    {
2253
 
      return !(matrix1 == matrix2);
2254
 
    }
2255
 
 
2256
 
    //private static Matrix CreateIdentity()
2257
 
    //{
2258
 
    //  Matrix matrix = new Matrix();
2259
 
    //  matrix.SetMatrix(1.0, 0.0, 0.0, 1.0, 0.0, 0.0, MatrixTypes.TRANSFORM_IS_IDENTITY);
2260
 
    //  return matrix;
2261
 
    //}
2262
 
 
2263
 
 
2264
 
    double m11, m12, m21, m22, mdx, mdy;
2265
 
 
2266
 
    private static XMatrix identity;
2267
 
 
2268
 
#if DEBUG_
2269
 
    /// <summary>
2270
 
    /// Some test code to check that there are no typing errors in the formulars.
2271
 
    /// </summary>
2272
 
    public static void Test()
2273
 
    {
2274
 
      XMatrix xm1 = new XMatrix(23, -35, 837, 332, -3, 12);
2275
 
      Matrix  m1 = new Matrix(23, -35, 837, 332, -3, 12);
2276
 
      DumpMatrix(xm1, m1);
2277
 
      XMatrix xm2 = new XMatrix(12, 235, 245, 42, 33, -56);
2278
 
      Matrix  m2 = xm2.ToMatrix();
2279
 
      DumpMatrix(xm2, m2);
2280
 
 
2281
 
//      xm1.Multiply(xm2, XMatrixOrder.Prepend);
2282
 
//      m1.Multiply(m2, MatrixOrder.Append);
2283
 
      xm1.Multiply(xm2, XMatrixOrder.Append);
2284
 
      m1.Multiply(m2, MatrixOrder.Append);
2285
 
      DumpMatrix(xm1, m1);
2286
 
 
2287
 
      xm1.Translate(-243, 342, XMatrixOrder.Append);
2288
 
      m1.Translate(-243, 342, MatrixOrder.Append);
2289
 
      DumpMatrix(xm1, m1);
2290
 
 
2291
 
      xm1.Scale(-5.66, 7.87);
2292
 
      m1.Scale(-5.66f, 7.87f);
2293
 
//      xm1.Scale(-5.66, 7.87, XMatrixOrder.Prepend);
2294
 
//      m1.Scale(-5.66f, 7.87f, MatrixOrder.Prepend);
2295
 
      DumpMatrix(xm1, m1);
2296
 
 
2297
 
 
2298
 
      xm1.Rotate(135, XMatrixOrder.Append);
2299
 
      m1.Rotate(135, MatrixOrder.Append);
2300
 
      //      xm1.Scale(-5.66, 7.87, XMatrixOrder.Prepend);
2301
 
      //      m1.Scale(-5.66f, 7.87f, MatrixOrder.Prepend);
2302
 
      DumpMatrix(xm1, m1);
2303
 
 
2304
 
      xm1.RotateAt(177, new XPoint(-3456, 654), XMatrixOrder.Append);
2305
 
      m1.RotateAt(177, new PointF(-3456, 654), MatrixOrder.Append);
2306
 
      DumpMatrix(xm1, m1);
2307
 
 
2308
 
      xm1.Shear(0.76, -0.87, XMatrixOrder.Prepend);
2309
 
      m1.Shear(0.76f, -0.87f, MatrixOrder.Prepend);
2310
 
      DumpMatrix(xm1, m1);
2311
 
 
2312
 
      xm1 = new XMatrix(23, -35, 837, 332, -3, 12);
2313
 
      m1 = new Matrix(23, -35, 837, 332, -3, 12);
2314
 
 
2315
 
      XPoint[] xpoints = new XPoint[3]{new XPoint(23, 10), new XPoint(-27, 120), new XPoint(-87, -55)};
2316
 
      PointF[] points = new PointF[3]{new PointF(23, 10), new PointF(-27, 120), new PointF(-87, -55)};
2317
 
 
2318
 
      xm1.TransformPoints(xpoints);
2319
 
      m1.TransformPoints(points);
2320
 
 
2321
 
      xm1.Invert();
2322
 
      m1.Invert();
2323
 
      DumpMatrix(xm1, m1);
2324
 
 
2325
 
    }
2326
 
 
2327
 
    static void DumpMatrix(XMatrix xm, Matrix m)
2328
 
    {
2329
 
      double[] xmv = xm.Elements;
2330
 
      float[] mv = m.Elements;
2331
 
      string message = String.Format("{0:0.###} {1:0.###} {2:0.###} {3:0.###} {4:0.###} {5:0.###}",
2332
 
        xmv[0], xmv[1], xmv[2], xmv[3], xmv[4], xmv[5]);
2333
 
      Console.WriteLine(message);
2334
 
      message = String.Format("{0:0.###} {1:0.###} {2:0.###} {3:0.###} {4:0.###} {5:0.###}",
2335
 
        mv[0], mv[1], mv[2], mv[3], mv[4], mv[5]);
2336
 
      Console.WriteLine(message);
2337
 
      Console.WriteLine();
2338
 
    }
2339
 
#endif
2340
 
  }
2341
 
#endif
2342
 
}
 
 
b'\\ No newline at end of file'
 
1518
}