All pastes #2113438 Raw Edit

Mine

public java v1 · immutable
#2113438 ·published 2012-02-08 22:41 UTC
rendered paste body
/******************************************************************************* * Copyright 2011 See AUTHORS file. *  * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at *  *   http://www.apache.org/licenses/LICENSE-2.0 *  * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************/package com.badlogic.gdx.tools.skins;import java.awt.image.BufferedImage;import java.awt.image.WritableRaster;import java.io.File;import java.io.FilenameFilter;import java.io.Writer;import java.util.HashMap;import javax.imageio.ImageIO;import com.badlogic.gdx.files.FileHandle;import com.badlogic.gdx.graphics.Pixmap.Format;import com.badlogic.gdx.graphics.Texture.TextureFilter;import com.badlogic.gdx.graphics.Texture;import com.badlogic.gdx.graphics.g2d.BitmapFont;import com.badlogic.gdx.graphics.g2d.NinePatch;import com.badlogic.gdx.graphics.g2d.BitmapFont.BitmapFontData;import com.badlogic.gdx.graphics.g2d.TextureAtlas.TextureAtlasData;import com.badlogic.gdx.graphics.g2d.TextureAtlas.TextureAtlasData.Region;import com.badlogic.gdx.graphics.g2d.TextureRegion;import com.badlogic.gdx.scenes.scene2d.ui.Skin;import com.badlogic.gdx.tools.FileProcessor;import com.badlogic.gdx.tools.imagepacker.TexturePacker;import com.badlogic.gdx.tools.imagepacker.TexturePacker.Settings;import com.badlogic.gdx.utils.Array;import com.badlogic.gdx.utils.GdxRuntimeException;import com.badlogic.gdx.utils.Json;import com.badlogic.gdx.utils.ObjectMap;import com.badlogic.gdx.utils.OrderedMap;/** * Utility to help build {@link Skin} files. *  * Based on the original SkinPacker by Nathan Sweet *  * @author tbone */public class NewSkinPacker{	/**	 * The directory containing all of the input resources.	 * 	 * This includes TextureRegions (.png files) and NinePatch (.9.png files)	 */	public FileHandle inputDirectory;		/**	 * The .json file to use as a template.	 * 	 * The only *required* section is the 'styles' section which defines the	 * different resource mappings.	 */	public FileHandle inputSkinTemplate;		/**	 * The output directory where the compiled skin file, font(s) and images	 * are put.  Everything in this directory will be removed during pack.	 */	public FileHandle outputDirectory;	/**	 * The texture atlas settings	 */	public Settings atlasSettings;	/**	 * Constructs a new skin packer	 * 	 * @param settings The {@link TexturePacker} {@link Settings}	 * @param inputDir Input directory containing the images.	 * @param outputDir Output directory	 * @param templateSkin Input template containing the style definitions	 */	public NewSkinPacker(Settings settings, FileHandle inputDir, FileHandle outputDir, FileHandle templateSkin)	{		atlasSettings = settings;		inputDirectory = inputDir;		outputDirectory = outputDir;		inputSkinTemplate = templateSkin;	}		public NewSkinPacker()	{		atlasSettings = new Settings();		atlasSettings.alias = true;		atlasSettings.pot = true;		atlasSettings.maxWidth = 1024;		atlasSettings.maxHeight = 1024;		atlasSettings.defaultFilterMag = TextureFilter.Linear;		atlasSettings.defaultFilterMin = TextureFilter.Linear;		atlasSettings.duplicatePadding = false;	}		/**	 * Packs the skin with the current settings.	 */	public void pack() throws Exception	{		if (outputDirectory.exists())			outputDirectory.deleteDirectory();		outputDirectory.mkdirs();				final ObjectMap<String, int[]> nameToSplits = new ObjectMap<String, int[]>();		final TexturePacker packer = new TexturePacker(atlasSettings);				// Region Processor		FileProcessor regionProcessor = new FileProcessor() {			protected void processFile(InputFile inputFile) throws Exception {				packer.addImage(ImageIO.read(inputFile.inputFile), inputFile.outputFile.getName());			}		};		regionProcessor.setInputFilter(new FilenameFilter() {			public boolean accept(File dir, String name) {				return name.endsWith(".png") && !name.endsWith(".9.png");			}		});		regionProcessor.setRecursive(false);		regionProcessor.setOutputSuffix("");		regionProcessor.process(inputDirectory.file(), outputDirectory.file());				// Nine Patch Processor		FileProcessor ninePatchProcessor = new FileProcessor()		{			protected void processFile (InputFile inputFile) throws Exception {                BufferedImage image = ImageIO.read(inputFile.inputFile);                String name = inputFile.outputFile.getName();                name = name.substring(0, name.length() - 2);                image = getSplits(image, name);                packer.addImage(image, name);			}						private BufferedImage getSplits (BufferedImage image, String name) {                WritableRaster raster = image.getRaster();                int[] rgba = new int[4];                int startX = 1;                for (int x = 1; x < raster.getWidth() - 1; x++) {                        raster.getPixel(x, 0, rgba);                        if (rgba[3] == 0) continue;                        if (rgba[0] != 0 || rgba[1] != 0 || rgba[2] != 0)                                throw new RuntimeException("Unknown pixel:" + x + ",0: " + name);                        startX = x;                        break;                }                int endX;                for (endX = startX; endX < raster.getWidth() - 1; endX++) {                        raster.getPixel(endX, 0, rgba);                        if (rgba[3] == 0) break;                        if (rgba[0] != 0 || rgba[1] != 0 || rgba[2] != 0)                                throw new RuntimeException("Unknown pixel " + endX + ",0: " + name);                }                for (int x = endX + 1; x < raster.getWidth() - 1; x++) {                        raster.getPixel(x, 0, rgba);                        if (rgba[3] != 0) throw new RuntimeException("Unknown pixel " + x + ",0: " + name);                }                int startY = 1;                for (int y = 1; y < raster.getHeight() - 1; y++) {                        raster.getPixel(0, y, rgba);                        if (rgba[3] == 0) continue;                        if (rgba[0] != 0 || rgba[1] != 0 || rgba[2] != 0)                                throw new RuntimeException("Unknown pixel: 0," + y + ": " + name);                        startY = y;                        break;                }                int endY;                for (endY = startY; endY < raster.getHeight() - 1; endY++) {                        raster.getPixel(0, endY, rgba);                        if (rgba[3] == 0) break;                        if (rgba[0] != 0 || rgba[1] != 0 || rgba[2] != 0)                                throw new RuntimeException("Unknown pixel 0," + endY + ": " + name);                }                for (int y = endY + 1; y < raster.getHeight() - 1; y++) {                        raster.getPixel(0, y, rgba);                        if (rgba[3] != 0) throw new RuntimeException("Unknown pixel 0," + y + ": " + name);                }                // No splits, or all splits.                boolean singleRegion = startX == 1 && endX == 1 && startY == 1 && endY == 1;                if (singleRegion) {                        endX = raster.getWidth();                        endY = raster.getHeight();                }                int[] splits = new int[5];                splits[0] = startX - 1;                splits[1] = endX - 1;                splits[2] = startY - 1;                splits[3] = endY - 1;                splits[4] = singleRegion ? 1 : 0;                nameToSplits.put(name, splits);                BufferedImage newImage = new BufferedImage(raster.getWidth() - 2, raster.getHeight() - 2,                        BufferedImage.TYPE_4BYTE_ABGR);                newImage.getGraphics().drawImage(image, 0, 0, newImage.getWidth(), newImage.getHeight(), 1, 1, raster.getWidth() - 1,                        raster.getHeight() - 1, null);                return newImage;			}		};		ninePatchProcessor.setRecursive(false);		ninePatchProcessor.addInputSuffix(".9.png");		ninePatchProcessor.setOutputSuffix("");		ninePatchProcessor.process(inputDirectory.file(), outputDirectory.file());				// Pack the images		final FileHandle packFile = outputDirectory.child("pack");		packer.process(outputDirectory.file(), packFile.file(), inputDirectory.name());		if (!packFile.exists())			throw new RuntimeException("No images were packed from input directory: " + inputDirectory.path());				// Builds a skin containing the new resources		Skin skin = new Skin();		TextureAtlasData atlas = new TextureAtlasData(packFile, packFile.parent(), true);		if (atlas.getPages().size > 1)			throw new GdxRuntimeException("Skin images could not be packed on to a single image!");		atlas.getPages().get(0).textureFile.moveTo(outputDirectory.child(inputSkinTemplate.nameWithoutExtension() + ".png"));		packFile.delete();				Texture texture = new Texture(1, 1, Format.Alpha);		for (Region region : atlas.getRegions())		{			int[] split = nameToSplits.get(region.name);			TextureRegion textureRegion = new TextureRegion(texture, region.left, region.top, region.width, region.height);						if (split == null) {				skin.addResource(region.name, textureRegion);			} else {				if (split[4] == 1)					skin.addResource(region.name, new NinePatch(textureRegion));				else					skin.addResource(region.name, new NinePatch(textureRegion, split[0], region.width - split[1], split[2], region.height - split[3]));			}		}				final FileHandle outputSkin = outputDirectory.child(inputSkinTemplate.name()); 		skin.save(outputSkin);				// Build the new skin file		Json json = new Json();		OrderedMap oldSkin = json.fromJson(OrderedMap.class, inputSkinTemplate);		OrderedMap newSkin = json.fromJson(OrderedMap.class, outputSkin);		OrderedMap oldResources = (OrderedMap)oldSkin.get("resources");		OrderedMap newResources = (OrderedMap)newSkin.get("resources");				OrderedMap newPatches = (OrderedMap)newResources.get(NinePatch.class.getName());		if (newPatches != null)		{			newPatches.orderedKeys().sort();			oldResources.put(NinePatch.class.getName(), newPatches);		}				OrderedMap newRegions = (OrderedMap)newResources.get(TextureRegion.class.getName());		if (newRegions != null)		{			newRegions.orderedKeys().sort();			oldResources.put(TextureRegion.class.getName(), newRegions);		}				Writer writer = outputSkin.writer(false);		writer.write(json.prettyPrint(oldSkin, 130));		writer.flush();		writer.close();				// Copy the font file(s)		OrderedMap fonts = (OrderedMap)oldResources.get(BitmapFont.class.getName());		for (String key : (Array<String>)fonts.orderedKeys())		{			FileHandle fontFile = inputSkinTemplate.parent().child((String)((OrderedMap)fonts.get(key)).get("file"));			FileHandle fontImage = new FileHandle(new BitmapFontData(fontFile, false).getImagePath());						fontFile.copyTo(outputDirectory);			fontImage.copyTo(outputDirectory);		}	}		public static void process(Settings settings, FileHandle inputDir, FileHandle outputDir, FileHandle inputSkinTemplate) throws Exception	{		new NewSkinPacker(settings, inputDir, outputDir, inputSkinTemplate).pack();	}}