2 * Copyright (C) 2013 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package com.android.gallery3d.filtershow.filters;
19 import android.graphics.Color;
20 import android.graphics.Path;
21 import android.graphics.PathMeasure;
22 import android.util.JsonReader;
23 import android.util.JsonWriter;
24 import android.util.Log;
26 import com.android.gallery3d.R;
27 import com.android.gallery3d.filtershow.controller.BasicParameterInt;
28 import com.android.gallery3d.filtershow.controller.BasicParameterStyle;
29 import com.android.gallery3d.filtershow.controller.Parameter;
30 import com.android.gallery3d.filtershow.controller.ParameterBrightness;
31 import com.android.gallery3d.filtershow.controller.ParameterHue;
32 import com.android.gallery3d.filtershow.controller.ParameterOpacity;
33 import com.android.gallery3d.filtershow.controller.ParameterSaturation;
34 import com.android.gallery3d.filtershow.editors.EditorDraw;
36 import java.io.IOException;
37 import java.util.Arrays;
38 import java.util.Vector;
40 public class FilterDrawRepresentation extends FilterRepresentation {
41 private static final String LOGTAG = "FilterDrawRepresentation";
43 public static final int PARAM_SIZE = 0;
44 public static final int PARAM_HUE = 1;
45 public static final int PARAM_BRIGHTNESS = 2;
46 public static final int PARAM_SATURATION = 3;
47 public static final int PARAM_OPACITY = 4;
48 public static final int PARAM_STYLE = 5;
49 private BasicParameterInt mParamSize = new BasicParameterInt(PARAM_SIZE, 20, 2, 300);
50 private BasicParameterInt mParamHue = new ParameterHue(PARAM_HUE, 0);
51 private BasicParameterInt mParamBrightness = new ParameterBrightness(PARAM_BRIGHTNESS, 220);
52 private BasicParameterInt mParamSaturation = new ParameterSaturation(PARAM_SATURATION, 200);
53 private ParameterOpacity mParamOpacity = new ParameterOpacity(PARAM_OPACITY, 200);
54 private BasicParameterStyle mParamStyle = new BasicParameterStyle(PARAM_STYLE, 5);
56 Parameter mCurrentParam = mParamSize;
57 private static final String SERIAL_COLOR = "color";
58 private static final String SERIAL_RADIUS = "radius";
59 private static final String SERIAL_TYPE = "type";
60 private static final String SERIAL_POINTS_COUNT = "point_count";
61 private static final String SERIAL_POINTS = "points";
62 private static final String SERIAL_PATH = "path";
65 private Parameter[] mAllParam = {
74 public void setPramMode(int mode) {
76 mCurrentParam = mAllParam[mParamMode];
79 public int getParamMode() {
83 public Parameter getCurrentParam() {
84 return mAllParam[mParamMode];
87 public Parameter getParam(int type) {
88 return mAllParam[type];
91 public static class StrokeData implements Cloneable {
96 public int noPoints = 0;
97 public float[] mPoints = new float[20];
100 public String toString() {
101 return "stroke(" + mType + ", path(" + (mPath) + "), " + mRadius + " , "
102 + Integer.toHexString(mColor) + ")";
106 public StrokeData clone() throws CloneNotSupportedException {
107 return (StrokeData) super.clone();
111 public String getValueString() {
113 switch (mParamMode) {
116 case PARAM_BRIGHTNESS:
117 case PARAM_SATURATION:
119 int val = ((BasicParameterInt) mAllParam[mParamMode]).getValue();
120 return ((val > 0) ? " +" : " ") + val;
128 private Vector<StrokeData> mDrawing = new Vector<StrokeData>();
129 private StrokeData mCurrent; // used in the currently drawing style
131 public FilterDrawRepresentation() {
133 setFilterClass(ImageFilterDraw.class);
134 setSerializationName("DRAW");
135 setFilterType(FilterRepresentation.TYPE_VIGNETTE);
136 setTextId(R.string.imageDraw);
137 setEditorId(EditorDraw.ID);
138 setOverlayId(R.drawable.filtershow_drawing);
139 setOverlayOnly(true);
143 public String toString() {
144 return getName() + " : strokes=" + mDrawing.size()
145 + ((mCurrent == null) ? " no current "
146 : ("draw=" + mCurrent.mType + " " + mCurrent.noPoints));
149 public Vector<StrokeData> getDrawing() {
153 public StrokeData getCurrentDrawing() {
158 public FilterRepresentation copy() {
159 FilterDrawRepresentation representation = new FilterDrawRepresentation();
160 copyAllParameters(representation);
161 return representation;
165 protected void copyAllParameters(FilterRepresentation representation) {
166 super.copyAllParameters(representation);
167 representation.useParametersFrom(this);
171 public boolean isNil() {
172 return getDrawing().isEmpty();
176 public void useParametersFrom(FilterRepresentation a) {
177 if (a instanceof FilterDrawRepresentation) {
178 FilterDrawRepresentation representation = (FilterDrawRepresentation) a;
180 if (representation.mCurrent != null) {
181 mCurrent = (StrokeData) representation.mCurrent.clone();
185 if (representation.mDrawing != null) {
186 mDrawing = (Vector<StrokeData>) representation.mDrawing.clone();
191 } catch (CloneNotSupportedException e) {
195 Log.v(LOGTAG, "cannot use parameters from " + a);
200 public boolean equals(FilterRepresentation representation) {
201 if (!super.equals(representation)) {
204 if (representation instanceof FilterDrawRepresentation) {
205 FilterDrawRepresentation fdRep = (FilterDrawRepresentation) representation;
206 if (fdRep.mDrawing.size() != mDrawing.size())
208 if (fdRep.mCurrent == null && (mCurrent == null || mCurrent.mPath == null)) {
211 if (fdRep.mCurrent != null && mCurrent != null && mCurrent.mPath != null) {
212 if (fdRep.mCurrent.noPoints == mCurrent.noPoints) {
221 private int computeCurrentColor(){
222 float hue = 360 * mParamHue.getValue() / (float) mParamHue.getMaximum();
223 float sat = mParamSaturation.getValue() / (float) mParamSaturation.getMaximum();
224 float val = mParamBrightness.getValue() / (float) mParamBrightness.getMaximum();
225 int op = mParamOpacity.getValue();
226 float[] hsv = new float[]{hue, sat, val};
227 return Color.HSVToColor(op, hsv);
230 public void fillStrokeParameters(StrokeData sd){
231 byte type = (byte) mParamStyle.getSelected();
232 int color = computeCurrentColor();
233 float size = mParamSize.getValue();
239 public void startNewSection(float x, float y) {
240 mCurrent = new StrokeData();
241 fillStrokeParameters(mCurrent);
242 mCurrent.mPath = new Path();
243 mCurrent.mPath.moveTo(x, y);
244 mCurrent.mPoints[0] = x;
245 mCurrent.mPoints[1] = y;
246 mCurrent.noPoints = 1;
249 public void addPoint(float x, float y) {
250 int len = mCurrent.noPoints * 2;
251 mCurrent.mPath.lineTo(x, y);
252 if ((len+2) > mCurrent.mPoints.length) {
253 mCurrent.mPoints = Arrays.copyOf(mCurrent.mPoints, mCurrent.mPoints.length * 2);
255 mCurrent.mPoints[len] = x;
256 mCurrent.mPoints[len + 1] = y;
260 public void endSection(float x, float y) {
262 mDrawing.add(mCurrent);
266 public void clearCurrentSection() {
270 public void clear() {
276 public void serializeRepresentation(JsonWriter writer) throws IOException {
277 writer.beginObject();
278 int len = mDrawing.size();
280 float[] mPosition = new float[2];
281 float[] mTan = new float[2];
283 PathMeasure mPathMeasure = new PathMeasure();
284 for (int i = 0; i < len; i++) {
285 writer.name(SERIAL_PATH + i);
286 writer.beginObject();
287 StrokeData mark = mDrawing.get(i);
288 writer.name(SERIAL_COLOR).value(mark.mColor);
289 writer.name(SERIAL_RADIUS).value(mark.mRadius);
290 writer.name(SERIAL_TYPE).value(mark.mType);
291 writer.name(SERIAL_POINTS_COUNT).value(mark.noPoints);
292 writer.name(SERIAL_POINTS);
295 int npoints = mark.noPoints * 2;
296 for (int j = 0; j < npoints; j++) {
297 writer.value(mark.mPoints[j]);
306 public void deSerializeRepresentation(JsonReader sreader) throws IOException {
307 sreader.beginObject();
308 Vector<StrokeData> strokes = new Vector<StrokeData>();
310 while (sreader.hasNext()) {
312 sreader.beginObject();
313 StrokeData stroke = new StrokeData();
315 while (sreader.hasNext()) {
316 String name = sreader.nextName();
317 if (name.equals(SERIAL_COLOR)) {
318 stroke.mColor = sreader.nextInt();
319 } else if (name.equals(SERIAL_RADIUS)) {
320 stroke.mRadius = (float) sreader.nextDouble();
321 } else if (name.equals(SERIAL_TYPE)) {
322 stroke.mType = (byte) sreader.nextInt();
323 } else if (name.equals(SERIAL_POINTS_COUNT)) {
324 stroke.noPoints = sreader.nextInt();
325 } else if (name.equals(SERIAL_POINTS)) {
328 sreader.beginArray();
329 while (sreader.hasNext()) {
330 if ((count + 1) > stroke.mPoints.length) {
331 stroke.mPoints = Arrays.copyOf(stroke.mPoints, count * 2);
333 stroke.mPoints[count++] = (float) sreader.nextDouble();
335 stroke.mPath = new Path();
336 stroke.mPath.moveTo(stroke.mPoints[0], stroke.mPoints[1]);
337 for (int i = 0; i < count; i += 2) {
338 stroke.mPath.lineTo(stroke.mPoints[i], stroke.mPoints[i + 1]);