diff --git a/src/clj_htmltopdf/watermark.clj b/src/clj_htmltopdf/watermark.clj
index ef46dae..941b27f 100644
--- a/src/clj_htmltopdf/watermark.clj
+++ b/src/clj_htmltopdf/watermark.clj
@@ -1,9 +1,12 @@
(ns clj-htmltopdf.watermark
+ (:require
+ [clojure.java.io :as io])
(:import
[java.io InputStream OutputStream]
[org.apache.pdfbox.pdmodel PDDocument PDPage PDPageContentStream PDPageContentStream$AppendMode]
[org.apache.pdfbox.pdmodel.common PDRectangle]
[org.apache.pdfbox.pdmodel.font PDType1Font PDFont]
+ [org.apache.pdfbox.pdmodel.graphics.image PDImageXObject PDImage]
[org.apache.pdfbox.pdmodel.graphics.state PDExtendedGraphicsState]
[org.apache.pdfbox.util Matrix]))
@@ -24,25 +27,25 @@
"courier-oblique" PDType1Font/COURIER_OBLIQUE
"courier-boldoblique" PDType1Font/COURIER_BOLD_OBLIQUE})
-(defn render-watermark!
- [^PDPage page ^PDPageContentStream cs options]
- (let [font (or (get watermark-fonts (:font options))
- (get watermark-fonts "helvetica-bold"))
- font-size (float (or (:font-size options) 36.0))
- font-color (or (:color options) [0 0 0])
- text (:text options)
- text-width (/ (* (.getStringWidth font text) font-size) 1000.0)
- text-height (/ (* (.getHeight (.getFontBoundingBox (.getFontDescriptor ^PDFont font))) font-size) 1000.0)
- rotation (float (or (:rotation options) 0))
- page-size (.getMediaBox page)
- page-width (.getWidth page-size)
- page-height (.getHeight page-size)
- x (if (= :center (:x options)) (/ page-width 2) (float (:x options)))
- y (if (= :center (:y options)) (/ page-height 2) (float (:y options)))
- transform (doto (Matrix.)
- (.translate x y)
- (.rotate (Math/toRadians rotation))
- (.translate (- (/ text-width 2)) (- (/ text-height 2))))]
+(defn render-text-watermark!
+ [^PDDocument doc ^PDPage page ^PDPageContentStream cs options]
+ (let [font (or (get watermark-fonts (:font options))
+ (get watermark-fonts "helvetica-bold"))
+ font-size (float (or (:font-size options) 36.0))
+ font-color (or (:color options) [0 0 0])
+ text (:text options)
+ text-width (/ (* (.getStringWidth font text) font-size) 1000.0)
+ text-height (/ (* (.getHeight (.getFontBoundingBox (.getFontDescriptor ^PDFont font))) font-size) 1000.0)
+ rotation (float (or (:rotation options) 0))
+ page-size (.getMediaBox page)
+ page-width (.getWidth page-size)
+ page-height (.getHeight page-size)
+ x (if (= :center (:x options)) (/ page-width 2) (float (:x options)))
+ y (if (= :center (:y options)) (/ page-height 2) (float (:y options)))
+ transform (doto (Matrix.)
+ (.translate x y)
+ (.rotate (Math/toRadians rotation))
+ (.translate (- (/ text-width 2)) (- (/ text-height 2))))]
(when (:opacity options)
(let [r0 (PDExtendedGraphicsState.)]
(.setNonStrokingAlphaConstant r0 (float (:opacity options)))
@@ -54,6 +57,36 @@
(.showText cs text)
(.endText cs)))
+(defn render-image-watermark!
+ [^PDDocument doc ^PDPage page ^PDPageContentStream cs options]
+ (let [image (PDImageXObject/createFromFileByContent (io/file (:image options)) doc)
+ image-width (.getWidth image)
+ image-height (.getHeight image)
+ rotation (float (or (:rotation options) 0))
+ page-size (.getMediaBox page)
+ page-width (.getWidth page-size)
+ page-height (.getHeight page-size)
+ x (if (= :center (:x options)) (/ page-width 2) (float (:x options)))
+ y (if (= :center (:y options)) (/ page-height 2) (float (:y options)))
+ transform (doto (Matrix.)
+ (.translate x y)
+ (.scale (or (:scale-x options) 1.0) (or (:scale-y options) 1.0))
+ (.rotate (Math/toRadians rotation))
+ (.translate (- (/ image-width 2)) (- (/ image-height 2))))]
+ (when (:opacity options)
+ (let [r0 (PDExtendedGraphicsState.)]
+ (.setNonStrokingAlphaConstant r0 (float (:opacity options)))
+ (.setGraphicsStateParameters cs r0)))
+ (.transform cs transform)
+ (.drawImage cs image (float 0) (float 0))))
+
+(defn render-watermark!
+ [^PDDocument doc ^PDPage page ^PDPageContentStream cs options]
+ (cond
+ (:text options) (render-text-watermark! doc page cs options)
+ (:image options) (render-image-watermark! doc page cs options)
+ :else (throw (Exception. "Unknown type of watermark. Either :text or :image should be specified."))))
+
(defn write-watermark!
[^InputStream pdf ^OutputStream out {:keys [watermark] :as options}]
(with-open [doc (PDDocument/load pdf)]
@@ -61,7 +94,7 @@
(let [cs (PDPageContentStream. doc page PDPageContentStream$AppendMode/APPEND true true)]
(with-open [cs cs]
(if (map? watermark)
- (render-watermark! page cs watermark)
- (watermark page cs)))))
+ (render-watermark! doc page cs watermark)
+ (watermark doc page cs)))))
(.save doc out)
out))