Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

25 pdf extracted fonts can not be loaded in browser #26

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions src/main/java/org/mabb/fontverter/opentype/CmapSubTable.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

package org.mabb.fontverter.opentype;

import org.apache.fontbox.cff.CFFStandardEncoding;
import org.mabb.fontverter.io.FontDataInput;
import org.mabb.fontverter.opentype.GlyphMapReader.GlyphMapping;
import org.mabb.fontverter.io.FontDataInputStream;
Expand Down Expand Up @@ -169,6 +170,8 @@ public void readData(FontDataInput input) throws IOException {
}

static class Format6SubTable extends CmapSubTable {
private Map<Integer, Integer> charCodeToGlyphId = new LinkedHashMap<Integer, Integer>();

public Format6SubTable() {
formatNumber = 6;
}
Expand All @@ -186,12 +189,25 @@ public byte[] getData() throws IOException {
public int glyphCount() {
return 0;
}

@Override
public List<GlyphMapping> getGlyphMappings() {
return GlyphMapReader.readCharCodesToGlyphs(charCodeToGlyphId, CFFStandardEncoding.getInstance());
}

public void readData(FontDataInput input) throws IOException {
int length = input.readUnsignedShort();
rawReadData = input.readBytes(length - 4);
input = new FontDataInputStream(rawReadData);

languageId = input.readUnsignedShort();
int firstCode = input.readUnsignedShort();
int entryCount = input.readUnsignedShort();
int[] glyphIndex = input.readUnsignedShortArray( entryCount );

for(int i = 0; i < entryCount; i++) {
charCodeToGlyphId.put( firstCode+i, glyphIndex[i] );
}
}
}

Expand Down
72 changes: 72 additions & 0 deletions src/main/java/org/mabb/fontverter/opentype/CmapTable.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@


import org.mabb.fontverter.io.FontDataInput;
import org.mabb.fontverter.opentype.CmapSubTable.Format0SubTable;
import org.mabb.fontverter.opentype.GlyphMapReader.GlyphMapping;
import org.mabb.fontverter.io.FontDataInputStream;
import org.mabb.fontverter.io.FontDataOutputStream;
Expand Down Expand Up @@ -53,7 +54,67 @@ int numTables() {
public String getTableType() {
return "cmap";
}

@Override
public void normalize() throws IOException {
super.normalize();

Format4SubTable newWindowsTable = null;
Format4SubTable newUnixTable = null;
Format0SubTable newMacTable = null;

if( this.windowsTable == null ) {
newWindowsTable = new Format4SubTable();
newWindowsTable.setPlatformId(3);
newWindowsTable.setEncodingId(1);

this.windowsTable = newWindowsTable;
}

if( this.unixTable == null ) {
newUnixTable = new Format4SubTable();
newUnixTable.setPlatformId(0);
newUnixTable.setEncodingId(3);

this.unixTable = newUnixTable;
}

if( this.macTable == null ) {
newMacTable = new Format0SubTable();
newMacTable.setPlatformId(1);
newMacTable.setEncodingId(0);

this.macTable = newMacTable;
}

if( newWindowsTable != null || newUnixTable != null || newMacTable != null ) {
for( GlyphMapping m : getGlyphMappings() ) {
if( m.glyphId > 0 ) {
if( newWindowsTable != null ) {
newWindowsTable.addGlyphMapping( m.charCode, m.glyphId );
}
if( newUnixTable != null ) {
newUnixTable.addGlyphMapping( m.charCode, m.glyphId );
}
if( newMacTable != null ) {
newMacTable.addGlyphMapping( m.charCode, m.glyphId );
}
}
}
if( newWindowsTable != null ) {
this.subTables.add(newWindowsTable);
}

if( newUnixTable != null ) {
this.subTables.add(newUnixTable);
}

if( newMacTable != null ) {
this.subTables.add(newMacTable);
}
}
}

@Override
protected byte[] generateUnpaddedData() throws IOException {
calculateOffsets();
Expand Down Expand Up @@ -117,6 +178,17 @@ else if (format == 14)
subTable.setEncodingId(header.encodingID);
subTable.setPlatformId(header.platformID);
subTables.add(subTable);

if( header.platformID == 0
&& subTable instanceof Format4SubTable) {
this.unixTable = (Format4SubTable) subTable;
} else if( header.platformID == 1
&& subTable instanceof Format0SubTable) {
this.macTable = (Format0SubTable) subTable;
} else if( header.platformID == 3
&& subTable instanceof Format4SubTable) {
this.windowsTable = (Format4SubTable) subTable;
}
}
}

Expand Down
33 changes: 32 additions & 1 deletion src/main/java/org/mabb/fontverter/opentype/OpenTypeFont.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.UUID;

import static org.mabb.fontverter.opentype.SfntHeader.*;

Expand Down Expand Up @@ -139,9 +140,34 @@ public void normalize() throws IOException {
if (getOs2() == null)
createNewOS2WinMetricsTable();

if (getNameTable() == null)
if (getNameTable() == null) {
setName(NameTable.createDefaultTable());
} else {
Copy link
Author

@tomsontom tomsontom Mar 31, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unfortunately these changes surface a bug in NameTable - i have a fix for that but if you want I can rollback those changes and provide another PR to fix this

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the problem is in the offset-computation where there are 2 problems:

  • it's not guaranteed that the length of the string has been computed
  • the offset computation is done BEFORE the entries are sorted
    I think currently one most of the time does not recognize that because if one call normalize() and then getData() the content is correct because on the get data-call

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh if you have a fix for it you can just throw it into this PR. I unfortunately haven't worked on this project in a long time so I'm not really familiar with the specifics here (I also haven't touched java in years either)

if( getNameTable().getName( OtfNameConstants.RecordType.FONT_FAMILY ) == null ) {
getNameTable().setFontFamily( "DefaultFamily" );
}

if( getNameTable().getName( OtfNameConstants.RecordType.FONT_SUB_FAMILY ) == null ) {
getNameTable().setFontSubFamily( "Normal" );
}

if( getNameTable().getName( OtfNameConstants.RecordType.FULL_FONT_NAME ) == null ) {
getNameTable().setFontFullName( "DefaultFontFullName" );
}

if( getNameTable().getName( OtfNameConstants.RecordType.POSTSCRIPT_NAME ) == null ) {
getNameTable().setPostScriptName( "DefaultPostScriptName" );
}

if( getNameTable().getName( OtfNameConstants.RecordType.UNIQUE_FONT_ID ) == null ) {
getNameTable().setUniqueId( UUID.randomUUID().toString().replace("-", ""));
}

if( getNameTable().getName( OtfNameConstants.RecordType.VERSION_STRING ) == null ) {
getNameTable().setVersion( "Version 1.1" );
}
}

if (getPost() == null)
setPost(PostScriptTable.createDefaultTable(getOpenTypeVersion()));

Expand Down Expand Up @@ -229,6 +255,11 @@ private void normalizeTables() throws IOException {
if (sfntHeader.sfntFlavor.isEmpty())
sfntHeader.sfntFlavor = determineSfntFlavor();

CmapTable cmap = getCmap();
if( cmap != null ) {
cmap.normalize();
}

if (getCmap() != null && getMxap() != null && !getMxap().isFromParsedFont)
getMxap().setNumGlyphs(getCmap().getGlyphCount());

Expand Down