使用SfntTool制作字体剪辑工具3 - 使用jd-gui反编译.class文件

在将sfnttool.jar转换为sfnttool.dll之后,已经可以将dll添加到C#引用中了,但是这还远远不够。

sfnttool.jar中含有主函数main,因而可以直接通过命令行调用,但是在C#中只能够调用相应类的方法,而这些方法是被封装在jar包中的主函数中的,因此需要查看sfnttool的源代码。

方法如下:

1、将sfnttool.jar使用压缩软件解压,找到SfntTool.class文件(sfnttool\com\google\typography\font\tools\sfnttool),这就是SfntTool的类文件。

2、下载jd-gui:http://jd.benow.ca/jd-gui/downloads/jd-gui-0.3.6.windows.zip;

3、反编译SfntTool.class文件,得到如下代码:

package com.google.typography.font.tools.sfnttool;

import com.google.typography.font.sfntly.Font;
import com.google.typography.font.sfntly.Font.Builder;
import com.google.typography.font.sfntly.FontFactory;
import com.google.typography.font.sfntly.Tag;
import com.google.typography.font.sfntly.data.WritableFontData;
import com.google.typography.font.sfntly.table.core.CMapTable.CMapId;
import com.google.typography.font.tools.conversion.eot.EOTWriter;
import com.google.typography.font.tools.conversion.woff.WoffWriter;
import com.google.typography.font.tools.subsetter.HintStripper;
import com.google.typography.font.tools.subsetter.RenumberingSubsetter;
import com.google.typography.font.tools.subsetter.Subsetter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class SfntTool
{
  private boolean strip = false;
  private String subsetString = null;
  private boolean woff = false;
  private boolean eot = false;
  private boolean mtx = false;
  
  public static void main(String[] paramArrayOfString)
    throws IOException
  {
    SfntTool localSfntTool = new SfntTool();
    File localFile1 = null;
    File localFile2 = null;
    int i = 0;
    int j = 1;
    for (int k = 0; k < paramArrayOfString.length; k++)
    {
      String str = null;
      if (paramArrayOfString[k].charAt(0) == '-') {
        str = paramArrayOfString[k].substring(1);
      }
      if (str != null)
      {
        if ((str.equals("help")) || (str.equals("?")))
        {
          printUsage();
          System.exit(0);
        }
        else if ((str.equals("b")) || (str.equals("bench")))
        {
          j = 10000;
        }
        else if ((str.equals("h")) || (str.equals("hints")))
        {
          localSfntTool.strip = true;
        }
        else if ((str.equals("s")) || (str.equals("string")))
        {
          localSfntTool.subsetString = paramArrayOfString[(k + 1)];
          k++;
        }
        else if ((str.equals("w")) || (str.equals("woff")))
        {
          localSfntTool.woff = true;
        }
        else if ((str.equals("e")) || (str.equals("eot")))
        {
          localSfntTool.eot = true;
        }
        else if ((str.equals("x")) || (str.equals("mtx")))
        {
          localSfntTool.mtx = true;
        }
        else
        {
          printUsage();
          System.exit(1);
        }
      }
      else if (localFile1 == null)
      {
        localFile1 = new File(paramArrayOfString[k]);
      }
      else
      {
        localFile2 = new File(paramArrayOfString[k]);
        break;
      }
    }
    if ((localSfntTool.woff) && (localSfntTool.eot))
    {
      System.out.println("WOFF and EOT options are mutually exclusive");
      System.exit(1);
    }
    if ((localFile1 != null) && (localFile2 != null)) {
      localSfntTool.subsetFontFile(localFile1, localFile2, j);
    } else {
      printUsage();
    }
  }
  
  private static final void printUsage()
  {
    System.out.println("Subset [-?|-h|-help] [-b] [-s string] fontfile outfile");
    System.out.println("Prototype font subsetter");
    System.out.println("\t-?,-help\tprint this help information");
    System.out.println("\t-s,-string\t String to subset");
    System.out.println("\t-b,-bench\t Benchmark (run 10000 iterations)");
    System.out.println("\t-h,-hints\t Strip hints");
    System.out.println("\t-w,-woff\t Output WOFF format");
    System.out.println("\t-e,-eot\t Output EOT format");
    System.out.println("\t-x,-mtx\t Enable Microtype Express compression for EOT format");
  }
  
  public void subsetFontFile(File paramFile1, File paramFile2, int paramInt)
    throws IOException
  {
    FontFactory localFontFactory = FontFactory.getInstance();
    FileInputStream localFileInputStream = null;
    try
    {
      localFileInputStream = new FileInputStream(paramFile1);
      byte[] arrayOfByte = new byte[(int)paramFile1.length()];
      localFileInputStream.read(arrayOfByte);
      Font[] arrayOfFont = null;
      arrayOfFont = localFontFactory.loadFonts(arrayOfByte);
      Font localFont1 = arrayOfFont[0];
      ArrayList localArrayList = new ArrayList();
      localArrayList.add(CMapTable.CMapId.WINDOWS_BMP);
      Object localObject1 = null;
      for (int i = 0; i < paramInt; i++)
      {
        Font localFont2 = localFont1;
        Object localObject3;
        if (this.subsetString != null)
        {
          localObject2 = new RenumberingSubsetter(localFont2, localFontFactory);
          ((Subsetter)localObject2).setCMaps(localArrayList, 1);
          localObject3 = GlyphCoverage.getGlyphCoverage(localFont1, this.subsetString);
          ((Subsetter)localObject2).setGlyphs((List)localObject3);
          HashSet localHashSet = new HashSet();
          localHashSet.add(Integer.valueOf(Tag.GDEF));
          localHashSet.add(Integer.valueOf(Tag.GPOS));
          localHashSet.add(Integer.valueOf(Tag.GSUB));
          localHashSet.add(Integer.valueOf(Tag.kern));
          localHashSet.add(Integer.valueOf(Tag.hdmx));
          localHashSet.add(Integer.valueOf(Tag.vmtx));
          localHashSet.add(Integer.valueOf(Tag.VDMX));
          localHashSet.add(Integer.valueOf(Tag.LTSH));
          localHashSet.add(Integer.valueOf(Tag.DSIG));
          localHashSet.add(Integer.valueOf(Tag.intValue(new byte[] { 109, 111, 114, 116 })));
          localHashSet.add(Integer.valueOf(Tag.intValue(new byte[] { 109, 111, 114, 120 })));
          ((Subsetter)localObject2).setRemoveTables(localHashSet);
          localFont2 = ((Subsetter)localObject2).subset().build();
        }
        if (this.strip)
        {
          localObject2 = new HintStripper(localFont2, localFontFactory);
          localObject3 = new HashSet();
          ((Set)localObject3).add(Integer.valueOf(Tag.fpgm));
          ((Set)localObject3).add(Integer.valueOf(Tag.prep));
          ((Set)localObject3).add(Integer.valueOf(Tag.cvt));
          ((Set)localObject3).add(Integer.valueOf(Tag.hdmx));
          ((Set)localObject3).add(Integer.valueOf(Tag.VDMX));
          ((Set)localObject3).add(Integer.valueOf(Tag.LTSH));
          ((Set)localObject3).add(Integer.valueOf(Tag.DSIG));
          ((Subsetter)localObject2).setRemoveTables((Set)localObject3);
          localFont2 = ((Subsetter)localObject2).subset().build();
        }
        Object localObject2 = new FileOutputStream(paramFile2);
        if (this.woff)
        {
          localObject3 = new WoffWriter().convert(localFont2);
          ((WritableFontData)localObject3).copyTo((OutputStream)localObject2);
        }
        else if (this.eot)
        {
          localObject3 = new EOTWriter(this.mtx).convert(localFont2);
          ((WritableFontData)localObject3).copyTo((OutputStream)localObject2);
        }
        else
        {
          localFontFactory.serializeFont(localFont2, (OutputStream)localObject2);
        }
      }
    }
    finally
    {
      if (localFileInputStream != null) {
        localFileInputStream.close();
      }
    }
  }
}

4、通过查看源代码中的逻辑,就可以创建自己的C#字体剪辑工具了。


猜你喜欢

转载自blog.csdn.net/pigautumn/article/details/72866812