         (.drawPolyline g2d xs ys n)))
 
 (defmethod draw-primitive :primitive-rect
-  [g2d shape {:keys [x y w h filled]}]
-  (if filled
-    (.fillRect g2d x y w h)
-    (.drawRect g2d x y w h)))
+  [g2d shape {:keys [l t w h filled]}]
+  (if filled
+    (.fillRect g2d l t w h)
+    (.drawRect g2d l t w h)))
 
 (defmethod draw-primitive :primitive-round-rect
-  [g2d shape {:keys [x y w h filled arc-width arc-height]}]
-  (if filled
-    (.fillRoundRect g2d x y w h arc-width arc-height)
-    (.drawRoundRect g2d x y w h arc-width arc-height)))
+  [g2d shape {:keys [l t w h filled arc-width arc-height]}]
+  (if filled
+    (.fillRoundRect g2d l t w h arc-width arc-height)
+    (.drawRoundRect g2d l t w h arc-width arc-height)))
+
+(defn draw-string-center
+  "Draw a string centered at position x,y."
+  [^Graphics2D graphics ^String text x y]
+  (let [context (.getFontRenderContext graphics)
+        height (.. graphics
+                   getFont (createGlyphVector context text)
+                   getVisualBounds
+                   getHeight)
+        width (.. graphics
+                  getFontMetrics
+                  (getStringBounds text graphics)
+                  getWidth)]
+    (.drawString graphics text
+                 (float (- x (/ width 2)))
+                 (float (+ y (/ height 2))))))
 
 (defmethod draw-primitive :primitive-text
   [g2d shape  {:keys [text x y font]}]
-  (let [{:keys [name bold italic size]} font
+  (let [{:keys [name bold italic underline strikethrough size]} font
         style (bit-or (if bold Font/BOLD 0) (if italic Font/ITALIC 0))
-        font-obj (Font. name style size)]
-    (.setFont g2d font-obj)
-    (.drawString g2d text x y)))
+        font1 (Font. name style size)
+        attributes (.getAttributes font1)]
+    (doto attributes
+      (.put TextAttribute/STRIKETHROUGH
+            (if strikethrough TextAttribute/STRIKETHROUGH_ON false))
+      (.put TextAttribute/UNDERLINE
+            (if underline TextAttribute/UNDERLINE_ON -1)))
+    (let [font2 (Font. attributes)]
+      (.setFont g2d font2)
+      (draw-string-center g2d text x y))))
 
 (defn draw-primitives [g2d items]
   (enable-anti-aliasing g2d)

(def temp-data
  [
   {:type :primitive-round-rect
    :params {:x 20 :y 10 :w 120 :h 100
             :arc-width 20 :arc-height 20
             :filled true :color Color/RED}}
   {:type :primitive-ellipse
    :params {:x 25 :y 15 :w 110 :h 90
             :arc-width 20 :arc-height 20
             :filled true :color Color/YELLOW}}
   {:type :primitive-round-rect
    :params {:x 20 :y 10 :w 120 :h 100
             :arc-width 20 :arc-height 20
             :filled false :color Color/BLACK}}
   {:type :primitive-polygon
    :params {:vertices [{:x 100 :y 100}
                        {:x 50 :y 150}
                        {:x 150 :y 150}]
             :filled false
             :closed true}}
   {:type :primitive-text
    :params {:x 80 :y 140 :text "TEST!" :color Color/BLACK
             :font {:name "Arial"
                    :bold true
                    :italic true
                    :size 16}}}
   {:type :primitive-arc
    :params {:x 40 :y 30 :w 100 :h 100
             :start-angle 10 :arc-angle 100 :color Color/GREEN
             :filled true}}
   ])

  (doto g2d
    (.setColor (:color params))))

(defn- -? [a b]
  (when (and a b)
    (- a b)))

(defn- +? [a b]
  (when (and a b)
    (+ a b)))

(defn- half? [a]
  (when a
    (/ a 2)))

(defn- twice? [a]
  (when a
    (* a 2)))

(defn complete-coordinates
  [{:keys [l left t top r right b bottom
           x y
           w width h height]
    :as the-map}]
  (let [l (or l left) t (or t top) r (or r right) b (or b bottom)
        w (or w width (-? r l) (twice? (-? x l)) (twice? (-? r x)))
        h (or h height (-? b t) (twice? (-? y t)) (twice? (-? b y)))
        l (or l (-? r w) (-? x (half? w)))
        t (or t (-? b h) (-? y (half? h)))
        r (or r (+? l w) (+? x (half? w)))
        b (or b (+? t h) (+? y (half? h)))
        x (or x (+? l (half? w)))
        y (or y (+? t (half? h)))]
    (merge the-map {:w w :h h :l l :t t :r r :b b :x x :y y})))
   
(defmulti draw-primitive (fn [g2d shape params] shape))

(defmethod draw-primitive :primitive-arc
  [g2d shape {:keys [l t w h filled start-angle arc-angle]}]
  (if filled
    (.fillArc g2d l t w h start-angle arc-angle)
    (.drawArc g2d l t w h start-angle arc-angle)))

(defmethod draw-primitive :primitive-ellipse
  [g2d shape {:keys [l t w h filled]}]
  (if filled
    (.fillOval g2d l t w h)
    (.drawOval g2d l t w h)))

(defmethod draw-primitive :primitive-image
  [g2d shape {:keys [image l t w h]}]
  (.drawImage g2d image
              l t
              (or w (.getWidth image))
              (or h (.getHeight image)) nil))

(defmethod draw-primitive :primitive-line
  [g2d shape {:keys [l t r b filled]}]
  (.drawLine g2d l t r b))

(defmethod draw-primitive :primitive-polygon
  [g2d shape {:keys [vertices filled closed]}]
