         {:keys [width height padding]} args
         boundaries (area (rectangle (- (/ width 2)) (- (/ height 2)) width height))
         *test-area* (area)
-        point-sequence (test-sequence args)
-        finder (fn [{:keys [text rect] :as word-info}]
+        finder (fn [{:keys [text word-bounds] :as word-info}]
                  ;(println (str "Placing " text " ..."))
-                 (let [hit (find-position *test-area* boundaries point-sequence word-info)]
+                 (let [point-sequence (test-sequence args word-info)
+                       [hit rotation] (find-position args *test-area* boundaries point-sequence word-info)]
                    (if (nil? hit)
                      nil
                      (do
-                       (.add *test-area* (area (grow-rect (translate-rect rect hit) padding)))
+                       (add-word-to-area! args *test-area* word-info hit rotation)
                        ;(println (str "Found place at " (.x hit) ", " (.y hit)))
-                       (assoc word-info :position hit)))))]
-    (doall (map finder word-infos))))
+                       (assoc word-info :position hit :rotation rotation)))))]
+    {:word-infos (doall (map finder word-infos))
+     :test-area *test-area*}))
 
 (defn- cloud-painter
-  [word-infos g w h]
-  (doto g
-    setup)
-
-  (doseq [{:keys [text font position]} (filter #(not (nil? %)) word-infos)]
-    (draw-string-centered g text
-                          (+ (/ w 2.0) (.x position))
-                          (+ (/ h 2.0) (.y position)) :font font)))
+  [{:keys [word-infos test-area]} g w h]
+  (let [c (point (/ w 2.0) (/ h 2.0))
+        bg (translate-area test-area c)]
+    (doto g
+      setup
+      ;(draw-rect (rectangle 0 0 (dec w) (dec h)))
+      ;(fill-shape bg)
+      ;(draw-shape bg)
+      )
+    (doseq [{:keys [text font position rotation]} (filter #(not (nil? %)) word-infos)]
+      (draw-string-centered g text (translate-point c position) :font font :rotation rotation))))
 
 (defn paint-cloud
-  [word-infos & args]
+  [cloud & args]
   (let [args (merge default-args)]
     (create-image (:width args) (:height args)
-                  (partial cloud-painter word-infos))))
+                  (partial cloud-painter cloud))))
 
 ; ########################
 

    (map (partial polar-point r) (range 0.0 (* 2 Math/PI) step))))

(defn- test-sequence
  [{:keys [precision max-font-size max-test-radius] :as args}]
  (let [imprecision (* (- 1.0 precision) (- 1.0 precision))
        radii (take-while
                  #(< % max-test-radius)
                  (map #(* (+ 1 (* imprecision max-font-size)) %) (lazy-numbers 1)))
        rings (map #(test-ring % precision) radii)]
    (cons (point) (apply concat rings))))

(defn- check-position
  [test-area boundaries {:keys [rect]} p]
  (let [rect* (translate-rect rect p)]
  (and
   (.contains boundaries rect*)
   (not (.intersects test-area rect*)))))

(defn- find-position
  [test-area boundaries point-sequence {:keys [rect] :as word-info}]
  (first (filter #(check-position test-area boundaries word-info %)
              point-sequence)))

(defn generate-cloud
  [word-infos & args]

(def base-font (Font. font-family font-style (float 100)))

(def default-args
  {:width 600
   :height 200
   :precision 0.5
   :font base-font
   :min-font-size 13
   :max-font-size 60
   :max-test-radius 350
   :padding 2
   :shape-mode :glyph-box ; :word-box, :glyph-box
   :allow-rotation true
   })

(defn- calc-font-size
  [{:keys [min-font-size max-font-size]} v]
  (float (+ min-font-size (* (- max-font-size min-font-size) v v))))

(defn- get-font
  [{:keys [font] :as args} v]
  (.deriveFont font (calc-font-size args v)))

(defn- build-word-info
  [g args [text value]]
  (let [font* (get-font args value)]
    {:text text
     :font font*
     :word-bounds (string-centered-bounds g font* text)
     :glyph-bounds (string-centered-glyphbounds g font* text)}))

(defn- build-word-infos
  [word-stats & args]
