mirror of
https://github.com/penpot/penpot.git
synced 2026-02-09 06:01:37 -05:00
Compare commits
4 Commits
develop
...
superalex-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5132e8819f | ||
|
|
ccfee34e76 | ||
|
|
6f3f2f9a71 | ||
|
|
ad5e8ccdb3 |
@@ -1,5 +1,11 @@
|
||||
# CHANGELOG
|
||||
|
||||
## 2.13.1
|
||||
|
||||
### :bug: Bugs fixed
|
||||
|
||||
- Fix PDF Exporter outputs empty page when board has A4 format [Taiga #13181](https://tree.taiga.io/project/penpot/issue/13181)
|
||||
|
||||
## 2.13.0
|
||||
|
||||
### :heart: Community contributions (Thank you!)
|
||||
|
||||
@@ -34,9 +34,7 @@
|
||||
javax.xml.XMLConstants
|
||||
javax.xml.parsers.SAXParserFactory
|
||||
org.apache.commons.io.IOUtils
|
||||
org.im4java.core.ConvertCmd
|
||||
org.im4java.core.IMOperation
|
||||
org.im4java.core.Info))
|
||||
org.im4java.core.ConvertCmd))
|
||||
|
||||
(def default-max-file-size
|
||||
(* 1024 1024 10)) ; 10 MiB
|
||||
@@ -224,17 +222,18 @@
|
||||
;; If we are processing an animated gif we use the first frame with -scene 0
|
||||
(let [dim-result (sh/sh "identify" "-format" "%w %h\n" path)
|
||||
orient-result (sh/sh "identify" "-format" "%[EXIF:Orientation]\n" path)]
|
||||
(if (and (= 0 (:exit dim-result))
|
||||
(= 0 (:exit orient-result)))
|
||||
(when (= 0 (:exit dim-result))
|
||||
(let [[w h] (-> (:out dim-result)
|
||||
str/trim
|
||||
(clojure.string/split #"\s+")
|
||||
(->> (mapv #(Integer/parseInt %))))
|
||||
orientation (-> orient-result :out str/trim)]
|
||||
(case orientation
|
||||
("6" "8") {:width h :height w} ; Rotated 90 or 270 degrees
|
||||
{:width w :height h})) ; Normal or unknown orientation
|
||||
nil)))
|
||||
orientation-exit (:exit orient-result)
|
||||
orientation (-> orient-result :out str/trim)]
|
||||
(if (= 0 orientation-exit)
|
||||
(case orientation
|
||||
("6" "8") {:width h :height w} ; Rotated 90 or 270 degrees
|
||||
{:width w :height h}) ; Normal or unknown orientation
|
||||
{:width w :height h}))))) ; If orientation can't be read, use dimensions as-is
|
||||
|
||||
(defmethod process :info
|
||||
[{:keys [input] :as params}]
|
||||
@@ -247,26 +246,37 @@
|
||||
:hint "uploaded svg does not provides dimensions"))
|
||||
(merge input info {:ts (ct/now) :size (fs/size path)}))
|
||||
|
||||
(let [instance (Info. (str path))
|
||||
mtype' (.getProperty instance "Mime type")]
|
||||
(let [path-str (str path)
|
||||
identify-res (sh/sh "identify" "-format" "image/%[magick]\n" path-str)
|
||||
;; identify prints one line per frame (animated GIFs, etc.); we take the first one
|
||||
mtype' (if (zero? (:exit identify-res))
|
||||
(-> identify-res
|
||||
:out
|
||||
str/trim
|
||||
(str/split #"\s+" 2)
|
||||
first
|
||||
str/lower)
|
||||
(ex/raise :type :validation
|
||||
:code :invalid-image
|
||||
:hint "invalid image"))
|
||||
{:keys [width height]}
|
||||
(or (get-dimensions-with-orientation path-str)
|
||||
(do
|
||||
(l/warn "Failed to read image dimensions with orientation" {:path path})
|
||||
(ex/raise :type :validation
|
||||
:code :invalid-image
|
||||
:hint "invalid image")))]
|
||||
(when (and (string? mtype)
|
||||
(not= mtype mtype'))
|
||||
(not= (str/lower mtype) mtype'))
|
||||
(ex/raise :type :validation
|
||||
:code :media-type-mismatch
|
||||
:hint (str "Seems like you are uploading a file whose content does not match the extension."
|
||||
"Expected: " mtype ". Got: " mtype')))
|
||||
(let [{:keys [width height]}
|
||||
(or (get-dimensions-with-orientation (str path))
|
||||
(do
|
||||
(l/warn "Failed to read image dimensions with orientation; falling back to im4java"
|
||||
{:path path})
|
||||
{:width (.getPageWidth instance)
|
||||
:height (.getPageHeight instance)}))]
|
||||
(assoc input
|
||||
:width width
|
||||
:height height
|
||||
:size (fs/size path)
|
||||
:ts (ct/now)))))))
|
||||
(assoc input
|
||||
:width width
|
||||
:height height
|
||||
:size (fs/size path)
|
||||
:ts (ct/now))))))
|
||||
|
||||
(defmethod process-error org.im4java.core.InfoException
|
||||
[error]
|
||||
|
||||
@@ -38,6 +38,24 @@
|
||||
(assoc :path "/render.html")
|
||||
(assoc :query (u/map->query-string params)))))
|
||||
|
||||
(sync-page-size! [dom]
|
||||
(bw/eval! dom
|
||||
(fn [elem]
|
||||
;; IMPORTANT: No CLJS runtime allowed. Use only JS
|
||||
;; primitives. This runs in a context without access to
|
||||
;; cljs.core. Avoid any functions that transpile to
|
||||
;; cljs.core/* calls, as they will break in the browser
|
||||
;; runtime.
|
||||
|
||||
(let [width (.getAttribute ^js elem "width")
|
||||
height (.getAttribute ^js elem "height")
|
||||
style-node (let [node (.createElement js/document "style")]
|
||||
(.appendChild (.-head js/document) node)
|
||||
node)]
|
||||
(set! (.-textContent style-node)
|
||||
(dm/str "@page { size: " width "px " height "px; margin: 0; }\n"
|
||||
"html, body, #app { margin: 0; padding: 0; width: " width "px; height: " height "px; overflow: visible; }"))))))
|
||||
|
||||
(render-object [page base-uri {:keys [id] :as object}]
|
||||
(p/let [uri (prepare-uri base-uri id)
|
||||
path (sh/tempfile :prefix "penpot.tmp.pdf." :suffix (mime/get-extension type))]
|
||||
@@ -45,6 +63,7 @@
|
||||
(bw/nav! page uri)
|
||||
(p/let [dom (bw/select page (dm/str "#screenshot-" id))]
|
||||
(bw/wait-for dom)
|
||||
(sync-page-size! dom)
|
||||
(bw/screenshot dom {:full-page? true})
|
||||
(bw/sleep page 2000) ; the good old fix with sleep
|
||||
(bw/pdf page {:path path})
|
||||
|
||||
Reference in New Issue
Block a user