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