/** * We get into this method when the current chunk is not visible. * Here we are calculating a piece of the Tj coefficient for a previous visible chunk. * For details see PDF spec., Text Space Details, formula for "tx" coefficient * and TextRenderInfo class (getUnscaledBaseline) */ private float GetUnscaledTextChunkWidth(PdfCleanUpContentChunk.Text chunk, float characterSpacing, float wordSpacing, float fontSize, float horizontalScaling) { // We should multiply by 100 because iText stores horizontal scaling as the value in [0, 1] interval; // also we need to add character and word spaces because TextRenderInfo class truncates them from the end of the string // (single character string in our case is also truncated) float scaledChunkWidth = (chunk.EndX - chunk.StartX) * 100f + (characterSpacing + (IsSpace(chunk) ? wordSpacing : 0)) * horizontalScaling * 100f; return(-scaledChunkWidth * 1000f / (horizontalScaling * 100f * fontSize)); }
private bool IsSpace(PdfCleanUpContentChunk.Text chunk) { return(chunk.GetText().ToUnicodeString() == " "); }
/** * Writes parts of text which are visible into a content stream. */ private void WriteTextChunks(IDictionary <int, float> structuredTJoperands, IList <PdfCleanUpContentChunk> chunks, PdfContentByte canvas, float characterSpacing, float wordSpacing, float fontSize, float horizontalScaling) { canvas.SetCharacterSpacing(0); canvas.SetWordSpacing(0); canvas.InternalBuffer.Append((byte)'['); float convertedCharacterSpacing = -characterSpacing * 1000f / fontSize; float convertedWordSpacing = -wordSpacing * 1000f / fontSize; float shift = structuredTJoperands != null ? structuredTJoperands[0] : 0; PdfCleanUpContentChunk.Text prevChunk = null; foreach (PdfCleanUpContentChunk chunk in chunks) { PdfCleanUpContentChunk.Text textChunk = (PdfCleanUpContentChunk.Text)chunk; if (prevChunk != null && prevChunk.NumOfStrTextBelongsTo != textChunk.NumOfStrTextBelongsTo && structuredTJoperands != null) { shift += structuredTJoperands[prevChunk.NumOfStrTextBelongsTo]; } if (textChunk.Visible) { if (Util.Compare(shift, 0.0f) != 0 && Util.Compare(shift, -0.0f) != 0) { canvas.InternalBuffer.Append(shift).Append(' '); } textChunk.GetText().ToPdf(canvas.PdfWriter, canvas.InternalBuffer); canvas.InternalBuffer.Append(' '); shift = convertedCharacterSpacing + (IsSpace(textChunk) ? convertedWordSpacing : 0); } else { shift += GetUnscaledTextChunkWidth(textChunk, characterSpacing, wordSpacing, fontSize, horizontalScaling); } prevChunk = textChunk; } if (Util.Compare(shift, 0) != 0 && Util.Compare(shift, -0.0f) != 0) { canvas.InternalBuffer.Append(shift); } canvas.InternalBuffer.Append(TJ); if (Util.Compare(characterSpacing, 0) != 0 && Util.Compare(characterSpacing, -0.0f) != 0) { new PdfNumber(characterSpacing).ToPdf(canvas.PdfWriter, canvas.InternalBuffer); canvas.InternalBuffer.Append(Tc); } if (Util.Compare(wordSpacing, 0) != 0 && Util.Compare(wordSpacing, -0.0f) != 0) { new PdfNumber(wordSpacing).ToPdf(canvas.PdfWriter, canvas.InternalBuffer); canvas.InternalBuffer.Append(Tw); } }