/** * Copyright (c) 2014 - 2017 Frank Appel * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Frank Appel - initial API and implementation */ package com.codeaffine.eclipse.ui.swt.theme; import static java.nio.file.Files.copy; import static java.nio.file.StandardCopyOption.REPLACE_EXISTING; import static java.util.Collections.emptyMap; import static java.util.Collections.list; import static org.eclipse.core.runtime.FileLocator.find; import static org.osgi.service.log.LogService.LOG_ERROR; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.nio.file.Files; import java.util.Enumeration; import org.eclipse.core.runtime.FileLocator; import org.eclipse.core.runtime.Path; import org.eclipse.swt.widgets.Display; import org.osgi.framework.BundleContext; import org.osgi.service.log.LogService; import org.osgi.util.tracker.ServiceTracker; class FontLoader { static final String FONT_FACE = "Source Code Pro"; static final String FONTS_DIRECTORY = "/fonts"; private final String fontDirectory; FontLoader( String fontDirectory ) { this.fontDirectory = fontDirectory; } void load( BundleContext context, Display display ) { try { doLoad( context, display ); } catch( RuntimeException rte ) { getLogService( context ).log( LOG_ERROR, "Unable to load clean sheet fonts.", rte ); } } private void doLoad( BundleContext context, Display display ) { list( getFontPaths( context, fontDirectory ) ) .forEach( fontPath -> loadFont( context, fontPath, display ) ); } private static LogService getLogService( BundleContext context ) { ServiceTracker<Object, Object> tracker = new ServiceTracker<>( context, LogService.class.getName(), null ); tracker.open(); LogService result = ( LogService )tracker.getService(); tracker.close(); return result; } private static Enumeration<String> getFontPaths( BundleContext context, String fontDirectory ) { return context.getBundle().getEntryPaths( fontDirectory ); } private static void loadFont( BundleContext context, String fontPath, Display display ) { if( fontPath.endsWith( ".ttf" ) ) { URL url = computeFontUrl( find( context.getBundle(), new Path( fontPath ), emptyMap() ) ); File diskLocation = getDiskLocation( fontPath ); copyToDisk( url, diskLocation ); display.asyncExec( () -> display.loadFont( diskLocation.toString() ) ); } } private static File getDiskLocation( String fontPath ) { try { return Activator.getInstance().getStateLocation().append( fontPath ).toFile().getCanonicalFile(); } catch( IOException shouldNotHappen ) { throw new IllegalStateException( shouldNotHappen ); } } private static URL computeFontUrl( URL url ) { try { return FileLocator.toFileURL( url ); } catch( IOException shouldNotHappen ) { throw new IllegalStateException( shouldNotHappen ); } } private static void copyToDisk( URL url, File diskLocation ) { try( InputStream input = url.openStream() ) { ensureDirectoryExists( diskLocation.toPath() ); copy( input, diskLocation.toPath(), REPLACE_EXISTING ); } catch (IOException shouldNotHappen ) { throw new IllegalStateException( shouldNotHappen ); } } private static void ensureDirectoryExists( java.nio.file.Path path ) throws IOException { if( !Files.exists( path.getParent() ) ) { Files.createDirectories( path.getParent() ); } } }