public virtual void WriteNanHighPrecisionTest() { double d = double.NaN; byte[] actuals = ByteUtils.GetIsoBytes(d, null, true); byte[] expecteds = DecimalFormatUtil.FormatNumber(0, "0.##").GetBytes(iText.IO.Util.EncodingUtil.ISO_8859_1 ); String message = "Expects: " + iText.IO.Util.JavaUtil.GetStringForBytes(expecteds) + ", actual: " + iText.IO.Util.JavaUtil.GetStringForBytes (actuals) + " \\\\ " + d; NUnit.Framework.Assert.AreEqual(expecteds, actuals, message); }
public virtual void WriteNumber3Test() { Random rnd = new Random(); for (int i = 0; i < 100000; i++) { double d = rnd.NextDouble(); if (d < 32700) { d *= 100000; } d = Round(d, 0); byte[] actuals = ByteUtils.GetIsoBytes(d); byte[] expecteds = DecimalFormatUtil.FormatNumber(d, "0").GetBytes(iText.IO.Util.EncodingUtil.ISO_8859_1); String message = "Expects: " + iText.IO.Util.JavaUtil.GetStringForBytes(expecteds) + ", actual: " + iText.IO.Util.JavaUtil.GetStringForBytes (actuals) + " \\\\ " + d; NUnit.Framework.Assert.AreEqual(expecteds, actuals, message); } }
public virtual void WriteNumber2Test() { Random rnd = new Random(); for (int i = 0; i < 100000; i++) { double d = (double)rnd.Next(1000000) / 1000000; d = Round(d, 5); if (Math.Abs(d) < 0.000015) { continue; } byte[] actuals = ByteUtils.GetIsoBytes(d); byte[] expecteds = DecimalFormatUtil.FormatNumber(d, "0.#####").GetBytes(); String message = "Expects: " + iText.IO.Util.JavaUtil.GetStringForBytes(expecteds) + ", actual: " + iText.IO.Util.JavaUtil.GetStringForBytes (actuals) + " \\\\ " + d; NUnit.Framework.Assert.AreEqual(expecteds, actuals, message); } }
public virtual void WriteNumber1Test() { Random rnd = new Random(); for (int i = 0; i < 100000; i++) { double d = (double)rnd.Next(2120000000) / 100000; d = Round(d, 2); if (d < 1.02) { i--; continue; } byte[] actuals = ByteUtils.GetIsoBytes(d); byte[] expecteds = DecimalFormatUtil.FormatNumber(d, "0.##").GetBytes(iText.IO.Util.EncodingUtil.ISO_8859_1 ); String message = "Expects: " + iText.IO.Util.JavaUtil.GetStringForBytes(expecteds) + ", actual: " + iText.IO.Util.JavaUtil.GetStringForBytes (actuals) + " \\\\ " + d; NUnit.Framework.Assert.AreEqual(expecteds, actuals, message); } }
/// <summary>Merge parent style declarations for passed styleProperty into passed style map</summary> /// <param name="styles">the styles map</param> /// <param name="styleProperty">the style property</param> /// <param name="parentPropValue">the parent properties value</param> /// <param name="parentFontSizeString">the parent font-size for resolving relative, font-dependent attributes</param> public virtual void MergeParentStyleDeclaration(IDictionary <String, String> styles, String styleProperty, String parentPropValue, String parentFontSizeString) { String childPropValue = styles.Get(styleProperty); if ((childPropValue == null && CheckInheritance(styleProperty)) || CommonCssConstants.INHERIT.Equals(childPropValue )) { if (ValueIsOfMeasurement(parentPropValue, CommonCssConstants.EM) || ValueIsOfMeasurement(parentPropValue, CommonCssConstants.EX) || (ValueIsOfMeasurement(parentPropValue, CommonCssConstants.PERCENTAGE) && fontSizeDependentPercentage .Contains(styleProperty))) { float absoluteParentFontSize = CssUtils.ParseAbsoluteLength(parentFontSizeString); // Format to 4 decimal places to prevent differences between Java and C# styles.Put(styleProperty, DecimalFormatUtil.FormatNumber(CssUtils.ParseRelativeValue(parentPropValue, absoluteParentFontSize ), "0.####") + CommonCssConstants.PT); } else { //Property is inherited, add to element style declarations styles.Put(styleProperty, parentPropValue); } } else { if (CommonCssConstants.TEXT_DECORATION.Equals(styleProperty) && !CommonCssConstants.INLINE_BLOCK.Equals(styles .Get(CommonCssConstants.DISPLAY))) { // TODO Note! This property is formally not inherited, but the browsers behave very similar to inheritance here. /* Text decorations on inline boxes are drawn across the entire element, * going across any descendant elements without paying any attention to their presence. */ // Also, when, for example, parent element has text-decoration:underline, and the child text-decoration:overline, // then the text in the child will be both overline and underline. This is why the declarations are merged // See TextDecorationTest#textDecoration01Test styles.Put(styleProperty, CssPropertyMerger.MergeTextDecoration(childPropValue, parentPropValue)); } } }
/// <summary>Outputs a <CODE>double</CODE> into a format suitable for the PDF.</summary> /// <param name="d">a double</param> /// <param name="buf">a ByteBufferOutputStream</param> /// <returns> /// the <CODE>String</CODE> representation of the <CODE>double</CODE> if /// <CODE>buf</CODE> is <CODE>null</CODE>. If <CODE>buf</CODE> is <B>not</B> <CODE>null</CODE>, /// then the double is appended directly to the buffer and this methods returns <CODE>null</CODE>. /// </returns> public static String FormatDouble(double d, iText.Kernel.Pdf.ByteBufferOutputStream buf) { if (HIGH_PRECISION) { String sform = DecimalFormatUtil.FormatNumber(d, "0.######"); if (buf == null) { return(sform); } else { buf.Append(sform); return(null); } } bool negative = false; if (Math.Abs(d) < 0.000015) { if (buf != null) { buf.Append(ZERO); return(null); } else { return("0"); } } if (d < 0) { negative = true; d = -d; } if (d < 1.0) { d += 0.000005; if (d >= 1) { if (negative) { if (buf != null) { buf.Append((byte)'-'); buf.Append((byte)'1'); return(null); } else { return("-1"); } } else { if (buf != null) { buf.Append((byte)'1'); return(null); } else { return("1"); } } } if (buf != null) { int v = (int)(d * 100000); if (negative) { buf.Append((byte)'-'); } buf.Append((byte)'0'); buf.Append((byte)'.'); buf.Append((byte)(v / 10000 + ZERO)); if (v % 10000 != 0) { buf.Append((byte)((v / 1000) % 10 + ZERO)); if (v % 1000 != 0) { buf.Append((byte)((v / 100) % 10 + ZERO)); if (v % 100 != 0) { buf.Append((byte)((v / 10) % 10 + ZERO)); if (v % 10 != 0) { buf.Append((byte)((v) % 10 + ZERO)); } } } } return(null); } else { int x = 100000; int v = (int)(d * x); StringBuilder res = new StringBuilder(); if (negative) { res.Append('-'); } res.Append("0."); while (v < x / 10) { res.Append('0'); x /= 10; } res.Append(v); int cut = res.Length - 1; while (res[cut] == '0') { --cut; } res.Length = cut + 1; return(res.ToString()); } } else { if (d <= 32767) { d += 0.005; int v = (int)(d * 100); if (v < byteCacheSize && byteCache[v] != null) { if (buf != null) { if (negative) { buf.Append((byte)'-'); } buf.Append(byteCache[v]); return(null); } else { String tmp = PdfEncodings.ConvertToString(byteCache[v], null); if (negative) { tmp = "-" + tmp; } return(tmp); } } if (buf != null) { if (v < byteCacheSize) { //create the cachebyte[] byte[] cache; int size = 0; if (v >= 1000000) { //the original number is >=10000, we need 5 more bytes size += 5; } else { if (v >= 100000) { //the original number is >=1000, we need 4 more bytes size += 4; } else { if (v >= 10000) { //the original number is >=100, we need 3 more bytes size += 3; } else { if (v >= 1000) { //the original number is >=10, we need 2 more bytes size += 2; } else { if (v >= 100) { //the original number is >=1, we need 1 more bytes size += 1; } } } } } //now we must check if we have a decimal number if (v % 100 != 0) { //yes, do not forget the "." size += 2; } if (v % 10 != 0) { size++; } cache = new byte[size]; int add = 0; if (v >= 1000000) { cache[add++] = bytes[(v / 1000000)]; } if (v >= 100000) { cache[add++] = bytes[(v / 100000) % 10]; } if (v >= 10000) { cache[add++] = bytes[(v / 10000) % 10]; } if (v >= 1000) { cache[add++] = bytes[(v / 1000) % 10]; } if (v >= 100) { cache[add++] = bytes[(v / 100) % 10]; } if (v % 100 != 0) { cache[add++] = (byte)'.'; cache[add++] = bytes[(v / 10) % 10]; if (v % 10 != 0) { cache[add++] = bytes[v % 10]; } } byteCache[v] = cache; } if (negative) { buf.Append((byte)'-'); } if (v >= 1000000) { buf.Append(bytes[(v / 1000000)]); } if (v >= 100000) { buf.Append(bytes[(v / 100000) % 10]); } if (v >= 10000) { buf.Append(bytes[(v / 10000) % 10]); } if (v >= 1000) { buf.Append(bytes[(v / 1000) % 10]); } if (v >= 100) { buf.Append(bytes[(v / 100) % 10]); } if (v % 100 != 0) { buf.Append((byte)'.'); buf.Append(bytes[(v / 10) % 10]); if (v % 10 != 0) { buf.Append(bytes[v % 10]); } } return(null); } else { StringBuilder res = new StringBuilder(); if (negative) { res.Append('-'); } if (v >= 1000000) { res.Append(chars[(v / 1000000)]); } if (v >= 100000) { res.Append(chars[(v / 100000) % 10]); } if (v >= 10000) { res.Append(chars[(v / 10000) % 10]); } if (v >= 1000) { res.Append(chars[(v / 1000) % 10]); } if (v >= 100) { res.Append(chars[(v / 100) % 10]); } if (v % 100 != 0) { res.Append('.'); res.Append(chars[(v / 10) % 10]); if (v % 10 != 0) { res.Append(chars[v % 10]); } } return(res.ToString()); } } else { d += 0.5; long v = (long)d; if (negative) { return("-" + System.Convert.ToString(v)); } else { return(System.Convert.ToString(v)); } } } }
/* (non-Javadoc) * @see com.itextpdf.html2pdf.css.resolve.ICssResolver#resolveStyles(com.itextpdf.html2pdf.html.node.INode, com.itextpdf.html2pdf.css.resolve.CssContext) */ private IDictionary <String, String> ResolveStyles(INode element, CssContext context) { IList <CssRuleSet> ruleSets = new List <CssRuleSet>(); ruleSets.Add(new CssRuleSet(null, UserAgentCss.GetStyles(element))); if (element is IElementNode) { ruleSets.Add(new CssRuleSet(null, HtmlStylesToCssConverter.Convert((IElementNode)element))); } ruleSets.AddAll(cssStyleSheet.GetCssRuleSets(element, deviceDescription)); if (element is IElementNode) { String styleAttribute = ((IElementNode)element).GetAttribute(AttributeConstants.STYLE); if (styleAttribute != null) { ruleSets.Add(new CssRuleSet(null, CssRuleSetParser.ParsePropertyDeclarations(styleAttribute))); } } IDictionary <String, String> elementStyles = CssStyleSheet.ExtractStylesFromRuleSets(ruleSets); if (CssConstants.CURRENTCOLOR.Equals(elementStyles.Get(CssConstants.COLOR))) { // css-color-3/#currentcolor: // If the ‘currentColor’ keyword is set on the ‘color’ property itself, it is treated as ‘color: inherit’. elementStyles.Put(CssConstants.COLOR, CssConstants.INHERIT); } String parentFontSizeStr = null; if (element.ParentNode() is IStylesContainer) { IStylesContainer parentNode = (IStylesContainer)element.ParentNode(); IDictionary <String, String> parentStyles = parentNode.GetStyles(); if (parentStyles == null && !(element.ParentNode() is IDocumentNode)) { ILog logger = LogManager.GetLogger(typeof(iText.Html2pdf.Css.Resolve.DefaultCssResolver)); logger.Error(iText.Html2pdf.LogMessageConstant.ERROR_RESOLVING_PARENT_STYLES); } if (parentStyles != null) { ICollection <IStyleInheritance> inheritanceRules = new HashSet <IStyleInheritance>(); inheritanceRules.Add(cssInheritance); foreach (KeyValuePair <String, String> entry in parentStyles) { elementStyles = StyleUtil.MergeParentStyleDeclaration(elementStyles, entry.Key, entry.Value, parentStyles. Get(CommonCssConstants.FONT_SIZE), inheritanceRules); } parentFontSizeStr = parentStyles.Get(CssConstants.FONT_SIZE); } } String elementFontSize = elementStyles.Get(CssConstants.FONT_SIZE); if (CssUtils.IsRelativeValue(elementFontSize) || CssConstants.LARGER.Equals(elementFontSize) || CssConstants .SMALLER.Equals(elementFontSize)) { float baseFontSize; if (CssUtils.IsRemValue(elementFontSize)) { baseFontSize = context.GetRootFontSize(); } else { if (parentFontSizeStr == null) { baseFontSize = CssUtils.ParseAbsoluteFontSize(CssDefaults.GetDefaultValue(CssConstants.FONT_SIZE)); } else { baseFontSize = CssUtils.ParseAbsoluteLength(parentFontSizeStr); } } float absoluteFontSize = CssUtils.ParseRelativeFontSize(elementFontSize, baseFontSize); // Format to 4 decimal places to prevent differences between Java and C# elementStyles.Put(CssConstants.FONT_SIZE, DecimalFormatUtil.FormatNumber(absoluteFontSize, "0.####") + CssConstants .PT); } else { elementStyles.Put(CssConstants.FONT_SIZE, Convert.ToString(CssUtils.ParseAbsoluteFontSize(elementFontSize) , System.Globalization.CultureInfo.InvariantCulture) + CssConstants.PT); } // Update root font size if (element is IElementNode && TagConstants.HTML.Equals(((IElementNode)element).Name())) { context.SetRootFontSize(elementStyles.Get(CssConstants.FONT_SIZE)); } ICollection <String> keys = new HashSet <String>(); foreach (KeyValuePair <String, String> entry in elementStyles) { if (CssConstants.INITIAL.Equals(entry.Value) || CssConstants.INHERIT.Equals(entry.Value)) { // if "inherit" is not resolved till now, parents don't have it keys.Add(entry.Key); } } foreach (String key in keys) { elementStyles.Put(key, CssDefaults.GetDefaultValue(key)); } // This is needed for correct resolving of content property, so doing it right here CounterProcessorUtil.ProcessCounters(elementStyles, context, element); ResolveContentProperty(elementStyles, element, context); return(elementStyles); }
/// <summary>Writes cross reference table and trailer to PDF.</summary> /// <exception cref="System.IO.IOException"/> /// <exception cref="iText.Kernel.PdfException"/> protected internal virtual void WriteXrefTableAndTrailer(PdfDocument document, PdfObject fileId, PdfObject crypto) { PdfWriter writer = document.GetWriter(); if (document.IsAppendMode()) { // Increment generation number for all freed references. foreach (int?objNr in freeReferences) { xref[(int)objNr].genNr++; } } else { foreach (int?objNr in freeReferences) { xref[(int)objNr] = null; } } freeReferences.Clear(); for (int i = count; i > 0; --i) { PdfIndirectReference lastRef = xref[i]; if (lastRef == null || (lastRef.IsFree() && lastRef.GetGenNumber() == 0) || (!lastRef.CheckState(PdfObject .FLUSHED) && !(document.properties.appendMode && !lastRef.CheckState(PdfObject.MODIFIED)))) { --count; } else { break; } } IList <int> sections = new List <int>(); int first = 0; int len = 1; if (document.IsAppendMode()) { first = 1; len = 0; } for (int i_1 = 1; i_1 < Size(); i_1++) { PdfIndirectReference reference = xref[i_1]; if (reference != null) { if ((document.properties.appendMode && !reference.CheckState(PdfObject.MODIFIED)) || (reference.IsFree() && reference.GetGenNumber() == 0) || (!reference.CheckState(PdfObject.FLUSHED))) { reference = null; } } if (reference == null) { if (len > 0) { sections.Add(first); sections.Add(len); } len = 0; } else { if (len > 0) { len++; } else { first = i_1; len = 1; } } } if (len > 0) { sections.Add(first); sections.Add(len); } if (document.properties.appendMode && sections.Count == 0) { // no modifications. xref = null; return; } long startxref = writer.GetCurrentPos(); if (writer.IsFullCompression()) { PdfStream xrefStream = ((PdfStream) new PdfStream().MakeIndirect(document)); xrefStream.MakeIndirect(document); xrefStream.Put(PdfName.Type, PdfName.XRef); xrefStream.Put(PdfName.ID, fileId); if (crypto != null) { xrefStream.Put(PdfName.Encrypt, crypto); } xrefStream.Put(PdfName.Size, new PdfNumber(this.Size())); List <PdfObject> tmpArray = new List <PdfObject>(3); tmpArray.Add(new PdfNumber(1)); tmpArray.Add(new PdfNumber(4)); tmpArray.Add(new PdfNumber(2)); xrefStream.Put(PdfName.W, new PdfArray(tmpArray)); xrefStream.Put(PdfName.Info, document.GetDocumentInfo().GetPdfObject()); xrefStream.Put(PdfName.Root, document.GetCatalog().GetPdfObject()); PdfArray index = new PdfArray(); foreach (int?section in sections) { index.Add(new PdfNumber((int)section)); } if (document.properties.appendMode) { PdfNumber lastXref = new PdfNumber(document.reader.GetLastXref()); xrefStream.Put(PdfName.Prev, lastXref); } xrefStream.Put(PdfName.Index, index); iText.Kernel.Pdf.PdfXrefTable xrefTable = document.GetXref(); for (int k = 0; k < sections.Count; k += 2) { first = (int)sections[k]; len = (int)sections[k + 1]; for (int i_2 = first; i_2 < first + len; i_2++) { PdfIndirectReference reference = xrefTable.Get(i_2); if (reference == null) { continue; } if (reference.IsFree()) { xrefStream.GetOutputStream().Write(0); //NOTE The object number of the next free object should be at this position due to spec. xrefStream.GetOutputStream().Write(IntToBytes(0)); xrefStream.GetOutputStream().Write(ShortToBytes(reference.GetGenNumber())); } else { if (reference.GetObjStreamNumber() == 0) { xrefStream.GetOutputStream().Write(1); System.Diagnostics.Debug.Assert(reference.GetOffset() < int.MaxValue); xrefStream.GetOutputStream().Write(IntToBytes((int)reference.GetOffset())); xrefStream.GetOutputStream().Write(ShortToBytes(reference.GetGenNumber())); } else { xrefStream.GetOutputStream().Write(2); xrefStream.GetOutputStream().Write(IntToBytes(reference.GetObjStreamNumber())); xrefStream.GetOutputStream().Write(ShortToBytes(reference.GetIndex())); } } } } xrefStream.Flush(); } else { writer.WriteString("xref\n"); iText.Kernel.Pdf.PdfXrefTable xrefTable = document.GetXref(); for (int k = 0; k < sections.Count; k += 2) { first = (int)sections[k]; len = (int)sections[k + 1]; writer.WriteInteger(first).WriteSpace().WriteInteger(len).WriteByte((byte)'\n'); for (int i_2 = first; i_2 < first + len; i_2++) { PdfIndirectReference reference = xrefTable.Get(i_2); writer.WriteString(DecimalFormatUtil.FormatNumber(reference.GetOffset(), objectOffsetFormatter)).WriteSpace ().WriteString(DecimalFormatUtil.FormatNumber(reference.GetGenNumber(), objectGenerationFormatter)).WriteSpace (); if (reference.IsFree()) { writer.WriteBytes(freeXRefEntry); } else { writer.WriteBytes(inUseXRefEntry); } } } PdfDictionary trailer = document.GetTrailer(); // Remove all unused keys in case stamp mode in case original file has full compression, but destination file has not. trailer.Remove(PdfName.W); trailer.Remove(PdfName.Index); trailer.Remove(PdfName.Type); trailer.Remove(PdfName.Length); trailer.Put(PdfName.Size, new PdfNumber(this.Size())); trailer.Put(PdfName.ID, fileId); if (crypto != null) { trailer.Put(PdfName.Encrypt, crypto); } writer.WriteString("trailer\n"); if (document.properties.appendMode) { PdfNumber lastXref = new PdfNumber(document.reader.GetLastXref()); trailer.Put(PdfName.Prev, lastXref); } writer.Write(document.GetTrailer()); writer.Write('\n'); } WriteKeyInfo(writer); writer.WriteString("startxref\n").WriteLong(startxref).WriteString("\n%%EOF\n"); xref = null; }
internal static byte[] GetIsoBytes(double d, ByteBuffer buffer, bool highPrecision) { if (highPrecision) { if (Math.Abs(d) < 0.000001) { if (buffer != null) { buffer.Prepend(zero); return(null); } else { return(zero); } } byte[] result = DecimalFormatUtil.FormatNumber(d, "0.######").GetBytes(iText.IO.Util.EncodingUtil.ISO_8859_1 ); if (buffer != null) { buffer.Prepend(result); return(null); } else { return(result); } } bool negative = false; if (Math.Abs(d) < 0.000015) { if (buffer != null) { buffer.Prepend(zero); return(null); } else { return(zero); } } ByteBuffer buf; if (d < 0) { negative = true; d = -d; } if (d < 1.0) { d += 0.000005; if (d >= 1) { byte[] result; if (negative) { result = negOne; } else { result = one; } if (buffer != null) { buffer.Prepend(result); return(null); } else { return(result); } } int v = (int)(d * 100000); int len = 5; for (; len > 0; len--) { if (v % 10 != 0) { break; } v /= 10; } buf = buffer != null ? buffer : new ByteBuffer(negative ? len + 3 : len + 2); for (int i = 0; i < len; i++) { buf.Prepend(bytes[v % 10]); v /= 10; } buf.Prepend((byte)'.').Prepend((byte)'0'); if (negative) { buf.Prepend((byte)'-'); } } else { if (d <= 32767) { d += 0.005; int v = (int)(d * 100); int intLen; if (v >= 1000000) { intLen = 5; } else { if (v >= 100000) { intLen = 4; } else { if (v >= 10000) { intLen = 3; } else { if (v >= 1000) { intLen = 2; } else { intLen = 1; } } } } int fracLen = 0; if (v % 100 != 0) { fracLen = 2; //fracLen include '.' if (v % 10 != 0) { fracLen++; } else { v /= 10; } } else { v /= 100; } buf = buffer != null ? buffer : new ByteBuffer(intLen + fracLen + (negative ? 1 : 0)); for (int i = 0; i < fracLen - 1; i++) { //-1 because fracLen include '.' buf.Prepend(bytes[v % 10]); v /= 10; } if (fracLen > 0) { buf.Prepend((byte)'.'); } for (int i = 0; i < intLen; i++) { buf.Prepend(bytes[v % 10]); v /= 10; } if (negative) { buf.Prepend((byte)'-'); } } else { d += 0.5; long v; if (d > long.MaxValue) { //by default cast logic do the same, but not in .NET v = long.MaxValue; } else { v = (long)d; } int intLen = LongSize(v); buf = buffer == null ? new ByteBuffer(intLen + (negative ? 1 : 0)) : buffer; for (int i = 0; i < intLen; i++) { buf.Prepend(bytes[(int)(v % 10)]); v /= 10; } if (negative) { buf.Prepend((byte)'-'); } } } return(buffer == null?buf.GetInternalBuffer() : null); }