protected void BreakByWord(ref RepString repString, out RepString repStringLeftover, double rWidth) { FontProp fp = repString.fontProp; StringBuilder sb = new StringBuilder(); StringBuilder sbLeftover = new StringBuilder(); double r_X = 0; foreach (string s in repString.sText.Split(null)) { if (sb.Length > 0) { r_X += fp.rWidth(" "); } r_X += fp.rWidth(s); if (r_X <= rWidth) { if (sb.Length > 0) { sb.Append(" "); } sb.Append(s); } else { if (sbLeftover.Length > 0) { sbLeftover.Append(" "); } sbLeftover.Append(s); } } if (sbLeftover.Length > 0) { repStringLeftover = new RepString(repString.fontProp, sbLeftover.ToString()); } else { repStringLeftover = null; } if (sb.Length > 0) { repString = new RepString(repString.fontProp, sb.ToString()); } else { repString = null; } }
//------------------------------------------------------------------------------------------07.02.2006 /// <summary>Writes the RepObj to the buffer.</summary> /// <param name="e">Environment data</param> public void Write(PdfIndirectObject_PageContents.Environment e) { PdfIndirectObject_PageContents p = e.pdfIndirectObject_PageContents; RepString repString = (RepString)e.repObj; Double rWidth = repString.fontProp.rWidth(repString.sText); Double rOfsX = rWidth * repString.rAlignH; Double rOfsY = repString.fontProp.rHeight() * (1 - repString.rAlignV); e.matrixD.Multiply(new MatrixD(1, 0, 0, 1, -rOfsX, rOfsY)); p.Command("BT"); p.Write_Font(repString.fontProp); if (e.bComplex) { p.Write_Matrix(e.matrixD); p.Command("Tm"); } else { p.Write_Point(e.matrixD.rDX, e.matrixD.rDY); p.Command("Td"); } p.String(repString.sText); p.Command("Tj"); p.Command("ET"); if (repString.fontProp.bUnderline) { Type1FontData type1FontData = (Type1FontData)repString.fontProp.fontPropData.fontData; PdfFontPropData pdfFontPropData = (PdfFontPropData)repString.fontProp.fontPropData; Double rSizeFactor = type1FontData.rSizeFactor(repString.fontProp); PenProp pp = new PenProp(e.report, rSizeFactor * type1FontData.fUnderlineThickness / 1000, repString.fontProp.color); p.Write_Pen(pp); Double rD = rSizeFactor * type1FontData.fUnderlinePosition / 1000; p.Write_Point(e.matrixD, 0, -rD); p.Command("m"); p.Write_Point(e.matrixD, rWidth, -rD); p.Command("l"); p.Command("S"); } }
protected double RealHight(RepObj repObj) { if (repObj is RepRect) { RepRect repRect = (RepRect)repObj; return(repRect.rHeight + repRect.penProp.rWidth); } else if (repObj is RepString) { RepString repString = (RepString)repObj; return(repString.fontProp.rLineFeed); } else if (repObj is RepImage) { RepImage repImage = (RepImage)repObj; if (Double.IsNaN(repImage.rHeight)) { using (Image image = Image.FromStream(repImage.stream)) { if (Double.IsNaN(repImage.rWidth)) { repImage.rWidth = image.Width / image.HorizontalResolution * 72; repImage.rHeight = image.Height / image.VerticalResolution * 72; } else { repImage.rHeight = image.Height * repImage.rWidth / image.Width; } } } return(repImage.rHeight); } else { return(repObj.rHeight); } }
protected void BreakByLetter(ref RepString repString, out RepString repStringLeftover, double rWidth) { FontProp fp = repString.fontProp; StringBuilder sb = new StringBuilder(); StringBuilder sbLeftover = new StringBuilder(); double r_X = 0; foreach (char c in repString.sText) { r_X += fp.rWidth(Convert.ToString(c)); if (r_X <= rWidth) { sb.Append(c); } else { sbLeftover.Append(c); } } if (sbLeftover.Length > 0) { repStringLeftover = new RepString(repString.fontProp, sbLeftover.ToString()); } else { repStringLeftover = null; } if (sb.Length > 0) { repString = new RepString(repString.fontProp, sb.ToString()); } else { repString = null; } }
//----------------------------------------------------------------------------------------------------x /// <summary>Adds a report object to the current container on a new line.</summary> /// <param name="repString">Report object to add to the container</param> public void AddNew(RepString repString) { NewLine(repString.fontProp.rLineFeed); Add(repString); }
//----------------------------------------------------------------------------------------------------x /// <summary>Adds a report object to the current container at the current position.</summary> /// <param name="repObj">Report object to add to the container</param> public void Add(RepObj repObj) { if (status == Status.Init) { if (_container_Cur == null) { CreateNewContainer(); } } if (repObj is RepString) { RepString repString = (RepString)repObj; FontProp fp = repString.fontProp; String sText = repString.sText; Int32 iLineStartIndex = 0; Int32 iIndex = 0; while (true) { if (rY_Cur > container_Cur.rHeight) { _container_Cur = null; CreateNewContainer(); } Int32 iLineBreakIndex = 0; Double rPosX = rX_Cur; Double rLineBreakPos = 0; while (true) { if (iIndex >= sText.Length) { iLineBreakIndex = iIndex; rLineBreakPos = rPosX; break; } Char c = sText[iIndex]; rPosX += fp.rWidth(Convert.ToString(c)); if (rPosX >= container_Cur.rWidth) { if (iLineBreakIndex == 0) { if (iIndex == iLineStartIndex) // at least one character must be printed { iIndex++; } iLineBreakIndex = iIndex; break; } iIndex = iLineBreakIndex; break; } if (c == ' ') { iLineBreakIndex = iIndex + 1; rLineBreakPos = rPosX; } else if (c == '\n') { iLineBreakIndex = iIndex; iIndex++; break; } iIndex++; } if (iLineStartIndex == 0 && iIndex >= sText.Length) // add entire object { container_Cur.Add(rX_Cur, rY_Cur, repObj); rX_Cur = rLineBreakPos; break; } String sLine = sText.Substring(iLineStartIndex, iLineBreakIndex - iLineStartIndex); container_Cur.Add(rX_Cur, rY_Cur, new RepString(fp, sLine)); if (iIndex >= sText.Length) { rX_Cur = rLineBreakPos; break; } rX_Cur = 0; rY_Cur += fp.rLineFeed; iLineStartIndex = iIndex; } } else { Debug.Fail("Unknown object type"); container_Cur.Add(rX_Cur, rY_Cur, repObj); } }
/// <summary> /// Adds a line of report objects to the current container at the current position. /// </summary> /// <param name="repObjs">Array of report objects to add to the container</param> /// <returns>Leftover report objects that didn't fit in the line.</returns> public RepObj[] AddLine(RepObj[] repObjs) { if (status == Status.Init && _container_Cur == null) { CreateNewContainer(); } double rMaxHeight = 0; double rMaxStringHeight = 0; double rWidth = 0; rX_Cur = 0; ArrayList line = new ArrayList(); ArrayList leftover = new ArrayList(); foreach (RepObj repObj in repObjs) { if (rWidth + RealWidth(repObj) <= container_Cur.rWidth) { line.Add(repObj); } else if (rWidth < container_Cur.rWidth && repObj is RepString) { RepString repString = (RepString)repObj; RepString repStringLeftover; BreakByWord(ref repString, out repStringLeftover, container_Cur.rWidth - rWidth); if (repString != null) { line.Add(repString); } if (repStringLeftover != null) { leftover.Add(repStringLeftover); } } else { leftover.Add(repObj); } rWidth += RealWidth(repObj); } // if line.Count is zero and leftover.count isn't, we've got a single RepObj bigger than // its container if (line.Count == 0 && leftover.Count > 0) { RepObj repObj = (RepObj)leftover[0]; if (repObj is RepString) // can't break by word, so break by letter { RepString repStringLeftover; RepString repString = (RepString)repObj; BreakByLetter(ref repString, out repStringLeftover, container_Cur.rWidth); if (repString != null) { line.Add(repString); } leftover.RemoveAt(0); if (repStringLeftover != null) { leftover.Insert(0, repStringLeftover); } } else { line.Add(leftover[0]); leftover.RemoveAt(0); } } // compute max hight and max line hight for alignment foreach (RepObj repObj in line) { if (repObj is RepString && RealHight(repObj) > rMaxStringHeight) { rMaxStringHeight = RealHight(repObj); } if (RealHight(repObj) > rMaxHeight) { rMaxHeight = RealHight(repObj); } } rY_Cur += rMaxHeight; rMaxStringHeight /= 4; // poor man's line leading if (rY_Cur > container_Cur.rHeight) { _container_Cur = null; CreateNewContainer(); rY_Cur += rMaxHeight; } foreach (RepObj repObj in line) { if (repObj is RepString) { container_Cur.Add(rX_Cur, rY_Cur - rMaxStringHeight, repObj); } else { container_Cur.Add(RealX(repObj, rX_Cur), RealY(repObj, rY_Cur), repObj); } rX_Cur += RealWidth(repObj); } if (leftover.Count > 0) { return((RepObj[])leftover.ToArray(typeof(RepObj))); } else { return(null); } }
//----------------------------------------------------------------------------------------------------x /// <summary>Adds a report object to the current container at the current position.</summary> /// <param name="al_RepObj">Result array for the report objects</param> /// <param name="repString">Report object to add to the container</param> /// <param name="rCurX"></param> /// <param name="rOfsX"></param> /// <param name="rAlignH">Horizontal allignment</param> /// <param name="rCurY"></param> /// <param name="rWidth"></param> internal void FormatString(ArrayList al_RepObj, RepString repString, ref Double rCurX, Double rOfsX, Double rAlignH, ref Double rCurY, Double rWidth) { FontProp fp = repString.fontProp; String sText = repString.sText; Int32 iLineStartIndex = 0; Int32 iIndex = 0; while (true) { Int32 iLineBreakIndex = 0; Double rPosX = rCurX; Double rLineBreakPos = 0; while (true) { if (iIndex >= sText.Length) { iLineBreakIndex = iIndex; rLineBreakPos = rPosX; break; } Char c = sText[iIndex]; if (c == '\r') { iLineBreakIndex = iIndex; iIndex++; c = sText[iIndex]; if (c == '\n') { iIndex++; } break; } rPosX += fp.rGetTextWidth(Convert.ToString(c)); if (rPosX >= rWidth) { if (iLineBreakIndex == 0 && rCurX <= rOfsX + 0.01) { if (iIndex == iLineStartIndex) // at least one character must be printed { iIndex++; } iLineBreakIndex = iIndex; break; } iIndex = iLineBreakIndex; break; } if (c == ' ') { iLineBreakIndex = iIndex + 1; rLineBreakPos = rPosX; } iIndex++; } if (iLineStartIndex == 0 && iIndex >= sText.Length) // add entire object { repString.matrixD.rDX = rCurX + (rWidth - rCurX) * rAlignH; repString.rAlignH = rAlignH; repString.matrixD.rDY = rCurY; repString.rAlignV = RepObj.rAlignBottom; al_RepObj.Add(repString); rCurX = rLineBreakPos; break; } if (iLineBreakIndex > iLineStartIndex && sText[iLineBreakIndex - 1] == ' ') { iLineBreakIndex--; } String sLine = sText.Substring(iLineStartIndex, iLineBreakIndex - iLineStartIndex); RepString rs = new RepString(fp, sLine); rs.matrixD.rDX = rCurX + (rWidth - rCurX) * rAlignH; rs.rAlignH = rAlignH; rs.matrixD.rDY = rCurY; rs.rAlignV = RepObj.rAlignBottom; al_RepObj.Add(rs); if (iIndex >= sText.Length) { rCurX = rLineBreakPos; break; } rCurX = rOfsX; rCurY += fp.rLineFeed; iLineStartIndex = iIndex; } }
//----------------------------------------------------------------------------------------------------x /// <summary>Adds a report object to the current container at the current position.</summary> /// <param name="repString">Report object to add to the container</param> /// <param name="container">Container</param> /// <param name="rCurX"></param> /// <param name="rOfsX"></param> /// <param name="rCurY"></param> /// <param name="rWidth"></param> public void PrintString(RepString repString, Container container, ref Double rCurX, Double rOfsX, ref Double rCurY, Double rWidth) { FontProp fp = repString.fontProp; String sText = repString.sText; Int32 iLineStartIndex = 0; Int32 iIndex = 0; while (true) { if (rCurY > container.rHeight) { NextContainer(); } Int32 iLineBreakIndex = 0; Double rPosX = rCurX; Double rLineBreakPos = 0; while (true) { if (iIndex >= sText.Length) { iLineBreakIndex = iIndex; rLineBreakPos = rPosX; break; } Char c = sText[iIndex]; rPosX += fp.rGetTextWidth(Convert.ToString(c)); if (rPosX >= rWidth) { if (iLineBreakIndex == 0) { if (iIndex == iLineStartIndex) // at least one character must be printed { iIndex++; } iLineBreakIndex = iIndex; break; } iIndex = iLineBreakIndex; break; } if (c == ' ') { iLineBreakIndex = iIndex + 1; rLineBreakPos = rPosX; } else if (c == '\n') { iLineBreakIndex = iIndex; iIndex++; break; } iIndex++; } if (iLineStartIndex == 0 && iIndex >= sText.Length) // add entire object { container.Add(rOfsX + rCurX, rCurY, repString); rCurX = rLineBreakPos; break; } String sLine = sText.Substring(iLineStartIndex, iLineBreakIndex - iLineStartIndex); container.Add(rOfsX + rCurX, rCurY, new RepString(fp, sLine)); if (iIndex >= sText.Length) { rCurX = rLineBreakPos; break; } rCurX = 0; rCurY += fp.rLineFeed; iLineStartIndex = iIndex; } }
//----------------------------------------------------------------------------------------------------x /// <overloads> /// <summary>Adds a report object to the cell.</summary> /// </overloads> /// /// <summary>Adds a report object to the cell at the current position with the specified offset (inch version).</summary> /// <remarks> /// The current horizontal position <see cref="TlmCell.rCurX"/> will be incremented by the width of the report object. /// <para>The horizontal offset <paramref name="rOfsH"/> can be used for example to make a space in front of the report object. /// The vertical offset <paramref name="rOfsV"/> can be used for example to adjust the vertical position of an image or to set super-/subscript fonts.</para> /// <para>For the metric version see <see cref="TlmCell.AddMM"/>.</para> /// </remarks> /// <param name="rOfsH">Horizontal offset (points, 1/72 inch)</param> /// <param name="rOfsV">Vertical offset (points, 1/72 inch)</param> /// <param name="repObj">Report object that will be added to the cell</param> /// <seealso cref="TlmCell.AddMM"/> public void Add(Double rOfsH, Double rOfsV, RepObj repObj) { RepString repString = repObj as RepString; if (RT.bEquals(rAngle, -90, 0.001)) // vertical { Debug.Assert(tlmRow_Start.iIndex == tlmRow_End.iIndex, "vertically merged cell are not supported"); Double rPreferredHeight = tlmRow_Start.rPreferredHeight; Double rInnerHeight = rPreferredHeight - rIndentTop - rIndentBottom; if (status == Status.Init) { if (Double.IsNaN(rPreferredHeight)) { throw new ReportException("The preferred height of the row must be set"); } rCurX = rIndentLeft + rInnerWidth * rAlignV; rCurY = rPreferredHeight - rIndentBottom - rInnerHeight * rAlignH; status = Status.Open; } CheckStatus_Open("cannot add a report object."); Double rUsedWidth = 0; if (iFirstRepObjOfCurLine < iRepObjCount) { RepObj ro = repObj_Get(iRepObjCount - 1); rUsedWidth = ro.rPosBottom; ro = repObj_Get(iFirstRepObjOfCurLine); rUsedWidth -= ro.rPosTop; } rUsedWidth += rOfsH; Double rRemainingWidth = rInnerHeight - rUsedWidth; if (repString != null) { if (status == Status.Open) { if (Double.IsNaN(rLineFeed)) { rLineFeed = repString.fontProp.rLineFeed; } //rCurX -= repString.fontProp.rHeight() * rAlignV; status = Status.OpenText; } if (tlmTextMode == TlmTextMode.EllipsisCharacter) { repString.sText = repString.fontProp.sTruncateText(repString.sText, rRemainingWidth); // ... !!! } } if (repString != null && (tlmTextMode == TlmTextMode.MultiLine || tlmTextMode == TlmTextMode.SingleMultiLine)) { Debug.Fail("not implemented"); } else { Double rOfs = (repObj.rWidth + rOfsH) * rAlignH; for (Int32 i = iFirstRepObjOfCurLine; i < iRepObjCount; i++) { RepObj ro = repObj_Get(i); ro.matrixD.rDY += rOfs; } repObj.RotateTransform(rAngle); repObj.matrixD.rDX = rCurX - rOfsV; repObj.rAlignH = rAlignH; repObj.matrixD.rDY = rCurY - rOfsH * (1 - rAlignH); repObj.rAlignV = rAlignV; AddRepObj(repObj); rCurY = repObj.rPosTop; } } else // horizontal { if (status == Status.Init) { rCurX = rIndentLeft + rInnerWidth * rAlignH; rCurY = rIndentTop; status = Status.Open; } CheckStatus_Open("cannot add a report object."); Double rUsedWidth = 0; if (iFirstRepObjOfCurLine < iRepObjCount) { RepObj ro = repObj_Get(iRepObjCount - 1); rUsedWidth = ro.rPosRight; ro = repObj_Get(iFirstRepObjOfCurLine); rUsedWidth -= ro.rPosLeft; } rUsedWidth += rOfsH; Double rRemainingWidth = rInnerWidth - rUsedWidth; if (repString != null) { if (status == Status.Open) { if (Double.IsNaN(rLineFeed)) { rLineFeed = repString.fontProp.rLineFeed; } rCurY += repString.fontProp.rSize; status = Status.OpenText; } if (tlmTextMode == TlmTextMode.EllipsisCharacter) { Double rWidth = repString.fontProp.rGetTextWidth(repString.sText); if (rWidth > rRemainingWidth) { if (bCut) { return; } repString.sText = repString.fontProp.sTruncateText(repString.sText, rRemainingWidth); bCut = true; rWidth = repString.fontProp.rGetTextWidth(repString.sText); if (rWidth >= rRemainingWidth) { if (iFirstRepObjOfCurLine < iRepObjCount) { RepObj ro = repObj_Get(iRepObjCount - 1); RepString rs = ro as RepString; if (rs != null) { rs.sText = rs.sText.Substring(0, rs.sText.Length - 1) + "..."; } } return; } } } } if (repString != null && (tlmTextMode == TlmTextMode.MultiLine || tlmTextMode == TlmTextMode.SingleMultiLine)) { Double rWidth = rInnerWidth + rIndentLeft; lock (al_RepObj) { Debug.Assert(al_RepObj.Count == 0); Double rCopy = rCurY; Double rOfs = rWidth * rAlignH; rCurX -= rOfs; tlmBase.FormatString(al_RepObj, repString, ref rCurX, rIndentLeft, rAlignH, ref _rCurY, rWidth); rCurX += rOfs; foreach (RepObj ro in al_RepObj) { AddRepObj(ro); if (tlmTextMode == TlmTextMode.SingleMultiLine) { tlmBase.Commit(); } } al_RepObj.Clear(); if (!RT.bEquals(rCopy, _rCurY, TlmBase.rTol)) { rCurY = _rCurY; // trigger iFirstRepObjOfCurLine iFirstRepObjOfCurLine = iRepObjCount - 1; } } } else { Double rOfs = (repObj.rWidth + rOfsH) * rAlignH; for (Int32 i = iFirstRepObjOfCurLine; i < iRepObjCount; i++) { RepObj ro = repObj_Get(i); ro.matrixD.rDX -= rOfs; } repObj.matrixD.rDX = rCurX + rOfsH * (1 - rAlignH); repObj.rAlignH = rAlignH; repObj.matrixD.rDY = rCurY + rOfsV; AddRepObj(repObj); rCurX = repObj.rPosRight; } } }
//----------------------------------------------------------------------------------------------------x /// <summary>Prepares the PDF-object structure for a container.</summary> /// <param name="pdfPageData"></param> /// <param name="iObjId"></param> /// <param name="container"></param> private void PrepareObjIdsForContainer(PdfIndirectObject_Page pdfPageData, Container container) { foreach (RepObj repObj in container) { if (repObj is Container) { PrepareObjIdsForContainer(pdfPageData, (Container)repObj); } else if (repObj is RepArcBase) { pdfPageData.bProcSet_PDF = true; } else if (repObj is RepImage) { // RepImage repImage = (RepImage)repObj; // ImageFormat imageFormat = repImage.imageData.image.RawFormat; // if (Object.Equals(imageFormat, ImageFormat.Jpeg)) { // pdfPageData.bProcSet_ImageC = true; // } // else if (Object.Equals(imageFormat, ImageFormat.Tiff)) { // pdfPageData.bProcSet_ImageB = true; // } // else { // Debug.Fail("unknown image type: send image to [email protected]"); // } RepImage repImage = repObj as RepImage; repImage.imageData.stream.Position = 0; //Added By TechnoGuru - [email protected] - http://www.borie.org/ //To support tiff file //I reload Image from stream to be more scalable //(Dont't have like that lots of image object on memeory #if !WindowsCE using (Image image = Image.FromStream(repImage.imageData.stream)) { if (image.RawFormat.Equals(ImageFormat.Tiff) && image.PixelFormat.Equals(PixelFormat.Format1bppIndexed)) { pdfPageData.bProcSet_ImageI = true; // CHANGED } else if (image.RawFormat.Equals(ImageFormat.Tiff) || image.RawFormat.Equals(ImageFormat.Jpeg)) { pdfPageData.bProcSet_ImageC = true; } else { Debug.Fail("unknown image type: send image to [email protected]"); } } #endif } else if (repObj is RepLine) { pdfPageData.bProcSet_PDF = true; } else if (repObj is RepRect) { pdfPageData.bProcSet_PDF = true; } else if (repObj is RepString) { FontData fontData_String = ((RepString)repObj).fontProp.fontData; PdfIndirectObject_Font pdfIndirectObject_Font = (PdfIndirectObject_Font)fontData_String.oFontDataX; if (fontData_String.oFontDataX == null) // extended font data for PDF must be created and registered { if (fontData_String is Type1FontData) { pdfIndirectObject_Font = new PdfIndirectObject_Font_Type1(this, (Type1FontData)fontData_String); } else if (fontData_String is OpenTypeFontData) { pdfIndirectObject_Font = new PdfIndirectObject_Font_OpenType(this, (OpenTypeFontData)fontData_String); } else { Debug.Fail("unknown type of FontData"); } fontData_String.oFontDataX = pdfIndirectObject_Font; } RepString repString = (RepString)repObj; foreach (Char ch in repString.sText) { fontData_String.bitArray_UsedChar[(Int32)ch] = true; } pdfPageData.RegisterFontData(fontData_String); pdfPageData.bProcSet_Text = true; } else { throw new ReportException("unknown report object type [" + repObj.GetType().FullName + "]"); } } }