Showing preview only (330K chars total). Download the full file or copy to clipboard to get everything.
Repository: sopov/resumeio2pdf
Branch: main
Commit: 528274d3c22e
Files: 108
Total size: 300.1 KB
Directory structure:
gitextract_c0w8xc36/
├── .github/
│ └── workflows/
│ ├── codeql-analysis.yml
│ ├── go.yml
│ └── golangci-lint.yml
├── .gitignore
├── LICENSE
├── README.md
├── go.mod
├── go.sum
├── main.go
└── vendor/
├── github.com/
│ ├── phpdave11/
│ │ └── gofpdi/
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── const.go
│ │ ├── go.mod
│ │ ├── go.sum
│ │ ├── gofpdi.go
│ │ ├── helper.go
│ │ ├── importer.go
│ │ ├── reader.go
│ │ └── writer.go
│ ├── pkg/
│ │ └── errors/
│ │ ├── .gitignore
│ │ ├── .travis.yml
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── appveyor.yml
│ │ ├── errors.go
│ │ └── stack.go
│ └── signintech/
│ └── gopdf/
│ ├── .gitignore
│ ├── Changelog.md
│ ├── LICENSE
│ ├── README.md
│ ├── box.go
│ ├── buff.go
│ ├── buff_write.go
│ ├── buffer_pool.go
│ ├── cache_contact_color.go
│ ├── cache_content_gray.go
│ ├── cache_content_image.go
│ ├── cache_content_imported_object.go
│ ├── cache_content_line.go
│ ├── cache_content_line_type.go
│ ├── cache_content_line_width.go
│ ├── cache_content_oval.go
│ ├── cache_content_polygon.go
│ ├── cache_content_rectangle.go
│ ├── cache_content_rotate.go
│ ├── cache_content_text.go
│ ├── cache_contnent_curve.go
│ ├── catalog_obj.go
│ ├── cell_option.go
│ ├── cid_font_obj.go
│ ├── config.go
│ ├── content_obj.go
│ ├── current.go
│ ├── device_rgb_obj.go
│ ├── embedfont_obj.go
│ ├── encoding_obj.go
│ ├── encryption_obj.go
│ ├── ext_g_state_obj.go
│ ├── font_obj.go
│ ├── font_option.go
│ ├── fontconverthelper.go
│ ├── fontdescriptor_obj.go
│ ├── fontmaker/
│ │ └── core/
│ │ ├── fontmaker.go
│ │ ├── fontmap.go
│ │ ├── kern_table.go
│ │ ├── math.go
│ │ ├── table_directory_entry.go
│ │ ├── ttf_info.go
│ │ ├── ttfparser.go
│ │ ├── ttfparser_cmap_other_format.go
│ │ └── ttfparser_kern.go
│ ├── func_kern_override.go
│ ├── go.mod
│ ├── go.sum
│ ├── gopdf.go
│ ├── i_cache_contneter.go
│ ├── ifont.go
│ ├── image_holder.go
│ ├── image_obj.go
│ ├── image_obj_parse.go
│ ├── img_info.go
│ ├── imported_obj.go
│ ├── iobj.go
│ ├── link_option.go
│ ├── list_cache_content.go
│ ├── map_of_character_To_glyph_index.go
│ ├── margin.go
│ ├── outlines_obj.go
│ ├── page_obj.go
│ ├── page_option.go
│ ├── page_sizes.go
│ ├── pages_obj.go
│ ├── pdf_dictionary_obj.go
│ ├── pdf_info_obj.go
│ ├── pdf_protection.go
│ ├── point.go
│ ├── procset_obj.go
│ ├── rect.go
│ ├── smask_obj.go
│ ├── strhelper.go
│ ├── style.go
│ ├── subfont_descriptor_obj.go
│ ├── subset_font_obj.go
│ ├── transparency.go
│ ├── transparency_xobject_group.go
│ ├── ttf_option.go
│ └── unicode_map.go
└── modules.txt
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/workflows/codeql-analysis.yml
================================================
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"
on:
push:
branches: [ main ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ main ]
schedule:
- cron: '43 20 * * 5'
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: [ 'go' ]
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
# Learn more:
# https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed
steps:
- name: Checkout repository
uses: actions/checkout@v2
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v1
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# queries: ./path/to/local/query, your-org/your-repo/queries@main
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v1
# ℹ️ Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
# and modify them (or add more) to build your code if your project
# uses a compiled language
#- run: |
# make bootstrap
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1
================================================
FILE: .github/workflows/go.yml
================================================
name: Go
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Go
uses: actions/setup-go@v2
with:
go-version: 1.17
- name: Build
run: go build -v ./...
- name: Test
run: go test -v ./...
================================================
FILE: .github/workflows/golangci-lint.yml
================================================
name: golangci-lint
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
golangci:
name: lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: golangci-lint
uses: golangci/golangci-lint-action@v2
with:
version: latest
================================================
FILE: .gitignore
================================================
# PDF files
*.pdf
# Test binary, built with `go test -c`
*.test
.idea/
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2021 Leonid Sopov
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: README.md
================================================
# resumeio2pdf
> ⚠️ This project is no longer maintained.
> Resume.io made changes on their side, so the tool no longer works.
A progam that allows users to download their resumes from [resume.io](https://resume.io/) as PDFs, including links.
## Usage
```bash
./resumeio2pdf [options] [ID or URL]
./resumeio2pdf https://resume.io/r/SecureID
```
Options:
* `-pdf` (string) name of pdf file (default: `SecureID` + `.pdf`)
* `-sid` (string) SecureID of resume
* `-url` (string) link to resume of the format: https://resume.io/r/SecureID
* `-verbose` show detail information
* `-version` show version
* `-y` overwrite PDF file
## Quick Instructions
1. Run `go build` to generate the executable.
2. Run `./resumeio2pdf https://resume.io/r/[SecureID]` where the provided URL is that generated by the **Share Link** on resume.io.
## Step-by-Step Instructions
1. Download the application by clicking the **<> Code** button and choosing **Download ZIP**.
2. Once the download has been completed, extract the files. You will end up with a **resumeio2pdf-main/** folder.
3. Open your terminal and navigate to the **resumeio2pdf-main/** folder that you have just extracted.
- You may have the option to skip this by simply choosing the **New Terminal at Folder** after right clicking on the folder.
4. With your terminal still open, type the command `go version` to see if you already have Go installed.
- If you get a message with version information that looks something like `go version go1.17.6 …` then you can skip to Step 6.
- Otherwise, continue on to the next step.
5. Open your web browser and navigate to the [Go Downloads Page](https://go.dev/dl/) and choose your operating system from the **Featured Downloads** section. Download the package and follow the installation instructions.
- Upon completion, restart your terminal and navigate back to the **resumeio2pdf-main/** folder. You should now see version information after typing in the `go version` command. If you have issues with this step, try visiting the [Go Download and Install Page](https://go.dev/doc/install) for the official instructions.
6. With Go installed, you can now run the `go build` command to build the executable file that will download your PDF.
- A successful build will not display any confirmation in the terminal. However, you can check the files in the **resumeio2pdf-main/** folder to confirm that a **resumeio2pdf** executable file has been generated by the command.
- If you received an error in the terminal, make sure you are still in the **resumeio2pdf-main/** folder before running the command. Otherwise, trace back through the above steps and give it another shot.
7. Finally, you can run the `./resumeio2pdf https://resume.io/r/[SecureID]` where the provided URL is that generated by the **Share Link** on resume.io. When the process is complete, you will receive a message in the terminal that your file has been stored as **\[SecureID].pdf**. Check the **resumeio2pdf-main/** folder for your file.
## Alternative Methods
Repository with binary files: https://github.com/sopov/resumeio2pdf.bin
## Other Questions and Concerns
* I don't understand how to install and/or use Go.
* Can you download my resume for me?
* Can you make a video tutorial?
Please visit the [pricing page on Resume.io](https://resume.io/pricing) which provides fair and affordable prices for this service, including an easy method of downloading your resume without the use of this software.
================================================
FILE: go.mod
================================================
module github.com/sopov/resumeio2pdf
go 1.16
require github.com/signintech/gopdf v0.9.20
================================================
FILE: go.sum
================================================
github.com/phpdave11/gofpdi v1.0.11 h1:wsBNx+3S0wy1dEp6fzv281S74ogZGgIdYWV2PugWgho=
github.com/phpdave11/gofpdi v1.0.11/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/signintech/gopdf v0.9.20 h1:UJInJStc5NpkSCSZCmkSrUy7JR/BqRWpoH50c7hJJ5w=
github.com/signintech/gopdf v0.9.20/go.mod h1:PXwitUSeFWEWs+wHVjSS3cUmD4PTXB686ozqfDIQQoQ=
================================================
FILE: main.go
================================================
package main
import (
"encoding/json"
"errors"
"flag"
"fmt"
"io"
"log"
"net/http"
"os"
"path/filepath"
"regexp"
"time"
"github.com/signintech/gopdf"
)
const (
Version = "1.0"
NameOfProgram = "resumeio2pdf"
Copy = "Copyright (c) 2021, Leonid Sopov <leonid@sopov.org>"
CopyURL = "https://github.com/sopov/resumeio2pdf/"
resumePage = "https://resume.io/r/%s"
resumeMeta = "https://ssr.resume.tools/meta/ssid-%s?cache=%s"
resumeExt = "png" // png, jpeg
resumeIMG = "https://ssr.resume.tools/to-image/ssid-%s-%d.%s?cache=%s&size=%d"
resumeSize = 1800
Timeout = 60 * time.Second
exitCodeMisuseArgs = 2
)
var (
url = flag.String("url", "", "link to resume of the format: https://resume.io/r/SecureID")
sid = flag.String("sid", "", "SecureID of resume")
showVersion = flag.Bool("version", false, "show version")
verbose = flag.Bool("verbose", false, "show detail information")
overWrite = flag.Bool("y", false, "overwrite PDF file")
pdfFileName = flag.String("pdf", "", "name of pdf file (default: SecureID + .pdf)")
httpClient = &http.Client{Timeout: Timeout}
reSID = regexp.MustCompile(`^[[:alnum:]]+$`)
reID = regexp.MustCompile(`^\d+$`)
reURL = regexp.MustCompile(`^https://resume[.]io/r/([[:alnum:]]+)`)
reIDURL = regexp.MustCompile(`^https://resume[.]io/(?:app|api)/.*?/(\d+)`)
)
type metaLink struct {
URL string `json:"url"`
Left float64 `json:"left"`
Top float64 `json:"top"`
Height float64 `json:"height"`
Width float64 `json:"width"`
}
type metaViewPort struct {
Height float64 `json:"height"`
Width float64 `json:"width"`
}
type metaPageInfo struct {
Links []metaLink `json:"links"`
ViewPort metaViewPort `json:"viewport"`
}
type metaInfo struct {
Pages []metaPageInfo `json:"pages"`
}
func main() {
if !readFlags() || *sid == "" {
os.Exit(exitCodeMisuseArgs)
}
loggerf("SecureID: %s", *sid)
loggerf("URL: %s", *url)
loggerf("PDF: %s", *pdfFileName)
meta, err := getMeta()
if err != nil {
log.Fatalln(err)
}
images, err := getResumeImages(len(meta.Pages))
if err != nil {
log.Fatalln(err)
}
err = generatePDF(meta, images)
if err != nil {
log.Fatalln(err)
}
cleanup(images)
fmt.Printf("Resume stored to %s\n", *pdfFileName)
}
func cleanup(images []string) {
for _, file := range images {
if _, err := os.Stat(file); os.IsNotExist(err) {
continue
}
if err := os.Remove(file); err != nil {
fmt.Printf("Error on remove `%s': %s", file, err.Error())
} else {
loggerf("Image `%s' successfully deleted.", file)
}
}
}
func generatePDF(info *metaInfo, images []string) error {
pdf := gopdf.GoPdf{}
logger("Start Generate PDF")
pageSize := gopdf.Rect{
W: info.Pages[0].ViewPort.Width,
H: info.Pages[0].ViewPort.Height,
}
pdf.Start(gopdf.Config{PageSize: pageSize})
for i, image := range images {
loggerf("Add page #%d", i+1)
pageSize := gopdf.Rect{
W: info.Pages[i].ViewPort.Width,
H: info.Pages[i].ViewPort.Height,
}
opt := gopdf.PageOption{
PageSize: &pageSize,
}
pdf.AddPageWithOption(opt)
err := pdf.Image(image, 0, 0, &pageSize)
if err != nil {
return err
}
for _, link := range info.Pages[i].Links {
loggerf("Add link to %s", link.URL)
x := link.Left
y := pageSize.H - link.Top - link.Height
pdf.AddExternalLink(link.URL, x, y, link.Width, link.Height)
}
}
loggerf("Store PDF to `%s'", *pdfFileName)
return pdf.WritePdf(*pdfFileName)
}
func getResumeImages(p int) (pages []string, err error) {
if p < 1 {
return nil, errors.New("required one or more pages")
}
for pID := 1; pID <= p; pID++ {
pageFile := fmt.Sprintf("%s-%d.%s", *sid, pID, resumeExt)
if _, err := os.Stat(pageFile); os.IsNotExist(err) {
loggerf("Download image #%d/%d", pID, p)
imgURL := fmt.Sprintf(resumeIMG, *sid, pID, resumeExt, time.Now().UTC().Format(time.RFC3339), resumeSize)
if err := downloadPage(imgURL, pageFile); err != nil {
return pages, err
}
}
pages = append(pages, pageFile)
}
loggerf("Total %d pages", len(pages))
return pages, nil
}
func downloadPage(imgURL, imgFile string) error {
r, err := httpClient.Get(imgURL)
if err != nil {
return err
}
defer r.Body.Close()
if r.StatusCode != http.StatusOK {
return errors.New(r.Status)
}
file, err := os.Create(imgFile)
if err != nil {
return err
}
defer file.Close()
_, err = io.Copy(file, r.Body)
if err != nil {
return err
}
return nil
}
func getJSON(url string, target interface{}) error {
logger("Download meta information")
r, err := httpClient.Get(url)
if err != nil {
return err
}
defer r.Body.Close()
if r.StatusCode != http.StatusOK {
return fmt.Errorf("Can't download information from the site resume.io. Please, check URL.\n\nError: %s", r.Status)
}
decoder := json.NewDecoder(r.Body)
err = decoder.Decode(&target)
if err != nil {
return err
}
return nil
}
func getMeta() (meta *metaInfo, err error) {
metaURL := fmt.Sprintf(resumeMeta, *sid, time.Now().UTC().Format(time.RFC3339))
meta = &metaInfo{}
err = getJSON(metaURL, meta)
return meta, err
}
func readFlags() bool {
flag.Parse()
if *showVersion {
fmt.Printf("Version: %s\n", Version)
return false
}
if !extractArg() {
return false
}
if *sid == "" && *url == "" {
usages()
return false
}
if *sid != "" {
if !reSID.MatchString(*sid) {
fmt.Println("The ID must be as alphanumeric")
return false
}
*url = fmt.Sprintf(resumePage, *sid)
}
if reIDURL.MatchString(*url) {
usageID()
return false
}
if !reURL.MatchString(*url) {
msg := fmt.Sprintf("The URL must be in the format %s\n", resumePage)
fmt.Printf(msg, "SecureID")
return false
}
if *sid == "" {
m := reURL.FindSubmatch([]byte(*url))
*sid = string(m[1])
}
if *pdfFileName == "" {
*pdfFileName = fmt.Sprintf("%s.pdf", *sid)
}
rePDF := regexp.MustCompile(`(?i)[.]pdf$`)
if !rePDF.MatchString(*pdfFileName) {
*pdfFileName = fmt.Sprintf("%s.pdf", *pdfFileName)
}
if _, err := os.Stat(*pdfFileName); !*overWrite && !os.IsNotExist(err) {
fmt.Printf("File `%s' already exists.\n\nFor overwrite run with `-y' flag\n", *pdfFileName)
return false
}
return true
}
func extractArg() bool {
arg := flag.Arg(0)
if arg == "" {
return true
}
if reID.MatchString(arg) {
usageID()
return false
}
if reIDURL.MatchString(arg) {
usageID()
return false
}
if reSID.MatchString(arg) {
*sid = arg
return true
}
if reURL.MatchString(arg) {
*url = arg
return true
}
return true
}
func usages() {
fileExec, err := os.Executable()
if err == nil {
fileExec = filepath.Base(fileExec)
}
if fileExec == "" {
fileExec = NameOfProgram
}
fmt.Println("Syntax:")
fmt.Println(" ", fileExec, "[options] [ID or URL]")
fmt.Println()
fmt.Println("Options:")
flag.PrintDefaults()
fmt.Println()
fmt.Println(Copy)
fmt.Println(CopyURL)
}
func usageID() {
fmt.Println("Open in browser: https://resume.io/app/resumes")
fmt.Println("Click on `...More' / `Share a link', and lunch with private URL.")
}
func logger(v ...interface{}) {
if !*verbose {
return
}
log.Println(v...)
}
func loggerf(format string, a ...interface{}) {
if !*verbose {
return
}
log.Printf(format, a...)
}
================================================
FILE: vendor/github.com/phpdave11/gofpdi/LICENSE
================================================
The MIT License (MIT)
Copyright (c) 2019-2020 David Barnes
Copyright (c) 2017 Setasign - Jan Slabon, https://www.setasign.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
================================================
FILE: vendor/github.com/phpdave11/gofpdi/README.md
================================================
# gofpdi
[](https://raw.githubusercontent.com/phpdave11/gofpdi/master/LICENSE)
[](https://goreportcard.com/report/github.com/phpdave11/gofpdi)
[](https://godoc.org/github.com/phpdave11/gofpdi)
## Go Free PDF Document Importer
gofpdi allows you to import an existing PDF into a new PDF. The following PDF generation libraries are supported:
- [gopdf](https://github.com/signintech/gopdf)
- [gofpdf](https://github.com/phpdave11/gofpdf)
## Acknowledgments
This package’s code is derived from the [fpdi](https://github.com/Setasign/FPDI/tree/1.6.x-legacy) library created by [Jan Slabon](https://github.com/JanSlabon).
[mrtsbt](https://github.com/mrtsbt) added support for reading a PDF from an `io.ReadSeeker` stream and also added support for using gofpdi concurrently. [Asher Tuggle](https://github.com/awesomeunleashed) added support for reading PDFs that have split xref tables.
## Examples
### gopdf example
```go
package main
import (
"github.com/signintech/gopdf"
"io"
"net/http"
"os"
)
func main() {
var err error
// Download a Font
fontUrl := "https://github.com/google/fonts/raw/master/ofl/daysone/DaysOne-Regular.ttf"
if err = DownloadFile("example-font.ttf", fontUrl); err != nil {
panic(err)
}
// Download a PDF
fileUrl := "https://tcpdf.org/files/examples/example_012.pdf"
if err = DownloadFile("example-pdf.pdf", fileUrl); err != nil {
panic(err)
}
pdf := gopdf.GoPdf{}
pdf.Start(gopdf.Config{PageSize: gopdf.Rect{W: 595.28, H: 841.89}}) //595.28, 841.89 = A4
pdf.AddPage()
err = pdf.AddTTFFont("daysone", "example-font.ttf")
if err != nil {
panic(err)
}
err = pdf.SetFont("daysone", "", 20)
if err != nil {
panic(err)
}
// Color the page
pdf.SetLineWidth(0.1)
pdf.SetFillColor(124, 252, 0) //setup fill color
pdf.RectFromUpperLeftWithStyle(50, 100, 400, 600, "FD")
pdf.SetFillColor(0, 0, 0)
pdf.SetX(50)
pdf.SetY(50)
pdf.Cell(nil, "Import existing PDF into GoPDF Document")
// Import page 1
tpl1 := pdf.ImportPage("example-pdf.pdf", 1, "/MediaBox")
// Draw pdf onto page
pdf.UseImportedTemplate(tpl1, 50, 100, 400, 0)
pdf.WritePdf("example.pdf")
}
// DownloadFile will download a url to a local file. It's efficient because it will
// write as it downloads and not load the whole file into memory.
func DownloadFile(filepath string, url string) error {
// Get the data
resp, err := http.Get(url)
if err != nil {
return err
}
defer resp.Body.Close()
// Create the file
out, err := os.Create(filepath)
if err != nil {
return err
}
defer out.Close()
// Write the body to file
_, err = io.Copy(out, resp.Body)
return err
}
```
Generated PDF: [example.pdf](https://github.com/signintech/gopdf/files/3144466/example.pdf)
Screenshot of PDF:

### gofpdf example #1 - import PDF from file
```go
package main
import (
"github.com/phpdave11/gofpdf"
"github.com/phpdave11/gofpdf/contrib/gofpdi"
"io"
"net/http"
"os"
)
func main() {
var err error
pdf := gofpdf.New("P", "mm", "A4", "")
// Download a PDF
fileUrl := "https://tcpdf.org/files/examples/example_026.pdf"
if err = DownloadFile("example-pdf.pdf", fileUrl); err != nil {
panic(err)
}
// Import example-pdf.pdf with gofpdi free pdf document importer
tpl1 := gofpdi.ImportPage(pdf, "example-pdf.pdf", 1, "/MediaBox")
pdf.AddPage()
pdf.SetFillColor(200, 700, 220)
pdf.Rect(20, 50, 150, 215, "F")
// Draw imported template onto page
gofpdi.UseImportedTemplate(pdf, tpl1, 20, 50, 150, 0)
pdf.SetFont("Helvetica", "", 20)
pdf.Cell(0, 0, "Import existing PDF into gofpdf document with gofpdi")
err = pdf.OutputFileAndClose("example.pdf")
if err != nil {
panic(err)
}
}
// DownloadFile will download a url to a local file. It's efficient because it will
// write as it downloads and not load the whole file into memory.
func DownloadFile(filepath string, url string) error {
// Get the data
resp, err := http.Get(url)
if err != nil {
return err
}
defer resp.Body.Close()
// Create the file
out, err := os.Create(filepath)
if err != nil {
return err
}
defer out.Close()
// Write the body to file
_, err = io.Copy(out, resp.Body)
return err
}
```
Generated PDF: [example.pdf](https://github.com/phpdave11/gofpdf/files/3178770/example.pdf)
Screenshot of PDF:

### gofpdf example #2 - import PDF from stream
```go
package main
import (
"bytes"
"github.com/phpdave11/gofpdf"
"github.com/phpdave11/gofpdf/contrib/gofpdi"
"io"
"io/ioutil"
"net/http"
)
func main() {
var err error
pdf := gofpdf.New("P", "mm", "A4", "")
// Download a PDF into memory
res, err := http.Get("https://tcpdf.org/files/examples/example_038.pdf")
if err != nil {
panic(err)
}
pdfBytes, err := ioutil.ReadAll(res.Body)
res.Body.Close()
if err != nil {
panic(err)
}
// convert []byte to io.ReadSeeker
rs := io.ReadSeeker(bytes.NewReader(pdfBytes))
// Import in-memory PDF stream with gofpdi free pdf document importer
tpl1 := gofpdi.ImportPageFromStream(pdf, &rs, 1, "/TrimBox")
pdf.AddPage()
pdf.SetFillColor(200, 700, 220)
pdf.Rect(20, 50, 150, 215, "F")
// Draw imported template onto page
gofpdi.UseImportedTemplate(pdf, tpl1, 20, 50, 150, 0)
pdf.SetFont("Helvetica", "", 20)
pdf.Cell(0, 0, "Import PDF stream into gofpdf document with gofpdi")
err = pdf.OutputFileAndClose("example.pdf")
if err != nil {
panic(err)
}
}
```
Generated PDF:
[example.pdf](https://github.com/phpdave11/gofpdi/files/3483219/example.pdf)
Screenshot of PDF:

================================================
FILE: vendor/github.com/phpdave11/gofpdi/const.go
================================================
package gofpdi
const (
PDF_TYPE_NULL = iota
PDF_TYPE_NUMERIC
PDF_TYPE_TOKEN
PDF_TYPE_HEX
PDF_TYPE_STRING
PDF_TYPE_DICTIONARY
PDF_TYPE_ARRAY
PDF_TYPE_OBJDEC
PDF_TYPE_OBJREF
PDF_TYPE_OBJECT
PDF_TYPE_STREAM
PDF_TYPE_BOOLEAN
PDF_TYPE_REAL
)
================================================
FILE: vendor/github.com/phpdave11/gofpdi/go.mod
================================================
module github.com/phpdave11/gofpdi
go 1.12
require github.com/pkg/errors v0.8.1
================================================
FILE: vendor/github.com/phpdave11/gofpdi/go.sum
================================================
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
================================================
FILE: vendor/github.com/phpdave11/gofpdi/gofpdi.go
================================================
package gofpdi
================================================
FILE: vendor/github.com/phpdave11/gofpdi/helper.go
================================================
package gofpdi
import (
"strings"
)
// Determine if a value is numeric
// Courtesy of https://github.com/syyongx/php2go/blob/master/php.go
func is_numeric(val interface{}) bool {
switch val.(type) {
case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64:
case float32, float64, complex64, complex128:
return true
case string:
str := val.(string)
if str == "" {
return false
}
// Trim any whitespace
str = strings.TrimSpace(str)
//fmt.Println(str)
if str[0] == '-' || str[0] == '+' {
if len(str) == 1 {
return false
}
str = str[1:]
}
// hex
if len(str) > 2 && str[0] == '0' && (str[1] == 'x' || str[1] == 'X') {
for _, h := range str[2:] {
if !((h >= '0' && h <= '9') || (h >= 'a' && h <= 'f') || (h >= 'A' && h <= 'F')) {
return false
}
}
return true
}
// 0-9,Point,Scientific
p, s, l := 0, 0, len(str)
for i, v := range str {
if v == '.' { // Point
if p > 0 || s > 0 || i+1 == l {
return false
}
p = i
} else if v == 'e' || v == 'E' { // Scientific
if i == 0 || s > 0 || i+1 == l {
return false
}
s = i
} else if v < '0' || v > '9' {
return false
}
}
return true
}
return false
}
func in_array(needle interface{}, hystack interface{}) bool {
switch key := needle.(type) {
case string:
for _, item := range hystack.([]string) {
if key == item {
return true
}
}
case int:
for _, item := range hystack.([]int) {
if key == item {
return true
}
}
case int64:
for _, item := range hystack.([]int64) {
if key == item {
return true
}
}
default:
return false
}
return false
}
// Taken from png library
// intSize is either 32 or 64.
const intSize = 32 << (^uint(0) >> 63)
func abs(x int) int {
// m := -1 if x < 0. m := 0 otherwise.
m := x >> (intSize - 1)
// In two's complement representation, the negative number
// of any number (except the smallest one) can be computed
// by flipping all the bits and add 1. This is faster than
// code with a branch.
// See Hacker's Delight, section 2-4.
return (x ^ m) - m
}
// filterPaeth applies the Paeth filter to the cdat slice.
// cdat is the current row's data, pdat is the previous row's data.
func filterPaeth(cdat, pdat []byte, bytesPerPixel int) {
var a, b, c, pa, pb, pc int
for i := 0; i < bytesPerPixel; i++ {
a, c = 0, 0
for j := i; j < len(cdat); j += bytesPerPixel {
b = int(pdat[j])
pa = b - c
pb = a - c
pc = abs(pa + pb)
pa = abs(pa)
pb = abs(pb)
if pa <= pb && pa <= pc {
// No-op.
} else if pb <= pc {
a = b
} else {
a = c
}
a += int(cdat[j])
a &= 0xff
cdat[j] = uint8(a)
c = b
}
}
}
================================================
FILE: vendor/github.com/phpdave11/gofpdi/importer.go
================================================
package gofpdi
import (
"fmt"
"io"
)
// The Importer class to be used by a pdf generation library
type Importer struct {
sourceFile string
readers map[string]*PdfReader
writers map[string]*PdfWriter
tplMap map[int]*TplInfo
tplN int
writer *PdfWriter
}
type TplInfo struct {
SourceFile string
Writer *PdfWriter
TemplateId int
}
func (this *Importer) GetReader() *PdfReader {
return this.GetReaderForFile(this.sourceFile)
}
func (this *Importer) GetWriter() *PdfWriter {
return this.GetWriterForFile(this.sourceFile)
}
func (this *Importer) GetReaderForFile(file string) *PdfReader {
if _, ok := this.readers[file]; ok {
return this.readers[file]
}
return nil
}
func (this *Importer) GetWriterForFile(file string) *PdfWriter {
if _, ok := this.writers[file]; ok {
return this.writers[file]
}
return nil
}
func NewImporter() *Importer {
importer := &Importer{}
importer.init()
return importer
}
func (this *Importer) init() {
this.readers = make(map[string]*PdfReader, 0)
this.writers = make(map[string]*PdfWriter, 0)
this.tplMap = make(map[int]*TplInfo, 0)
this.writer, _ = NewPdfWriter("")
}
func (this *Importer) SetSourceFile(f string) {
this.sourceFile = f
// If reader hasn't been instantiated, do that now
if _, ok := this.readers[this.sourceFile]; !ok {
reader, err := NewPdfReader(this.sourceFile)
if err != nil {
panic(err)
}
this.readers[this.sourceFile] = reader
}
// If writer hasn't been instantiated, do that now
if _, ok := this.writers[this.sourceFile]; !ok {
writer, err := NewPdfWriter("")
if err != nil {
panic(err)
}
// Make the next writer start template numbers at this.tplN
writer.SetTplIdOffset(this.tplN)
this.writers[this.sourceFile] = writer
}
}
func (this *Importer) SetSourceStream(rs *io.ReadSeeker) {
this.sourceFile = fmt.Sprintf("%v", rs)
if _, ok := this.readers[this.sourceFile]; !ok {
reader, err := NewPdfReaderFromStream(*rs)
if err != nil {
panic(err)
}
this.readers[this.sourceFile] = reader
}
// If writer hasn't been instantiated, do that now
if _, ok := this.writers[this.sourceFile]; !ok {
writer, err := NewPdfWriter("")
if err != nil {
panic(err)
}
// Make the next writer start template numbers at this.tplN
writer.SetTplIdOffset(this.tplN)
this.writers[this.sourceFile] = writer
}
}
func (this *Importer) GetPageSizes() map[int]map[string]map[string]float64 {
result, err := this.GetReader().getAllPageBoxes(1.0)
if err != nil {
panic(err)
}
return result
}
func (this *Importer) ImportPage(pageno int, box string) int {
res, err := this.GetWriter().ImportPage(this.GetReader(), pageno, box)
if err != nil {
panic(err)
}
// Get current template id
tplN := this.tplN
// Set tpl info
this.tplMap[tplN] = &TplInfo{SourceFile: this.sourceFile, TemplateId: res, Writer: this.GetWriter()}
// Increment template id
this.tplN++
return tplN
}
func (this *Importer) SetNextObjectID(objId int) {
this.GetWriter().SetNextObjectID(objId)
}
// Put form xobjects and get back a map of template names (e.g. /GOFPDITPL1) and their object ids (int)
func (this *Importer) PutFormXobjects() map[string]int {
res := make(map[string]int, 0)
tplNamesIds, err := this.GetWriter().PutFormXobjects(this.GetReader())
if err != nil {
panic(err)
}
for tplName, pdfObjId := range tplNamesIds {
res[tplName] = pdfObjId.id
}
return res
}
// Put form xobjects and get back a map of template names (e.g. /GOFPDITPL1) and their object ids (sha1 hash)
func (this *Importer) PutFormXobjectsUnordered() map[string]string {
this.GetWriter().SetUseHash(true)
res := make(map[string]string, 0)
tplNamesIds, err := this.GetWriter().PutFormXobjects(this.GetReader())
if err != nil {
panic(err)
}
for tplName, pdfObjId := range tplNamesIds {
res[tplName] = pdfObjId.hash
}
return res
}
// Get object ids (int) and their contents (string)
func (this *Importer) GetImportedObjects() map[int]string {
res := make(map[int]string, 0)
pdfObjIdBytes := this.GetWriter().GetImportedObjects()
for pdfObjId, bytes := range pdfObjIdBytes {
res[pdfObjId.id] = string(bytes)
}
return res
}
// Get object ids (sha1 hash) and their contents ([]byte)
// The contents may have references to other object hashes which will need to be replaced by the pdf generator library
// The positions of the hashes (sha1 - 40 characters) can be obtained by calling GetImportedObjHashPos()
func (this *Importer) GetImportedObjectsUnordered() map[string][]byte {
res := make(map[string][]byte, 0)
pdfObjIdBytes := this.GetWriter().GetImportedObjects()
for pdfObjId, bytes := range pdfObjIdBytes {
res[pdfObjId.hash] = bytes
}
return res
}
// Get the positions of the hashes (sha1 - 40 characters) within each object, to be replaced with
// actual objects ids by the pdf generator library
func (this *Importer) GetImportedObjHashPos() map[string]map[int]string {
res := make(map[string]map[int]string, 0)
pdfObjIdPosHash := this.GetWriter().GetImportedObjHashPos()
for pdfObjId, posHashMap := range pdfObjIdPosHash {
res[pdfObjId.hash] = posHashMap
}
return res
}
// For a given template id (returned from ImportPage), get the template name (e.g. /GOFPDITPL1) and
// the 4 float64 values necessary to draw the template a x,y for a given width and height.
func (this *Importer) UseTemplate(tplid int, _x float64, _y float64, _w float64, _h float64) (string, float64, float64, float64, float64) {
// Look up template id in importer tpl map
tplInfo := this.tplMap[tplid]
return tplInfo.Writer.UseTemplate(tplInfo.TemplateId, _x, _y, _w, _h)
}
================================================
FILE: vendor/github.com/phpdave11/gofpdi/reader.go
================================================
package gofpdi
import (
"bufio"
"bytes"
"compress/zlib"
"encoding/binary"
"fmt"
"github.com/pkg/errors"
"io"
"io/ioutil"
"math"
"os"
"strconv"
)
type PdfReader struct {
availableBoxes []string
stack []string
trailer *PdfValue
catalog *PdfValue
pages []*PdfValue
xrefPos int
xref map[int]map[int]int
xrefStream map[int][2]int
f io.ReadSeeker
nBytes int64
sourceFile string
}
func NewPdfReaderFromStream(rs io.ReadSeeker) (*PdfReader, error) {
length, err := rs.Seek(0, 2)
if err != nil {
return nil, errors.Wrapf(err, "Failed to determine stream length")
}
parser := &PdfReader{f: rs, nBytes: length}
if err := parser.init(); err != nil {
return nil, errors.Wrap(err, "Failed to initialize parser")
}
if err := parser.read(); err != nil {
return nil, errors.Wrap(err, "Failed to read pdf from stream")
}
return parser, nil
}
func NewPdfReader(filename string) (*PdfReader, error) {
var err error
f, err := os.Open(filename)
if err != nil {
return nil, errors.Wrap(err, "Failed to open file")
}
info, err := f.Stat()
if err != nil {
return nil, errors.Wrap(err, "Failed to obtain file information")
}
parser := &PdfReader{f: f, sourceFile: filename, nBytes: info.Size()}
if err = parser.init(); err != nil {
return nil, errors.Wrap(err, "Failed to initialize parser")
}
if err = parser.read(); err != nil {
return nil, errors.Wrap(err, "Failed to read pdf")
}
return parser, nil
}
func (this *PdfReader) init() error {
this.availableBoxes = []string{"/MediaBox", "/CropBox", "/BleedBox", "/TrimBox", "/ArtBox"}
this.xref = make(map[int]map[int]int, 0)
this.xrefStream = make(map[int][2]int, 0)
err := this.read()
if err != nil {
return errors.Wrap(err, "Failed to read pdf")
}
return nil
}
type PdfValue struct {
Type int
String string
Token string
Int int
Real float64
Bool bool
Dictionary map[string]*PdfValue
Array []*PdfValue
Id int
NewId int
Gen int
Value *PdfValue
Stream *PdfValue
Bytes []byte
}
// Jump over comments
func (this *PdfReader) skipComments(r *bufio.Reader) error {
var err error
var b byte
for {
b, err = r.ReadByte()
if err != nil {
return errors.Wrap(err, "Failed to ReadByte while skipping comments")
}
if b == '\n' || b == '\r' {
if b == '\r' {
// Peek and see if next char is \n
b2, err := r.ReadByte()
if err != nil {
return errors.Wrap(err, "Failed to read byte")
}
if b2 != '\n' {
r.UnreadByte()
}
}
break
}
}
return nil
}
// Advance reader so that whitespace is ignored
func (this *PdfReader) skipWhitespace(r *bufio.Reader) error {
var err error
var b byte
for {
b, err = r.ReadByte()
if err != nil {
if err == io.EOF {
break
}
return errors.Wrap(err, "Failed to read byte")
}
if b == ' ' || b == '\n' || b == '\r' || b == '\t' {
continue
} else {
r.UnreadByte()
break
}
}
return nil
}
// Read a token
func (this *PdfReader) readToken(r *bufio.Reader) (string, error) {
var err error
// If there is a token available on the stack, pop it out and return it.
if len(this.stack) > 0 {
var popped string
popped, this.stack = this.stack[len(this.stack)-1], this.stack[:len(this.stack)-1]
return popped, nil
}
err = this.skipWhitespace(r)
if err != nil {
return "", errors.Wrap(err, "Failed to skip whitespace")
}
b, err := r.ReadByte()
if err != nil {
if err == io.EOF {
return "", nil
}
return "", errors.Wrap(err, "Failed to read byte")
}
switch b {
case '[', ']', '(', ')':
// This is either an array or literal string delimeter, return it.
return string(b), nil
case '<', '>':
// This could either be a hex string or a dictionary delimiter.
// Determine the appropriate case and return the token.
nb, err := r.ReadByte()
if err != nil {
return "", errors.Wrap(err, "Failed to read byte")
}
if nb == b {
return string(b) + string(nb), nil
} else {
r.UnreadByte()
return string(b), nil
}
case '%':
err = this.skipComments(r)
if err != nil {
return "", errors.Wrap(err, "Failed to skip comments")
}
return this.readToken(r)
default:
// FIXME this may not be performant to create new strings for each byte
// Is it probably better to create a buffer and then convert to a string at the end.
str := string(b)
loop:
for {
b, err := r.ReadByte()
if err != nil {
return "", errors.Wrap(err, "Failed to read byte")
}
switch b {
case ' ', '%', '[', ']', '<', '>', '(', ')', '\r', '\n', '\t', '/':
r.UnreadByte()
break loop
default:
str += string(b)
}
}
return str, nil
}
return "", nil
}
// Read a value based on a token
func (this *PdfReader) readValue(r *bufio.Reader, t string) (*PdfValue, error) {
var err error
var b byte
result := &PdfValue{}
result.Type = -1
result.Token = t
result.Dictionary = make(map[string]*PdfValue, 0)
result.Array = make([]*PdfValue, 0)
switch t {
case "<":
// This is a hex string
// Read bytes until '>' is found
var s string
for {
b, err = r.ReadByte()
if err != nil {
return nil, errors.Wrap(err, "Failed to read byte")
}
if b != '>' {
s += string(b)
} else {
break
}
}
result.Type = PDF_TYPE_HEX
result.String = s
case "<<":
// This is a dictionary
// Recurse into this function until we reach the end of the dictionary.
for {
key, err := this.readToken(r)
if err != nil {
return nil, errors.Wrap(err, "Failed to read token")
}
if key == "" {
return nil, errors.New("Token is empty")
}
if key == ">>" {
break
}
// read next token
newKey, err := this.readToken(r)
if err != nil {
return nil, errors.Wrap(err, "Failed to read token")
}
value, err := this.readValue(r, newKey)
if err != nil {
return nil, errors.Wrap(err, "Failed to read value for token: "+newKey)
}
if value.Type == -1 {
return result, nil
}
// Catch missing value
if value.Type == PDF_TYPE_TOKEN && value.String == ">>" {
result.Type = PDF_TYPE_NULL
result.Dictionary[key] = value
break
}
// Set value in dictionary
result.Dictionary[key] = value
}
result.Type = PDF_TYPE_DICTIONARY
return result, nil
case "[":
// This is an array
tmpResult := make([]*PdfValue, 0)
// Recurse into this function until we reach the end of the array
for {
key, err := this.readToken(r)
if err != nil {
return nil, errors.Wrap(err, "Failed to read token")
}
if key == "" {
return nil, errors.New("Token is empty")
}
if key == "]" {
break
}
value, err := this.readValue(r, key)
if err != nil {
return nil, errors.Wrap(err, "Failed to read value for token: "+key)
}
if value.Type == -1 {
return result, nil
}
tmpResult = append(tmpResult, value)
}
result.Type = PDF_TYPE_ARRAY
result.Array = tmpResult
case "(":
// This is a string
openBrackets := 1
// Create new buffer
var buf bytes.Buffer
// Read bytes until brackets are balanced
for openBrackets > 0 {
b, err := r.ReadByte()
if err != nil {
return nil, errors.Wrap(err, "Failed to read byte")
}
switch b {
case '(':
openBrackets++
case ')':
openBrackets--
case '\\':
nb, err := r.ReadByte()
if err != nil {
return nil, errors.Wrap(err, "Failed to read byte")
}
buf.WriteByte(b)
buf.WriteByte(nb)
continue
}
if openBrackets > 0 {
buf.WriteByte(b)
}
}
result.Type = PDF_TYPE_STRING
result.String = buf.String()
case "stream":
return nil, errors.New("Stream not implemented")
default:
result.Type = PDF_TYPE_TOKEN
result.Token = t
if is_numeric(t) {
// A numeric token. Make sure that it is not part of something else
t2, err := this.readToken(r)
if err != nil {
return nil, errors.Wrap(err, "Failed to read token")
}
if t2 != "" {
if is_numeric(t2) {
// Two numeric tokens in a row.
// In this case, we're probably in front of either an object reference
// or an object specification.
// Determine the case and return the data.
t3, err := this.readToken(r)
if err != nil {
return nil, errors.Wrap(err, "Failed to read token")
}
if t3 != "" {
switch t3 {
case "obj":
result.Type = PDF_TYPE_OBJDEC
result.Id, _ = strconv.Atoi(t)
result.Gen, _ = strconv.Atoi(t2)
return result, nil
case "R":
result.Type = PDF_TYPE_OBJREF
result.Id, _ = strconv.Atoi(t)
result.Gen, _ = strconv.Atoi(t2)
return result, nil
}
// If we get to this point, that numeric value up there was just a numeric value.
// Push the extra tokens back into the stack and return the value.
this.stack = append(this.stack, t3)
}
}
this.stack = append(this.stack, t2)
}
if n, err := strconv.Atoi(t); err == nil {
result.Type = PDF_TYPE_NUMERIC
result.Int = n
result.Real = float64(n) // Also assign Real value here to fix page box parsing bugs
} else {
result.Type = PDF_TYPE_REAL
result.Real, _ = strconv.ParseFloat(t, 64)
}
} else if t == "true" || t == "false" {
result.Type = PDF_TYPE_BOOLEAN
result.Bool = t == "true"
} else if t == "null" {
result.Type = PDF_TYPE_NULL
} else {
result.Type = PDF_TYPE_TOKEN
result.Token = t
}
}
return result, nil
}
// Resolve a compressed object (PDF 1.5)
func (this *PdfReader) resolveCompressedObject(objSpec *PdfValue) (*PdfValue, error) {
var err error
// Make sure object reference exists in xrefStream
if _, ok := this.xrefStream[objSpec.Id]; !ok {
return nil, errors.New(fmt.Sprintf("Could not find object ID %d in xref stream or xref table.", objSpec.Id))
}
// Get object id and index
objectId := this.xrefStream[objSpec.Id][0]
objectIndex := this.xrefStream[objSpec.Id][1]
// Read compressed object
compressedObjSpec := &PdfValue{Type: PDF_TYPE_OBJREF, Id: objectId, Gen: 0}
// Resolve compressed object
compressedObj, err := this.resolveObject(compressedObjSpec)
if err != nil {
return nil, errors.Wrap(err, "Failed to resolve compressed object")
}
// Verify object type is /ObjStm
if _, ok := compressedObj.Value.Dictionary["/Type"]; ok {
if compressedObj.Value.Dictionary["/Type"].Token != "/ObjStm" {
return nil, errors.New("Expected compressed object type to be /ObjStm")
}
} else {
return nil, errors.New("Could not determine compressed object type.")
}
// Get number of sub-objects in compressed object
n := compressedObj.Value.Dictionary["/N"].Int
if n <= 0 {
return nil, errors.New("No sub objects in compressed object")
}
// Get offset of first object
first := compressedObj.Value.Dictionary["/First"].Int
// Get length
//length := compressedObj.Value.Dictionary["/Length"].Int
// Check for filter
filter := ""
if _, ok := compressedObj.Value.Dictionary["/Filter"]; ok {
filter = compressedObj.Value.Dictionary["/Filter"].Token
if filter != "/FlateDecode" {
return nil, errors.New("Unsupported filter - expected /FlateDecode, got: " + filter)
}
}
if filter == "/FlateDecode" {
// Decompress if filter is /FlateDecode
// Uncompress zlib compressed data
var out bytes.Buffer
zlibReader, _ := zlib.NewReader(bytes.NewBuffer(compressedObj.Stream.Bytes))
defer zlibReader.Close()
io.Copy(&out, zlibReader)
// Set stream to uncompressed data
compressedObj.Stream.Bytes = out.Bytes()
}
// Get io.Reader for bytes
r := bufio.NewReader(bytes.NewBuffer(compressedObj.Stream.Bytes))
subObjId := 0
subObjPos := 0
// Read sub-object indeces and their positions within the (un)compressed object
for i := 0; i < n; i++ {
var token string
var _objidx int
var _objpos int
// Read first token (object index)
token, err = this.readToken(r)
if err != nil {
return nil, errors.Wrap(err, "Failed to read token")
}
// Convert line (string) into int
_objidx, err = strconv.Atoi(token)
if err != nil {
return nil, errors.Wrap(err, "Failed to convert token into integer: "+token)
}
// Read first token (object index)
token, err = this.readToken(r)
if err != nil {
return nil, errors.Wrap(err, "Failed to read token")
}
// Convert line (string) into int
_objpos, err = strconv.Atoi(token)
if err != nil {
return nil, errors.Wrap(err, "Failed to convert token into integer: "+token)
}
if i == objectIndex {
subObjId = _objidx
subObjPos = _objpos
}
}
// Now create an io.ReadSeeker
rs := io.ReadSeeker(bytes.NewReader(compressedObj.Stream.Bytes))
// Determine where to seek to (sub-object position + /First)
seekTo := int64(subObjPos + first)
// Fast forward to the object
rs.Seek(seekTo, 0)
// Create a new io.Reader
r = bufio.NewReader(rs)
// Read token
token, err := this.readToken(r)
if err != nil {
return nil, errors.Wrap(err, "Failed to read token")
}
// Read object
obj, err := this.readValue(r, token)
if err != nil {
return nil, errors.Wrap(err, "Failed to read value for token: "+token)
}
result := &PdfValue{}
result.Id = subObjId
result.Gen = 0
result.Type = PDF_TYPE_OBJECT
result.Value = obj
return result, nil
}
func (this *PdfReader) resolveObject(objSpec *PdfValue) (*PdfValue, error) {
var err error
var old_pos int64
// Create new bufio.Reader
r := bufio.NewReader(this.f)
if objSpec.Type == PDF_TYPE_OBJREF {
// This is a reference, resolve it.
offset := this.xref[objSpec.Id][objSpec.Gen]
if _, ok := this.xref[objSpec.Id]; !ok {
// This may be a compressed object
return this.resolveCompressedObject(objSpec)
}
// Save current file position
// This is needed if you want to resolve reference while you're reading another object.
// (e.g.: if you need to determine the length of a stream)
old_pos, err = this.f.Seek(0, os.SEEK_CUR)
if err != nil {
return nil, errors.Wrap(err, "Failed to get current position of file")
}
// Reposition the file pointer and load the object header
_, err = this.f.Seek(int64(offset), 0)
if err != nil {
return nil, errors.Wrap(err, "Failed to set position of file")
}
token, err := this.readToken(r)
if err != nil {
return nil, errors.Wrap(err, "Failed to read token")
}
obj, err := this.readValue(r, token)
if err != nil {
return nil, errors.Wrap(err, "Failed to read value for token: "+token)
}
if obj.Type != PDF_TYPE_OBJDEC {
return nil, errors.New(fmt.Sprintf("Expected type to be PDF_TYPE_OBJDEC, got: %d", obj.Type))
}
if obj.Id != objSpec.Id {
return nil, errors.New(fmt.Sprintf("Object ID (%d) does not match ObjSpec ID (%d)", obj.Id, objSpec.Id))
}
if obj.Gen != objSpec.Gen {
return nil, errors.New("Object Gen does not match ObjSpec Gen")
}
// Read next token
token, err = this.readToken(r)
if err != nil {
return nil, errors.Wrap(err, "Failed to read token")
}
// Read actual object value
value, err := this.readValue(r, token)
if err != nil {
return nil, errors.Wrap(err, "Failed to read value for token: "+token)
}
// Read next token
token, err = this.readToken(r)
if err != nil {
return nil, errors.Wrap(err, "Failed to read token")
}
result := &PdfValue{}
result.Id = obj.Id
result.Gen = obj.Gen
result.Type = PDF_TYPE_OBJECT
result.Value = value
if token == "stream" {
result.Type = PDF_TYPE_STREAM
err = this.skipWhitespace(r)
if err != nil {
return nil, errors.Wrap(err, "Failed to skip whitespace")
}
// Get stream length dictionary
lengthDict := value.Dictionary["/Length"]
// Get number of bytes of stream
length := lengthDict.Int
// If lengthDict is an object reference, resolve the object and set length
if lengthDict.Type == PDF_TYPE_OBJREF {
lengthDict, err = this.resolveObject(lengthDict)
if err != nil {
return nil, errors.Wrap(err, "Failed to resolve length object of stream")
}
// Set length to resolved object value
length = lengthDict.Value.Int
}
// Read length bytes
bytes := make([]byte, length)
// Cannot use reader.Read() because that may not read all the bytes
_, err := io.ReadFull(r, bytes)
if err != nil {
return nil, errors.Wrap(err, "Failed to read bytes from buffer")
}
token, err = this.readToken(r)
if err != nil {
return nil, errors.Wrap(err, "Failed to read token")
}
if token != "endstream" {
return nil, errors.New("Expected next token to be: endstream, got: " + token)
}
token, err = this.readToken(r)
if err != nil {
return nil, errors.Wrap(err, "Failed to read token")
}
streamObj := &PdfValue{}
streamObj.Type = PDF_TYPE_STREAM
streamObj.Bytes = bytes
result.Stream = streamObj
}
if token != "endobj" {
return nil, errors.New("Expected next token to be: endobj, got: " + token)
}
// Reposition the file pointer to previous position
_, err = this.f.Seek(old_pos, 0)
if err != nil {
return nil, errors.Wrap(err, "Failed to set position of file")
}
return result, nil
} else {
return objSpec, nil
}
return &PdfValue{}, nil
}
// Find the xref offset (should be at the end of the PDF)
func (this *PdfReader) findXref() error {
var result int
var err error
var toRead int64
toRead = 1500
// If PDF is smaller than 1500 bytes, be sure to only read the number of bytes that are in the file
fileSize := this.nBytes
if fileSize < toRead {
toRead = fileSize
}
// 0 means relative to the origin of the file,
// 1 means relative to the current offset,
// and 2 means relative to the end.
whence := 2
// Perform seek operation
_, err = this.f.Seek(-toRead, whence)
if err != nil {
return errors.Wrap(err, "Failed to set position of file")
}
// Create new bufio.Reader
r := bufio.NewReader(this.f)
for {
// Read all tokens until "startxref" is found
token, err := this.readToken(r)
if err != nil {
return errors.Wrap(err, "Failed to read token")
}
if token == "startxref" {
token, err = this.readToken(r)
// Probably EOF before finding startxref
if err != nil {
return errors.Wrap(err, "Failed to find startxref token")
}
// Convert line (string) into int
result, err = strconv.Atoi(token)
if err != nil {
return errors.Wrap(err, "Failed to convert xref position into integer: "+token)
}
// Successfully read the xref position
this.xrefPos = result
break
}
}
// Rewind file pointer
whence = 0
_, err = this.f.Seek(0, whence)
if err != nil {
return errors.Wrap(err, "Failed to set position of file")
}
this.xrefPos = result
return nil
}
// Read and parse the xref table
func (this *PdfReader) readXref() error {
var err error
// Create new bufio.Reader
r := bufio.NewReader(this.f)
// Set file pointer to xref start
_, err = this.f.Seek(int64(this.xrefPos), 0)
if err != nil {
return errors.Wrap(err, "Failed to set position of file")
}
// Xref should start with 'xref'
t, err := this.readToken(r)
if err != nil {
return errors.Wrap(err, "Failed to read token")
}
if t != "xref" {
// Maybe this is an XRef stream ...
v, err := this.readValue(r, t)
if err != nil {
return errors.Wrap(err, "Failed to read XRef stream")
}
if v.Type == PDF_TYPE_OBJDEC {
// Read next token
t, err = this.readToken(r)
if err != nil {
return errors.Wrap(err, "Failed to read token")
}
// Read actual object value
v, err := this.readValue(r, t)
if err != nil {
return errors.Wrap(err, "Failed to read value for token: "+t)
}
// If /Type is set, check to see if it is XRef
if _, ok := v.Dictionary["/Type"]; ok {
if v.Dictionary["/Type"].Token == "/XRef" {
// Continue reading xref stream data now that it is confirmed that it is an xref stream
// Check for /DecodeParms
paethDecode := false
if _, ok := v.Dictionary["/DecodeParms"]; ok {
columns := 0
predictor := 0
if _, ok2 := v.Dictionary["/DecodeParms"].Dictionary["/Columns"]; ok2 {
columns = v.Dictionary["/DecodeParms"].Dictionary["/Columns"].Int
}
if _, ok2 := v.Dictionary["/DecodeParms"].Dictionary["/Predictor"]; ok2 {
predictor = v.Dictionary["/DecodeParms"].Dictionary["/Predictor"].Int
}
if columns != 4 || predictor != 12 {
return errors.New("Unsupported /DecodeParms - only tested with /Columns 4 /Predictor 12")
}
paethDecode = true
}
// Check to make sure field size is [1 2 1] - not yet tested with other field sizes
if v.Dictionary["/W"].Array[0].Int != 1 || v.Dictionary["/W"].Array[1].Int > 4 || v.Dictionary["/W"].Array[2].Int != 1 {
return errors.New(fmt.Sprintf("Unsupported field sizes in cross-reference stream dictionary: /W [%d %d %d]",
v.Dictionary["/W"].Array[0].Int,
v.Dictionary["/W"].Array[1].Int,
v.Dictionary["/W"].Array[2].Int))
}
index := make([]int, 2)
// If /Index is not set, this is an error
if _, ok := v.Dictionary["/Index"]; ok {
if len(v.Dictionary["/Index"].Array) < 2 {
return errors.Wrap(err, "Index array does not contain 2 elements")
}
index[0] = v.Dictionary["/Index"].Array[0].Int
index[1] = v.Dictionary["/Index"].Array[1].Int
} else {
index[0] = 0
}
prevXref := 0
// Check for previous xref stream
if _, ok := v.Dictionary["/Prev"]; ok {
prevXref = v.Dictionary["/Prev"].Int
}
// Set root object
if _, ok := v.Dictionary["/Root"]; ok {
// Just set the whole dictionary with /Root key to keep compatibiltiy with existing code
this.trailer = v
} else {
// Don't return an error here. The trailer could be in another XRef stream.
//return errors.New("Did not set root object")
}
startObject := index[0]
err = this.skipWhitespace(r)
if err != nil {
return errors.Wrap(err, "Failed to skip whitespace")
}
// Get stream length dictionary
lengthDict := v.Dictionary["/Length"]
// Get number of bytes of stream
length := lengthDict.Int
// If lengthDict is an object reference, resolve the object and set length
if lengthDict.Type == PDF_TYPE_OBJREF {
lengthDict, err = this.resolveObject(lengthDict)
if err != nil {
return errors.Wrap(err, "Failed to resolve length object of stream")
}
// Set length to resolved object value
length = lengthDict.Value.Int
}
t, err = this.readToken(r)
if err != nil {
return errors.Wrap(err, "Failed to read token")
}
if t != "stream" {
return errors.New("Expected next token to be: stream, got: " + t)
}
err = this.skipWhitespace(r)
if err != nil {
return errors.Wrap(err, "Failed to skip whitespace")
}
// Read length bytes
data := make([]byte, length)
// Cannot use reader.Read() because that may not read all the bytes
_, err := io.ReadFull(r, data)
if err != nil {
return errors.Wrap(err, "Failed to read bytes from buffer")
}
// Look for endstream token
t, err = this.readToken(r)
if err != nil {
return errors.Wrap(err, "Failed to read token")
}
if t != "endstream" {
return errors.New("Expected next token to be: endstream, got: " + t)
}
// Look for endobj token
t, err = this.readToken(r)
if err != nil {
return errors.Wrap(err, "Failed to read token")
}
if t != "endobj" {
return errors.New("Expected next token to be: endobj, got: " + t)
}
// Now decode zlib data
b := bytes.NewReader(data)
z, err := zlib.NewReader(b)
if err != nil {
return errors.Wrap(err, "zlib.NewReader error")
}
defer z.Close()
p, err := ioutil.ReadAll(z)
if err != nil {
return errors.Wrap(err, "ioutil.ReadAll error")
}
objPos := 0
objGen := 0
i := startObject
// Decode result with paeth algorithm
var result []byte
b = bytes.NewReader(p)
firstFieldSize := v.Dictionary["/W"].Array[0].Int
middleFieldSize := v.Dictionary["/W"].Array[1].Int
lastFieldSize := v.Dictionary["/W"].Array[2].Int
fieldSize := firstFieldSize + middleFieldSize + lastFieldSize
if paethDecode {
fieldSize++
}
prevRow := make([]byte, fieldSize)
for {
result = make([]byte, fieldSize)
_, err := io.ReadFull(b, result)
if err != nil {
if err == io.EOF {
break
} else {
return errors.Wrap(err, "io.ReadFull error")
}
}
if paethDecode {
filterPaeth(result, prevRow, fieldSize)
copy(prevRow, result)
}
objectData := make([]byte, fieldSize)
if paethDecode {
copy(objectData, result[1:fieldSize])
} else {
copy(objectData, result[0:fieldSize])
}
if objectData[0] == 1 {
// Regular objects
b := make([]byte, 4)
copy(b[4-middleFieldSize:], objectData[1:1+middleFieldSize])
objPos = int(binary.BigEndian.Uint32(b))
objGen = int(objectData[firstFieldSize+middleFieldSize])
// Append map[int]int
this.xref[i] = make(map[int]int, 1)
// Set object id, generation, and position
this.xref[i][objGen] = objPos
} else if objectData[0] == 2 {
// Compressed objects
b := make([]byte, 4)
copy(b[4-middleFieldSize:], objectData[1:1+middleFieldSize])
objId := int(binary.BigEndian.Uint32(b))
objIdx := int(objectData[firstFieldSize+middleFieldSize])
// object id (i) is located in StmObj (objId) at index (objIdx)
this.xrefStream[i] = [2]int{objId, objIdx}
}
i++
}
// Check for previous xref stream
if prevXref > 0 {
// Set xrefPos to /Prev xref
this.xrefPos = prevXref
// Read preivous xref
xrefErr := this.readXref()
if xrefErr != nil {
return errors.Wrap(xrefErr, "Failed to read prev xref")
}
}
}
}
return nil
}
return errors.New("Expected xref to start with 'xref'. Got: " + t)
}
for {
// Next value will be the starting object id (usually 0, but not always) or the trailer
t, err = this.readToken(r)
if err != nil {
return errors.Wrap(err, "Failed to read token")
}
// Check for trailer
if t == "trailer" {
break
}
// Convert token to int
startObject, err := strconv.Atoi(t)
if err != nil {
return errors.Wrap(err, "Failed to convert start object to integer: "+t)
}
// Determine how many objects there are
t, err = this.readToken(r)
if err != nil {
return errors.Wrap(err, "Failed to read token")
}
// Convert token to int
numObject, err := strconv.Atoi(t)
if err != nil {
return errors.Wrap(err, "Failed to convert num object to integer: "+t)
}
// For all objects in xref, read object position, object generation, and status (free or new)
for i := startObject; i < startObject+numObject; i++ {
t, err = this.readToken(r)
if err != nil {
return errors.Wrap(err, "Failed to read token")
}
// Get object position as int
objPos, err := strconv.Atoi(t)
if err != nil {
return errors.Wrap(err, "Failed to convert object position to integer: "+t)
}
t, err = this.readToken(r)
if err != nil {
return errors.Wrap(err, "Failed to read token")
}
// Get object generation as int
objGen, err := strconv.Atoi(t)
if err != nil {
return errors.Wrap(err, "Failed to convert object generation to integer: "+t)
}
// Get object status (free or new)
objStatus, err := this.readToken(r)
if err != nil {
return errors.Wrap(err, "Failed to read token")
}
if objStatus != "f" && objStatus != "n" {
return errors.New("Expected objStatus to be 'n' or 'f', got: " + objStatus)
}
// Append map[int]int
this.xref[i] = make(map[int]int, 1)
// Set object id, generation, and position
this.xref[i][objGen] = objPos
}
}
// Read trailer dictionary
t, err = this.readToken(r)
if err != nil {
return errors.Wrap(err, "Failed to read token")
}
trailer, err := this.readValue(r, t)
if err != nil {
return errors.Wrap(err, "Failed to read value for token: "+t)
}
// If /Root is set, then set trailer object so that /Root can be read later
if _, ok := trailer.Dictionary["/Root"]; ok {
this.trailer = trailer
}
// If a /Prev xref trailer is specified, parse that
if tr, ok := trailer.Dictionary["/Prev"]; ok {
// Resolve parent xref table
this.xrefPos = tr.Int
return this.readXref()
}
return nil
}
// Read root (catalog object)
func (this *PdfReader) readRoot() error {
var err error
rootObjSpec := this.trailer.Dictionary["/Root"]
// Read root (catalog)
this.catalog, err = this.resolveObject(rootObjSpec)
if err != nil {
return errors.Wrap(err, "Failed to resolve root object")
}
return nil
}
// Read all pages in PDF
func (this *PdfReader) readPages() error {
var err error
// resolve_pages_dict
pagesDict, err := this.resolveObject(this.catalog.Value.Dictionary["/Pages"])
if err != nil {
return errors.Wrap(err, "Failed to resolve pages object")
}
// This will normally return itself
kids, err := this.resolveObject(pagesDict.Value.Dictionary["/Kids"])
if err != nil {
return errors.Wrap(err, "Failed to resolve kids object")
}
// Allocate pages
this.pages = make([]*PdfValue, len(kids.Array))
// Loop through pages and add to result
for i := 0; i < len(kids.Array); i++ {
page, err := this.resolveObject(kids.Array[i])
if err != nil {
return errors.Wrap(err, "Failed to resolve kid object")
}
// Set page
this.pages[i] = page
}
return nil
}
// Get references to page resources for a given page number
func (this *PdfReader) getPageResources(pageno int) (*PdfValue, error) {
var err error
// Check to make sure page exists in pages slice
if len(this.pages) < pageno {
return nil, errors.New(fmt.Sprintf("Page %d does not exist!!", pageno))
}
// Resolve page object
page, err := this.resolveObject(this.pages[pageno-1])
if err != nil {
return nil, errors.Wrap(err, "Failed to resolve page object")
}
// Check to see if /Resources exists in Dictionary
if _, ok := page.Value.Dictionary["/Resources"]; ok {
// Resolve /Resources object
res, err := this.resolveObject(page.Value.Dictionary["/Resources"])
if err != nil {
return nil, errors.Wrap(err, "Failed to resolve resources object")
}
// If type is PDF_TYPE_OBJECT, return its Value
if res.Type == PDF_TYPE_OBJECT {
return res.Value, nil
}
// Otherwise, returned the resolved object
return res, nil
} else {
// If /Resources does not exist, check to see if /Parent exists and return that
if _, ok := page.Value.Dictionary["/Parent"]; ok {
// Resolve parent object
res, err := this.resolveObject(page.Value.Dictionary["/Parent"])
if err != nil {
return nil, errors.Wrap(err, "Failed to resolve parent object")
}
// If /Parent object type is PDF_TYPE_OBJECT, return its Value
if res.Type == PDF_TYPE_OBJECT {
return res.Value, nil
}
// Otherwise, return the resolved parent object
return res, nil
}
}
// Return an empty PdfValue if we got here
// TODO: Improve error handling
return &PdfValue{}, nil
}
// Get page content and return a slice of PdfValue objects
func (this *PdfReader) getPageContent(objSpec *PdfValue) ([]*PdfValue, error) {
var err error
var content *PdfValue
// Allocate slice
contents := make([]*PdfValue, 0)
if objSpec.Type == PDF_TYPE_OBJREF {
// If objSpec is an object reference, resolve the object and append it to contents
content, err = this.resolveObject(objSpec)
if err != nil {
return nil, errors.Wrap(err, "Failed to resolve object")
}
contents = append(contents, content)
} else if objSpec.Type == PDF_TYPE_ARRAY {
// If objSpec is an array, loop through the array and recursively get page content and append to contents
for i := 0; i < len(objSpec.Array); i++ {
tmpContents, err := this.getPageContent(objSpec.Array[i])
if err != nil {
return nil, errors.Wrap(err, "Failed to get page content")
}
for j := 0; j < len(tmpContents); j++ {
contents = append(contents, tmpContents[j])
}
}
}
return contents, nil
}
// Get content (i.e. PDF drawing instructions)
func (this *PdfReader) getContent(pageno int) (string, error) {
var err error
var contents []*PdfValue
// Check to make sure page exists in pages slice
if len(this.pages) < pageno {
return "", errors.New(fmt.Sprintf("Page %d does not exist.", pageno))
}
// Get page
page := this.pages[pageno-1]
// FIXME: This could be slow, converting []byte to string and appending many times
buffer := ""
// Check to make sure /Contents exists in page dictionary
if _, ok := page.Value.Dictionary["/Contents"]; ok {
// Get an array of page content
contents, err = this.getPageContent(page.Value.Dictionary["/Contents"])
if err != nil {
return "", errors.Wrap(err, "Failed to get page content")
}
for i := 0; i < len(contents); i++ {
// Decode content if one or more /Filter is specified.
// Most common filter is FlateDecode which can be uncompressed with zlib
tmpBuffer, err := this.rebuildContentStream(contents[i])
if err != nil {
return "", errors.Wrap(err, "Failed to rebuild content stream")
}
// FIXME: This is probably slow
buffer += string(tmpBuffer)
}
}
return buffer, nil
}
// Rebuild content stream
// This will decode content if one or more /Filter (such as FlateDecode) is specified.
// If there are multiple filters, they will be decoded in the order in which they were specified.
func (this *PdfReader) rebuildContentStream(content *PdfValue) ([]byte, error) {
var err error
var tmpFilter *PdfValue
// Allocate slice of PdfValue
filters := make([]*PdfValue, 0)
// If content has a /Filter, append it to filters slice
if _, ok := content.Value.Dictionary["/Filter"]; ok {
filter := content.Value.Dictionary["/Filter"]
// If filter type is a reference, resolve it
if filter.Type == PDF_TYPE_OBJREF {
tmpFilter, err = this.resolveObject(filter)
if err != nil {
return nil, errors.Wrap(err, "Failed to resolve object")
}
filter = tmpFilter.Value
}
if filter.Type == PDF_TYPE_TOKEN {
// If filter type is a token (e.g. FlateDecode), appent it to filters slice
filters = append(filters, filter)
} else if filter.Type == PDF_TYPE_ARRAY {
// If filter type is an array, then there are multiple filters. Set filters variable to array value.
filters = filter.Array
}
}
// Set stream variable to content bytes
stream := content.Stream.Bytes
// Loop through filters and apply each filter to stream
for i := 0; i < len(filters); i++ {
switch filters[i].Token {
case "/FlateDecode":
// Uncompress zlib compressed data
var out bytes.Buffer
zlibReader, _ := zlib.NewReader(bytes.NewBuffer(stream))
defer zlibReader.Close()
io.Copy(&out, zlibReader)
// Set stream to uncompressed data
stream = out.Bytes()
default:
return nil, errors.New("Unspported filter: " + filters[i].Token)
}
}
return stream, nil
}
func (this *PdfReader) getAllPageBoxes(k float64) (map[int]map[string]map[string]float64, error) {
var err error
// Allocate result with the number of available boxes
result := make(map[int]map[string]map[string]float64, len(this.pages))
for i := 1; i <= len(this.pages); i++ {
result[i], err = this.getPageBoxes(i, k)
if result[i] == nil {
return nil, errors.Wrap(err, "Unable to get page box")
}
}
return result, nil
}
// Get all page box data
func (this *PdfReader) getPageBoxes(pageno int, k float64) (map[string]map[string]float64, error) {
var err error
// Allocate result with the number of available boxes
result := make(map[string]map[string]float64, len(this.availableBoxes))
// Check to make sure page exists in pages slice
if len(this.pages) < pageno {
return nil, errors.New(fmt.Sprintf("Page %d does not exist?", pageno))
}
// Resolve page object
page, err := this.resolveObject(this.pages[pageno-1])
if err != nil {
return nil, errors.New("Failed to resolve page object")
}
// Loop through available boxes and add to result
for i := 0; i < len(this.availableBoxes); i++ {
box, err := this.getPageBox(page, this.availableBoxes[i], k)
if err != nil {
return nil, errors.New("Failed to get page box")
}
result[this.availableBoxes[i]] = box
}
return result, nil
}
// Get a specific page box value (e.g. MediaBox) and return its values
func (this *PdfReader) getPageBox(page *PdfValue, box_index string, k float64) (map[string]float64, error) {
var err error
var tmpBox *PdfValue
// Allocate 8 fields in result
result := make(map[string]float64, 8)
// Check to make sure box_index (e.g. MediaBox) exists in page dictionary
if _, ok := page.Value.Dictionary[box_index]; ok {
box := page.Value.Dictionary[box_index]
// If the box type is a reference, resolve it
if box.Type == PDF_TYPE_OBJREF {
tmpBox, err = this.resolveObject(box)
if err != nil {
return nil, errors.New("Failed to resolve object")
}
box = tmpBox.Value
}
if box.Type == PDF_TYPE_ARRAY {
// If the box type is an array, calculate scaled value based on k
result["x"] = box.Array[0].Real / k
result["y"] = box.Array[1].Real / k
result["w"] = math.Abs(box.Array[0].Real-box.Array[2].Real) / k
result["h"] = math.Abs(box.Array[1].Real-box.Array[3].Real) / k
result["llx"] = math.Min(box.Array[0].Real, box.Array[2].Real)
result["lly"] = math.Min(box.Array[1].Real, box.Array[3].Real)
result["urx"] = math.Max(box.Array[0].Real, box.Array[2].Real)
result["ury"] = math.Max(box.Array[1].Real, box.Array[3].Real)
} else {
// TODO: Improve error handling
return nil, errors.New("Could not get page box")
}
} else if _, ok := page.Value.Dictionary["/Parent"]; ok {
parentObj, err := this.resolveObject(page.Value.Dictionary["/Parent"])
if err != nil {
return nil, errors.Wrap(err, "Could not resolve parent object")
}
// If the page box is inherited from /Parent, recursively return page box of parent
return this.getPageBox(parentObj, box_index, k)
}
return result, nil
}
// Get page rotation for a page number
func (this *PdfReader) getPageRotation(pageno int) (*PdfValue, error) {
// Check to make sure page exists in pages slice
if len(this.pages) < pageno {
return nil, errors.New(fmt.Sprintf("Page %d does not exist!!!!", pageno))
}
return this._getPageRotation(this.pages[pageno-1])
}
// Get page rotation for a page object spec
func (this *PdfReader) _getPageRotation(page *PdfValue) (*PdfValue, error) {
var err error
// Resolve page object
page, err = this.resolveObject(page)
if err != nil {
return nil, errors.New("Failed to resolve page object")
}
// Check to make sure /Rotate exists in page dictionary
if _, ok := page.Value.Dictionary["/Rotate"]; ok {
res, err := this.resolveObject(page.Value.Dictionary["/Rotate"])
if err != nil {
return nil, errors.New("Failed to resolve rotate object")
}
// If the type is PDF_TYPE_OBJECT, return its value
if res.Type == PDF_TYPE_OBJECT {
return res.Value, nil
}
// Otherwise, return the object
return res, nil
} else {
// Check to see if parent has a rotation
if _, ok := page.Value.Dictionary["/Parent"]; ok {
// Recursively return /Parent page rotation
res, err := this._getPageRotation(page.Value.Dictionary["/Parent"])
if err != nil {
return nil, errors.Wrap(err, "Failed to get page rotation for parent")
}
// If the type is PDF_TYPE_OBJECT, return its value
if res.Type == PDF_TYPE_OBJECT {
return res.Value, nil
}
// Otherwise, return the object
return res, nil
}
}
return &PdfValue{Int: 0}, nil
}
func (this *PdfReader) read() error {
var err error
// Find xref position
err = this.findXref()
if err != nil {
return errors.Wrap(err, "Failed to find xref position")
}
// Parse xref table
err = this.readXref()
if err != nil {
return errors.Wrap(err, "Failed to read xref table")
}
// Read catalog
err = this.readRoot()
if err != nil {
return errors.Wrap(err, "Failed to read root")
}
// Read pages
err = this.readPages()
if err != nil {
return errors.Wrap(err, "Failed to to read pages")
}
return nil
}
================================================
FILE: vendor/github.com/phpdave11/gofpdi/writer.go
================================================
package gofpdi
import (
"bufio"
"bytes"
"compress/zlib"
"crypto/sha1"
"encoding/hex"
"fmt"
"github.com/pkg/errors"
"math"
"os"
)
type PdfWriter struct {
f *os.File
w *bufio.Writer
r *PdfReader
k float64
tpls []*PdfTemplate
m int
n int
offsets map[int]int
offset int
result map[int]string
// Keep track of which objects have already been written
obj_stack map[int]*PdfValue
don_obj_stack map[int]*PdfValue
written_objs map[*PdfObjectId][]byte
written_obj_pos map[*PdfObjectId]map[int]string
current_obj *PdfObject
current_obj_id int
tpl_id_offset int
use_hash bool
}
type PdfObjectId struct {
id int
hash string
}
type PdfObject struct {
id *PdfObjectId
buffer *bytes.Buffer
}
func (this *PdfWriter) SetTplIdOffset(n int) {
this.tpl_id_offset = n
}
func (this *PdfWriter) Init() {
this.k = 1
this.obj_stack = make(map[int]*PdfValue, 0)
this.don_obj_stack = make(map[int]*PdfValue, 0)
this.tpls = make([]*PdfTemplate, 0)
this.written_objs = make(map[*PdfObjectId][]byte, 0)
this.written_obj_pos = make(map[*PdfObjectId]map[int]string, 0)
this.current_obj = new(PdfObject)
}
func (this *PdfWriter) SetUseHash(b bool) {
this.use_hash = b
}
func (this *PdfWriter) SetNextObjectID(id int) {
this.n = id - 1
}
func NewPdfWriter(filename string) (*PdfWriter, error) {
writer := &PdfWriter{}
writer.Init()
if filename != "" {
var err error
f, err := os.Create(filename)
if err != nil {
return nil, errors.Wrap(err, "Unable to create filename: "+filename)
}
writer.f = f
writer.w = bufio.NewWriter(f)
}
return writer, nil
}
// Done with parsing. Now, create templates.
type PdfTemplate struct {
Id int
Reader *PdfReader
Resources *PdfValue
Buffer string
Box map[string]float64
Boxes map[string]map[string]float64
X float64
Y float64
W float64
H float64
Rotation int
N int
}
func (this *PdfWriter) GetImportedObjects() map[*PdfObjectId][]byte {
return this.written_objs
}
// For each object (uniquely identified by a sha1 hash), return the positions
// of each hash within the object, to be replaced with pdf object ids (integers)
func (this *PdfWriter) GetImportedObjHashPos() map[*PdfObjectId]map[int]string {
return this.written_obj_pos
}
func (this *PdfWriter) ClearImportedObjects() {
this.written_objs = make(map[*PdfObjectId][]byte, 0)
}
// Create a PdfTemplate object from a page number (e.g. 1) and a boxName (e.g. MediaBox)
func (this *PdfWriter) ImportPage(reader *PdfReader, pageno int, boxName string) (int, error) {
var err error
// Set default scale to 1
this.k = 1
// Get all page boxes
pageBoxes, err := reader.getPageBoxes(1, this.k)
if err != nil {
return -1, errors.Wrap(err, "Failed to get page boxes")
}
// If requested box name does not exist for this page, use an alternate box
if _, ok := pageBoxes[boxName]; !ok {
if boxName == "/BleedBox" || boxName == "/TrimBox" || boxName == "ArtBox" {
boxName = "/CropBox"
} else if boxName == "/CropBox" {
boxName = "/MediaBox"
}
}
// If the requested box name or an alternate box name cannot be found, trigger an error
// TODO: Improve error handling
if _, ok := pageBoxes[boxName]; !ok {
return -1, errors.New("Box not found: " + boxName)
}
pageResources, err := reader.getPageResources(pageno)
if err != nil {
return -1, errors.Wrap(err, "Failed to get page resources")
}
content, err := reader.getContent(pageno)
if err != nil {
return -1, errors.Wrap(err, "Failed to get content")
}
// Set template values
tpl := &PdfTemplate{}
tpl.Reader = reader
tpl.Resources = pageResources
tpl.Buffer = content
tpl.Box = pageBoxes[boxName]
tpl.Boxes = pageBoxes
tpl.X = 0
tpl.Y = 0
tpl.W = tpl.Box["w"]
tpl.H = tpl.Box["h"]
// Set template rotation
rotation, err := reader.getPageRotation(pageno)
if err != nil {
return -1, errors.Wrap(err, "Failed to get page rotation")
}
angle := rotation.Int % 360
// Normalize angle
if angle != 0 {
steps := angle / 90
w := tpl.W
h := tpl.H
if steps%2 == 0 {
tpl.W = w
tpl.H = h
} else {
tpl.W = h
tpl.H = w
}
if angle < 0 {
angle += 360
}
tpl.Rotation = angle * -1
}
this.tpls = append(this.tpls, tpl)
// Return last template id
return len(this.tpls) - 1, nil
}
// Create a new object and keep track of the offset for the xref table
func (this *PdfWriter) newObj(objId int, onlyNewObj bool) {
if objId < 0 {
this.n++
objId = this.n
}
if !onlyNewObj {
// set current object id integer
this.current_obj_id = objId
// Create new PdfObject and PdfObjectId
this.current_obj = new(PdfObject)
this.current_obj.buffer = new(bytes.Buffer)
this.current_obj.id = new(PdfObjectId)
this.current_obj.id.id = objId
this.current_obj.id.hash = this.shaOfInt(objId)
this.written_obj_pos[this.current_obj.id] = make(map[int]string, 0)
}
}
func (this *PdfWriter) endObj() {
this.out("endobj")
this.written_objs[this.current_obj.id] = this.current_obj.buffer.Bytes()
this.current_obj_id = -1
}
func (this *PdfWriter) shaOfInt(i int) string {
hasher := sha1.New()
hasher.Write([]byte(fmt.Sprintf("%s-%s", i, this.r.sourceFile)))
sha := hex.EncodeToString(hasher.Sum(nil))
return sha
}
func (this *PdfWriter) outObjRef(objId int) {
sha := this.shaOfInt(objId)
// Keep track of object hash and position - to be replaced with actual object id (integer)
this.written_obj_pos[this.current_obj.id][this.current_obj.buffer.Len()] = sha
if this.use_hash {
this.current_obj.buffer.WriteString(sha)
} else {
this.current_obj.buffer.WriteString(fmt.Sprintf("%d", objId))
}
this.current_obj.buffer.WriteString(" 0 R ")
}
// Output PDF data with a newline
func (this *PdfWriter) out(s string) {
this.current_obj.buffer.WriteString(s)
this.current_obj.buffer.WriteString("\n")
}
// Output PDF data
func (this *PdfWriter) straightOut(s string) {
this.current_obj.buffer.WriteString(s)
}
// Output a PdfValue
func (this *PdfWriter) writeValue(value *PdfValue) {
switch value.Type {
case PDF_TYPE_TOKEN:
this.straightOut(value.Token + " ")
break
case PDF_TYPE_NUMERIC:
this.straightOut(fmt.Sprintf("%d", value.Int) + " ")
break
case PDF_TYPE_REAL:
this.straightOut(fmt.Sprintf("%F", value.Real) + " ")
break
case PDF_TYPE_ARRAY:
this.straightOut("[")
for i := 0; i < len(value.Array); i++ {
this.writeValue(value.Array[i])
}
this.out("]")
break
case PDF_TYPE_DICTIONARY:
this.straightOut("<<")
for k, v := range value.Dictionary {
this.straightOut(k + " ")
this.writeValue(v)
}
this.straightOut(">>")
break
case PDF_TYPE_OBJREF:
// An indirect object reference. Fill the object stack if needed.
// Check to see if object already exists on the don_obj_stack.
if _, ok := this.don_obj_stack[value.Id]; !ok {
this.newObj(-1, true)
this.obj_stack[value.Id] = &PdfValue{Type: PDF_TYPE_OBJREF, Gen: value.Gen, Id: value.Id, NewId: this.n}
this.don_obj_stack[value.Id] = &PdfValue{Type: PDF_TYPE_OBJREF, Gen: value.Gen, Id: value.Id, NewId: this.n}
}
// Get object ID from don_obj_stack
objId := this.don_obj_stack[value.Id].NewId
this.outObjRef(objId)
//this.out(fmt.Sprintf("%d 0 R", objId))
break
case PDF_TYPE_STRING:
// A string
this.straightOut("(" + value.String + ")")
break
case PDF_TYPE_STREAM:
// A stream. First, output the stream dictionary, then the stream data itself.
this.writeValue(value.Value)
this.out("stream")
this.out(string(value.Stream.Bytes))
this.out("endstream")
break
case PDF_TYPE_HEX:
this.straightOut("<" + value.String + ">")
break
case PDF_TYPE_BOOLEAN:
if value.Bool {
this.straightOut("true")
} else {
this.straightOut("false")
}
break
case PDF_TYPE_NULL:
// The null object
this.straightOut("null ")
break
}
}
// Output Form XObjects (1 for each template)
// returns a map of template names (e.g. /GOFPDITPL1) to PdfObjectId
func (this *PdfWriter) PutFormXobjects(reader *PdfReader) (map[string]*PdfObjectId, error) {
// Set current reader
this.r = reader
var err error
var result = make(map[string]*PdfObjectId, 0)
compress := true
filter := ""
if compress {
filter = "/Filter /FlateDecode "
}
for i := 0; i < len(this.tpls); i++ {
tpl := this.tpls[i]
if tpl == nil {
return nil, errors.New("Template is nil")
}
var p string
if compress {
var b bytes.Buffer
w := zlib.NewWriter(&b)
w.Write([]byte(tpl.Buffer))
w.Close()
p = b.String()
} else {
p = tpl.Buffer
}
// Create new PDF object
this.newObj(-1, false)
cN := this.n // remember current "n"
tpl.N = this.n
// Return xobject form name and object position
pdfObjId := new(PdfObjectId)
pdfObjId.id = cN
pdfObjId.hash = this.shaOfInt(cN)
result[fmt.Sprintf("/GOFPDITPL%d", i+this.tpl_id_offset)] = pdfObjId
this.out("<<" + filter + "/Type /XObject")
this.out("/Subtype /Form")
this.out("/FormType 1")
this.out(fmt.Sprintf("/BBox [%.2F %.2F %.2F %.2F]", tpl.Box["llx"]*this.k, tpl.Box["lly"]*this.k, (tpl.Box["urx"]+tpl.X)*this.k, (tpl.Box["ury"]-tpl.Y)*this.k))
var c, s, tx, ty float64
c = 1
// Handle rotated pages
if tpl.Box != nil {
tx = -tpl.Box["llx"]
ty = -tpl.Box["lly"]
if tpl.Rotation != 0 {
angle := float64(tpl.Rotation) * math.Pi / 180.0
c = math.Cos(float64(angle))
s = math.Sin(float64(angle))
switch tpl.Rotation {
case -90:
tx = -tpl.Box["lly"]
ty = tpl.Box["urx"]
break
case -180:
tx = tpl.Box["urx"]
ty = tpl.Box["ury"]
break
case -270:
tx = tpl.Box["ury"]
ty = -tpl.Box["llx"]
}
}
} else {
tx = -tpl.Box["x"] * 2
ty = tpl.Box["y"] * 2
}
tx *= this.k
ty *= this.k
if c != 1 || s != 0 || tx != 0 || ty != 0 {
this.out(fmt.Sprintf("/Matrix [%.5F %.5F %.5F %.5F %.5F %.5F]", c, s, -s, c, tx, ty))
}
// Now write resources
this.out("/Resources ")
if tpl.Resources != nil {
this.writeValue(tpl.Resources) // "n" will be changed
} else {
return nil, errors.New("Template resources are empty")
}
nN := this.n // remember new "n"
this.n = cN // reset to current "n"
this.out("/Length " + fmt.Sprintf("%d", len(p)) + " >>")
this.out("stream")
this.out(p)
this.out("endstream")
this.endObj()
this.n = nN // reset to new "n"
// Put imported objects, starting with the ones from the XObject's Resources,
// then from dependencies of those resources).
err = this.putImportedObjects(reader)
if err != nil {
return nil, errors.Wrap(err, "Failed to put imported objects")
}
}
return result, nil
}
func (this *PdfWriter) putImportedObjects(reader *PdfReader) error {
var err error
var nObj *PdfValue
// obj_stack will have new items added to it in the inner loop, so do another loop to check for extras
// TODO make the order of this the same every time
for {
atLeastOne := false
// FIXME: How to determine number of objects before this loop?
for i := 0; i < 9999; i++ {
k := i
v := this.obj_stack[i]
if v == nil {
continue
}
atLeastOne = true
nObj, err = reader.resolveObject(v)
if err != nil {
return errors.Wrap(err, "Unable to resolve object")
}
// New object with "NewId" field
this.newObj(v.NewId, false)
if nObj.Type == PDF_TYPE_STREAM {
this.writeValue(nObj)
} else {
this.writeValue(nObj.Value)
}
this.endObj()
// Remove from stack
this.obj_stack[k] = nil
}
if !atLeastOne {
break
}
}
return nil
}
// Get the calculated size of a template
// If one size is given, this method calculates the other one
func (this *PdfWriter) getTemplateSize(tplid int, _w float64, _h float64) map[string]float64 {
result := make(map[string]float64, 2)
tpl := this.tpls[tplid]
w := tpl.W
h := tpl.H
if _w == 0 && _h == 0 {
_w = w
_h = h
}
if _w == 0 {
_w = _h * w / h
}
if _h == 0 {
_h = _w * h / w
}
result["w"] = _w
result["h"] = _h
return result
}
func (this *PdfWriter) UseTemplate(tplid int, _x float64, _y float64, _w float64, _h float64) (string, float64, float64, float64, float64) {
tpl := this.tpls[tplid]
w := tpl.W
h := tpl.H
_x += tpl.X
_y += tpl.Y
wh := this.getTemplateSize(0, _w, _h)
_w = wh["w"]
_h = wh["h"]
tData := make(map[string]float64, 9)
tData["x"] = 0.0
tData["y"] = 0.0
tData["w"] = _w
tData["h"] = _h
tData["scaleX"] = (_w / w)
tData["scaleY"] = (_h / h)
tData["tx"] = _x
tData["ty"] = (0 - _y - _h)
tData["lty"] = (0 - _y - _h) - (0-h)*(_h/h)
return fmt.Sprintf("/GOFPDITPL%d", tplid+this.tpl_id_offset), tData["scaleX"], tData["scaleY"], tData["tx"] * this.k, tData["ty"] * this.k
}
================================================
FILE: vendor/github.com/pkg/errors/.gitignore
================================================
# Compiled Object files, Static and Dynamic libs (Shared Objects)
*.o
*.a
*.so
# Folders
_obj
_test
# Architecture specific extensions/prefixes
*.[568vq]
[568vq].out
*.cgo1.go
*.cgo2.c
_cgo_defun.c
_cgo_gotypes.go
_cgo_export.*
_testmain.go
*.exe
*.test
*.prof
================================================
FILE: vendor/github.com/pkg/errors/.travis.yml
================================================
language: go
go_import_path: github.com/pkg/errors
go:
- 1.4.x
- 1.5.x
- 1.6.x
- 1.7.x
- 1.8.x
- 1.9.x
- 1.10.x
- 1.11.x
- tip
script:
- go test -v ./...
================================================
FILE: vendor/github.com/pkg/errors/LICENSE
================================================
Copyright (c) 2015, Dave Cheney <dave@cheney.net>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
================================================
FILE: vendor/github.com/pkg/errors/README.md
================================================
# errors [](https://travis-ci.org/pkg/errors) [](https://ci.appveyor.com/project/davecheney/errors/branch/master) [](http://godoc.org/github.com/pkg/errors) [](https://goreportcard.com/report/github.com/pkg/errors) [](https://sourcegraph.com/github.com/pkg/errors?badge)
Package errors provides simple error handling primitives.
`go get github.com/pkg/errors`
The traditional error handling idiom in Go is roughly akin to
```go
if err != nil {
return err
}
```
which applied recursively up the call stack results in error reports without context or debugging information. The errors package allows programmers to add context to the failure path in their code in a way that does not destroy the original value of the error.
## Adding context to an error
The errors.Wrap function returns a new error that adds context to the original error. For example
```go
_, err := ioutil.ReadAll(r)
if err != nil {
return errors.Wrap(err, "read failed")
}
```
## Retrieving the cause of an error
Using `errors.Wrap` constructs a stack of errors, adding context to the preceding error. Depending on the nature of the error it may be necessary to reverse the operation of errors.Wrap to retrieve the original error for inspection. Any error value which implements this interface can be inspected by `errors.Cause`.
```go
type causer interface {
Cause() error
}
```
`errors.Cause` will recursively retrieve the topmost error which does not implement `causer`, which is assumed to be the original cause. For example:
```go
switch err := errors.Cause(err).(type) {
case *MyError:
// handle specifically
default:
// unknown error
}
```
[Read the package documentation for more information](https://godoc.org/github.com/pkg/errors).
## Contributing
We welcome pull requests, bug fixes and issue reports. With that said, the bar for adding new symbols to this package is intentionally set high.
Before proposing a change, please discuss your change by raising an issue.
## License
BSD-2-Clause
================================================
FILE: vendor/github.com/pkg/errors/appveyor.yml
================================================
version: build-{build}.{branch}
clone_folder: C:\gopath\src\github.com\pkg\errors
shallow_clone: true # for startup speed
environment:
GOPATH: C:\gopath
platform:
- x64
# http://www.appveyor.com/docs/installed-software
install:
# some helpful output for debugging builds
- go version
- go env
# pre-installed MinGW at C:\MinGW is 32bit only
# but MSYS2 at C:\msys64 has mingw64
- set PATH=C:\msys64\mingw64\bin;%PATH%
- gcc --version
- g++ --version
build_script:
- go install -v ./...
test_script:
- set PATH=C:\gopath\bin;%PATH%
- go test -v ./...
#artifacts:
# - path: '%GOPATH%\bin\*.exe'
deploy: off
================================================
FILE: vendor/github.com/pkg/errors/errors.go
================================================
// Package errors provides simple error handling primitives.
//
// The traditional error handling idiom in Go is roughly akin to
//
// if err != nil {
// return err
// }
//
// which when applied recursively up the call stack results in error reports
// without context or debugging information. The errors package allows
// programmers to add context to the failure path in their code in a way
// that does not destroy the original value of the error.
//
// Adding context to an error
//
// The errors.Wrap function returns a new error that adds context to the
// original error by recording a stack trace at the point Wrap is called,
// together with the supplied message. For example
//
// _, err := ioutil.ReadAll(r)
// if err != nil {
// return errors.Wrap(err, "read failed")
// }
//
// If additional control is required, the errors.WithStack and
// errors.WithMessage functions destructure errors.Wrap into its component
// operations: annotating an error with a stack trace and with a message,
// respectively.
//
// Retrieving the cause of an error
//
// Using errors.Wrap constructs a stack of errors, adding context to the
// preceding error. Depending on the nature of the error it may be necessary
// to reverse the operation of errors.Wrap to retrieve the original error
// for inspection. Any error value which implements this interface
//
// type causer interface {
// Cause() error
// }
//
// can be inspected by errors.Cause. errors.Cause will recursively retrieve
// the topmost error that does not implement causer, which is assumed to be
// the original cause. For example:
//
// switch err := errors.Cause(err).(type) {
// case *MyError:
// // handle specifically
// default:
// // unknown error
// }
//
// Although the causer interface is not exported by this package, it is
// considered a part of its stable public interface.
//
// Formatted printing of errors
//
// All error values returned from this package implement fmt.Formatter and can
// be formatted by the fmt package. The following verbs are supported:
//
// %s print the error. If the error has a Cause it will be
// printed recursively.
// %v see %s
// %+v extended format. Each Frame of the error's StackTrace will
// be printed in detail.
//
// Retrieving the stack trace of an error or wrapper
//
// New, Errorf, Wrap, and Wrapf record a stack trace at the point they are
// invoked. This information can be retrieved with the following interface:
//
// type stackTracer interface {
// StackTrace() errors.StackTrace
// }
//
// The returned errors.StackTrace type is defined as
//
// type StackTrace []Frame
//
// The Frame type represents a call site in the stack trace. Frame supports
// the fmt.Formatter interface that can be used for printing information about
// the stack trace of this error. For example:
//
// if err, ok := err.(stackTracer); ok {
// for _, f := range err.StackTrace() {
// fmt.Printf("%+s:%d", f)
// }
// }
//
// Although the stackTracer interface is not exported by this package, it is
// considered a part of its stable public interface.
//
// See the documentation for Frame.Format for more details.
package errors
import (
"fmt"
"io"
)
// New returns an error with the supplied message.
// New also records the stack trace at the point it was called.
func New(message string) error {
return &fundamental{
msg: message,
stack: callers(),
}
}
// Errorf formats according to a format specifier and returns the string
// as a value that satisfies error.
// Errorf also records the stack trace at the point it was called.
func Errorf(format string, args ...interface{}) error {
return &fundamental{
msg: fmt.Sprintf(format, args...),
stack: callers(),
}
}
// fundamental is an error that has a message and a stack, but no caller.
type fundamental struct {
msg string
*stack
}
func (f *fundamental) Error() string { return f.msg }
func (f *fundamental) Format(s fmt.State, verb rune) {
switch verb {
case 'v':
if s.Flag('+') {
io.WriteString(s, f.msg)
f.stack.Format(s, verb)
return
}
fallthrough
case 's':
io.WriteString(s, f.msg)
case 'q':
fmt.Fprintf(s, "%q", f.msg)
}
}
// WithStack annotates err with a stack trace at the point WithStack was called.
// If err is nil, WithStack returns nil.
func WithStack(err error) error {
if err == nil {
return nil
}
return &withStack{
err,
callers(),
}
}
type withStack struct {
error
*stack
}
func (w *withStack) Cause() error { return w.error }
func (w *withStack) Format(s fmt.State, verb rune) {
switch verb {
case 'v':
if s.Flag('+') {
fmt.Fprintf(s, "%+v", w.Cause())
w.stack.Format(s, verb)
return
}
fallthrough
case 's':
io.WriteString(s, w.Error())
case 'q':
fmt.Fprintf(s, "%q", w.Error())
}
}
// Wrap returns an error annotating err with a stack trace
// at the point Wrap is called, and the supplied message.
// If err is nil, Wrap returns nil.
func Wrap(err error, message string) error {
if err == nil {
return nil
}
err = &withMessage{
cause: err,
msg: message,
}
return &withStack{
err,
callers(),
}
}
// Wrapf returns an error annotating err with a stack trace
// at the point Wrapf is called, and the format specifier.
// If err is nil, Wrapf returns nil.
func Wrapf(err error, format string, args ...interface{}) error {
if err == nil {
return nil
}
err = &withMessage{
cause: err,
msg: fmt.Sprintf(format, args...),
}
return &withStack{
err,
callers(),
}
}
// WithMessage annotates err with a new message.
// If err is nil, WithMessage returns nil.
func WithMessage(err error, message string) error {
if err == nil {
return nil
}
return &withMessage{
cause: err,
msg: message,
}
}
// WithMessagef annotates err with the format specifier.
// If err is nil, WithMessagef returns nil.
func WithMessagef(err error, format string, args ...interface{}) error {
if err == nil {
return nil
}
return &withMessage{
cause: err,
msg: fmt.Sprintf(format, args...),
}
}
type withMessage struct {
cause error
msg string
}
func (w *withMessage) Error() string { return w.msg + ": " + w.cause.Error() }
func (w *withMessage) Cause() error { return w.cause }
func (w *withMessage) Format(s fmt.State, verb rune) {
switch verb {
case 'v':
if s.Flag('+') {
fmt.Fprintf(s, "%+v\n", w.Cause())
io.WriteString(s, w.msg)
return
}
fallthrough
case 's', 'q':
io.WriteString(s, w.Error())
}
}
// Cause returns the underlying cause of the error, if possible.
// An error value has a cause if it implements the following
// interface:
//
// type causer interface {
// Cause() error
// }
//
// If the error does not implement Cause, the original error will
// be returned. If the error is nil, nil will be returned without further
// investigation.
func Cause(err error) error {
type causer interface {
Cause() error
}
for err != nil {
cause, ok := err.(causer)
if !ok {
break
}
err = cause.Cause()
}
return err
}
================================================
FILE: vendor/github.com/pkg/errors/stack.go
================================================
package errors
import (
"fmt"
"io"
"path"
"runtime"
"strings"
)
// Frame represents a program counter inside a stack frame.
type Frame uintptr
// pc returns the program counter for this frame;
// multiple frames may have the same PC value.
func (f Frame) pc() uintptr { return uintptr(f) - 1 }
// file returns the full path to the file that contains the
// function for this Frame's pc.
func (f Frame) file() string {
fn := runtime.FuncForPC(f.pc())
if fn == nil {
return "unknown"
}
file, _ := fn.FileLine(f.pc())
return file
}
// line returns the line number of source code of the
// function for this Frame's pc.
func (f Frame) line() int {
fn := runtime.FuncForPC(f.pc())
if fn == nil {
return 0
}
_, line := fn.FileLine(f.pc())
return line
}
// Format formats the frame according to the fmt.Formatter interface.
//
// %s source file
// %d source line
// %n function name
// %v equivalent to %s:%d
//
// Format accepts flags that alter the printing of some verbs, as follows:
//
// %+s function name and path of source file relative to the compile time
// GOPATH separated by \n\t (<funcname>\n\t<path>)
// %+v equivalent to %+s:%d
func (f Frame) Format(s fmt.State, verb rune) {
switch verb {
case 's':
switch {
case s.Flag('+'):
pc := f.pc()
fn := runtime.FuncForPC(pc)
if fn == nil {
io.WriteString(s, "unknown")
} else {
file, _ := fn.FileLine(pc)
fmt.Fprintf(s, "%s\n\t%s", fn.Name(), file)
}
default:
io.WriteString(s, path.Base(f.file()))
}
case 'd':
fmt.Fprintf(s, "%d", f.line())
case 'n':
name := runtime.FuncForPC(f.pc()).Name()
io.WriteString(s, funcname(name))
case 'v':
f.Format(s, 's')
io.WriteString(s, ":")
f.Format(s, 'd')
}
}
// StackTrace is stack of Frames from innermost (newest) to outermost (oldest).
type StackTrace []Frame
// Format formats the stack of Frames according to the fmt.Formatter interface.
//
// %s lists source files for each Frame in the stack
// %v lists the source file and line number for each Frame in the stack
//
// Format accepts flags that alter the printing of some verbs, as follows:
//
// %+v Prints filename, function, and line number for each Frame in the stack.
func (st StackTrace) Format(s fmt.State, verb rune) {
switch verb {
case 'v':
switch {
case s.Flag('+'):
for _, f := range st {
fmt.Fprintf(s, "\n%+v", f)
}
case s.Flag('#'):
fmt.Fprintf(s, "%#v", []Frame(st))
default:
fmt.Fprintf(s, "%v", []Frame(st))
}
case 's':
fmt.Fprintf(s, "%s", []Frame(st))
}
}
// stack represents a stack of program counters.
type stack []uintptr
func (s *stack) Format(st fmt.State, verb rune) {
switch verb {
case 'v':
switch {
case st.Flag('+'):
for _, pc := range *s {
f := Frame(pc)
fmt.Fprintf(st, "\n%+v", f)
}
}
}
}
func (s *stack) StackTrace() StackTrace {
f := make([]Frame, len(*s))
for i := 0; i < len(f); i++ {
f[i] = Frame((*s)[i])
}
return f
}
func callers() *stack {
const depth = 32
var pcs [depth]uintptr
n := runtime.Callers(3, pcs[:])
var st stack = pcs[0:n]
return &st
}
// funcname removes the path prefix component of a function's name reported by func.Name().
func funcname(name string) string {
i := strings.LastIndex(name, "/")
name = name[i+1:]
i = strings.Index(name, ".")
return name[i+1:]
}
================================================
FILE: vendor/github.com/signintech/gopdf/.gitignore
================================================
##android
# built application files
*.apk
*.ap_
# files for the dex VM
*.dex
# Java class files
*.class
# generated files
bin/
gen/
pkg/
*.jar
# Local configuration file (sdk path, etc)
local.properties
##eclipse
*.pydevproject
.project
.metadata
bin/**
tmp/**
tmp/**/*
*.tmp
*.bak
*.swp
*~.nib
local.properties
.classpath
.settings/
.loadpath
# External tool builders
.externalToolBuilders/
# Locally stored "Eclipse launch configurations"
*.launch
# CDT-specific
.cproject
# PDT-specific
.buildpath
##tmp
*~
*.bak
proguard-project.txt
/project.properties
lint.xml
.bzr
fontmaker/tmp/
fontmaker/fontmaker
fontmaker/ttf/
*.orig
.vscode
test/out/
test/debug.test
*.test
*.out
.DS_Store
.idea
.scannerwork
================================================
FILE: vendor/github.com/signintech/gopdf/Changelog.md
================================================
### May 2016
Remove old function
- ```GoPdf.AddFont(family string, ifont IFont, zfontpath string)```.
- Remove all font map file.
================================================
FILE: vendor/github.com/signintech/gopdf/LICENSE
================================================
The MIT License (MIT)
Copyright (c) 2015 signintech
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
================================================
FILE: vendor/github.com/signintech/gopdf/README.md
================================================
gopdf
====
gopdf is a simple library for generating PDF document written in Go lang.
#### Features
- Unicode subfont embedding. (Chinese, Japanese, Korean, etc.)
- Draw line, oval, rect, curve
- Draw image ( jpg, png )
- Set image mask
- Password protection
- Font [kerning](https://en.wikipedia.org/wiki/Kerning)
## Installation
```
go get -u github.com/signintech/gopdf
```
### Print text
```go
package main
import (
"log"
"github.com/signintech/gopdf"
)
func main() {
pdf := gopdf.GoPdf{}
pdf.Start(gopdf.Config{ PageSize: *gopdf.PageSizeA4 })
pdf.AddPage()
err := pdf.AddTTFFont("wts11", "../ttf/wts11.ttf")
if err != nil {
log.Print(err.Error())
return
}
err = pdf.SetFont("wts11", "", 14)
if err != nil {
log.Print(err.Error())
return
}
pdf.Cell(nil, "您好")
pdf.WritePdf("hello.pdf")
}
```
### Image
```go
package main
import (
"log"
"github.com/signintech/gopdf"
)
func main() {
pdf := gopdf.GoPdf{}
pdf.Start(gopdf.Config{PageSize: *gopdf.PageSizeA4 })
pdf.AddPage()
var err error
err = pdf.AddTTFFont("loma", "../ttf/Loma.ttf")
if err != nil {
log.Print(err.Error())
return
}
pdf.Image("../imgs/gopher.jpg", 200, 50, nil) //print image
err = pdf.SetFont("loma", "", 14)
if err != nil {
log.Print(err.Error())
return
}
pdf.SetX(250) //move current location
pdf.SetY(200)
pdf.Cell(nil, "gopher and gopher") //print text
pdf.WritePdf("image.pdf")
}
```
### Links
```go
package main
import (
"log"
"github.com/signintech/gopdf"
)
func main() {
pdf := gopdf.GoPdf{}
pdf.Start(gopdf.Config{ PageSize: *gopdf.PageSizeA4 }) //595.28, 841.89 = A4
pdf.AddPage()
err := pdf.AddTTFFont("times", "./test/res/times.ttf")
if err != nil {
log.Print(err.Error())
return
}
err = pdf.SetFont("times", "", 14)
if err != nil {
log.Print(err.Error())
return
}
pdf.SetX(30)
pdf.SetY(40)
pdf.Text("Link to example.com")
pdf.AddExternalLink("http://example.com/", 27.5, 28, 125, 15)
pdf.SetX(30)
pdf.SetY(70)
pdf.Text("Link to second page")
pdf.AddInternalLink("anchor", 27.5, 58, 120, 15)
pdf.AddPage()
pdf.SetX(30)
pdf.SetY(100)
pdf.SetAnchor("anchor")
pdf.Text("Anchor position")
pdf.WritePdf("hello.tmp.pdf")
}
```
### Draw line
```go
pdf.SetLineWidth(2)
pdf.SetLineType("dashed")
pdf.Line(10, 30, 585, 30)
```
### Draw oval
```go
pdf.SetLineWidth(1)
pdf.Oval(100, 200, 500, 500)
```
### Draw polygon
```go
pdf.SetStrokeColor(255, 0, 0)
pdf.SetLineWidth(2)
pdf.SetFillColor(0, 255, 0)
pdf.Polygon([]gopdf.Point{{X: 10, Y: 30}, {X: 585, Y: 200}, {X: 585, Y: 250}}, "DF")
```
### Rotation text or image
```go
pdf.SetX(100)
pdf.SetY(100)
pdf.Rotate(270.0, 100.0, 100.0)
pdf.Text("Hello...")
pdf.RotateReset() //reset
```
### Set transparency
Read about [transparency in pdf](https://www.adobe.com/content/dam/acom/en/devnet/acrobat/pdfs/PDF32000_2008.pdf) `(page 320, section 11)`
```go
// alpha - value of transparency, can be between `0` and `1`
// blendMode - default value is `/Normal` - read about [blendMode and kinds of its](https://www.adobe.com/content/dam/acom/en/devnet/acrobat/pdfs/PDF32000_2008.pdf) `(page 325, section 11.3.5)`
transparency := Transparency{
Alpha: 0.5,
BlendModeType: "",
}
pdf.SetTransparency(transparency Transparency)
```
### Password protection
```go
package main
import (
"log"
"github.com/signintech/gopdf"
)
func main() {
pdf := gopdf.GoPdf{}
pdf.Start(gopdf.Config{
PageSize: *gopdf.PageSizeA4, //595.28, 841.89 = A4
Protection: gopdf.PDFProtectionConfig{
UseProtection: true,
Permissions: gopdf.PermissionsPrint | gopdf.PermissionsCopy | gopdf.PermissionsModify,
OwnerPass: []byte("123456"),
UserPass: []byte("123456789")},
})
pdf.AddPage()
pdf.AddTTFFont("loma", "../ttf/loma.ttf")
pdf.Cell(nil,"Hi")
pdf.WritePdf("protect.pdf")
}
```
### Import existing PDF
Import existing PDF power by package [gofpdi](https://github.com/phpdave11/gofpdi) created by @phpdave11 (thank you :smile:)
```go
package main
import (
"github.com/signintech/gopdf"
"io"
"net/http"
"os"
)
func main() {
var err error
// Download a Font
fontUrl := "https://github.com/google/fonts/raw/master/ofl/daysone/DaysOne-Regular.ttf"
if err = DownloadFile("example-font.ttf", fontUrl); err != nil {
panic(err)
}
// Download a PDF
fileUrl := "https://tcpdf.org/files/examples/example_012.pdf"
if err = DownloadFile("example-pdf.pdf", fileUrl); err != nil {
panic(err)
}
pdf := gopdf.GoPdf{}
pdf.Start(gopdf.Config{PageSize: gopdf.Rect{W: 595.28, H: 841.89}}) //595.28, 841.89 = A4
pdf.AddPage()
err = pdf.AddTTFFont("daysone", "example-font.ttf")
if err != nil {
panic(err)
}
err = pdf.SetFont("daysone", "", 20)
if err != nil {
panic(err)
}
// Color the page
pdf.SetLineWidth(0.1)
pdf.SetFillColor(124, 252, 0) //setup fill color
pdf.RectFromUpperLeftWithStyle(50, 100, 400, 600, "FD")
pdf.SetFillColor(0, 0, 0)
pdf.SetX(50)
pdf.SetY(50)
pdf.Cell(nil, "Import existing PDF into GoPDF Document")
// Import page 1
tpl1 := pdf.ImportPage("example-pdf.pdf", 1, "/MediaBox")
// Draw pdf onto page
pdf.UseImportedTemplate(tpl1, 50, 100, 400, 0)
pdf.WritePdf("example.pdf")
}
// DownloadFile will download a url to a local file. It's efficient because it will
// write as it downloads and not load the whole file into memory.
func DownloadFile(filepath string, url string) error {
// Get the data
resp, err := http.Get(url)
if err != nil {
return err
}
defer resp.Body.Close()
// Create the file
out, err := os.Create(filepath)
if err != nil {
return err
}
defer out.Close()
// Write the body to file
_, err = io.Copy(out, resp.Body)
return err
}
```
### Possible to set [Trim-box](https://wiki.scribus.net/canvas/PDF_Boxes_:_mediabox,_cropbox,_bleedbox,_trimbox,_artbox)
```go
package main
import (
"log"
"github.com/signintech/gopdf"
)
func main() {
pdf := gopdf.GoPdf{}
mm6ToPx := 22.68
// Base trim-box
pdf.Start(gopdf.Config{
PageSize: *gopdf.PageSizeA4, //595.28, 841.89 = A4
TrimBox: gopdf.Box{Left: mm6ToPx, Top: mm6ToPx, Right: 595 - mm6ToPx, Bottom: 842 - mm6ToPx},
})
// Page trim-box
opt := gopdf.PageOption{
PageSize: gopdf.PageSizeA4, //595.28, 841.89 = A4
TrimBox: &gopdf.Box{Left: mm6ToPx, Top: mm6ToPx, Right: 595 - mm6ToPx, Bottom: 842 - mm6ToPx},
}
pdf.AddPageWithOption(opt)
if err := pdf.AddTTFFont("wts11", "../ttf/wts11.ttf"); err != nil {
log.Print(err.Error())
return
}
if err := pdf.SetFont("wts11", "", 14); err != nil {
log.Print(err.Error())
return
}
pdf.Cell(nil,"Hi")
pdf.WritePdf("hello.pdf")
}
```
visit https://github.com/oneplus1000/gopdfsample for more samples.
================================================
FILE: vendor/github.com/signintech/gopdf/box.go
================================================
package gopdf
type Box struct {
Left, Top, Right, Bottom float64
unitOverride int
}
// UnitsToPoints converts the box coordinates to Points. When this is called it is assumed the values of the box are in Units
func (box *Box) UnitsToPoints(t int) (b *Box) {
if box == nil {
return
}
if box.unitOverride != UnitUnset {
t = box.unitOverride
}
b = &Box{
Left: box.Left,
Top: box.Top,
Right: box.Right,
Bottom: box.Bottom,
}
UnitsToPointsVar(t, &b.Left, &b.Top, &b.Right, &b.Bottom)
return
}
================================================
FILE: vendor/github.com/signintech/gopdf/buff.go
================================================
package gopdf
//Buff for pdf content
type Buff struct {
position int
datas []byte
}
//Write : write []byte to buffer
func (b *Buff) Write(p []byte) (int, error) {
for len(b.datas) < b.position+len(p) {
b.datas = append(b.datas, 0)
}
i := 0
max := len(p)
for i < max {
b.datas[i+b.position] = p[i]
i++
}
b.position += i
return 0, nil
}
//Len : len of buffer
func (b *Buff) Len() int {
return len(b.datas)
}
//Bytes : get bytes
func (b *Buff) Bytes() []byte {
return b.datas
}
//Position : get current postion
func (b *Buff) Position() int {
return b.position
}
//SetPosition : set current postion
func (b *Buff) SetPosition(pos int) {
b.position = pos
}
================================================
FILE: vendor/github.com/signintech/gopdf/buff_write.go
================================================
package gopdf
import "io"
//WriteUInt32 writes a 32-bit unsigned integer value to w io.Writer
func WriteUInt32(w io.Writer, v uint) error {
a := byte(v >> 24)
b := byte(v >> 16)
c := byte(v >> 8)
d := byte(v)
_, err := w.Write([]byte{a, b, c, d})
if err != nil {
return err
}
return nil
}
//WriteUInt16 writes a 16-bit unsigned integer value to w io.Writer
func WriteUInt16(w io.Writer, v uint) error {
a := byte(v >> 8)
b := byte(v)
_, err := w.Write([]byte{a, b})
if err != nil {
return err
}
return nil
}
//WriteTag writes string value to w io.Writer
func WriteTag(w io.Writer, tag string) error {
b := []byte(tag)
_, err := w.Write(b)
if err != nil {
return err
}
return nil
}
//WriteBytes writes []byte value to w io.Writer
func WriteBytes(w io.Writer, data []byte, offset int, count int) error {
_, err := w.Write(data[offset : offset+count])
if err != nil {
return err
}
return nil
}
================================================
FILE: vendor/github.com/signintech/gopdf/buffer_pool.go
================================================
package gopdf
import (
"bytes"
"sync"
)
// buffer pool to reduce GC
var buffers = sync.Pool{
// New is called when a new instance is needed
New: func() interface{} {
return new(bytes.Buffer)
},
}
// GetBuffer fetches a buffer from the pool
func GetBuffer() *bytes.Buffer {
return buffers.Get().(*bytes.Buffer)
}
// PutBuffer returns a buffer to the pool
func PutBuffer(buf *bytes.Buffer) {
buf.Reset()
buffers.Put(buf)
}
================================================
FILE: vendor/github.com/signintech/gopdf/cache_contact_color.go
================================================
package gopdf
import (
"fmt"
"io"
)
const colorTypeStroke = "RG"
const colorTypeFill = "rg"
type cacheContentColor struct {
colorType string
r, g, b uint8
}
func (c *cacheContentColor) write(w io.Writer, protection *PDFProtection) error {
fmt.Fprintf(w, "%.3f %.3f %.3f %s\n", float64(c.r)/255, float64(c.g)/255, float64(c.b)/255, c.colorType)
return nil
}
================================================
FILE: vendor/github.com/signintech/gopdf/cache_content_gray.go
================================================
package gopdf
import (
"fmt"
"io"
)
const grayTypeFill = "g"
const grayTypeStroke = "G"
type cacheContentGray struct {
grayType string
scale float64
}
func (c *cacheContentGray) write(w io.Writer, protection *PDFProtection) error {
fmt.Fprintf(w, "%.2f %s\n", c.scale, c.grayType)
return nil
}
================================================
FILE: vendor/github.com/signintech/gopdf/cache_content_image.go
================================================
package gopdf
import (
"fmt"
"io"
)
type cacheContentImage struct {
verticalFlip bool
horizontalFlip bool
index int
x float64
y float64
pageHeight float64
rect Rect
crop *CropOptions
extGStateIndexes []int
}
func (c *cacheContentImage) write(w io.Writer, protection *PDFProtection) error {
width := c.rect.W
height := c.rect.H
contentStream := "q\n"
for _, extGStateIndex := range c.extGStateIndexes {
contentStream += fmt.Sprintf("/GS%d gs\n", extGStateIndex)
}
if c.horizontalFlip || c.verticalFlip {
fh := "1"
if c.horizontalFlip {
fh = "-1"
}
fv := "1"
if c.verticalFlip {
fv = "-1"
}
contentStream += fmt.Sprintf("%s 0 0 %s 0 0 cm\n", fh, fv)
}
if c.crop != nil {
clippingX := c.x
if c.horizontalFlip {
clippingX = -clippingX - c.crop.Width
}
clippingY := c.pageHeight - (c.y + c.crop.Height)
if c.verticalFlip {
clippingY = -clippingY - c.crop.Height
}
startX := c.x - c.crop.X
if c.horizontalFlip {
startX = -startX - width
}
startY := c.pageHeight - (c.y - c.crop.Y + c.rect.H)
if c.verticalFlip {
startY = -startY - height
}
contentStream += fmt.Sprintf("%0.2f %0.2f %0.2f %0.2f re W* n\n", clippingX, clippingY, c.crop.Width, c.crop.Height)
contentStream += fmt.Sprintf("q %0.2f 0 0 %0.2f %0.2f %0.2f cm /I%d Do Q\n", width, height, startX, startY, c.index+1)
} else {
x := c.x
y := c.pageHeight - (c.y + height)
if c.horizontalFlip {
x = -x - width
}
if c.verticalFlip {
y = -y - height
}
contentStream += fmt.Sprintf("q %0.2f 0 0 %0.2f %0.2f %0.2f cm /I%d Do Q\n", width, height, x, y, c.index+1)
}
contentStream += "Q\n"
if _, err := io.WriteString(w, contentStream); err != nil {
return err
}
return nil
}
================================================
FILE: vendor/github.com/signintech/gopdf/cache_content_imported_object.go
================================================
package gopdf
import (
"fmt"
"io"
)
type cacheContentImportedTemplate struct {
pageHeight float64
tplName string
scaleX float64
scaleY float64
tX float64
tY float64
}
func (c *cacheContentImportedTemplate) write(w io.Writer, protection *PDFProtection) error {
c.tY += c.pageHeight
fmt.Fprintf(w, "q 0 J 1 w 0 j 0 G 0 g q %.4F 0 0 %.4F %.4F %.4F cm %s Do Q Q\n", c.scaleX, c.scaleY, c.tX, c.tY, c.tplName)
return nil
}
================================================
FILE: vendor/github.com/signintech/gopdf/cache_content_line.go
================================================
package gopdf
import (
"fmt"
"io"
)
type cacheContentLine struct {
pageHeight float64
x1 float64
y1 float64
x2 float64
y2 float64
}
func (c *cacheContentLine) write(w io.Writer, protection *PDFProtection) error {
fmt.Fprintf(w, "%0.2f %0.2f m %0.2f %0.2f l S\n", c.x1, c.pageHeight-c.y1, c.x2, c.pageHeight-c.y2)
return nil
}
================================================
FILE: vendor/github.com/signintech/gopdf/cache_content_line_type.go
================================================
package gopdf
import (
"fmt"
"io"
)
type cacheContentLineType struct {
lineType string
}
func (c *cacheContentLineType) write(w io.Writer, protection *PDFProtection) error {
switch c.lineType {
case "dashed":
fmt.Fprint(w, "[5] 2 d\n")
case "dotted":
fmt.Fprint(w, "[2 3] 11 d\n")
default:
fmt.Fprint(w, "[] 0 d\n")
}
return nil
}
================================================
FILE: vendor/github.com/signintech/gopdf/cache_content_line_width.go
================================================
package gopdf
import (
"fmt"
"io"
)
type cacheContentLineWidth struct {
width float64
}
func (c *cacheContentLineWidth) write(w io.Writer, protection *PDFProtection) error {
fmt.Fprintf(w, "%.2f w\n", c.width)
return nil
}
================================================
FILE: vendor/github.com/signintech/gopdf/cache_content_oval.go
================================================
package gopdf
import (
"fmt"
"io"
)
type cacheContentOval struct {
pageHeight float64
x1 float64
y1 float64
x2 float64
y2 float64
}
func (c *cacheContentOval) write(w io.Writer, protection *PDFProtection) error {
h := c.pageHeight
x1 := c.x1
y1 := c.y1
x2 := c.x2
y2 := c.y2
cp := 0.55228 // Magnification of the control point
v1 := [2]float64{x1 + (x2-x1)/2, h - y2} // Vertex of the lower
v2 := [2]float64{x2, h - (y1 + (y2-y1)/2)} // .. Right
v3 := [2]float64{x1 + (x2-x1)/2, h - y1} // .. Upper
v4 := [2]float64{x1, h - (y1 + (y2-y1)/2)} // .. Left
fmt.Fprintf(w, "%0.2f %0.2f m\n", v1[0], v1[1])
fmt.Fprintf(w,
"%0.2f %0.2f %0.2f %0.2f %0.2f %0.2f c\n",
v1[0]+(x2-x1)/2*cp, v1[1], v2[0], v2[1]-(y2-y1)/2*cp, v2[0], v2[1],
)
fmt.Fprintf(w,
"%0.2f %0.2f %0.2f %0.2f %0.2f %0.2f c\n",
v2[0], v2[1]+(y2-y1)/2*cp, v3[0]+(x2-x1)/2*cp, v3[1], v3[0], v3[1],
)
fmt.Fprintf(w,
"%0.2f %0.2f %0.2f %0.2f %0.2f %0.2f c\n",
v3[0]-(x2-x1)/2*cp, v3[1], v4[0], v4[1]+(y2-y1)/2*cp, v4[0], v4[1],
)
fmt.Fprintf(w,
"%0.2f %0.2f %0.2f %0.2f %0.2f %0.2f c S\n",
v4[0], v4[1]-(y2-y1)/2*cp, v1[0]-(x2-x1)/2*cp, v1[1], v1[0], v1[1],
)
return nil
}
================================================
FILE: vendor/github.com/signintech/gopdf/cache_content_polygon.go
================================================
package gopdf
import (
"fmt"
"io"
)
type cacheContentPolygon struct {
pageHeight float64
style string
points []Point
}
func (c *cacheContentPolygon) write(w io.Writer, protection *PDFProtection) error {
for i, point := range c.points {
fmt.Fprintf(w, "%.2f %.2f", point.X, c.pageHeight-point.Y)
if i == 0 {
fmt.Fprintf(w, " m ")
} else {
fmt.Fprintf(w, " l ")
}
}
if c.style == "F" {
fmt.Fprintf(w, " f\n")
} else if c.style == "FD" || c.style == "DF" {
fmt.Fprintf(w, " b\n")
} else {
fmt.Fprintf(w, " s\n")
}
return nil
}
================================================
FILE: vendor/github.com/signintech/gopdf/cache_content_rectangle.go
================================================
package gopdf
import (
"fmt"
"io"
)
type cacheContentRectangle struct {
pageHeight float64
x float64
y float64
width float64
height float64
style PaintStyle
extGStateIndexes []int
}
func NewCacheContentRectangle(pageHeight float64, rectOpts DrawableRectOptions) ICacheContent {
if rectOpts.PaintStyle == "" {
rectOpts.PaintStyle = DrawPaintStyle
}
return cacheContentRectangle{
x: rectOpts.X,
y: rectOpts.Y,
width: rectOpts.W,
height: rectOpts.H,
pageHeight: pageHeight,
style: rectOpts.PaintStyle,
extGStateIndexes: rectOpts.extGStateIndexes,
}
}
func (c cacheContentRectangle) write(w io.Writer, protection *PDFProtection) error {
stream := "q\n"
for _, extGStateIndex := range c.extGStateIndexes {
stream += fmt.Sprintf("/GS%d gs\n", extGStateIndex)
}
stream += fmt.Sprintf("%0.2f %0.2f %0.2f %0.2f re %s\n", c.x, c.pageHeight-c.y, c.width, c.height, c.style)
stream += "Q\n"
if _, err := io.WriteString(w, stream); err != nil {
return err
}
return nil
}
================================================
FILE: vendor/github.com/signintech/gopdf/cache_content_rotate.go
================================================
package gopdf
import (
"fmt"
"io"
"math"
)
type cacheContentRotate struct {
isReset bool
pageHeight float64
angle, x, y float64
}
func (cc *cacheContentRotate) write(w io.Writer, protection *PDFProtection) error {
if cc.isReset == true {
fmt.Fprintf(w, "Q\n")
return nil
}
angle := (cc.angle * 22.0) / (180.0 * 7.0)
c := math.Cos(angle)
s := math.Sin(angle)
cy := cc.pageHeight - cc.y
fmt.Fprintf(w, "q %.5f %.5f %.5f %.5f %.2f %.2f cm 1 0 0 1 %.2f %.2f cm\n", c, s, -s, c, cc.x, cy, -cc.x, -cy)
return nil
}
================================================
FILE: vendor/github.com/signintech/gopdf/cache_content_text.go
================================================
package gopdf
import (
"errors"
"fmt"
"io"
)
//ContentTypeCell cell
const ContentTypeCell = 0
//ContentTypeText text
const ContentTypeText = 1
type cacheContentText struct {
//---setup---
rectangle *Rect
textColor Rgb
grayFill float64
txtColorMode string
fontCountIndex int //Curr.FontFontCount+1
fontSize int
fontStyle int
setXCount int //จำนวนครั้งที่ใช้ setX
x, y float64
fontSubset *SubsetFontObj
pageheight float64
contentType int
cellOpt CellOption
lineWidth float64
text string
//---result---
cellWidthPdfUnit, textWidthPdfUnit float64
cellHeightPdfUnit float64
}
func (c *cacheContentText) isSame(cache cacheContentText) bool {
if c.rectangle != nil {
//if rectangle != nil we assumes this is not same content
return false
}
if c.textColor.equal(cache.textColor) &&
c.grayFill == cache.grayFill &&
c.fontCountIndex == cache.fontCountIndex &&
c.fontSize == cache.fontSize &&
c.fontStyle == cache.fontStyle &&
c.setXCount == cache.setXCount &&
c.y == cache.y {
return true
}
return false
}
func (c *cacheContentText) setPageHeight(pageheight float64) {
c.pageheight = pageheight
}
func (c *cacheContentText) pageHeight() float64 {
return c.pageheight //841.89
}
func convertTypoUnit(val float64, unitsPerEm uint, fontSize float64) float64 {
val = val * 1000.00 / float64(unitsPerEm)
return val * fontSize / 1000.0
}
func (c *cacheContentText) calTypoAscender() float64 {
return convertTypoUnit(float64(c.fontSubset.ttfp.TypoAscender()), c.fontSubset.ttfp.UnitsPerEm(), float64(c.fontSize))
}
func (c *cacheContentText) calTypoDescender() float64 {
return convertTypoUnit(float64(c.fontSubset.ttfp.TypoDescender()), c.fontSubset.ttfp.UnitsPerEm(), float64(c.fontSize))
}
func (c *cacheContentText) calY() (float64, error) {
pageHeight := c.pageHeight()
if c.contentType == ContentTypeText {
return pageHeight - c.y, nil
} else if c.contentType == ContentTypeCell {
y := float64(0.0)
if c.cellOpt.Align&Bottom == Bottom {
y = pageHeight - c.y - c.cellHeightPdfUnit - c.calTypoDescender()
} else if c.cellOpt.Align&Middle == Middle {
y = pageHeight - c.y - c.cellHeightPdfUnit*0.5 - (c.calTypoDescender()+c.calTypoAscender())*0.5
} else {
//top
y = pageHeight - c.y - c.calTypoAscender()
}
return y, nil
}
return 0.0, errors.New("contentType not found")
}
func (c *cacheContentText) calX() (float64, error) {
if c.contentType == ContentTypeText {
return c.x, nil
} else if c.contentType == ContentTypeCell {
x := float64(0.0)
if c.cellOpt.Align&Right == Right {
x = c.x + c.cellWidthPdfUnit - c.textWidthPdfUnit
} else if c.cellOpt.Align&Center == Center {
x = c.x + c.cellWidthPdfUnit*0.5 - c.textWidthPdfUnit*0.5
} else {
x = c.x
}
return x, nil
}
return 0.0, errors.New("contentType not found")
}
func (c *cacheContentText) write(w io.Writer, protection *PDFProtection) error {
r := c.textColor.r
g := c.textColor.g
b := c.textColor.b
x, err := c.calX()
if err != nil {
return err
}
y, err := c.calY()
if err != nil {
return err
}
for _, extGStateIndex := range c.cellOpt.extGStateIndexes {
linkToGSObj := fmt.Sprintf("/GS%d gs\n", extGStateIndex)
if _, err := io.WriteString(w, linkToGSObj); err != nil {
return err
}
}
if _, err := io.WriteString(w, "BT\n"); err != nil {
return err
}
fmt.Fprintf(w, "%0.2f %0.2f TD\n", x, y)
fmt.Fprintf(w, "/F%d %d Tf\n", c.fontCountIndex, c.fontSize)
if c.txtColorMode == "color" {
fmt.Fprintf(w, "%0.3f %0.3f %0.3f rg\n", float64(r)/255, float64(g)/255, float64(b)/255)
}
io.WriteString(w, "[<")
unitsPerEm := int(c.fontSubset.ttfp.UnitsPerEm())
var leftRune rune
var leftRuneIndex uint
for i, r := range c.text {
glyphindex, err := c.fontSubset.CharIndex(r)
if err != nil {
return err
}
pairvalPdfUnit := 0
if i > 0 && c.fontSubset.ttfFontOption.UseKerning { //kerning
pairval := kern(c.fontSubset, leftRune, r, leftRuneIndex, glyphindex)
pairvalPdfUnit = convertTTFUnit2PDFUnit(int(pairval), unitsPerEm)
if pairvalPdfUnit != 0 {
fmt.Fprintf(w, ">%d<", (-1)*pairvalPdfUnit)
}
}
fmt.Fprintf(w, "%04X", glyphindex)
leftRune = r
leftRuneIndex = glyphindex
}
io.WriteString(w, ">] TJ\n")
io.WriteString(w, "ET\n")
if c.fontStyle&Underline == Underline {
err := c.underline(w, c.x, c.y, c.x+c.cellWidthPdfUnit, c.y)
if err != nil {
return err
}
}
c.drawBorder(w)
return nil
}
func (c *cacheContentText) drawBorder(w io.Writer) error {
//stream.WriteString(fmt.Sprintf("%.2f w\n", 0.1))
lineOffset := c.lineWidth * 0.5
if c.cellOpt.Border&Top == Top {
startX := c.x - lineOffset
startY := c.pageHeight() - c.y
endX := c.x + c.cellWidthPdfUnit + lineOffset
endY := startY
_, err := fmt.Fprintf(w, "%0.2f %0.2f m %0.2f %0.2f l s\n", startX, startY, endX, endY)
if err != nil {
return err
}
}
if c.cellOpt.Border&Left == Left {
startX := c.x
startY := c.pageHeight() - c.y
endX := c.x
endY := startY - c.cellHeightPdfUnit
_, err := fmt.Fprintf(w, "%0.2f %0.2f m %0.2f %0.2f l s\n", startX, startY, endX, endY)
if err != nil {
return err
}
}
if c.cellOpt.Border&Right == Right {
startX := c.x + c.cellWidthPdfUnit
startY := c.pageHeight() - c.y
endX := c.x + c.cellWidthPdfUnit
endY := startY - c.cellHeightPdfUnit
_, err := fmt.Fprintf(w, "%0.2f %0.2f m %0.2f %0.2f l s\n", startX, startY, endX, endY)
if err != nil {
return err
}
}
if c.cellOpt.Border&Bottom == Bottom {
startX := c.x - lineOffset
startY := c.pageHeight() - c.y - c.cellHeightPdfUnit
endX := c.x + c.cellWidthPdfUnit + lineOffset
endY := startY
_, err := fmt.Fprintf(w, "%0.2f %0.2f m %0.2f %0.2f l s\n", startX, startY, endX, endY)
if err != nil {
return err
}
}
return nil
}
func (c *cacheContentText) underline(w io.Writer, startX float64, startY float64, endX float64, endY float64) error {
if c.fontSubset == nil {
return errors.New("error AppendUnderline not found font")
}
unitsPerEm := float64(c.fontSubset.ttfp.UnitsPerEm())
h := c.pageHeight()
ut := float64(c.fontSubset.GetUt())
up := float64(c.fontSubset.GetUp())
textH := ContentObjCalTextHeight(c.fontSize)
arg3 := float64(h) - (float64(startY) - ((up / unitsPerEm) * float64(c.fontSize))) - textH
arg4 := (ut / unitsPerEm) * float64(c.fontSize)
fmt.Fprintf(w, "%0.2f %0.2f %0.2f -%0.2f re f\n", startX, arg3, endX-startX, arg4)
//fmt.Printf("arg3=%f arg4=%f\n", arg3, arg4)
return nil
}
func (c *cacheContentText) createContent() (float64, float64, error) {
cellWidthPdfUnit, cellHeightPdfUnit, textWidthPdfUnit, err := createContent(c.fontSubset, c.text, c.fontSize, c.rectangle)
if err != nil {
return 0, 0, err
}
c.cellWidthPdfUnit = cellWidthPdfUnit
c.cellHeightPdfUnit = cellHeightPdfUnit
c.textWidthPdfUnit = textWidthPdfUnit
return cellWidthPdfUnit, cellHeightPdfUnit, nil
}
func createContent(f *SubsetFontObj, text string, fontSize int, rectangle *Rect) (float64, float64, float64, error) {
unitsPerEm := int(f.ttfp.UnitsPerEm())
var leftRune rune
var leftRuneIndex uint
sumWidth := int(0)
//fmt.Printf("unitsPerEm = %d", unitsPerEm)
for i, r := range text {
glyphindex, err := f.CharIndex(r)
if err != nil {
return 0, 0, 0, err
}
pairvalPdfUnit := 0
if i > 0 && f.ttfFontOption.UseKerning { //kerning
pairval := kern(f, leftRune, r, leftRuneIndex, glyphindex)
pairvalPdfUnit = convertTTFUnit2PDFUnit(int(pairval), unitsPerEm)
}
width, err := f.CharWidth(r)
if err != nil {
return 0, 0, 0, err
}
sumWidth += int(width) + int(pairvalPdfUnit)
leftRune = r
leftRuneIndex = glyphindex
}
cellWidthPdfUnit := float64(0)
cellHeightPdfUnit := float64(0)
if rectangle == nil {
cellWidthPdfUnit = float64(sumWidth) * (float64(fontSize) / 1000.0)
typoAscender := convertTypoUnit(float64(f.ttfp.TypoAscender()), f.ttfp.UnitsPerEm(), float64(fontSize))
typoDescender := convertTypoUnit(float64(f.ttfp.TypoDescender()), f.ttfp.UnitsPerEm(), float64(fontSize))
cellHeightPdfUnit = typoAscender - typoDescender
} else {
cellWidthPdfUnit = rectangle.W
cellHeightPdfUnit = rectangle.H
}
textWidthPdfUnit := float64(sumWidth) * (float64(fontSize) / 1000.0)
return cellWidthPdfUnit, cellHeightPdfUnit, textWidthPdfUnit, nil
}
func kern(f *SubsetFontObj, leftRune rune, rightRune rune, leftIndex uint, rightIndex uint) int16 {
pairVal := int16(0)
if haveKerning, kval := f.KernValueByLeft(leftIndex); haveKerning {
if ok, v := kval.ValueByRight(rightIndex); ok {
pairVal = v
}
}
if f.funcKernOverride != nil {
pairVal = f.funcKernOverride(
leftRune,
rightRune,
leftIndex,
rightIndex,
pairVal,
)
}
return pairVal
}
//CacheContent Export cacheContent
type CacheContent struct {
cacheContentText
}
//Setup setup all information for cacheContent
func (c *CacheContent) Setup(rectangle *Rect,
textColor Rgb,
grayFill float64,
fontCountIndex int, //Curr.FontFontCount+1
fontSize int,
fontStyle int,
setXCount int, //จำนวนครั้งที่ใช้ setX
x, y float64,
fontSubset *SubsetFontObj,
pageheight float64,
contentType int,
cellOpt CellOption,
lineWidth float64,
) {
c.cacheContentText = cacheContentText{
fontSubset: fontSubset,
rectangle: rectangle,
textColor: textColor,
grayFill: grayFill,
fontCountIndex: fontCountIndex,
fontSize: fontSize,
fontStyle: fontStyle,
setXCount: setXCount,
x: x,
y: y,
pageheight: pageheight,
contentType: ContentTypeCell,
cellOpt: cellOpt,
lineWidth: lineWidth,
}
}
//WriteTextToContent write text to content
func (c *CacheContent) WriteTextToContent(text string) {
c.cacheContentText.text += text
}
================================================
FILE: vendor/github.com/signintech/gopdf/cache_contnent_curve.go
================================================
package gopdf
import (
"fmt"
"io"
)
type cacheContentCurve struct {
pageHeight float64
x0 float64
y0 float64
x1 float64
y1 float64
x2 float64
y2 float64
x3 float64
y3 float64
style string
}
func (c *cacheContentCurve) write(w io.Writer, protection *PDFProtection) error {
h := c.pageHeight
x0 := c.x0
y0 := c.y0
x1 := c.x1
y1 := c.y1
x2 := c.x2
y2 := c.y2
x3 := c.x3
y3 := c.y3
style := c.style
//cp := 0.55228
fmt.Fprintf(w, "%0.2f %0.2f m\n", x0, h-y0)
fmt.Fprintf(w,
"%0.2f %0.2f %0.2f %0.2f %0.2f %0.2f c",
x1, h-y1, x2, h-y2, x3, h-y3,
)
op := "S"
if style == "F" {
op = "f"
} else if style == "FD" || style == "DF" {
op = "B"
}
fmt.Fprintf(w, " %s\n", op)
return nil
}
================================================
FILE: vendor/github.com/signintech/gopdf/catalog_obj.go
================================================
package gopdf
import (
"fmt"
"io"
)
//CatalogObj : catalog dictionary
type CatalogObj struct { //impl IObj
outlinesObjID int
}
func (c *CatalogObj) init(funcGetRoot func() *GoPdf) {
c.outlinesObjID = -1
}
func (c *CatalogObj) getType() string {
return "Catalog"
}
func (c *CatalogObj) write(w io.Writer, objID int) error {
io.WriteString(w, "<<\n")
fmt.Fprintf(w, " /Type /%s\n", c.getType())
io.WriteString(w, " /Pages 2 0 R\n")
if c.outlinesObjID >= 0 {
io.WriteString(w, " /PageMode /UseOutlines\n")
fmt.Fprintf(w, " /Outlines %d 0 R\n", c.outlinesObjID)
}
io.WriteString(w, ">>\n")
return nil
}
func (c *CatalogObj) SetIndexObjOutlines(index int) {
c.outlinesObjID = index + 1
}
================================================
FILE: vendor/github.com/signintech/gopdf/cell_option.go
================================================
package gopdf
//Left left
const Left = 8 //001000
//Top top
const Top = 4 //000100
//Right right
const Right = 2 //000010
//Bottom bottom
const Bottom = 1 //000001
//Center center
const Center = 16 //010000
//Middle middle
const Middle = 32 //100000
//AllBorders allborders
const AllBorders = 15 //001111
//CellOption cell option
type CellOption struct {
Align int //Allows to align the text. Possible values are: Left,Center,Right,Top,Bottom,Middle
Border int //Indicates if borders must be drawn around the cell. Possible values are: Left, Top, Right, Bottom, ALL
Float int //Indicates where the current position should go after the call. Possible values are: Right, Bottom
Transparency *Transparency
extGStateIndexes []int
}
================================================
FILE: vendor/github.com/signintech/gopdf/cid_font_obj.go
================================================
package gopdf
import (
"fmt"
"io"
)
// CIDFontObj is a CID-keyed font.
// cf. https://www.adobe.com/content/dam/acom/en/devnet/font/pdfs/5014.CIDFont_Spec.pdf
type CIDFontObj struct {
PtrToSubsetFontObj *SubsetFontObj
indexObjSubfontDescriptor int
}
func (ci *CIDFontObj) init(funcGetRoot func() *GoPdf) {
}
//SetIndexObjSubfontDescriptor set indexObjSubfontDescriptor
func (ci *CIDFontObj) SetIndexObjSubfontDescriptor(index int) {
ci.indexObjSubfontDescriptor = index
}
func (ci *CIDFontObj) getType() string {
return "CIDFont"
}
func (ci *CIDFontObj) write(w io.Writer, objID int) error {
io.WriteString(w, "<<\n")
fmt.Fprintf(w, "/BaseFont /%s\n", CreateEmbeddedFontSubsetName(ci.PtrToSubsetFontObj.GetFamily()))
io.WriteString(w, "/CIDSystemInfo\n")
io.WriteString(w, "<<\n")
io.WriteString(w, " /Ordering (Identity)\n")
io.WriteString(w, " /Registry (Adobe)\n")
io.WriteString(w, " /Supplement 0\n")
io.WriteString(w, ">>\n")
fmt.Fprintf(w, "/FontDescriptor %d 0 R\n", ci.indexObjSubfontDescriptor+1) //TODO fix
io.WriteString(w, "/Subtype /CIDFontType2\n")
io.WriteString(w, "/Type /Font\n")
glyphIndexs := ci.PtrToSubsetFontObj.CharacterToGlyphIndex.AllVals()
io.WriteString(w, "/W [")
for _, v := range glyphIndexs {
width := ci.PtrToSubsetFontObj.GlyphIndexToPdfWidth(v)
fmt.Fprintf(w, "%d[%d]", v, width)
}
io.WriteString(w, "]\n")
io.WriteString(w, ">>\n")
return nil
}
//SetPtrToSubsetFontObj set PtrToSubsetFontObj
func (ci *CIDFontObj) SetPtrToSubsetFontObj(ptr *SubsetFontObj) {
ci.PtrToSubsetFontObj = ptr
}
================================================
FILE: vendor/github.com/signintech/gopdf/config.go
================================================
package gopdf
// The units that can be used in the document
const (
UnitUnset = iota // No units were set, when conversion is called on nothing will happen
UnitPT // Points
UnitMM // Millimeters
UnitCM // centimeters
UnitIN // inches
// The math needed to convert units to points
conversionUnitPT = 1.0
conversionUnitMM = 72.0 / 25.4
conversionUnitCM = 72.0 / 2.54
conversionUnitIN = 72.0
)
// The units that can be used in the document (for backward compatibility)
// Deprecated: Use UnitUnset,UnitPT,UnitMM,UnitCM,UnitIN instead
const (
Unit_Unset = UnitUnset // No units were set, when conversion is called on nothing will happen
Unit_PT = UnitPT // Points
Unit_MM = UnitMM // Millimeters
Unit_CM = UnitCM // centimeters
Unit_IN = UnitIN // inches
)
//Config static config
type Config struct {
Unit int // The unit type to use when composing the document.
TrimBox Box // The default trim box for all pages in the document
PageSize Rect // The default page size for all pages in the document
K float64 // Not sure
Protection PDFProtectionConfig // Protection settings
}
//PDFProtectionConfig config of pdf protection
type PDFProtectionConfig struct {
UseProtection bool
Permissions int
UserPass []byte
OwnerPass []byte
}
// UnitsToPoints converts units of the provided type to points
func UnitsToPoints(t int, u float64) float64 {
switch t {
case UnitPT:
return u * conversionUnitPT
case UnitMM:
return u * conversionUnitMM
case UnitCM:
return u * conversionUnitCM
case UnitIN:
return u * conversionUnitIN
default:
return u
}
}
// PointsToUnits converts points to the provided units
func PointsToUnits(t int, u float64) float64 {
switch t {
case UnitPT:
return u / conversionUnitPT
case UnitMM:
return u / conversionUnitMM
case UnitCM:
return u / conversionUnitCM
case UnitIN:
return u / conversionUnitIN
default:
return u
}
}
// UnitsToPointsVar converts units of the provided type to points for all variables supplied
func UnitsToPointsVar(t int, u ...*float64) {
for x := 0; x < len(u); x++ {
*u[x] = UnitsToPoints(t, *u[x])
}
}
// PointsToUnitsVar converts points to the provided units for all variables supplied
func PointsToUnitsVar(t int, u ...*float64) {
for x := 0; x < len(u); x++ {
*u[x] = PointsToUnits(t, *u[x])
}
}
================================================
FILE: vendor/github.com/signintech/gopdf/content_obj.go
================================================
package gopdf
import (
"compress/zlib"
"fmt"
"io"
"strings"
)
//ContentObj content object
type ContentObj struct { //impl IObj
listCache listCacheContent
//text bytes.Buffer
getRoot func() *GoPdf
}
func (c *ContentObj) protection() *PDFProtection {
return c.getRoot().protection()
}
func (c *ContentObj) init(funcGetRoot func() *GoPdf) {
c.getRoot = funcGetRoot
}
func (c *ContentObj) write(w io.Writer, objID int) error {
buff := GetBuffer()
defer PutBuffer(buff)
isFlate := (c.getRoot().compressLevel != zlib.NoCompression)
if isFlate {
ww, err := zlib.NewWriterLevel(buff, c.getRoot().compressLevel)
if err != nil {
// should never happen...
return err
}
if err := c.listCache.write(ww, c.protection()); err != nil {
return err
}
if err := ww.Close(); err != nil {
return err
}
} else {
if err := c.listCache.write(buff, c.protection()); err != nil {
return err
}
}
if _, err := io.WriteString(w, "<<\n"); err != nil {
return err
}
if isFlate {
if _, err := io.WriteString(w, "/Filter/FlateDecode"); err != nil {
return err
}
}
if _, err := fmt.Fprintf(w, "/Length %d\n", buff.Len()); err != nil {
return err
}
if _, err := io.WriteString(w, ">>\n"); err != nil {
return err
}
if _, err := io.WriteString(w, "stream\n"); err != nil {
return err
}
if c.protection() != nil {
tmp, err := rc4Cip(c.protection().objectkey(objID), buff.Bytes())
if err != nil {
return err
}
if _, err := w.Write(tmp); err != nil {
return err
}
if _, err := io.WriteString(w, "\n"); err != nil {
return err
}
} else {
if _, err := buff.WriteTo(w); err != nil {
return err
}
if isFlate {
if _, err := io.WriteString(w, "\n"); err != nil {
return err
}
}
}
if _, err := io.WriteString(w, "endstream\n"); err != nil {
return err
}
return nil
}
func (c *ContentObj) getType() string {
return "Content"
}
//AppendStreamText append text
func (c *ContentObj) AppendStreamText(text string) error {
//support only CURRENT_FONT_TYPE_SUBSET
textColor := c.getRoot().curr.textColor()
grayFill := c.getRoot().curr.grayFill
fontCountIndex := c.getRoot().curr.FontFontCount + 1
fontSize := c.getRoot().curr.FontSize
fontStyle := c.getRoot().curr.FontStyle
x := c.getRoot().curr.X
y := c.getRoot().curr.Y
setXCount := c.getRoot().curr.setXCount
fontSubset := c.getRoot().curr.FontISubset
cellOption := CellOption{Transparency: c.getRoot().curr.transparency}
cache := cacheContentText{
fontSubset: fontSubset,
rectangle: nil,
textColor: textColor,
grayFill: grayFill,
fontCountIndex: fontCountIndex,
fontSize: fontSize,
fontStyle: fontStyle,
setXCount: setXCount,
x: x,
y: y,
cellOpt: cellOption,
pageheight: c.getRoot().curr.pageSize.H,
contentType: ContentTypeText,
lineWidth: c.getRoot().curr.lineWidth,
txtColorMode: c.getRoot().curr.txtColorMode,
}
var err error
c.getRoot().curr.X, c.getRoot().curr.Y, err = c.listCache.appendContentText(cache, text)
if err != nil {
return err
}
return nil
}
//AppendStreamSubsetFont add stream of text
func (c *ContentObj) AppendStreamSubsetFont(rectangle *Rect, text string, cellOpt CellOption) error {
textColor := c.getRoot().curr.textColor()
grayFill := c.getRoot().curr.grayFill
fontCountIndex := c.getRoot().curr.FontFontCount + 1
fontSize := c.getRoot().curr.FontSize
fontStyle := c.getRoot().curr.FontStyle
x := c.getRoot().curr.X
y := c.getRoot().curr.Y
setXCount := c.getRoot().curr.setXCount
fontSubset := c.getRoot().curr.FontISubset
cache := cacheContentText{
fontSubset: fontSubset,
rectangle: rectangle,
textColor: textColor,
grayFill: grayFill,
fontCountIndex: fontCountIndex,
fontSize: fontSize,
fontStyle: fontStyle,
setXCount: setXCount,
x: x,
y: y,
pageheight: c.getRoot().curr.pageSize.H,
contentType: ContentTypeCell,
cellOpt: cellOpt,
lineWidth: c.getRoot().curr.lineWidth,
txtColorMode: c.getRoot().curr.txtColorMode,
}
var err error
c.getRoot().curr.X, c.getRoot().curr.Y, err = c.listCache.appendContentText(cache, text)
if err != nil {
return err
}
return nil
}
//AppendStreamLine append line
func (c *ContentObj) AppendStreamLine(x1 float64, y1 float64, x2 float64, y2 float64) {
//h := c.getRoot().config.PageSize.H
//c.stream.WriteString(fmt.Sprintf("%0.2f %0.2f m %0.2f %0.2f l s\n", x1, h-y1, x2, h-y2))
var cache cacheContentLine
cache.pageHeight = c.getRoot().curr.pageSize.H
cache.x1 = x1
cache.y1 = y1
cache.x2 = x2
cache.y2 = y2
c.listCache.append(&cache)
}
//AppendStreamImportedTemplate append imported template
func (c *ContentObj) AppendStreamImportedTemplate(tplName string, scaleX float64, scaleY float64, tX float64, tY float64) {
var cache cacheContentImportedTemplate
cache.pageHeight = c.getRoot().curr.pageSize.H
cache.tplName = tplName
cache.scaleX = scaleX
cache.scaleY = scaleY
cache.tX = tX
cache.tY = tY
c.listCache.append(&cache)
}
func (c *ContentObj) AppendStreamRectangle(opts DrawableRectOptions) {
cache := NewCacheContentRectangle(c.getRoot().curr.pageSize.H, opts)
c.listCache.append(cache)
}
//AppendStreamOval append oval
func (c *ContentObj) AppendStreamOval(x1 float64, y1 float64, x2 float64, y2 float64) {
var cache cacheContentOval
cache.pageHeight = c.getRoot().curr.pageSize.H
cache.x1 = x1
cache.y1 = y1
cache.x2 = x2
cache.y2 = y2
c.listCache.append(&cache)
}
//AppendStreamCurve draw curve
// - x0, y0: Start point
// - x1, y1: Control point 1
// - x2, y2: Control point 2
// - x3, y3: End point
// - style: Style of rectangule (draw and/or fill: D, F, DF, FD)
// D or empty string: draw. This is the default value.
// F: fill
// DF or FD: draw and fill
func (c *ContentObj) AppendStreamCurve(x0 float64, y0 float64, x1 float64, y1 float64, x2 float64, y2 float64, x3 float64, y3 float64, style string) {
var cache cacheContentCurve
cache.pageHeight = c.getRoot().curr.pageSize.H
cache.x0 = x0
cache.y0 = y0
cache.x1 = x1
cache.y1 = y1
cache.x2 = x2
cache.y2 = y2
cache.x3 = x3
cache.y3 = y3
cache.style = strings.ToUpper(strings.TrimSpace(style))
c.listCache.append(&cache)
}
//AppendStreamSetLineWidth : set line width
func (c *ContentObj) AppendStreamSetLineWidth(w float64) {
var cache cacheContentLineWidth
cache.width = w
c.listCache.append(&cache)
}
//AppendStreamSetLineType : Set linetype [solid, dashed, dotted]
func (c *ContentObj) AppendStreamSetLineType(t string) {
var cache cacheContentLineType
cache.lineType = t
c.listCache.append(&cache)
}
//AppendStreamSetGrayFill set the grayscale fills
func (c *ContentObj) AppendStreamSetGrayFill(w float64) {
w = fixRange10(w)
var cache cacheContentGray
cache.grayType = grayTypeFill
cache.scale = w
c.listCache.append(&cache)
}
//AppendStreamSetGrayStroke set the grayscale stroke
func (c *ContentObj) AppendStreamSetGrayStroke(w float64) {
w = fixRange10(w)
var cache cacheContentGray
cache.grayType = grayTypeStroke
cache.scale = w
c.listCache.append(&cache)
}
//AppendStreamSetColorStroke set the color stroke
func (c *ContentObj) AppendStreamSetColorStroke(r uint8, g uint8, b uint8) {
var cache cacheContentColor
cache.colorType = colorTypeStroke
cache.r = r
cache.g = g
cache.b = b
c.listCache.append(&cache)
}
//AppendStreamSetColorFill set the color fill
func (c *ContentObj) AppendStreamSetColorFill(r uint8, g uint8, b uint8) {
var cache cacheContentColor
cache.colorType = colorTypeFill
cache.r = r
cache.g = g
cache.b = b
c.listCache.append(&cache)
}
func (c *ContentObj) GetCacheContentImage(index int, opts ImageOptions) *cacheContentImage {
h := c.getRoot().curr.pageSize.H
return &cacheContentImage{
pageHeight: h,
index: index,
x: opts.X,
y: opts.Y,
rect: *opts.Rect,
crop: opts.Crop,
verticalFlip: opts.VerticalFlip,
horizontalFlip: opts.HorizontalFlip,
extGStateIndexes: opts.extGStateIndexes,
}
}
//AppendStreamImage append image
func (c *ContentObj) AppendStreamImage(index int, opts ImageOptions) {
cache := c.GetCacheContentImage(index, opts)
c.listCache.append(cache)
}
//AppendStreamPolygon append polygon
func (c *ContentObj) AppendStreamPolygon(points []Point, style string) {
var cache cacheContentPolygon
cache.points = points
cache.style = style
cache.pageHeight = c.getRoot().curr.pageSize.H
c.listCache.append(&cache)
}
func (c *ContentObj) appendRotate(angle, x, y float64) {
var cache cacheContentRotate
cache.isReset = false
cache.pageHeight = c.getRoot().curr.pageSize.H
cache.angle = angle
cache.x = x
cache.y = y
c.listCache.append(&cache)
}
func (c *ContentObj) appendRotateReset() {
var cache cacheContentRotate
cache.isReset = true
c.listCache.append(&cache)
}
//ContentObjCalTextHeight calculates height of text.
func ContentObjCalTextHeight(fontsize int) float64 {
return (float64(fontsize) * 0.7)
}
// When setting colour and grayscales the value has to be between 0.00 and 1.00
// This function takes a float64 and returns 0.0 if it is less than 0.0 and 1.0 if it
// is more than 1.0
func fixRange10(val float64) float64 {
if val < 0.0 {
return 0.0
}
if val > 1.0 {
return 1.0
}
return val
}
func convertTTFUnit2PDFUnit(n int, upem int) int {
var ret int
if n < 0 {
rest1 := n % upem
storrest := 1000 * rest1
//ledd2 := (storrest != 0 ? rest1 / storrest : 0);
ledd2 := 0
if storrest != 0 {
ledd2 = rest1 / storrest
} else {
ledd2 = 0
}
ret = -((-1000*n)/upem - int(ledd2))
} else {
ret = (n/upem)*1000 + ((n%upem)*1000)/upem
}
return ret
}
================================================
FILE: vendor/github.com/signintech/gopdf/current.go
================================================
package gopdf
//Current current state
type Current struct {
setXCount int //many times we go func SetX()
X float64
Y float64
//font
IndexOfFontObj int
CountOfFont int
CountOfL int
FontSize int
FontStyle int // Regular|Bold|Italic|Underline
FontFontCount int
FontType int // CURRENT_FONT_TYPE_IFONT or CURRENT_FONT_TYPE_SUBSET
FontISubset *SubsetFontObj // FontType == CURRENT_FONT_TYPE_SUBSET
//page
IndexOfPageObj int
//img
CountOfImg int
//cache of image in pdf file
ImgCaches map[int]ImageCache
//text color mode
txtColorMode string //color, gray
//text color
txtColor Rgb
//text grayscale
grayFill float64
//draw grayscale
grayStroke float64
lineWidth float64
//current page size
pageSize *Rect
//current trim box
trimBox *Box
sMasksMap SMaskMap
extGStatesMap ExtGStatesMap
transparency *Transparency
transparencyMap TransparencyMap
}
func (c *Current) setTextColor(rgb Rgb) {
c.txtColor = rgb
}
func (c *Current) textColor() Rgb {
return c.txtColor
}
// ImageCache is metadata for caching images.
type ImageCache struct {
Path string //ID or Path
Index int
Rect *Rect
}
//Rgb rgb color
type Rgb struct {
r uint8
g uint8
b uint8
}
//SetR set red
func (rgb *Rgb) SetR(r uint8) {
rgb.r = r
}
//SetG set green
func (rgb *Rgb) SetG(g uint8) {
rgb.g = g
}
//SetB set blue
func (rgb *Rgb) SetB(b uint8) {
rgb.b = b
}
func (rgb Rgb) equal(obj Rgb) bool {
if rgb.r == obj.r && rgb.g == obj.g && rgb.b == obj.b {
return true
}
return false
}
================================================
FILE: vendor/github.com/signintech/gopdf/device_rgb_obj.go
================================================
package gopdf
import (
"fmt"
"io"
)
//DeviceRGBObj DeviceRGB
type DeviceRGBObj struct {
data []byte
getRoot func() *GoPdf
}
func (d *DeviceRGBObj) init(funcGetRoot func() *GoPdf) {
d.getRoot = funcGetRoot
}
func (d *DeviceRGBObj) protection() *PDFProtection {
return d.getRoot().protection()
}
func (d *DeviceRGBObj) getType() string {
return "devicergb"
}
//สร้าง ข้อมูลใน pdf
func (d *DeviceRGBObj) write(w io.Writer, objID int) error {
io.WriteString(w, "<<\n")
fmt.Fprintf(w, "/Length %d\n", len(d.data))
io.WriteString(w, ">>\n")
io.WriteString(w, "stream\n")
if d.protection() != nil {
tmp, err := rc4Cip(d.protection().objectkey(objID), d.data)
if err != nil {
return err
}
w.Write(tmp)
io.WriteString(w, "\n")
} else {
w.Write(d.data)
}
io.WriteString(w, "endstream\n")
return nil
}
================================================
FILE: vendor/github.com/signintech/gopdf/embedfont_obj.go
================================================
package gopdf
import (
"fmt"
"io"
"io/ioutil"
)
// EmbedFontObj is an embedded font object.
type EmbedFontObj struct {
Data string
zfontpath string
font IFont
getRoot func() *GoPdf
}
func (e *EmbedFontObj) init(funcGetRoot func() *GoPdf) {
e.getRoot = funcGetRoot
}
func (e *EmbedFontObj) protection() *PDFProtection {
return e.getRoot().protection()
}
func (e *EmbedFontObj) write(w io.Writer, objID int) error {
b, err := ioutil.ReadFile(e.zfontpath)
if err != nil {
return err
}
fmt.Fprintf(w, "<</Length %d\n", len(b))
io.WriteString(w, "/Filter /FlateDecode\n")
fmt.Fprintf(w, "/Length1 %d\n", e.font.GetOriginalsize())
io.WriteString(w, ">>\n")
io.WriteString(w, "stream\n")
if e.protection() != nil {
tmp, err := rc4Cip(e.protection().objectkey(objID), b)
if err != nil {
return err
}
w.Write(tmp)
io.WriteString(w, "\n")
} else {
w.Write(b)
}
io.WriteString(w, "\nendstream\n")
return nil
}
func (e *EmbedFontObj) getType() string {
return "EmbedFont"
}
// SetFont sets the font of an embedded font object.
func (e *EmbedFontObj) SetFont(font IFont, zfontpath string) {
e.font = font
e.zfontpath = zfontpath
}
================================================
FILE: vendor/github.com/signintech/gopdf/encoding_obj.go
================================================
package gopdf
import (
"io"
)
// EncodingObj is a font object.
type EncodingObj struct {
font IFont
}
func (e *EncodingObj) init(funcGetRoot func() *GoPdf) {
}
func (e *EncodingObj) getType() string {
return "Encoding"
}
func (e *EncodingObj) write(w io.Writer, objID int) error {
io.WriteString(w, "<</Type /Encoding /BaseEncoding /WinAnsiEncoding /Differences [")
io.WriteString(w, e.font.GetDiff())
io.WriteString(w, "]>>\n")
return nil
}
// SetFont sets the font of an encoding object.
func (e *EncodingObj) SetFont(font IFont) {
e.font = font
}
// GetFont gets the font from an encoding object.
func (e *EncodingObj) GetFont() IFont {
return e.font
}
================================================
FILE: vendor/github.com/signintech/gopdf/encryption_obj.go
================================================
package gopdf
import (
"fmt"
"io"
"strings"
)
//EncryptionObj encryption object res
type EncryptionObj struct {
uValue []byte //U entry in pdf document
oValue []byte //O entry in pdf document
pValue int //P entry in pdf document
}
func (e *EncryptionObj) init(func() *GoPdf) {
}
func (e *EncryptionObj) getType() string {
return "Encryption"
}
func (e *EncryptionObj) write(w io.Writer, objID int) error {
io.WriteString(w, "<<\n")
io.WriteString(w, "/Filter /Standard\n")
io.WriteString(w, "/V 1\n")
io.WriteString(w, "/R 2\n")
fmt.Fprintf(w, "/O (%s)\n", e.escape(e.oValue))
fmt.Fprintf(w, "/U (%s)\n", e.escape(e.uValue))
fmt.Fprintf(w, "/P %d\n", e.pValue)
io.WriteString(w, ">>\n")
return nil
}
func (e *EncryptionObj) escape(b []byte) string {
s := string(b)
s = strings.Replace(s, "\\", "\\\\", -1)
s = strings.Replace(s, "(", "\\(", -1)
s = strings.Replace(s, ")", "\\)", -1)
s = strings.Replace(s, "\r", "\\r", -1)
return s
}
================================================
FILE: vendor/github.com/signintech/gopdf/ext_g_state_obj.go
================================================
package gopdf
import (
"fmt"
"io"
"sync"
"github.com/pkg/errors"
)
// TODO: add all fields https://www.adobe.com/content/dam/acom/en/devnet/acrobat/pdfs/PDF32000_2008.pdf 8.4.5 page 128
type ExtGState struct {
Index int
ca *float64
CA *float64
BM *BlendModeType
SMaskIndex *int
}
type ExtGStateOptions struct {
StrokingCA *float64
NonStrokingCa *float64
BlendMode *BlendModeType
SMaskIndex *int
}
func (extOpt ExtGStateOptions) GetId() string {
id := ""
if extOpt.StrokingCA != nil {
id += fmt.Sprintf("CA_%.3f;", *extOpt.StrokingCA)
}
if extOpt.NonStrokingCa != nil {
id += fmt.Sprintf("ca_%.3f;", *extOpt.NonStrokingCa)
}
if extOpt.BlendMode != nil {
id += fmt.Sprintf("BM_%s;", *extOpt.BlendMode)
}
if extOpt.SMaskIndex != nil {
id += fmt.Sprintf("SMask_%d_0_R;", *extOpt.SMaskIndex)
}
return id
}
func GetCachedExtGState(opts ExtGStateOptions, gp *GoPdf) (ExtGState, error) {
extGState, ok := gp.curr.extGStatesMap.Find(opts)
if !ok {
extGState = ExtGState{
BM: opts.BlendMode,
CA: opts.StrokingCA,
ca: opts.NonStrokingCa,
SMaskIndex: opts.SMaskIndex,
}
extGState.Index = gp.addObj(extGState)
pdfObj := gp.pdfObjs[gp.indexOfProcSet]
procset, ok := pdfObj.(*ProcSetObj)
if !ok {
return ExtGState{}, errors.New("can't convert pdfobject to procsetobj")
}
procset.ExtGStates = append(procset.ExtGStates, ExtGS{Index: extGState.Index})
gp.curr.extGStatesMap.Save(opts.GetId(), extGState)
//extGState = extGState
}
return extGState, nil
}
func (egs ExtGState) init(func() *GoPdf) {}
func (egs ExtGState) getType() string {
return "ExtGState"
}
func (egs ExtGState) write(w io.Writer, objID int) error {
content := "<<\n"
content += "\t/Type /ExtGState\n"
if egs.ca != nil {
content += fmt.Sprintf("\t/ca %.3F\n", *egs.ca)
}
if egs.CA != nil {
content += fmt.Sprintf("\t/CA %.3F\n", *egs.CA)
}
if egs.BM != nil {
content += fmt.Sprintf("\t/BM %s\n", *egs.BM)
}
if egs.SMaskIndex != nil {
content += fmt.Sprintf("\t/SMask %d 0 R\n", *egs.SMaskIndex+1)
}
content += ">>\n"
if _, err := io.WriteString(w, content); err != nil {
return err
}
return nil
}
type ExtGStatesMap struct {
syncer sync.Mutex
table map[string]ExtGState
}
func NewExtGStatesMap() ExtGStatesMap {
return ExtGStatesMap{
syncer: sync.Mutex{},
table: make(map[string]ExtGState),
}
}
func (extm *ExtGStatesMap) Find(extGState ExtGStateOptions) (ExtGState, bool) {
key := extGState.GetId()
extm.syncer.Lock()
defer extm.syncer.Unlock()
t, ok := extm.table[key]
if !ok {
return ExtGState{}, false
}
return t, ok
}
func (tm *ExtGStatesMap) Save(id string, extGState ExtGState) ExtGState {
tm.syncer.Lock()
defer tm.syncer.Unlock()
tm.table[id] = extGState
return extGState
}
================================================
FILE: vendor/github.com/signintech/gopdf/font_obj.go
================================================
package gopdf
import (
"fmt"
"io"
)
//FontObj font obj
type FontObj struct {
Family string
//Style string
//Size int
IsEmbedFont bool
indexObjWidth int
indexObjFontDescriptor int
indexObjEncoding int
Font IFont
CountOfFont int
}
func (f *FontObj) init(funcGetRoot func() *GoPdf) {
f.IsEmbedFont = false
//me.CountOfFont = -1
}
func (f *FontObj) write(w io.Writer, objID int) error {
baseFont := f.Family
if f.Font != nil {
baseFont = f.Font.GetName()
}
io.WriteString(w, "<<\n")
fmt.Fprintf(w, " /Type /%s\n", f.getType())
io.WriteString(w, " /Subtype /TrueType\n")
fmt.Fprintf(w, " /BaseFont /%s\n", baseFont)
if f.IsEmbedFont {
io.WriteString(w, " /FirstChar 32 /LastChar 255\n")
fmt.Fprintf(w, " /Widths %d 0 R\n", f.indexObjWidth)
fmt.Fprintf(w, " /FontDescriptor %d 0 R\n", f.indexObjFontDescriptor)
fmt.Fprintf(w, " /Encoding %d 0 R\n", f.indexObjEncoding)
}
io.WriteString(w, ">>\n")
return nil
}
func (f *FontObj) getType() string {
return "Font"
}
// SetIndexObjWidth sets the width of a font object.
func (f *FontObj) SetIndexObjWidth(index int) {
f.indexObjWidth = index
}
// SetIndexObjFontDescriptor sets the font descriptor.
func (f *FontObj) SetIndexObjFontDescriptor(index int) {
f.indexObjFontDescriptor = index
}
// SetIndexObjEncoding sets the encoding.
func (f *FontObj) SetIndexObjEncoding(index int) {
f.indexObjEncoding = index
}
================================================
FILE: vendor/github.com/signintech/gopdf/font_option.go
================================================
package gopdf
import (
"strings"
)
//Regular - font style regular
const Regular = 0 //000000
//Italic - font style italic
const Italic = 1 //000001
//Bold - font style bold
const Bold = 2 //000010
//Underline - font style underline
const Underline = 4 //000100
func getConvertedStyle(fontStyle string) (style int) {
fontStyle = strings.ToUpper(fontStyle)
if strings.Contains(fontStyle, "B") {
style = style | Bold
}
if strings.Contains(fontStyle, "I") {
style = style | Italic
}
if strings.Contains(fontStyle, "U") {
style = style | Underline
}
return
}
================================================
FILE: vendor/github.com/signintech/gopdf/fontconverthelper.go
================================================
package gopdf
import (
"strconv"
//"fmt"
"bytes"
)
// FontConvertHelperCw2Str converts main ASCII characters of a FontCW to a string.
func FontConvertHelperCw2Str(cw FontCw) string {
buff := new(bytes.Buffer)
buff.WriteString(" ")
i := 32
for i <= 255 {
buff.WriteString(strconv.Itoa(cw[byte(i)]) + " ")
i++
}
return buff.String()
}
// FontConvertHelper_Cw2Str converts main ASCII characters of a FontCW to a string. (for backward compatibility)
// Deprecated: Use FontConvertHelperCw2Str(cw FontCw) instead
func FontConvertHelper_Cw2Str(cw FontCw) string {
return FontConvertHelperCw2Str(cw)
}
================================================
FILE: vendor/github.com/signintech/gopdf/fontdescriptor_obj.go
================================================
package gopdf
import (
"fmt"
"io"
)
// FontDescriptorObj is a font descriptor object.
type FontDescriptorObj struct {
font IFont
fontFileObjRelate string
}
func (f *FontDescriptorObj) init(funcGetRoot func() *GoPdf) {
}
func (f *FontDescriptorObj) write(w io.Writer, objID int) error {
fmt.Fprintf(w, "<</Type /FontDescriptor /FontName /%s ", f.font.GetName())
descs := f.font.GetDesc()
i := 0
max := len(descs)
for i < max {
fmt.Fprintf(w, "/%s %s ", descs[i].Key, descs[i].Val)
i++
}
if f.getType() == "Type1" {
io.WriteString(w, "/FontFile ")
} else {
io.WriteString(w, "/FontFile2 ")
}
io.WriteString(w, f.fontFileObjRelate)
io.WriteString(w, ">>\n")
return nil
}
func (f *FontDescriptorObj) getType() string {
return "FontDescriptor"
}
// SetFont sets the font in descriptor.
func (f *FontDescriptorObj) SetFont(font IFont) {
f.font = font
}
// GetFont gets font from descriptor.
func (f *FontDescriptorObj) GetFont() IFont {
return f.font
}
// SetFontFileObjRelate ???
func (f *FontDescriptorObj) SetFontFileObjRelate(relate string) {
f.fontFileObjRelate = relate
}
================================================
FILE: vendor/github.com/signintech/gopdf/fontmaker/core/fontmaker.go
================================================
package core
import (
"bufio"
"bytes"
"compress/zlib"
"errors"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strconv"
"strings"
)
//ErrFontLicenseDoesNotAllowEmbedding Font license does not allow embedding
var ErrFontLicenseDoesNotAllowEmbedding = errors.New("Font license does not allow embedding")
//FontMaker font maker
type FontMaker struct {
results []string
}
//GetResults get result
func (f *FontMaker) GetResults() []string {
return f.results
}
//NewFontMaker new FontMaker
func NewFontMaker() *FontMaker {
return new(FontMaker)
}
func (f *FontMaker) MakeFont(fontpath string, mappath string, encode string, outfolderpath string) error {
encodingpath := mappath + "/" + encode + ".map"
//read font file
if _, err := os.Stat(fontpath); os.IsNotExist(err) {
return err
}
fileext := filepath.Ext(fontpath)
if strings.ToLower(fileext) != ".ttf" {
//now support only ttf :-P
return errors.New("support only ttf ")
}
fontmaps, err := f.LoadMap(encodingpath)
if err != nil {
return err
}
info, err := f.GetInfoFromTrueType(fontpath, fontmaps)
if err != nil {
return err
}
//zip
basename := filepath.Base(fontpath)
tmp := strings.Split(basename, ".")
basename = strings.Replace(tmp[0], " ", "_", -1)
gzfilename := basename + ".z"
var buff bytes.Buffer
gzipwriter := zlib.NewWriter(&buff)
fontbytes, err := ioutil.ReadFile(fontpath)
if err != nil {
return err
}
_, err = gzipwriter.Write(fontbytes)
if err != nil {
return err
}
gzipwriter.Close()
err = ioutil.WriteFile(outfolderpath+"/"+gzfilename, buff.Bytes(), 0644)
if err != nil {
return err
}
info.PushString("File", gzfilename)
f.results = append(f.results, fmt.Sprintf("Save Z file at %s.", outfolderpath+"/"+gzfilename))
//Definition File
_, err = f.MakeDefinitionFile(f.GoStructName(basename), mappath, outfolderpath+"/"+basename+".font.go", encode, fontmaps, info)
if err != nil {
return err
}
return nil
}
func (f *FontMaker) GoStructName(name string) string {
goname := strings.ToUpper(name[0:1]) + name[1:]
return goname
}
func (f *FontMaker) MakeDefinitionFile(gofontname string, mappath string, exportfile string, encode string, fontmaps []FontMap, info TtfInfo) (string, error) {
fonttype := "TrueType"
str := ""
str += "package fonts //change this\n"
str += "import (\n"
str += " \"github.com/signintech/gopdf\"\n"
str += ")\n"
str += "type " + gofontname + " struct {\n"
str += "\tfamily string\n"
str += "\tfonttype string\n"
str += "\tname string\n"
str += "\tdesc []gopdf.FontDescItem\n"
str += "\tup int\n"
str += "\tut int\n"
str += "\tcw gopdf.FontCw\n"
str += "\tenc string\n"
str += "\tdiff string\n"
str += "}\n"
str += "func (me * " + gofontname + ") Init(){\n"
widths, err := info.GetMapIntInt64("Widths")
if err != nil {
return "", err
}
tmpStr, err := f.MakeWidthArray(widths)
if err != nil {
return "", err
}
str += tmpStr
tmpInt64, err := info.GetInt64("UnderlinePosition")
if err != nil {
return "", err
}
str += fmt.Sprintf("\tme.up = %d\n", tmpInt64)
tmpInt64, err = info.GetInt64("UnderlineThickness")
if err != nil {
return "", err
}
str += fmt.Sprintf("\tme.ut = %d\n", tmpInt64)
str += "\tme.fonttype = \"" + fonttype + "\"\n"
tmpStr, err = info.GetString("FontName")
if err != nil {
return "", err
}
str += fmt.Sprintf("\tme.name = \"%s\"\n", tmpStr)
str += "\tme.enc = \"" + encode + "\"\n"
diff, err := f.MakeFontEncoding(mappath, fontmaps)
if err != nil {
return "", err
}
if diff != "" {
str += "\tme.diff = \"" + diff + "\"\n"
}
fd, err := f.MakeFontDescriptor(info)
if err != nil {
return "", err
}
str += fd
str += "}\n"
str += "func (me * " + gofontname + ")GetType() string{\n"
str += "\treturn me.fonttype\n"
str += "}\n"
str += "func (me * " + gofontname + ")GetName() string{\n"
str += "\treturn me.name\n"
str += "} \n"
str += "func (me * " + gofontname + ")GetDesc() []gopdf.FontDescItem{\n"
str += "\treturn me.desc\n"
str += "}\n"
str += "func (me * " + gofontname + ")GetUp() int{\n"
str += "\treturn me.up\n"
str += "}\n"
str += "func (me * " + gofontname + ")GetUt() int{\n"
str += "\treturn me.ut\n"
str += "}\n"
str += "func (me * " + gofontname + ")GetCw() gopdf.FontCw{\n"
str += "\treturn me.cw\n"
str += "}\n"
str += "func (me * " + gofontname + ")GetEnc() string{\n"
str += "\treturn me.enc\n"
str += "}\n"
str += "func (me * " + gofontname + ")GetDiff() string {\n"
str += "\treturn me.diff\n"
str += "}\n"
str += "func (me * " + gofontname + ") GetOriginalsize() int{\n"
str += "\treturn 98764\n"
str += "}\n"
str += "func (me * " + gofontname + ") SetFamily(family string){\n"
str += "\tme.family = family\n"
str += "}\n"
str += "func (me * " + gofontname + ") GetFamily() string{\n"
str += "\treturn me.family\n"
str += "}\n"
err = ioutil.WriteFile(exportfile, []byte(str), 0666)
if err != nil {
return "", err
}
f.results = append(f.results, fmt.Sprintf("Save GO file at %s.", exportfile))
return str, nil
}
func (f *FontMaker) MakeFontDescriptor(info TtfInfo) (string, error) {
fd := ""
fd = "\tme.desc = make([]gopdf.FontDescItem,8)\n"
// Ascent
ascender, err := info.GetInt64("Ascender")
if err != nil {
return "", err
}
fd += fmt.Sprintf("\tme.desc[0] = gopdf.FontDescItem{ Key:\"Ascent\",Val : \"%d\" }\n", ascender)
// Descent
descender, err := info.GetInt64("Descender")
if err != nil {
return "", err
}
fd += fmt.Sprintf("\tme.desc[1] = gopdf.FontDescItem{ Key: \"Descent\", Val : \"%d\" }\n", descender)
// CapHeight
capHeight, err := info.GetInt64("CapHeight")
if err == nil {
fd += fmt.Sprintf("\tme.desc[2] = gopdf.FontDescItem{ Key:\"CapHeight\", Val : \"%d\" }\n", capHeight)
} else if err == ERROR_NO_KEY_FOUND {
fd += fmt.Sprintf("\tme.desc[2] = gopdf.FontDescItem{ Key:\"CapHeight\", Val : \"%d\" }\n", ascender)
} else {
return "", err
}
// Flags
flags := 0
isFixedPitch, err := info.GetBool("IsFixedPitch")
if err != nil {
return "", err
}
if isFixedPitch {
flags += 1 << 0
}
flags += 1 << 5
italicAngle, err := info.GetInt64("ItalicAngle")
if italicAngle != 0 {
flags += 1 << 6
}
fd += fmt.Sprintf("\tme.desc[3] = gopdf.FontDescItem{ Key: \"Flags\", Val : \"%d\" }\n", flags)
//fmt.Printf("\n----\n")
// FontBBox
fbb, err := info.GetInt64s("FontBBox")
if err != nil {
return "", err
}
fd += fmt.Sprintf("\tme.desc[4] = gopdf.FontDescItem{ Key:\"FontBBox\", Val : \"[%d %d %d %d]\" }\n", fbb[0], fbb[1], fbb[2], fbb[3])
// ItalicAngle
fd += fmt.Sprintf("\tme.desc[5] = gopdf.FontDescItem{ Key:\"ItalicAngle\", Val : \"%d\" }\n", italicAngle)
// StemV
stdVW, err := info.GetInt64("StdVW")
issetStdVW := false
if err == nil {
issetStdVW = true
} else if err == ERROR_NO_KEY_FOUND {
issetStdVW = false
} else {
return "", err
}
bold, err := info.GetBool("Bold")
if err != nil {
return "", err
}
stemv := int(0)
if issetStdVW {
stemv = stdVW
} else if bold {
stemv = 120
} else {
stemv = 70
}
fd += fmt.Sprintf("\tme.desc[6] = gopdf.FontDescItem{ Key:\"StemV\", Val : \"%d\" }\n ", stemv)
// MissingWidth
missingWidth, err := info.GetInt64("MissingWidth")
if err != nil {
return "", err
}
fd += fmt.Sprintf("\tme.desc[7] = gopdf.FontDescItem{ Key:\"MissingWidth\", Val : \"%d\" } \n ", missingWidth)
return fd, nil
}
func (f *FontMaker) MakeFontEncoding(mappath string, fontmaps []FontMap) (string, error) {
refpath := mappath + "/cp1252.map"
ref, err := f.LoadMap(refpath)
if err != nil {
return "", err
}
s := ""
last := 0
for c := 0; c <= 255; c++ {
if fontmaps[c].Name != ref[c].Name {
if c != last+1 {
s += fmt.Sprintf("%d ", c)
}
last = c
s += "/" + fontmaps[c].Name + " "
}
}
return strings.TrimSpace(s), nil
}
func (f *FontMaker) MakeWidthArray(widths map[int]int) (string, error) {
str := "\tme.cw = make(gopdf.FontCw)\n"
for c := 0; c <= 255; c++ {
str += "\tme.cw["
chr := string(c)
if chr == "\"" {
str += "gopdf.ToByte(\"\\\"\")"
} else if chr == "\\" {
str += "gopdf.ToByte(\"\\\\\")"
} else if c >= 32 && c <= 126 {
str += "gopdf.ToByte(\"" + chr + "\")"
} else {
str += fmt.Sprintf("gopdf.Chr(%d)", c)
}
str += fmt.Sprintf("]=%d\n", widths[c])
}
return str, nil
}
func (f *FontMaker) FileSize(path string) (int64, error) {
file, err := os.Open(path)
if err != nil {
return -1, err
}
defer file.Close()
// get the file size
stat, err := file.Stat()
if err != nil {
return -1, err
}
return stat.Size(), nil
}
func (f *FontMaker) GetInfoFromTrueType(fontpath string, fontmaps []FontMap) (TtfInfo, error) {
var parser TTFParser
err := parser.Parse(fontpath)
if err != nil {
return nil, err
}
if !parser.Embeddable {
return nil, ErrFontLicenseDoesNotAllowEmbedding
}
info := NewTtfInfo()
fileContent, err := ioutil.ReadFile(fontpath)
if err != nil {
return nil, err
}
info.PushBytes("Data", fileContent)
size, err := f.FileSize(fontpath)
if err != nil {
return nil, err
}
info.PushInt64("OriginalSize", size)
k := float64(1000.0 / float64(parser.unitsPerEm))
info.PushString("FontName", parser.postScriptName)
info.PushBool("Bold", parser.Bold)
info.PushInt("ItalicAngle", parser.italicAngle)
info.PushBool("IsFixedPitch", parser.isFixedPitch)
info.PushInt("Ascender", f.MultiplyAndRound(k, parser.typoAscender))
info.PushInt("Descender", f.MultiplyAndRound(k, parser.typoDescender))
info.PushInt("UnderlineThickness", f.MultiplyAndRound(k, parser.underlineThickness))
info.PushInt("UnderlinePosition", f.MultiplyAndRound(k, parser.underlinePosition))
fontBBoxs := []int{
f.MultiplyAndRound(k, parser.xMin),
f.MultiplyAndRound(k, parser.yMin),
f.MultiplyAndRound(k, parser.xMax),
f.MultiplyAndRound(k, parser.yMax),
}
info.PushInt64s("FontBBox", fontBBoxs)
info.PushInt("CapHeight", f.MultiplyAndRound(k, parser.capHeight))
missingWidth := f.MultiplyAndRoundWithUInt64(k, parser.widths[0])
info.PushInt("MissingWidth", missingWidth)
widths := make(map[int]int)
max := 256
c := 0
for c < max {
widths[c] = missingWidth
c++
}
c = 0 //reset
for c < max {
if fontmaps[c].Name != ".notdef" {
uv := fontmaps[c].Uv
if val, ok := parser.chars[int(uv)]; ok {
w := parser.widths[val]
widths[c] = f.MultiplyAndRoundWithUInt64(k, w)
} else {
f.results = append(f.results, fmt.Sprintf("Warning: Character %s (%d) is missing", fontmaps[c].Name, fontmaps[c].Uv))
}
}
c++
}
info.PushMapIntInt64("Widths", widths)
return info, nil
}
func (f *FontMaker) MultiplyAndRoundWithUInt64(k float64, v uint) int {
r := k * float64(v)
return f.Round(r)
}
func (f *FontMaker) MultiplyAndRound(k float64, v int) int {
r := k * float64(v)
return f.Round(r)
}
func (f *FontMaker) Round(value float64) int {
return Round(value)
}
func (f *FontMaker) LoadMap(encodingpath string) ([]FontMap, error) {
if _, err := os.Stat(encodingpath); os.IsNotExist(err) {
return nil, err
}
var fontmaps []FontMap
i := 0
max := 256
for i < max {
fontmaps = append(fontmaps, FontMap{Uv: -1, Name: ".notdef"})
i++
}
file, err := os.Open(encodingpath)
if err != nil {
return nil, err
}
defer file.Close()
scanner := bufio.NewScanner(file)
scanner.Split(bufio.ScanLines)
for scanner.Scan() {
line := strings.TrimSpace(scanner.Text())
e := strings.Split(line, " ")
strC := (e[0])[1:]
strUv := (e[1])[2:]
c, err := strconv.ParseInt(strC, 16, 0)
if err != nil {
return nil, err
}
uv, err := strconv.ParseInt(strUv, 16, 0)
if err != nil {
return nil, err
}
name := e[2]
//fmt.Println("strC = "+strC+"strUv = "+strUv+" c=%d , uv= %d", c, uv)
fontmaps[c].Name = name
fontmaps[c].Uv = int(uv)
}
return fontmaps, nil
}
================================================
FILE: vendor/github.com/signintech/gopdf/fontmaker/core/fontmap.go
================================================
package core
type FontMap struct {
Uv int
Name string
}
================================================
FILE: vendor/github.com/signintech/gopdf/fontmaker/core/kern_table.go
================================================
package core
//KernTable https://www.microsoft.com/typography/otspec/kern.htm
type KernTable struct {
Version uint //for debug
NTables uint //for debug
Kerning KernMap
}
//KernMap kerning map map[left]KernValue
type KernMap map[uint]KernValue
//KernValue kerning values map[right]value
type KernValue map[uint]int16
//ValueByRight get value by right
func (k KernValue) ValueByRight(right uint) (bool, int16) {
if val, ok := k[uint(right)]; ok {
return true, val
}
return false, 0
}
================================================
FILE: vendor/github.com/signintech/gopdf/fontmaker/core/math.go
================================================
package core
func Round(value float64) int {
if value < 0.0 {
value -= 0.5
} else {
value += 0.5
}
return int(value)
}
================================================
FILE: vendor/github.com/signintech/gopdf/fontmaker/core/table_directory_entry.go
================================================
package core
type TableDirectoryEntry struct {
CheckSum uint
Offset uint
Length uint
}
func (t TableDirectoryEntry) PaddedLength() int {
l := int(t.Length)
return (l + 3) & ^3
}
================================================
FILE: vendor/github.com/signintech/gopdf/fontmaker/core/ttf_info.go
================================================
package core
import (
"errors"
)
var ERROR_NO_KEY_FOUND = errors.New("no key found")
var ERROR_NO_GET_WRONG_TYPE = errors.New("get wrong type")
type TtfInfo map[string]interface{}
func (t TtfInfo) PushString(key string, val string) {
t[key] = val
}
func (t TtfInfo) PushBytes(key string, val []byte) {
t[key] = val
}
func (t TtfInfo) PushInt64(key string, val int64) {
t[key] = val
}
func (t TtfInfo) PushInt(key string, val int) {
t[key] = val
}
func (t TtfInfo) PushUInt64(key string, val uint) {
t[key] = val
}
func (t TtfInfo) PushBool(key string, val bool) {
t[key] = val
}
func (t TtfInfo) PushInt64s(key string, val []int) {
t[key] = val
}
func (t TtfInfo) PushMapIntInt64(key string, val map[int]int) {
t[key] = val
}
func (t TtfInfo) GetBool(key string) (bool, error) {
if val, ok := t[key]; ok {
if m, ok := val.(bool); ok {
/* act on str */
return m, nil
} else {
return false, ERROR_NO_GET_WRONG_TYPE
}
} else {
return false, ERROR_NO_KEY_FOUND
}
}
func (t TtfInfo) GetString(key string) (string, error) {
if val, ok := t[key]; ok {
if m, ok := val.(string); ok {
/* act on str */
return m, nil
} else {
return "", ERROR_NO_GET_WRONG_TYPE
}
} else {
return "", ERROR_NO_KEY_FOUND
}
}
func (t TtfInfo) GetInt64(key string) (int, error) {
if val, ok := t[key]; ok {
if m, ok := val.(int); ok {
/* act on str */
return m, nil
} else {
return 0, ERROR_NO_GET_WRONG_TYPE
}
} else {
return 0, ERROR_NO_KEY_FOUND
}
}
func (t TtfInfo) GetInt64s(key string) ([]int, error) {
if val, ok := t[key]; ok {
if m, ok := val.([]int); ok {
/* act on str */
return m, nil
} else {
return nil, ERROR_NO_GET_WRONG_TYPE
}
} else {
return nil, ERROR_NO_KEY_FOUND
}
}
func (t TtfInfo) GetMapIntInt64(key string) (map[int]int, error) {
if val, ok := t[key]; ok {
if m, ok := val.(map[int]int); ok {
/* act on str */
return m, nil
} else {
return nil, ERROR_NO_GET_WRONG_TYPE
}
} else {
return nil, ERROR_NO_KEY_FOUND
}
}
func NewTtfInfo() TtfInfo {
info := make(TtfInfo)
return info
}
================================================
FILE: vendor/github.com/signintech/gopdf/fontmaker/core/ttfparser.go
================================================
package core
import (
//"encoding/binary"
//"encoding/hex"
"bytes"
"encoding/binary"
"errors"
"fmt"
"io"
"io/ioutil"
"os"
"regexp"
"strconv"
"strings"
)
var ERROR_NO_UNICODE_ENCODING_FOUND = errors.New("No Unicode encoding found")
var ERROR_UNEXPECTED_SUBTABLE_FORMAT = errors.New("Unexpected subtable format")
var ERROR_INCORRECT_MAGIC_NUMBER = errors.New("Incorrect magic number")
var ERROR_POSTSCRIPT_NAME_NOT_FOUND = errors.New("PostScript name not found")
//TTFParser true type font parser
type TTFParser struct {
tables map[string]TableDirectoryEntry
//head
unitsPerEm uint
xMin int
yMin int
xMax int
yMax int
indexToLocFormat int
//Hhea
numberOfHMetrics uint
ascender int
descender int
//end Hhea
numGlyphs uint
widths []uint
chars map[int]uint
postScriptName string
//os2
os2Version uint
Embeddable bool
Bold bool
typoAscender int
typoDescender int
capHeight int
sxHeight int
//post
italicAngle int
underlinePosition int
underlineThickness int
isFixedPitch bool
sTypoLineGap int
usWinAscent uint
usWinDescent uint
//cmap
IsShortIndex bool
LocaTable []uint
SegCount uint
StartCount []uint
EndCount []uint
IdRangeOffset []uint
IdDelta []uint
GlyphIdArray []uint
symbol bool
//cmap format 12
groupingTables []CmapFormat12GroupingTable
//data of font
cachedFontData []byte
//kerning
useKerning bool //user config for use or not use kerning
kern *KernTable
}
var Symbolic = 1 << 2
var Nonsymbolic = (1 << 5)
//Kern get KernTable
func (t *TTFParser) Kern() *KernTable {
return t.kern
}
//UnderlinePosition postion of underline
func (t *TTFParser) UnderlinePosition() int {
return t.underlinePosition
}
//GroupingTables get cmap format12 grouping table
func (t *TTFParser) GroupingTables() []CmapFormat12GroupingTable {
return t.groupingTables
}
//UnderlineThickness thickness of underline
func (t *TTFParser) UnderlineThickness() int {
return t.underlineThickness
}
func (t *TTFParser) XHeight() int {
if t.os2Version >= 2 && t.sxHeight != 0 {
return t.sxHeight
} else {
return int((0.66) * float64(t.ascender))
}
}
func (t *TTFParser) XMin() int {
return t.xMin
}
func (t *TTFParser) YMin() int {
return t.yMin
}
func (t *TTFParser) XMax() int {
return t.xMax
}
func (t *TTFParser) YMax() int {
return t.yMax
}
func (t *TTFParser) ItalicAngle() int {
return t.italicAngle
}
func (t *TTFParser) Flag() int {
flag := 0
if t.symbol {
flag |= Symbolic
} else {
flag |= Nonsymbolic
}
return flag
}
func (t *TTFParser) Ascender() int {
if t.typoAscender == 0 {
return t.ascender
}
return int(t.usWinAscent)
}
func (t *TTFParser) Descender() int {
if t.typoDescender == 0 {
return t.descender
}
descender := int(t.usWinDescent)
if t.descender < 0 {
descender = descender * (-1)
}
return descender
}
func (t *TTFParser) TypoAscender() int {
return t.typoAscender
}
func (t *TTFParser) TypoDescender() int {
return t.typoDescender
}
//CapHeight https://en.wikipedia.org/wiki/Cap_height
func (t *TTFParser) CapHeight() int {
return t.capHeight
}
//NumGlyphs number of glyph
func (t *TTFParser) NumGlyphs() uint {
return t.numGlyphs
}
func (t *TTFParser) UnitsPerEm() uint {
return t.unitsPerEm
}
func (t *TTFParser) NumberOfHMetrics() uint {
return t.numberOfHMetrics
}
func (t *TTFParser) Widths() []uint {
return t.widths
}
func (t *TTFParser) Chars() map[int]uint {
return t.chars
}
func (t *TTFParser) GetTables() map[string]TableDirectoryEntry {
return t.tables
}
//SetUseKerning set useKerning must set before Parse
func (t *TTFParser) SetUseKerning(use bool) {
t.useKerning = use
}
//Parse parse
func (t *TTFParser) Parse(filepath string) error {
data, err := ioutil.ReadFile(filepath)
if err != nil {
return err
}
return t.ParseFontData(data)
}
//ParseByReader parse by io.reader
func (t *TTFParser) ParseByReader(rd io.Reader) error {
fontData, err := ioutil.ReadAll(rd)
if err != nil {
return err
}
return t.ParseFontData(fontData)
}
// ParseFontData parses font data.
func (t *TTFParser) ParseFontData(fontData []byte) error {
fd := bytes.NewReader(fontData)
version, err := t.Read(fd, 4)
if err != nil {
return err
}
if !bytes.Equal(version, []byte{0x00, 0x01, 0x00, 0x00}) {
return errors.New("Unrecognized file (font) format")
}
i := uint(0)
numTables, err := t.ReadUShort(fd)
if err != nil {
return err
}
t.Skip(fd, 3*2) //searchRange, entrySelector, rangeShift
t.tables = make(map[string]TableDirectoryEntry)
for i < numTables {
tag, err := t.Read(fd, 4)
if err != nil {
return err
}
checksum, err := t.ReadULong(fd)
if err != nil {
return err
}
offset, err := t.ReadULong(fd)
if err != nil {
return err
}
length, err := t.ReadULong(fd)
if err != nil {
return err
}
//fmt.Printf("\n\ntag=%s \nOffset = %d\n", tag, offset)
var table TableDirectoryEntry
table.Offset = uint(offset)
table.CheckSum = checksum
table.Length = length
//fmt.Printf("\n\ntag=%s \nOffset = %d\nPaddedLength =%d\n\n ", tag, table.Offset, table.PaddedLength())
t.tables[t.BytesToString(tag)] = table
i++
}
err = t.ParseHead(fd)
if err != nil {
return err
}
err = t.ParseHhea(fd)
if err != nil {
return err
}
err = t.ParseMaxp(fd)
if err != nil {
return err
}
err = t.ParseHmtx(fd)
if err != nil {
return err
}
err = t.ParseCmap(fd)
if err != nil {
return err
}
err = t.ParseName(fd)
if err != nil {
return err
}
err = t.ParseOS2(fd)
if err != nil {
return err
}
err = t.ParsePost(fd)
if err != nil {
return err
}
err = t.ParseLoca(fd)
if err != nil {
return err
}
if t.useKerning {
err = t.Parsekern(fd)
if err != nil {
return err
}
}
t.cachedFontData = fontData
return nil
}
func (t *TTFParser) FontData() []byte {
return t.cachedFontData
}
//ParseLoca parse loca table https://www.microsoft.com/typography/otspec/loca.htm
func (t *TTFParser) ParseLoca(fd *bytes.Reader) error {
t.IsShortIndex = false
if t.indexToLocFormat == 0 {
t.IsShortIndex = true
}
//fmt.Printf("indexToLocFormat = %d\n", me.indexToLocFormat)
err := t.Seek(fd, "loca")
if err != nil {
return err
}
var locaTable []uint
table := t.tables["loca"]
if t.IsShortIndex {
//do ShortIndex
entries := table.Length / 2
i := uint(0)
for i < entries {
item, err := t.ReadUShort(fd)
if err != nil {
return err
}
locaTable = append(locaTable, item*2)
i++
}
} else {
entries := table.Length / 4
i := uint(0)
for i < entries {
item, err := t.ReadULong(fd)
if err != nil {
return err
}
locaTable = append(locaTable, item)
i++
}
}
t.LocaTable = locaTable
return nil
}
//ParsePost parse post table https://www.microsoft.com/typography/otspec/post.htm
func (t *TTFParser) ParsePost(fd *bytes.Reader) error {
err := t.Seek(fd, "post")
if err != nil {
return err
}
err = t.Skip(fd, 4) // version
if err != nil {
return err
}
t.italicAngle, err = t.ReadShort(fd)
if err != nil {
return err
}
err = t.Skip(fd, 2) // Skip decimal part
if err != nil {
return err
}
t.underlinePosition, err = t.ReadShort(fd)
if err != nil {
return err
}
//fmt.Printf("start>>>>>>>\n")
t.underlineThickness, err = t.ReadShort(fd)
if err != nil {
return err
}
//fmt.Printf("underlineThickness=%d\n", t.underlineThickness)
//fmt.Printf(">>>>>>>%d\n", me.underlineThickness)
isFixedPitch, err := t.ReadULong(fd)
if err != nil {
return err
}
t.isFixedPitch = (isFixedPitch != 0)
return nil
}
//ParseOS2 parse OS2 table https://www.microsoft.com/typography/otspec/OS2.htm
func (t *TTFParser) ParseOS2(fd *bytes.Reader) error {
err := t.Seek(fd, "OS/2")
if err != nil {
return err
}
version, err := t.ReadUShort(fd)
if err != nil {
return err
}
t.os2Version = version
err = t.Skip(fd, 3*2) // xAvgCharWidth, usWeightClass, usWidthClass
if err != nil {
return err
}
fsType, err := t.ReadUShort(fd)
if err != nil {
return err
}
t.Embeddable = (fsType != 2) && ((fsType & 0x200) == 0)
err = t.Skip(fd, (11*2)+10+(4*4)+4)
if err != nil {
return err
}
fsSelection, err := t.ReadUShort(fd)
if err != nil {
return err
}
t.Bold = ((fsSelection & 32) != 0)
err = t.Skip(fd, 2*2) // usFirstCharIndex, usLastCharIndex
if err != nil {
return err
}
t.typoAscender, err = t.ReadShort(fd)
if err != nil {
return err
}
t.typoDescender, err = t.ReadShort(fd)
if err != nil {
return err
}
t.sTypoLineGap, err = t.ReadShort(fd)
if err != nil {
return err
}
t.usWinAscent, err = t.ReadUShort(fd)
if err != nil {
return err
}
t.usWinDescent, err = t.ReadUShort(fd)
if err != nil {
return err
}
if version >= 2 {
err = t.Skip(fd, 2*4)
if err != nil {
return err
}
t.sxHeight, err = t.ReadShort(fd)
if err != nil {
return err
}
t.capHeight, err = t.ReadShort(fd)
if err != nil {
return err
}
} else {
t.capHeight = t.ascender
}
return nil
}
//ParseName parse name table https://www.microsoft.com/typography/otspec/name.htm
func (t *TTFParser) ParseName(fd *bytes.Reader) error {
//$this->Seek('name');
err := t.Seek(fd, "name")
if err != nil {
return err
}
tableOffset, err := t.FTell(fd)
if err != nil {
return err
}
t.postScriptName = ""
err = t.Skip(fd, 2) // format
if err != nil {
return err
}
count, err := t.ReadUShort(fd)
if err != nil {
return err
}
stringOffset, err := t.ReadUShort(fd)
if err != nil {
return err
}
for i := 0; i < int(count); i++ {
err = t.Skip(fd, 3*2) // platformID, encodingID, languageID
if err != nil {
return err
}
nameID, err := t.ReadUShort(fd)
if err != nil {
return err
}
length, err := t.ReadUShort(fd)
if err != nil {
return err
}
offset, err := t.ReadUShort(fd)
if err != nil {
return err
}
if nameID == 6 {
// PostScript name
_, err = fd.Seek(int64(tableOffset+stringOffset+offset), 0)
if err != nil {
return err
}
stmp, err := t.Read(fd, int(length))
if err != nil {
return err
}
var tmpStmp []byte
for _, v := range stmp {
if v != 0 {
tmpStmp = append(tmpStmp, v)
}
}
s := fmt.Sprintf("%s", string(tmpStmp)) //strings(stmp)
s = strings.Replace(s, strconv.Itoa(0), "", -1)
s, err = t.PregReplace("|[ \\[\\](){}<>/%]|", "", s)
if err != nil {
return err
}
t.postScriptName = s
break
}
}
if t.postScriptName == "" {
return ERROR_POSTSCRIPT_NAME_NOT_FOUND
}
//fmt.Printf("%s\n", me.postScriptName)
return nil
}
func (t *TTFParser) PregReplace(pattern string, replacement string, subject string) (string, error) {
reg, err := regexp.Compile(pattern)
if err != nil {
return "", err
}
str := reg.ReplaceAllString(subject, replacement)
return str, nil
}
//ParseCmap parse cmap table format 4 https://www.microsoft.com/typography/otspec/cmap.htm
func (t *TTFParser) ParseCmap(fd *bytes.Reader) error {
t.Seek(fd, "cmap")
t.Skip(fd, 2) // version
numTables, err := t.ReadUShort(fd)
if err != nil {
return err
}
offset31 := uint(0)
for i := 0; i < int(numTables); i++ {
platformID, err := t.ReadUShort(fd)
if err != nil {
return err
}
encodingID, err := t.ReadUShort(fd)
if err != nil {
return err
}
offset, err := t.ReadULong(fd)
if err != nil {
return err
}
t.symbol = false //init
if platformID == 3 && encodingID == 1 {
if encodingID == 0 {
t.symbol = true
}
offset31 = offset
}
//fmt.Printf("me.symbol=%d\n", me.symbol)
} //end for
if offset31 == 0 {
//No Unicode encoding found
return ERROR_NO_UNICODE_ENCODING_FOUND
}
var startCount, endCount, idDelta, idRangeOffset, glyphIDArray []uint
_, err = fd.Seek(int64(t.tables["cmap"].Offset+offset31), 0)
if err != nil {
return err
}
format, err := t.ReadUShort(fd)
if err != nil {
return err
}
if format != 4 {
//Unexpected subtable format
return ERROR_UNEXPECTED_SUBTABLE_FORMAT
}
length, err := t.ReadUShort(fd)
if err != nil {
return err
}
//fmt.Printf("\nlength=%d\n", length)
err = t.Skip(fd, 2) // language
if err != nil {
return err
}
segCount, err := t.ReadUShort(fd)
if err != nil {
return err
}
segCount = segCount / 2
t.SegCount = segCount
err = t.Skip(fd, 3*2) // searchRange, entrySelector, rangeShift
if err != nil {
return err
}
glyphCount := (length - (16 + 8*segCount)) / 2
//fmt.Printf("\nglyphCount=%d\n", glyphCount)
for i := 0; i < int(segCount); i++ {
tmp, err := t.ReadUShort(fd)
if err != nil {
return err
}
endCount = append(endCount, tmp)
}
t.EndCount = endCount
err = t.Skip(fd, 2) // reservedPad
if err != nil {
return err
}
for i := 0; i < int(segCount); i++ {
tmp, err := t.ReadUShort(fd)
if err != nil {
return err
}
startCount = append(startCount, tmp)
}
t.StartCount = startCount
for i := 0; i < int(segCount); i++ {
tmp, err := t.ReadUShort(fd)
if err != nil {
return err
}
idDelta = append(idDelta, tmp)
}
t.IdDelta = idDelta
offset, err := t.FTell(fd)
if err != nil {
return err
}
for i := 0; i < int(segCount); i++ {
tmp, err := t.ReadUShort(fd)
if err != nil {
return err
}
idRangeOffset = append(idRangeOffset, tmp)
}
t.IdRangeOffset = idRangeOffset
//_ = glyphIdArray
for i := 0; i < int(glyphCount); i++ {
tmp, err := t.ReadUShort(fd)
if err != nil {
return err
}
glyphIDArray = append(glyphIDArray, tmp)
}
t.GlyphIdArray = glyphIDArray
t.chars = make(map[int]uint)
for i := 0; i < int(segCount); i++ {
c1 := startCount[i]
c2 := endCount[i]
d := idDelta[i]
ro := idRangeOffset[i]
if ro > 0 {
_, err = fd.Seek(int64(offset+uint(2*i)+ro), 0)
if err != nil {
return err
}
}
for c := c1; c <= c2; c++ {
var gid uint
if c == 0xFFFF {
break
}
if ro > 0 {
gid, err = t.ReadUShort(fd)
if err != nil {
return err
}
if gid > 0 {
gid += d
}
} else {
gid = c + d
}
if gid >= 65536 {
gid -= 65536
}
if gid > 0 {
//fmt.Printf("%d gid = %d, ", int(c), gid)
t.chars[int(c)] = gid
}
}
}
_, err = t.ParseCmapFormat12(fd)
if err != nil {
return err
}
return nil
}
func (t *TTFParser) FTell(fd *bytes.Reader) (uint, error) {
offset, err := fd.Seek(0, os.SEEK_CUR)
return uint(offset), err
}
//ParseHmtx parse hmtx table https://www.microsoft.com/typography/otspec/hmtx.htm
func (t *TTFParser) ParseHmtx(fd *bytes.Reader) error {
t.Seek(fd, "hmtx")
i := uint(0)
for i < t.numberOfHMetrics {
advanceWidth, err := t.ReadUShort(fd)
if err != nil {
return err
}
err = t.Skip(fd, 2)
if err != nil {
return err
}
t.widths = append(t.widths, advanceWidth)
i++
}
if t.numberOfHMetrics < t.numGlyphs {
var err error
lastWidth := t.widths[t.numberOfHMetrics-1]
t.widths, err = t.ArrayPadUint(t.widths, t.numGlyphs, lastWidth)
if err != nil {
return err
}
}
return nil
}
func (t *TTFParser) ArrayPadUint(arr []uint, size uint, val uint) ([]uint, error) {
var result []uint
i := uint(0)
for i < size {
if int(i) < len(arr) {
result = append(result, arr[i])
} else {
result = append(result, val)
}
i++
}
return result, nil
}
//ParseHead parse head table https://www.microsoft.com/typography/otspec/Head.htm
func (t *TTFParser) ParseHead(fd *bytes.Reader) error {
//fmt.Printf("\nParseHead\n")
err := t.Seek(fd, "head")
if err != nil {
return err
}
err = t.Skip(fd, 3*4) // version, fontRevision, checkSumAdjustment
if err != nil {
return err
}
magicNumber, err := t.ReadULong(fd)
if err != nil {
return err
}
//fmt.Printf("\nmagicNumber = %d\n", magicNumber)
if magicNumber != 0x5F0F3CF5 {
return ERROR_INCORRECT_MAGIC_NUMBER
}
err = t.Skip(fd, 2)
if err != nil {
return err
}
t.unitsPerEm, err = t.ReadUShort(fd)
if err != nil {
return err
}
err = t.Skip(fd, 2*8) // created, modified
if err != nil {
return err
}
t.xMin, err = t.ReadShort(fd)
if err != nil {
return err
}
t.yMin, err = t.ReadShort(fd)
if err != nil {
return err
}
t.xMax, err = t.ReadShort(fd)
if err != nil {
return err
}
t.yMax, err = t.ReadShort(fd)
if err != nil {
return err
}
err = t.Skip(fd, 2*3) //skip macStyle,lowestRecPPEM,fontDirectionHint
if err != nil {
return err
}
t.indexToLocFormat, err = t.ReadShort(fd)
if err != nil {
retu
gitextract_c0w8xc36/
├── .github/
│ └── workflows/
│ ├── codeql-analysis.yml
│ ├── go.yml
│ └── golangci-lint.yml
├── .gitignore
├── LICENSE
├── README.md
├── go.mod
├── go.sum
├── main.go
└── vendor/
├── github.com/
│ ├── phpdave11/
│ │ └── gofpdi/
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── const.go
│ │ ├── go.mod
│ │ ├── go.sum
│ │ ├── gofpdi.go
│ │ ├── helper.go
│ │ ├── importer.go
│ │ ├── reader.go
│ │ └── writer.go
│ ├── pkg/
│ │ └── errors/
│ │ ├── .gitignore
│ │ ├── .travis.yml
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── appveyor.yml
│ │ ├── errors.go
│ │ └── stack.go
│ └── signintech/
│ └── gopdf/
│ ├── .gitignore
│ ├── Changelog.md
│ ├── LICENSE
│ ├── README.md
│ ├── box.go
│ ├── buff.go
│ ├── buff_write.go
│ ├── buffer_pool.go
│ ├── cache_contact_color.go
│ ├── cache_content_gray.go
│ ├── cache_content_image.go
│ ├── cache_content_imported_object.go
│ ├── cache_content_line.go
│ ├── cache_content_line_type.go
│ ├── cache_content_line_width.go
│ ├── cache_content_oval.go
│ ├── cache_content_polygon.go
│ ├── cache_content_rectangle.go
│ ├── cache_content_rotate.go
│ ├── cache_content_text.go
│ ├── cache_contnent_curve.go
│ ├── catalog_obj.go
│ ├── cell_option.go
│ ├── cid_font_obj.go
│ ├── config.go
│ ├── content_obj.go
│ ├── current.go
│ ├── device_rgb_obj.go
│ ├── embedfont_obj.go
│ ├── encoding_obj.go
│ ├── encryption_obj.go
│ ├── ext_g_state_obj.go
│ ├── font_obj.go
│ ├── font_option.go
│ ├── fontconverthelper.go
│ ├── fontdescriptor_obj.go
│ ├── fontmaker/
│ │ └── core/
│ │ ├── fontmaker.go
│ │ ├── fontmap.go
│ │ ├── kern_table.go
│ │ ├── math.go
│ │ ├── table_directory_entry.go
│ │ ├── ttf_info.go
│ │ ├── ttfparser.go
│ │ ├── ttfparser_cmap_other_format.go
│ │ └── ttfparser_kern.go
│ ├── func_kern_override.go
│ ├── go.mod
│ ├── go.sum
│ ├── gopdf.go
│ ├── i_cache_contneter.go
│ ├── ifont.go
│ ├── image_holder.go
│ ├── image_obj.go
│ ├── image_obj_parse.go
│ ├── img_info.go
│ ├── imported_obj.go
│ ├── iobj.go
│ ├── link_option.go
│ ├── list_cache_content.go
│ ├── map_of_character_To_glyph_index.go
│ ├── margin.go
│ ├── outlines_obj.go
│ ├── page_obj.go
│ ├── page_option.go
│ ├── page_sizes.go
│ ├── pages_obj.go
│ ├── pdf_dictionary_obj.go
│ ├── pdf_info_obj.go
│ ├── pdf_protection.go
│ ├── point.go
│ ├── procset_obj.go
│ ├── rect.go
│ ├── smask_obj.go
│ ├── strhelper.go
│ ├── style.go
│ ├── subfont_descriptor_obj.go
│ ├── subset_font_obj.go
│ ├── transparency.go
│ ├── transparency_xobject_group.go
│ ├── ttf_option.go
│ └── unicode_map.go
└── modules.txt
SYMBOL INDEX (794 symbols across 82 files)
FILE: main.go
constant Version (line 20) | Version = "1.0"
constant NameOfProgram (line 21) | NameOfProgram = "resumeio2pdf"
constant Copy (line 22) | Copy = "Copyright (c) 2021, Leonid Sopov <leonid@sopov.org>"
constant CopyURL (line 23) | CopyURL = "https://github.com/sopov/resumeio2pdf/"
constant resumePage (line 25) | resumePage = "https://resume.io/r/%s"
constant resumeMeta (line 26) | resumeMeta = "https://ssr.resume.tools/meta/ssid-%s?cache=%s"
constant resumeExt (line 27) | resumeExt = "png"
constant resumeIMG (line 28) | resumeIMG = "https://ssr.resume.tools/to-image/ssid-%s-%d.%s?cache=%s&s...
constant resumeSize (line 29) | resumeSize = 1800
constant Timeout (line 30) | Timeout = 60 * time.Second
constant exitCodeMisuseArgs (line 32) | exitCodeMisuseArgs = 2
type metaLink (line 50) | type metaLink struct
type metaViewPort (line 58) | type metaViewPort struct
type metaPageInfo (line 63) | type metaPageInfo struct
type metaInfo (line 68) | type metaInfo struct
function main (line 72) | func main() {
function cleanup (line 101) | func cleanup(images []string) {
function generatePDF (line 115) | func generatePDF(info *metaInfo, images []string) error {
function getResumeImages (line 159) | func getResumeImages(p int) (pages []string, err error) {
function downloadPage (line 183) | func downloadPage(imgURL, imgFile string) error {
function getJSON (line 209) | func getJSON(url string, target interface{}) error {
function getMeta (line 233) | func getMeta() (meta *metaInfo, err error) {
function readFlags (line 241) | func readFlags() bool {
function extractArg (line 303) | func extractArg() bool {
function usages (line 333) | func usages() {
function usageID (line 355) | func usageID() {
function logger (line 360) | func logger(v ...interface{}) {
function loggerf (line 368) | func loggerf(format string, a ...interface{}) {
FILE: vendor/github.com/phpdave11/gofpdi/const.go
constant PDF_TYPE_NULL (line 4) | PDF_TYPE_NULL = iota
constant PDF_TYPE_NUMERIC (line 5) | PDF_TYPE_NUMERIC
constant PDF_TYPE_TOKEN (line 6) | PDF_TYPE_TOKEN
constant PDF_TYPE_HEX (line 7) | PDF_TYPE_HEX
constant PDF_TYPE_STRING (line 8) | PDF_TYPE_STRING
constant PDF_TYPE_DICTIONARY (line 9) | PDF_TYPE_DICTIONARY
constant PDF_TYPE_ARRAY (line 10) | PDF_TYPE_ARRAY
constant PDF_TYPE_OBJDEC (line 11) | PDF_TYPE_OBJDEC
constant PDF_TYPE_OBJREF (line 12) | PDF_TYPE_OBJREF
constant PDF_TYPE_OBJECT (line 13) | PDF_TYPE_OBJECT
constant PDF_TYPE_STREAM (line 14) | PDF_TYPE_STREAM
constant PDF_TYPE_BOOLEAN (line 15) | PDF_TYPE_BOOLEAN
constant PDF_TYPE_REAL (line 16) | PDF_TYPE_REAL
FILE: vendor/github.com/phpdave11/gofpdi/helper.go
function is_numeric (line 9) | func is_numeric(val interface{}) bool {
function in_array (line 60) | func in_array(needle interface{}, hystack interface{}) bool {
constant intSize (line 89) | intSize = 32 << (^uint(0) >> 63)
function abs (line 91) | func abs(x int) int {
function filterPaeth (line 105) | func filterPaeth(cdat, pdat []byte, bytesPerPixel int) {
FILE: vendor/github.com/phpdave11/gofpdi/importer.go
type Importer (line 9) | type Importer struct
method GetReader (line 24) | func (this *Importer) GetReader() *PdfReader {
method GetWriter (line 28) | func (this *Importer) GetWriter() *PdfWriter {
method GetReaderForFile (line 32) | func (this *Importer) GetReaderForFile(file string) *PdfReader {
method GetWriterForFile (line 40) | func (this *Importer) GetWriterForFile(file string) *PdfWriter {
method init (line 55) | func (this *Importer) init() {
method SetSourceFile (line 62) | func (this *Importer) SetSourceFile(f string) {
method SetSourceStream (line 87) | func (this *Importer) SetSourceStream(rs *io.ReadSeeker) {
method GetPageSizes (line 111) | func (this *Importer) GetPageSizes() map[int]map[string]map[string]flo...
method ImportPage (line 121) | func (this *Importer) ImportPage(pageno int, box string) int {
method SetNextObjectID (line 139) | func (this *Importer) SetNextObjectID(objId int) {
method PutFormXobjects (line 144) | func (this *Importer) PutFormXobjects() map[string]int {
method PutFormXobjectsUnordered (line 157) | func (this *Importer) PutFormXobjectsUnordered() map[string]string {
method GetImportedObjects (line 171) | func (this *Importer) GetImportedObjects() map[int]string {
method GetImportedObjectsUnordered (line 183) | func (this *Importer) GetImportedObjectsUnordered() map[string][]byte {
method GetImportedObjHashPos (line 194) | func (this *Importer) GetImportedObjHashPos() map[string]map[int]string {
method UseTemplate (line 205) | func (this *Importer) UseTemplate(tplid int, _x float64, _y float64, _...
type TplInfo (line 18) | type TplInfo struct
function NewImporter (line 48) | func NewImporter() *Importer {
FILE: vendor/github.com/phpdave11/gofpdi/reader.go
type PdfReader (line 17) | type PdfReader struct
method init (line 68) | func (this *PdfReader) init() error {
method skipComments (line 97) | func (this *PdfReader) skipComments(r *bufio.Reader) error {
method skipWhitespace (line 126) | func (this *PdfReader) skipWhitespace(r *bufio.Reader) error {
method readToken (line 151) | func (this *PdfReader) readToken(r *bufio.Reader) (string, error) {
method readValue (line 226) | func (this *PdfReader) readValue(r *bufio.Reader, t string) (*PdfValue...
method resolveCompressedObject (line 451) | func (this *PdfReader) resolveCompressedObject(objSpec *PdfValue) (*Pd...
method resolveObject (line 589) | func (this *PdfReader) resolveObject(objSpec *PdfValue) (*PdfValue, er...
method findXref (line 740) | func (this *PdfReader) findXref() error {
method readXref (line 805) | func (this *PdfReader) readXref() error {
method readRoot (line 1170) | func (this *PdfReader) readRoot() error {
method readPages (line 1185) | func (this *PdfReader) readPages() error {
method getPageResources (line 1218) | func (this *PdfReader) getPageResources(pageno int) (*PdfValue, error) {
method getPageContent (line 1272) | func (this *PdfReader) getPageContent(objSpec *PdfValue) ([]*PdfValue,...
method getContent (line 1303) | func (this *PdfReader) getContent(pageno int) (string, error) {
method rebuildContentStream (line 1345) | func (this *PdfReader) rebuildContentStream(content *PdfValue) ([]byte...
method getAllPageBoxes (line 1398) | func (this *PdfReader) getAllPageBoxes(k float64) (map[int]map[string]...
method getPageBoxes (line 1415) | func (this *PdfReader) getPageBoxes(pageno int, k float64) (map[string...
method getPageBox (line 1446) | func (this *PdfReader) getPageBox(page *PdfValue, box_index string, k ...
method getPageRotation (line 1494) | func (this *PdfReader) getPageRotation(pageno int) (*PdfValue, error) {
method _getPageRotation (line 1504) | func (this *PdfReader) _getPageRotation(page *PdfValue) (*PdfValue, er...
method read (line 1549) | func (this *PdfReader) read() error {
function NewPdfReaderFromStream (line 31) | func NewPdfReaderFromStream(rs io.ReadSeeker) (*PdfReader, error) {
function NewPdfReader (line 46) | func NewPdfReader(filename string) (*PdfReader, error) {
type PdfValue (line 79) | type PdfValue struct
FILE: vendor/github.com/phpdave11/gofpdi/writer.go
type PdfWriter (line 15) | type PdfWriter struct
method SetTplIdOffset (line 47) | func (this *PdfWriter) SetTplIdOffset(n int) {
method Init (line 51) | func (this *PdfWriter) Init() {
method SetUseHash (line 61) | func (this *PdfWriter) SetUseHash(b bool) {
method SetNextObjectID (line 65) | func (this *PdfWriter) SetNextObjectID(id int) {
method GetImportedObjects (line 101) | func (this *PdfWriter) GetImportedObjects() map[*PdfObjectId][]byte {
method GetImportedObjHashPos (line 107) | func (this *PdfWriter) GetImportedObjHashPos() map[*PdfObjectId]map[in...
method ClearImportedObjects (line 111) | func (this *PdfWriter) ClearImportedObjects() {
method ImportPage (line 116) | func (this *PdfWriter) ImportPage(reader *PdfReader, pageno int, boxNa...
method newObj (line 200) | func (this *PdfWriter) newObj(objId int, onlyNewObj bool) {
method endObj (line 221) | func (this *PdfWriter) endObj() {
method shaOfInt (line 228) | func (this *PdfWriter) shaOfInt(i int) string {
method outObjRef (line 235) | func (this *PdfWriter) outObjRef(objId int) {
method out (line 250) | func (this *PdfWriter) out(s string) {
method straightOut (line 256) | func (this *PdfWriter) straightOut(s string) {
method writeValue (line 261) | func (this *PdfWriter) writeValue(value *PdfValue) {
method PutFormXobjects (line 341) | func (this *PdfWriter) PutFormXobjects(reader *PdfReader) (map[string]...
method putImportedObjects (line 464) | func (this *PdfWriter) putImportedObjects(reader *PdfReader) error {
method getTemplateSize (line 514) | func (this *PdfWriter) getTemplateSize(tplid int, _w float64, _h float...
method UseTemplate (line 541) | func (this *PdfWriter) UseTemplate(tplid int, _x float64, _y float64, ...
type PdfObjectId (line 37) | type PdfObjectId struct
type PdfObject (line 42) | type PdfObject struct
function NewPdfWriter (line 69) | func NewPdfWriter(filename string) (*PdfWriter, error) {
type PdfTemplate (line 86) | type PdfTemplate struct
FILE: vendor/github.com/pkg/errors/errors.go
function New (line 102) | func New(message string) error {
function Errorf (line 112) | func Errorf(format string, args ...interface{}) error {
type fundamental (line 120) | type fundamental struct
method Error (line 125) | func (f *fundamental) Error() string { return f.msg }
method Format (line 127) | func (f *fundamental) Format(s fmt.State, verb rune) {
function WithStack (line 145) | func WithStack(err error) error {
type withStack (line 155) | type withStack struct
method Cause (line 160) | func (w *withStack) Cause() error { return w.error }
method Format (line 162) | func (w *withStack) Format(s fmt.State, verb rune) {
function Wrap (line 181) | func Wrap(err error, message string) error {
function Wrapf (line 198) | func Wrapf(err error, format string, args ...interface{}) error {
function WithMessage (line 214) | func WithMessage(err error, message string) error {
function WithMessagef (line 226) | func WithMessagef(err error, format string, args ...interface{}) error {
type withMessage (line 236) | type withMessage struct
method Error (line 241) | func (w *withMessage) Error() string { return w.msg + ": " + w.cause.E...
method Cause (line 242) | func (w *withMessage) Cause() error { return w.cause }
method Format (line 244) | func (w *withMessage) Format(s fmt.State, verb rune) {
function Cause (line 269) | func Cause(err error) error {
FILE: vendor/github.com/pkg/errors/stack.go
type Frame (line 12) | type Frame
method pc (line 16) | func (f Frame) pc() uintptr { return uintptr(f) - 1 }
method file (line 20) | func (f Frame) file() string {
method line (line 31) | func (f Frame) line() int {
method Format (line 52) | func (f Frame) Format(s fmt.State, verb rune) {
type StackTrace (line 81) | type StackTrace
method Format (line 91) | func (st StackTrace) Format(s fmt.State, verb rune) {
type stack (line 110) | type stack
method Format (line 112) | func (s *stack) Format(st fmt.State, verb rune) {
method StackTrace (line 125) | func (s *stack) StackTrace() StackTrace {
function callers (line 133) | func callers() *stack {
function funcname (line 142) | func funcname(name string) string {
FILE: vendor/github.com/signintech/gopdf/box.go
type Box (line 3) | type Box struct
method UnitsToPoints (line 9) | func (box *Box) UnitsToPoints(t int) (b *Box) {
FILE: vendor/github.com/signintech/gopdf/buff.go
type Buff (line 4) | type Buff struct
method Write (line 10) | func (b *Buff) Write(p []byte) (int, error) {
method Len (line 25) | func (b *Buff) Len() int {
method Bytes (line 30) | func (b *Buff) Bytes() []byte {
method Position (line 35) | func (b *Buff) Position() int {
method SetPosition (line 40) | func (b *Buff) SetPosition(pos int) {
FILE: vendor/github.com/signintech/gopdf/buff_write.go
function WriteUInt32 (line 6) | func WriteUInt32(w io.Writer, v uint) error {
function WriteUInt16 (line 19) | func WriteUInt16(w io.Writer, v uint) error {
function WriteTag (line 31) | func WriteTag(w io.Writer, tag string) error {
function WriteBytes (line 41) | func WriteBytes(w io.Writer, data []byte, offset int, count int) error {
FILE: vendor/github.com/signintech/gopdf/buffer_pool.go
function GetBuffer (line 17) | func GetBuffer() *bytes.Buffer {
function PutBuffer (line 22) | func PutBuffer(buf *bytes.Buffer) {
FILE: vendor/github.com/signintech/gopdf/cache_contact_color.go
constant colorTypeStroke (line 8) | colorTypeStroke = "RG"
constant colorTypeFill (line 10) | colorTypeFill = "rg"
type cacheContentColor (line 12) | type cacheContentColor struct
method write (line 17) | func (c *cacheContentColor) write(w io.Writer, protection *PDFProtecti...
FILE: vendor/github.com/signintech/gopdf/cache_content_gray.go
constant grayTypeFill (line 8) | grayTypeFill = "g"
constant grayTypeStroke (line 9) | grayTypeStroke = "G"
type cacheContentGray (line 11) | type cacheContentGray struct
method write (line 16) | func (c *cacheContentGray) write(w io.Writer, protection *PDFProtectio...
FILE: vendor/github.com/signintech/gopdf/cache_content_image.go
type cacheContentImage (line 8) | type cacheContentImage struct
method write (line 20) | func (c *cacheContentImage) write(w io.Writer, protection *PDFProtecti...
FILE: vendor/github.com/signintech/gopdf/cache_content_imported_object.go
type cacheContentImportedTemplate (line 8) | type cacheContentImportedTemplate struct
method write (line 17) | func (c *cacheContentImportedTemplate) write(w io.Writer, protection *...
FILE: vendor/github.com/signintech/gopdf/cache_content_line.go
type cacheContentLine (line 8) | type cacheContentLine struct
method write (line 16) | func (c *cacheContentLine) write(w io.Writer, protection *PDFProtectio...
FILE: vendor/github.com/signintech/gopdf/cache_content_line_type.go
type cacheContentLineType (line 8) | type cacheContentLineType struct
method write (line 12) | func (c *cacheContentLineType) write(w io.Writer, protection *PDFProte...
FILE: vendor/github.com/signintech/gopdf/cache_content_line_width.go
type cacheContentLineWidth (line 8) | type cacheContentLineWidth struct
method write (line 12) | func (c *cacheContentLineWidth) write(w io.Writer, protection *PDFProt...
FILE: vendor/github.com/signintech/gopdf/cache_content_oval.go
type cacheContentOval (line 8) | type cacheContentOval struct
method write (line 16) | func (c *cacheContentOval) write(w io.Writer, protection *PDFProtectio...
FILE: vendor/github.com/signintech/gopdf/cache_content_polygon.go
type cacheContentPolygon (line 8) | type cacheContentPolygon struct
method write (line 14) | func (c *cacheContentPolygon) write(w io.Writer, protection *PDFProtec...
FILE: vendor/github.com/signintech/gopdf/cache_content_rectangle.go
type cacheContentRectangle (line 8) | type cacheContentRectangle struct
method write (line 34) | func (c cacheContentRectangle) write(w io.Writer, protection *PDFProte...
function NewCacheContentRectangle (line 18) | func NewCacheContentRectangle(pageHeight float64, rectOpts DrawableRectO...
FILE: vendor/github.com/signintech/gopdf/cache_content_rotate.go
type cacheContentRotate (line 9) | type cacheContentRotate struct
method write (line 15) | func (cc *cacheContentRotate) write(w io.Writer, protection *PDFProtec...
FILE: vendor/github.com/signintech/gopdf/cache_content_text.go
constant ContentTypeCell (line 10) | ContentTypeCell = 0
constant ContentTypeText (line 13) | ContentTypeText = 1
type cacheContentText (line 15) | type cacheContentText struct
method isSame (line 37) | func (c *cacheContentText) isSame(cache cacheContentText) bool {
method setPageHeight (line 55) | func (c *cacheContentText) setPageHeight(pageheight float64) {
method pageHeight (line 59) | func (c *cacheContentText) pageHeight() float64 {
method calTypoAscender (line 68) | func (c *cacheContentText) calTypoAscender() float64 {
method calTypoDescender (line 72) | func (c *cacheContentText) calTypoDescender() float64 {
method calY (line 76) | func (c *cacheContentText) calY() (float64, error) {
method calX (line 96) | func (c *cacheContentText) calX() (float64, error) {
method write (line 113) | func (c *cacheContentText) write(w io.Writer, protection *PDFProtectio...
method drawBorder (line 183) | func (c *cacheContentText) drawBorder(w io.Writer) error {
method underline (line 236) | func (c *cacheContentText) underline(w io.Writer, startX float64, star...
method createContent (line 254) | func (c *cacheContentText) createContent() (float64, float64, error) {
function convertTypoUnit (line 63) | func convertTypoUnit(val float64, unitsPerEm uint, fontSize float64) flo...
function createContent (line 266) | func createContent(f *SubsetFontObj, text string, fontSize int, rectangl...
function kern (line 311) | func kern(f *SubsetFontObj, leftRune rune, rightRune rune, leftIndex uin...
type CacheContent (line 333) | type CacheContent struct
method Setup (line 338) | func (c *CacheContent) Setup(rectangle *Rect,
method WriteTextToContent (line 371) | func (c *CacheContent) WriteTextToContent(text string) {
FILE: vendor/github.com/signintech/gopdf/cache_contnent_curve.go
type cacheContentCurve (line 8) | type cacheContentCurve struct
method write (line 21) | func (c *cacheContentCurve) write(w io.Writer, protection *PDFProtecti...
FILE: vendor/github.com/signintech/gopdf/catalog_obj.go
type CatalogObj (line 9) | type CatalogObj struct
method init (line 13) | func (c *CatalogObj) init(funcGetRoot func() *GoPdf) {
method getType (line 18) | func (c *CatalogObj) getType() string {
method write (line 22) | func (c *CatalogObj) write(w io.Writer, objID int) error {
method SetIndexObjOutlines (line 34) | func (c *CatalogObj) SetIndexObjOutlines(index int) {
FILE: vendor/github.com/signintech/gopdf/cell_option.go
constant Left (line 4) | Left = 8
constant Top (line 6) | Top = 4
constant Right (line 8) | Right = 2
constant Bottom (line 10) | Bottom = 1
constant Center (line 12) | Center = 16
constant Middle (line 14) | Middle = 32
constant AllBorders (line 16) | AllBorders = 15
type CellOption (line 19) | type CellOption struct
FILE: vendor/github.com/signintech/gopdf/cid_font_obj.go
type CIDFontObj (line 10) | type CIDFontObj struct
method init (line 15) | func (ci *CIDFontObj) init(funcGetRoot func() *GoPdf) {
method SetIndexObjSubfontDescriptor (line 19) | func (ci *CIDFontObj) SetIndexObjSubfontDescriptor(index int) {
method getType (line 23) | func (ci *CIDFontObj) getType() string {
method write (line 27) | func (ci *CIDFontObj) write(w io.Writer, objID int) error {
method SetPtrToSubsetFontObj (line 51) | func (ci *CIDFontObj) SetPtrToSubsetFontObj(ptr *SubsetFontObj) {
FILE: vendor/github.com/signintech/gopdf/config.go
constant UnitUnset (line 5) | UnitUnset = iota
constant UnitPT (line 6) | UnitPT
constant UnitMM (line 7) | UnitMM
constant UnitCM (line 8) | UnitCM
constant UnitIN (line 9) | UnitIN
constant conversionUnitPT (line 12) | conversionUnitPT = 1.0
constant conversionUnitMM (line 13) | conversionUnitMM = 72.0 / 25.4
constant conversionUnitCM (line 14) | conversionUnitCM = 72.0 / 2.54
constant conversionUnitIN (line 15) | conversionUnitIN = 72.0
constant Unit_Unset (line 21) | Unit_Unset = UnitUnset
constant Unit_PT (line 22) | Unit_PT = UnitPT
constant Unit_MM (line 23) | Unit_MM = UnitMM
constant Unit_CM (line 24) | Unit_CM = UnitCM
constant Unit_IN (line 25) | Unit_IN = UnitIN
type Config (line 29) | type Config struct
type PDFProtectionConfig (line 38) | type PDFProtectionConfig struct
function UnitsToPoints (line 46) | func UnitsToPoints(t int, u float64) float64 {
function PointsToUnits (line 62) | func PointsToUnits(t int, u float64) float64 {
function UnitsToPointsVar (line 78) | func UnitsToPointsVar(t int, u ...*float64) {
function PointsToUnitsVar (line 85) | func PointsToUnitsVar(t int, u ...*float64) {
FILE: vendor/github.com/signintech/gopdf/content_obj.go
type ContentObj (line 11) | type ContentObj struct
method protection (line 17) | func (c *ContentObj) protection() *PDFProtection {
method init (line 21) | func (c *ContentObj) init(funcGetRoot func() *GoPdf) {
method write (line 25) | func (c *ContentObj) write(w io.Writer, objID int) error {
method getType (line 97) | func (c *ContentObj) getType() string {
method AppendStreamText (line 102) | func (c *ContentObj) AppendStreamText(text string) error {
method AppendStreamSubsetFont (line 145) | func (c *ContentObj) AppendStreamSubsetFont(rectangle *Rect, text stri...
method AppendStreamLine (line 183) | func (c *ContentObj) AppendStreamLine(x1 float64, y1 float64, x2 float...
method AppendStreamImportedTemplate (line 196) | func (c *ContentObj) AppendStreamImportedTemplate(tplName string, scal...
method AppendStreamRectangle (line 207) | func (c *ContentObj) AppendStreamRectangle(opts DrawableRectOptions) {
method AppendStreamOval (line 213) | func (c *ContentObj) AppendStreamOval(x1 float64, y1 float64, x2 float...
method AppendStreamCurve (line 232) | func (c *ContentObj) AppendStreamCurve(x0 float64, y0 float64, x1 floa...
method AppendStreamSetLineWidth (line 248) | func (c *ContentObj) AppendStreamSetLineWidth(w float64) {
method AppendStreamSetLineType (line 255) | func (c *ContentObj) AppendStreamSetLineType(t string) {
method AppendStreamSetGrayFill (line 263) | func (c *ContentObj) AppendStreamSetGrayFill(w float64) {
method AppendStreamSetGrayStroke (line 272) | func (c *ContentObj) AppendStreamSetGrayStroke(w float64) {
method AppendStreamSetColorStroke (line 281) | func (c *ContentObj) AppendStreamSetColorStroke(r uint8, g uint8, b ui...
method AppendStreamSetColorFill (line 291) | func (c *ContentObj) AppendStreamSetColorFill(r uint8, g uint8, b uint...
method GetCacheContentImage (line 300) | func (c *ContentObj) GetCacheContentImage(index int, opts ImageOptions...
method AppendStreamImage (line 317) | func (c *ContentObj) AppendStreamImage(index int, opts ImageOptions) {
method AppendStreamPolygon (line 323) | func (c *ContentObj) AppendStreamPolygon(points []Point, style string) {
method appendRotate (line 331) | func (c *ContentObj) appendRotate(angle, x, y float64) {
method appendRotateReset (line 341) | func (c *ContentObj) appendRotateReset() {
function ContentObjCalTextHeight (line 348) | func ContentObjCalTextHeight(fontsize int) float64 {
function fixRange10 (line 355) | func fixRange10(val float64) float64 {
function convertTTFUnit2PDFUnit (line 365) | func convertTTFUnit2PDFUnit(n int, upem int) int {
FILE: vendor/github.com/signintech/gopdf/current.go
type Current (line 4) | type Current struct
method setTextColor (line 54) | func (c *Current) setTextColor(rgb Rgb) {
method textColor (line 58) | func (c *Current) textColor() Rgb {
type ImageCache (line 63) | type ImageCache struct
type Rgb (line 70) | type Rgb struct
method SetR (line 77) | func (rgb *Rgb) SetR(r uint8) {
method SetG (line 82) | func (rgb *Rgb) SetG(g uint8) {
method SetB (line 87) | func (rgb *Rgb) SetB(b uint8) {
method equal (line 91) | func (rgb Rgb) equal(obj Rgb) bool {
FILE: vendor/github.com/signintech/gopdf/device_rgb_obj.go
type DeviceRGBObj (line 9) | type DeviceRGBObj struct
method init (line 14) | func (d *DeviceRGBObj) init(funcGetRoot func() *GoPdf) {
method protection (line 18) | func (d *DeviceRGBObj) protection() *PDFProtection {
method getType (line 22) | func (d *DeviceRGBObj) getType() string {
method write (line 27) | func (d *DeviceRGBObj) write(w io.Writer, objID int) error {
FILE: vendor/github.com/signintech/gopdf/embedfont_obj.go
type EmbedFontObj (line 10) | type EmbedFontObj struct
method init (line 17) | func (e *EmbedFontObj) init(funcGetRoot func() *GoPdf) {
method protection (line 21) | func (e *EmbedFontObj) protection() *PDFProtection {
method write (line 25) | func (e *EmbedFontObj) write(w io.Writer, objID int) error {
method getType (line 49) | func (e *EmbedFontObj) getType() string {
method SetFont (line 54) | func (e *EmbedFontObj) SetFont(font IFont, zfontpath string) {
FILE: vendor/github.com/signintech/gopdf/encoding_obj.go
type EncodingObj (line 8) | type EncodingObj struct
method init (line 12) | func (e *EncodingObj) init(funcGetRoot func() *GoPdf) {
method getType (line 15) | func (e *EncodingObj) getType() string {
method write (line 18) | func (e *EncodingObj) write(w io.Writer, objID int) error {
method SetFont (line 26) | func (e *EncodingObj) SetFont(font IFont) {
method GetFont (line 31) | func (e *EncodingObj) GetFont() IFont {
FILE: vendor/github.com/signintech/gopdf/encryption_obj.go
type EncryptionObj (line 10) | type EncryptionObj struct
method init (line 16) | func (e *EncryptionObj) init(func() *GoPdf) {
method getType (line 20) | func (e *EncryptionObj) getType() string {
method write (line 24) | func (e *EncryptionObj) write(w io.Writer, objID int) error {
method escape (line 36) | func (e *EncryptionObj) escape(b []byte) string {
FILE: vendor/github.com/signintech/gopdf/ext_g_state_obj.go
type ExtGState (line 12) | type ExtGState struct
method init (line 73) | func (egs ExtGState) init(func() *GoPdf) {}
method getType (line 75) | func (egs ExtGState) getType() string {
method write (line 79) | func (egs ExtGState) write(w io.Writer, objID int) error {
type ExtGStateOptions (line 20) | type ExtGStateOptions struct
method GetId (line 27) | func (extOpt ExtGStateOptions) GetId() string {
function GetCachedExtGState (line 45) | func GetCachedExtGState(opts ExtGStateOptions, gp *GoPdf) (ExtGState, er...
type ExtGStatesMap (line 106) | type ExtGStatesMap struct
method Find (line 118) | func (extm *ExtGStatesMap) Find(extGState ExtGStateOptions) (ExtGState...
method Save (line 133) | func (tm *ExtGStatesMap) Save(id string, extGState ExtGState) ExtGState {
function NewExtGStatesMap (line 111) | func NewExtGStatesMap() ExtGStatesMap {
FILE: vendor/github.com/signintech/gopdf/font_obj.go
type FontObj (line 9) | type FontObj struct
method init (line 23) | func (f *FontObj) init(funcGetRoot func() *GoPdf) {
method write (line 28) | func (f *FontObj) write(w io.Writer, objID int) error {
method getType (line 48) | func (f *FontObj) getType() string {
method SetIndexObjWidth (line 53) | func (f *FontObj) SetIndexObjWidth(index int) {
method SetIndexObjFontDescriptor (line 58) | func (f *FontObj) SetIndexObjFontDescriptor(index int) {
method SetIndexObjEncoding (line 63) | func (f *FontObj) SetIndexObjEncoding(index int) {
FILE: vendor/github.com/signintech/gopdf/font_option.go
constant Regular (line 8) | Regular = 0
constant Italic (line 10) | Italic = 1
constant Bold (line 12) | Bold = 2
constant Underline (line 14) | Underline = 4
function getConvertedStyle (line 16) | func getConvertedStyle(fontStyle string) (style int) {
FILE: vendor/github.com/signintech/gopdf/fontconverthelper.go
function FontConvertHelperCw2Str (line 10) | func FontConvertHelperCw2Str(cw FontCw) string {
function FontConvertHelper_Cw2Str (line 23) | func FontConvertHelper_Cw2Str(cw FontCw) string {
FILE: vendor/github.com/signintech/gopdf/fontdescriptor_obj.go
type FontDescriptorObj (line 9) | type FontDescriptorObj struct
method init (line 14) | func (f *FontDescriptorObj) init(funcGetRoot func() *GoPdf) {
method write (line 18) | func (f *FontDescriptorObj) write(w io.Writer, objID int) error {
method getType (line 41) | func (f *FontDescriptorObj) getType() string {
method SetFont (line 46) | func (f *FontDescriptorObj) SetFont(font IFont) {
method GetFont (line 51) | func (f *FontDescriptorObj) GetFont() IFont {
method SetFontFileObjRelate (line 56) | func (f *FontDescriptorObj) SetFontFileObjRelate(relate string) {
FILE: vendor/github.com/signintech/gopdf/fontmaker/core/fontmaker.go
type FontMaker (line 20) | type FontMaker struct
method GetResults (line 25) | func (f *FontMaker) GetResults() []string {
method MakeFont (line 34) | func (f *FontMaker) MakeFont(fontpath string, mappath string, encode s...
method GoStructName (line 94) | func (f *FontMaker) GoStructName(name string) string {
method MakeDefinitionFile (line 99) | func (f *FontMaker) MakeDefinitionFile(gofontname string, mappath stri...
method MakeFontDescriptor (line 213) | func (f *FontMaker) MakeFontDescriptor(info TtfInfo) (string, error) {
method MakeFontEncoding (line 304) | func (f *FontMaker) MakeFontEncoding(mappath string, fontmaps []FontMa...
method MakeWidthArray (line 325) | func (f *FontMaker) MakeWidthArray(widths map[int]int) (string, error) {
method FileSize (line 345) | func (f *FontMaker) FileSize(path string) (int64, error) {
method GetInfoFromTrueType (line 361) | func (f *FontMaker) GetInfoFromTrueType(fontpath string, fontmaps []Fo...
method MultiplyAndRoundWithUInt64 (line 433) | func (f *FontMaker) MultiplyAndRoundWithUInt64(k float64, v uint) int {
method MultiplyAndRound (line 438) | func (f *FontMaker) MultiplyAndRound(k float64, v int) int {
method Round (line 443) | func (f *FontMaker) Round(value float64) int {
method LoadMap (line 447) | func (f *FontMaker) LoadMap(encodingpath string) ([]FontMap, error) {
function NewFontMaker (line 30) | func NewFontMaker() *FontMaker {
FILE: vendor/github.com/signintech/gopdf/fontmaker/core/fontmap.go
type FontMap (line 3) | type FontMap struct
FILE: vendor/github.com/signintech/gopdf/fontmaker/core/kern_table.go
type KernTable (line 4) | type KernTable struct
type KernMap (line 11) | type KernMap
type KernValue (line 14) | type KernValue
method ValueByRight (line 17) | func (k KernValue) ValueByRight(right uint) (bool, int16) {
FILE: vendor/github.com/signintech/gopdf/fontmaker/core/math.go
function Round (line 3) | func Round(value float64) int {
FILE: vendor/github.com/signintech/gopdf/fontmaker/core/table_directory_entry.go
type TableDirectoryEntry (line 3) | type TableDirectoryEntry struct
method PaddedLength (line 9) | func (t TableDirectoryEntry) PaddedLength() int {
FILE: vendor/github.com/signintech/gopdf/fontmaker/core/ttf_info.go
type TtfInfo (line 10) | type TtfInfo
method PushString (line 12) | func (t TtfInfo) PushString(key string, val string) {
method PushBytes (line 16) | func (t TtfInfo) PushBytes(key string, val []byte) {
method PushInt64 (line 20) | func (t TtfInfo) PushInt64(key string, val int64) {
method PushInt (line 24) | func (t TtfInfo) PushInt(key string, val int) {
method PushUInt64 (line 28) | func (t TtfInfo) PushUInt64(key string, val uint) {
method PushBool (line 32) | func (t TtfInfo) PushBool(key string, val bool) {
method PushInt64s (line 36) | func (t TtfInfo) PushInt64s(key string, val []int) {
method PushMapIntInt64 (line 40) | func (t TtfInfo) PushMapIntInt64(key string, val map[int]int) {
method GetBool (line 44) | func (t TtfInfo) GetBool(key string) (bool, error) {
method GetString (line 58) | func (t TtfInfo) GetString(key string) (string, error) {
method GetInt64 (line 72) | func (t TtfInfo) GetInt64(key string) (int, error) {
method GetInt64s (line 86) | func (t TtfInfo) GetInt64s(key string) ([]int, error) {
method GetMapIntInt64 (line 100) | func (t TtfInfo) GetMapIntInt64(key string) (map[int]int, error) {
function NewTtfInfo (line 114) | func NewTtfInfo() TtfInfo {
FILE: vendor/github.com/signintech/gopdf/fontmaker/core/ttfparser.go
type TTFParser (line 24) | type TTFParser struct
method Kern (line 88) | func (t *TTFParser) Kern() *KernTable {
method UnderlinePosition (line 93) | func (t *TTFParser) UnderlinePosition() int {
method GroupingTables (line 98) | func (t *TTFParser) GroupingTables() []CmapFormat12GroupingTable {
method UnderlineThickness (line 103) | func (t *TTFParser) UnderlineThickness() int {
method XHeight (line 107) | func (t *TTFParser) XHeight() int {
method XMin (line 115) | func (t *TTFParser) XMin() int {
method YMin (line 119) | func (t *TTFParser) YMin() int {
method XMax (line 123) | func (t *TTFParser) XMax() int {
method YMax (line 127) | func (t *TTFParser) YMax() int {
method ItalicAngle (line 131) | func (t *TTFParser) ItalicAngle() int {
method Flag (line 135) | func (t *TTFParser) Flag() int {
method Ascender (line 145) | func (t *TTFParser) Ascender() int {
method Descender (line 152) | func (t *TTFParser) Descender() int {
method TypoAscender (line 163) | func (t *TTFParser) TypoAscender() int {
method TypoDescender (line 167) | func (t *TTFParser) TypoDescender() int {
method CapHeight (line 172) | func (t *TTFParser) CapHeight() int {
method NumGlyphs (line 177) | func (t *TTFParser) NumGlyphs() uint {
method UnitsPerEm (line 181) | func (t *TTFParser) UnitsPerEm() uint {
method NumberOfHMetrics (line 185) | func (t *TTFParser) NumberOfHMetrics() uint {
method Widths (line 189) | func (t *TTFParser) Widths() []uint {
method Chars (line 193) | func (t *TTFParser) Chars() map[int]uint {
method GetTables (line 197) | func (t *TTFParser) GetTables() map[string]TableDirectoryEntry {
method SetUseKerning (line 202) | func (t *TTFParser) SetUseKerning(use bool) {
method Parse (line 207) | func (t *TTFParser) Parse(filepath string) error {
method ParseByReader (line 216) | func (t *TTFParser) ParseByReader(rd io.Reader) error {
method ParseFontData (line 226) | func (t *TTFParser) ParseFontData(fontData []byte) error {
method FontData (line 326) | func (t *TTFParser) FontData() []byte {
method ParseLoca (line 331) | func (t *TTFParser) ParseLoca(fd *bytes.Reader) error {
method ParsePost (line 374) | func (t *TTFParser) ParsePost(fd *bytes.Reader) error {
method ParseOS2 (line 419) | func (t *TTFParser) ParseOS2(fd *bytes.Reader) error {
method ParseName (line 503) | func (t *TTFParser) ParseName(fd *bytes.Reader) error {
method PregReplace (line 586) | func (t *TTFParser) PregReplace(pattern string, replacement string, su...
method ParseCmap (line 597) | func (t *TTFParser) ParseCmap(fd *bytes.Reader) error {
method FTell (line 779) | func (t *TTFParser) FTell(fd *bytes.Reader) (uint, error) {
method ParseHmtx (line 785) | func (t *TTFParser) ParseHmtx(fd *bytes.Reader) error {
method ArrayPadUint (line 813) | func (t *TTFParser) ArrayPadUint(arr []uint, size uint, val uint) ([]u...
method ParseHead (line 829) | func (t *TTFParser) ParseHead(fd *bytes.Reader) error {
method ParseHhea (line 900) | func (t *TTFParser) ParseHhea(fd *bytes.Reader) error {
method ParseMaxp (line 936) | func (t *TTFParser) ParseMaxp(fd *bytes.Reader) error {
method Seek (line 956) | func (t *TTFParser) Seek(fd *bytes.Reader, tag string) error {
method BytesToString (line 970) | func (t *TTFParser) BytesToString(b []byte) string {
method ReadUShort (line 975) | func (t *TTFParser) ReadUShort(fd *bytes.Reader) (uint, error) {
method ReadShort (line 985) | func (t *TTFParser) ReadShort(fd *bytes.Reader) (int, error) {
method ReadShortInt16 (line 1002) | func (t *TTFParser) ReadShortInt16(fd *bytes.Reader) (int16, error) {
method ReadULong (line 1011) | func (t *TTFParser) ReadULong(fd *bytes.Reader) (uint, error) {
method Skip (line 1022) | func (t *TTFParser) Skip(fd *bytes.Reader, length int) error {
method Read (line 1031) | func (t *TTFParser) Read(fd *bytes.Reader, length int) ([]byte, error) {
FILE: vendor/github.com/signintech/gopdf/fontmaker/core/ttfparser_cmap_other_format.go
method ParseCmapFormat12 (line 9) | func (t *TTFParser) ParseCmapFormat12(fd *bytes.Reader) (bool, error) {
type cmapFormat12EncodingSubtable (line 119) | type cmapFormat12EncodingSubtable struct
type CmapFormat12GroupingTable (line 125) | type CmapFormat12GroupingTable struct
FILE: vendor/github.com/signintech/gopdf/fontmaker/core/ttfparser_kern.go
method Parsekern (line 9) | func (t *TTFParser) Parsekern(fd *bytes.Reader) error {
method parsekernSubTable (line 45) | func (t *TTFParser) parsekernSubTable(fd *bytes.Reader) error {
method parsekernSubTableFormat0 (line 67) | func (t *TTFParser) parsekernSubTableFormat0(fd *bytes.Reader) error {
FILE: vendor/github.com/signintech/gopdf/func_kern_override.go
type FuncKernOverride (line 4) | type FuncKernOverride
FILE: vendor/github.com/signintech/gopdf/gopdf.go
constant subsetFont (line 21) | subsetFont = "SubsetFont"
constant defaultMargin (line 24) | defaultMargin = 10.0
type GoPdf (line 27) | type GoPdf struct
method SetLineWidth (line 119) | func (gp *GoPdf) SetLineWidth(width float64) {
method SetCompressLevel (line 130) | func (gp *GoPdf) SetCompressLevel(level int) {
method SetNoCompression (line 145) | func (gp *GoPdf) SetNoCompression() {
method SetLineType (line 155) | func (gp *GoPdf) SetLineType(linetype string) {
method Line (line 160) | func (gp *GoPdf) Line(x1 float64, y1 float64, x2 float64, y2 float64) {
method RectFromLowerLeft (line 166) | func (gp *GoPdf) RectFromLowerLeft(x float64, y float64, wdth float64,...
method RectFromUpperLeft (line 180) | func (gp *GoPdf) RectFromUpperLeft(x float64, y float64, wdth float64,...
method RectFromLowerLeftWithStyle (line 198) | func (gp *GoPdf) RectFromLowerLeftWithStyle(x float64, y float64, wdth...
method RectFromLowerLeftWithOpts (line 211) | func (gp *GoPdf) RectFromLowerLeftWithOpts(opts DrawableRectOptions) e...
method RectFromUpperLeftWithStyle (line 233) | func (gp *GoPdf) RectFromUpperLeftWithStyle(x float64, y float64, wdth...
method RectFromUpperLeftWithOpts (line 246) | func (gp *GoPdf) RectFromUpperLeftWithOpts(opts DrawableRectOptions) e...
method Oval (line 266) | func (gp *GoPdf) Oval(x1 float64, y1 float64, x2 float64, y2 float64) {
method Br (line 272) | func (gp *GoPdf) Br(h float64) {
method SetGrayFill (line 279) | func (gp *GoPdf) SetGrayFill(grayScale float64) {
method SetGrayStroke (line 286) | func (gp *GoPdf) SetGrayStroke(grayScale float64) {
method SetX (line 292) | func (gp *GoPdf) SetX(x float64) {
method GetX (line 299) | func (gp *GoPdf) GetX() float64 {
method SetY (line 304) | func (gp *GoPdf) SetY(y float64) {
method GetY (line 310) | func (gp *GoPdf) GetY() float64 {
method ImageByHolder (line 315) | func (gp *GoPdf) ImageByHolder(img ImageHolder, x float64, y float64, ...
method ImageByHolderWithOptions (line 329) | func (gp *GoPdf) ImageByHolderWithOptions(img ImageHolder, opts ImageO...
method maskHolder (line 367) | func (gp *GoPdf) maskHolder(img ImageHolder, opts ImageOptions) (int, ...
method createTransparencyXObjectGroup (line 434) | func (gp *GoPdf) createTransparencyXObjectGroup(image *cacheContentIma...
method imageByHolder (line 470) | func (gp *GoPdf) imageByHolder(img ImageHolder, opts ImageOptions) err...
method Image (line 553) | func (gp *GoPdf) Image(picPath string, x float64, y float64, rect *Rec...
method ImageFrom (line 570) | func (gp *GoPdf) ImageFrom(img image.Image, x float64, y float64, rect...
method AddPage (line 600) | func (gp *GoPdf) AddPage() {
method AddPageWithOption (line 606) | func (gp *GoPdf) AddPageWithOption(opt PageOption) {
method AddOutline (line 641) | func (gp *GoPdf) AddOutline(title string) {
method Start (line 646) | func (gp *GoPdf) Start(config Config) {
method SetFontWithStyle (line 683) | func (gp *GoPdf) SetFontWithStyle(family string, style int, size int) ...
method SetFont (line 715) | func (gp *GoPdf) SetFont(family string, style string, size int) error {
method WritePdf (line 720) | func (gp *GoPdf) WritePdf(pdfPath string) error {
method Write (line 724) | func (gp *GoPdf) Write(w io.Writer) error {
method Read (line 728) | func (gp *GoPdf) Read(p []byte) (int, error) {
method Close (line 738) | func (gp *GoPdf) Close() error {
method compilePdf (line 743) | func (gp *GoPdf) compilePdf(w io.Writer) error {
method GetBytesPdfReturnErr (line 787) | func (gp *GoPdf) GetBytesPdfReturnErr() ([]byte, error) {
method GetBytesPdf (line 797) | func (gp *GoPdf) GetBytesPdf() []byte {
method Text (line 806) | func (gp *GoPdf) Text(text string) error {
method CellWithOption (line 822) | func (gp *GoPdf) CellWithOption(rectangle *Rect, text string, opt Cell...
method Cell (line 845) | func (gp *GoPdf) Cell(rectangle *Rect, text string) error {
method MultiCell (line 866) | func (gp *GoPdf) MultiCell(rectangle *Rect, text string) error {
method SplitText (line 908) | func (gp *GoPdf) SplitText(text string, width float64) ([]string, erro...
method ImportPage (line 948) | func (gp *GoPdf) ImportPage(sourceFile string, pageno int, box string)...
method ImportPageStream (line 982) | func (gp *GoPdf) ImportPageStream(sourceStream *io.ReadSeeker, pageno ...
method UseImportedTemplate (line 1014) | func (gp *GoPdf) UseImportedTemplate(tplid int, x float64, y float64, ...
method GetNextObjectID (line 1022) | func (gp *GoPdf) GetNextObjectID() int {
method GetNumberOfPages (line 1027) | func (gp *GoPdf) GetNumberOfPages() int {
method ImportObjects (line 1032) | func (gp *GoPdf) ImportObjects(objs map[int]string, startObjID int) {
method ImportTemplates (line 1041) | func (gp *GoPdf) ImportTemplates(tpls map[string]int) {
method AddExternalLink (line 1049) | func (gp *GoPdf) AddExternalLink(url string, x, y, w, h float64) {
method AddInternalLink (line 1056) | func (gp *GoPdf) AddInternalLink(anchor string, x, y, w, h float64) {
method SetAnchor (line 1063) | func (gp *GoPdf) SetAnchor(name string) {
method AddTTFFontData (line 1069) | func (gp *GoPdf) AddTTFFontData(family string, fontData []byte) error {
method AddTTFFontDataWithOption (line 1074) | func (gp *GoPdf) AddTTFFontDataWithOption(family string, fontData []by...
method AddTTFFontByReader (line 1090) | func (gp *GoPdf) AddTTFFontByReader(family string, rd io.Reader) error {
method AddTTFFontByReaderWithOption (line 1095) | func (gp *GoPdf) AddTTFFontByReaderWithOption(family string, rd io.Rea...
method setSubsetFontObject (line 1112) | func (gp *GoPdf) setSubsetFontObject(subsetFont *SubsetFontObj, family...
method AddTTFFontWithOption (line 1161) | func (gp *GoPdf) AddTTFFontWithOption(family string, ttfpath string, o...
method AddTTFFont (line 1175) | func (gp *GoPdf) AddTTFFont(family string, ttfpath string) error {
method KernOverride (line 1180) | func (gp *GoPdf) KernOverride(family string, fn FuncKernOverride) error {
method SetTextColor (line 1200) | func (gp *GoPdf) SetTextColor(r uint8, g uint8, b uint8) {
method SetStrokeColor (line 1211) | func (gp *GoPdf) SetStrokeColor(r uint8, g uint8, b uint8) {
method SetFillColor (line 1216) | func (gp *GoPdf) SetFillColor(r uint8, g uint8, b uint8) {
method MeasureTextWidth (line 1221) | func (gp *GoPdf) MeasureTextWidth(text string) (float64, error) {
method Curve (line 1242) | func (gp *GoPdf) Curve(x0 float64, y0 float64, x1 float64, y1 float64,...
method SetInfo (line 1255) | func (gp *GoPdf) SetInfo(info PdfInfo) {
method Rotate (line 1263) | func (gp *GoPdf) Rotate(angle, x, y float64) {
method RotateReset (line 1269) | func (gp *GoPdf) RotateReset() {
method Polygon (line 1283) | func (gp *GoPdf) Polygon(points []Point, style string) {
method init (line 1297) | func (gp *GoPdf) init() {
method resetCurrXY (line 1340) | func (gp *GoPdf) resetCurrXY() {
method UnitsToPoints (line 1346) | func (gp *GoPdf) UnitsToPoints(u float64) float64 {
method UnitsToPointsVar (line 1351) | func (gp *GoPdf) UnitsToPointsVar(u ...*float64) {
method PointsToUnits (line 1356) | func (gp *GoPdf) PointsToUnits(u float64) float64 {
method PointsToUnitsVar (line 1361) | func (gp *GoPdf) PointsToUnitsVar(u ...*float64) {
method isUseProtection (line 1365) | func (gp *GoPdf) isUseProtection() bool {
method createProtection (line 1369) | func (gp *GoPdf) createProtection() *PDFProtection {
method protection (line 1379) | func (gp *GoPdf) protection() *PDFProtection {
method prepare (line 1383) | func (gp *GoPdf) prepare() {
method xref (line 1436) | func (gp *GoPdf) xref(w io.Writer, xrefbyteoffset int, linelens []int,...
method writeInfo (line 1467) | func (gp *GoPdf) writeInfo(w io.Writer) {
method formatXrefline (line 1499) | func (gp *GoPdf) formatXrefline(n int) string {
method addObj (line 1507) | func (gp *GoPdf) addObj(iobj IObj) int {
method getContent (line 1513) | func (gp *GoPdf) getContent() *ContentObj {
method SetTransparency (line 1549) | func (gp *GoPdf) SetTransparency(transparency Transparency) error {
method getCachedTransparency (line 1560) | func (gp *GoPdf) getCachedTransparency(transparency *Transparency) (*T...
method saveTransparency (line 1575) | func (gp *GoPdf) saveTransparency(transparency *Transparency) (*Transp...
method IsCurrFontContainGlyph (line 1604) | func (gp *GoPdf) IsCurrFontContainGlyph(r rune) (bool, error) {
type DrawableRectOptions (line 83) | type DrawableRectOptions struct
type CropOptions (line 93) | type CropOptions struct
type ImageOptions (line 100) | type ImageOptions struct
type MaskOptions (line 113) | type MaskOptions struct
type countingWriter (line 770) | type countingWriter struct
method Write (line 780) | func (cw *countingWriter) Write(b []byte) (int, error) {
function newCountingWriter (line 776) | func newCountingWriter(w io.Writer) *countingWriter {
function encodeUtf8 (line 1527) | func encodeUtf8(str string) string {
function infodate (line 1539) | func infodate(t time.Time) string {
FILE: vendor/github.com/signintech/gopdf/i_cache_contneter.go
type ICacheContent (line 7) | type ICacheContent interface
FILE: vendor/github.com/signintech/gopdf/ifont.go
type IFont (line 4) | type IFont interface
type FontCw (line 21) | type FontCw
type FontDescItem (line 24) | type FontDescItem struct
function ToByte (line 35) | func ToByte(chr string) byte {
FILE: vendor/github.com/signintech/gopdf/image_holder.go
type ImageHolder (line 12) | type ImageHolder interface
function ImageHolderByBytes (line 18) | func ImageHolderByBytes(b []byte) (ImageHolder, error) {
function ImageHolderByPath (line 23) | func ImageHolderByPath(path string) (ImageHolder, error) {
function ImageHolderByReader (line 28) | func ImageHolderByReader(r io.Reader) (ImageHolder, error) {
type imageBuff (line 33) | type imageBuff struct
method ID (line 79) | func (i *imageBuff) ID() string {
function newImageBuff (line 38) | func newImageBuff(b []byte) (*imageBuff, error) {
function newImageBuffByPath (line 50) | func newImageBuffByPath(path string) (*imageBuff, error) {
function newImageBuffByReader (line 61) | func newImageBuffByReader(r io.Reader) (*imageBuff, error) {
FILE: vendor/github.com/signintech/gopdf/image_obj.go
type ImageObj (line 19) | type ImageObj struct
method init (line 29) | func (i *ImageObj) init(funcGetRoot func() *GoPdf) {
method setProtection (line 33) | func (i *ImageObj) setProtection(p *PDFProtection) {
method protection (line 37) | func (i *ImageObj) protection() *PDFProtection {
method write (line 41) | func (i *ImageObj) write(w io.Writer, objID int) error {
method isColspaceIndexed (line 88) | func (i *ImageObj) isColspaceIndexed() bool {
method haveSMask (line 92) | func (i *ImageObj) haveSMask() bool {
method createSMask (line 96) | func (i *ImageObj) createSMask() (*SMask, error) {
method createDeviceRGB (line 109) | func (i *ImageObj) createDeviceRGB() (*DeviceRGBObj, error) {
method getType (line 115) | func (i *ImageObj) getType() string {
method SetImagePath (line 120) | func (i *ImageObj) SetImagePath(path string) error {
method SetImage (line 136) | func (i *ImageObj) SetImage(r io.Reader) error {
method GetRect (line 148) | func (i *ImageObj) GetRect() *Rect {
method getRect (line 158) | func (i *ImageObj) getRect() (*Rect, error) {
method parse (line 190) | func (i *ImageObj) parse() error {
method Parse (line 203) | func (i *ImageObj) Parse() error {
FILE: vendor/github.com/signintech/gopdf/image_obj_parse.go
type ColorSpaces (line 16) | type ColorSpaces
constant DeviceGray (line 19) | DeviceGray = "DeviceGray"
function writeMaskImgProps (line 22) | func writeMaskImgProps(w io.Writer, imginfo imgInfo) error {
function writeImgProps (line 41) | func writeImgProps(w io.Writer, imginfo imgInfo, splittedMask bool) error {
function writeBaseImgProps (line 83) | func writeBaseImgProps(w io.Writer, imginfo imgInfo, colorSpace string) ...
function isColspaceIndexed (line 113) | func isColspaceIndexed(imginfo imgInfo) bool {
function haveSMask (line 120) | func haveSMask(imginfo imgInfo) bool {
function parseImgByPath (line 127) | func parseImgByPath(path string) (imgInfo, error) {
function parseImg (line 135) | func parseImg(raw *bytes.Reader) (imgInfo, error) {
function parseImgJpg (line 169) | func parseImgJpg(info *imgInfo, imgConfig image.Config) error {
function parsePng (line 192) | func parsePng(f *bytes.Reader, info *imgInfo, imgConfig image.Config) er...
function compress (line 448) | func compress(data []byte) ([]byte, error) {
function readUInt (line 464) | func readUInt(f *bytes.Reader) (uint, error) {
function readInt (line 474) | func readInt(f *bytes.Reader) (int, error) {
function readBytes (line 489) | func readBytes(f *bytes.Reader, len int) ([]byte, error) {
function isDeviceRGB (line 498) | func isDeviceRGB(formatname string, img *image.Image) bool {
function ImgReactagleToWH (line 508) | func ImgReactagleToWH(imageRect image.Rectangle) (float64, float64) {
FILE: vendor/github.com/signintech/gopdf/img_info.go
type imgInfo (line 3) | type imgInfo struct
FILE: vendor/github.com/signintech/gopdf/imported_obj.go
type ImportedObj (line 8) | type ImportedObj struct
method init (line 12) | func (c *ImportedObj) init(funcGetRoot func() *GoPdf) {
method getType (line 16) | func (c *ImportedObj) getType() string {
method write (line 20) | func (c *ImportedObj) write(w io.Writer, objID int) error {
FILE: vendor/github.com/signintech/gopdf/iobj.go
type IObj (line 8) | type IObj interface
FILE: vendor/github.com/signintech/gopdf/link_option.go
type anchorOption (line 3) | type anchorOption struct
type linkOption (line 8) | type linkOption struct
FILE: vendor/github.com/signintech/gopdf/list_cache_content.go
type listCacheContent (line 5) | type listCacheContent struct
method last (line 9) | func (l *listCacheContent) last() ICacheContent {
method append (line 17) | func (l *listCacheContent) append(cache ICacheContent) {
method appendContentText (line 21) | func (l *listCacheContent) appendContentText(cache cacheContentText, t...
method write (line 62) | func (l *listCacheContent) write(w io.Writer, protection *PDFProtectio...
FILE: vendor/github.com/signintech/gopdf/map_of_character_To_glyph_index.go
type MapOfCharacterToGlyphIndex (line 4) | type MapOfCharacterToGlyphIndex struct
method KeyExists (line 18) | func (m *MapOfCharacterToGlyphIndex) KeyExists(k rune) bool {
method Set (line 31) | func (m *MapOfCharacterToGlyphIndex) Set(k rune, v uint) {
method Index (line 38) | func (m *MapOfCharacterToGlyphIndex) Index(k rune) (int, bool) {
method Val (line 51) | func (m *MapOfCharacterToGlyphIndex) Val(k rune) (uint, bool) {
method AllKeys (line 60) | func (m *MapOfCharacterToGlyphIndex) AllKeys() []rune {
method AllVals (line 65) | func (m *MapOfCharacterToGlyphIndex) AllVals() []uint {
function NewMapOfCharacterToGlyphIndex (line 11) | func NewMapOfCharacterToGlyphIndex() *MapOfCharacterToGlyphIndex {
FILE: vendor/github.com/signintech/gopdf/margin.go
type Margins (line 4) | type Margins struct
method SetLeftMargin (line 9) | func (gp *GoPdf) SetLeftMargin(margin float64) {
method SetTopMargin (line 15) | func (gp *GoPdf) SetTopMargin(margin float64) {
method SetMargins (line 21) | func (gp *GoPdf) SetMargins(left, top, right, bottom float64) {
method SetMarginLeft (line 27) | func (gp *GoPdf) SetMarginLeft(margin float64) {
method SetMarginTop (line 32) | func (gp *GoPdf) SetMarginTop(margin float64) {
method SetMarginRight (line 37) | func (gp *GoPdf) SetMarginRight(margin float64) {
method SetMarginBottom (line 42) | func (gp *GoPdf) SetMarginBottom(margin float64) {
method Margins (line 47) | func (gp *GoPdf) Margins() (float64, float64, float64, float64) {
method MarginLeft (line 55) | func (gp *GoPdf) MarginLeft() float64 {
method MarginTop (line 60) | func (gp *GoPdf) MarginTop() float64 {
method MarginRight (line 65) | func (gp *GoPdf) MarginRight() float64 {
method MarginBottom (line 70) | func (gp *GoPdf) MarginBottom() float64 {
FILE: vendor/github.com/signintech/gopdf/outlines_obj.go
type OutlinesObj (line 9) | type OutlinesObj struct
method init (line 19) | func (o *OutlinesObj) init(funcGetRoot func() *GoPdf) {
method getType (line 25) | func (o *OutlinesObj) getType() string {
method write (line 29) | func (o *OutlinesObj) write(w io.Writer, objID int) error {
method SetIndexObjOutlines (line 51) | func (o *OutlinesObj) SetIndexObjOutlines(index int) {
method AddOutline (line 55) | func (o *OutlinesObj) AddOutline(dest int, title string) {
method Count (line 68) | func (o *OutlinesObj) Count() int {
type OutlineObj (line 72) | type OutlineObj struct
method init (line 81) | func (o *OutlineObj) init(funcGetRoot func() *GoPdf) {
method getType (line 84) | func (o *OutlineObj) getType() string {
method write (line 88) | func (o *OutlineObj) write(w io.Writer, objID int) error {
FILE: vendor/github.com/signintech/gopdf/page_obj.go
type PageObj (line 10) | type PageObj struct
method init (line 18) | func (p *PageObj) init(funcGetRoot func() *GoPdf) {
method setOption (line 23) | func (p *PageObj) setOption(opt PageOption) {
method write (line 27) | func (p *PageObj) write(w io.Writer, objID int) error {
method writeExternalLink (line 72) | func (p *PageObj) writeExternalLink(w io.Writer, l linkOption, objID i...
method writeInternalLink (line 92) | func (p *PageObj) writeInternalLink(w io.Writer, l linkOption, anchors...
method getType (line 102) | func (p *PageObj) getType() string {
FILE: vendor/github.com/signintech/gopdf/page_option.go
type PageOption (line 4) | type PageOption struct
method isEmpty (line 9) | func (p PageOption) isEmpty() bool {
method isTrimBoxSet (line 16) | func (p PageOption) isTrimBoxSet() bool {
FILE: vendor/github.com/signintech/gopdf/pages_obj.go
type PagesObj (line 9) | type PagesObj struct
method init (line 15) | func (p *PagesObj) init(funcGetRoot func() *GoPdf) {
method write (line 20) | func (p *PagesObj) write(w io.Writer, objID int) error {
method getType (line 33) | func (p *PagesObj) getType() string {
method test (line 37) | func (p *PagesObj) test() {
FILE: vendor/github.com/signintech/gopdf/pdf_dictionary_obj.go
type PdfDictionaryObj (line 26) | type PdfDictionaryObj struct
method init (line 32) | func (p *PdfDictionaryObj) init(funcGetRoot func() *GoPdf) {
method setProtection (line 36) | func (p *PdfDictionaryObj) setProtection(pr *PDFProtection) {
method protection (line 40) | func (p *PdfDictionaryObj) protection() *PDFProtection {
method write (line 44) | func (p *PdfDictionaryObj) write(w io.Writer, objID int) error {
method getType (line 82) | func (p *PdfDictionaryObj) getType() string {
method SetPtrToSubsetFontObj (line 87) | func (p *PdfDictionaryObj) SetPtrToSubsetFontObj(ptr *SubsetFontObj) {
method makeGlyfAndLocaTable (line 91) | func (p *PdfDictionaryObj) makeGlyfAndLocaTable() ([]byte, []int, erro...
method getGlyphSize (line 145) | func (p *PdfDictionaryObj) getGlyphSize(glyph int) int {
method getGlyphData (line 154) | func (p *PdfDictionaryObj) getGlyphData(glyph int) []byte {
method makeFont (line 169) | func (p *PdfDictionaryObj) makeFont() ([]byte, error) {
method completeGlyphClosure (line 266) | func (p *PdfDictionaryObj) completeGlyphClosure(mapOfglyphs *MapOfChar...
method AddCompositeGlyphs (line 292) | func (p *PdfDictionaryObj) AddCompositeGlyphs(glyphArray *[]int, glyph...
method GetOffset (line 351) | func (p *PdfDictionaryObj) GetOffset(glyph int) int {
constant hasScale (line 344) | hasScale = 8
constant moreComponents (line 345) | moreComponents = 32
constant arg1and2areWords (line 346) | arg1and2areWords = 1
constant xAndYScale (line 347) | xAndYScale = 64
constant twoByTwo (line 348) | twoByTwo = 128
function CheckSum (line 359) | func CheckSum(data []byte) uint {
FILE: vendor/github.com/signintech/gopdf/pdf_info_obj.go
type PdfInfo (line 6) | type PdfInfo struct
FILE: vendor/github.com/signintech/gopdf/pdf_protection.go
constant PermissionsPrint (line 13) | PermissionsPrint = 4
constant PermissionsModify (line 15) | PermissionsModify = 8
constant PermissionsCopy (line 17) | PermissionsCopy = 16
constant PermissionsAnnotForms (line 19) | PermissionsAnnotForms = 32
type PDFProtection (line 28) | type PDFProtection struct
method SetProtection (line 38) | func (p *PDFProtection) SetProtection(permissions int, userPass []byte...
method setProtection (line 42) | func (p *PDFProtection) setProtection(permissions int, userPass []byte...
method generateEncryptionKey (line 50) | func (p *PDFProtection) generateEncryptionKey(userPass []byte, ownerPa...
method EncryptionObj (line 75) | func (p *PDFProtection) EncryptionObj() *EncryptionObj {
method encryptionObj (line 79) | func (p *PDFProtection) encryptionObj() *EncryptionObj {
method createOValue (line 87) | func (p *PDFProtection) createOValue(userPassWithPadding []byte, owner...
method createUValue (line 99) | func (p *PDFProtection) createUValue(userPassWithPadding []byte, oValu...
method randomPass (line 116) | func (p *PDFProtection) randomPass(strlen int) []byte {
method Objectkey (line 127) | func (p *PDFProtection) Objectkey(objID int) []byte {
method objectkey (line 131) | func (p *PDFProtection) objectkey(n int) []byte {
function rc4Cip (line 139) | func rc4Cip(key []byte, src []byte) ([]byte, error) {
FILE: vendor/github.com/signintech/gopdf/point.go
type Point (line 4) | type Point struct
FILE: vendor/github.com/signintech/gopdf/procset_obj.go
type ProcSetObj (line 9) | type ProcSetObj struct
method init (line 18) | func (pr *ProcSetObj) init(funcGetRoot func() *GoPdf) {
method write (line 24) | func (pr *ProcSetObj) write(w io.Writer, objID int) error {
method getType (line 65) | func (pr *ProcSetObj) getType() string {
type RelateFonts (line 70) | type RelateFonts
method IsContainsFamily (line 73) | func (re *RelateFonts) IsContainsFamily(family string) bool {
method IsContainsFamilyAndStyle (line 83) | func (re *RelateFonts) IsContainsFamilyAndStyle(family string, style i...
type RelateFont (line 93) | type RelateFont struct
type RelateXobjects (line 103) | type RelateXobjects
type RelateXobject (line 106) | type RelateXobject struct
type ExtGS (line 111) | type ExtGS struct
FILE: vendor/github.com/signintech/gopdf/rect.go
type Rect (line 4) | type Rect struct
method PointsToUnits (line 11) | func (rect *Rect) PointsToUnits(t int) (r *Rect) {
method UnitsToPoints (line 26) | func (rect *Rect) UnitsToPoints(t int) (r *Rect) {
FILE: vendor/github.com/signintech/gopdf/smask_obj.go
type SMaskSubtypes (line 9) | type SMaskSubtypes
constant SMaskAlphaSubtype (line 12) | SMaskAlphaSubtype = "/Alpha"
constant SMaskLuminositySubtype (line 13) | SMaskLuminositySubtype = "/Luminosity"
type SMask (line 17) | type SMask struct
method init (line 53) | func (s SMask) init(func() *GoPdf) {}
method setProtection (line 55) | func (s *SMask) setProtection(p *PDFProtection) {
method protection (line 59) | func (s SMask) protection() *PDFProtection {
method getType (line 63) | func (s SMask) getType() string {
method write (line 67) | func (s SMask) write(w io.Writer, objID int) error {
type SMaskOptions (line 27) | type SMaskOptions struct
method GetId (line 32) | func (smask SMaskOptions) GetId() string {
function GetCachedMask (line 38) | func GetCachedMask(opts SMaskOptions, gp *GoPdf) SMask {
type SMaskMap (line 102) | type SMaskMap struct
method Find (line 114) | func (smask *SMaskMap) Find(sMask SMaskOptions) (SMask, bool) {
method Save (line 129) | func (smask *SMaskMap) Save(id string, sMask SMask) SMask {
function NewSMaskMap (line 107) | func NewSMaskMap() SMaskMap {
FILE: vendor/github.com/signintech/gopdf/strhelper.go
function StrHelperGetStringWidth (line 9) | func StrHelperGetStringWidth(str string, fontSize int, ifont IFont) floa...
function CreateEmbeddedFontSubsetName (line 22) | func CreateEmbeddedFontSubsetName(name string) string {
function ReadShortFromByte (line 29) | func ReadShortFromByte(data []byte, offset int) (int64, int) {
function ReadUShortFromByte (line 44) | func ReadUShortFromByte(data []byte, offset int) (uint64, int) {
FILE: vendor/github.com/signintech/gopdf/style.go
type PaintStyle (line 3) | type PaintStyle
constant DrawPaintStyle (line 6) | DrawPaintStyle PaintStyle = "S"
constant FillPaintStyle (line 7) | FillPaintStyle PaintStyle = "f"
constant DrawFillPaintStyle (line 8) | DrawFillPaintStyle PaintStyle = "B"
function parseStyle (line 11) | func parseStyle(style string) PaintStyle {
FILE: vendor/github.com/signintech/gopdf/subfont_descriptor_obj.go
type SubfontDescriptorObj (line 11) | type SubfontDescriptorObj struct
method init (line 16) | func (s *SubfontDescriptorObj) init(func() *GoPdf) {}
method getType (line 18) | func (s *SubfontDescriptorObj) getType() string {
method write (line 22) | func (s *SubfontDescriptorObj) write(w io.Writer, objID int) error {
method SetIndexObjPdfDictionary (line 47) | func (s *SubfontDescriptorObj) SetIndexObjPdfDictionary(index int) {
method SetPtrToSubsetFontObj (line 52) | func (s *SubfontDescriptorObj) SetPtrToSubsetFontObj(ptr *SubsetFontOb...
function DesignUnitsToPdf (line 57) | func DesignUnitsToPdf(val int, unitsPerEm uint) int {
FILE: vendor/github.com/signintech/gopdf/subset_font_obj.go
type SubsetFontObj (line 18) | type SubsetFontObj struct
method init (line 29) | func (s *SubsetFontObj) init(funcGetRoot func() *GoPdf) {
method write (line 34) | func (s *SubsetFontObj) write(w io.Writer, objID int) error {
method SetIndexObjCIDFont (line 48) | func (s *SubsetFontObj) SetIndexObjCIDFont(index int) {
method SetIndexObjUnicodeMap (line 53) | func (s *SubsetFontObj) SetIndexObjUnicodeMap(index int) {
method SetFamily (line 58) | func (s *SubsetFontObj) SetFamily(familyname string) {
method GetFamily (line 63) | func (s *SubsetFontObj) GetFamily() string {
method SetTtfFontOption (line 68) | func (s *SubsetFontObj) SetTtfFontOption(option TtfOption) {
method GetTtfFontOption (line 73) | func (s *SubsetFontObj) GetTtfFontOption() TtfOption {
method KernValueByLeft (line 78) | func (s *SubsetFontObj) KernValueByLeft(left uint) (bool, *core.KernVa...
method SetTTFByPath (line 97) | func (s *SubsetFontObj) SetTTFByPath(ttfpath string) error {
method SetTTFByReader (line 108) | func (s *SubsetFontObj) SetTTFByReader(rd io.Reader) error {
method SetTTFData (line 119) | func (s *SubsetFontObj) SetTTFData(data []byte) error {
method AddChars (line 130) | func (s *SubsetFontObj) AddChars(txt string) error {
method CharIndex (line 150) | func (s *SubsetFontObj) CharIndex(r rune) (uint, error) {
method CharWidth (line 159) | func (s *SubsetFontObj) CharWidth(r rune) (uint, error) {
method getType (line 167) | func (s *SubsetFontObj) getType() string {
method charCodeToGlyphIndexFormat12 (line 171) | func (s *SubsetFontObj) charCodeToGlyphIndexFormat12(r rune) (uint, er...
method charCodeToGlyphIndexFormat4 (line 185) | func (s *SubsetFontObj) charCodeToGlyphIndexFormat4(r rune) (uint, err...
method CharCodeToGlyphIndex (line 215) | func (s *SubsetFontObj) CharCodeToGlyphIndex(r rune) (uint, error) {
method GlyphIndexToPdfWidth (line 232) | func (s *SubsetFontObj) GlyphIndexToPdfWidth(glyphIndex uint) uint {
method GetTTFParser (line 248) | func (s *SubsetFontObj) GetTTFParser() *core.TTFParser {
method GetUt (line 253) | func (s *SubsetFontObj) GetUt() int {
method GetUp (line 258) | func (s *SubsetFontObj) GetUp() int {
FILE: vendor/github.com/signintech/gopdf/transparency.go
type BlendModeType (line 10) | type BlendModeType
constant Hue (line 13) | Hue BlendModeType = "/Hue"
constant Color (line 14) | Color BlendModeType = "/Color"
constant NormalBlendMode (line 15) | NormalBlendMode BlendModeType = "/Normal"
constant Darken (line 16) | Darken BlendModeType = "/Darken"
constant Screen (line 17) | Screen BlendModeType = "/Screen"
constant Overlay (line 18) | Overlay BlendModeType = "/Overlay"
constant Lighten (line 19) | Lighten BlendModeType = "/Lighten"
constant Multiply (line 20) | Multiply BlendModeType = "/Multiply"
constant Exclusion (line 21) | Exclusion BlendModeType = "/Exclusion"
constant ColorBurn (line 22) | ColorBurn BlendModeType = "/ColorBurn"
constant HardLight (line 23) | HardLight BlendModeType = "/HardLight"
constant SoftLight (line 24) | SoftLight BlendModeType = "/SoftLight"
constant Difference (line 25) | Difference BlendModeType = "/Difference"
constant Saturation (line 26) | Saturation BlendModeType = "/Saturation"
constant Luminosity (line 27) | Luminosity BlendModeType = "/Luminosity"
constant ColorDodge (line 28) | ColorDodge BlendModeType = "/ColorDodge"
constant DefaultAplhaValue (line 31) | DefaultAplhaValue = 1
type Transparency (line 34) | type Transparency struct
method GetId (line 56) | func (t Transparency) GetId() string {
function NewTransparency (line 40) | func NewTransparency(alpha float64, blendModeType string) (Transparency,...
type TransparencyMap (line 62) | type TransparencyMap struct
method Find (line 74) | func (tm *TransparencyMap) Find(transparency Transparency) (Transparen...
method Save (line 89) | func (tm *TransparencyMap) Save(transparency Transparency) Transparency {
function NewTransparencyMap (line 67) | func NewTransparencyMap() TransparencyMap {
function defineBlendModeType (line 99) | func defineBlendModeType(bmType string) (BlendModeType, error) {
FILE: vendor/github.com/signintech/gopdf/transparency_xobject_group.go
type TransparencyXObjectGroup (line 8) | type TransparencyXObjectGroup struct
method init (line 41) | func (s TransparencyXObjectGroup) init(funcGetRoot func() *GoPdf) {
method setProtection (line 45) | func (s *TransparencyXObjectGroup) setProtection(p *PDFProtection) {
method protection (line 49) | func (s TransparencyXObjectGroup) protection() *PDFProtection {
method getType (line 53) | func (s TransparencyXObjectGroup) getType() string {
method write (line 57) | func (s TransparencyXObjectGroup) write(w io.Writer, objId int) error {
type TransparencyXObjectGroupOptions (line 19) | type TransparencyXObjectGroupOptions struct
function GetCachedTransparencyXObjectGroup (line 26) | func GetCachedTransparencyXObjectGroup(opts TransparencyXObjectGroupOpti...
FILE: vendor/github.com/signintech/gopdf/ttf_option.go
type TtfOption (line 4) | type TtfOption struct
function defaultTtfFontOption (line 10) | func defaultTtfFontOption() TtfOption {
FILE: vendor/github.com/signintech/gopdf/unicode_map.go
type UnicodeMap (line 9) | type UnicodeMap struct
method init (line 15) | func (u *UnicodeMap) init(funcGetRoot func() *GoPdf) {
method setProtection (line 19) | func (u *UnicodeMap) setProtection(p *PDFProtection) {
method protection (line 23) | func (u *UnicodeMap) protection() *PDFProtection {
method SetPtrToSubsetFontObj (line 28) | func (u *UnicodeMap) SetPtrToSubsetFontObj(ptr *SubsetFontObj) {
method getType (line 32) | func (u *UnicodeMap) getType() string {
method write (line 36) | func (u *UnicodeMap) write(w io.Writer, objID int) error {
type mapGlyphIndexToCharacter (line 101) | type mapGlyphIndexToCharacter struct
method set (line 111) | func (m *mapGlyphIndexToCharacter) set(index int, r rune) {
method size (line 116) | func (m *mapGlyphIndexToCharacter) size() int {
method allIndexs (line 120) | func (m *mapGlyphIndexToCharacter) allIndexs() []int {
method runeByIndex (line 124) | func (m *mapGlyphIndexToCharacter) runeByIndex(index int) (rune, bool) {
function newMapGlyphIndexToCharacter (line 106) | func newMapGlyphIndexToCharacter() *mapGlyphIndexToCharacter {
Condensed preview — 108 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (346K chars).
[
{
"path": ".github/workflows/codeql-analysis.yml",
"chars": 2429,
"preview": "# For most projects, this workflow file will not need changing; you simply need\n# to commit it to your repository.\n#\n# Y"
},
{
"path": ".github/workflows/go.yml",
"chars": 357,
"preview": "name: Go\n\non:\n push:\n branches: [ main ]\n pull_request:\n branches: [ main ]\n\njobs:\n\n build:\n runs-on: ubuntu"
},
{
"path": ".github/workflows/golangci-lint.yml",
"chars": 314,
"preview": "name: golangci-lint\non:\n push:\n branches: [ main ]\n pull_request:\n branches: [ main ]\njobs:\n golangci:\n name"
},
{
"path": ".gitignore",
"chars": 72,
"preview": "# PDF files\n*.pdf\n\n# Test binary, built with `go test -c`\n*.test\n\n.idea/"
},
{
"path": "LICENSE",
"chars": 1069,
"preview": "MIT License\n\nCopyright (c) 2021 Leonid Sopov\n\nPermission is hereby granted, free of charge, to any person obtaining a co"
},
{
"path": "README.md",
"chars": 3487,
"preview": "# resumeio2pdf\n\n> ⚠️ This project is no longer maintained. \n> Resume.io made changes on their side, so the tool no long"
},
{
"path": "go.mod",
"chars": 91,
"preview": "module github.com/sopov/resumeio2pdf\n\ngo 1.16\n\nrequire github.com/signintech/gopdf v0.9.20\n"
},
{
"path": "go.sum",
"chars": 511,
"preview": "github.com/phpdave11/gofpdi v1.0.11 h1:wsBNx+3S0wy1dEp6fzv281S74ogZGgIdYWV2PugWgho=\ngithub.com/phpdave11/gofpdi v1.0.11/"
},
{
"path": "main.go",
"chars": 7297,
"preview": "package main\n\nimport (\n\t\"encoding/json\"\n\t\"errors\"\n\t\"flag\"\n\t\"fmt\"\n\t\"io\"\n\t\"log\"\n\t\"net/http\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"regex"
},
{
"path": "vendor/github.com/phpdave11/gofpdi/LICENSE",
"chars": 1151,
"preview": "The MIT License (MIT)\n\nCopyright (c) 2019-2020 David Barnes\nCopyright (c) 2017 Setasign - Jan Slabon, https://www.setasi"
},
{
"path": "vendor/github.com/phpdave11/gofpdi/README.md",
"chars": 6942,
"preview": "# gofpdi\n[](https://raw.githubusercontent.com/phpdave1"
},
{
"path": "vendor/github.com/phpdave11/gofpdi/const.go",
"chars": 251,
"preview": "package gofpdi\n\nconst (\n\tPDF_TYPE_NULL = iota\n\tPDF_TYPE_NUMERIC\n\tPDF_TYPE_TOKEN\n\tPDF_TYPE_HEX\n\tPDF_TYPE_STRING\n\tPDF_TYPE"
},
{
"path": "vendor/github.com/phpdave11/gofpdi/go.mod",
"chars": 82,
"preview": "module github.com/phpdave11/gofpdi\n\ngo 1.12\n\nrequire github.com/pkg/errors v0.8.1\n"
},
{
"path": "vendor/github.com/phpdave11/gofpdi/go.sum",
"chars": 161,
"preview": "github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=\ngithub.com/pkg/errors v0.8.1/go.mod h1:bwaw"
},
{
"path": "vendor/github.com/phpdave11/gofpdi/gofpdi.go",
"chars": 15,
"preview": "package gofpdi\n"
},
{
"path": "vendor/github.com/phpdave11/gofpdi/helper.go",
"chars": 2717,
"preview": "package gofpdi\n\nimport (\n\t\"strings\"\n)\n\n// Determine if a value is numeric\n// Courtesy of https://github.com/syyongx/php2"
},
{
"path": "vendor/github.com/phpdave11/gofpdi/importer.go",
"chars": 5629,
"preview": "package gofpdi\n\nimport (\n\t\"fmt\"\n\t\"io\"\n)\n\n// The Importer class to be used by a pdf generation library\ntype Importer stru"
},
{
"path": "vendor/github.com/phpdave11/gofpdi/reader.go",
"chars": 40612,
"preview": "package gofpdi\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"compress/zlib\"\n\t\"encoding/binary\"\n\t\"fmt\"\n\t\"github.com/pkg/errors\"\n\t\"io\"\n\t\"i"
},
{
"path": "vendor/github.com/phpdave11/gofpdi/writer.go",
"chars": 12785,
"preview": "package gofpdi\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"compress/zlib\"\n\t\"crypto/sha1\"\n\t\"encoding/hex\"\n\t\"fmt\"\n\t\"github.com/pkg/error"
},
{
"path": "vendor/github.com/pkg/errors/.gitignore",
"chars": 266,
"preview": "# Compiled Object files, Static and Dynamic libs (Shared Objects)\n*.o\n*.a\n*.so\n\n# Folders\n_obj\n_test\n\n# Architecture spe"
},
{
"path": "vendor/github.com/pkg/errors/.travis.yml",
"chars": 175,
"preview": "language: go\ngo_import_path: github.com/pkg/errors\ngo:\n - 1.4.x\n - 1.5.x\n - 1.6.x\n - 1.7.x\n - 1.8.x\n - 1.9.x\n - 1"
},
{
"path": "vendor/github.com/pkg/errors/LICENSE",
"chars": 1312,
"preview": "Copyright (c) 2015, Dave Cheney <dave@cheney.net>\nAll rights reserved.\n\nRedistribution and use in source and binary form"
},
{
"path": "vendor/github.com/pkg/errors/README.md",
"chars": 2371,
"preview": "# errors [](https://travis-ci.org/pkg/errors) [\n\n// Frame represents a program counter inside a st"
},
{
"path": "vendor/github.com/signintech/gopdf/.gitignore",
"chars": 717,
"preview": "##android\n# built application files\n*.apk\n*.ap_\n\n# files for the dex VM\n*.dex\n\n# Java class files\n*.class\n\n# generated f"
},
{
"path": "vendor/github.com/signintech/gopdf/Changelog.md",
"chars": 131,
"preview": "### May 2016\n\nRemove old function\n- ```GoPdf.AddFont(family string, ifont IFont, zfontpath string)```.\n- Remove all font"
},
{
"path": "vendor/github.com/signintech/gopdf/LICENSE",
"chars": 1078,
"preview": "The MIT License (MIT)\n\nCopyright (c) 2015 signintech\n\nPermission is hereby granted, free of charge, to any person obtain"
},
{
"path": "vendor/github.com/signintech/gopdf/README.md",
"chars": 7181,
"preview": "gopdf\n====\n\ngopdf is a simple library for generating PDF document written in Go lang.\n\n\n#### Features\n\n- Unicode subfont"
},
{
"path": "vendor/github.com/signintech/gopdf/box.go",
"chars": 532,
"preview": "package gopdf\n\ntype Box struct {\n\tLeft, Top, Right, Bottom float64\n\tunitOverride int\n}\n\n// UnitsToPoints con"
},
{
"path": "vendor/github.com/signintech/gopdf/buff.go",
"chars": 682,
"preview": "package gopdf\n\n//Buff for pdf content\ntype Buff struct {\n\tposition int\n\tdatas []byte\n}\n\n//Write : write []byte to buf"
},
{
"path": "vendor/github.com/signintech/gopdf/buff_write.go",
"chars": 930,
"preview": "package gopdf\n\nimport \"io\"\n\n//WriteUInt32 writes a 32-bit unsigned integer value to w io.Writer\nfunc WriteUInt32(w io.W"
},
{
"path": "vendor/github.com/signintech/gopdf/buffer_pool.go",
"chars": 435,
"preview": "package gopdf\n\nimport (\n\t\"bytes\"\n\t\"sync\"\n)\n\n// buffer pool to reduce GC\nvar buffers = sync.Pool{\n\t// New is called when "
},
{
"path": "vendor/github.com/signintech/gopdf/cache_contact_color.go",
"chars": 370,
"preview": "package gopdf\n\nimport (\n\t\"fmt\"\n\t\"io\"\n)\n\nconst colorTypeStroke = \"RG\"\n\nconst colorTypeFill = \"rg\"\n\ntype cacheContentColor"
},
{
"path": "vendor/github.com/signintech/gopdf/cache_content_gray.go",
"chars": 307,
"preview": "package gopdf\n\nimport (\n\t\"fmt\"\n\t\"io\"\n)\n\nconst grayTypeFill = \"g\"\nconst grayTypeStroke = \"G\"\n\ntype cacheContentGray struc"
},
{
"path": "vendor/github.com/signintech/gopdf/cache_content_image.go",
"chars": 1825,
"preview": "package gopdf\n\nimport (\n\t\"fmt\"\n\t\"io\"\n)\n\ntype cacheContentImage struct {\n\tverticalFlip bool\n\thorizontalFlip bool\n\ti"
},
{
"path": "vendor/github.com/signintech/gopdf/cache_content_imported_object.go",
"chars": 459,
"preview": "package gopdf\n\nimport (\n\t\"fmt\"\n\t\"io\"\n)\n\ntype cacheContentImportedTemplate struct {\n\tpageHeight float64\n\ttplName strin"
},
{
"path": "vendor/github.com/signintech/gopdf/cache_content_line.go",
"chars": 370,
"preview": "package gopdf\n\nimport (\n\t\"fmt\"\n\t\"io\"\n)\n\ntype cacheContentLine struct {\n\tpageHeight float64\n\tx1 float64\n\ty1 "
},
{
"path": "vendor/github.com/signintech/gopdf/cache_content_line_type.go",
"chars": 349,
"preview": "package gopdf\n\nimport (\n\t\"fmt\"\n\t\"io\"\n)\n\ntype cacheContentLineType struct {\n\tlineType string\n}\n\nfunc (c *cacheContentLine"
},
{
"path": "vendor/github.com/signintech/gopdf/cache_content_line_width.go",
"chars": 231,
"preview": "package gopdf\n\nimport (\n\t\"fmt\"\n\t\"io\"\n)\n\ntype cacheContentLineWidth struct {\n\twidth float64\n}\n\nfunc (c *cacheContentLineW"
},
{
"path": "vendor/github.com/signintech/gopdf/cache_content_oval.go",
"chars": 1243,
"preview": "package gopdf\n\nimport (\n\t\"fmt\"\n\t\"io\"\n)\n\ntype cacheContentOval struct {\n\tpageHeight float64\n\tx1 float64\n\ty1 "
},
{
"path": "vendor/github.com/signintech/gopdf/cache_content_polygon.go",
"chars": 572,
"preview": "package gopdf\n\nimport (\n\t\"fmt\"\n\t\"io\"\n)\n\ntype cacheContentPolygon struct {\n\tpageHeight float64\n\tstyle string\n\tpoints"
},
{
"path": "vendor/github.com/signintech/gopdf/cache_content_rectangle.go",
"chars": 1145,
"preview": "package gopdf\n\nimport (\n\t\"fmt\"\n\t\"io\"\n)\n\ntype cacheContentRectangle struct {\n\tpageHeight float64\n\tx "
},
{
"path": "vendor/github.com/signintech/gopdf/cache_content_rotate.go",
"chars": 536,
"preview": "package gopdf\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"math\"\n)\n\ntype cacheContentRotate struct {\n\tisReset bool\n\tpageHeight float64\n"
},
{
"path": "vendor/github.com/signintech/gopdf/cache_content_text.go",
"chars": 9846,
"preview": "package gopdf\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n)\n\n//ContentTypeCell cell\nconst ContentTypeCell = 0\n\n//ContentTypeText te"
},
{
"path": "vendor/github.com/signintech/gopdf/cache_contnent_curve.go",
"chars": 789,
"preview": "package gopdf\n\nimport (\n\t\"fmt\"\n\t\"io\"\n)\n\ntype cacheContentCurve struct {\n\tpageHeight float64\n\tx0 float64\n\ty0 "
},
{
"path": "vendor/github.com/signintech/gopdf/catalog_obj.go",
"chars": 711,
"preview": "package gopdf\n\nimport (\n\t\"fmt\"\n\t\"io\"\n)\n\n//CatalogObj : catalog dictionary\ntype CatalogObj struct { //impl IObj\n\toutlines"
},
{
"path": "vendor/github.com/signintech/gopdf/cell_option.go",
"chars": 756,
"preview": "package gopdf\n\n//Left left\nconst Left = 8 //001000\n//Top top\nconst Top = 4 //000100\n//Right right\nconst Right = 2 //0000"
},
{
"path": "vendor/github.com/signintech/gopdf/cid_font_obj.go",
"chars": 1572,
"preview": "package gopdf\n\nimport (\n\t\"fmt\"\n\t\"io\"\n)\n\n// CIDFontObj is a CID-keyed font.\n// cf. https://www.adobe.com/content/dam/acom"
},
{
"path": "vendor/github.com/signintech/gopdf/config.go",
"chars": 2461,
"preview": "package gopdf\n\n// The units that can be used in the document\nconst (\n\tUnitUnset = iota // No units were set, when conver"
},
{
"path": "vendor/github.com/signintech/gopdf/content_obj.go",
"chars": 9780,
"preview": "package gopdf\n\nimport (\n\t\"compress/zlib\"\n\t\"fmt\"\n\t\"io\"\n\t\"strings\"\n)\n\n//ContentObj content object\ntype ContentObj struct {"
},
{
"path": "vendor/github.com/signintech/gopdf/current.go",
"chars": 1563,
"preview": "package gopdf\n\n//Current current state\ntype Current struct {\n\tsetXCount int //many times we go func SetX()\n\tX fl"
},
{
"path": "vendor/github.com/signintech/gopdf/device_rgb_obj.go",
"chars": 834,
"preview": "package gopdf\n\nimport (\n\t\"fmt\"\n\t\"io\"\n)\n\n//DeviceRGBObj DeviceRGB\ntype DeviceRGBObj struct {\n\tdata []byte\n\tgetRoot fu"
},
{
"path": "vendor/github.com/signintech/gopdf/embedfont_obj.go",
"chars": 1179,
"preview": "package gopdf\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"io/ioutil\"\n)\n\n// EmbedFontObj is an embedded font object.\ntype EmbedFontObj struc"
},
{
"path": "vendor/github.com/signintech/gopdf/encoding_obj.go",
"chars": 671,
"preview": "package gopdf\n\nimport (\n\t\"io\"\n)\n\n// EncodingObj is a font object.\ntype EncodingObj struct {\n\tfont IFont\n}\n\nfunc (e *Enco"
},
{
"path": "vendor/github.com/signintech/gopdf/encryption_obj.go",
"chars": 968,
"preview": "package gopdf\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"strings\"\n)\n\n//EncryptionObj encryption object res\ntype EncryptionObj struct {\n\tu"
},
{
"path": "vendor/github.com/signintech/gopdf/ext_g_state_obj.go",
"chars": 2846,
"preview": "package gopdf\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"sync\"\n\n\t\"github.com/pkg/errors\"\n)\n\n// TODO: add all fields https://www.adobe.com/"
},
{
"path": "vendor/github.com/signintech/gopdf/font_obj.go",
"chars": 1431,
"preview": "package gopdf\n\nimport (\n\t\"fmt\"\n\t\"io\"\n)\n\n//FontObj font obj\ntype FontObj struct {\n\tFamily string\n\t//Style string\n\t//Size "
},
{
"path": "vendor/github.com/signintech/gopdf/font_option.go",
"chars": 572,
"preview": "package gopdf\n\nimport (\n\t\"strings\"\n)\n\n//Regular - font style regular\nconst Regular = 0 //000000\n//Italic - font style it"
},
{
"path": "vendor/github.com/signintech/gopdf/fontconverthelper.go",
"chars": 612,
"preview": "package gopdf\n\nimport (\n\t\"strconv\"\n\t//\"fmt\"\n\t\"bytes\"\n)\n\n// FontConvertHelperCw2Str converts main ASCII characters of a F"
},
{
"path": "vendor/github.com/signintech/gopdf/fontdescriptor_obj.go",
"chars": 1126,
"preview": "package gopdf\n\nimport (\n\t\"fmt\"\n\t\"io\"\n)\n\n// FontDescriptorObj is a font descriptor object.\ntype FontDescriptorObj struct "
},
{
"path": "vendor/github.com/signintech/gopdf/fontmaker/core/fontmaker.go",
"chars": 11791,
"preview": "package core\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"compress/zlib\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io/ioutil\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strconv"
},
{
"path": "vendor/github.com/signintech/gopdf/fontmaker/core/fontmap.go",
"chars": 61,
"preview": "package core\n\ntype FontMap struct {\n\tUv int\n\tName string\n}\n"
},
{
"path": "vendor/github.com/signintech/gopdf/fontmaker/core/kern_table.go",
"chars": 498,
"preview": "package core\n\n//KernTable https://www.microsoft.com/typography/otspec/kern.htm\ntype KernTable struct {\n\tVersion uint //f"
},
{
"path": "vendor/github.com/signintech/gopdf/fontmaker/core/math.go",
"chars": 128,
"preview": "package core\n\nfunc Round(value float64) int {\n\tif value < 0.0 {\n\t\tvalue -= 0.5\n\t} else {\n\t\tvalue += 0.5\n\t}\n\treturn int(v"
},
{
"path": "vendor/github.com/signintech/gopdf/fontmaker/core/table_directory_entry.go",
"chars": 189,
"preview": "package core\n\ntype TableDirectoryEntry struct {\n\tCheckSum uint\n\tOffset uint\n\tLength uint\n}\n\nfunc (t TableDirectoryEn"
},
{
"path": "vendor/github.com/signintech/gopdf/fontmaker/core/ttf_info.go",
"chars": 2106,
"preview": "package core\n\nimport (\n\t\"errors\"\n)\n\nvar ERROR_NO_KEY_FOUND = errors.New(\"no key found\")\nvar ERROR_NO_GET_WRONG_TYPE = er"
},
{
"path": "vendor/github.com/signintech/gopdf/fontmaker/core/ttfparser.go",
"chars": 19402,
"preview": "package core\n\nimport (\n\t//\"encoding/binary\"\n\t//\"encoding/hex\"\n\t\"bytes\"\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"io/io"
},
{
"path": "vendor/github.com/signintech/gopdf/fontmaker/core/ttfparser_cmap_other_format.go",
"chars": 2356,
"preview": "package core\n\nimport (\n\t\"bytes\"\n\t\"errors\"\n)\n\n//ParseCmapFormat12 parse cmap table format 12 https://www.microsoft.com/ty"
},
{
"path": "vendor/github.com/signintech/gopdf/fontmaker/core/ttfparser_kern.go",
"chars": 1879,
"preview": "package core\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n)\n\n//Parsekern parse kerning table https://www.microsoft.com/typography/otspec/k"
},
{
"path": "vendor/github.com/signintech/gopdf/func_kern_override.go",
"chars": 184,
"preview": "package gopdf\n\n//FuncKernOverride return your custome pair value\ntype FuncKernOverride func(\n\tleftRune rune,\n\trightRune"
},
{
"path": "vendor/github.com/signintech/gopdf/go.mod",
"chars": 124,
"preview": "module github.com/signintech/gopdf\n\ngo 1.11\n\nrequire (\n\tgithub.com/phpdave11/gofpdi v1.0.11\n\tgithub.com/pkg/errors v0.8."
},
{
"path": "vendor/github.com/signintech/gopdf/go.sum",
"chars": 336,
"preview": "github.com/phpdave11/gofpdi v1.0.11 h1:wsBNx+3S0wy1dEp6fzv281S74ogZGgIdYWV2PugWgho=\ngithub.com/phpdave11/gofpdi v1.0.11/"
},
{
"path": "vendor/github.com/signintech/gopdf/gopdf.go",
"chars": 41399,
"preview": "package gopdf\n\nimport (\n\t\"bufio\"\n\t\"bytes\"\n\t\"compress/zlib\" // for constants\n\t\"fmt\"\n\t\"image\"\n\t\"image/jpeg\"\n\t\"io\"\n\t\"io/iou"
},
{
"path": "vendor/github.com/signintech/gopdf/i_cache_contneter.go",
"chars": 119,
"preview": "package gopdf\n\nimport (\n\t\"io\"\n)\n\ntype ICacheContent interface {\n\twrite(w io.Writer, protection *PDFProtection) error\n}\n"
},
{
"path": "vendor/github.com/signintech/gopdf/ifont.go",
"chars": 650,
"preview": "package gopdf\n\n// IFont represents a font interface.\ntype IFont interface {\n\tInit()\n\tGetType() string\n\tGetName() string\n"
},
{
"path": "vendor/github.com/signintech/gopdf/image_holder.go",
"chars": 1433,
"preview": "package gopdf\n\nimport (\n\t\"bytes\"\n\t\"crypto/md5\"\n\t\"fmt\"\n\t\"io\"\n\t\"io/ioutil\"\n)\n\n//ImageHolder hold image data\ntype ImageHold"
},
{
"path": "vendor/github.com/signintech/gopdf/image_obj.go",
"chars": 3756,
"preview": "package gopdf\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"image\"\n\t// Packages image/jpeg and image/png are not used explicitly in the co"
},
{
"path": "vendor/github.com/signintech/gopdf/image_obj_parse.go",
"chars": 10273,
"preview": "package gopdf\n\nimport (\n\t\"bytes\"\n\t\"compress/zlib\"\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"fmt\"\n\t\"image\"\n\t\"image/color\"\n\t\"io\"\n\t\"io"
},
{
"path": "vendor/github.com/signintech/gopdf/img_info.go",
"chars": 345,
"preview": "package gopdf\n\ntype imgInfo struct {\n\tw, h int\n\t//src string\n\tformatName string\n\tcolspace str"
},
{
"path": "vendor/github.com/signintech/gopdf/imported_obj.go",
"chars": 362,
"preview": "package gopdf\n\nimport (\n\t\"io\"\n)\n\n//ImportedObj : imported object\ntype ImportedObj struct { //impl IObj\n\tData string\n}\n\nf"
},
{
"path": "vendor/github.com/signintech/gopdf/iobj.go",
"chars": 168,
"preview": "package gopdf\n\nimport (\n\t\"io\"\n)\n\n//IObj inteface for all pdf object\ntype IObj interface {\n\tinit(func() *GoPdf)\n\tgetType("
},
{
"path": "vendor/github.com/signintech/gopdf/link_option.go",
"chars": 154,
"preview": "package gopdf\n\ntype anchorOption struct {\n\tpage int\n\ty float64\n}\n\ntype linkOption struct {\n\tx, y, w, h float64\n\turl "
},
{
"path": "vendor/github.com/signintech/gopdf/list_cache_content.go",
"chars": 1415,
"preview": "package gopdf\n\nimport \"io\"\n\ntype listCacheContent struct {\n\tcaches []ICacheContent\n}\n\nfunc (l *listCacheContent) last() "
},
{
"path": "vendor/github.com/signintech/gopdf/map_of_character_To_glyph_index.go",
"chars": 1424,
"preview": "package gopdf\n\n//MapOfCharacterToGlyphIndex map of CharacterToGlyphIndex\ntype MapOfCharacterToGlyphIndex struct {\n\tkeyIn"
},
{
"path": "vendor/github.com/signintech/gopdf/margin.go",
"chars": 2102,
"preview": "package gopdf\n\n// Margins type.\ntype Margins struct {\n\tLeft, Top, Right, Bottom float64\n}\n\n// SetLeftMargin sets left ma"
},
{
"path": "vendor/github.com/signintech/gopdf/outlines_obj.go",
"chars": 1926,
"preview": "package gopdf\n\nimport (\n\t\"fmt\"\n\t\"io\"\n)\n\n//OutlinesObj : outlines dictionary\ntype OutlinesObj struct { //impl IObj\n\tgetRo"
},
{
"path": "vendor/github.com/signintech/gopdf/page_obj.go",
"chars": 2777,
"preview": "package gopdf\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"strings\"\n)\n\n//PageObj pdf page object\ntype PageObj struct { //impl IObj\n\tContents"
},
{
"path": "vendor/github.com/signintech/gopdf/page_option.go",
"chars": 411,
"preview": "package gopdf\n\n//PageOption option of page\ntype PageOption struct {\n\tTrimBox *Box\n\tPageSize *Rect\n}\n\nfunc (p PageOption"
},
{
"path": "vendor/github.com/signintech/gopdf/page_sizes.go",
"chars": 1886,
"preview": "package gopdf\n\n// PageSizeLetter page format\nvar PageSizeLetter = &Rect{W: 612, H: 792, unitOverride: UnitPT}\n\n// PageSi"
},
{
"path": "vendor/github.com/signintech/gopdf/pages_obj.go",
"chars": 801,
"preview": "package gopdf\n\nimport (\n\t\"fmt\"\n\t\"io\"\n)\n\n//PagesObj pdf pages object\ntype PagesObj struct { //impl IObj\n\tPageCount int\n\tK"
},
{
"path": "vendor/github.com/signintech/gopdf/pdf_dictionary_obj.go",
"chars": 9213,
"preview": "package gopdf\n\nimport (\n\t\"compress/zlib\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"sort\"\n\n\t\"github.com/signintech/gopdf/fontmaker/core\"\n)"
},
{
"path": "vendor/github.com/signintech/gopdf/pdf_info_obj.go",
"chars": 697,
"preview": "package gopdf\n\nimport \"time\"\n\n//PdfInfo Document Information Dictionary\ntype PdfInfo struct {\n\tTitle string //"
},
{
"path": "vendor/github.com/signintech/gopdf/pdf_protection.go",
"chars": 3968,
"preview": "package gopdf\n\nimport (\n\t\"crypto/md5\"\n\t\"crypto/rc4\"\n\t\"encoding/binary\"\n\t\"math/rand\"\n\t\"time\"\n)\n\nconst (\n\t//PermissionsPri"
},
{
"path": "vendor/github.com/signintech/gopdf/point.go",
"chars": 96,
"preview": "package gopdf\n\n//Point a point in a two-dimensional\ntype Point struct {\n\tX float64\n\tY float64\n}\n"
},
{
"path": "vendor/github.com/signintech/gopdf/procset_obj.go",
"chars": 2509,
"preview": "package gopdf\n\nimport (\n\t\"fmt\"\n\t\"io\"\n)\n\n// ProcSetObj is a PDF procSet object.\ntype ProcSetObj struct {\n\t//Font\n\tRelates"
},
{
"path": "vendor/github.com/signintech/gopdf/rect.go",
"chars": 863,
"preview": "package gopdf\n\n// Rect defines a rectangle.\ntype Rect struct {\n\tW float64\n\tH float64\n\tunitOverride"
},
{
"path": "vendor/github.com/signintech/gopdf/smask_obj.go",
"chars": 2626,
"preview": "package gopdf\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"sync\"\n)\n\ntype SMaskSubtypes string\n\nconst (\n\tSMaskAlphaSubtype = \"/Alpha\"\n\tS"
},
{
"path": "vendor/github.com/signintech/gopdf/strhelper.go",
"chars": 1075,
"preview": "package gopdf\n\nimport (\n\t\"math/big\"\n\t\"strings\"\n)\n\n//StrHelperGetStringWidth get string width\nfunc StrHelperGetStringWidt"
},
{
"path": "vendor/github.com/signintech/gopdf/style.go",
"chars": 354,
"preview": "package gopdf\n\ntype PaintStyle string\n\nconst (\n\tDrawPaintStyle PaintStyle = \"S\"\n\tFillPaintStyle PaintStyle = \"f\""
},
{
"path": "vendor/github.com/signintech/gopdf/subfont_descriptor_obj.go",
"chars": 2033,
"preview": "package gopdf\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\n\t\"github.com/signintech/gopdf/fontmaker/core\"\n)\n\n//SubfontDescriptorObj pdf subfon"
},
{
"path": "vendor/github.com/signintech/gopdf/subset_font_obj.go",
"chars": 6382,
"preview": "package gopdf\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\n\t\"github.com/signintech/gopdf/fontmaker/core\"\n)\n\n//ErrCharNotFound char "
},
{
"path": "vendor/github.com/signintech/gopdf/transparency.go",
"chars": 3096,
"preview": "package gopdf\n\nimport (\n\t\"fmt\"\n\t\"sync\"\n\n\t\"github.com/pkg/errors\"\n)\n\ntype BlendModeType string\n\nconst (\n\tHue "
},
{
"path": "vendor/github.com/signintech/gopdf/transparency_xobject_group.go",
"chars": 2159,
"preview": "package gopdf\n\nimport (\n\t\"fmt\"\n\t\"io\"\n)\n\ntype TransparencyXObjectGroup struct {\n\tIndex int\n\tBBox ["
},
{
"path": "vendor/github.com/signintech/gopdf/ttf_option.go",
"chars": 285,
"preview": "package gopdf\n\n//TtfOption font option\ntype TtfOption struct {\n\tUseKerning bool\n\tStyle int // Regular|Bo"
},
{
"path": "vendor/github.com/signintech/gopdf/unicode_map.go",
"chars": 3151,
"preview": "package gopdf\n\nimport (\n\t\"fmt\"\n\t\"io\"\n)\n\n//UnicodeMap unicode map\ntype UnicodeMap struct {\n\tPtrToSubsetFontObj *SubsetFon"
},
{
"path": "vendor/modules.txt",
"chars": 240,
"preview": "# github.com/phpdave11/gofpdi v1.0.11\ngithub.com/phpdave11/gofpdi\n# github.com/pkg/errors v0.8.1\ngithub.com/pkg/errors\n#"
}
]
About this extraction
This page contains the full source code of the sopov/resumeio2pdf GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 108 files (300.1 KB), approximately 96.1k tokens, and a symbol index with 794 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.