github.com/pdfcpu/pdfcpu@v0.11.1/pkg/api/test/createFromJSON_test.go (about)

     1  /*
     2  Copyright 2023 The pdf Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8  	http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package test
    18  
    19  import (
    20  	"path/filepath"
    21  	"testing"
    22  
    23  	"github.com/pdfcpu/pdfcpu/pkg/api"
    24  	"github.com/pdfcpu/pdfcpu/pkg/pdfcpu/model"
    25  )
    26  
    27  /**************************************************************
    28   * All form related processing is optimized for Adobe Reader! *
    29   **************************************************************/
    30  
    31  func createPDF(t *testing.T, msg, inFile, inFileJSON, outFile string, conf *model.Configuration) {
    32  
    33  	t.Helper()
    34  
    35  	// inFile	inFileJSON 	outFile		action
    36  	// ---------------------------------------------------------------
    37  	// ""		jsonFile 	outfile		write outFile
    38  	// inFile 	jsonFile	""			update (read and write inFile)
    39  	// inFile 	jsonFile 	outFile		read inFile and write outFile
    40  
    41  	if outFile == "" {
    42  		outFile = inFile
    43  	}
    44  
    45  	if err := api.CreateFile(inFile, inFileJSON, outFile, conf); err != nil {
    46  		t.Fatalf("%s: %v\n", msg, err)
    47  	}
    48  
    49  	if err := api.ValidateFile(outFile, nil); err != nil {
    50  		t.Fatalf("%s: %v\n", msg, err)
    51  	}
    52  
    53  }
    54  
    55  func TestCreateContentPrimitivesViaJson(t *testing.T) {
    56  
    57  	t.Helper()
    58  	inDir := filepath.Join(inDir, "json", "create")
    59  	outDir := filepath.Join(samplesDir, "create", "primitives")
    60  
    61  	for _, tt := range []struct {
    62  		msg        string
    63  		inFileJSON string
    64  		outFile    string
    65  	}{
    66  		// Render page content samples.
    67  
    68  		// Font
    69  		{"TestFonts", "fonts.json", "fonts.pdf"},
    70  
    71  		// Text
    72  		{"TestTextAnchored", "textAnchored.json", "textAnchored.pdf"},
    73  		{"TestTextBordersAndPaddings", "textBordersAndPaddings.json", "textBordersAndPaddings.pdf"},
    74  		{"TestTextAlignment", "textAndAlignment.json", "textAndAlignment.pdf"},
    75  
    76  		// Image
    77  		{"TestImages", "images.json", "images.pdf"},
    78  		{"TestImagesOptimized", "imagesOptimized.json", "imagesOptimized.pdf"},
    79  		{"TestImagesDirsFiles", "imagesDirsFiles.json", "imagesDirsFiles.pdf"},
    80  
    81  		// Box
    82  		{"TestBoxesAndColors", "boxesAndColors.json", "boxesAndColors.pdf"},
    83  		{"TestBoxesAndMargin", "boxesAndMargin.json", "boxesAndMargin.pdf"},
    84  		{"TestBoxesAndRotation", "boxesAndRotation.json", "boxesAndRotation.pdf"},
    85  
    86  		// Table
    87  		{"TestTable", "table.json", "table.pdf"},
    88  		{"TestTableRTL", "tableRTL.json", "tableRTL.pdf"},
    89  		{"TestTableCJK", "tableCJK.json", "tableCJK.pdf"},
    90  
    91  		// Content Region
    92  		{"TestRegions", "regions.json", "regions.pdf"},
    93  		{"TestRegionsMarginBorderPadding", "regionsMargBordPadd.json", "regionsMarginBorderPadding.pdf"},
    94  	} {
    95  		inFileJSON := filepath.Join(inDir, tt.inFileJSON)
    96  		outFile := filepath.Join(outDir, tt.outFile)
    97  		createPDF(t, tt.msg, "", inFileJSON, outFile, conf)
    98  	}
    99  
   100  }
   101  
   102  func TestCreateFormPrimitivesViaJson(t *testing.T) {
   103  
   104  	inDirForm := filepath.Join(inDir, "json", "form")
   105  	outDirForm := filepath.Join(samplesDir, "form", "primitives")
   106  
   107  	for _, tt := range []struct {
   108  		msg        string
   109  		inFileJSON string
   110  		outFile    string
   111  	}{
   112  		// Render form field samples.
   113  
   114  		// Textfield
   115  		{"TestTextfield", "textfield.json", "textfield.pdf"},
   116  		{"TestTextfieldGroup", "textfieldGroup.json", "textfieldGroup.pdf"},
   117  		{"TestTextfieldGroupSingle", "textfieldGroupSingle.json", "textfieldGroupSingle.pdf"},
   118  
   119  		// Textarea
   120  		{"TestTextarea", "textarea.json", "textarea.pdf"},
   121  		{"TestTextareaGroup", "textareaGroup.json", "textareaGroup.pdf"},
   122  
   123  		// Datefield
   124  		{"TestDatefield", "datefield.json", "datefield.pdf"},
   125  		{"TestDatefieldGroup", "datefieldGroup.json", "datefieldGroup.pdf"},
   126  
   127  		// Checkbox
   128  		{"TestCheckbox", "checkbox.json", "checkbox.pdf"},
   129  		{"TestCheckboxGroup", "checkboxGroup.json", "checkboxGroup.pdf"},
   130  
   131  		// Radio button group
   132  		{"TestRadiobuttonsHor", "radiobuttonsHor.json", "radiobuttonsHor.pdf"},
   133  		{"TestRadiobuttonsHorGroup", "radiobuttonsHorGroup.json", "radiobuttonsHorGroup.pdf"},
   134  		{"TestRadiobuttonsVertLeft", "radiobuttonsVertL.json", "radiobuttonsVertL.pdf"},
   135  		{"TestRadiobuttonsVertLeftGroup", "radiobuttonsVertLGroup.json", "radiobuttonsVertLGroup.pdf"},
   136  		{"TestRadiobuttonsVertRight", "radiobuttonsVertR.json", "radiobuttonsVertR.pdf"},
   137  		{"TestRadiobuttonsVertRightGroup", "radiobuttonsVertRGroup.json", "radiobuttonsVertRGroup.pdf"},
   138  
   139  		// Combobox
   140  		{"TestCombobox", "combobox.json", "combobox.pdf"},
   141  		{"TestComboboxGroup", "comboboxGroup.json", "comboboxGroup.pdf"},
   142  
   143  		// Listbox
   144  		{"TestListbox", "listbox.json", "listbox.pdf"},
   145  		{"TestListboxGroup", "listboxGroup.json", "listboxGroup.pdf"},
   146  	} {
   147  		inFileJSON := filepath.Join(inDirForm, tt.inFileJSON)
   148  		outFile := filepath.Join(outDirForm, tt.outFile)
   149  		createPDF(t, tt.msg, "", inFileJSON, outFile, conf)
   150  	}
   151  
   152  }
   153  
   154  func TestCreateSinglePageDemoFormsViaJson(t *testing.T) {
   155  
   156  	// Render single page demo forms for export, reset, lock, unlock and fill tests.
   157  
   158  	inDirFormDemo := filepath.Join(inDir, "json", "form", "demoSinglePage")
   159  	outDirFormDemo := filepath.Join(samplesDir, "form", "demoSinglePage")
   160  
   161  	for _, tt := range []struct {
   162  		msg        string
   163  		inFileJSON string
   164  		outFile    string
   165  	}{
   166  		{"TestFormDemoEN", "english.json", "english.pdf"},             // Core font (Helvetica)
   167  		{"TestFormDemoUK", "ukrainian.json", "ukrainian.pdf"},         // User font (Roboto-Regular)
   168  		{"TestFormDemoAR", "arabic.json", "arabic.pdf"},               // User font RTL (Roboto-Regular)
   169  		{"TestFormDemoSC", "chineseSimple.json", "chineseSimple.pdf"}, // User font CJK (UnifontMedium)
   170  		{"TestPersonFormDemo", "person.json", "person.pdf"},           // Person Form
   171  	} {
   172  		inFileJSON := filepath.Join(inDirFormDemo, tt.inFileJSON)
   173  		outFile := filepath.Join(outDirFormDemo, tt.outFile)
   174  		createPDF(t, tt.msg, "", inFileJSON, outFile, conf)
   175  	}
   176  
   177  }
   178  
   179  func TestCreateDemoFormsViaJson(t *testing.T) {
   180  
   181  	inDirFormDemo := filepath.Join(inDir, "json", "form", "demo")
   182  	outDirFormDemo := filepath.Join(samplesDir, "form", "demo")
   183  
   184  	for _, tt := range []struct {
   185  		msg        string
   186  		inFileJSON string
   187  		outFile    string
   188  	}{
   189  		// Render demo forms.
   190  
   191  		// For corrections please open an issue on Github.
   192  
   193  		// Core font (Helvetica)
   194  		{"TestFormDemoDM", "danish.json", "danish.pdf"},
   195  		{"TestFormDemoNL", "dutch.json", "dutch.pdf"},
   196  		{"TestFormDemoEN", "english.json", "english.pdf"},
   197  		{"TestFormDemoFI", "finnish.json", "finnish.pdf"},
   198  		{"TestFormDemoFR", "french.json", "french.pdf"},
   199  		{"TestFormDemoDE", "german.json", "german.pdf"},
   200  		{"TestFormDemoHU", "hungarian.json", "hungarian.pdf"},
   201  		{"TestFormDemoIN", "indonesian.json", "indonesian.pdf"},
   202  		{"TestFormDemoIC", "icelandic.json", "icelandic.pdf"},
   203  		{"TestFormDemoIT", "italian.json", "italian.pdf"},
   204  		{"TestFormDemoNO", "norwegian.json", "norwegian.pdf"},
   205  		{"TestFormDemoPT", "portuguese.json", "portuguese.pdf"},
   206  		{"TestFormDemoSK", "slovak.json", "slovak.pdf"},
   207  		{"TestFormDemoSL", "slovenian.json", "slovenian.pdf"},
   208  		{"TestFormDemoES", "spanish.json", "spanish.pdf"},
   209  		{"TestFormDemoSWA", "swahili.json", "swahili.pdf"},
   210  		{"TestFormDemoSWE", "swedish.json", "swedish.pdf"},
   211  
   212  		// User font (Roboto-Regular)
   213  		{"TestFormDemoBR", "belarusian.json", "belarusian.pdf"},
   214  		{"TestFormDemoBG", "bulgarian.json", "bulgarian.pdf"},
   215  		{"TestFormDemoCR", "croatian.json", "croatian.pdf"},
   216  		{"TestFormDemoCZ", "czech.json", "czech.pdf"},
   217  		{"TestFormDemoGR", "greek.json", "greek.pdf"},
   218  		{"TestFormDemoKU", "kurdish.json", "kurdish.pdf"},
   219  		{"TestFormDemoPO", "polish.json", "polish.pdf"},
   220  		{"TestFormDemoRO", "romanian.json", "romanian.pdf"},
   221  		{"TestFormDemoRU", "russian.json", "russian.pdf"},
   222  		{"TestFormDemoTK", "turkish.json", "turkish.pdf"},
   223  		{"TestFormDemoUK", "ukrainian.json", "ukrainian.pdf"},
   224  		{"TestFormDemoVI", "vietnamese.json", "vietnamese.pdf"},
   225  
   226  		// User font (UnifontMedium)
   227  		{"TestFormDemoAR", "arabic.json", "arabic.pdf"},
   228  		{"TestFormDemoARM", "armenian.json", "armenian.pdf"},
   229  		{"TestFormDemoAZ", "azerbaijani.json", "azerbaijani.pdf"},
   230  		{"TestFormDemoBA", "bangla.json", "bangla.pdf"},
   231  		{"TestFormDemoSC", "chineseSimple.json", "chineseSimple.pdf"},
   232  		{"TestFormDemoTC", "chineseTrad.json", "chineseTraditional.pdf"},
   233  		{"TestFormDemoHE", "hebrew.json", "hebrew.pdf"},
   234  		{"TestFormDemoHI", "hindi.json", "hindi.pdf"},
   235  		{"TestFormDemoJP", "japanese.json", "japanese.pdf"},
   236  		{"TestFormDemoKR", "korean.json", "korean.pdf"},
   237  		{"TestFormDemoMA", "marathi.json", "marathi.pdf"},
   238  		{"TestFormDemoPE", "persian.json", "persian.pdf"},
   239  		{"TestFormDemoUR", "thai.json", "thai.pdf"},
   240  		{"TestFormDemoUR", "urdu.json", "urdu.pdf"},
   241  	} {
   242  		inFileJSON := filepath.Join(inDirFormDemo, tt.inFileJSON)
   243  		outFile := filepath.Join(outDirFormDemo, tt.outFile)
   244  		createPDF(t, tt.msg, "", inFileJSON, outFile, conf)
   245  	}
   246  
   247  }
   248  
   249  func TestCreateAndUpdatePageViaJson(t *testing.T) {
   250  
   251  	// CREATE PDF, UPDATE/ADD PAGE
   252  	// 1. Create PDF page
   253  	// 2. Add textbox and reuse corefont/userfont/cjkfont
   254  	// 	 a) from same page
   255  	// 	 b) on different page
   256  
   257  	jsonDir := filepath.Join(inDir, "json", "create", "flow")
   258  	outDir := filepath.Join(samplesDir, "create", "flow")
   259  
   260  	// Create PDF in outDir.
   261  	inFileJSON1 := filepath.Join(jsonDir, "createPage.json")
   262  	file := filepath.Join(outDir, "createAndUpdatePage.pdf")
   263  	createPDF(t, "pass1", "", inFileJSON1, file, conf)
   264  
   265  	// Update PDF in outDir: reuse fonts from (same) page 1
   266  	inFileJSON2 := filepath.Join(jsonDir, "updatePage1.json")
   267  	createPDF(t, "pass2", file, inFileJSON2, file, conf)
   268  
   269  	// Update PDF in outDir: reuse fonts from (different) page 1
   270  	inFileJSON3 := filepath.Join(jsonDir, "updatePage2.json")
   271  	createPDF(t, "pass2", file, inFileJSON3, file, conf)
   272  }
   273  
   274  func TestReadAndUpdatePageViaJson(t *testing.T) {
   275  
   276  	// READ PDF, UPDATE/ADD PAGE
   277  	// 1. Read any PDF
   278  	// 2. Add textbox and reuse corefont/userfont/cjkfont
   279  	// 	 a) from same page
   280  	// 	 b) on different page
   281  
   282  	jsonDir := filepath.Join(inDir, "json", "create", "flow")
   283  	outDir := filepath.Join(samplesDir, "create", "flow")
   284  
   285  	// Update PDF in outDir.
   286  	inFile := filepath.Join(inDir, "Walden.pdf")
   287  	inFileJSON1 := filepath.Join(jsonDir, "updateAnyPage1.json")
   288  	outFile := filepath.Join(outDir, "readAndUpdatePage.pdf")
   289  	createPDF(t, "pass", inFile, inFileJSON1, outFile, conf)
   290  
   291  	// Update PDF in outDir: reuse fonts from (different) page 1 and create new page
   292  	inFileJSON2 := filepath.Join(jsonDir, "updateAnyPage2.json")
   293  	createPDF(t, "pass2", outFile, inFileJSON2, outFile, conf)
   294  }
   295  
   296  func TestCreateFormAndUpdatePageViaJson(t *testing.T) {
   297  
   298  	// CREATE FORM, UPDATE/ADD PAGE
   299  	// 1. Create PDF form
   300  	// 2. Add content
   301  
   302  	jsonDir := filepath.Join(inDir, "json", "form")
   303  	outDir := filepath.Join(samplesDir, "form", "flow")
   304  
   305  	// Create PDF form in outDir and add content using corefont.
   306  	inFileJSON1 := filepath.Join(jsonDir, "demo", "english.json")
   307  	file := filepath.Join(outDir, "createFormAndUpdatePageCoreFont.pdf")
   308  	createPDF(t, "pass1", "", inFileJSON1, file, conf)
   309  	// Update PDF form in outDir reusing page font.
   310  	inFileJSON2 := filepath.Join(jsonDir, "flow", "updatePageCoreFont.json")
   311  	createPDF(t, "pass2", file, inFileJSON2, file, conf)
   312  
   313  	// Create PDF form in outDir and add content using userfont.
   314  	inFileJSON1 = filepath.Join(jsonDir, "demo", "ukrainian.json")
   315  	file = filepath.Join(outDir, "createFormAndUpdatePageUserFont.pdf")
   316  	createPDF(t, "pass1", "", inFileJSON1, file, conf)
   317  	// Update PDF form in outDir reusing page font.
   318  	inFileJSON2 = filepath.Join(jsonDir, "flow", "updatePageUserFont.json")
   319  	createPDF(t, "pass2", file, inFileJSON2, file, conf)
   320  
   321  	// Create PDF form in outDir and add content using CJK userfont.
   322  	inFileJSON1 = filepath.Join(jsonDir, "demo", "chineseSimple.json")
   323  	file = filepath.Join(outDir, "createFormAndUpdatePageCJKUserFont.pdf")
   324  	createPDF(t, "pass1", "", inFileJSON1, file, conf)
   325  	// Update PDF form in outDir reusing page font.
   326  	inFileJSON2 = filepath.Join(jsonDir, "flow", "updatePageCJKUserFont.json")
   327  	createPDF(t, "pass2", file, inFileJSON2, file, conf)
   328  }
   329  
   330  func TestReadFormAndUpdateFormViaJson(t *testing.T) {
   331  
   332  	// READ FORM, UPDATE FORM
   333  	// 1. Read PDF form
   334  	// 2. Add fields
   335  
   336  	jsonDir := filepath.Join(inDir, "json", "form", "flow")
   337  	outDir := filepath.Join(samplesDir, "form", "flow")
   338  
   339  	// Read demo form and update with corefont in outDir.
   340  	inFile := filepath.Join(samplesDir, "form", "demo", "english.pdf")
   341  	inFileJSON := filepath.Join(jsonDir, "updateFormCoreFont.json")
   342  	outFile := filepath.Join(outDir, "readFormAndUpdateFormCoreFont.pdf")
   343  	createPDF(t, "pass1", inFile, inFileJSON, outFile, conf)
   344  
   345  	// Read demo form and update with userfont in outDir.
   346  	inFile = filepath.Join(samplesDir, "form", "demo", "ukrainian.pdf")
   347  	inFileJSON = filepath.Join(jsonDir, "updateFormUserFont.json")
   348  	outFile = filepath.Join(outDir, "readFormAndUpdateFormUserFont.pdf")
   349  	createPDF(t, "pass1", inFile, inFileJSON, outFile, conf)
   350  
   351  	// Read demo form and update with CJK userfont in outDir.
   352  	inFile = filepath.Join(samplesDir, "form", "demo", "chineseSimple.pdf")
   353  	inFileJSON = filepath.Join(jsonDir, "updateFormCJK.json")
   354  	outFile = filepath.Join(outDir, "readFormAndUpdateFormCJK.pdf")
   355  	createPDF(t, "pass1", inFile, inFileJSON, outFile, conf)
   356  }