001package org.openstreetmap.gui.jmapviewer; 002 003//License: GPL. 004 005import static org.openstreetmap.gui.jmapviewer.FeatureAdapter.tr; 006 007import java.awt.Color; 008import java.awt.Font; 009import java.awt.Graphics; 010import java.awt.Image; 011import java.awt.Point; 012import java.awt.Rectangle; 013import java.awt.font.TextAttribute; 014import java.awt.geom.Rectangle2D; 015import java.awt.image.ImageObserver; 016import java.util.HashMap; 017 018import org.openstreetmap.gui.jmapviewer.interfaces.Attributed; 019 020public class AttributionSupport { 021 022 private Attributed source; 023 024 private Image attrImage; 025 private String attrTermsText; 026 private String attrTermsUrl; 027 public static final Font ATTR_FONT = new Font("Arial", Font.PLAIN, 10); 028 public static final Font ATTR_LINK_FONT; 029 030 protected Rectangle attrTextBounds = null; 031 protected Rectangle attrToUBounds = null; 032 protected Rectangle attrImageBounds = null; 033 034 static { 035 HashMap<TextAttribute, Integer> aUnderline = new HashMap<TextAttribute, Integer>(); 036 aUnderline.put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON); 037 ATTR_LINK_FONT = ATTR_FONT.deriveFont(aUnderline); 038 } 039 040 public void initialize(Attributed source) { 041 this.source = source; 042 boolean requireAttr = source.requiresAttribution(); 043 if (requireAttr) { 044 attrImage = source.getAttributionImage(); 045 attrTermsText = source.getTermsOfUseText(); 046 attrTermsUrl = source.getTermsOfUseURL(); 047 if (attrTermsUrl != null && attrTermsText == null) { 048 attrTermsText = tr("Background Terms of Use"); 049 } 050 } else { 051 attrImage = null; 052 attrTermsUrl = null; 053 } 054 } 055 056 public void paintAttribution(Graphics g, int width, int height, Coordinate topLeft, Coordinate bottomRight, int zoom, ImageObserver observer) { 057 if (source == null || !source.requiresAttribution()) { 058 attrToUBounds = null; 059 attrImageBounds = null; 060 attrTextBounds = null; 061 return; 062 } 063 064 // Draw attribution 065 Font font = g.getFont(); 066 g.setFont(ATTR_LINK_FONT); 067 068 // Draw terms of use text 069 int termsTextHeight = 0; 070 int termsTextY = height; 071 072 if (attrTermsText != null) { 073 Rectangle2D termsStringBounds = g.getFontMetrics().getStringBounds(attrTermsText, g); 074 int textRealHeight = (int) termsStringBounds.getHeight(); 075 termsTextHeight = textRealHeight - 5; 076 int termsTextWidth = (int) termsStringBounds.getWidth(); 077 termsTextY = height - termsTextHeight; 078 int x = 2; 079 int y = height - termsTextHeight; 080 attrToUBounds = new Rectangle(x, y-termsTextHeight, termsTextWidth, textRealHeight); 081 g.setColor(Color.black); 082 g.drawString(attrTermsText, x + 1, y + 1); 083 g.setColor(Color.white); 084 g.drawString(attrTermsText, x, y); 085 } else { 086 attrToUBounds = null; 087 } 088 089 // Draw attribution logo 090 if (attrImage != null) { 091 int x = 2; 092 int imgWidth = attrImage.getWidth(observer); 093 int imgHeight = attrImage.getHeight(observer); 094 int y = termsTextY - imgHeight - termsTextHeight - 5; 095 attrImageBounds = new Rectangle(x, y, imgWidth, imgHeight); 096 g.drawImage(attrImage, x, y, null); 097 } else { 098 attrImageBounds = null; 099 } 100 101 g.setFont(ATTR_FONT); 102 String attributionText = source.getAttributionText(zoom, topLeft, bottomRight); 103 if (attributionText != null) { 104 Rectangle2D stringBounds = g.getFontMetrics().getStringBounds(attributionText, g); 105 int textHeight = (int) stringBounds.getHeight() - 5; 106 int x = width - (int) stringBounds.getWidth(); 107 int y = height - textHeight; 108 g.setColor(Color.black); 109 g.drawString(attributionText, x + 1, y + 1); 110 g.setColor(Color.white); 111 g.drawString(attributionText, x, y); 112 attrTextBounds = new Rectangle(x, y-textHeight, (int) stringBounds.getWidth(), (int) stringBounds.getHeight()); 113 } else { 114 attrTextBounds = null; 115 } 116 117 g.setFont(font); 118 } 119 120 public boolean handleAttributionCursor(Point p) { 121 if (attrTextBounds != null && attrTextBounds.contains(p)) { 122 return true; 123 } else if (attrImageBounds != null && attrImageBounds.contains(p)) { 124 return true; 125 } else if (attrToUBounds != null && attrToUBounds.contains(p)) { 126 return true; 127 } 128 return false; 129 } 130 131 public boolean handleAttribution(Point p, boolean click) { 132 if (source == null || !source.requiresAttribution()) 133 return false; 134 135 if (attrTextBounds != null && attrTextBounds.contains(p)) { 136 String attributionURL = source.getAttributionLinkURL(); 137 if (attributionURL != null) { 138 if (click) { 139 FeatureAdapter.openLink(attributionURL); 140 } 141 return true; 142 } 143 } else if (attrImageBounds != null && attrImageBounds.contains(p)) { 144 String attributionImageURL = source.getAttributionImageURL(); 145 if (attributionImageURL != null) { 146 if (click) { 147 FeatureAdapter.openLink(source.getAttributionImageURL()); 148 } 149 return true; 150 } 151 } else if (attrToUBounds != null && attrToUBounds.contains(p)) { 152 String termsOfUseURL = source.getTermsOfUseURL(); 153 if (termsOfUseURL != null) { 154 if (click) { 155 FeatureAdapter.openLink(termsOfUseURL); 156 } 157 return true; 158 } 159 } 160 return false; 161 } 162 163} 164