ITextSharp поворачивает весь текст на странице относительно точки

Я только что сжег час, разрабатывая решение этой проблемы, которое, я уверен, не самое лучшее; Я был бы рад услышать, если есть лучшее решение.

Мне нужно повернуть весь текст на странице относительно точки. Я пытался преобразовать точку в начало координат, выполнить поворот, а затем преобразовать обратно, но кажется, что окончательное преобразование происходит относительно преобразования вращения (что, если подумать, имеет смысл).

Вот упрощенная версия моего кода:

imports itextsharp.text

public class Example

    public shared function RotateAboutPoint(byval sourceReader as pdf.pdfreader, byval rads as double, byval centreX as double, byval centreY as double) as pdf.pdfreader            

        Using ms As New System.IO.MemoryStream
            Using doc As New Document
                Using writer As pdf.PdfWriter = pdf.PdfWriter.GetInstance(doc, ms)
                    doc.Open()
                    For i As Integer = 1 To sourceReader.NumberOfPages
                        Dim p As pdf.PdfTemplate = writer.GetImportedPage(sourceReader, i)

                        dim trans as new itextsharp.awt.geom.affinetransform
                        trans.translate(-centrex, -centrey)
                        trans.rotate(-rads)
                        trans.translate(centerx, centery)

                        doc.setpagesize(sourcereader.getpagesizewithrotation(I))
                        doc.newpage()

                        writer.DirectContent.AddTemplate(p, trans)
                    Next i
                    doc.Close()
                End Using
            End Using
            sourceReader.Close()
            sourceReader.Dispose()
            return New pdf.PdfReader(ms.ToArray)
        End Using
    end function
end class

person GHC    schedule 19.05.2015    source источник


Ответы (1)


Вот решения, с которыми я столкнулся, в основном выполняют вращение без перевода, а затем переводят путем добавления двух векторов, один из которых идет от начала вращения к требуемому центру вращения, а другой - из (место, где требуемый центр вращения будет повернуто до) к началу вращения

imports itextsharp.text

public class Example

    public shared function RotateAboutPoint(byval sourceReader as pdf.pdfreader, byval rads as double, byval centreX as double, byval centreY as double) as pdf.pdfreader            

        Using ms As New System.IO.MemoryStream
            Using doc As New Document
                Using writer As pdf.PdfWriter = pdf.PdfWriter.GetInstance(doc, ms)
                    doc.Open()
                    For i As Integer = 1 To sourceReader.NumberOfPages
                        Dim p As pdf.PdfTemplate = writer.GetImportedPage(sourceReader, i)

                        Dim transAdjust As New iTextSharp.awt.geom.AffineTransform
                        transAdjust.SetToIdentity()
                        transAdjust.Translate(centreX - ((centreX * System.Math.Cos(rads)) + (centreY * System.Math.Sin(rads))), centreY - ((centreX * -System.Math.Sin(rads)) + (centreY * System.Math.Cos(rads))))
                        Dim transRotate As New iTextSharp.awt.geom.AffineTransform
                        transRotate.SetToIdentity()
                        transRotate.Rotate(-rads)

                        Dim finalTrans As New iTextSharp.awt.geom.AffineTransform
                        finalTrans.SetToIdentity()
                        finalTrans.Concatenate(transAdjust)
                        finalTrans.Concatenate(transRotate)

                        doc.setpagesize(sourcereader.getpagesizewithrotation(I))
                        doc.newpage()

                        writer.DirectContent.AddTemplate(p, finalTrans)
                    Next i
                    doc.Close()
                End Using
            End Using
            sourceReader.Close()
            sourceReader.Dispose()
            return New pdf.PdfReader(ms.ToArray)
        End Using
    end function
end class

Это кажется грязным, но это работает — мне было бы очень интересно, если бы существовал более простой способ с использованием комбинаций преобразований и поворотов.

person GHC    schedule 19.05.2015
comment
Если угол поворота может быть только 0, 90, 180 или 270 (и никакое промежуточное значение), то есть гораздо более простой способ достичь своей цели. Если угол может иметь любое значение (не только кратное 90), тогда вам действительно нужно выполнить математику, и использование AffineTransform является более удобочитаемым способом сделать это. это (хотя это все еще выглядит сложным). - person Bruno Lowagie; 19.05.2015
comment
@BrunoLowagie Спасибо за ваш комментарий. Боюсь, мне нужно вращать произвольно, поэтому я не могу использовать поворот страницы. Знаете ли вы о более простом способе достижения моей цели, используя цепочку AffineTransforms без всей тригонометрии? - person GHC; 19.05.2015
comment
Вы можете умножить различные преобразования, получив 6 значений a, b, c, d, e и f, которые требуются при использовании другого метода AddTemplate(). Значения e и f определяют перевод. В случае ротации a и d будут 0, тогда как b будут -sin(angle), а d будут cos(angle). Проверьте раздел 4.2.5.1 Азбуки PDF с iText, чтобы узнать правильную математику (я просто пишу это из макушка моей головы). - person Bruno Lowagie; 19.05.2015