16224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala/*
26224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala * Copyright 2012 AndroidPlot.com
36224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala *
46224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala *    Licensed under the Apache License, Version 2.0 (the "License");
56224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala *    you may not use this file except in compliance with the License.
66224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala *    You may obtain a copy of the License at
76224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala *
86224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala *        http://www.apache.org/licenses/LICENSE-2.0
96224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala *
106224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala *    Unless required by applicable law or agreed to in writing, software
116224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala *    distributed under the License is distributed on an "AS IS" BASIS,
126224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala *    See the License for the specific language governing permissions and
146224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala *    limitations under the License.
156224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala */
166224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala
176224eda509d436a575f801942337da92a6c18767Eino-Ville Talvalapackage com.androidplot.util;
186224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala
196224eda509d436a575f801942337da92a6c18767Eino-Ville Talvalaimport android.content.Context;
206224eda509d436a575f801942337da92a6c18767Eino-Ville Talvalaimport android.graphics.PointF;
216224eda509d436a575f801942337da92a6c18767Eino-Ville Talvalaimport android.graphics.Rect;
226224eda509d436a575f801942337da92a6c18767Eino-Ville Talvalaimport android.graphics.RectF;
236224eda509d436a575f801942337da92a6c18767Eino-Ville Talvalaimport android.util.DisplayMetrics;
246224eda509d436a575f801942337da92a6c18767Eino-Ville Talvalaimport android.util.TypedValue;
256224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala
266224eda509d436a575f801942337da92a6c18767Eino-Ville Talvalaimport java.util.Collections;
276224eda509d436a575f801942337da92a6c18767Eino-Ville Talvalaimport java.util.HashMap;
286224eda509d436a575f801942337da92a6c18767Eino-Ville Talvalaimport java.util.Map;
296224eda509d436a575f801942337da92a6c18767Eino-Ville Talvalaimport java.util.regex.Matcher;
306224eda509d436a575f801942337da92a6c18767Eino-Ville Talvalaimport java.util.regex.Pattern;
316224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala
326224eda509d436a575f801942337da92a6c18767Eino-Ville Talvalapublic class PixelUtils {
336224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala    private static DisplayMetrics metrics;
346224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala    private static final float FLOAT_INT_AVG_NUDGE = 0.5f;
356224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala    //private static float SCALE = 1;   //  pix per dp
366224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala    //private static int X_PIX = 1;     // total display horizontal pix
376224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala    //private static int Y_PIX = 1;     // total display vertical pix
386224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala
396224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala    /**
406224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala     * Recalculates scale value etc.  Should be called when an application starts or
416224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala     * whenever the screen is rotated.
426224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala     */
436224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala    public static void init(Context ctx) {
446224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala        //DisplayMetrics dm = ctx.getResources().getDisplayMetrics();
456224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala        //SCALE = dm.density;
466224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala        //X_PIX = dm.widthPixels;
476224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala        //Y_PIX = dm.heightPixels;
486224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala        metrics = ctx.getResources().getDisplayMetrics();
496224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala
506224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala    }
516224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala
526224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala    public static PointF add(PointF lhs, PointF rhs) {
536224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala        return new PointF(lhs.x + rhs.x, lhs.y + rhs.y);
546224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala    }
556224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala
566224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala    public static PointF sub(PointF lhs, PointF rhs) {
576224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala        return new PointF(lhs.x - rhs.x, lhs.y - rhs.y);
586224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala    }
596224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala
606224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala    /**
616224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala     * Converts a sub-pixel accurate RectF to a Rect
626224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala     * using the closest matching full pixel vals.  This is
636224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala     * useful for clipping operations etc.
646224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala     * @param rectIn The rect to be converted
656224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala     * @return
666224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala     */
676224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala    /*public static Rect toRect(RectF rectIn) {
686224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala        return new Rect(
696224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala                (int) (rectIn.left + FLOAT_INT_AVG_NUDGE),
706224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala                (int) (rectIn.top + FLOAT_INT_AVG_NUDGE),
716224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala                (int) (rectIn.right + FLOAT_INT_AVG_NUDGE),
726224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala                (int) (rectIn.bottom + FLOAT_INT_AVG_NUDGE));
736224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala    }*/
746224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala
756224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala    /**
766224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala     * Converts a sub-pixel accurate RectF to
776224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala     * a single pixel accurate rect.  This is helpful
786224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala     * for clipping operations which dont do a good job with
796224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala     * subpixel vals.
806224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala     * @param in
816224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala     * @return
826224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala     */
836224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala    public static RectF sink(RectF in) {
846224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala        return nearestPixRect(in.left, in.top, in.right, in.bottom);
856224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala    }
866224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala
876224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala    public static RectF nearestPixRect(float left, float top, float right, float bottom) {
886224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala        return new RectF(
896224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala                (int) (left + FLOAT_INT_AVG_NUDGE),
906224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala                (int) (top + FLOAT_INT_AVG_NUDGE),
916224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala                (int) (right + FLOAT_INT_AVG_NUDGE),
926224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala                (int) (bottom + FLOAT_INT_AVG_NUDGE));
936224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala    }
946224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala
956224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala    /**
966224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala     * Converts a dp value to pixels.
976224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala     * @param dp
986224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala     * @return Pixel value of dp.
996224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala     */
1006224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala    public static float dpToPix(float dp) {
1016224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala        //return SCALE * dp + FLOAT_INT_AVG_NUDGE;
1026224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala        //InternalDimension id = new InternalDimension(dp, TypedValue.COMPLEX_UNIT_DIP);
1036224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala        return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, metrics);
1046224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala
1056224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala    }
1066224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala
1076224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala    /**
1086224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala     * Converts an sp value to pixels.
1096224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala     * @param sp
1106224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala     * @return Pixel value of sp.
1116224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala     */
1126224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala    @SuppressWarnings("SameParameterValue")
1136224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala    public static float spToPix(float sp) {
1146224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala        return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, sp, metrics);
1156224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala    }
1166224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala
1176224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala
1186224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala    /**
1196224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala     *
1206224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala     * @param fraction A float value between 0 and 1.
1216224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala     * @return Number of pixels fraction represents on the current device's display.
1226224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala     */
1236224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala    public static float fractionToPixH(float fraction) {
1246224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala        return metrics.heightPixels * fraction;
1256224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala
1266224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala    }
1276224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala
1286224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala    /**
1296224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala     *
1306224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala     * @param fraction A float value between 0 and 1.
1316224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala     * @return Number of pixels fraction represents on the current device's display.
1326224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala     */
1336224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala    public static float fractionToPixW(float fraction) {
1346224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala        return metrics.widthPixels * fraction;
1356224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala    }
1366224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala
1376224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala
1386224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala    /**
1396224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala     *
1406224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala     * CODE BELOW IS ADAPTED IN PART FROM MINDRIOT'S SAMPLE CODE HERE:
1416224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala     * http://stackoverflow.com/questions/8343971/how-to-parse-a-dimension-string-and-convert-it-to-a-dimension-value
1426224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala     */
1436224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala    // -- Initialize dimension string to constant lookup.
1446224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala    public static final Map<String, Integer> dimensionConstantLookup = initDimensionConstantLookup();
1456224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala
1466224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala    private static Map<String, Integer> initDimensionConstantLookup() {
1476224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala        Map<String, Integer> m = new HashMap<String, Integer>();
1486224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala        m.put("px", TypedValue.COMPLEX_UNIT_PX);
1496224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala        m.put("dip", TypedValue.COMPLEX_UNIT_DIP);
1506224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala        m.put("dp", TypedValue.COMPLEX_UNIT_DIP);
1516224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala        m.put("sp", TypedValue.COMPLEX_UNIT_SP);
1526224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala        m.put("pt", TypedValue.COMPLEX_UNIT_PT);
1536224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala        m.put("in", TypedValue.COMPLEX_UNIT_IN);
1546224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala        m.put("mm", TypedValue.COMPLEX_UNIT_MM);
1556224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala        return Collections.unmodifiableMap(m);
1566224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala    }
1576224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala
1586224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala    // -- Initialize pattern for dimension string.
1596224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala    private static final Pattern DIMENSION_PATTERN = Pattern.compile("^\\s*(\\d+(\\.\\d+)*)\\s*([a-zA-Z]+)\\s*$");
1606224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala
1616224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala    /*public static int stringToDimensionPixelSize(String dimension, DisplayMetrics metrics) {
1626224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala        // -- Mimics TypedValue.complexToDimensionPixelSize(int data, DisplayMetrics metrics).
1636224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala        InternalDimension internalDimension = stringToInternalDimension(dimension);
1646224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala        final float value = internalDimension.value;
1656224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala        final float f = TypedValue.applyDimension(internalDimension.unit, value, metrics);
1666224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala        final int res = (int) (f + 0.5f);
1676224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala        if (res != 0) return res;
1686224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala        if (value == 0) return 0;
1696224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala        if (value > 0) return 1;
1706224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala        return -1;
1716224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala    }*/
1726224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala
1736224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala    public static float stringToDimension(String dimension) {
1746224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala        // -- Mimics TypedValue.complexToDimension(int data, DisplayMetrics metrics).
1756224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala        InternalDimension internalDimension = stringToInternalDimension(dimension);
1766224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala        return TypedValue.applyDimension(internalDimension.unit, internalDimension.value, metrics);
1776224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala    }
1786224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala
1796224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala    private static InternalDimension stringToInternalDimension(String dimension) {
1806224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala        // -- Match target against pattern.
1816224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala        Matcher matcher = DIMENSION_PATTERN.matcher(dimension);
1826224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala        if (matcher.matches()) {
1836224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala            // -- Match found.
1846224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala            // -- Extract value.
1856224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala            float value = Float.valueOf(matcher.group(1));
1866224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala            // -- Extract dimension units.
1876224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala            String unit = matcher.group(3).toLowerCase();
1886224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala            // -- Get Android dimension constant.
1896224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala            Integer dimensionUnit = dimensionConstantLookup.get(unit);
1906224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala            if (dimensionUnit == null) {
1916224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala                // -- Invalid format.
1926224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala                throw new NumberFormatException();
1936224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala            } else {
1946224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala                // -- Return valid dimension.
1956224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala                return new InternalDimension(value, dimensionUnit);
1966224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala            }
1976224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala        } else {
1986224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala            // -- Invalid format.
1996224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala            throw new NumberFormatException();
2006224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala        }
2016224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala    }
2026224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala
2036224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala    private static class InternalDimension {
2046224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala        float value;
2056224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala        int unit;
2066224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala
2076224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala        public InternalDimension(float value, int unit) {
2086224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala            this.value = value;
2096224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala            this.unit = unit;
2106224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala        }
2116224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala    }
2126224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala
2136224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala
2146224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala}
2156224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala
2166224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala
2176224eda509d436a575f801942337da92a6c18767Eino-Ville Talvala
218