summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorb5f0d6c3 <[email protected]>2022-05-01 16:42:32 +0800
committerb5f0d6c3 <[email protected]>2022-05-01 16:42:32 +0800
commit62084c06ba118693234b0debf8ae5590274fd6c0 (patch)
tree647ddc0d962a0df3c21683fd9ee57eef7e06b36e
parent591ed09da22ec61dd129ea346fd2ad61eb132e67 (diff)
update mkvlib:fix & optimization
-rw-r--r--mkvlib/ass.go287
-rw-r--r--mkvlib/go.mod3
-rw-r--r--mkvlib/shared.go2
3 files changed, 135 insertions, 157 deletions
diff --git a/mkvlib/ass.go b/mkvlib/ass.go
index 8ba585c..472d067 100644
--- a/mkvlib/ass.go
+++ b/mkvlib/ass.go
@@ -7,6 +7,8 @@ import (
"fmt"
"github.com/KurenaiRyu/MkvAutoSubset/mkvlib/parser"
"github.com/antchfx/xmlquery"
+ "golang.org/x/image/font/opentype"
+ "golang.org/x/image/font/sfnt"
"io"
"io/ioutil"
"os"
@@ -27,7 +29,7 @@ const (
type fontInfo struct {
file string
runes []rune
- index string
+ index int
oldName string
newName string
sFont string
@@ -55,7 +57,6 @@ type assProcessor struct {
lcb logCallback
cache []cacheInfo
tDir string
- _m map[string][]string
fg map[string]string
seps []string
rename bool
@@ -197,25 +198,21 @@ func (self *assProcessor) getTTCCount(file string) int {
return 0
}
-func (self *assProcessor) dumpFont(file, out string, full, cmap bool, index int) []string {
+func (self *assProcessor) dumpFont(file, out string, full bool) []string {
ok := false
count := 1
_, n, _, _ := splitPath(file)
list := make([]string, 0)
- if index > -1 {
- count = index + 1
- } else {
- index = 0
- if strings.HasSuffix(strings.ToLower(n), ".ttc") {
- count = self.getTTCCount(file)
- if count < 1 {
- printLog(self.lcb, `Failed to get the ttc font count: "%s".`, n)
- return list
- }
+ if strings.HasSuffix(strings.ToLower(n), ".ttc") {
+ count = self.getTTCCount(file)
+ if count < 1 {
+ printLog(self.lcb, `Failed to get the ttc font count: "%s".`, n)
+ return list
}
}
+
reg, _ := regexp.Compile(`[\x00-\x1f]|(&#([0-9]|[12][0-9]|3[01]);)`)
- for i := index; i < count; i++ {
+ for i := 0; i < count; i++ {
fn := fmt.Sprintf("%s_%d.ttx", file, i)
if out != "" {
_, fn, _, _ = splitPath(fn)
@@ -228,9 +225,6 @@ func (self *assProcessor) dumpFont(file, out string, full, cmap bool, index int)
args = append(args, "-o", fn)
if !full {
args = append(args, "-t", "name")
- if cmap {
- args = append(args, "-t", "cmap")
- }
}
args = append(args, file)
if p, err := newProcess(nil, nil, nil, "", ttx, args...); err == nil {
@@ -254,81 +248,66 @@ func (self *assProcessor) dumpFont(file, out string, full, cmap bool, index int)
return list
}
-func (self *assProcessor) dumpFonts(files []string, full bool) bool {
- if self.tDir == "" {
- self.tDir = path.Join(os.TempDir(), randomStr(8))
- if os.MkdirAll(self.tDir, os.ModePerm) != nil {
- return false
+func (self *assProcessor) getFontName(p string) [][]map[string]bool {
+ w := func(_font *sfnt.Font) []map[string]bool {
+ names := make(map[string]bool)
+ types := make(map[string]bool)
+ id1, _ := _font.Name(nil, sfnt.NameIDFamily)
+ id2, _ := _font.Name(nil, sfnt.NameIDSubfamily)
+ id4, _ := _font.Name(nil, sfnt.NameIDFull)
+ id6, _ := _font.Name(nil, sfnt.NameIDPostScript)
+ if id1 != "" {
+ names[id1] = true
}
+ if id4 != "" {
+ names[id4] = true
+ }
+ if id6 != "" {
+ names[id6] = true
+ }
+ if id2 != "" {
+ types[id2] = true
+ }
+ return []map[string]bool{names, types}
}
- ok := 0
- l := len(files)
- wg := new(sync.WaitGroup)
- wg.Add(l)
- m := new(sync.Mutex)
- if self._m == nil {
- self._m = make(map[string][]string)
- }
- for _, item := range files {
- go func(_item string) {
- _ok := self.dumpFont(_item, self.tDir, full, self.check, -1)
- if len(_ok) > 0 {
- m.Lock()
- ok++
- self._m[_item] = _ok
- m.Unlock()
- }
- wg.Done()
- }(item)
- }
- wg.Wait()
- return ok == l
-}
-
-func (self *assProcessor) getFontName(p string) []map[string]bool {
+ list := make([][]map[string]bool, 0)
f, err := openFile(p, true, false)
+ defer func() { _ = f.Close() }()
if err == nil {
- defer func() { _ = f.Close() }()
- names := make(map[string]bool)
- types := make(map[string]bool)
- items := make(map[string]bool)
- xml, err := xmlquery.Parse(f)
+ data, err := ioutil.ReadAll(f)
if err == nil {
- for _, v := range xml.SelectElements(`ttFont/name/namerecord`) {
- id := v.SelectAttr("nameID")
- name := strings.TrimSpace(v.FirstChild.Data)
- switch id {
- case "1", "3", "4", "6":
- names[name] = true
- break
- case "2", "17":
- types[name] = true
- break
+ fonts := make([]*sfnt.Font, 0)
+ if strings.HasSuffix(strings.ToLower(p), ".ttc") {
+ c, err := opentype.ParseCollection(data)
+ if err == nil {
+ l := c.NumFonts()
+ for i := 0; i < l; i++ {
+ _f, err := c.Font(i)
+ if err == nil {
+ fonts = append(fonts, _f)
+ }
+ }
+ }
+ } else {
+ _f, err := opentype.Parse(data)
+ if err == nil {
+ fonts = append(fonts, _f)
}
}
- for _, v := range xml.SelectElements(`ttFont/cmap//map`) {
- code := v.SelectAttr("code")
- hex, _ := strconv.ParseInt(code, 0, 64)
- c := string(rune(hex))
- items[c] = true
+ for _, _font := range fonts {
+ list = append(list, w(_font))
}
- return []map[string]bool{names, types, items}
}
}
- return nil
+ return list
}
-func (self *assProcessor) getFontsName(files []string) map[string][]map[string]bool {
+func (self *assProcessor) getFontsName(files []string) map[string][][]map[string]bool {
l := len(files)
wg := new(sync.WaitGroup)
wg.Add(l)
m := new(sync.Mutex)
- _m := make(map[string][]map[string]bool)
- defer func() {
- for _, item := range files {
- _ = os.Remove(item)
- }
- }()
+ _m := make(map[string][][]map[string]bool)
for _, item := range files {
go func(_item string) {
names := self.getFontName(_item)
@@ -344,17 +323,34 @@ func (self *assProcessor) getFontsName(files []string) map[string][]map[string]b
return _m
}
-func (self *assProcessor) checkFontMissing(f *fontInfo, v map[string]bool, i int, c bool) bool {
+func (self *assProcessor) checkFontMissing(f *fontInfo, i int, c bool) bool {
_str := ""
_runes := make([]rune, 0)
- _m := make(map[rune]bool)
- for _, _v := range f.runes {
- if !v[string(_v)] {
- if (_v == '\u0020' || _v == '\u00a0') && !_m[_v] {
- _m[_v] = true
- _runes = append(_runes, _v)
+ _f, err := os.Open(f.file)
+ if err == nil {
+ defer func() { _ = _f.Name() }()
+ data, err := ioutil.ReadAll(_f)
+ if err == nil {
+ var _font *sfnt.Font
+ if strings.HasSuffix(strings.ToLower(f.file), ".ttc") {
+ c, err := opentype.ParseCollection(data)
+ if err == nil {
+ _font, _ = c.Font(f.index)
+ }
} else {
- _str += string(_v)
+ _font, _ = opentype.Parse(data)
+ }
+ if _font != nil {
+ for _, r := range f.runes {
+ n, _ := _font.GlyphIndex(nil, r)
+ if n == 0 {
+ if r == '\u0020' || r == '\u00a0' {
+ _runes = append(_runes, r)
+ } else {
+ _str += string(r)
+ }
+ }
+ }
}
}
}
@@ -378,18 +374,9 @@ func (self *assProcessor) checkFontMissing(f *fontInfo, v map[string]bool, i int
}
func (self *assProcessor) matchFonts() bool {
- if !self.dumpFonts(self.fonts, false) {
- return false
- }
self.fg = make(map[string]string)
- reg, _ := regexp.Compile(`_(\d+)\.ttx$`)
- m := make(map[string]map[string][]map[string]bool)
- for font, ttxs := range self._m {
- _m := self.getFontsName(ttxs)
- if len(_m) > 0 {
- m[font] = _m
- }
- }
+ fonts := findFonts(self._fonts)
+ m := self.getFontsName(fonts)
_count := make(map[string]int)
w := func(fb bool) {
for k, _ := range self.m {
@@ -404,14 +391,16 @@ func (self *assProcessor) matchFonts() bool {
for __k, v := range m {
for ___k, _v := range v {
if self.matchFontName(_v, _k) {
+ self.m[k].file = __k
+ self.m[k].index = ___k
if self.check {
_count[_k[0]]++
- if !self.checkFontMissing(self.m[k], _v[2], _count[_k[0]], false) && self.strict {
+ if !self.checkFontMissing(self.m[k], _count[_k[0]], false) && self.strict {
+ self.m[k].file = ""
+ self.m[k].index = 0
continue
}
}
- self.m[k].file = __k
- self.m[k].index = reg.FindStringSubmatch(___k)[1]
n := self.fg[_k[0]]
if n == "" {
n = randomStr(8)
@@ -502,6 +491,12 @@ func (self *assProcessor) reMap() {
}
func (self *assProcessor) createFontSubset(font *fontInfo) bool {
+ if self.tDir == "" {
+ self.tDir = path.Join(os.TempDir(), randomStr(8))
+ if os.MkdirAll(self.tDir, os.ModePerm) != nil {
+ return false
+ }
+ }
ok := false
fn := fmt.Sprintf(`%s.txt`, font.newName)
_, fn, _, _ = splitPath(fn)
@@ -528,14 +523,14 @@ func (self *assProcessor) createFontSubset(font *fontInfo) bool {
args = append(args, "--text-file="+fn)
args = append(args, "--output-file="+_fn)
args = append(args, "--name-languages="+"*")
- args = append(args, "--font-number="+font.index)
+ args = append(args, "--font-number="+strconv.Itoa(font.index))
args = append(args, font.file)
if p, err := newProcess(nil, nil, nil, "", pyftsubset, args...); err == nil {
s, err := p.Wait()
ok = err == nil && s.ExitCode() == 0
}
if !ok {
- printLog(self.lcb, `Failed to subset font: "%s"[%s].`, n, font.index)
+ printLog(self.lcb, `Failed to subset font: "%s"[%s].`, font.oldName, font.index)
} else {
font.sFont = _fn
}
@@ -574,14 +569,8 @@ func (self *assProcessor) createFontsSubset() bool {
}
func (self *assProcessor) changeFontName(font *fontInfo) bool {
- if self.tDir == "" {
- self.tDir = path.Join(os.TempDir(), randomStr(8))
- if os.MkdirAll(self.tDir, os.ModePerm) != nil {
- return false
- }
- }
ec := 0
- if len(self.dumpFont(font.sFont, self.tDir, true, false, -1)) > 0 {
+ if len(self.dumpFont(font.sFont, self.tDir, true)) > 0 {
fn := fmt.Sprintf("%s_0.ttx", font.sFont)
_, fn, _, _ = splitPath(fn)
fn = path.Join(self.tDir, fn)
@@ -602,7 +591,7 @@ func (self *assProcessor) changeFontName(font *fontInfo) bool {
case "0":
v.FirstChild.Data = "Processed by " + LibFName + " at " + time.Now().Format("2006-01-02 15:04:05")
break
- case "1", "3", "4", "6":
+ case "1", "4", "6":
v.FirstChild.Data = n
break
}
@@ -648,6 +637,12 @@ func (self *assProcessor) changeFontName(font *fontInfo) bool {
}
func (self *assProcessor) changeFontsName() bool {
+ if self.tDir == "" {
+ self.tDir = path.Join(os.TempDir(), randomStr(8))
+ if os.MkdirAll(self.tDir, os.ModePerm) != nil {
+ return false
+ }
+ }
ok := 0
l := len(self.m)
wg := new(sync.WaitGroup)
@@ -742,51 +737,36 @@ func (self *assProcessor) createFontsCache(output string) []string {
ok := 0
l := len(fonts)
m := new(sync.Mutex)
- if self.tDir == "" {
- self.tDir = path.Join(os.TempDir(), randomStr(8))
- if os.MkdirAll(self.tDir, os.ModePerm) != nil {
- printLog(self.lcb, `Failed to create temp dir: "%s"`, self.tDir)
- return []string{""}
- }
- }
- reg, _ := regexp.Compile(`_(\d+)\.ttx$`)
wg := new(sync.WaitGroup)
el := make([]string, 0)
w := func(s, e int) {
for i := s; i < e; i++ {
go func(x int) {
_item := fonts[x]
- list := self.dumpFont(_item, self.tDir, false, false, -1)
- if len(list) > 0 {
- m.Lock()
- _m := self.getFontsName(list)
- _fonts := make([][]string, len(_m))
- _types := make([][]string, len(_m))
- for k, v := range _m {
- index := reg.FindStringSubmatch(k)[1]
- q, _ := strconv.Atoi(index)
- _list := make([]string, 0)
- for _k, _ := range v[0] {
- _list = append(_list, _k)
- }
- _fonts[q] = _list
- _list = make([]string, 0)
- for _k, _ := range v[1] {
- _list = append(_list, _k)
- }
- _types[q] = _list
+ m.Lock()
+ _m := self.getFontName(_item)
+ _fonts := make([][]string, len(_m))
+ _types := make([][]string, len(_m))
+ for k, v := range _m {
+ _list := make([]string, 0)
+ for _k, _ := range v[0] {
+ _list = append(_list, _k)
}
- if len(_fonts) > 0 && len(_types) > 0 {
- ok++
- cache = append(cache, fontCache{_item, _fonts, _types})
- printLog(self.lcb, "Cache font (%d/%d) done.", ok, l)
- } else {
- el = append(el, _item)
+ _fonts[k] = _list
+ _list = make([]string, 0)
+ for _k, _ := range v[1] {
+ _list = append(_list, _k)
}
- m.Unlock()
+ _types[k] = _list
+ }
+ if len(_fonts) > 0 && len(_types) > 0 {
+ ok++
+ cache = append(cache, fontCache{_item, _fonts, _types})
+ printLog(self.lcb, "Cache font (%d/%d) done.", ok, l)
} else {
el = append(el, _item)
}
+ m.Unlock()
wg.Done()
}(i)
}
@@ -869,7 +849,7 @@ func (self *assProcessor) loadCache(p string) {
}
}
-func (self *assProcessor) matchCache(k string) (string, string) {
+func (self *assProcessor) matchCache(k string) (string, int) {
ok := ""
i := -1
_count := 0
@@ -877,24 +857,21 @@ func (self *assProcessor) matchCache(k string) (string, string) {
for _, v := range self.cache {
for q, list := range v.Names {
if self.matchFontName(list, _k) {
+ ok = v.File
+ i = q
if self.check {
- ttxs := self.dumpFont(v.File, self.tDir, false, self.check, i)
- if len(ttxs) > 0 {
- names := self.getFontsName(ttxs)
- if len(names) > 0 {
- _count++
- if !self.checkFontMissing(self.m[k], names[ttxs[0]][2], _count, true) && self.strict {
- continue
- }
- } else {
+ names := self.getFontName(v.File)
+ if len(names) > 0 {
+ _count++
+ if !self.checkFontMissing(self.m[k], _count, true) && self.strict {
+ ok = ""
+ i = 0
continue
}
} else {
continue
}
}
- ok = v.File
- i = q
break
}
}
@@ -905,5 +882,5 @@ func (self *assProcessor) matchCache(k string) (string, string) {
if _, err := os.Stat(ok); err != nil {
ok = ""
}
- return ok, strconv.Itoa(i)
+ return ok, i
}
diff --git a/mkvlib/go.mod b/mkvlib/go.mod
index 39c7dad..94e1b7e 100644
--- a/mkvlib/go.mod
+++ b/mkvlib/go.mod
@@ -5,11 +5,12 @@ go 1.18
require (
github.com/antchfx/xmlquery v1.3.10
github.com/asticode/go-astikit v0.29.1
+ golang.org/x/image v0.0.0-20220413100746-70e8d0d3baa9
)
require (
github.com/antchfx/xpath v1.2.0 // indirect
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect
golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc // indirect
- golang.org/x/text v0.3.0 // indirect
+ golang.org/x/text v0.3.6 // indirect
)
diff --git a/mkvlib/shared.go b/mkvlib/shared.go
index 52c13cf..e2dccb9 100644
--- a/mkvlib/shared.go
+++ b/mkvlib/shared.go
@@ -11,7 +11,7 @@ import (
)
const libName = "mkvlib"
-const libVer = "v1.6.8"
+const libVer = "v1.6.9"
const LibFName = libName + " " + libVer