David PHAM-VAN

Fix parsing TTF fonts with zero-length glyphs

@@ -168,6 +168,7 @@ class TtfParser { @@ -168,6 +168,7 @@ class TtfParser {
168 168
169 final charToGlyphIndexMap = <int, int>{}; 169 final charToGlyphIndexMap = <int, int>{};
170 final glyphOffsets = <int>[]; 170 final glyphOffsets = <int>[];
  171 + final glyphSizes = <int>[];
171 final glyphInfoMap = <int, PdfFontMetrics>{}; 172 final glyphInfoMap = <int, PdfFontMetrics>{};
172 final bitmapOffsets = <int, TtfBitmapInfo>{}; 173 final bitmapOffsets = <int, TtfBitmapInfo>{};
173 174
@@ -346,14 +347,21 @@ class TtfParser { @@ -346,14 +347,21 @@ class TtfParser {
346 347
347 void _parseIndexes() { 348 void _parseIndexes() {
348 final basePosition = tableOffsets[loca_table]!; 349 final basePosition = tableOffsets[loca_table]!;
349 - final numGlyphs = this.numGlyphs;  
350 if (indexToLocFormat == 0) { 350 if (indexToLocFormat == 0) {
351 - for (var i = 0; i < numGlyphs; i++) {  
352 - glyphOffsets.add(bytes.getUint16(basePosition + i * 2) * 2); 351 + var prevOffset = bytes.getUint16(basePosition) * 2;
  352 + for (var i = 1; i < numGlyphs + 1; i++) {
  353 + final offset = bytes.getUint16(basePosition + i * 2) * 2;
  354 + glyphOffsets.add(prevOffset);
  355 + glyphSizes.add(offset - prevOffset);
  356 + prevOffset = offset;
353 } 357 }
354 } else { 358 } else {
355 - for (var i = 0; i < numGlyphs; i++) {  
356 - glyphOffsets.add(bytes.getUint32(basePosition + i * 4)); 359 + var prevOffset = bytes.getUint32(basePosition);
  360 + for (var i = 1; i < numGlyphs + 1; i++) {
  361 + final offset = bytes.getUint32(basePosition + i * 4);
  362 + glyphOffsets.add(prevOffset);
  363 + glyphSizes.add(offset - prevOffset);
  364 + prevOffset = offset;
357 } 365 }
358 } 366 }
359 } 367 }
@@ -366,12 +374,8 @@ class TtfParser { @@ -366,12 +374,8 @@ class TtfParser {
366 final numOfLongHorMetrics = this.numOfLongHorMetrics; 374 final numOfLongHorMetrics = this.numOfLongHorMetrics;
367 final defaultadvanceWidth = 375 final defaultadvanceWidth =
368 bytes.getUint16(hmtxOffset + (numOfLongHorMetrics - 1) * 4); 376 bytes.getUint16(hmtxOffset + (numOfLongHorMetrics - 1) * 4);
369 - var glyphIndex = 0;  
370 - for (final offset in glyphOffsets) {  
371 - final xMin = bytes.getInt16(baseOffset + offset + 2); // 2  
372 - final yMin = bytes.getInt16(baseOffset + offset + 4); // 4  
373 - final xMax = bytes.getInt16(baseOffset + offset + 6); // 6  
374 - final yMax = bytes.getInt16(baseOffset + offset + 8); // 8 377 +
  378 + for (var glyphIndex = 0; glyphIndex < numGlyphs; glyphIndex++) {
375 final advanceWidth = glyphIndex < numOfLongHorMetrics 379 final advanceWidth = glyphIndex < numOfLongHorMetrics
376 ? bytes.getUint16(hmtxOffset + glyphIndex * 4) 380 ? bytes.getUint16(hmtxOffset + glyphIndex * 4)
377 : defaultadvanceWidth; 381 : defaultadvanceWidth;
@@ -380,6 +384,25 @@ class TtfParser { @@ -380,6 +384,25 @@ class TtfParser {
380 : bytes.getInt16(hmtxOffset + 384 : bytes.getInt16(hmtxOffset +
381 numOfLongHorMetrics * 4 + 385 numOfLongHorMetrics * 4 +
382 (glyphIndex - numOfLongHorMetrics) * 2); 386 (glyphIndex - numOfLongHorMetrics) * 2);
  387 + if (glyphSizes[glyphIndex] == 0) {
  388 + glyphInfoMap[glyphIndex] = PdfFontMetrics(
  389 + left: 0,
  390 + top: 0,
  391 + right: 0,
  392 + bottom: 0,
  393 + ascent: 0,
  394 + descent: 0,
  395 + advanceWidth: advanceWidth / unitsPerEm,
  396 + leftBearing: leftBearing / unitsPerEm,
  397 + );
  398 + continue;
  399 + }
  400 + final offset = glyphOffsets[glyphIndex];
  401 + final xMin = bytes.getInt16(baseOffset + offset + 2); // 2
  402 + final yMin = bytes.getInt16(baseOffset + offset + 4); // 4
  403 + final xMax = bytes.getInt16(baseOffset + offset + 6); // 6
  404 + final yMax = bytes.getInt16(baseOffset + offset + 8); // 8
  405 +
383 glyphInfoMap[glyphIndex] = PdfFontMetrics( 406 glyphInfoMap[glyphIndex] = PdfFontMetrics(
384 left: xMin.toDouble() / unitsPerEm, 407 left: xMin.toDouble() / unitsPerEm,
385 top: yMin.toDouble() / unitsPerEm, 408 top: yMin.toDouble() / unitsPerEm,
@@ -390,7 +413,6 @@ class TtfParser { @@ -390,7 +413,6 @@ class TtfParser {
390 advanceWidth: advanceWidth.toDouble() / unitsPerEm, 413 advanceWidth: advanceWidth.toDouble() / unitsPerEm,
391 leftBearing: leftBearing.toDouble() / unitsPerEm, 414 leftBearing: leftBearing.toDouble() / unitsPerEm,
392 ); 415 );
393 - glyphIndex++;  
394 } 416 }
395 } 417 }
396 418
@@ -4,6 +4,7 @@ @@ -4,6 +4,7 @@
4 4
5 - Update pdfium version to 4861 5 - Update pdfium version to 4861
6 - Fix crash when Android load a PDF file which had password 6 - Fix crash when Android load a PDF file which had password
  7 +- Fix parsing TTF fonts with zero-length glyphs
7 8
8 ## 5.7.2 9 ## 5.7.2
9 10
No preview for this file type