Hello Telerik,
On my project, I have a RadDiagram with some shapes, and inside, text is defined.
I need to export this RadDiagram to a PDF File > I create a Bitmap Image from the RadDiagram, and insert this image in the PDF file.
However, texts in the PDF should be selectables. So, before the export, I hide all of texts, and I write them directly inside the PDF after it generation.
From a Textblock, I save primordial informations, and hide the text :
Dim
ptb
As
New
ParsedTextBlock(tb.Name, tb.Text, tb.ActualWidth, tb.ActualHeight, rotation,
CType
(tb.HorizontalAlignment, Windows.Forms.HorizontalAlignment),
tb.FontSize, tb.FontStyle, tb.FontFamily, tb.Foreground, tb.FontStretch, tb.FontWeight, tb.Background,
tb.TransformToAncestor(diag).Transform(
New
Windows.Point(0, 0)))
tb.Visibility = Windows.Visibility.Collapsed
ParsedTextBlock is a custom class to store some properties.
After, I have some methods to export Textblock :
Public
Sub
ExportSummaryDiagTextBlocks(diag
As
RadDiagram, vector
As
Windows.Vector)
Dim
diagItems
As
List(Of RadDiagramItem) = diag.Items.
Select
(
Function
(i) diag.ContainerGenerator.ContainerFromItem(i)).OrderBy(
Function
(c) c.ZIndex).ToList()
Dim
diagShapes
As
List(Of RadDiagramShape) = diagItems.OfType(Of RadDiagramShape).ToList()
Dim
vectorFromPdfOrigin
As
New
Windows.Vector(40, 70)
'40,70 is some fune tuning and should be modified if pageSize / layout is modified
Dim
w
As
Single
= ReportPageSize.GetWidth
Dim
wRatioDiag
As
Single
= WIDTH_RATIO_SUMMARY_FOR_DIAG_IMG
Dim
legacyRectRatio
As
Double
= Rect_Summary.Width / Rect_Summary.Height
Dim
rectDiagSummary
As
New
Geom.Rectangle(
CSng
(vectorFromPdfOrigin.X),
CSng
(vectorFromPdfOrigin.Y),
CSng
(w * wRatioDiag),
CSng
(w * wRatioDiag / legacyRectRatio))
Dim
windowsRectDiagSummary
As
New
Windows.Rect(0, 0,
CSng
(w * wRatioDiag),
CSng
(w * wRatioDiag / legacyRectRatio))
Dim
wRatioNewRectVersLegRect
As
Double
= rectDiagSummary.GetWidth / Rect_Summary.Width
Me
._ptb.ForEach(
Sub
(ptb) ExportTextBlock(ptb, diag, Rect_Summary, rectDiagSummary, vector,
New
Windows.Vector(40, 70)))
End
Sub
Me._ptb is a list of ParsedTextBlock.
Private
Sub
ExportTextBlock(ptb
As
ParsedTextBlock, diag
As
RadDiagram, diagRect
As
Windows.Rect, pdfRect
As
Geom.Rectangle, transformVector
As
Windows.Vector, vectorFromPdfOrigin
As
Windows.Vector)
Dim
p
As
Windows.Point = CalculateCoordForExport(diag, ptb, diagRect, pdfRect, transformVector, vectorFromPdfOrigin)
Dim
font
As
PdfFont = PdfFontFactory.CreateRegisteredFont(ptb.FontFamily.ToString(), PdfEncodings.IDENTITY_H,
True
,
FontHelper.ConvertWeightToPdfStyleInteger(ptb.FontWeight, (ptb.FontStyle = Windows.FontStyles.Italic)))
Dim
para
As
Paragraph =
New
Paragraph(ptb.Text).SetFont(font)
Dim
wRatioNewRectVersLegRect
As
Double
= pdfRect.GetWidth / diagRect.Width
Dim
fontSize
As
Single
=
CSng
(Math.Round(ptb.FontSize * wRatioNewRectVersLegRect, 1))
If
fontSize < 3
Then
fontSize = 3
Dim
w
As
Double
= ptb.Width * wRatioNewRectVersLegRect
para.SetPadding(0)
para.SetMargin(0)
para.SetFixedPosition(Convert.ToSingle(p.X), Convert.ToSingle(p.Y),
CSng
(w))
para.SetFontSize(fontSize)
'para.SetFontSize(CSng(ptb.FontSize))
para.SetHorizontalAlignment(iText.Layout.Properties.HorizontalAlignment.CENTER)
para.SetVerticalAlignment(VerticalAlignment.MIDDLE)
para.SetBackgroundColor(ColorHelper.ConvertBrushToDeviceRgb(ptb.Background))
Dim
rot
As
Double
= ptb.Rotation
' GetRotation(tb)
If
rot <> 0
Then
'Dim rot_radian As Double = ((-rot + 360) Mod 360) * Math.PI / 180.0 ' I multiply because WPF is counterclockwise but PDF is clockwise
Dim
rot_radian
As
Double
= -(rot * (Math.PI / 180))
para.SetRotationAngle(rot_radian)
End
If
_doc.Add(para)
End
Sub
And :
Private
Function
CalculateCoordForExport(diag
As
RadDiagram, tb
As
ParsedTextBlock, diagRect
As
Windows.Rect, pdfRect
As
Geom.Rectangle, transformVector
As
Windows.Vector,
vectorFromPdfOrigin
As
Windows.Vector)
As
Windows.Point
Dim
oldPoint
As
Windows.Point = tb.Coordinates
' tb.TransformToAncestor(diag).Transform(New Windows.Point(0, 0))
oldPoint =
New
Windows.Point(oldPoint.X - transformVector.X, oldPoint.Y - transformVector.Y)
'2 appliquer le crop
Dim
pointAfterCrop
As
Windows.Point = CoordinateHelper.ApplyCrop(oldPoint,
New
Windows.Point(
Me
.Rect_Summary.X,
Me
.Rect_Summary.Y))
'3 appliquer le resizing
Dim
pointAfterResising
As
Windows.Point = CoordinateHelper.CalculatePointAfterResizing(pointAfterCrop, diagRect, pdfRect)
'4 appliquer le Y reverse. car l'origine du raddiagram est en haut à gauche tandis que pour iText, c'est en bas à gauche
Dim
pointAfterReversingY
As
Windows.Point =
New
Windows.Point(pointAfterResising.X, pdfRect.GetHeight - pointAfterResising.Y)
'5 appliquer decalage nouvel origine
Dim
pointAfterNewOrigin
As
Windows.Point = Windows.Vector.Add(vectorFromPdfOrigin, pointAfterReversingY)
'6 soustraire à Y la Height de la shape car l'origine du raddiagram est en haut à gauche tandis que pour iText, c'est en bas à gauche
Dim
heightRatio
As
Double
= pdfRect.GetHeight / diagRect.Height
Dim
pointAfterMinusHeight
As
New
Windows.Point(pointAfterNewOrigin.X, pointAfterNewOrigin.Y - (tb.Height * heightRatio))
Return
pointAfterMinusHeight
End
Function
With these methods, for a text not rotated, it's OK. But the problem is when the text is rotated.
You can see the Origin screen, this one is the RadDiagram before exportation, and the Result screen, this one is the result inside the PDF.
And depending to the rotation angle, the result for rotated text is so bad.
My excpectation is that the position from the TextBlock is bad (calculation is false ?)...
I hope you can help me to write at the good place a rotated TextBlock.
Thank you.