Skip to content

Commit 0c7952a

Browse files
yulian-gaponenkoiText-CI
authored andcommitted
Set typo ascender/descender for type3 fonts based on font dictionary
Refactor type 3 fonts glyph space normalization. DEVSIX-5199 Autoported commit. Original commit hash: [c72ff11f4]
1 parent c68860f commit 0c7952a

File tree

14 files changed

+311
-104
lines changed

14 files changed

+311
-104
lines changed

itext.tests/itext.kernel.tests/itext/kernel/font/PdfType3FontTest.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,6 @@ public virtual void NoDifferenceTest() {
243243
}
244244

245245
[NUnit.Framework.Test]
246-
[LogMessage(iText.IO.LogMessageConstant.TYPE3_FONT_INITIALIZATION_ISSUE)]
247246
public virtual void MissingFontMatrixTest() {
248247
PdfDictionary dictionary = new PdfDictionary();
249248
dictionary.Put(PdfName.Widths, new PdfArray());
@@ -257,7 +256,6 @@ public virtual void MissingFontMatrixTest() {
257256
}
258257

259258
[NUnit.Framework.Test]
260-
[LogMessage(iText.IO.LogMessageConstant.TYPE3_FONT_INITIALIZATION_ISSUE)]
261259
public virtual void MissingWidthsTest() {
262260
PdfDictionary dictionary = new PdfDictionary();
263261
dictionary.Put(PdfName.FontMatrix, new PdfArray());

itext.tests/itext.kernel.tests/itext/kernel/pdf/canvas/parser/GlyphBboxCalculationTest.cs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,24 @@ public virtual void Type3FontsWithIdentityFontMatrixAndMultiplier() {
100100
, destinationFolder, "diff_"));
101101
}
102102

103+
[NUnit.Framework.Test]
104+
public virtual void Type3FontCustomFontMatrixAndFontBBoxTest() {
105+
String inputPdf = sourceFolder + "type3FontCustomFontMatrixAndFontBBox.pdf";
106+
// Resultant rectangle is expected to be a bounding box over the text on the page.
107+
Rectangle expectedRectangle = new Rectangle(10f, 97.84f, 14.400002f, 8.880005f);
108+
IList<Rectangle> actualRectangles;
109+
using (PdfDocument pdfDoc = new PdfDocument(new PdfReader(inputPdf))) {
110+
GlyphBboxCalculationTest.TextBBoxEventListener eventListener = new GlyphBboxCalculationTest.TextBBoxEventListener
111+
();
112+
PdfCanvasProcessor canvasProcessor = new PdfCanvasProcessor(eventListener);
113+
PdfPage page = pdfDoc.GetPage(1);
114+
canvasProcessor.ProcessPageContent(page);
115+
actualRectangles = eventListener.GetRectangles();
116+
}
117+
NUnit.Framework.Assert.AreEqual(1, actualRectangles.Count);
118+
NUnit.Framework.Assert.IsTrue(expectedRectangle.EqualsWithEpsilon(actualRectangles[0]));
119+
}
120+
103121
private class CharacterPositionEventListener : ITextExtractionStrategy {
104122
internal float glyphWidth;
105123

@@ -128,5 +146,30 @@ public virtual ICollection<EventType> GetSupportedEvents() {
128146
return new LinkedHashSet<EventType>(JavaCollectionsUtil.SingletonList(EventType.RENDER_TEXT));
129147
}
130148
}
149+
150+
private class TextBBoxEventListener : IEventListener {
151+
private readonly IList<Rectangle> rectangles = new List<Rectangle>();
152+
153+
public virtual IList<Rectangle> GetRectangles() {
154+
return rectangles;
155+
}
156+
157+
public virtual void EventOccurred(IEventData data, EventType type) {
158+
if (EventType.RENDER_TEXT.Equals(type)) {
159+
TextRenderInfo renderInfo = (TextRenderInfo)data;
160+
Vector startPoint = renderInfo.GetDescentLine().GetStartPoint();
161+
Vector endPoint = renderInfo.GetAscentLine().GetEndPoint();
162+
float x1 = Math.Min(startPoint.Get(0), endPoint.Get(0));
163+
float x2 = Math.Max(startPoint.Get(0), endPoint.Get(0));
164+
float y1 = Math.Min(startPoint.Get(1), endPoint.Get(1));
165+
float y2 = Math.Max(startPoint.Get(1), endPoint.Get(1));
166+
rectangles.Add(new Rectangle(x1, y1, x2 - x1, y2 - y1));
167+
}
168+
}
169+
170+
public virtual ICollection<EventType> GetSupportedEvents() {
171+
return null;
172+
}
173+
}
131174
}
132175
}

itext/itext.io/itext/io/font/FontMetrics.cs

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -136,14 +136,36 @@ public virtual int[] GetGlyphWidths() {
136136
return glyphWidths;
137137
}
138138

139+
/// <summary>Gets typo (a.k.a. sTypo or OS/2) vertical metric corresponding to ascender.</summary>
140+
/// <remarks>
141+
/// Gets typo (a.k.a. sTypo or OS/2) vertical metric corresponding to ascender.
142+
/// <para />
143+
/// Typo vertical metrics are the primary source for iText ascender/descender calculations.
144+
/// </remarks>
145+
/// <returns>typo ascender value in normalized 1000-units</returns>
139146
public virtual int GetTypoAscender() {
140147
return typoAscender;
141148
}
142149

150+
/// <summary>Gets typo (a.k.a. sTypo or OS/2) vertical metric corresponding to descender.</summary>
151+
/// <remarks>
152+
/// Gets typo (a.k.a. sTypo or OS/2) vertical metric corresponding to descender.
153+
/// <para />
154+
/// Typo vertical metrics are the primary source for iText ascender/descender calculations.
155+
/// </remarks>
156+
/// <returns>typo descender value in normalized 1000-units</returns>
143157
public virtual int GetTypoDescender() {
144158
return typoDescender;
145159
}
146160

161+
/// <summary>Gets the capital letters height.</summary>
162+
/// <remarks>
163+
/// Gets the capital letters height.
164+
/// <para />
165+
/// This property defines the vertical coordinate of the top of flat capital letters,
166+
/// measured from the baseline.
167+
/// </remarks>
168+
/// <returns>cap height in 1000-units</returns>
147169
public virtual int GetCapHeight() {
148170
return capHeight;
149171
}
@@ -255,14 +277,36 @@ protected internal virtual void SetGlyphWidths(int[] glyphWidths) {
255277
this.glyphWidths = glyphWidths;
256278
}
257279

280+
/// <summary>Sets typo (a.k.a. sTypo or OS/2) vertical metric corresponding to ascender.</summary>
281+
/// <remarks>
282+
/// Sets typo (a.k.a. sTypo or OS/2) vertical metric corresponding to ascender.
283+
/// <para />
284+
/// Typo vertical metrics are the primary source for iText ascender/descender calculations.
285+
/// </remarks>
286+
/// <param name="typoAscender">typo ascender value in normalized 1000-units</param>
258287
protected internal virtual void SetTypoAscender(int typoAscender) {
259288
this.typoAscender = (int)(typoAscender * normalizationCoef);
260289
}
261290

262-
protected internal virtual void SetTypoDescender(int typoDesctender) {
263-
this.typoDescender = (int)(typoDesctender * normalizationCoef);
264-
}
265-
291+
/// <summary>Sets typo (a.k.a. sTypo or OS/2) vertical metric corresponding to descender.</summary>
292+
/// <remarks>
293+
/// Sets typo (a.k.a. sTypo or OS/2) vertical metric corresponding to descender.
294+
/// <para />
295+
/// Typo vertical metrics are the primary source for iText ascender/descender calculations.
296+
/// </remarks>
297+
/// <param name="typoDescender">typo descender value in normalized 1000-units</param>
298+
protected internal virtual void SetTypoDescender(int typoDescender) {
299+
this.typoDescender = (int)(typoDescender * normalizationCoef);
300+
}
301+
302+
/// <summary>Sets the capital letters height.</summary>
303+
/// <remarks>
304+
/// Sets the capital letters height.
305+
/// <para />
306+
/// This property defines the vertical coordinate of the top of flat capital letters,
307+
/// measured from the baseline.
308+
/// </remarks>
309+
/// <param name="capHeight">cap height in 1000-units</param>
266310
protected internal virtual void SetCapHeight(int capHeight) {
267311
this.capHeight = (int)(capHeight * normalizationCoef);
268312
}

itext/itext.io/itext/io/font/FontProgram.cs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,14 +196,32 @@ internal static String TrimFontStyle(String name) {
196196
}
197197
}
198198

199+
/// <summary>Sets typo ascender.</summary>
200+
/// <remarks>
201+
/// Sets typo ascender. See also
202+
/// <see cref="FontMetrics.SetTypoAscender(int)"/>.
203+
/// </remarks>
204+
/// <param name="ascender">typo ascender value in 1000-units</param>
199205
protected internal virtual void SetTypoAscender(int ascender) {
200206
fontMetrics.SetTypoAscender(ascender);
201207
}
202208

209+
/// <summary>Sets typo descender.</summary>
210+
/// <remarks>
211+
/// Sets typo descender. See also
212+
/// <see cref="FontMetrics.SetTypoDescender(int)"/>.
213+
/// </remarks>
214+
/// <param name="descender">typo descender value in 1000-units</param>
203215
protected internal virtual void SetTypoDescender(int descender) {
204216
fontMetrics.SetTypoDescender(descender);
205217
}
206218

219+
/// <summary>Sets the capital letters height.</summary>
220+
/// <remarks>
221+
/// Sets the capital letters height. See also
222+
/// <see cref="FontMetrics.SetCapHeight(int)"/>.
223+
/// </remarks>
224+
/// <param name="capHeight">cap height in 1000-units</param>
207225
protected internal virtual void SetCapHeight(int capHeight) {
208226
fontMetrics.SetCapHeight(capHeight);
209227
}
@@ -212,9 +230,9 @@ protected internal virtual void SetXHeight(int xHeight) {
212230
fontMetrics.SetXHeight(xHeight);
213231
}
214232

215-
/// <summary>Sets the PostScript italic angel.</summary>
233+
/// <summary>Sets the PostScript italic angle.</summary>
216234
/// <remarks>
217-
/// Sets the PostScript italic angel.
235+
/// Sets the PostScript italic angle.
218236
/// <para />
219237
/// Italic angle in counter-clockwise degrees from the vertical. Zero for upright text, negative for text that leans to the right (forward).
220238
/// </remarks>

itext/itext.kernel/itext/kernel/font/FontUtil.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -121,9 +121,7 @@ internal static String CreateRandomFontName() {
121121

122122
internal static int[] ConvertSimpleWidthsArray(PdfArray widthsArray, int first, int missingWidth) {
123123
int[] res = new int[256];
124-
for (int i = 0; i < res.Length; i++) {
125-
res[i] = missingWidth;
126-
}
124+
JavaUtil.Fill(res, missingWidth);
127125
if (widthsArray == null) {
128126
ILog logger = LogManager.GetLogger(typeof(FontUtil));
129127
logger.Warn(iText.IO.LogMessageConstant.FONT_DICTIONARY_WITH_NO_WIDTHS);

itext/itext.kernel/itext/kernel/font/PdfFont.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ public abstract class PdfFont : PdfObjectWrapper<PdfDictionary> {
6161

6262
protected internal static readonly byte[] EMPTY_BYTES = new byte[0];
6363

64+
[Obsolete]
6465
protected internal static readonly double[] DEFAULT_FONT_MATRIX = new double[] { 0.001, 0, 0, 0.001, 0, 0 };
6566

6667
protected internal IDictionary<int, Glyph> notdefGlyphs = new Dictionary<int, Glyph>();
@@ -199,6 +200,7 @@ public virtual bool AppendDecodedCodesToGlyphsList(IList<Glyph> list, PdfString
199200

200201
public abstract void WriteText(String text, PdfOutputStream stream);
201202

203+
[Obsolete]
202204
public virtual double[] GetFontMatrix() {
203205
return DEFAULT_FONT_MATRIX;
204206
}

itext/itext.kernel/itext/kernel/font/PdfSimpleFont.cs

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -426,18 +426,7 @@ protected internal virtual void FlushFontData(String fontName, PdfName subtype)
426426
if (IsForceWidthsOutput() || !IsBuiltInFont() || fontEncoding.HasDifferences()) {
427427
GetPdfObject().Put(PdfName.FirstChar, new PdfNumber(firstChar));
428428
GetPdfObject().Put(PdfName.LastChar, new PdfNumber(lastChar));
429-
PdfArray wd = new PdfArray();
430-
for (int k = firstChar; k <= lastChar; ++k) {
431-
if (shortTag[k] == 0) {
432-
wd.Add(new PdfNumber(0));
433-
}
434-
else {
435-
//prevent lost of widths info
436-
int uni = fontEncoding.GetUnicode(k);
437-
Glyph glyph = uni > -1 ? GetGlyph(uni) : fontProgram.GetGlyphByCode(k);
438-
wd.Add(new PdfNumber(GetGlyphWidth(glyph)));
439-
}
440-
}
429+
PdfArray wd = BuildWidthsArray(firstChar, lastChar);
441430
GetPdfObject().Put(PdfName.Widths, wd);
442431
}
443432
PdfDictionary fontDescriptor = !IsBuiltInFont() ? GetFontDescriptor(fontName) : null;
@@ -508,12 +497,28 @@ protected internal override PdfDictionary GetFontDescriptor(String fontName) {
508497
return fontDescriptor;
509498
}
510499

500+
protected internal virtual PdfArray BuildWidthsArray(int firstChar, int lastChar) {
501+
PdfArray wd = new PdfArray();
502+
for (int k = firstChar; k <= lastChar; ++k) {
503+
if (shortTag[k] == 0) {
504+
wd.Add(new PdfNumber(0));
505+
}
506+
else {
507+
int uni = fontEncoding.GetUnicode(k);
508+
Glyph glyph = uni > -1 ? GetGlyph(uni) : fontProgram.GetGlyphByCode(k);
509+
wd.Add(new PdfNumber(glyph != null ? glyph.GetWidth() : 0));
510+
}
511+
}
512+
return wd;
513+
}
514+
511515
protected internal abstract void AddFontStream(PdfDictionary fontDescriptor);
512516

513517
protected internal virtual void SetFontProgram(T fontProgram) {
514518
this.fontProgram = fontProgram;
515519
}
516520

521+
[Obsolete]
517522
protected internal virtual double GetGlyphWidth(Glyph glyph) {
518523
return glyph != null ? glyph.GetWidth() : 0;
519524
}

0 commit comments

Comments
 (0)