155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project/* 255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * 455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * you may not use this file except in compliance with the License. 655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * You may obtain a copy of the License at 755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * 855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * 1055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software 1155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 1255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * See the License for the specific language governing permissions and 1455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * limitations under the License. 1555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project */ 1655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project 1769425d803b34589309a69eddc53a338e1409b30cXavier Ducrohetpackage com.android.ide.eclipse.adt.internal.editors; 1855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project 1981cefe2a26dd6db8a878e30874d12cdcbff0e83bXavier Ducrohetimport com.android.SdkConstants; 203e75d4f79a8328ed18505830c786402369082efaTor Norbyeimport com.android.annotations.NonNull; 21b9317238c40c76f9a31647021f232adba6da0979Tor Norbyeimport com.android.annotations.Nullable; 2255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Projectimport com.android.ide.eclipse.adt.AdtPlugin; 235ae903bf8670f40e9eb40ebbd0a25c15eaac5962Tor Norbyeimport com.android.ide.eclipse.adt.internal.editors.ui.ErrorImageComposite; 245ae903bf8670f40e9eb40ebbd0a25c15eaac5962Tor Norbyeimport com.google.common.collect.Maps; 2555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project 2655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Projectimport org.eclipse.jface.resource.ImageDescriptor; 2755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Projectimport org.eclipse.swt.SWT; 2893b86c1f3185c8df21e2a45a31e4cd9ce567cef0Tor Norbyeimport org.eclipse.swt.graphics.Color; 2955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Projectimport org.eclipse.swt.graphics.Font; 3055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Projectimport org.eclipse.swt.graphics.FontData; 3155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Projectimport org.eclipse.swt.graphics.GC; 3255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Projectimport org.eclipse.swt.graphics.Image; 3355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Projectimport org.eclipse.swt.graphics.ImageData; 3455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Projectimport org.eclipse.swt.graphics.Point; 3593b86c1f3185c8df21e2a45a31e4cd9ce567cef0Tor Norbyeimport org.eclipse.swt.graphics.RGB; 3655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Projectimport org.eclipse.swt.widgets.Display; 37a7da09b74d5f41667823ddf36c0cd7f145f54a2dTor Norbyeimport org.eclipse.ui.plugin.AbstractUIPlugin; 3855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project 39a7da09b74d5f41667823ddf36c0cd7f145f54a2dTor Norbyeimport java.net.URL; 405ae903bf8670f40e9eb40ebbd0a25c15eaac5962Tor Norbyeimport java.util.IdentityHashMap; 415ae903bf8670f40e9eb40ebbd0a25c15eaac5962Tor Norbyeimport java.util.Map; 4255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project 4355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project/** 4455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * Factory to generate icons for Android Editors. 4555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * <p/> 4655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * Icons are kept here and reused. 4755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project */ 4855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Projectpublic class IconFactory { 4955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project public static final int COLOR_RED = SWT.COLOR_DARK_RED; 5055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project public static final int COLOR_GREEN = SWT.COLOR_DARK_GREEN; 5155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project public static final int COLOR_BLUE = SWT.COLOR_DARK_BLUE; 5255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project public static final int COLOR_DEFAULT = SWT.COLOR_BLACK; 5355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project 5455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project public static final int SHAPE_CIRCLE = 'C'; 5555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project public static final int SHAPE_RECT = 'R'; 5655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project public static final int SHAPE_DEFAULT = SHAPE_CIRCLE; 5793b86c1f3185c8df21e2a45a31e4cd9ce567cef0Tor Norbye 5855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project private static IconFactory sInstance; 5955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project 605ae903bf8670f40e9eb40ebbd0a25c15eaac5962Tor Norbye private Map<String, Image> mIconMap = Maps.newHashMap(); 615ae903bf8670f40e9eb40ebbd0a25c15eaac5962Tor Norbye private Map<URL, Image> mUrlMap = Maps.newHashMap(); 625ae903bf8670f40e9eb40ebbd0a25c15eaac5962Tor Norbye private Map<String, ImageDescriptor> mImageDescMap = Maps.newHashMap(); 635ae903bf8670f40e9eb40ebbd0a25c15eaac5962Tor Norbye private Map<Image, Image> mErrorIcons; 645ae903bf8670f40e9eb40ebbd0a25c15eaac5962Tor Norbye private Map<Image, Image> mWarningIcons; 6593b86c1f3185c8df21e2a45a31e4cd9ce567cef0Tor Norbye 6655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project private IconFactory() { 6755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project } 6893b86c1f3185c8df21e2a45a31e4cd9ce567cef0Tor Norbye 6955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project public static synchronized IconFactory getInstance() { 7055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project if (sInstance == null) { 7155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project sInstance = new IconFactory(); 7255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project } 7355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project return sInstance; 7455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project } 7593b86c1f3185c8df21e2a45a31e4cd9ce567cef0Tor Norbye 76a7da09b74d5f41667823ddf36c0cd7f145f54a2dTor Norbye public void dispose() { 7755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project // Dispose icons 7855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project for (Image icon : mIconMap.values()) { 7955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project // The map can contain null values 8055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project if (icon != null) { 8155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project icon.dispose(); 8255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project } 8355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project } 8455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project mIconMap.clear(); 85a7da09b74d5f41667823ddf36c0cd7f145f54a2dTor Norbye for (Image icon : mUrlMap.values()) { 86a7da09b74d5f41667823ddf36c0cd7f145f54a2dTor Norbye // The map can contain null values 87a7da09b74d5f41667823ddf36c0cd7f145f54a2dTor Norbye if (icon != null) { 88a7da09b74d5f41667823ddf36c0cd7f145f54a2dTor Norbye icon.dispose(); 89a7da09b74d5f41667823ddf36c0cd7f145f54a2dTor Norbye } 90a7da09b74d5f41667823ddf36c0cd7f145f54a2dTor Norbye } 91a7da09b74d5f41667823ddf36c0cd7f145f54a2dTor Norbye mUrlMap.clear(); 925ae903bf8670f40e9eb40ebbd0a25c15eaac5962Tor Norbye if (mErrorIcons != null) { 935ae903bf8670f40e9eb40ebbd0a25c15eaac5962Tor Norbye for (Image icon : mErrorIcons.values()) { 945ae903bf8670f40e9eb40ebbd0a25c15eaac5962Tor Norbye // The map can contain null values 955ae903bf8670f40e9eb40ebbd0a25c15eaac5962Tor Norbye if (icon != null) { 965ae903bf8670f40e9eb40ebbd0a25c15eaac5962Tor Norbye icon.dispose(); 975ae903bf8670f40e9eb40ebbd0a25c15eaac5962Tor Norbye } 985ae903bf8670f40e9eb40ebbd0a25c15eaac5962Tor Norbye } 995ae903bf8670f40e9eb40ebbd0a25c15eaac5962Tor Norbye mErrorIcons = null; 1005ae903bf8670f40e9eb40ebbd0a25c15eaac5962Tor Norbye } 1015ae903bf8670f40e9eb40ebbd0a25c15eaac5962Tor Norbye if (mWarningIcons != null) { 1025ae903bf8670f40e9eb40ebbd0a25c15eaac5962Tor Norbye for (Image icon : mWarningIcons.values()) { 1035ae903bf8670f40e9eb40ebbd0a25c15eaac5962Tor Norbye // The map can contain null values 1045ae903bf8670f40e9eb40ebbd0a25c15eaac5962Tor Norbye if (icon != null) { 1055ae903bf8670f40e9eb40ebbd0a25c15eaac5962Tor Norbye icon.dispose(); 1065ae903bf8670f40e9eb40ebbd0a25c15eaac5962Tor Norbye } 1075ae903bf8670f40e9eb40ebbd0a25c15eaac5962Tor Norbye } 1085ae903bf8670f40e9eb40ebbd0a25c15eaac5962Tor Norbye mWarningIcons = null; 1095ae903bf8670f40e9eb40ebbd0a25c15eaac5962Tor Norbye } 11055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project } 11155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project 11255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project /** 11355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * Returns an Image for a given icon name. 11455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * <p/> 11555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * Callers should not dispose it. 11693b86c1f3185c8df21e2a45a31e4cd9ce567cef0Tor Norbye * 11755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * @param osName The leaf name, without the extension, of an existing icon in the 11855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * editor's "icons" directory. If it doesn't exists, a default icon will be 11955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * generated automatically based on the name. 12055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project */ 12155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project public Image getIcon(String osName) { 12255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project return getIcon(osName, COLOR_DEFAULT, SHAPE_DEFAULT); 12355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project } 12455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project 12555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project /** 12655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * Returns an Image for a given icon name. 12755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * <p/> 12855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * Callers should not dispose it. 12993b86c1f3185c8df21e2a45a31e4cd9ce567cef0Tor Norbye * 13055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * @param osName The leaf name, without the extension, of an existing icon in the 1313e75d4f79a8328ed18505830c786402369082efaTor Norbye * editor's "icons" directory. If it doesn't exist, a default icon will be 13255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * generated automatically based on the name. 13355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * @param color The color of the text in the automatically generated icons, 13455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * one of COLOR_DEFAULT, COLOR_RED, COLOR_BLUE or COLOR_RED. 13555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * @param shape The shape of the icon in the automatically generated icons, 13655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * one of SHAPE_DEFAULT, SHAPE_CIRCLE or SHAPE_RECT. 13755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project */ 13855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project public Image getIcon(String osName, int color, int shape) { 13955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project String key = Character.toString((char) shape) + Integer.toString(color) + osName; 14055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project Image icon = mIconMap.get(key); 14155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project if (icon == null && !mIconMap.containsKey(key)) { 14255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project ImageDescriptor id = getImageDescriptor(osName, color, shape); 14355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project if (id != null) { 14455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project icon = id.createImage(); 14555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project } 14655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project // Note that we store null references in the icon map, to avoid looking them 14755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project // up every time. If it didn't exist once, it will not exist later. 14855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project mIconMap.put(key, icon); 14955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project } 15055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project return icon; 15155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project } 15255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project 15355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project /** 15455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * Returns an ImageDescriptor for a given icon name. 15555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * <p/> 15655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * Callers should not dispose it. 15793b86c1f3185c8df21e2a45a31e4cd9ce567cef0Tor Norbye * 15855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * @param osName The leaf name, without the extension, of an existing icon in the 15955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * editor's "icons" directory. If it doesn't exists, a default icon will be 16055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * generated automatically based on the name. 16155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project */ 16255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project public ImageDescriptor getImageDescriptor(String osName) { 16355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project return getImageDescriptor(osName, COLOR_DEFAULT, SHAPE_DEFAULT); 16455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project } 16593b86c1f3185c8df21e2a45a31e4cd9ce567cef0Tor Norbye 16655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project /** 16755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * Returns an ImageDescriptor for a given icon name. 16855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * <p/> 16955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * Callers should not dispose it. 17093b86c1f3185c8df21e2a45a31e4cd9ce567cef0Tor Norbye * 17155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * @param osName The leaf name, without the extension, of an existing icon in the 17255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * editor's "icons" directory. If it doesn't exists, a default icon will be 17355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * generated automatically based on the name. 17455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * @param color The color of the text in the automatically generated icons. 17555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * one of COLOR_DEFAULT, COLOR_RED, COLOR_BLUE or COLOR_RED. 17655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * @param shape The shape of the icon in the automatically generated icons, 17755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * one of SHAPE_DEFAULT, SHAPE_CIRCLE or SHAPE_RECT. 17855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project */ 17955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project public ImageDescriptor getImageDescriptor(String osName, int color, int shape) { 18055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project String key = Character.toString((char) shape) + Integer.toString(color) + osName; 18155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project ImageDescriptor id = mImageDescMap.get(key); 18255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project if (id == null && !mImageDescMap.containsKey(key)) { 183a7da09b74d5f41667823ddf36c0cd7f145f54a2dTor Norbye id = AbstractUIPlugin.imageDescriptorFromPlugin( 18455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project AdtPlugin.PLUGIN_ID, 18555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project String.format("/icons/%1$s.png", osName)); //$NON-NLS-1$ 18655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project 18755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project if (id == null) { 18855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project id = new LetterImageDescriptor(osName.charAt(0), color, shape); 18955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project } 19093b86c1f3185c8df21e2a45a31e4cd9ce567cef0Tor Norbye 19155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project // Note that we store null references in the icon map, to avoid looking them 19255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project // up every time. If it didn't exist once, it will not exist later. 19355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project mImageDescMap.put(key, id); 19455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project } 19555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project return id; 19655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project } 19755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project 19855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project /** 1993e75d4f79a8328ed18505830c786402369082efaTor Norbye * Returns an Image for a given icon name. 2003e75d4f79a8328ed18505830c786402369082efaTor Norbye * <p/> 2013e75d4f79a8328ed18505830c786402369082efaTor Norbye * Callers should not dispose it. 2023e75d4f79a8328ed18505830c786402369082efaTor Norbye * 2033e75d4f79a8328ed18505830c786402369082efaTor Norbye * @param osName The leaf name, without the extension, of an existing icon 2043e75d4f79a8328ed18505830c786402369082efaTor Norbye * in the editor's "icons" directory. If it doesn't exist, the 2053e75d4f79a8328ed18505830c786402369082efaTor Norbye * fallback will be used instead. 2063e75d4f79a8328ed18505830c786402369082efaTor Norbye * @param fallback the fallback icon name to use if the primary icon does 207b9317238c40c76f9a31647021f232adba6da0979Tor Norbye * not exist, or null if the method should return null if the 208b9317238c40c76f9a31647021f232adba6da0979Tor Norbye * image does not exist 209b9317238c40c76f9a31647021f232adba6da0979Tor Norbye * @return the icon, which should not be disposed by the caller, or null 210b9317238c40c76f9a31647021f232adba6da0979Tor Norbye * if the image does not exist *and* 2113e75d4f79a8328ed18505830c786402369082efaTor Norbye */ 212b9317238c40c76f9a31647021f232adba6da0979Tor Norbye @Nullable 213b9317238c40c76f9a31647021f232adba6da0979Tor Norbye public Image getIcon(@NonNull String osName, @Nullable String fallback) { 2143e75d4f79a8328ed18505830c786402369082efaTor Norbye String key = osName; 2153e75d4f79a8328ed18505830c786402369082efaTor Norbye Image icon = mIconMap.get(key); 2163e75d4f79a8328ed18505830c786402369082efaTor Norbye if (icon == null && !mIconMap.containsKey(key)) { 2173e75d4f79a8328ed18505830c786402369082efaTor Norbye ImageDescriptor id = getImageDescriptor(osName, fallback); 2183e75d4f79a8328ed18505830c786402369082efaTor Norbye if (id != null) { 2193e75d4f79a8328ed18505830c786402369082efaTor Norbye icon = id.createImage(); 2203e75d4f79a8328ed18505830c786402369082efaTor Norbye } 2213e75d4f79a8328ed18505830c786402369082efaTor Norbye // Note that we store null references in the icon map, to avoid looking them 2223e75d4f79a8328ed18505830c786402369082efaTor Norbye // up every time. If it didn't exist once, it will not exist later. 2233e75d4f79a8328ed18505830c786402369082efaTor Norbye mIconMap.put(key, icon); 2243e75d4f79a8328ed18505830c786402369082efaTor Norbye } 2253e75d4f79a8328ed18505830c786402369082efaTor Norbye return icon; 2263e75d4f79a8328ed18505830c786402369082efaTor Norbye } 2273e75d4f79a8328ed18505830c786402369082efaTor Norbye 2283e75d4f79a8328ed18505830c786402369082efaTor Norbye /** 229b9317238c40c76f9a31647021f232adba6da0979Tor Norbye * Returns an icon of the given name, or if that image does not exist and 230b9317238c40c76f9a31647021f232adba6da0979Tor Norbye * icon of the given fallback name. 2313e75d4f79a8328ed18505830c786402369082efaTor Norbye * 2323e75d4f79a8328ed18505830c786402369082efaTor Norbye * @param key the icon name 233b9317238c40c76f9a31647021f232adba6da0979Tor Norbye * @param fallbackKey the fallback image to use if the primary key does not 234b9317238c40c76f9a31647021f232adba6da0979Tor Norbye * exist 235b9317238c40c76f9a31647021f232adba6da0979Tor Norbye * @return the image descriptor, or null if the image does not exist and the 236b9317238c40c76f9a31647021f232adba6da0979Tor Norbye * fallbackKey is null 2373e75d4f79a8328ed18505830c786402369082efaTor Norbye */ 238b9317238c40c76f9a31647021f232adba6da0979Tor Norbye @Nullable 239b9317238c40c76f9a31647021f232adba6da0979Tor Norbye public ImageDescriptor getImageDescriptor(@NonNull String key, @Nullable String fallbackKey) { 2403e75d4f79a8328ed18505830c786402369082efaTor Norbye ImageDescriptor id = mImageDescMap.get(key); 2413e75d4f79a8328ed18505830c786402369082efaTor Norbye if (id == null && !mImageDescMap.containsKey(key)) { 2423e75d4f79a8328ed18505830c786402369082efaTor Norbye id = AbstractUIPlugin.imageDescriptorFromPlugin( 2433e75d4f79a8328ed18505830c786402369082efaTor Norbye AdtPlugin.PLUGIN_ID, 2443e75d4f79a8328ed18505830c786402369082efaTor Norbye String.format("/icons/%1$s.png", key)); //$NON-NLS-1$ 2453e75d4f79a8328ed18505830c786402369082efaTor Norbye if (id == null) { 246b9317238c40c76f9a31647021f232adba6da0979Tor Norbye if (fallbackKey == null) { 247b9317238c40c76f9a31647021f232adba6da0979Tor Norbye return null; 248b9317238c40c76f9a31647021f232adba6da0979Tor Norbye } 2493e75d4f79a8328ed18505830c786402369082efaTor Norbye id = getImageDescriptor(fallbackKey); 2503e75d4f79a8328ed18505830c786402369082efaTor Norbye } 2513e75d4f79a8328ed18505830c786402369082efaTor Norbye 2523e75d4f79a8328ed18505830c786402369082efaTor Norbye // Place the fallback image for this key as well such that we don't keep trying 2533e75d4f79a8328ed18505830c786402369082efaTor Norbye // to load the failed image 2543e75d4f79a8328ed18505830c786402369082efaTor Norbye mImageDescMap.put(key, id); 2553e75d4f79a8328ed18505830c786402369082efaTor Norbye } 2563e75d4f79a8328ed18505830c786402369082efaTor Norbye 2573e75d4f79a8328ed18505830c786402369082efaTor Norbye return id; 2583e75d4f79a8328ed18505830c786402369082efaTor Norbye } 2593e75d4f79a8328ed18505830c786402369082efaTor Norbye 2603e75d4f79a8328ed18505830c786402369082efaTor Norbye /** 261a7da09b74d5f41667823ddf36c0cd7f145f54a2dTor Norbye * Returns the image indicated by the given URL 262a7da09b74d5f41667823ddf36c0cd7f145f54a2dTor Norbye * 263a7da09b74d5f41667823ddf36c0cd7f145f54a2dTor Norbye * @param url the url to the image resources 264a7da09b74d5f41667823ddf36c0cd7f145f54a2dTor Norbye * @return the image for the url, or null if it cannot be initialized 265a7da09b74d5f41667823ddf36c0cd7f145f54a2dTor Norbye */ 266a7da09b74d5f41667823ddf36c0cd7f145f54a2dTor Norbye public Image getIcon(URL url) { 267a7da09b74d5f41667823ddf36c0cd7f145f54a2dTor Norbye Image image = mUrlMap.get(url); 268a7da09b74d5f41667823ddf36c0cd7f145f54a2dTor Norbye if (image == null) { 269a7da09b74d5f41667823ddf36c0cd7f145f54a2dTor Norbye ImageDescriptor descriptor = ImageDescriptor.createFromURL(url); 270a7da09b74d5f41667823ddf36c0cd7f145f54a2dTor Norbye image = descriptor.createImage(); 271a7da09b74d5f41667823ddf36c0cd7f145f54a2dTor Norbye mUrlMap.put(url, image); 272a7da09b74d5f41667823ddf36c0cd7f145f54a2dTor Norbye } 273a7da09b74d5f41667823ddf36c0cd7f145f54a2dTor Norbye 274a7da09b74d5f41667823ddf36c0cd7f145f54a2dTor Norbye return image; 275a7da09b74d5f41667823ddf36c0cd7f145f54a2dTor Norbye } 276a7da09b74d5f41667823ddf36c0cd7f145f54a2dTor Norbye 277a7da09b74d5f41667823ddf36c0cd7f145f54a2dTor Norbye /** 2785ae903bf8670f40e9eb40ebbd0a25c15eaac5962Tor Norbye * Returns an image with an error icon overlaid on it. The icons are cached, 2795ae903bf8670f40e9eb40ebbd0a25c15eaac5962Tor Norbye * so the base image should be cached as well, or this method will keep 2805ae903bf8670f40e9eb40ebbd0a25c15eaac5962Tor Norbye * storing new overlays into its cache. 2815ae903bf8670f40e9eb40ebbd0a25c15eaac5962Tor Norbye * 2825ae903bf8670f40e9eb40ebbd0a25c15eaac5962Tor Norbye * @param image the base image 2835ae903bf8670f40e9eb40ebbd0a25c15eaac5962Tor Norbye * @return the combined image 2845ae903bf8670f40e9eb40ebbd0a25c15eaac5962Tor Norbye */ 2855ae903bf8670f40e9eb40ebbd0a25c15eaac5962Tor Norbye @NonNull 2865ae903bf8670f40e9eb40ebbd0a25c15eaac5962Tor Norbye public Image addErrorIcon(@NonNull Image image) { 2875ae903bf8670f40e9eb40ebbd0a25c15eaac5962Tor Norbye if (mErrorIcons != null) { 2885ae903bf8670f40e9eb40ebbd0a25c15eaac5962Tor Norbye Image combined = mErrorIcons.get(image); 2895ae903bf8670f40e9eb40ebbd0a25c15eaac5962Tor Norbye if (combined != null) { 2905ae903bf8670f40e9eb40ebbd0a25c15eaac5962Tor Norbye return combined; 2915ae903bf8670f40e9eb40ebbd0a25c15eaac5962Tor Norbye } 2925ae903bf8670f40e9eb40ebbd0a25c15eaac5962Tor Norbye } else { 2935ae903bf8670f40e9eb40ebbd0a25c15eaac5962Tor Norbye mErrorIcons = new IdentityHashMap<Image, Image>(); 2945ae903bf8670f40e9eb40ebbd0a25c15eaac5962Tor Norbye } 2955ae903bf8670f40e9eb40ebbd0a25c15eaac5962Tor Norbye 2965ae903bf8670f40e9eb40ebbd0a25c15eaac5962Tor Norbye Image combined = new ErrorImageComposite(image, false).createImage(); 2975ae903bf8670f40e9eb40ebbd0a25c15eaac5962Tor Norbye mErrorIcons.put(image, combined); 2985ae903bf8670f40e9eb40ebbd0a25c15eaac5962Tor Norbye 2995ae903bf8670f40e9eb40ebbd0a25c15eaac5962Tor Norbye return combined; 3005ae903bf8670f40e9eb40ebbd0a25c15eaac5962Tor Norbye } 3015ae903bf8670f40e9eb40ebbd0a25c15eaac5962Tor Norbye 3025ae903bf8670f40e9eb40ebbd0a25c15eaac5962Tor Norbye /** 3035ae903bf8670f40e9eb40ebbd0a25c15eaac5962Tor Norbye * Returns an image with a warning icon overlaid on it. The icons are 3045ae903bf8670f40e9eb40ebbd0a25c15eaac5962Tor Norbye * cached, so the base image should be cached as well, or this method will 3055ae903bf8670f40e9eb40ebbd0a25c15eaac5962Tor Norbye * keep storing new overlays into its cache. 3065ae903bf8670f40e9eb40ebbd0a25c15eaac5962Tor Norbye * 3075ae903bf8670f40e9eb40ebbd0a25c15eaac5962Tor Norbye * @param image the base image 3085ae903bf8670f40e9eb40ebbd0a25c15eaac5962Tor Norbye * @return the combined image 3095ae903bf8670f40e9eb40ebbd0a25c15eaac5962Tor Norbye */ 3105ae903bf8670f40e9eb40ebbd0a25c15eaac5962Tor Norbye @NonNull 3115ae903bf8670f40e9eb40ebbd0a25c15eaac5962Tor Norbye public Image addWarningIcon(@NonNull Image image) { 3125ae903bf8670f40e9eb40ebbd0a25c15eaac5962Tor Norbye if (mWarningIcons != null) { 3135ae903bf8670f40e9eb40ebbd0a25c15eaac5962Tor Norbye Image combined = mWarningIcons.get(image); 3145ae903bf8670f40e9eb40ebbd0a25c15eaac5962Tor Norbye if (combined != null) { 3155ae903bf8670f40e9eb40ebbd0a25c15eaac5962Tor Norbye return combined; 3165ae903bf8670f40e9eb40ebbd0a25c15eaac5962Tor Norbye } 3175ae903bf8670f40e9eb40ebbd0a25c15eaac5962Tor Norbye } else { 3185ae903bf8670f40e9eb40ebbd0a25c15eaac5962Tor Norbye mWarningIcons = new IdentityHashMap<Image, Image>(); 3195ae903bf8670f40e9eb40ebbd0a25c15eaac5962Tor Norbye } 3205ae903bf8670f40e9eb40ebbd0a25c15eaac5962Tor Norbye 3215ae903bf8670f40e9eb40ebbd0a25c15eaac5962Tor Norbye Image combined = new ErrorImageComposite(image, true).createImage(); 3225ae903bf8670f40e9eb40ebbd0a25c15eaac5962Tor Norbye mWarningIcons.put(image, combined); 3235ae903bf8670f40e9eb40ebbd0a25c15eaac5962Tor Norbye 3245ae903bf8670f40e9eb40ebbd0a25c15eaac5962Tor Norbye return combined; 3255ae903bf8670f40e9eb40ebbd0a25c15eaac5962Tor Norbye } 3265ae903bf8670f40e9eb40ebbd0a25c15eaac5962Tor Norbye 3275ae903bf8670f40e9eb40ebbd0a25c15eaac5962Tor Norbye /** 32855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * A simple image description that generates a 16x16 image which consists 32955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project * of a colored letter inside a black & white circle. 33055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project */ 33155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project private static class LetterImageDescriptor extends ImageDescriptor { 33255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project 33355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project private final char mLetter; 33455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project private final int mColor; 33555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project private final int mShape; 33655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project 33755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project public LetterImageDescriptor(char letter, int color, int shape) { 33893b86c1f3185c8df21e2a45a31e4cd9ce567cef0Tor Norbye mLetter = Character.toUpperCase(letter); 33955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project mColor = color; 34055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project mShape = shape; 34155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project } 34293b86c1f3185c8df21e2a45a31e4cd9ce567cef0Tor Norbye 34355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project @Override 34455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project public ImageData getImageData() { 34593b86c1f3185c8df21e2a45a31e4cd9ce567cef0Tor Norbye 34655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project final int SX = 15; 34755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project final int SY = 15; 34855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project final int RX = 4; 34955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project final int RY = 4; 35093b86c1f3185c8df21e2a45a31e4cd9ce567cef0Tor Norbye 35155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project Display display = Display.getCurrent(); 35255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project if (display == null) { 35355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project return null; 35455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project } 35555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project 35655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project Image image = new Image(display, SX, SY); 35793b86c1f3185c8df21e2a45a31e4cd9ce567cef0Tor Norbye 35855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project GC gc = new GC(image); 35955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project gc.setAdvanced(true); 36055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project gc.setAntialias(SWT.ON); 36155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project gc.setTextAntialias(SWT.ON); 36255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project 363a2d7874ed23bfc2fa7665cc84901e0f4781b4e51Tor Norbye // image.setBackground() does not appear to have any effect; we must explicitly 36493b86c1f3185c8df21e2a45a31e4cd9ce567cef0Tor Norbye // paint into the image the background color we want masked out later. 36593b86c1f3185c8df21e2a45a31e4cd9ce567cef0Tor Norbye // HOWEVER, alpha transparency does not work; we only get to mark a single color 36693b86c1f3185c8df21e2a45a31e4cd9ce567cef0Tor Norbye // as transparent. You might think we could pick a system color (to avoid having 36793b86c1f3185c8df21e2a45a31e4cd9ce567cef0Tor Norbye // to allocate and dispose the color), or a wildly unique color (to make sure we 36893b86c1f3185c8df21e2a45a31e4cd9ce567cef0Tor Norbye // don't accidentally pick up any extra pixels in the image as transparent), but 36993b86c1f3185c8df21e2a45a31e4cd9ce567cef0Tor Norbye // this has the very unfortunate side effect of making neighbor pixels in the 37093b86c1f3185c8df21e2a45a31e4cd9ce567cef0Tor Norbye // antialiased rendering of the circle pick up shades of that alternate color, 37193b86c1f3185c8df21e2a45a31e4cd9ce567cef0Tor Norbye // which looks bad. Therefore we pick a color which is similar to one of our 37293b86c1f3185c8df21e2a45a31e4cd9ce567cef0Tor Norbye // existing colors but hopefully different from most pixels. A visual check 37393b86c1f3185c8df21e2a45a31e4cd9ce567cef0Tor Norbye // confirms that this seems to work pretty well: 37493b86c1f3185c8df21e2a45a31e4cd9ce567cef0Tor Norbye RGB backgroundRgb = new RGB(254, 254, 254); 37593b86c1f3185c8df21e2a45a31e4cd9ce567cef0Tor Norbye Color backgroundColor = new Color(display, backgroundRgb); 37693b86c1f3185c8df21e2a45a31e4cd9ce567cef0Tor Norbye gc.setBackground(backgroundColor); 37793b86c1f3185c8df21e2a45a31e4cd9ce567cef0Tor Norbye gc.fillRectangle(0, 0, SX, SY); 37893b86c1f3185c8df21e2a45a31e4cd9ce567cef0Tor Norbye 37955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project gc.setBackground(display.getSystemColor(SWT.COLOR_WHITE)); 38055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project if (mShape == SHAPE_CIRCLE) { 38155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project gc.fillOval(0, 0, SX - 1, SY - 1); 38255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project } else if (mShape == SHAPE_RECT) { 38355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project gc.fillRoundRectangle(0, 0, SX - 1, SY - 1, RX, RY); 38455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project } 38593b86c1f3185c8df21e2a45a31e4cd9ce567cef0Tor Norbye 38655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project gc.setForeground(display.getSystemColor(SWT.COLOR_BLACK)); 38755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project gc.setLineWidth(1); 38855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project if (mShape == SHAPE_CIRCLE) { 38955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project gc.drawOval(0, 0, SX - 1, SY - 1); 39055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project } else if (mShape == SHAPE_RECT) { 39155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project gc.drawRoundRectangle(0, 0, SX - 1, SY - 1, RX, RY); 39255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project } 39355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project 39455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project // Get a bold version of the default system font, if possible. 39555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project Font font = display.getSystemFont(); 39655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project FontData[] fds = font.getFontData(); 39755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project fds[0].setStyle(SWT.BOLD); 39855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project // use 3/4th of the circle diameter for the font size (in pixels) 39955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project // and convert it to "font points" (font points in SWT are hardcoded in an 40055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project // arbitrary 72 dpi and then converted in real pixels using whatever is 40155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project // indicated by getDPI -- at least that's how it works under Win32). 40255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project fds[0].setHeight((int) ((SY + 1) * 3./4. * 72./display.getDPI().y)); 40355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project // Note: win32 implementation always uses fds[0] so we change just that one. 40455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project // getFontData indicates that the array of fd is really an unusual thing for X11. 40555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project font = new Font(display, fds); 40655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project gc.setFont(font); 40755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project gc.setForeground(display.getSystemColor(mColor)); 40855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project 40955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project // Text measurement varies so slightly depending on the platform 41055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project int ofx = 0; 41155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project int ofy = 0; 41255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project if (SdkConstants.CURRENT_PLATFORM == SdkConstants.PLATFORM_WINDOWS) { 41355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project ofx = +1; 41455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project ofy = -1; 41593b86c1f3185c8df21e2a45a31e4cd9ce567cef0Tor Norbye } else if (SdkConstants.CURRENT_PLATFORM == SdkConstants.PLATFORM_DARWIN) { 41693b86c1f3185c8df21e2a45a31e4cd9ce567cef0Tor Norbye // Tweak pixel positioning of some letters that don't look good on the Mac 41793b86c1f3185c8df21e2a45a31e4cd9ce567cef0Tor Norbye if (mLetter != 'T' && mLetter != 'V') { 41893b86c1f3185c8df21e2a45a31e4cd9ce567cef0Tor Norbye ofy = -1; 41993b86c1f3185c8df21e2a45a31e4cd9ce567cef0Tor Norbye } 42093b86c1f3185c8df21e2a45a31e4cd9ce567cef0Tor Norbye if (mLetter == 'I') { 42193b86c1f3185c8df21e2a45a31e4cd9ce567cef0Tor Norbye ofx = -2; 42293b86c1f3185c8df21e2a45a31e4cd9ce567cef0Tor Norbye } 42355a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project } 42493b86c1f3185c8df21e2a45a31e4cd9ce567cef0Tor Norbye 42593b86c1f3185c8df21e2a45a31e4cd9ce567cef0Tor Norbye String s = Character.toString(mLetter); 42655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project Point p = gc.textExtent(s); 42755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project int tx = (SX + ofx - p.x) / 2; 42855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project int ty = (SY + ofy - p.y) / 2; 42955a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project gc.drawText(s, tx, ty, true /* isTransparent */); 43055a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project 43155a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project font.dispose(); 43255a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project gc.dispose(); 43393b86c1f3185c8df21e2a45a31e4cd9ce567cef0Tor Norbye 43455a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project ImageData data = image.getImageData(); 43555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project image.dispose(); 43693b86c1f3185c8df21e2a45a31e4cd9ce567cef0Tor Norbye backgroundColor.dispose(); 43793b86c1f3185c8df21e2a45a31e4cd9ce567cef0Tor Norbye 43893b86c1f3185c8df21e2a45a31e4cd9ce567cef0Tor Norbye // Set transparent pixel in the palette such that on paint (over palette, 43993b86c1f3185c8df21e2a45a31e4cd9ce567cef0Tor Norbye // which has a background of SWT.COLOR_WIDGET_BACKGROUND, and over the tree 44093b86c1f3185c8df21e2a45a31e4cd9ce567cef0Tor Norbye // which has a white background) we will substitute the background in for 44193b86c1f3185c8df21e2a45a31e4cd9ce567cef0Tor Norbye // the backgroundPixel. 44293b86c1f3185c8df21e2a45a31e4cd9ce567cef0Tor Norbye int backgroundPixel = data.palette.getPixel(backgroundRgb); 44393b86c1f3185c8df21e2a45a31e4cd9ce567cef0Tor Norbye data.transparentPixel = backgroundPixel; 44493b86c1f3185c8df21e2a45a31e4cd9ce567cef0Tor Norbye 44555a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project return data; 44655a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project } 44755a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project } 44855a2c71f27d3e0b8344597c7f281e687cb7aeb1bThe Android Open Source Project} 449