//We won't know the actual number of characters until
//we process the byte data(could be two bytes each) but
//it won't ever be more than string.length*2(there are some cases
//were a single byte will result in two output characters "fi"
final PDFont font = graphicsState.getTextState().getFont();
// all fonts are providing the width/height of a character in thousandths of a unit of text space
float fontMatrixXScaling = 1/1000f;
float fontMatrixYScaling = 1/1000f;
float glyphSpaceToTextSpaceFactor = 1/1000f;
// expect Type3 fonts, those are providing the width of a character in glyph space units
if (font instanceof PDType3Font)
{
PDMatrix fontMatrix = font.getFontMatrix();
fontMatrixXScaling = fontMatrix.getValue(0, 0);
fontMatrixYScaling = fontMatrix.getValue(1, 1);
//This will typically be 1000 but in the case of a type3 font
//this might be a different number
glyphSpaceToTextSpaceFactor = 1f/fontMatrix.getValue( 0, 0 );
}
float spaceWidthText=0;
try
{
// to avoid crash as described in PDFBOX-614
// lets see what the space displacement should be
spaceWidthText = (font.getSpaceWidth()*glyphSpaceToTextSpaceFactor);
}
catch (Throwable exception)
{
LOG.warn( exception, exception);
}
if( spaceWidthText == 0 )
{
spaceWidthText = (font.getAverageFontWidth()*glyphSpaceToTextSpaceFactor);
//The average space width appears to be higher than necessary
//so lets make it a little bit smaller.
spaceWidthText *= .80f;
}
float maxVerticalDisplacementText = 0;
Matrix textStateParameters = new Matrix();
textStateParameters.setValue(0,0, fontSizeText*horizontalScalingText);
textStateParameters.setValue(1,1, fontSizeText);
textStateParameters.setValue(2,1, riseText);
int pageRotation = page.findRotation();
float pageHeight = page.findCropBox().getHeight();
float pageWidth = page.findCropBox().getWidth();
Matrix ctm = getGraphicsState().getCurrentTransformationMatrix();
Matrix textXctm = new Matrix();
Matrix textMatrixEnd = new Matrix();
Matrix td = new Matrix();
Matrix tempMatrix = new Matrix();
int codeLength = 1;
for( int i=0; i<string.length; i+=codeLength)
{
// Decode the value to a Unicode character
codeLength = 1;
String c = font.encode( string, i, codeLength );
int[] codePoints = null;
if( c == null && i+1<string.length)
{
//maybe a multibyte encoding
codeLength++;
c = font.encode( string, i, codeLength );
codePoints = new int[] {font.getCodeFromArray(string, i, codeLength)};
}
// the space width has to be transformed into display units
float spaceWidthDisp = spaceWidthText * fontSizeText * horizontalScalingText
* textMatrix.getValue(0, 0) * ctm.getValue(0, 0);
//todo, handle horizontal displacement
// get the width and height of this character in text units
float characterHorizontalDisplacementText = font.getFontWidth( string, i, codeLength );
float characterVerticalDisplacementText = font.getFontHeight( string, i, codeLength );
// multiply the width/height with the scaling factor
characterHorizontalDisplacementText = characterHorizontalDisplacementText * fontMatrixXScaling;
characterVerticalDisplacementText = characterVerticalDisplacementText * fontMatrixYScaling;