InDesign SDK  20.5
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
PMMatrix.h
1 //========================================================================================
2 //
3 // $File$
4 //
5 // Owner: Jeff Argast
6 //
7 // $Author$
8 //
9 // $DateTime$
10 //
11 // $Revision$
12 //
13 // $Change$
14 //
15 // Copyright 1997-2010 Adobe Systems Incorporated. All rights reserved.
16 //
17 // NOTICE: Adobe permits you to use, modify, and distribute this file in accordance
18 // with the terms of the Adobe license agreement accompanying it. If you have received
19 // this file from a source other than Adobe, then your use, modification, or
20 // distribution of it requires the prior written permission of Adobe.
21 //
22 //
23 // PMMatrix encapsulates the matrix math used in PM. It hides both the data type and
24 // the corresponding AGM matrix. It is possible to emulate the matrix math that occurs
25 // in AGM using the PMMatrix AGM methods.
26 //
27 //========================================================================================
28 
29 #ifndef __PMMatrix__
30 #define __PMMatrix__
31  #include "K2Vector.h"
32  #include "PMPoint.h"
33 
34 //----------------------------------------------------------------------------------------
35 // Forward declarations
36 //----------------------------------------------------------------------------------------
37 
38 class PMMatrix;
39 class PMRect;
40 class PMLineSeg;
41 class PMPolygon4;
42 
43  struct _t_BRVFixedMatrix;
44  struct BRVCoordMatrix;
45 
46 namespace dvacore {
47  namespace geom {
48  template <class T> class ScaleMatrixT;
49  }
50 }
51 
52 
53 //----------------------------------------------------------------------------------------
54 // Typedefs
55 //----------------------------------------------------------------------------------------
57 
58 
61  class PMMatrix
62  {
63  public:
64  typedef base_type data_type;
65 
69  void ReadWrite(IPMStream *s);
70 
71 
72 //-------------------------------------------------------------------------------------
78  constexpr PMMatrix() noexcept
79  : fa(1.0), fb(0.0), fc(0.0), fd(1.0), fe(0.0), ff(0.0)
80  {
81  }
82 
88  constexpr PMMatrix( PMReal a, PMReal b, PMReal c, PMReal d, PMReal e, PMReal f) noexcept
89  : fa(a), fb(b), fc(c), fd(d), fe(e), ff(f)
90  {
91  }
92 
95  constexpr PMMatrix(const PMMatrix &m) noexcept = default;
96  constexpr PMMatrix(PMMatrix &&m) noexcept = default;
97 
101  PMMatrix(const BRVCoordMatrix &m);
102 
105  PMMatrix& operator=(const PMMatrix &m) noexcept = default;
106  PMMatrix& operator=(PMMatrix &&m) noexcept = default;
107 
108 
112  void SetMatrix (const BRVCoordMatrix &m);
113 
117  void SetMatrix (const _t_BRVFixedMatrix &m);
118 
122  void SetMatrix (const dvacore::geom::ScaleMatrixT<float> &m);
123 
127  void GetAGMFixedMatrix (_t_BRVFixedMatrix* retMatrix) const;
128 
132  void GetAGMFloatMatrix (BRVCoordMatrix* retMatrix) const;
133 
137  void GetUIMatrixF32 (dvacore::geom::ScaleMatrixT<float>* retMatrix) const;
138 
139 
143  bool16 operator==(const PMMatrix& other) const;
144 
145  bool16 operator!=(const PMMatrix& other) const
146  {
147  return !(*this == other);
148  }
149 
152  bool16 operator<(const PMMatrix& other) const;
153 
154 //-------------------------------------------------------------------------------------
155 
159  void Transform(PMReal* x, PMReal* y) const;
160 
161  void Transform(PMPoint* p) const
162  {
163  Transform(&p->X(), &p->Y());
164  }
165 
166 
171  void Transform( PMPolygon4* fourPoints) const;
172 
173 
177  void Transform(PMRect* rect) const;
178 
179 
185  void Transform(PMLineSeg* segment) const;
186 
187 
188 //-------------------------------------------------------------------------------------
189 
190 
226  const PMReal operator[](int index) const;
227 
228 
229 //-------------------------------------------------------------------------------------
230 
231 
234  bool16 IsIdentity() const noexcept;
235  bool exactly_identity() const noexcept; //Similar to IsIdentity, except exact comparison of double values is done and check is ordered based on
236  //which elements are most likely to reveal non-identity. For all purposes, just use IsIdentity. Leaving this
237  //function in place for historical reasons.
238 
241  void ResetToIdentity() noexcept;
242 
243 
247  PMReal Determinant() const;
248 
249 
253  bool16 IsSingular() const { return Determinant() == 0.0; }
254 
255 
263  bool16 PreservesBoxes() const;
264 
265 
268  void Invert();
269 
272  PMMatrix Inverse() const;
273 
274 
275 
276 //-------------------------------------------------------------------------------------
277 
278 
279 
282  friend PMMatrix operator*( const PMMatrix &m1, const PMMatrix &m2);
283 
286  void PreConcat(const PMMatrix &m);
287 
290  void PostConcat(const PMMatrix &m);
291 
292 
296  void PermuteLeftPast( const PMMatrix& m);
297 
301  void PermuteRightPast( const PMMatrix& m);
302 
303 
304 
305 
306 //-------------------------------------------------------------------------------------
307 
308 
309 
312  void PreScale( PMReal xScale, PMReal yScale);
313 
314 
317  void Scale( PMReal xScale, PMReal yScale);
318 
319 
320  const PMMatrix& ScaleFrom( const PMPoint& stationaryPoint, PMReal xScale, PMReal yScale)
321  {
322  Translate( -stationaryPoint.X(), -stationaryPoint.Y());
323  Scale( xScale, yScale);
324  Translate( stationaryPoint.X(), stationaryPoint.Y());
325  return *this;
326  }
327 
328 
329 
332  void SkewHorizontal( PMReal xSkewAngleInDegrees);
333 
336  void SkewVertical( PMReal ySkewAngleInDegrees);
337 
338  void SkewFrom( const PMPoint& stationaryPoint, PMReal skewAngle, PMReal noSkewDirectionAngle)
339  {
340  Translate( -stationaryPoint.X(), -stationaryPoint.Y());
341  Rotate( -noSkewDirectionAngle);
342  SkewHorizontal( skewAngle); //XFIssue LH coordinates
343  Rotate( noSkewDirectionAngle);
344  Translate( stationaryPoint.X(), stationaryPoint.Y());
345  }
346 
347 
348 
351  void PreRotate( PMReal angleInDegrees);
352 
355  void Rotate( PMReal angleInDegrees);
356 
357  const PMMatrix& RotateAbout( const PMPoint& center, PMReal angle)
358  {
359  Translate( -center.X(), -center.Y());
360  Rotate( angle); //XFIssue LH coordinates
361  Translate( center.X(), center.Y());
362  return *this;
363  }
364 
365 
368  void PreTranslate( PMReal x, PMReal y);
369  inline void PreTranslate( const PMPoint& offset) { PreTranslate( offset.X(), offset.Y());}
370 
373  void Translate( PMReal x, PMReal y);
374  inline void Translate( const PMPoint& offset) { Translate( offset.X(), offset.Y());}
375 
376 
377 
378 //-------------------------------------------------------------------------------------
379 
380 
385  void ScaleTo( PMReal xScale, PMReal yScale);
386  void ScaleTo( const PMPoint& stationaryPoint, PMReal xScale, PMReal yScale);
387 
391  void SkewTo( PMReal xSkewAngleInDegrees);
392  void SkewTo( const PMPoint& stationaryPoint, PMReal xSkewAngleInDegrees);
393  void SkewToSlope( const PMPoint& stationaryPoint, PMReal skewSlope);
394 
398  void RotateTo( PMReal thetaInDegrees);
399  void RotateTo( const PMPoint& stationaryPoint, PMReal thetaInDegrees);
400  void RotateTo( const PMPoint& stationaryPoint, PMReal cosineAngle, PMReal sineAngle);
401 
406  void TranslateTo( PMReal x, PMReal y);
407  void SetOrigin( PMReal x, PMReal y){ TranslateTo( x, y);}
408 
409 
410 
411 
412 //-------------------------------------------------------------------------------------
413 
414 
415 
416  /* An enumeration that specifies the factorization order used by GetMatrixFactors and GetTransformValues.
417  For example, a value of kFactorOrder_SKRT specifies that the matrix should be factored into elementary
418  transformation matrices in the order (scale)*(skew)*(rotate)*(translate). Note since matrix
419  multiplication is not commutative, the factorization of a matrix depends on the desired factor order.
420  Currently only kFactorOrder_SKRT and kFactorOrder_RKST are implemented. Passing any other TransformFactorOrder
421  value will return an incorrect result.
422  */
423  enum TransformFactorOrder {
424  kFactorOrder_SKRT = 0,
425 // kFactorOrder_SKTR,
426 // kFactorOrder_SRKT,
427 // kFactorOrder_SRTK,
428 // kFactorOrder_STKR,
429 // kFactorOrder_STRK,
430 //
431 // kFactorOrder_KSRT,
432 // kFactorOrder_KSTR,
433 // kFactorOrder_KRST,
434 // kFactorOrder_KRTS,
435 // kFactorOrder_KTSR,
436 // kFactorOrder_KTRS,
437 //
438 // kFactorOrder_RSKT,
439 // kFactorOrder_RSTK,
440  kFactorOrder_RKST = 14,
441 // kFactorOrder_RKTS,
442 // kFactorOrder_RTSK,
443 // kFactorOrder_RTKS,
444 //
445 // kFactorOrder_TSKR,
446 // kFactorOrder_TSRK,
447 // kFactorOrder_TKSR,
448 // kFactorOrder_TKRS,
449 // kFactorOrder_TRSK,
450 // kFactorOrder_TRKS,
451  kFactorOrder_End
452  };
453 
454 
455  static const uint32 kHasNoTransformContent = 0;
456  static const uint32 kHasScaleContent = 1;
457  static const uint32 kHasSkewContent = 2;
458  static const uint32 kHasRotateContent = 4;
459  static const uint32 kHasTranslateContent = 8;
460  static const uint32 kHasAllTransformContent = (kHasScaleContent | kHasSkewContent | kHasRotateContent | kHasTranslateContent);
461 
503  uint32 GetMatrixFactors(
504  PMMatrix* scale, PMMatrix* skew,
505  PMMatrix* rotate, PMMatrix* translate,
506  TransformFactorOrder factorOrder = kFactorOrder_SKRT
507  ) const;
508 
509 
536  uint32 GetTransformValues(
537  PMReal* xscale, PMReal* yscale,
538  PMReal* skewslope,
539  PMReal* costheta, PMReal* sintheta,
540  PMReal* xtranslation, PMReal* ytranslation,
541  TransformFactorOrder factorOrder = kFactorOrder_SKRT
542  ) const;
543 
544 
550  uint32 GetMatrixContent() const;
551 
552 
553 
557  PMReal GetXScale() const;
558 
562  PMReal GetYScale() const;
563 
568  PMReal GetXSkewAngle() const;
569 
577  PMReal GetRotationAngle( bool16 zeroCentered = kFalse) const;
578 
582  PMReal GetXTranslation() const noexcept
583  {
584  return fe;
585  }
586 
590  PMReal GetYTranslation() const noexcept
591  {
592  return ff;
593  }
594 
595 
596 
597  // If you need rotation and any other the other values it is faster to call
598  // the following method instead of each of the above methods. Arguments may
599  // be nil for those items you don't care about
600 
607  void GetMatrixInfo (PMReal* rotAngle, PMReal* xSkewAngle, PMReal* xScale, PMReal* yScale) const;
608 
609 
610  void SanityCheck() const
611  {
612 #if DEBUG
613  SanityCheck_();
614 #endif
615  }
616 
617  private:
618  void SanityCheck_() const;
619  void RotateTo(double cosine, double sine);
620  uint32 GetTransformValues_SKRT(PMReal* xscale, PMReal* yscale, PMReal* skewslope, PMReal* costheta, PMReal* sintheta, PMReal* xtranslation, PMReal* ytranslation) const;
621  uint32 GetTransformValues_RKST(PMReal* xscale, PMReal* yscale, PMReal* skewslope, PMReal* costheta, PMReal* sintheta, PMReal* xtranslation, PMReal* ytranslation) const;
622  void InternalSkewTo(double k);
623 
624 
625  PMReal fa, fb, fc, fd, fe, ff;
626  };
627 
628 
629 #endif