From e31293ef2b08cf9cc361b2e31d09c7b9a925dc63 Mon Sep 17 00:00:00 2001 From: Paulo Coutinho Date: Fri, 11 Mar 2022 19:53:00 -0300 Subject: [PATCH 1/3] updated to version 4938 --- docker/android/Dockerfile | 2 +- docker/wasm/Dockerfile | 2 +- extras/wasm/template/index.html | 144 ++++++++++++++++---------------- modules/config.py | 6 +- modules/ios.py | 1 + 5 files changed, 79 insertions(+), 76 deletions(-) diff --git a/docker/android/Dockerfile b/docker/android/Dockerfile index 5569b35..5d7b5ff 100644 --- a/docker/android/Dockerfile +++ b/docker/android/Dockerfile @@ -58,7 +58,7 @@ WORKDIR /build RUN gclient config --unmanaged https://pdfium.googlesource.com/pdfium.git RUN gclient sync WORKDIR /build/pdfium -RUN git checkout 187d077faebb81a2bbc11d777ece46830cf5cd8f +RUN git checkout 626a3abbc9d53135270afbc2f4e9b5de2b5c59ce RUN ln -s /usr/bin/python3 /usr/bin/python RUN ln -s /usr/bin/pip3 /usr/bin/pip diff --git a/docker/wasm/Dockerfile b/docker/wasm/Dockerfile index f0eb9a6..dddb79f 100644 --- a/docker/wasm/Dockerfile +++ b/docker/wasm/Dockerfile @@ -37,7 +37,7 @@ WORKDIR /build RUN gclient config --unmanaged https://pdfium.googlesource.com/pdfium.git RUN gclient sync WORKDIR /build/pdfium -RUN git checkout 187d077faebb81a2bbc11d777ece46830cf5cd8f +RUN git checkout 626a3abbc9d53135270afbc2f4e9b5de2b5c59ce RUN ln -s /usr/bin/python3 /usr/bin/python RUN ln -s /usr/bin/pip3 /usr/bin/pip diff --git a/extras/wasm/template/index.html b/extras/wasm/template/index.html index aa0e29b..aa12390 100644 --- a/extras/wasm/template/index.html +++ b/extras/wasm/template/index.html @@ -23,10 +23,10 @@ let moduleLoaded = false; let debugMode = false; let autoOpenMode = true; - - // pdfium initialization + let doc; let FPDF = {}; + // pdfium initialization Object.assign(FPDF, { ANNOT: 0x01, // Set if annotations are to be rendered. LCD_TEXT: 0x02, // Set if using text rendering optimized for LCD display. @@ -80,74 +80,7 @@ const F = FPDF.Bitmap_BGRA; const C = 4; - // runtime initialized - Module.onRuntimeInitialized = async _ => { - moduleLoaded = true; - - if (pageLoaded) { - console.log('The module was loaded!'); - } - - checkIfEverythingWasLoaded(); - }; - - // functions - async function loadFile() { - try { - changeButton('Loading file from input...', 'warning'); - - resetOnLoad(); - - let files = fileInput.files; - - if (files.length <= 0) { - throw { message: "Select a PDF file or type a public PDF url" }; - } - - let file = files[0]; - - let fileByteArray = await fileToByteArray(file); - - if (fileByteArray.length <= 0) { - throw { message: "The PDF file is invalid" }; - } - - changeButton('Processing file...', 'warning'); - - setTimeout(function () { - processPDF(fileByteArray); - }, 300); - } catch (error) { - changeButton('Error while load file', 'danger'); - console.log('Error while load file: ' + error.message); - } - } - - async function loadFileFromURL(url) { - try { - changeButton('Loading file from URL...', 'warning'); - - resetOnLoad(); - - let response = await fetch(url); - let fileBuffer = await response.arrayBuffer(); - let fileByteArray = new Uint8Array(fileBuffer); - - if (fileByteArray.length <= 0) { - throw { message: "The PDF file is invalid" }; - } - - changeButton('Processing file...', 'warning'); - - setTimeout(function () { - processPDF(fileByteArray); - }, 300); - } catch (error) { - changeButton('Error while load file from URL', 'danger'); - console.log('Error while load file from URL: ' + error.message); - } - } - + // classes class Page { constructor(index, o) { this.index = index; @@ -212,6 +145,7 @@ getPage(index) { let page = this.pages[index]; + if (!page) { page = new Page(index); this.pages[index] = page; @@ -223,6 +157,7 @@ renderPages() { const wasmBuffer = this.o.wasmBuffer; const wasm = this.o.wasm; + doc.pages.forEach(async function (page, index) { if (!page.loaded) { setTimeout(function () { @@ -242,6 +177,7 @@ let images = pageList.querySelectorAll(".column img"); let width = images[0].offsetWidth + "px"; let height = images[0].offsetHeight + "px"; + images.forEach((img) => { if (!img.getAttribute("src")) { img.style.width = width; @@ -251,7 +187,73 @@ } } - let doc; + // runtime initialized + Module.onRuntimeInitialized = async _ => { + moduleLoaded = true; + + if (pageLoaded) { + console.log('The module was loaded!'); + } + + checkIfEverythingWasLoaded(); + }; + + // functions + async function loadFile() { + try { + changeButton('Loading file from input...', 'warning'); + + resetOnLoad(); + + let files = fileInput.files; + + if (files.length <= 0) { + throw { message: "Select a PDF file or type a public PDF url" }; + } + + let file = files[0]; + + let fileByteArray = await fileToByteArray(file); + + if (fileByteArray.length <= 0) { + throw { message: "The PDF file is invalid" }; + } + + changeButton('Processing file...', 'warning'); + + setTimeout(function () { + processPDF(fileByteArray); + }, 300); + } catch (error) { + changeButton('Error while load file', 'danger'); + console.log('Error while load file: ' + error.message); + } + } + + async function loadFileFromURL(url) { + try { + changeButton('Loading file from URL...', 'warning'); + + resetOnLoad(); + + let response = await fetch(url); + let fileBuffer = await response.arrayBuffer(); + let fileByteArray = new Uint8Array(fileBuffer); + + if (fileByteArray.length <= 0) { + throw { message: "The PDF file is invalid" }; + } + + changeButton('Processing file...', 'warning'); + + setTimeout(function () { + processPDF(fileByteArray); + }, 300); + } catch (error) { + changeButton('Error while load file from URL', 'danger'); + console.log('Error while load file from URL: ' + error.message); + } + } async function processPDF(fileByteArray) { try { diff --git a/modules/config.py b/modules/config.py index ac64cf2..413e0aa 100644 --- a/modules/config.py +++ b/modules/config.py @@ -3,9 +3,9 @@ task = "" # pdfium -pdfium_git_branch = "4795" -pdfium_git_commit = "187d077faebb81a2bbc11d777ece46830cf5cd8f" -# ^ ref: https://pdfium.googlesource.com/pdfium/+/refs/heads/chromium/4795 +pdfium_git_branch = "4938" +pdfium_git_commit = "626a3abbc9d53135270afbc2f4e9b5de2b5c59ce" +# ^ ref: https://pdfium.googlesource.com/pdfium/+/refs/heads/chromium/4938 # OBS 1: don't forget change in android docker file (docker/android/Dockerfile) # OBS 2: don't forget change in wasm docker file (docker/wasm/Dockerfile) diff --git a/modules/ios.py b/modules/ios.py index a3ee2c8..0b48a6c 100644 --- a/modules/ios.py +++ b/modules/ios.py @@ -418,6 +418,7 @@ def run_task_build(): args.append("ios_enable_code_signing=false") args.append("use_xcode_clang=true") args.append("pdf_is_complete_lib=true") + args.append("use_custom_libcxx=false") if target["target_cpu"] == "arm": args.append("enable_ios_bitcode=true") From ed8a32f82960d18014468f782dcc0c05e5c8c223 Mon Sep 17 00:00:00 2001 From: Paulo Coutinho Date: Fri, 11 Mar 2022 19:53:50 -0300 Subject: [PATCH 2/3] updated to version 4938 --- README.md | 14 +++++++------- extras/wasm/template/README.md | 2 +- extras/wasm/template/index.html | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 75cc1d9..9bb60a1 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@

- + PDFium Library Logo

@@ -7,10 +7,10 @@

PDFium Library

- PDFium - iOS - PDFium - macOS - PDFium - Android - PDFium - WASM + PDFium - iOS + PDFium - macOS + PDFium - Android + PDFium - WASM

@@ -58,7 +58,7 @@ These are the `general` steps that need be executed `before all` others platform 1. Get the source: ``` -git clone https://github.com/paulo-coutinho/pdfium-lib.git +git clone https://github.com/paulocoutinhox/pdfium-lib.git cd pdfium-lib ``` @@ -101,7 +101,7 @@ Check tutorial here: [Build for WASM](docs/BUILD_WASM.md) Access releases page to download prebuilt binaries: -https://github.com/paulo-coutinho/pdfium-lib/releases +https://github.com/paulocoutinhox/pdfium-lib/releases ## How to include files and extend pdfium diff --git a/extras/wasm/template/README.md b/extras/wasm/template/README.md index 57891c2..4e7fb0f 100644 --- a/extras/wasm/template/README.md +++ b/extras/wasm/template/README.md @@ -21,6 +21,6 @@ Example: The main project is hosted here: -[https://github.com/paulo-coutinho/pdfium-lib](https://github.com/paulo-coutinho/pdfium-lib) +[https://github.com/paulocoutinhox/pdfium-lib](https://github.com/paulocoutinhox/pdfium-lib) The PDF Viewer use PDFium project from Google to parse PDF data and render final image. diff --git a/extras/wasm/template/index.html b/extras/wasm/template/index.html index aa12390..230e2ca 100644 --- a/extras/wasm/template/index.html +++ b/extras/wasm/template/index.html @@ -1177,7 +1177,7 @@

PDF Viewer

This application is powered by an open source project called PDF Viewer and can be found here. No data is stored and + target="_blank" href="https://github.com/paulocoutinhox/pdfium-lib">here. No data is stored and everything run only on client side.

From 58548b9adb3d1b05fc942f3b562b9049e8087a0c Mon Sep 17 00:00:00 2001 From: Paulo Coutinho Date: Fri, 11 Mar 2022 21:05:58 -0300 Subject: [PATCH 3/3] updated to version 4938 --- extras/wasm/template/index.html | 203 +++++++++++++++++--------------- modules/android.py | 8 ++ 2 files changed, 117 insertions(+), 94 deletions(-) diff --git a/extras/wasm/template/index.html b/extras/wasm/template/index.html index 230e2ca..011ddeb 100644 --- a/extras/wasm/template/index.html +++ b/extras/wasm/template/index.html @@ -82,15 +82,16 @@ // classes class Page { - constructor(index, o) { + constructor(index, processor) { this.index = index; this.src = null; - this.o = o; + this.processor = processor; } render() { let canvas = document.createElement('canvas'); - this.o.render(this.index, canvas, 3.0, 90); + this.processor.render(this.index, canvas, 3.0, 90); + let dataUri = canvas.toDataURL(); this.updateImage(dataUri); } @@ -98,9 +99,10 @@ createImage() { let image = document.createElement('img'); let pageIndex = this.index; + image.id = "pageImage" + (pageIndex + 1); image.src = ''; - image.className = "page-list-item"; + image.className = "is-invisible page-list-item"; return image; } @@ -112,6 +114,7 @@ let pageIndex = this.index; let image = document.getElementById("pageImage" + (pageIndex + 1)); image.src = dataUri; + image.classList.remove("is-invisible"); image.onclick = function () { openModal(); changeCurrentPageItem(pageIndex + 1); @@ -119,6 +122,7 @@ const container = image.closest('.column'); const loaderWrapper = container.querySelector('.page-loader-wrapper'); + if (loaderWrapper) { container.removeChild(loaderWrapper); } @@ -129,17 +133,103 @@ } } + class Processor { + constructor(wasmData) { + this.wasmData = wasmData; + } + + getPageSize(i = 0, s = 2) { + return H(F64, 2, [-1, -1])((w, h) => FPDF.GetPageSizeByIndex(this.wasmData.wasm, i, w, h)).map(v => parseInt(v) * s); + } + + getRender(i = 0, w, h) { + const flag = FPDF.REVERSE_BYTE_ORDER | FPDF.ANNOT; + const heap = Module._malloc(w * h * C); + + for (let i = 0; i < w * h * C; i++) { + Module.HEAPU8[heap + i] = 0; + } + + const bmap = FPDF.Bitmap_CreateEx(w, h, F, heap, w * C); + const page = FPDF.LoadPage(this.wasmData.wasm, i); + + FPDF.Bitmap_FillRect(bmap, 0, 0, w, h, 0xFFFFFFFF); + FPDF.RenderPageBitmap(bmap, page, 0, 0, w, h, 0, flag); + FPDF.Bitmap_Destroy(bmap); + FPDF.ClosePage(page); + + return heap; + } + + getPageRender(n = 0, w, h) { + let pageRenderPtr = this.getRender(n, w, h); + let pageRenderData = []; + + for (let v = 0; v < w * h * C; v++) { + pageRenderData.push(Module.HEAPU8[pageRenderPtr + v]); + } + + Module._free(pageRenderPtr); + + return pageRenderData; + } + + render(n = 0, canvas, scale, rotation) { + const [w, h] = this.getPageSize(n, scale, rotation); + const data = this.getPageRender(n, w, h, rotation); + + canvas.width = w; + canvas.height = h; + + const x = canvas.getContext('2d'); + const i = x.createImageData(w, h); + i.data.set(data); + x.putImageData(i, 0, 0); + } + + getLastError() { + let lastError = FPDF.GetLastError(); + + switch (lastError) { + case FPDF.LAST_ERROR.SUCCESS: + return "success"; + break; + case FPDF.LAST_ERROR.UNKNOWN: + return "unknown error"; + break; + case FPDF.LAST_ERROR.FILE: + return "file not found or could not be opened"; + break; + case FPDF.LAST_ERROR.FORMAT: + return "file not in PDF format or corrupted"; + break; + case FPDF.LAST_ERROR.PASSWORD: + return "password required or incorrect password"; + break; + case FPDF.LAST_ERROR.SECURITY: + return "unsupported security scheme"; + break; + case FPDF.LAST_ERROR.PAGE: + return "page not found or content error"; + break; + default: + return "unknown error"; + } + } + } + class Doc { - constructor(pagesCount, o) { - this.pages = Array(pagesCount).fill(null) - this.o = o; + constructor(wasmData) { + this.processor = new Processor(wasmData); + } - this.onCreate(); + setPages(pagesCount) { + this.pages = Array(pagesCount).fill(null); } - onCreate() { + createAllPages() { for (let i = 0; i < this.pages.length; i++) { - this.pages[i] = new Page(i, this.o); + this.pages[i] = new Page(i, this.processor); } } @@ -155,13 +245,14 @@ } renderPages() { - const wasmBuffer = this.o.wasmBuffer; - const wasm = this.o.wasm; + const wasmBuffer = this.processor.wasmData.wasmBuffer; + const wasm = this.processor.wasmData.wasm; doc.pages.forEach(async function (page, index) { if (!page.loaded) { setTimeout(function () { page.render(); + if (index === doc.pages.length - 1) { Module._free(wasmBuffer); @@ -287,103 +378,27 @@ // create document console.log('Loading document...'); - let o = { + doc = new Doc({ wasm: FPDF.LoadMemDocument(wasmBuffer, fileSize, ""), wasmBuffer: wasmBuffer, - }; - - o.getPageSize = (i = 0, s = 2) => H(F64, 2, [-1, -1])((w, h) => FPDF.GetPageSizeByIndex(o.wasm, i, w, h)).map(v => parseInt(v) * s); - - o.getRender = function (i = 0, w, h) { - const flag = FPDF.REVERSE_BYTE_ORDER | FPDF.ANNOT; - const heap = Module._malloc(w * h * C); - - for (let i = 0; i < w * h * C; i++) { - Module.HEAPU8[heap + i] = 0; - } - - const bmap = FPDF.Bitmap_CreateEx(w, h, F, heap, w * C); - const page = FPDF.LoadPage(this.wasm, i); - - FPDF.Bitmap_FillRect(bmap, 0, 0, w, h, 0xFFFFFFFF); - FPDF.RenderPageBitmap(bmap, page, 0, 0, w, h, 0, flag); - FPDF.Bitmap_Destroy(bmap); - FPDF.ClosePage(page); - - return heap; - }; - - o.getPageRender = function (n = 0, w, h) { - let pageRenderPtr = this.getRender(n, w, h); - let pageRenderData = []; - - for (let v = 0; v < w * h * C; v++) { - pageRenderData.push(Module.HEAPU8[pageRenderPtr + v]); - } - - Module._free(pageRenderPtr); - - return pageRenderData; - }; - - o.render = function (n = 0, canvas, scale, rotation) { - const [w, h] = this.getPageSize(n, scale, rotation); - const data = this.getPageRender(n, w, h, rotation); - - canvas.width = w; - canvas.height = h; - - const x = canvas.getContext('2d'); - const i = x.createImageData(w, h); - i.data.set(data); - x.putImageData(i, 0, 0); - }; - - o.getLastError = function () { - let lastError = FPDF.GetLastError(); - - switch (lastError) { - case FPDF.LAST_ERROR.SUCCESS: - return "success"; - break; - case FPDF.LAST_ERROR.UNKNOWN: - return "unknown error"; - break; - case FPDF.LAST_ERROR.FILE: - return "file not found or could not be opened"; - break; - case FPDF.LAST_ERROR.FORMAT: - return "file not in PDF format or corrupted"; - break; - case FPDF.LAST_ERROR.PASSWORD: - return "password required or incorrect password"; - break; - case FPDF.LAST_ERROR.SECURITY: - return "unsupported security scheme"; - break; - case FPDF.LAST_ERROR.PAGE: - return "page not found or content error"; - break; - default: - return "unknown error"; - } - } + }); // check last error - let lastError = o.getLastError(); + let lastError = doc.processor.getLastError(); console.log("Load document state: " + lastError); // count page console.log('Couting pages...'); - let pages = FPDF.GetPageCount(o.wasm); + let pages = FPDF.GetPageCount(doc.processor.wasmData.wasm); console.log('Pages: ' + pages); // list all pages if (pages > 0) { console.log('Rendering ' + pages + ' PDF pages...'); - doc = new Doc(pages, o); + doc.setPages(pages); + doc.createAllPages(); for (let x = 0; x < pages; x++) { console.log('Rendering page ' + (x + 1) + '...'); diff --git a/modules/android.py b/modules/android.py index 8ed8cc6..665b4c8 100644 --- a/modules/android.py +++ b/modules/android.py @@ -62,6 +62,14 @@ def run_task_patch(): f.set_file_line_content(source_file, line_number, content, new_line=True) + # more one + line_number = f.get_file_line_number_with_content( + source_file, line_content, strip=True + ) + + f.set_file_line_content(source_file, line_number, content, new_line=True) + + # more one line_number = f.get_file_line_number_with_content( source_file, line_content, strip=True )