Index: trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/StyledMapRenderer.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/StyledMapRenderer.java	(revision 7453)
+++ trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/StyledMapRenderer.java	(revision 7459)
@@ -433,4 +433,8 @@
         }
 
+        drawAreaText(osm, text, area);
+    }
+
+    private void drawAreaText(OsmPrimitive osm, TextElement text, Shape area) {
         if (text != null && isShowNames()) {
             // abort if we can't compose the label to be rendered
@@ -449,17 +453,57 @@
             // Centroids are not optimal either, just imagine a U-shaped house.
 
-            Rectangle centeredNBounds = new Rectangle(pb.x + (int)((pb.width - nb.getWidth())/2.0),
-                    pb.y + (int)((pb.height - nb.getHeight())/2.0),
-                    (int)nb.getWidth(),
-                    (int)nb.getHeight());
-
-            if ((pb.width >= nb.getWidth() && pb.height >= nb.getHeight()) && // quick check
-                    area.contains(centeredNBounds) // slow but nice
-            ) {
-                Font defaultFont = g.getFont();
-                int x = (int)(centeredNBounds.getMinX() - nb.getMinX());
-                int y = (int)(centeredNBounds.getMinY() - nb.getMinY());
-                displayText(null, name, x, y, osm.isDisabled(), text);
-                g.setFont(defaultFont);
+            // quick check to see if label box is smaller than primitive box
+            if (pb.width >= nb.getWidth() && pb.height >= nb.getHeight()) {
+
+                final double w = pb.width  - nb.getWidth();
+                final double h = pb.height - nb.getHeight();
+
+                final int x2 = pb.x + (int)(w/2.0);
+                final int y2 = pb.y + (int)(h/2.0);
+
+                final int nbw = (int) nb.getWidth();
+                final int nbh = (int) nb.getHeight();
+
+                Rectangle centeredNBounds = new Rectangle(x2, y2, nbw, nbh);
+
+                // slower check to see if label is displayed inside primitive shape
+                boolean labelOK = area.contains(centeredNBounds);
+                if (!labelOK) {
+                    // if center position (C) is not inside osm shape, try naively some other positions as follows:
+                    final int x1 = pb.x + (int)(  w/4.0);
+                    final int x3 = pb.x + (int)(3*w/4.0);
+                    final int y1 = pb.y + (int)(  h/4.0);
+                    final int y3 = pb.y + (int)(3*h/4.0);
+                    // +-----------+
+                    // |  5  1  6  |
+                    // |  4  C  2  |
+                    // |  8  3  7  |
+                    // +-----------+
+                    Rectangle[] candidates = new Rectangle[] {
+                            new Rectangle(x2, y1, nbw, nbh),
+                            new Rectangle(x3, y2, nbw, nbh),
+                            new Rectangle(x2, y3, nbw, nbh),
+                            new Rectangle(x1, y2, nbw, nbh),
+                            new Rectangle(x1, y1, nbw, nbh),
+                            new Rectangle(x3, y1, nbw, nbh),
+                            new Rectangle(x3, y3, nbw, nbh),
+                            new Rectangle(x1, y3, nbw, nbh)
+                    };
+                    // Dumb algorithm to find a better placement. We could surely find a smarter one but it should
+                    // solve most of building issues with only few calculations (8 at most)
+                    for (int i = 0; i < candidates.length && !labelOK; i++) {
+                        centeredNBounds = candidates[i];
+                        labelOK = area.contains(centeredNBounds);
+                    }
+                }
+                if (labelOK) {
+                    Font defaultFont = g.getFont();
+                    int x = (int)(centeredNBounds.getMinX() - nb.getMinX());
+                    int y = (int)(centeredNBounds.getMinY() - nb.getMinY());
+                    displayText(null, name, x, y, osm.isDisabled(), text);
+                    g.setFont(defaultFont);
+                } else if (Main.isDebugEnabled()) {
+                    Main.debug("Couldn't find a correct label placement for "+osm+" / "+name);
+                }
             }
         }
