final long posX = renderableText.getX();
final long posY = renderableText.getY();
final float x1 = (float) (StrictGeomUtility.toExternalValue(posX));
final PdfContentByte cb;
PdfTextSpec textSpec = (PdfTextSpec) getTextSpec();
if (textSpec == null)
{
final StyleSheet layoutContext = renderableText.getStyleSheet();
// The code below may be weird, but at least it is predictable weird.
final String fontName = getMetaData().getNormalizedFontFamilyName
((String) layoutContext.getStyleProperty(TextStyleKeys.FONT));
final String encoding = (String) layoutContext.getStyleProperty(TextStyleKeys.FONTENCODING);
final float fontSize = (float) layoutContext.getDoubleStyleProperty(TextStyleKeys.FONTSIZE, 10);
final boolean embed = globalEmbed || layoutContext.getBooleanStyleProperty(TextStyleKeys.EMBEDDED_FONT);
final boolean bold = layoutContext.getBooleanStyleProperty(TextStyleKeys.BOLD);
final boolean italics = layoutContext.getBooleanStyleProperty(TextStyleKeys.ITALIC);
final BaseFontFontMetrics fontMetrics = getMetaData().getBaseFontFontMetrics
(fontName, fontSize, bold, italics, encoding, embed, false);
final PdfGraphics2D g2 = (PdfGraphics2D) getGraphics();
final Color cssColor = (Color) layoutContext.getStyleProperty(ElementStyleKeys.PAINT);
g2.setPaint(cssColor);
g2.setFillPaint();
g2.setStrokePaint();
//final float translateY = (float) affineTransform.getTranslateY();
cb = g2.getRawContentByte();
textSpec = new PdfTextSpec(layoutContext, getMetaData(), g2, fontMetrics, cb);
setTextSpec(textSpec);
cb.beginText();
cb.setFontAndSize(fontMetrics.getBaseFont(), fontSize);
}
else
{
cb = textSpec.getContentByte();
}
final BaseFontFontMetrics baseFontRecord = textSpec.getFontMetrics();
final BaseFont baseFont = baseFontRecord.getBaseFont();
final float ascent = baseFont.getFontDescriptor(BaseFont.BBOXURY, textSpec.getFontSize());
final float y2 = (float) (StrictGeomUtility.toExternalValue(posY) + ascent);
final float y = globalHeight - y2;
final AffineTransform affineTransform = textSpec.getGraphics().getTransform();
final float translateX = (float) affineTransform.getTranslateX();
final FontNativeContext nativeContext = baseFontRecord.getNativeContext();
if (baseFontRecord.isTrueTypeFont() && textSpec.isBold() && nativeContext.isNativeBold() == false)
{
final float strokeWidth = textSpec.getFontSize() / 30.0f; // right from iText ...
if (strokeWidth == 1)
{
cb.setTextRenderingMode(PdfContentByte.TEXT_RENDER_MODE_FILL);
}
else
{
cb.setTextRenderingMode(PdfContentByte.TEXT_RENDER_MODE_FILL_STROKE);
cb.setLineWidth(strokeWidth);
}
}
else
{
cb.setTextRenderingMode(PdfContentByte.TEXT_RENDER_MODE_FILL);
}
// if the font does not declare to be italics already, emulate it ..
if (baseFontRecord.isTrueTypeFont() && textSpec.isItalics() && nativeContext.isNativeItalics() == false)
{
final float italicAngle =
baseFont.getFontDescriptor(BaseFont.ITALICANGLE, textSpec.getFontSize());
if (italicAngle == 0)
{
// italics requested, but the font itself does not supply italics gylphs.
cb.setTextMatrix(1, 0, PdfLogicalPageDrawable.ITALIC_ANGLE, 1, x1 + translateX, y);
}
else
{
cb.setTextMatrix(x1 + translateX, y);
}
}
else
{
cb.setTextMatrix(x1 + translateX, y);
}
final OutputProcessorMetaData metaData = getMetaData();
final GlyphList gs = renderableText.getGlyphs();
final int offset = renderableText.getOffset();
final CodePointBuffer codePointBuffer = getCodePointBuffer();
if (metaData.isFeatureSupported(OutputProcessorFeature.FAST_FONTRENDERING) &&
isNormalTextSpacing(renderableText))
{
final int maxLength = renderableText.computeMaximumTextSize(contentX2);
final String text = gs.getText(renderableText.getOffset(), maxLength, codePointBuffer);
cb.showText(text);
}
else
{
final PdfTextArray textArray = new PdfTextArray();
final StringBuilder buffer = new StringBuilder(gs.getSize());
final int maxPos = offset + renderableText.computeMaximumTextSize(contentX2);
for (int i = offset; i < maxPos; i++)
{
final Glyph g = gs.getGlyph(i);
final Spacing spacing = g.getSpacing();
if (i != offset)
{
final float optimum = (float) StrictGeomUtility.toFontMetricsValue(spacing.getMinimum());
if (optimum != 0)
{
textArray.add(buffer.toString());
textArray.add(-optimum / textSpec.getFontSize());
buffer.setLength(0);
}
}
final String text = gs.getGlyphAsString(i, codePointBuffer);
buffer.append(text);
}
if (buffer.length() > 0)
{
textArray.add(buffer.toString());
}
cb.showText(textArray);
}
}