Mercurial > hg > indyvon
changeset 16:0fda22fc53d2
Remove anchor from Layer protocol.
More function text layout calculation.
author | Mikhail Kryshen <mikhail@kryshen.net> |
---|---|
date | Thu, 17 Jun 2010 05:20:37 +0400 |
parents | 87bd822aa815 |
children | 31382464ef27 |
files | src/indyvon/component.clj src/indyvon/core.clj |
diffstat | 2 files changed, 31 insertions(+), 65 deletions(-) [+] |
line wrap: on
line diff
--- a/src/indyvon/component.clj Tue Jun 15 06:31:11 2010 +0400 +++ b/src/indyvon/component.clj Thu Jun 17 05:20:37 2010 +0400 @@ -47,7 +47,7 @@ (do (def frame (java.awt.Frame. "Test")) (def layer1 - (reify-layer + (reify Layer (render! [this context g] (register-context context) (.setColor g Color/RED) @@ -55,7 +55,7 @@ (size [this context] [30 20]))) (def layer1b (border-layer layer1 2 3)) (def layer2 - (reify-layer + (reify Layer (render! [this context g] (register-context context) (.setColor g Color/YELLOW) @@ -66,7 +66,7 @@ (def layer3 (border-layer (text-layer "Sample\ntext" :right :bottom))) (def layer - (reify-layer + (reify Layer (render! [this context g] (.drawLine g 0 0 (:width context) (:height context)) (draw! context layer2 g 15 20)
--- a/src/indyvon/core.clj Tue Jun 15 06:31:11 2010 +0400 +++ b/src/indyvon/core.clj Thu Jun 17 05:20:37 2010 +0400 @@ -10,8 +10,7 @@ (defprotocol Layer (render! [this context graphics]) - (size [this context]) - (anchor [this context])) + (size [this context])) (defrecord Theme [fore-color back-color border-color font]) @@ -24,25 +23,6 @@ (defn default-context [] (LayerContext. nil nil 0 0 0 0 nil nil nil (default-theme))) -(defn- spec-map - ([specs] - (spec-map {} specs)) - ([mm specs] - (if-let [form (first specs)] - (recur (conj mm [(first form) (next form)]) - (next specs)) - mm))) - -(defn- merge-specs [s1 s2] - (for [spec (spec-map (spec-map s1) s2)] - (cons (first spec) (second spec)))) - -(defmacro reify-layer [& specs] - `(reify Layer ~@(merge-specs - '((size [_ _] [0 0]) - (anchor [_ _] [0 0])) - specs))) - (defn- make-graphics [graphics x y w h clip] (if clip (.create graphics x y w h) @@ -64,10 +44,10 @@ ([context layer graphics x y clip] (let [s (size layer context)] (draw! context layer graphics - x y (s 0) (s 1) clip))) + x y (s 0) (s 1) clip))) ([context layer graphics x y w h] (draw! context layer graphics - x y w h true)) + x y w h true)) ([context layer graphics x y w h clip] (let [graphics (make-graphics graphics x y w h clip) graphics (apply-theme graphics (:theme context))] @@ -84,14 +64,6 @@ (finally (.dispose graphics)))))) -(defmacro decorate-layer [layer & specs] - `(let [layer# ~layer] - (reify Layer ~@(merge-specs - `((~'render! [l# c# g#] (draw! c# layer# g#)) - (~'size [l# c#] (size layer# c#)) - (~'anchor [l# c#] (anchor layer# c#))) - specs)))) - ;; ;; Layer implementations. ;; @@ -104,7 +76,7 @@ (border-layer content width 0)) ([content width gap] (let [offset (+ width gap)] - (reify-layer + (reify Layer (render! [l c g] (let [w (:width c) h (:height c)] @@ -116,28 +88,20 @@ (size [l c] (let [s (size content c)] [(+ (s 0) offset offset) - (+ (s 1) offset offset)])) - (anchor [l c] - (let [a (anchor content c)] - [(+ (a 0) offset) - (+ (a 1) offset)])))))) + (+ (s 1) offset offset)])))))) (defn- re-split [re s] (seq (.split re s))) -(defn- text-size [lines font font-context] - (loop [lines lines - width 0 - height 0] - (if-let [line (first lines)] - (let [layout (TextLayout. line font font-context)] - (recur (next lines) - (max width (.getAdvance layout)) - (+ height - (.getAscent layout) - (.getDescent layout) - (.getLeading layout)))) - [width height]))) +(defn- layout-text [lines font font-context] + (map #(TextLayout. % font font-context) lines)) + +(defn- text-width [layouts] + (reduce #(max %1 (.getAdvance %2)) 0 layouts)) + +(defn- text-height [layouts] + (reduce #(+ %1 (.getAscent %2) (.getDescent %2) (.getLeading %2)) + 0 layouts)) (defn text-layer "Creates a layer to display multiline text." @@ -145,29 +109,31 @@ (text-layer text :left :top)) ([text h-align v-align] (let [lines (re-split #"\r\n|\n|\r|\u0085|\u2028|\u2029" text)] - (reify-layer + (reify Layer (render! [l c g] (let [w (:width c) h (:height c) font (.getFont g) font-context (:font-context c) + layouts (layout-text lines font font-context) y (case v-align :top 0 - :center (/ (- h ((text-size - lines font font-context) 1)) - 2) - :bottom (- h ((text-size - lines font font-context) 1)))] - (loop [lines lines, y y] - (when-first [line lines] - (let [layout (TextLayout. line font font-context) - ascent (.getAscent layout) + :center (/ (- h (text-height layouts)) 2) + :bottom (- h (text-height layouts)))] + (loop [layouts layouts, y y] + (when-first [layout layouts] + (let [ascent (.getAscent layout) lh (+ ascent (.getDescent layout) (.getLeading layout)) x (case h-align :left 0 :center (/ (- w (.getAdvance layout)) 2) :right (- w (.getAdvance layout)))] (.draw layout g x (+ y ascent)) - (recur (next lines) (+ y lh))))))) + (recur (next layouts) (+ y lh))))))) (size [l c] - (text-size lines (-> c :theme :font) (:font-context c))))))) + (let [layouts (layout-text lines + (-> c :theme :font) + (:font-context c)) + width (text-width layouts) + height (text-height layouts)] + [width height]))))))