public void Multiply(TransformationMatrix m)
            {
                //performance optimalization: try to avoid multiple calculations.
                if (1 == m.a &&
                     0 == m.b &&
                     0 == m.c &&
                     1 == m.d
                )
                {
                    //offset only.
                    //this.Translate(m.OffsetX, m.OffsetY);
                }
                else
                {
                    //complex matrix
                    TransformationMatrix n = this.Clone();

                    a = m.a * n.a + m.b * n.c;
                    b = m.a * n.b + m.b * n.d;
                    c = m.c * n.a + m.d * n.c;
                    d = m.c * n.b + m.d * n.d;
                    e = m.e * n.a + m.f * n.c + n.e;
                    f = m.e * n.b + m.f * n.d + n.f;
                }
            }
    private static int GetTransformationIndex(TransformationMatrix transformationMatrix, BoundsInches imageBounds)
    {
      int[] vector = new int[4];

      vector[0] = GetSignOrZero(transformationMatrix.a);
      vector[1] = GetSignOrZero(transformationMatrix.b);
      vector[2] = GetSignOrZero(transformationMatrix.c);
      vector[3] = GetSignOrZero(transformationMatrix.d);

      int result = 0; // Default is to use the original picture

      for(int i = 0; i < 8; i++)
      {
        bool match = true;

        for(int j = 0; j < 4; j++)
        {
          if(fTransformationArray[i, j] != vector[j])
          {
            match = false;
          }
        }

        if(match)
        {
          result = i;
        }
      }

      // TODO: Calculate imageBounds
      imageBounds = null;

      return result;
    }
    private static TransformationMatrix GetTransformationMatrix(BoundsInches imageBounds, int transformationIndex)
    {
      TransformationMatrix result = new TransformationMatrix();

      result.a = fTransformationArray[transformationIndex, 0];
      result.b = fTransformationArray[transformationIndex, 1];
      result.c = fTransformationArray[transformationIndex, 2];
      result.d = fTransformationArray[transformationIndex, 3];
      result.e = fTransformationArray[transformationIndex, 4];
      result.f = fTransformationArray[transformationIndex, 5];

      result.a *= imageBounds.Width;
      result.b *= imageBounds.Height;
      result.c *= imageBounds.Width;
      result.d *= imageBounds.Height;
      result.e *= imageBounds.Width;
      result.e += imageBounds.X;
      result.f *= imageBounds.Height;
      result.f += imageBounds.Y;

      result.a *= 72;
      result.b *= 72;
      result.c *= 72;
      result.d *= 72;
      result.e *= 72;
      result.f *= 72;

      return result;
    }
 public TransformationMatrix Transpose()
     {
     TransformationMatrix result = new TransformationMatrix();
     result.cell[0,0] = this.cell[0,0]; result.cell[0,1] = this.cell[1,0]; result.cell[0,2] = this.cell[2,0]; result.cell[0,3] = this.cell[3,0];
     result.cell[1,0] = this.cell[0,1]; result.cell[1,1] = this.cell[1,1]; result.cell[1,2] = this.cell[2,1]; result.cell[1,3] = this.cell[3,1];
     result.cell[2,0] = this.cell[0,2]; result.cell[2,1] = this.cell[1,2]; result.cell[2,2] = this.cell[2,2]; result.cell[2,3] = this.cell[3,2];
     result.cell[3,0] = this.cell[0,3]; result.cell[3,1] = this.cell[1,3]; result.cell[3,2] = this.cell[2,3]; result.cell[3,3] = this.cell[3,3];
     return result;
     }
 static double RowDotCol(int iRow, TransformationMatrix left, double[] right) 
     {
     return left.cell[iRow,0]*right[0]
          + left.cell[iRow,1]*right[1]
          + left.cell[iRow,2]*right[2]
          + left.cell[iRow,3]*right[3];
     }
 static double RowDotCol(int iRow, int iCol, TransformationMatrix left, TransformationMatrix right) 
     {
     return left.cell[iRow,0]*right.cell[0,iCol]
         + left.cell[iRow,1]*right.cell[1,iCol]
         + left.cell[iRow,2]*right.cell[2,iCol] 
         + left.cell[iRow,3]*right.cell[3,iCol];
     }
 public static TransformationMatrix operator*(TransformationMatrix me, TransformationMatrix him)
     {
     TransformationMatrix result = new TransformationMatrix();
     result.cell[0,0] = RowDotCol(0,0,me, him); result.cell[0,1] = RowDotCol(0,1,me, him); result.cell[0,2] = RowDotCol(0,2,me, him); result.cell[0,3] = RowDotCol(0,3,me, him);
     result.cell[1,0] = RowDotCol(1,0,me, him); result.cell[1,1] = RowDotCol(1,1,me, him); result.cell[1,2] = RowDotCol(1,2,me, him); result.cell[1,3] = RowDotCol(1,3,me, him);
     result.cell[2,0] = RowDotCol(2,0,me, him); result.cell[2,1] = RowDotCol(2,1,me, him); result.cell[2,2] = RowDotCol(2,2,me, him); result.cell[2,3] = RowDotCol(2,3,me, him);
     result.cell[3,0] = RowDotCol(3,0,me, him); result.cell[3,1] = RowDotCol(3,1,me, him); result.cell[3,2] = RowDotCol(3,2,me, him); result.cell[3,3] = RowDotCol(3,3,me, him);
     return result;
     }
    public TransformationMatrix Inverse()
    // Return the inverse matrix. Code here generated automatically from Mathematica.
        {
        TransformationMatrix result = new TransformationMatrix();
        double denom = ((((cell[0, 2] * (cell[1, 0] * (cell[2, 3] * cell[3, 1] - 
            cell[2, 1] * cell[3, 3]) + cell[1, 1] * (cell[2, 0] * cell[3, 3] - 
            cell[2, 3] * cell[3, 0]) + cell[1, 3] * (cell[2, 1] * cell[3, 0] - 
            cell[2, 0] * cell[3, 1])) + cell[0, 3] * (cell[1, 0] * (cell[2, 1] * 
            cell[3, 2] - cell[2, 2] * cell[3, 1]) + cell[1, 1] * (cell[2, 2] * 
            cell[3, 0] - cell[2, 0] * cell[3, 2]) + cell[1, 2] * (cell[2, 0] * 
            cell[3, 1] - cell[2, 1] * cell[3, 0])) + cell[3, 3] * (cell[0, 0] * 
            (cell[1, 2] * cell[2, 1] - cell[1, 1] * cell[2, 2]) + cell[0, 1] * 
            (cell[1, 0] * cell[2, 2] - cell[1, 2] * cell[2, 0])) + cell[0, 0] * 
            cell[1, 1] * cell[2, 3] * cell[3, 2] + cell[0, 0] * cell[1, 3] * 
            cell[2, 2] * cell[3, 1] + cell[0, 1] * cell[1, 2] * cell[2, 3] * 
            cell[3, 0] + cell[0, 1] * cell[1, 3] * cell[2, 0] * cell[3, 2]) - 
            cell[0, 1] * cell[1, 0] * cell[2, 3] * cell[3, 2]) - cell[0, 0] * 
            cell[1, 3] * cell[2, 1] * cell[3, 2]) - cell[0, 0] * cell[1, 2] * 
            cell[2, 3] * cell[3, 1]) - cell[0, 1] * cell[1, 3] * cell[2, 2] * 
            cell[3, 0];

        result.cell[0,0] = (cell[1,1] * (cell[2,3] * cell[3,2] - cell[2,2] * cell[3,3]) + cell[1,2] * (cell[2,1] * cell[3,3] - cell[2,3] * cell[3,1]) + cell[1,3] * (cell[2,2] * cell[3,1] - cell[2,1] * cell[3,2]) ) / denom;
        result.cell[0,1] = (cell[0,1] * (cell[2,2] * cell[3,3] - cell[2,3] * cell[3,2]) + cell[0,2] * (cell[2,3] * cell[3,1] - cell[2,1] * cell[3,3]) + cell[0,3] * (cell[2,1] * cell[3,2] - cell[2,2] * cell[3,1]) ) / denom;
        result.cell[0,2] = (cell[0,1] * (cell[1,3] * cell[3,2] - cell[1,2] * cell[3,3]) + cell[0,2] * (cell[1,1] * cell[3,3] - cell[1,3] * cell[3,1]) + cell[0,3] * (cell[1,2] * cell[3,1] - cell[1,1] * cell[3,2]) ) / denom;
        result.cell[0,3] = (cell[0,1] * (cell[1,2] * cell[2,3] - cell[1,3] * cell[2,2]) + cell[0,2] * (cell[1,3] * cell[2,1] - cell[1,1] * cell[2,3]) + cell[0,3] * (cell[1,1] * cell[2,2] - cell[1,2] * cell[2,1]) ) / denom;
        result.cell[1,0] = (cell[1,0] * (cell[2,2] * cell[3,3] - cell[2,3] * cell[3,2]) + cell[1,2] * (cell[2,3] * cell[3,0] - cell[2,0] * cell[3,3]) + cell[1,3] * (cell[2,0] * cell[3,2] - cell[2,2] * cell[3,0]) ) / denom;
        result.cell[1,1] = (cell[0,0] * (cell[2,3] * cell[3,2] - cell[2,2] * cell[3,3]) + cell[0,2] * (cell[2,0] * cell[3,3] - cell[2,3] * cell[3,0]) + cell[0,3] * (cell[2,2] * cell[3,0] - cell[2,0] * cell[3,2]) ) / denom;
        result.cell[1,2] = (cell[0,0] * (cell[1,2] * cell[3,3] - cell[1,3] * cell[3,2]) + cell[0,2] * (cell[1,3] * cell[3,0] - cell[1,0] * cell[3,3]) + cell[0,3] * (cell[1,0] * cell[3,2] - cell[1,2] * cell[3,0]) ) / denom;
        result.cell[1,3] = (cell[0,0] * (cell[1,3] * cell[2,2] - cell[1,2] * cell[2,3]) + cell[0,2] * (cell[1,0] * cell[2,3] - cell[1,3] * cell[2,0]) + cell[0,3] * (cell[1,2] * cell[2,0] - cell[1,0] * cell[2,2]) ) / denom;
        result.cell[2,0] = (cell[1,0] * (cell[2,3] * cell[3,1] - cell[2,1] * cell[3,3]) + cell[1,1] * (cell[2,0] * cell[3,3] - cell[2,3] * cell[3,0]) + cell[1,3] * (cell[2,1] * cell[3,0] - cell[2,0] * cell[3,1]) ) / denom;
        result.cell[2,1] = (cell[0,0] * (cell[2,1] * cell[3,3] - cell[2,3] * cell[3,1]) + cell[0,1] * (cell[2,3] * cell[3,0] - cell[2,0] * cell[3,3]) + cell[0,3] * (cell[2,0] * cell[3,1] - cell[2,1] * cell[3,0]) ) / denom;
        result.cell[2,2] = (cell[0,0] * (cell[1,3] * cell[3,1] - cell[1,1] * cell[3,3]) + cell[0,1] * (cell[1,0] * cell[3,3] - cell[1,3] * cell[3,0]) + cell[0,3] * (cell[1,1] * cell[3,0] - cell[1,0] * cell[3,1]) ) / denom;
        result.cell[2,3] = (cell[0,0] * (cell[1,1] * cell[2,3] - cell[1,3] * cell[2,1]) + cell[0,1] * (cell[1,3] * cell[2,0] - cell[1,0] * cell[2,3]) + cell[0,3] * (cell[1,0] * cell[2,1] - cell[1,1] * cell[2,0]) ) / denom;
        result.cell[3,0] = (cell[1,0] * (cell[2,1] * cell[3,2] - cell[2,2] * cell[3,1]) + cell[1,1] * (cell[2,2] * cell[3,0] - cell[2,0] * cell[3,2]) + cell[1,2] * (cell[2,0] * cell[3,1] - cell[2,1] * cell[3,0]) ) / denom;
        result.cell[3,1] = (cell[0,0] * (cell[2,2] * cell[3,1] - cell[2,1] * cell[3,2]) + cell[0,1] * (cell[2,0] * cell[3,2] - cell[2,2] * cell[3,0]) + cell[0,2] * (cell[2,1] * cell[3,0] - cell[2,0] * cell[3,1]) ) / denom;
        result.cell[3,2] = (cell[0,0] * (cell[1,1] * cell[3,2] - cell[1,2] * cell[3,1]) + cell[0,1] * (cell[1,2] * cell[3,0] - cell[1,0] * cell[3,2]) + cell[0,2] * (cell[1,0] * cell[3,1] - cell[1,1] * cell[3,0]) ) / denom;
        result.cell[3,3] = (cell[0,0] * (cell[1,2] * cell[2,1] - cell[1,1] * cell[2,2]) + cell[0,1] * (cell[1,0] * cell[2,2] - cell[1,2] * cell[2,0]) + cell[0,2] * (cell[1,1] * cell[2,0] - cell[1,0] * cell[2,1]) ) / denom;

        return result;
        }
 public void test2()
 {
     var matrix = new TransformationMatrix(1, 0, 0, 1, 0, 0);
     matrix.Multiply(new TransformationMatrix(1, 0, 0, 1, 0, 0));
     AssertEquals(1.0, matrix.A);
 }
Exemple #10
0
        internal void UpdateLocation(TransformationMatrix transform)
        {
            foreach (HalfEdge3Vertex v in m_Mesh.Vertices)
            {
                double x = transform[0, 0] * v.X + transform[0, 1] * v.Y + transform[0, 2] * v.Z + transform[0, 3];
                double y = transform[1, 0] * v.X + transform[1, 1] * v.Y + transform[1, 2] * v.Z + transform[1, 3];
                double z = transform[2, 0] * v.X + transform[2, 1] * v.Y + transform[2, 2] * v.Z + transform[2, 3];
                v.X = x; v.Y = y; v.Z = z;
            }

            m_transformationMatrix = transform * m_transformationMatrix;
        }
Exemple #11
0
        internal virtual void Rotate(double angle, Vector3D direction)
        {
            Vector3D d = direction.Unit();
            double x = d.X;
            double y = d.Y;
            double z = d.Z;

            TransformationMatrix m = new TransformationMatrix();
            double c = Math.Cos(angle);
            double s = Math.Sin(angle);

            m[0,0] = (x*x) * (1-c)+c;
            m[1,0] = x*y * (1-c)-z*s;
            m[2,0] = x*z * (1-c)+y*s;

            m[0,1] = y*x * (1-c)+z*s;
            m[1,1] = (y*y) * (1-c)+c;
            m[2,1] = y*z * (1-c)-x*s;

            m[0,2] = x*z * (1-c)-y*s;
            m[1,2] = y*z * (1-c)+x*s;
            m[2,2] = (z*z) * (1-c)+c;

            UpdateLocation(m);

            m = m.Invert().Transpose();
            foreach (Vector3D v in m_Mesh.Normals)
            {
                double x0 = m[0, 0] * v.X + m[0, 1] * v.Y + m[0, 2] * v.Z + m[0, 3];
                double y0 = m[1, 0] * v.X + m[1, 1] * v.Y + m[1, 2] * v.Z + m[1, 3];
                double z0 = m[2, 0] * v.X + m[2, 1] * v.Y + m[2, 2] * v.Z + m[2, 3];
                v.X = x0; v.Y = y0; v.Z = z0;
            }
        }
        public void ModifyCurrentTransformationMatrix(double[] value)
        {
            var ctm = GetCurrentState().CurrentTransformationMatrix;

            GetCurrentState().CurrentTransformationMatrix = TransformationMatrix.FromArray(value).Multiply(ctm);
        }
        private void AdjustTextMatrix(double tx, double ty)
        {
            var matrix = TransformationMatrix.GetTranslationMatrix(tx, ty);

            TextMatrices.TextMatrix = matrix.Multiply(TextMatrices.TextMatrix);
        }
        public void ShowText(IInputBytes bytes)
        {
            var currentState = GetCurrentState();

            var font = currentState.FontState.FromExtendedGraphicsState ? activeExtendedGraphicsStateFont : resourceStore.GetFont(currentState.FontState.FontName);

            if (font == null)
            {
                throw new InvalidOperationException($"Could not find the font with name {currentState.FontState.FontName} in the resource store. It has not been loaded yet.");
            }

            var fontSize          = currentState.FontState.FontSize;
            var horizontalScaling = currentState.FontState.HorizontalScaling / 100.0;
            var characterSpacing  = currentState.FontState.CharacterSpacing;
            var rise = currentState.FontState.Rise;

            var transformationMatrix = currentState.CurrentTransformationMatrix;

            var renderingMatrix =
                TransformationMatrix.FromValues(fontSize * horizontalScaling, 0, 0, fontSize, 0, rise);

            var pointSize = Math.Round(transformationMatrix.Multiply(TextMatrices.TextMatrix).Transform(new PdfRectangle(0, 0, 1, fontSize)).Height, 2);

            while (bytes.MoveNext())
            {
                var code = font.ReadCharacterCode(bytes, out int codeLength);

                var foundUnicode = font.TryGetUnicode(code, out var unicode);

                if (!foundUnicode || unicode == null)
                {
                    log.Warn($"We could not find the corresponding character with code {code} in font {font.Name}.");
                    // Try casting directly to string as in PDFBox 1.8.
                    unicode = new string((char)code, 1);
                }

                var wordSpacing = 0.0;
                if (code == ' ' && codeLength == 1)
                {
                    wordSpacing += GetCurrentState().FontState.WordSpacing;
                }

                var textMatrix = TextMatrices.TextMatrix;

                if (font.IsVertical)
                {
                    if (!(font is IVerticalWritingSupported verticalFont))
                    {
                        throw new InvalidOperationException($"Font {font.Name} was in vertical writing mode but did not implement {nameof(IVerticalWritingSupported)}.");
                    }

                    var positionVector = verticalFont.GetPositionVector(code);

                    textMatrix = textMatrix.Translate(positionVector.X, positionVector.Y);
                }

                var boundingBox = font.GetBoundingBox(code);

                var transformedGlyphBounds = PerformantRectangleTransformer
                                             .Transform(renderingMatrix, textMatrix, transformationMatrix, boundingBox.GlyphBounds);

                var transformedPdfBounds = PerformantRectangleTransformer
                                           .Transform(renderingMatrix, textMatrix, transformationMatrix, new PdfRectangle(0, 0, boundingBox.Width, 0));

                // If the text rendering mode calls for filling, the current nonstroking color in the graphics state is used;
                // if it calls for stroking, the current stroking color is used.
                // In modes that perform both filling and stroking, the effect is as if each glyph outline were filled and then stroked in separate operations.
                // TODO: expose color as something more advanced
                var color = currentState.FontState.TextRenderingMode != TextRenderingMode.Stroke
                    ? currentState.CurrentNonStrokingColor
                    : currentState.CurrentStrokingColor;

                Letter letter = null;
                if (Diacritics.IsInCombiningDiacriticRange(unicode) && bytes.CurrentOffset > 0 && letters.Count > 0)
                {
                    var attachTo = letters[letters.Count - 1];

                    if (attachTo.TextSequence == textSequence &&
                        Diacritics.TryCombineDiacriticWithPreviousLetter(unicode, attachTo.Value, out var newLetter))
                    {
                        // TODO: union of bounding boxes.
                        letters.Remove(attachTo);

                        letter = new Letter(
                            newLetter,
                            attachTo.GlyphRectangle,
                            attachTo.StartBaseLine,
                            attachTo.EndBaseLine,
                            attachTo.Width,
                            attachTo.FontSize,
                            attachTo.Font,
                            attachTo.Color,
                            attachTo.PointSize,
                            attachTo.TextSequence);
                    }
                    else
                    {
                        letter = new Letter(
                            unicode,
                            transformedGlyphBounds,
                            transformedPdfBounds.BottomLeft,
                            transformedPdfBounds.BottomRight,
                            transformedPdfBounds.Width,
                            fontSize,
                            font.Details,
                            color,
                            pointSize,
                            textSequence);
                    }
                }
                else
                {
                    letter = new Letter(
                        unicode,
                        transformedGlyphBounds,
                        transformedPdfBounds.BottomLeft,
                        transformedPdfBounds.BottomRight,
                        transformedPdfBounds.Width,
                        fontSize,
                        font.Details,
                        color,
                        pointSize,
                        textSequence);
                }

                letters.Add(letter);

                markedContentStack.AddLetter(letter);

                double tx, ty;
                if (font.IsVertical)
                {
                    var verticalFont = (IVerticalWritingSupported)font;
                    var displacement = verticalFont.GetDisplacementVector(code);
                    tx = 0;
                    ty = (displacement.Y * fontSize) + characterSpacing + wordSpacing;
                }
                else
                {
                    tx = (boundingBox.Width * fontSize + characterSpacing + wordSpacing) * horizontalScaling;
                    ty = 0;
                }

                TextMatrices.TextMatrix = TextMatrices.TextMatrix.Translate(tx, ty);
            }
        }