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