Index: applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/JMapViewer.java
===================================================================
--- applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/JMapViewer.java	(revision 26249)
+++ applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/JMapViewer.java	(revision 26253)
@@ -10,4 +10,5 @@
 import java.awt.Insets;
 import java.awt.Point;
+import java.awt.Rectangle;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
@@ -86,4 +87,8 @@
     public static final Font ATTR_FONT = new Font("Arial", Font.PLAIN, 10);
     public static final Font ATTR_LINK_FONT;
+
+    protected Rectangle attrTextBounds = null;
+    protected Rectangle attrToUBounds = null;
+    protected Rectangle attrImageBounds = null;
 
     static {
@@ -753,9 +758,12 @@
 
         Rectangle2D termsStringBounds = g.getFontMetrics().getStringBounds("Background Terms of Use", g);
-        int textHeight = (int) termsStringBounds.getHeight() - 5;
+        int textRealHeight = (int) termsStringBounds.getHeight();
+        int textHeight = textRealHeight - 5;
+        int textWidth = (int) termsStringBounds.getWidth();
         int termsTextY = getHeight() - textHeight;
         if (attrTermsUrl != null) {
             int x = 2;
             int y = getHeight() - textHeight;
+            attrToUBounds = new Rectangle(x, y-textHeight, textWidth, textRealHeight);
             g.setColor(Color.black);
             g.drawString("Background Terms of Use", x + 1, y + 1);
@@ -767,6 +775,8 @@
         if (attrImage != null) {
             int x = 2;
+            int imgWidth = attrImage.getWidth(this);
             int height = attrImage.getHeight(null);
             int y = termsTextY - height - textHeight - 5;
+            attrImageBounds = new Rectangle(x, y, imgWidth, height);
             g.drawImage(attrImage, x, y, null);
         }
@@ -784,4 +794,5 @@
             g.setColor(Color.white);
             g.drawString(attributionText, x, y);
+            attrTextBounds = new Rectangle(x, y-textHeight, textWidth, textRealHeight);
         }
 
Index: applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/tilesources/AbstractOsmTileSource.java
===================================================================
--- applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/tilesources/AbstractOsmTileSource.java	(revision 26249)
+++ applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/tilesources/AbstractOsmTileSource.java	(revision 26253)
@@ -26,5 +26,5 @@
     @Override
     public boolean requiresAttribution() {
-        return false;
+        return true;
     }
 
Index: applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/tilesources/TMSTileSource.java
===================================================================
--- applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/tilesources/TMSTileSource.java	(revision 26249)
+++ applications/viewer/jmapviewer/src/org/openstreetmap/gui/jmapviewer/tilesources/TMSTileSource.java	(revision 26253)
@@ -1,8 +1,15 @@
 package org.openstreetmap.gui.jmapviewer.tilesources;
 
+import java.awt.Image;
+
+import org.openstreetmap.gui.jmapviewer.Coordinate;
 
 public class TMSTileSource extends AbstractTSMTileSource {
     protected int maxZoom;
     protected int minZoom = 0;
+    protected String attributionText;
+    protected Image attributionImage;
+    protected String attributionLinkURL;
+    protected String termsOfUseURL;
 
     public TMSTileSource(String name, String url, int maxZoom) {
@@ -30,3 +37,44 @@
         return TileUpdate.IfNoneMatch;
     }
+
+    @Override
+    public boolean requiresAttribution() {
+        return attributionText != null;
+    }
+
+    @Override
+    public String getAttributionText(int zoom, Coordinate topLeft, Coordinate botRight) {
+        return attributionText;
+    }
+
+    @Override
+    public Image getAttributionImage() {
+        return attributionImage;
+    }
+
+    @Override
+    public String getAttributionLinkURL() {
+        return attributionLinkURL;
+    }
+
+    @Override
+    public String getTermsOfUseURL() {
+        return termsOfUseURL;
+    }
+
+    public void setAttributionText(String text) {
+        attributionText = text;
+    }
+
+    public void setAttributionImage(Image img) {
+        attributionImage = img;
+    }
+
+    public void setAttributionLinkURL(String text) {
+        attributionLinkURL = text;
+    }
+
+    public void setTermsOfUseURL(String text) {
+        termsOfUseURL = text;
+    }
 }
