SubwayTooter-Android-App/_Emoji/src/main/java/com/android/ide/common/vectordrawable/VdTree.java

152 lines
5.2 KiB
Java

/*
* Copyright (C) 2015 The Android Open Source Project
*
* 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.android.ide.common.vectordrawable;
import java.awt.*;
import java.awt.geom.Path2D;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Used to represent the whole VectorDrawable XML file's tree.
*/
class VdTree {
private static Logger logger = Logger.getLogger(VdTree.class.getSimpleName());
VdGroup mCurrentGroup = new VdGroup();
ArrayList<VdElement> mChildren;
float mBaseWidth = 1;
float mBaseHeight = 1;
float mPortWidth = 1;
float mPortHeight = 1;
float mRootAlpha = 1;
/**
* Ensure there is at least one animation for every path in group (linking
* them by names) Build the "current" path based on the first group
*/
void parseFinish() {
mChildren = mCurrentGroup.getChildren();
}
void add(VdElement pathOrGroup) {
mCurrentGroup.add(pathOrGroup);
}
float getBaseWidth(){
return mBaseWidth;
}
float getBaseHeight(){
return mBaseHeight;
}
private void drawInternal(Graphics g, int w, int h) {
float scaleX = w / mPortWidth;
float scaleY = h / mPortHeight;
float minScale = Math.min(scaleX, scaleY);
if (mChildren == null) {
logger.log(Level.FINE, "no pathes");
return;
}
((Graphics2D) g).scale(scaleX, scaleY);
Rectangle bounds = null;
for (int i = 0; i < mChildren.size(); i++) {
// TODO: do things differently when it is a path or group!!
VdPath path = (VdPath) mChildren.get(i);
logger.log(Level.FINE, "mCurrentPaths[" + i + "]=" + path.getName() +
Integer.toHexString(path.mFillColor));
if (mChildren.get(i) != null) {
Rectangle r = drawPath(path, g, w, h, minScale);
if (bounds == null) {
bounds = r;
} else {
bounds.add(r);
}
}
}
logger.log(Level.FINE, "Rectangle " + bounds);
logger.log(Level.FINE, "Port " + mPortWidth + "," + mPortHeight);
double right = mPortWidth - bounds.getMaxX();
double bot = mPortHeight - bounds.getMaxY();
logger.log(Level.FINE, "x " + bounds.getMinX() + ", " + right);
logger.log(Level.FINE, "y " + bounds.getMinY() + ", " + bot);
}
private Rectangle drawPath(VdPath path, Graphics canvas, int w, int h, float scale) {
Path2D path2d = new Path2D.Double();
Graphics2D g = (Graphics2D) canvas;
path.toPath(path2d);
// TODO: Use AffineTransform to apply group's transformation info.
double theta = Math.toRadians(path.mRotate);
g.rotate(theta, path.mRotateX, path.mRotateY);
if (path.mClip) {
logger.log(Level.FINE, "CLIP");
g.setColor(Color.RED);
g.fill(path2d);
}
if (path.mFillColor != 0) {
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.setColor(new Color(path.mFillColor, true));
g.fill(path2d);
}
if (path.mStrokeColor != 0) {
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.setStroke(new BasicStroke(path.mStrokeWidth));
g.setColor(new Color(path.mStrokeColor, true));
g.draw(path2d);
}
g.rotate(-theta, path.mRotateX, path.mRotateY);
return path2d.getBounds();
}
// /**
// * Draw the VdTree into an image.
// * If the root alpha is less than 1.0, then draw into a temporary image,
// * then draw into the result image applying alpha blending.
// */
// public void drawIntoImage(BufferedImage image) {
// Graphics2D gFinal = (Graphics2D) image.getGraphics();
// int width = image.getWidth();
// int height = image.getHeight();
// gFinal.setColor(new Color(255, 255, 255, 0));
// gFinal.fillRect(0, 0, width, height);
//
// float rootAlpha = mRootAlpha;
// if (rootAlpha < 1.0) {
// BufferedImage alphaImage = AssetUtil.newArgbBufferedImage(width, height);
// Graphics2D gTemp = (Graphics2D)alphaImage.getGraphics();
// drawInternal(gTemp, width, height);
// gFinal.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, rootAlpha));
// gFinal.drawImage(alphaImage, 0, 0, null);
// gTemp.dispose();
// } else {
// drawInternal(gFinal, width, height);
// }
// gFinal.dispose();
// }
}