Merge branch 'v3' into v3-pdf-appender
@ -13,12 +13,19 @@ import (
|
||||
"bytes"
|
||||
"crypto/md5"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
goimage "image"
|
||||
"image/png"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"math"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/boombuler/barcode"
|
||||
@ -35,6 +42,15 @@ func init() {
|
||||
common.SetLogger(common.NewConsoleLogger(common.LogLevelDebug))
|
||||
}
|
||||
|
||||
// Rendering tests are run when UNIDOC_RENDERTEST_BASELINE_PATH environment variable is set to
|
||||
// a folder containing a rendered PNG image of each page of generated PDF files.
|
||||
// Rendering requires pdftoppm to be present on the system.
|
||||
// To generate the images based on the current version of unidoc, set UNIDOC_RENDERTEST_BASELINE_PATH
|
||||
// and run the test as usual. Files for all tests will be generated. Rename ones you want to test from
|
||||
// xxx.png to xxx_exp.png, make changes to the code and run the test again (with environment variable set).
|
||||
|
||||
var baselineRenderPath = os.Getenv("UNIDOC_RENDERTEST_BASELINE_PATH")
|
||||
|
||||
const testPdfFile1 = "./testdata/minimal.pdf"
|
||||
const testPdfLoremIpsumFile = "./testdata/lorem.pdf"
|
||||
const testPdfTemplatesFile1 = "./testdata/templates1.pdf"
|
||||
@ -84,9 +100,7 @@ func TestTemplate1(t *testing.T) {
|
||||
template.SetPos(100, 200)
|
||||
creator.Draw(template)
|
||||
|
||||
creator.WriteToFile(tempFile("template_1.pdf"))
|
||||
|
||||
return
|
||||
testWriteAndRender(t, creator, "template_1.pdf")
|
||||
}
|
||||
|
||||
// TestImage1 tests loading an image and adding to file at an absolute position.
|
||||
@ -114,11 +128,7 @@ func TestImage1(t *testing.T) {
|
||||
return
|
||||
}
|
||||
|
||||
err = creator.WriteToFile(tempFile("1.pdf"))
|
||||
if err != nil {
|
||||
t.Errorf("Fail: %v\n", err)
|
||||
return
|
||||
}
|
||||
testWriteAndRender(t, creator, "1.pdf")
|
||||
}
|
||||
|
||||
// TestImageWithEncoder tests loading inserting an image with a specified encoder.
|
||||
@ -153,11 +163,7 @@ func TestImageWithEncoder(t *testing.T) {
|
||||
return
|
||||
}
|
||||
|
||||
err = creator.WriteToFile(tempFile("1_dct.pdf"))
|
||||
if err != nil {
|
||||
t.Errorf("Fail: %v\n", err)
|
||||
return
|
||||
}
|
||||
testWriteAndRender(t, creator, "1_dct.pdf")
|
||||
}
|
||||
|
||||
func TestShapes1(t *testing.T) {
|
||||
@ -239,11 +245,7 @@ func TestShapes1(t *testing.T) {
|
||||
return
|
||||
}
|
||||
|
||||
err = creator.WriteToFile(tempFile("1_shapes.pdf"))
|
||||
if err != nil {
|
||||
t.Errorf("Fail: %v\n", err)
|
||||
return
|
||||
}
|
||||
testWriteAndRender(t, creator, "1_shapes.pdf")
|
||||
}
|
||||
|
||||
// Example drawing image and line shape on a block and applying to pages, also demonstrating block
|
||||
@ -288,11 +290,7 @@ func TestShapesOnBlock(t *testing.T) {
|
||||
block.SetAngle(90)
|
||||
creator.Draw(block)
|
||||
|
||||
err = creator.WriteToFile(tempFile("1_shapes_on_block.pdf"))
|
||||
if err != nil {
|
||||
t.Errorf("Fail: %v\n", err)
|
||||
return
|
||||
}
|
||||
testWriteAndRender(t, creator, "1_shapes_on_block.pdf")
|
||||
}
|
||||
|
||||
// Test image wrapping between pages when using relative context mode.
|
||||
@ -321,11 +319,7 @@ func TestImageWrapping(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
err = creator.WriteToFile(tempFile("1_wrap.pdf"))
|
||||
if err != nil {
|
||||
t.Errorf("Fail: %v\n", err)
|
||||
return
|
||||
}
|
||||
testWriteAndRender(t, creator, "1_wrap.pdf")
|
||||
}
|
||||
|
||||
// Test rotating image. Rotating about upper left corner.
|
||||
@ -361,11 +355,7 @@ func TestImageRotation(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
err = creator.WriteToFile(tempFile("1_rotate.pdf"))
|
||||
if err != nil {
|
||||
t.Errorf("Fail: %v\n", err)
|
||||
return
|
||||
}
|
||||
testWriteAndRender(t, creator, "1_rotate.pdf")
|
||||
}
|
||||
|
||||
// Test image, rotation and page wrapping. Disadvantage here is that content is overlapping. May be reconsidered
|
||||
@ -403,11 +393,7 @@ func TestImageRotationAndWrap(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
err = creator.WriteToFile(tempFile("rotate_2.pdf"))
|
||||
if err != nil {
|
||||
t.Errorf("Fail: %v\n", err)
|
||||
return
|
||||
}
|
||||
testWriteAndRender(t, creator, "rotate_2.pdf")
|
||||
}
|
||||
|
||||
// Test basic paragraph with default font.
|
||||
@ -426,11 +412,7 @@ func TestParagraph1(t *testing.T) {
|
||||
return
|
||||
}
|
||||
|
||||
err = creator.WriteToFile(tempFile("2_p1.pdf"))
|
||||
if err != nil {
|
||||
t.Errorf("Fail: %v\n", err)
|
||||
return
|
||||
}
|
||||
testWriteAndRender(t, creator, "2_p1.pdf")
|
||||
}
|
||||
|
||||
// Test paragraph and page and text wrapping with left, justify, center and right modes.
|
||||
@ -538,11 +520,7 @@ func TestParagraphFonts(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
err = creator.WriteToFile(tempFile("2_pArial.pdf"))
|
||||
if err != nil {
|
||||
t.Errorf("Fail: %v\n", err)
|
||||
return
|
||||
}
|
||||
testWriteAndRender(t, creator, "2_pArial.pdf")
|
||||
}
|
||||
|
||||
// Test writing with the 14 built in fonts.
|
||||
@ -608,11 +586,7 @@ func TestParagraphStandardFonts(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
err := creator.WriteToFile(tempFile("2_standard14fonts.pdf"))
|
||||
if err != nil {
|
||||
t.Errorf("Fail: %v\n", err)
|
||||
return
|
||||
}
|
||||
testWriteAndRender(t, creator, "2_standard14fonts.pdf")
|
||||
}
|
||||
|
||||
// Test paragraph with Chinese characters.
|
||||
@ -643,13 +617,8 @@ func TestParagraphChinese(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
testWriteAndRender(t, creator, "2_p_nihao.pdf")
|
||||
fname := tempFile("2_p_nihao.pdf")
|
||||
err = creator.WriteToFile(fname)
|
||||
if err != nil {
|
||||
t.Errorf("Fail: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
st, err := os.Stat(fname)
|
||||
if err != nil {
|
||||
t.Errorf("Fail: %v\n", err)
|
||||
@ -710,11 +679,7 @@ func TestParagraphUnicode(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
err = creator.WriteToFile(tempFile("2_p_multi.pdf"))
|
||||
if err != nil {
|
||||
t.Errorf("Fail: %v\n", err)
|
||||
return
|
||||
}
|
||||
testWriteAndRender(t, creator, "2_p_multi.pdf")
|
||||
}
|
||||
|
||||
// Tests creating a chapter with paragraphs.
|
||||
@ -763,11 +728,7 @@ func TestChapterMargins(t *testing.T) {
|
||||
c.Draw(ch)
|
||||
}
|
||||
|
||||
err := c.WriteToFile(tempFile("3_chapters_margins.pdf"))
|
||||
if err != nil {
|
||||
t.Errorf("Fail: %v\n", err)
|
||||
return
|
||||
}
|
||||
testWriteAndRender(t, c, "3_chapters_margins.pdf")
|
||||
}
|
||||
|
||||
// Test creating and drawing subchapters with text content.
|
||||
@ -872,11 +833,7 @@ func TestSubchaptersSimple(t *testing.T) {
|
||||
return nil
|
||||
})
|
||||
|
||||
err := c.WriteToFile(tempFile("3_subchapters_simple.pdf"))
|
||||
if err != nil {
|
||||
t.Errorf("Fail: %v\n", err)
|
||||
return
|
||||
}
|
||||
testWriteAndRender(t, c, "3_subchapters_simple.pdf")
|
||||
}
|
||||
|
||||
func TestSubchapters(t *testing.T) {
|
||||
@ -1042,11 +999,7 @@ func TestTable(t *testing.T) {
|
||||
|
||||
c.Draw(table)
|
||||
|
||||
err := c.WriteToFile(tempFile("4_table.pdf"))
|
||||
if err != nil {
|
||||
t.Errorf("Fail: %v\n", err)
|
||||
return
|
||||
}
|
||||
testWriteAndRender(t, c, "4_table.pdf")
|
||||
}
|
||||
|
||||
func TestTableCellWrapping(t *testing.T) {
|
||||
@ -1133,10 +1086,7 @@ func TestTableCellWrapping(t *testing.T) {
|
||||
t.Fatalf("Error drawing: %v", err)
|
||||
}
|
||||
|
||||
err = c.WriteToFile(tempFile("tablecell_wrap.pdf"))
|
||||
if err != nil {
|
||||
t.Fatalf("Fail: %v\n", err)
|
||||
}
|
||||
testWriteAndRender(t, c, "tablecell_wrap.pdf")
|
||||
}
|
||||
|
||||
// Test creating and drawing a table.
|
||||
@ -1174,11 +1124,7 @@ func TestBorderedTable1(t *testing.T) {
|
||||
|
||||
c.Draw(table)
|
||||
|
||||
err := c.WriteToFile(tempFile("4_table_bordered.pdf"))
|
||||
if err != nil {
|
||||
t.Errorf("Fail: %v\n", err)
|
||||
return
|
||||
}
|
||||
testWriteAndRender(t, c, "4_table_bordered.pdf")
|
||||
}
|
||||
|
||||
// Test creating and drawing a table.
|
||||
@ -1235,11 +1181,7 @@ func TestBorderedTable2(t *testing.T) {
|
||||
|
||||
c.Draw(table)
|
||||
|
||||
err := c.WriteToFile(tempFile("4_table_bordered.pdf"))
|
||||
if err != nil {
|
||||
t.Errorf("Fail: %v\n", err)
|
||||
return
|
||||
}
|
||||
testWriteAndRender(t, c, "4_table_bordered2.pdf")
|
||||
}
|
||||
|
||||
func newContent(c *Creator, text string, alignment TextAlignment, font *model.PdfFont, fontSize float64, color Color) *Paragraph {
|
||||
@ -1466,11 +1408,7 @@ func TestCreatorHendricksReq1(t *testing.T) {
|
||||
c.Draw(table2)
|
||||
c.Draw(table3)
|
||||
|
||||
err := c.WriteToFile(tempFile("hendricks.pdf"))
|
||||
if err != nil {
|
||||
t.Errorf("Fail: %v\n", err)
|
||||
return
|
||||
}
|
||||
testWriteAndRender(t, c, "hendricks.pdf")
|
||||
}
|
||||
|
||||
func TestCreatorTableBorderReq1(t *testing.T) {
|
||||
@ -1797,11 +1735,7 @@ func TestCreatorTableBorderReq1(t *testing.T) {
|
||||
c.Draw(table9)
|
||||
c.Draw(table10)
|
||||
|
||||
err := c.WriteToFile(tempFile("table_border_req1_test.pdf"))
|
||||
if err != nil {
|
||||
t.Errorf("Fail: %v\n", err)
|
||||
return
|
||||
}
|
||||
testWriteAndRender(t, c, "table_border_req1_test.pdf")
|
||||
}
|
||||
|
||||
func TestCellBorder(t *testing.T) {
|
||||
@ -1818,11 +1752,7 @@ func TestCellBorder(t *testing.T) {
|
||||
|
||||
c.Draw(table)
|
||||
|
||||
err := c.WriteToFile(tempFile("cell.pdf"))
|
||||
if err != nil {
|
||||
t.Errorf("Fail: %v\n", err)
|
||||
return
|
||||
}
|
||||
testWriteAndRender(t, c, "cell.pdf")
|
||||
}
|
||||
|
||||
func TestTableInSubchapter(t *testing.T) {
|
||||
@ -1917,11 +1847,7 @@ func TestTableInSubchapter(t *testing.T) {
|
||||
return
|
||||
}
|
||||
|
||||
err = c.WriteToFile(tempFile("4_tables_in_subchap.pdf"))
|
||||
if err != nil {
|
||||
t.Errorf("Fail: %v\n", err)
|
||||
return
|
||||
}
|
||||
testWriteAndRender(t, c, "4_tables_in_subchap.pdf")
|
||||
}
|
||||
|
||||
// Add headers and footers via creator.
|
||||
@ -1992,11 +1918,7 @@ func TestHeadersAndFooters(t *testing.T) {
|
||||
// Make unidoc headers and footers.
|
||||
addHeadersAndFooters(c)
|
||||
|
||||
err := c.WriteToFile(tempFile("4_headers.pdf"))
|
||||
if err != nil {
|
||||
t.Errorf("Fail: %v\n", err)
|
||||
return
|
||||
}
|
||||
testWriteAndRender(t, c, "4_headers.pdf")
|
||||
}
|
||||
|
||||
func makeQrCodeImage(text string, width float64, oversampling int) (goimage.Image, error) {
|
||||
@ -2037,7 +1959,7 @@ func TestQRCodeOnNewPage(t *testing.T) {
|
||||
creator.Draw(img)
|
||||
}
|
||||
|
||||
creator.WriteToFile(tempFile("3_barcode_qr_newpage.pdf"))
|
||||
testWriteAndRender(t, creator, "3_barcode_qr_newpage.pdf")
|
||||
}
|
||||
|
||||
// Example of using a template Page, generating and applying QR
|
||||
@ -2115,7 +2037,7 @@ func TestQRCodeOnTemplate(t *testing.T) {
|
||||
creator.Draw(loremTpl)
|
||||
|
||||
// Write the example to file.
|
||||
creator.WriteToFile(tempFile("4_barcode_on_tpl.pdf"))
|
||||
testWriteAndRender(t, creator, "4_barcode_on_tpl.pdf")
|
||||
}
|
||||
|
||||
// Test adding encryption to output.
|
||||
@ -2967,3 +2889,143 @@ func TestCreatorStable(t *testing.T) {
|
||||
t.Fatal("output is not stable")
|
||||
}
|
||||
}
|
||||
|
||||
var errRenderNotSupported = errors.New("rendering pdf is not supported on this system")
|
||||
|
||||
// renderPDFToPNGs uses pdftoppm tool to render specified PDF file into a set of PNG images (one per page).
|
||||
// PNG images will be named xxx-N.png where N is the number of page, starting from 1.
|
||||
func renderPDFToPNGs(pdfPath string, dpi int, out string) error {
|
||||
if dpi == 0 {
|
||||
// default is 150, but 100 should be good enough for tests
|
||||
dpi = 100
|
||||
}
|
||||
if _, err := exec.LookPath("pdftoppm"); err != nil {
|
||||
return errRenderNotSupported
|
||||
}
|
||||
dpis := strconv.Itoa(dpi)
|
||||
return exec.Command("pdftoppm", pdfPath, out, "-png", "-rx", dpis, "-ry", dpis).Run()
|
||||
}
|
||||
|
||||
func readPNG(file string) (goimage.Image, error) {
|
||||
f, err := os.Open(file)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer f.Close()
|
||||
return png.Decode(f)
|
||||
}
|
||||
|
||||
func comparePNGFiles(file1, file2 string) (bool, error) {
|
||||
// fast path - compare hashes
|
||||
h1, err := hashFile(file1)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
h2, err := hashFile(file2)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if h1 == h2 {
|
||||
return true, nil
|
||||
}
|
||||
// slow path - compare pixel by pixel
|
||||
img1, err := readPNG(file1)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
img2, err := readPNG(file2)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if img1.Bounds() != img2.Bounds() {
|
||||
return false, nil
|
||||
}
|
||||
rgb1, ok := img1.(*goimage.RGBA)
|
||||
if !ok {
|
||||
return compareImages(img1, img2)
|
||||
}
|
||||
rgb2, ok := img2.(*goimage.RGBA)
|
||||
if !ok {
|
||||
return compareImages(img1, img2)
|
||||
}
|
||||
return compareImagesRGBA(rgb1, rgb2)
|
||||
}
|
||||
|
||||
func compareImages(img1, img2 goimage.Image) (bool, error) {
|
||||
rect := img1.Bounds()
|
||||
for x := 0; x < rect.Size().X; x++ {
|
||||
for y := 0; y < rect.Size().Y; y++ {
|
||||
r1, g1, b1, a1 := img1.At(x, y).RGBA()
|
||||
r2, g2, b2, a2 := img2.At(x, y).RGBA()
|
||||
if r1 != r2 || g1 != g2 || b1 != b2 || a1 != a2 {
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func compareImagesRGBA(img1, img2 *goimage.RGBA) (bool, error) {
|
||||
if img1.Stride != img2.Stride {
|
||||
// TODO(dennwc): does this ever happen? if so, we can still optimize this
|
||||
log.Println("WARN: RGB images with different strides")
|
||||
return compareImages(img1, img2)
|
||||
} else if len(img1.Pix) != len(img2.Pix) {
|
||||
return false, nil
|
||||
}
|
||||
return bytes.Equal(img1.Pix, img2.Pix), nil
|
||||
}
|
||||
|
||||
func hashFile(file string) (string, error) {
|
||||
f, err := os.Open(file)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer f.Close()
|
||||
h := md5.New()
|
||||
_, err = io.Copy(h, f)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return hex.EncodeToString(h.Sum(nil)), nil
|
||||
}
|
||||
|
||||
func testWriteAndRender(t *testing.T, c *Creator, pname string) {
|
||||
pname = tempFile(pname)
|
||||
err := c.WriteToFile(pname)
|
||||
if err != nil {
|
||||
t.Errorf("Fail: %v\n", err)
|
||||
return
|
||||
}
|
||||
testRender(t, pname)
|
||||
}
|
||||
|
||||
func testRender(t *testing.T, pname string) {
|
||||
tname := strings.TrimSuffix(filepath.Base(pname), filepath.Ext(pname))
|
||||
t.Run("render", func(t *testing.T) {
|
||||
if baselineRenderPath == "" {
|
||||
t.Skip("skipping render tests; set UNIDOC_RENDERTEST_BASELINE_PATH to run")
|
||||
}
|
||||
fname := filepath.Join(baselineRenderPath, tname)
|
||||
// will emit template_1-x.png
|
||||
err := renderPDFToPNGs(pname, 0, fname)
|
||||
if err != nil {
|
||||
t.Skip(err)
|
||||
}
|
||||
for i := 1; true; i++ {
|
||||
name1 := fmt.Sprintf(fname+"-%d.png", i)
|
||||
name2 := fmt.Sprintf(fname+"-%d_exp.png", i)
|
||||
if _, err := os.Stat(name1); i > 1 && err != nil {
|
||||
break
|
||||
}
|
||||
t.Run(fmt.Sprintf("page%d", i), func(t *testing.T) {
|
||||
ok, err := comparePNGFiles(name1, name2)
|
||||
if os.IsNotExist(err) {
|
||||
t.Skip("no test file")
|
||||
} else if !ok {
|
||||
t.Fatal("wrong page rendered")
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
BIN
pdf/creator/testdata/1-1_exp.png
vendored
Normal file
After Width: | Height: | Size: 87 KiB |
BIN
pdf/creator/testdata/1_dct-1_exp.png
vendored
Normal file
After Width: | Height: | Size: 166 KiB |
BIN
pdf/creator/testdata/1_shapes-1_exp.png
vendored
Normal file
After Width: | Height: | Size: 90 KiB |
BIN
pdf/creator/testdata/1_shapes_on_block-1_exp.png
vendored
Normal file
After Width: | Height: | Size: 39 KiB |
BIN
pdf/creator/testdata/1_shapes_on_block-2_exp.png
vendored
Normal file
After Width: | Height: | Size: 39 KiB |
BIN
pdf/creator/testdata/1_shapes_on_block-3_exp.png
vendored
Normal file
After Width: | Height: | Size: 41 KiB |
BIN
pdf/creator/testdata/1_wrap-1_exp.png
vendored
Normal file
After Width: | Height: | Size: 142 KiB |
BIN
pdf/creator/testdata/2_pArial-1_exp.png
vendored
Normal file
After Width: | Height: | Size: 248 KiB |
BIN
pdf/creator/testdata/2_p_multi-1_exp.png
vendored
Normal file
After Width: | Height: | Size: 107 KiB |
BIN
pdf/creator/testdata/2_p_nihao-1_exp.png
vendored
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
pdf/creator/testdata/2_standard14fonts-1_exp.png
vendored
Normal file
After Width: | Height: | Size: 91 KiB |
BIN
pdf/creator/testdata/3_barcode_qr_newpage-1_exp.png
vendored
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
pdf/creator/testdata/3_chapters_margins-1_exp.png
vendored
Normal file
After Width: | Height: | Size: 260 KiB |
BIN
pdf/creator/testdata/3_chapters_margins-2_exp.png
vendored
Normal file
After Width: | Height: | Size: 289 KiB |
BIN
pdf/creator/testdata/3_chapters_margins-3_exp.png
vendored
Normal file
After Width: | Height: | Size: 37 KiB |
BIN
pdf/creator/testdata/3_subchapters_simple-1_exp.png
vendored
Normal file
After Width: | Height: | Size: 23 KiB |
BIN
pdf/creator/testdata/3_subchapters_simple-2_exp.png
vendored
Normal file
After Width: | Height: | Size: 46 KiB |
BIN
pdf/creator/testdata/3_subchapters_simple-3_exp.png
vendored
Normal file
After Width: | Height: | Size: 266 KiB |
BIN
pdf/creator/testdata/3_subchapters_simple-4_exp.png
vendored
Normal file
After Width: | Height: | Size: 212 KiB |
BIN
pdf/creator/testdata/4_barcode_on_tpl-1_exp.png
vendored
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
pdf/creator/testdata/4_barcode_on_tpl-2_exp.png
vendored
Normal file
After Width: | Height: | Size: 223 KiB |
BIN
pdf/creator/testdata/4_table-1_exp.png
vendored
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
pdf/creator/testdata/4_table_bordered-1_exp.png
vendored
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
pdf/creator/testdata/4_table_bordered2-1_exp.png
vendored
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
pdf/creator/testdata/4_tables_in_subchap-1_exp.png
vendored
Normal file
After Width: | Height: | Size: 58 KiB |
BIN
pdf/creator/testdata/cell-1_exp.png
vendored
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
pdf/creator/testdata/hendricks-1_exp.png
vendored
Normal file
After Width: | Height: | Size: 57 KiB |
BIN
pdf/creator/testdata/rotate_2-1_exp.png
vendored
Normal file
After Width: | Height: | Size: 50 KiB |
BIN
pdf/creator/testdata/table_border_req1_test-1_exp.png
vendored
Normal file
After Width: | Height: | Size: 34 KiB |
BIN
pdf/creator/testdata/tablecell_wrap-1_exp.png
vendored
Normal file
After Width: | Height: | Size: 97 KiB |
BIN
pdf/creator/testdata/template_1-1_exp.png
vendored
Normal file
After Width: | Height: | Size: 29 KiB |