| /* ==================================================================== |
| Licensed to the Apache Software Foundation (ASF) under one or more |
| contributor license agreements. See the NOTICE file distributed with |
| this work for additional information regarding copyright ownership. |
| The ASF licenses this file to You 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 org.apache.poi.ooxml.util; |
| |
| import static org.apache.poi.util.Units.EMU_PER_DXA; |
| import static org.apache.poi.util.Units.EMU_PER_INCH; |
| import static org.apache.poi.util.Units.EMU_PER_POINT; |
| |
| import java.util.Locale; |
| |
| public class POIXMLUnits { |
| |
| /** |
| * Office will read percentages formatted with a trailing percent sign or formatted |
| * as 1000th of a percent without a trailing percent sign |
| * |
| * @return the percent scaled by 1000, so 100% = 100000 |
| */ |
| public static int parsePercent(org.openxmlformats.schemas.drawingml.x2006.main.STPositivePercentage pctUnion) { |
| return parsePercentInner(pctUnion, 1); |
| } |
| |
| /** |
| * Office will read percentages formatted with a trailing percent sign or formatted |
| * as 1000th of a percent without a trailing percent sign |
| * |
| * @return the percent scaled by 1000, so 100% = 100000 |
| */ |
| public static int parsePercent(org.openxmlformats.schemas.drawingml.x2006.main.STPositiveFixedPercentage pctUnion) { |
| return parsePercentInner(pctUnion, 1); |
| } |
| |
| /** |
| * Office will read percentages formatted with a trailing percent sign or formatted |
| * as 1000th of a percent without a trailing percent sign |
| * |
| * @return the percent scaled by 1000, so 100% = 100000 |
| */ |
| public static int parsePercent(org.openxmlformats.schemas.drawingml.x2006.main.STPercentage pctUnion) { |
| return parsePercentInner(pctUnion, 1); |
| } |
| |
| /** |
| * Specifies the percentage of the text size that this bullet should be. It is specified here in terms of |
| * 100% being equal to 100000 and 1% being specified in increments of 1000. This attribute should not be |
| * lower than 25%, or 25000, and not be higher than 400%, or 400000. |
| * |
| * @return the percent scaled by 1000, so 100% = 100000 |
| */ |
| public static int parsePercent(org.openxmlformats.schemas.drawingml.x2006.main.STTextBulletSizePercent pctUnion) { |
| return parsePercentInner(pctUnion, 1); |
| } |
| |
| /** |
| * Office will read percentages formatted with a trailing percent sign or formatted |
| * as 1000th of a percent without a trailing percent sign |
| * |
| * @return the percent scaled by 1000, so 100% = 100000 |
| */ |
| public static int parsePercent(org.openxmlformats.schemas.drawingml.x2006.main.STTextSpacingPercentOrPercentString pctUnion) { |
| return parsePercentInner(pctUnion, 1); |
| } |
| |
| /** |
| * Office will read percentages formatted with a trailing percent sign or formatted |
| * as 1000th of a percent without a trailing percent sign |
| * |
| * @return the percent scaled by 1000, so 100% = 100000 |
| */ |
| public static int parsePercent(org.openxmlformats.schemas.drawingml.x2006.main.STTextFontScalePercentOrPercentString pctUnion) { |
| return parsePercentInner(pctUnion, 1); |
| } |
| |
| /** |
| * This type seems to be interpreted as percent value when the trailing percent sign is missing.<p> |
| * sample snippet from settings.xml |
| * <pre>{@code |
| * <w:zoom w:percent="50" /> |
| * }</pre> |
| * |
| * @return the percent scaled by 1000, so 100% = 100000 |
| */ |
| public static int parsePercent(org.openxmlformats.schemas.wordprocessingml.x2006.main.STDecimalNumberOrPercent pctUnion) { |
| return parsePercentInner(pctUnion, 1000); |
| } |
| |
| /** |
| * This type seems to be interpreted as percent value when the trailing percent sign is missing.<p> |
| * sample snippet from settings.xml |
| * <pre>{@code |
| * <w:textscale w:w="50" /> |
| * }</pre> |
| * |
| * @return the percent scaled by 1000, so 100% = 100000 |
| */ |
| public static int parsePercent(org.openxmlformats.schemas.wordprocessingml.x2006.main.STTextScale pctUnion) { |
| return parsePercentInner(pctUnion, 1000); |
| } |
| |
| |
| public static int parsePercent(org.openxmlformats.schemas.drawingml.x2006.chart.STGapAmount pctUnion) { |
| return parsePercentInner(pctUnion, 1000); |
| } |
| |
| |
| public static int parsePercent(org.openxmlformats.schemas.drawingml.x2006.chart.STOverlap pctUnion) { |
| return parsePercentInner(pctUnion, 1000); |
| } |
| |
| |
| public static int parsePercent(org.openxmlformats.schemas.drawingml.x2006.chart.STDepthPercent pctUnion) { |
| return parsePercentInner(pctUnion, 1000); |
| } |
| |
| |
| public static int parsePercent(org.openxmlformats.schemas.drawingml.x2006.chart.STHPercent pctUnion) { |
| return parsePercentInner(pctUnion, 1000); |
| } |
| |
| |
| public static int parsePercent(org.openxmlformats.schemas.drawingml.x2006.chart.STHoleSize pctUnion) { |
| return parsePercentInner(pctUnion, 1); |
| } |
| |
| |
| private static int parsePercentInner(org.apache.xmlbeans.XmlAnySimpleType pctUnion, int noUnitScale) { |
| String strVal = pctUnion.getStringValue(); |
| if (strVal.endsWith("%")) { |
| return Integer.parseInt(strVal.substring(0, strVal.length()-1)) * 1000; |
| } else { |
| return Integer.parseInt(strVal) * noUnitScale; |
| } |
| } |
| |
| /** |
| * The standard states that ST_Coordinate32 is read and written as either a length |
| * followed by a unit, or EMUs with no unit present. |
| * |
| * @return length in EMUs |
| */ |
| public static long parseLength(org.openxmlformats.schemas.drawingml.x2006.main.STCoordinate32 coordUnion) { |
| return parseLengthInner(coordUnion, 1d); |
| } |
| |
| /** |
| * The standard states that ST_Coordinate is read and written as either a length |
| * followed by a unit, or EMUs with no unit present. |
| * |
| * @return length in EMUs |
| */ |
| public static long parseLength(org.openxmlformats.schemas.drawingml.x2006.main.STCoordinate coordUnion) { |
| return parseLengthInner(coordUnion, 1d); |
| } |
| |
| /** |
| * The standard states that ST_TextPoint is read and written as a length followed by a unit |
| * or as hundredths of a point with no unit present. |
| * |
| * @return length in EMUs |
| */ |
| public static long parseLength(org.openxmlformats.schemas.drawingml.x2006.main.STTextPoint coordUnion) { |
| return parseLengthInner(coordUnion, EMU_PER_POINT/100d); |
| } |
| |
| /** |
| * If no unit is specified, a twips-measure is a twentieth of a point |
| * |
| * @return length in EMUs |
| */ |
| public static long parseLength(org.openxmlformats.schemas.officeDocument.x2006.sharedTypes.STTwipsMeasure coordUnion) { |
| return parseLengthInner(coordUnion, EMU_PER_DXA); |
| } |
| |
| /** |
| * If no unit is specified, a twips-measure is a twentieth of a point |
| * |
| * @return length in EMUs |
| */ |
| public static long parseLength(org.openxmlformats.schemas.wordprocessingml.x2006.main.STSignedTwipsMeasure coordUnion) { |
| return parseLengthInner(coordUnion, EMU_PER_DXA); |
| } |
| |
| /** |
| * If no unit is specified, a hps-measure is a half of a point |
| * |
| * @return length in EMUs |
| */ |
| public static long parseLength(org.openxmlformats.schemas.wordprocessingml.x2006.main.STHpsMeasure coordUnion) { |
| return parseLengthInner(coordUnion, EMU_PER_POINT*2d); |
| } |
| |
| |
| /** |
| * If no unit is specified, a hps-measure is a half of a point |
| * |
| * @return length in EMUs |
| */ |
| public static long parseLength(org.openxmlformats.schemas.wordprocessingml.x2006.main.STSignedHpsMeasure coordUnion) { |
| return parseLengthInner(coordUnion, EMU_PER_POINT*2d); |
| } |
| |
| |
| /** |
| * If no unit is specified, DXA (twentieth of a point) is assumed |
| * |
| * @return length in EMUs |
| */ |
| public static long parseLength(org.openxmlformats.schemas.wordprocessingml.x2006.main.STMeasurementOrPercent coordUnion) { |
| if (coordUnion.getStringValue().endsWith("%")) return -1; |
| return parseLengthInner(coordUnion, EMU_PER_DXA); |
| } |
| |
| |
| /** |
| * Returns the EMUs for the given measurement (mm|cm|in|pt|pc|pi, defaults to EMUs*noUnitEmuFactor if not specified) |
| * |
| * @param coordUnion the raw type |
| * @return the EMUs for the given attribute |
| */ |
| private static long parseLengthInner(org.apache.xmlbeans.XmlAnySimpleType coordUnion, double noUnitEmuFactor) { |
| String strVal = coordUnion.getStringValue().toLowerCase(Locale.ROOT); |
| double digVal = Double.parseDouble(strVal.replaceAll("(mm|cm|in|pt|pc|pi)", "")); |
| long emu; |
| // http://startbigthinksmall.wordpress.com/2010/01/04/points-inches-and-emus-measuring-units-in-office-open-xml/ |
| if (strVal.endsWith("mm")) { |
| emu = (long)(((digVal/10f)/2.54f)*EMU_PER_INCH); |
| } else if (strVal.endsWith("cm")) { |
| emu = (long)((digVal/2.54f)*EMU_PER_INCH); |
| } else if (strVal.endsWith("in")) { |
| emu = (long)(digVal*EMU_PER_INCH); |
| } else if (strVal.endsWith("pc") || strVal.endsWith("pi")) { |
| emu = (long)(digVal*0.166f*EMU_PER_INCH); |
| } else if (strVal.endsWith("pt")) { |
| emu = (long)(digVal*EMU_PER_POINT); |
| } else { |
| emu = (long)(digVal*noUnitEmuFactor); |
| } |
| return emu; |
| } |
| |
| |
| |
| public static boolean parseOnOff(org.openxmlformats.schemas.wordprocessingml.x2006.main.CTOnOff onOff) { |
| if(onOff == null) return false; |
| if(!onOff.isSetVal()) return true; |
| return parseOnOff(onOff.xgetVal()); |
| } |
| |
| public static boolean parseOnOff(org.openxmlformats.schemas.officeDocument.x2006.sharedTypes.STOnOff onOff) { |
| if (onOff == null) return false; |
| String str = onOff.getStringValue(); |
| return ("true".equalsIgnoreCase(str) || "on".equalsIgnoreCase(str) || "x".equalsIgnoreCase(str) || "1".equals(str)); |
| } |
| |
| } |