protected float getDescender() { float sizeCoef = size / FontProgram.UNITS_NORMALIZATION; return font.getFontProgram().getFontMetrics().getTypoDescender() * sizeCoef; } }
private static FontProgramDescriptor fetchDescriptorFromFontProgram(FontProgram fontProgram) { return new FontProgramDescriptor(fontProgram.getFontNames(), fontProgram.getFontMetrics()); } }
private static FontProgramDescriptor fetchDescriptorFromFontProgram(FontProgram fontProgram) { return new FontProgramDescriptor(fontProgram.getFontNames(), fontProgram.getFontMetrics()); } }
/** * Gets the ascent of a char code in normalized 1000 units. The ascent will always be * greater than or equal to zero even if all the characters have a lower ascent. * * @param unicode the char code to get the ascent of * @param fontSize the font size * @return the ascent in points */ public int getAscent(int unicode, float fontSize) { int max = 0; Glyph glyph = getGlyph(unicode); if (glyph == null) { return 0; } int[] bbox = glyph.getBbox(); if (bbox != null && bbox[3] > max) { max = bbox[3]; } else if (bbox == null && getFontProgram().getFontMetrics().getTypoAscender() > max) { max = getFontProgram().getFontMetrics().getTypoAscender(); } return (int) (max * fontSize / FontProgram.UNITS_NORMALIZATION); }
private float approximateFontSizeToFitBBox(PdfFont localFont, Rectangle bBox, String value) { float fs; float height = bBox.getHeight() - borderWidth * 2; int[] fontBbox = localFont.getFontProgram().getFontMetrics().getBbox(); fs = height / (fontBbox[2] - fontBbox[1]) * FontProgram.UNITS_NORMALIZATION; float baseWidth = localFont.getWidth(value, 1); if (baseWidth != 0) { float availableWidth = Math.max(bBox.getWidth() - borderWidth * 2, 0); // This constant is taken based on what was the resultant padding in previous version of this algorithm in case border width was zero. float absMaxPadding = 4f; // relative value is quite big in order to preserve visible padding on small field sizes. This constant is taken arbitrary, based on visual similarity to Acrobat behaviour. float relativePaddingForSmallSizes = 0.15f; // with current constants, if availableWidth is less than ~26 points, padding will be made relative if (availableWidth * relativePaddingForSmallSizes < absMaxPadding) { availableWidth -= availableWidth * relativePaddingForSmallSizes * 2; } else { availableWidth -= absMaxPadding * 2; } fs = Math.min(fs, availableWidth / baseWidth); } return fs; }
/** * Gets the descent of a char code in points. The descent will always be * less than or equal to zero even if all the characters have an higher descent. * * @param unicode the char code to get the descent of * @param fontSize the font size * @return the descent in points */ public int getDescent(int unicode, float fontSize) { int min = 0; Glyph glyph = getGlyph(unicode); if (glyph == null) { return 0; } int[] bbox = glyph.getBbox(); if (bbox != null && bbox[1] < min) { min = bbox[1]; } else if (bbox == null && getFontProgram().getFontMetrics().getTypoDescender() < min) { min = getFontProgram().getFontMetrics().getTypoDescender(); } return (int) (min * fontSize / FontProgram.UNITS_NORMALIZATION); }
private float approximateFontSizeToFitBBox(PdfFont localFont, Rectangle bBox, String value) { float fs; float height = bBox.getHeight() - borderWidth * 2; int[] fontBbox = localFont.getFontProgram().getFontMetrics().getBbox(); fs = height / (fontBbox[2] - fontBbox[1]) * FontProgram.UNITS_NORMALIZATION; float baseWidth = localFont.getWidth(value, 1); if (baseWidth != 0) { float availableWidth = Math.max(bBox.getWidth() - borderWidth * 2, 0); // This constant is taken based on what was the resultant padding in previous version of this algorithm in case border width was zero. float absMaxPadding = 4f; // relative value is quite big in order to preserve visible padding on small field sizes. This constant is taken arbitrary, based on visual similarity to Acrobat behaviour. float relativePaddingForSmallSizes = 0.15f; // with current constants, if availableWidth is less than ~26 points, padding will be made relative if (availableWidth * relativePaddingForSmallSizes < absMaxPadding) { availableWidth -= availableWidth * relativePaddingForSmallSizes * 2; } else { availableWidth -= absMaxPadding * 2; } fs = Math.min(fs, availableWidth / baseWidth); } return fs; }
/** * Gets the descent of a {@code String} in points. The descent will always be * less than or equal to zero even if all the characters have an higher descent. * * @param text the {@code String} to get the descent of * @param fontSize the font size * @return the descent in points */ public int getDescent(String text, float fontSize) { int min = 0; for (int k = 0; k < text.length(); ++k) { int ch; if (TextUtil.isSurrogatePair(text, k)) { ch = TextUtil.convertToUtf32(text, k); k++; } else { ch = text.charAt(k); } Glyph glyph = getGlyph(ch); if (glyph != null) { int[] bbox = glyph.getBbox(); if (bbox != null && bbox[1] < min) { min = bbox[1]; } else if (bbox == null && getFontProgram().getFontMetrics().getTypoDescender() < min) { min = getFontProgram().getFontMetrics().getTypoDescender(); } } } return (int) (min * fontSize / FontProgram.UNITS_NORMALIZATION); }
/** * Gets the ascent of a {@code String} in points. The ascent will always be * greater than or equal to zero even if all the characters have a lower ascent. * * @param text the {@code String} to get the ascent of * @param fontSize the font size * @return the ascent in points */ public int getAscent(String text, float fontSize) { int max = 0; for (int k = 0; k < text.length(); ++k) { int ch; if (TextUtil.isSurrogatePair(text, k)) { ch = TextUtil.convertToUtf32(text, k); k++; } else { ch = text.charAt(k); } Glyph glyph = getGlyph(ch); if (glyph != null) { int[] bbox = glyph.getBbox(); if (bbox != null && bbox[3] > max) { max = bbox[3]; } else if (bbox == null && getFontProgram().getFontMetrics().getTypoAscender() > max) { max = getFontProgram().getFontMetrics().getTypoAscender(); } } } return (int) (max * fontSize / FontProgram.UNITS_NORMALIZATION); }
private float[] getAscentDescent() { checkGraphicsState(); float ascent = gs.getFont().getFontProgram().getFontMetrics().getTypoAscender(); float descent = gs.getFont().getFontProgram().getFontMetrics().getTypoDescender(); // If descent is positive, we consider it a bug and fix it if (descent > 0) { descent = -descent; } float scale = ascent - descent < 700 ? ascent - descent : 1000; descent = descent / scale * gs.getFontSize(); ascent = ascent / scale * gs.getFontSize(); return new float[]{ascent, descent}; } }
fontProgram.getFontMetrics().setBbox(llx, lly, urx, ury); } else { int[] bbox = fontProgram.getFontMetrics().getBbox(); int newLlx = Math.min(bbox[0], llx); int newLly = Math.min(bbox[1], lly); int newUrx = Math.max(bbox[2], urx); int newUry = Math.max(bbox[3], ury); fontProgram.getFontMetrics().setBbox(newLlx, newLly, newUrx, newUry);
@Override protected PdfDictionary getFontDescriptor(String fontName) { PdfDictionary fontDescriptor = new PdfDictionary(); makeObjectIndirect(fontDescriptor); fontDescriptor.put(PdfName.Type, PdfName.FontDescriptor); fontDescriptor.put(PdfName.FontName, new PdfName(fontName)); fontDescriptor.put(PdfName.FontBBox, new PdfArray(getFontProgram().getFontMetrics().getBbox())); fontDescriptor.put(PdfName.Ascent, new PdfNumber(getFontProgram().getFontMetrics().getTypoAscender())); fontDescriptor.put(PdfName.Descent, new PdfNumber(getFontProgram().getFontMetrics().getTypoDescender())); fontDescriptor.put(PdfName.CapHeight, new PdfNumber(getFontProgram().getFontMetrics().getCapHeight())); fontDescriptor.put(PdfName.ItalicAngle, new PdfNumber(getFontProgram().getFontMetrics().getItalicAngle())); fontDescriptor.put(PdfName.StemV, new PdfNumber(getFontProgram().getFontMetrics().getStemV())); fontDescriptor.put(PdfName.Flags, new PdfNumber(getFontProgram().getPdfFontFlags())); if (fontProgram.getFontIdentification().getPanose() != null) { PdfDictionary styleDictionary = new PdfDictionary(); styleDictionary.put(PdfName.Panose, new PdfString(fontProgram.getFontIdentification().getPanose()).setHexWriting(true)); fontDescriptor.put(PdfName.Style, styleDictionary); } return fontDescriptor; }
static float[] calculateAscenderDescender(PdfFont font) { FontMetrics fontMetrics = font.getFontProgram().getFontMetrics(); float ascender; float descender; if (fontMetrics.getWinAscender() == 0 || fontMetrics.getWinDescender() == 0 || fontMetrics.getTypoAscender() == fontMetrics.getWinAscender() && fontMetrics.getTypoDescender() == fontMetrics.getWinDescender()) { ascender = fontMetrics.getTypoAscender() * TYPO_ASCENDER_SCALE_COEFF; descender = fontMetrics.getTypoDescender() * TYPO_ASCENDER_SCALE_COEFF; } else { ascender = fontMetrics.getWinAscender(); descender = fontMetrics.getWinDescender(); } return new float[]{ascender, descender}; }
static float[] calculateAscenderDescender(PdfFont font) { FontMetrics fontMetrics = font.getFontProgram().getFontMetrics(); float ascender; float descender; if (fontMetrics.getWinAscender() == 0 || fontMetrics.getWinDescender() == 0 || fontMetrics.getTypoAscender() == fontMetrics.getWinAscender() && fontMetrics.getTypoDescender() == fontMetrics.getWinDescender()) { ascender = fontMetrics.getTypoAscender() * TYPO_ASCENDER_SCALE_COEFF; descender = fontMetrics.getTypoDescender() * TYPO_ASCENDER_SCALE_COEFF; } else { ascender = fontMetrics.getWinAscender(); descender = fontMetrics.getWinDescender(); } return new float[]{ascender, descender}; }
private static GlyphLine replaceSpecialWhitespaceGlyphs(GlyphLine line, PdfFont font) { if (null != line) { Glyph space = font.getGlyph('\u0020'); Glyph glyph; for (int i = 0; i < line.size(); i++) { glyph = line.get(i); Integer xAdvance = getSpecialWhitespaceXAdvance(glyph, space, font.getFontProgram().getFontMetrics().isFixedPitch()); if (xAdvance != null) { Glyph newGlyph = new Glyph(space, glyph.getUnicode()); assert xAdvance <= Short.MAX_VALUE && xAdvance >= Short.MIN_VALUE; newGlyph.setXAdvance((short) (int) xAdvance); line.set(i, newGlyph); } } } return line; }
private static GlyphLine replaceSpecialWhitespaceGlyphs(GlyphLine line, PdfFont font) { if (null != line) { Glyph space = font.getGlyph('\u0020'); Glyph glyph; for (int i = 0; i < line.size(); i++) { glyph = line.get(i); Integer xAdvance = getSpecialWhitespaceXAdvance(glyph, space, font.getFontProgram().getFontMetrics().isFixedPitch()); if (xAdvance != null) { Glyph newGlyph = new Glyph(space, glyph.getUnicode()); assert xAdvance <= Short.MAX_VALUE && xAdvance >= Short.MIN_VALUE; newGlyph.setXAdvance((short) (int) xAdvance); line.set(i, newGlyph); } } } return line; }
@Override protected PdfDictionary getFontDescriptor(String fontName) { if (fontName != null && fontName.length() > 0) { PdfDictionary fontDescriptor = new PdfDictionary(); makeObjectIndirect(fontDescriptor); fontDescriptor.put(PdfName.Type, PdfName.FontDescriptor); FontMetrics fontMetrics = fontProgram.getFontMetrics(); fontDescriptor.put(PdfName.CapHeight, new PdfNumber(fontMetrics.getCapHeight())); fontDescriptor.put(PdfName.ItalicAngle, new PdfNumber(fontMetrics.getItalicAngle())); FontNames fontNames = fontProgram.getFontNames(); fontDescriptor.put(PdfName.FontWeight, new PdfNumber(fontNames.getFontWeight())); fontDescriptor.put(PdfName.FontName, new PdfName(fontName)); if (fontNames.getFamilyName() != null && fontNames.getFamilyName().length > 0 && fontNames.getFamilyName()[0].length >= 4) { fontDescriptor.put(PdfName.FontFamily, new PdfString(fontNames.getFamilyName()[0][3])); } int flags = fontProgram.getPdfFontFlags(); flags &= ~(FontDescriptorFlags.Symbolic | FontDescriptorFlags.Nonsymbolic); // reset both flags flags |= fontEncoding.isFontSpecific() ? // set based on font encoding FontDescriptorFlags.Symbolic : FontDescriptorFlags.Nonsymbolic; fontDescriptor.put(PdfName.Flags, new PdfNumber(flags)); return fontDescriptor; } else if (getPdfObject().getIndirectReference() != null && getPdfObject().getIndirectReference().getDocument().isTagged()) { Logger logger = LoggerFactory.getLogger(PdfType3Font.class); logger.warn(LogMessageConstant.TYPE3_FONT_ISSUE_TAGGED_PDF); } return null; }
if (getPdfObject().containsKey(PdfName.FontBBox)) { PdfArray fontBBox = getPdfObject().getAsArray(PdfName.FontBBox); fontProgram.getFontMetrics().setBbox(fontBBox.getAsNumber(0).intValue(), fontBBox.getAsNumber(1).intValue(), fontBBox.getAsNumber(2).intValue(), fontBBox.getAsNumber(3).intValue()); } else { fontProgram.getFontMetrics().setBbox(0, 0, 0, 0);
@Override public void flush() { if (isFlushed()) return; ensureUnderlyingObjectHasIndirectReference(); if (((Type3Font) getFontProgram()).getNumberOfGlyphs() < 1) { throw new PdfException("No glyphs defined for type3 font."); } PdfDictionary charProcs = new PdfDictionary(); for (int i = 0; i < 256; i++) { if (fontEncoding.canDecode(i)) { Type3Glyph glyph = getType3Glyph(fontEncoding.getUnicode(i)); if (glyph != null) { charProcs.put(new PdfName(fontEncoding.getDifference(i)), glyph.getContentStream()); glyph.getContentStream().flush(); } } } getPdfObject().put(PdfName.CharProcs, charProcs); getPdfObject().put(PdfName.FontMatrix, new PdfArray(getFontMatrix())); getPdfObject().put(PdfName.FontBBox, new PdfArray(fontProgram.getFontMetrics().getBbox())); String fontName = fontProgram.getFontNames().getFontName(); super.flushFontData(fontName, PdfName.Type3); //BaseFont is not listed as key in Type 3 font specification. getPdfObject().remove(PdfName.BaseFont); super.flush(); }
protected PdfDictionary getFontDescriptor(String fontName) { assert fontName != null && fontName.length() > 0; FontMetrics fontMetrics = fontProgram.getFontMetrics(); FontNames fontNames = fontProgram.getFontNames(); PdfDictionary fontDescriptor = new PdfDictionary();