changeset 15:87bd822aa815

Text layer.
author Mikhail Kryshen <mikhail@kryshen.net>
date Tue, 15 Jun 2010 06:31:11 +0400
parents 0a2fafca72d8
children 0fda22fc53d2
files src/indyvon/component.clj src/indyvon/core.clj
diffstat 2 files changed, 58 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/src/indyvon/component.clj	Tue Jun 15 04:35:57 2010 +0400
+++ b/src/indyvon/component.clj	Tue Jun 15 06:31:11 2010 +0400
@@ -63,12 +63,15 @@
              (draw! context layer1b g 10 5)
              (draw! context layer1 g 55 5))
           (size [this context] [70 65])))
+    (def layer3
+         (border-layer (text-layer "Sample\ntext" :right :bottom)))
     (def layer
          (reify-layer
           (render! [this context g]
              (.drawLine g 0 0 (:width context) (:height context))
-             (draw! context layer2 g 15 20))
-          (size [this context] [100 100])))
+             (draw! context layer2 g 15 20)
+             (draw! context layer3 g 100 100 80 50))
+          (size [this context] [300 400])))
     (doto frame
       (.addWindowListener
        (proxy [java.awt.event.WindowAdapter] []
--- a/src/indyvon/core.clj	Tue Jun 15 04:35:57 2010 +0400
+++ b/src/indyvon/core.clj	Tue Jun 15 06:31:11 2010 +0400
@@ -5,7 +5,8 @@
 ;;
 
 (ns indyvon.core
-  (:import (java.awt Color Font)))
+  (:import (java.awt Color Font)
+           (java.awt.font FontRenderContext TextLayout)))
 
 (defprotocol Layer
   (render! [this context graphics])
@@ -68,7 +69,8 @@
      (draw! context layer graphics
                     x y w h true))
   ([context layer graphics x y w h clip]
-     (let [graphics (make-graphics graphics x y w h clip)]
+     (let [graphics (make-graphics graphics x y w h clip)
+           graphics (apply-theme graphics (:theme context))]
        (try
          (render! layer
                   (assoc context
@@ -120,9 +122,52 @@
              [(+ (a 0) offset)
               (+ (a 1) offset)]))))))
 
-;; (defn text-layer
-;;   ([text]
-;;      (text :left :top))
-;;   ([text h-align v-align]
-;;      (let [newline #"\\r\\n|\\n|\\r|\\u0085|\\u2028|\\u2029"]
-;;        (reify-layer))))
\ No newline at end of file
+(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 text-layer
+  "Creates a layer to display multiline text."
+  ([text]
+     (text-layer text :left :top))
+  ([text h-align v-align]
+     (let [lines (re-split #"\r\n|\n|\r|\u0085|\u2028|\u2029" text)]
+       (reify-layer
+        (render! [l c g]
+           (let [w (:width c)
+                 h (:height c)
+                 font (.getFont g)
+                 font-context (:font-context c)
+                 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)
+                       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)))))))
+        (size [l c]
+           (text-size lines (-> c :theme :font) (:font-context c)))))))