diff --git a/go.mod b/go.mod index 69c2bab..af53b47 100644 --- a/go.mod +++ b/go.mod @@ -3,14 +3,12 @@ module github.com/benoitkugler/go-weasyprint go 1.17 require ( - github.com/benoitkugler/pdf v0.0.7 + github.com/benoitkugler/pdf v0.0.14 github.com/benoitkugler/textprocessing v0.0.3 - github.com/benoitkugler/webrender v0.0.9 - github.com/go-text/typesetting v0.1.0 + github.com/benoitkugler/webrender v0.0.10 + github.com/go-text/typesetting v0.2.0 ) -replace github.com/benoitkugler/webrender => ../webrender - require ( github.com/benoitkugler/pstokenizer v1.0.1 // indirect github.com/benoitkugler/textlayout v0.3.0 // indirect diff --git a/go.sum b/go.sum index 77a3e70..ba57e6f 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,7 @@ github.com/benoitkugler/pdf v0.0.7 h1:959UFa5YoKLOARhK+EZL8GHjseE61/3juty4puwC3e0= github.com/benoitkugler/pdf v0.0.7/go.mod h1:r6/Weo/I6C80KgkJhnfbvlIygvj2sl/rWcTPWJdbfMs= +github.com/benoitkugler/pdf v0.0.14 h1:H1gB72gAYxumaAz6fGT15zJbSk+gzX/7XnO4+zkg46c= +github.com/benoitkugler/pdf v0.0.14/go.mod h1:r6/Weo/I6C80KgkJhnfbvlIygvj2sl/rWcTPWJdbfMs= github.com/benoitkugler/pstokenizer v1.0.0/go.mod h1:l1G2Voirz0q/jj0TQfabNxVsa8HZXh/VMxFSRALWTiE= github.com/benoitkugler/pstokenizer v1.0.1 h1:3+18uif4Dg4+w84AmkWPKOujhPKbLnkgxP1eb/KtiGg= github.com/benoitkugler/pstokenizer v1.0.1/go.mod h1:l1G2Voirz0q/jj0TQfabNxVsa8HZXh/VMxFSRALWTiE= @@ -11,8 +13,12 @@ github.com/benoitkugler/textprocessing v0.0.3 h1:Q2X+Z6vxuW5Bxn1R9RaNt0qcprBfpc2 github.com/benoitkugler/textprocessing v0.0.3/go.mod h1:/4bLyCf1QYywunMK3Gf89Nhb50YI/9POewqrLxWhxd4= github.com/benoitkugler/webrender v0.0.9 h1:kosTM7DM1qKhTUXoKGvnrq9/EZl0dPgCE6PpPorUgDI= github.com/benoitkugler/webrender v0.0.9/go.mod h1:9GlVnm/06qJ9FeDiaiQAHP0ksCgXuXQxkF5cL6O+s0Q= +github.com/benoitkugler/webrender v0.0.10 h1:MsAVz4d+V+q3/RGFNqx7O5qmCUT/lLNpxRf8OSB/NMc= +github.com/benoitkugler/webrender v0.0.10/go.mod h1:9GlVnm/06qJ9FeDiaiQAHP0ksCgXuXQxkF5cL6O+s0Q= github.com/go-text/typesetting v0.1.0 h1:vioSaLPYcHwPEPLT7gsjCGDCoYSbljxoHJzMnKwVvHw= github.com/go-text/typesetting v0.1.0/go.mod h1:d22AnmeKq/on0HNv73UFriMKc4Ez6EqZAofLhAzpSzI= +github.com/go-text/typesetting v0.2.0 h1:fbzsgbmk04KiWtE+c3ZD4W2nmCRzBqrqQOvYlwAOdho= +github.com/go-text/typesetting v0.2.0/go.mod h1:2+owI/sxa73XA581LAzVuEBZ3WEEV2pXeDswCH/3i1I= github.com/go-text/typesetting-utils v0.0.0-20231211103740-d9332ae51f04 h1:zBx+p/W2aQYtNuyZNcTfinWvXBQwYtDfme051PR/lAY= github.com/go-text/typesetting-utils v0.0.0-20231211103740-d9332ae51f04/go.mod h1:DDxDdQEnB70R8owOx3LVpEFvpMK9eeH1o2r0yZhFI9o= github.com/hhrutter/lzw v1.0.0 h1:laL89Llp86W3rRs83LvKbwYRx6INE8gDn0XNb1oXtm0= diff --git a/main_test.go b/main_test.go index 3a20e89..0b1a941 100644 --- a/main_test.go +++ b/main_test.go @@ -13,7 +13,7 @@ import ( "github.com/benoitkugler/webrender/logger" "github.com/benoitkugler/webrender/text" "github.com/benoitkugler/webrender/utils" - "github.com/go-text/typesetting/opentype/loader" + ot "github.com/go-text/typesetting/font/opentype" ) var fontconfig text.FontConfiguration @@ -183,17 +183,18 @@ func TestSVGGradient(t *testing.T) { } } -func TestTmp(t *testing.T) { +func TestFixUpstreamFont(t *testing.T) { + t.Skip() f, _ := os.Open("resources_test/weasyprint.otb") - ft, err := loader.NewLoader(f) + ft, err := ot.NewLoader(f) if err != nil { t.Fatal(err) } - fmt.Println(ft.RawTable(loader.MustNewTag("loca"))) - fmt.Println(ft.HasTable(loader.MustNewTag("glyf"))) - var allTables []loader.Table + fmt.Println(ft.RawTable(ot.MustNewTag("loca"))) + fmt.Println(ft.HasTable(ot.MustNewTag("glyf"))) + var allTables []ot.Table for _, table := range ft.Tables() { - if table == loader.MustNewTag("loca") || table == loader.MustNewTag("glyf") { + if table == ot.MustNewTag("loca") || table == ot.MustNewTag("glyf") { continue } fmt.Println(table) @@ -201,12 +202,12 @@ func TestTmp(t *testing.T) { if err != nil { t.Fatal(err) } - allTables = append(allTables, loader.Table{ + allTables = append(allTables, ot.Table{ Tag: table, Content: b, }) } - err = os.WriteFile("weasyprint.otb_fixed", loader.WriteTTF(allTables), os.ModePerm) + err = os.WriteFile("weasyprint.otb_fixed", ot.WriteTTF(allTables), os.ModePerm) if err != nil { t.Fatal(err) } diff --git a/pdf/page.go b/pdf/page.go index 6ad26b8..4f6bc07 100644 --- a/pdf/page.go +++ b/pdf/page.go @@ -269,8 +269,10 @@ func (g *group) DrawWithOpacity(opacity fl, gr backend.Canvas) { content := gr.(*group).stream.ToXFormObject(compressStreams) form := &model.XObjectTransparencyGroup{ XObjectForm: *content, - CS: model.ColorSpaceRGB, - I: true, + Group: model.TransparencyGroup{ + CS: model.ColorSpaceRGB, + I: true, + }, } g.stream.SetFillAlpha(opacity) g.stream.SetStrokeAlpha(opacity) diff --git a/pdf/text.go b/pdf/text.go index 52731fc..fdba11c 100644 --- a/pdf/text.go +++ b/pdf/text.go @@ -16,10 +16,9 @@ import ( "github.com/benoitkugler/webrender/backend" "github.com/benoitkugler/webrender/text" drawText "github.com/benoitkugler/webrender/text/draw" - "github.com/go-text/typesetting/opentype/api" - "github.com/go-text/typesetting/opentype/api/font" - "github.com/go-text/typesetting/opentype/loader" - "github.com/go-text/typesetting/opentype/tables" + "github.com/go-text/typesetting/font" + ot "github.com/go-text/typesetting/font/opentype" + "github.com/go-text/typesetting/font/opentype/tables" ) type pdfFont struct { @@ -182,7 +181,7 @@ func cidWidths(dict map[backend.GID]backend.GlyphExtents) []model.CIDWidth { // returns true if a valid 'glyf' , 'cff ' 'or' tables is present func isSupportedFont(content []byte) bool { - ld, err := loader.NewLoader(bytes.NewReader(content)) + ld, err := ot.NewLoader(bytes.NewReader(content)) if err != nil { return false } @@ -211,9 +210,9 @@ func isSupportedFont(content []byte) bool { glyf, _ := tables.ParseGlyf(glyfRaw, loca) hasValidGlyf = len(glyf) > 0 } - hasCff := ld.HasTable(loader.MustNewTag("CFF ")) + hasCff := ld.HasTable(ot.MustNewTag("CFF ")) - hasBitmap := ld.HasTable(loader.MustNewTag("EBDT")) && ld.HasTable(loader.MustNewTag("EBLC")) + hasBitmap := ld.HasTable(ot.MustNewTag("EBDT")) && ld.HasTable(ot.MustNewTag("EBLC")) return hasValidGlyf || hasCff || hasBitmap } @@ -224,7 +223,7 @@ func newFontFile(fontDesc backend.FontDescription, font pdfFont, content []byte) // subset the font set := glyphSet{} for gid := range font.Cmap { - set.Add(api.GID(gid)) + set.Add(ot.GID(gid)) } contentS, err := subset(bytes.NewReader(content), set) if err != nil { diff --git a/pdf/text_font_subset.go b/pdf/text_font_subset.go index 387f2af..56e3cc8 100644 --- a/pdf/text_font_subset.go +++ b/pdf/text_font_subset.go @@ -4,32 +4,31 @@ import ( "encoding/binary" "fmt" - "github.com/go-text/typesetting/opentype/api" - "github.com/go-text/typesetting/opentype/api/font" - "github.com/go-text/typesetting/opentype/loader" - "github.com/go-text/typesetting/opentype/tables" + "github.com/go-text/typesetting/font" + ot "github.com/go-text/typesetting/font/opentype" + "github.com/go-text/typesetting/font/opentype/tables" ) // basic font subset var ( - maxpTag = loader.MustNewTag("maxp") - locaTag = loader.MustNewTag("loca") - glyfTag = loader.MustNewTag("glyf") - - fvarTag = loader.MustNewTag("fvar") - avarTag = loader.MustNewTag("avar") - mVARTag = loader.MustNewTag("MVAR") - gvarTag = loader.MustNewTag("gvar") - hVARTag = loader.MustNewTag("HVAR") - vVARTag = loader.MustNewTag("VVAR") - - gSUBTag = loader.MustNewTag("GSUB") - gPOSTag = loader.MustNewTag("GPOS") + maxpTag = ot.MustNewTag("maxp") + locaTag = ot.MustNewTag("loca") + glyfTag = ot.MustNewTag("glyf") + + fvarTag = ot.MustNewTag("fvar") + avarTag = ot.MustNewTag("avar") + mVARTag = ot.MustNewTag("MVAR") + gvarTag = ot.MustNewTag("gvar") + hVARTag = ot.MustNewTag("HVAR") + vVARTag = ot.MustNewTag("VVAR") + + gSUBTag = ot.MustNewTag("GSUB") + gPOSTag = ot.MustNewTag("GPOS") ) // several tables are not useful in PDF -func ignoreTable(table loader.Tag) bool { +func ignoreTable(table ot.Tag) bool { switch table { case fvarTag, avarTag, mVARTag, gvarTag, hVARTag, vVARTag, gSUBTag, gPOSTag: return true @@ -38,13 +37,13 @@ func ignoreTable(table loader.Tag) bool { } } -type glyphSet map[api.GID]struct{} +type glyphSet map[ot.GID]struct{} -func (gs glyphSet) Add(g api.GID) { gs[g] = struct{}{} } +func (gs glyphSet) Add(g ot.GID) { gs[g] = struct{}{} } // recursively fetch composite glyphs deps, adding it to the set func handleComposite(glyphs glyphSet, glyf tables.Glyf) { - queue := make([]api.GID, 0, len(glyphs)) + queue := make([]ot.GID, 0, len(glyphs)) // start with the given glyphs for g := range glyphs { queue = append(queue, g) @@ -63,7 +62,7 @@ func handleComposite(glyphs glyphSet, glyf tables.Glyf) { case tables.CompositeGlyph: // fetch deps for _, part := range data.Glyphs { - dep := api.GID(part.GlyphIndex) + dep := ot.GID(part.GlyphIndex) // if not already seen, add it to the queue if _, ok := glyphs[dep]; !ok { glyphs.Add(dep) @@ -79,8 +78,8 @@ func handleComposite(glyphs glyphSet, glyf tables.Glyf) { // Variables font are not supported : the variable tables will be dropped // TODO: For now, [subset] only supports the 'glyf' table -func subset(input loader.Resource, glyphs glyphSet) ([]byte, error) { - ld, err := loader.NewLoader(input) +func subset(input ot.Resource, glyphs glyphSet) ([]byte, error) { + ld, err := ot.NewLoader(input) if err != nil { return nil, fmt.Errorf("subsetting failed: %s", err) } @@ -129,13 +128,13 @@ func subset(input loader.Resource, glyphs glyphSet) ([]byte, error) { } origTablesTags := ld.Tables() - tables := make([]loader.Table, 0, len(origTablesTags)) + tables := make([]ot.Table, 0, len(origTablesTags)) for _, tag := range origTablesTags { if ignoreTable(tag) { continue } - table := loader.Table{Tag: tag} + table := ot.Table{Tag: tag} if tag == glyfTag && glyfNew != nil { table.Content = glyfNew @@ -151,7 +150,7 @@ func subset(input loader.Resource, glyphs glyphSet) ([]byte, error) { tables = append(tables, table) } - return loader.WriteTTF(tables), nil + return ot.WriteTTF(tables), nil } // mutate and returns [loca] and [glyph] @@ -159,8 +158,8 @@ func subsetGlyf(loca []uint32, glyf []byte, glyphs glyphSet) ([]uint32, []byte) // trim the unused glyph data, and adjust the offset to have start == end currentStart := loca[0] nbGlyphs := len(loca) - 1 - maxGlyphUsed := api.GID(0) - for gid := api.GID(0); gid < api.GID(nbGlyphs); gid++ { + maxGlyphUsed := ot.GID(0) + for gid := ot.GID(0); gid < ot.GID(nbGlyphs); gid++ { origStart, origEnd := loca[gid], loca[gid+1] // start and end offsets will change, but not the length glyphLength := origEnd - origStart diff --git a/pdf/text_font_subset_test.go b/pdf/text_font_subset_test.go index e41674e..a0c59d2 100644 --- a/pdf/text_font_subset_test.go +++ b/pdf/text_font_subset_test.go @@ -4,11 +4,11 @@ import ( "reflect" "testing" - "github.com/go-text/typesetting/opentype/api" - "github.com/go-text/typesetting/opentype/tables" + ot "github.com/go-text/typesetting/font/opentype" + "github.com/go-text/typesetting/font/opentype/tables" ) -func gs(gids ...api.GID) glyphSet { +func gs(gids ...ot.GID) glyphSet { out := make(glyphSet) for _, gid := range gids { out.Add(gid) @@ -16,7 +16,7 @@ func gs(gids ...api.GID) glyphSet { return out } -func comp(deps ...api.GID) tables.Glyph { +func comp(deps ...ot.GID) tables.Glyph { var parts []tables.CompositeGlyphPart for _, dep := range deps { parts = append(parts, tables.CompositeGlyphPart{GlyphIndex: uint16(dep)})