Merge pull request #496 from gedoor/antecer

使用HashMap存储字形数据
pull/497/head
Antecer 5 years ago committed by GitHub
commit 11943f8c38
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 76
      app/src/main/java/io/legado/app/model/analyzeRule/QueryTTF.java

@ -1,15 +1,12 @@
package io.legado.app.model.analyzeRule; package io.legado.app.model.analyzeRule;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Pair;
import org.apache.commons.lang3.tuple.Triple; import org.apache.commons.lang3.tuple.Triple;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -170,18 +167,10 @@ public class QueryTTF {
return ReadUIntX(8); return ReadUIntX(8);
} }
public long ReadInt64() {
return ReadUIntX(8);
}
public int ReadUInt32() { public int ReadUInt32() {
return (int) ReadUIntX(4); return (int) ReadUIntX(4);
} }
public int ReadInt32() {
return (int) ReadUIntX(4);
}
public int ReadUInt16() { public int ReadUInt16() {
return (int) ReadUIntX(2); return (int) ReadUIntX(2);
} }
@ -233,7 +222,6 @@ public class QueryTTF {
private final List<Integer> Loca = new LinkedList<>(); private final List<Integer> Loca = new LinkedList<>();
private final CmapLayout Cmap = new CmapLayout(); private final CmapLayout Cmap = new CmapLayout();
private final List<GlyfLayout> Glyf = new LinkedList<>(); private final List<GlyfLayout> Glyf = new LinkedList<>();
private final Map<Integer, short[]> UnicodeMap = new LinkedHashMap<>();
private final Pair<Integer, Integer>[] pps = new Pair[]{ private final Pair<Integer, Integer>[] pps = new Pair[]{
Pair.of(3, 10), Pair.of(3, 10),
Pair.of(0, 4), Pair.of(0, 4),
@ -243,6 +231,9 @@ public class QueryTTF {
Pair.of(0, 1) Pair.of(0, 1)
}; };
public final Map<Integer, String> CodeToGlyph = new HashMap<>();
public final Map<String, Integer> GlyphToCode = new HashMap<>();
/** /**
* 构造函数 * 构造函数
* *
@ -474,16 +465,19 @@ public class QueryTTF {
} }
} }
// 建立Unicode&Glyf映射 // 建立Unicode&Glyph双向
for (int i = 0; i < 130000; ++i) { for (int key = 0; key < 130000; ++key) {
if (i == 0xFF) i = 0x3400; // 屏蔽部分编码 if (key == 0xFF) key = 0x3400;
int gid = GetGlyfIndex(i); int gid = GetGlyfIndex(key);
if (gid == 0) continue; if (gid == 0) continue;
int thisLength = Glyf.get(gid).flags.length; StringBuilder sb = new StringBuilder();
short[] thisGlyf = new short[thisLength << 1]; // 字型数据转String,方便存HashMap
System.arraycopy(Glyf.get(gid).xCoordinates, 0, thisGlyf, 0, thisLength); for (short b : Glyf.get(gid).xCoordinates) sb.append(b);
System.arraycopy(Glyf.get(gid).yCoordinates, 0, thisGlyf, thisLength, thisLength); for (short b : Glyf.get(gid).yCoordinates) sb.append(b);
UnicodeMap.put(i, thisGlyf); String val = sb.toString();
CodeToGlyph.put(key, val);
if (GlyphToCode.containsKey(val)) continue;
GlyphToCode.put(val, key);
} }
} }
@ -548,7 +542,6 @@ public class QueryTTF {
glyfID = tab.glyphIdArray[code - tab.startCode[start] + (tab.idRangeOffset[start] >> 1) - (tab.idRangeOffset.length - start)]; glyfID = tab.glyphIdArray[code - tab.startCode[start] + (tab.idRangeOffset[start] >> 1) - (tab.idRangeOffset.length - start)];
} else glyfID = code + tab.idDelta[start]; } else glyfID = code + tab.idDelta[start];
glyfID &= 0xFFFF; glyfID &= 0xFFFF;
} else if (fmt == 6) { } else if (fmt == 6) {
CmapFormat6 tab = (CmapFormat6) table; CmapFormat6 tab = (CmapFormat6) table;
int index = code - tab.firstCode; int index = code - tab.firstCode;
@ -571,42 +564,23 @@ public class QueryTTF {
return glyfID; return glyfID;
} }
// 缓存查询结果,避免重复遍历
private final Map<Integer, short[]> CacheGlyhps = new HashMap<>();
/** /**
* 使用轮廓数据获取Unicode值 * 使用Unicode值获取轮廓数据
* *
* @param inputGlyf 传入short[]轮廓数组 * @param key 传入Unicode十进制值
* @return 返回Unicode十进制 * @return 返回轮廓数组的String
*/ */
public int GetCodeByGlyf(short[] inputGlyf) { public String GetGlyfByCode(int key) {
if (inputGlyf.length == 0) return 0; return CodeToGlyph.getOrDefault(key, "");
// 优先查询缓存
for (Map.Entry<Integer, short[]> g : CacheGlyhps.entrySet()) {
if (Arrays.equals(inputGlyf, g.getValue())) {
return g.getKey();
}
}
// 缓存内没有就查询完整的字体表
for (Map.Entry<Integer, short[]> g : UnicodeMap.entrySet()) {
if (inputGlyf.length != g.getValue().length) continue;
if (Arrays.equals(inputGlyf, g.getValue())) {
CacheGlyhps.put(g.getKey(), inputGlyf);
return g.getKey();
}
}
return 0;
} }
/** /**
* 使用Unicode值获取轮廓数据 * 使用轮廓数据获取Unicode值
* *
* @param code 传入Unicode十进制 * @param val 传入轮廓数组的String值
* @return 返回short[]轮廓数组 * @return 返回Unicode十进制值
*/ */
public short[] GetGlyfByCode(int code) { public int GetCodeByGlyf(String val) {
if (code <= 0) return new short[0]; return GlyphToCode.getOrDefault(val, 0);
return UnicodeMap.getOrDefault(code, new short[0]);
} }
} }

Loading…
Cancel
Save