File indexing completed on 2024-05-12 04:33:58

0001 // -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; c-brace-offset: 0; -*-
0002 // units.cpp
0003 //
0004 // Part of KVIEWSHELL - A framework for multipage text/gfx viewers
0005 //
0006 // SPDX-FileCopyrightText: 2003 Stefan Kebekus
0007 // SPDX-FileCopyrightText: 2006 Wilfried Huss
0008 // SPDX-License-Identifier: GPL-2.0-or-later
0009 
0010 #include <config.h>
0011 
0012 #include "debug_dvi.h"
0013 #include "length.h"
0014 
0015 class unitOfDistance
0016 {
0017 public:
0018     float mmPerUnit;
0019     const char *name;
0020 };
0021 
0022 static const unitOfDistance distanceUnitTable[] = {
0023     // Metric units
0024     {1.0f, "mm"},
0025     {1.0f, "millimeter"},
0026     {10.0f, "cm"},
0027     {10.0f, "centimeter"},
0028     {float(100.0 * 10.0), "m"},
0029     {float(100.0 * 10.0), "meter"},
0030 
0031     // Imperial units
0032     {25.4f, "in"},
0033     {25.4f, "inch"},
0034 
0035     // Typographical units
0036     {float(2540.0 / 7227.0), "pt"}, // TeX points. 7227points = 254cm
0037     {float(25.4 / 72.0), "bp"},     // big points, 1/72 inch as used in Postscript
0038     {float(25.4 / 6.0), "pc"},      // pica = 1/6 inch
0039     {float(25.4 / 6.0), "pica"},
0040     {float(25.4 * 0.0148), "dd"}, // didot points = 0.0148 inches
0041     {float(25.4 * 0.0148), "didot"},
0042     {float(25.4 * 0.178), "cc"}, // cicero points = 0.178 inches
0043     {float(25.4 * 0.178), "cicero"},
0044 
0045     {0.0f, nullptr},
0046 };
0047 
0048 float Length::convertToMM(const QString &distance, bool *ok)
0049 {
0050     float MMperUnit = 0.0;
0051     int unitPos = 0; // position of the unit in the string
0052 
0053     // Check for various known units, and store the beginning position
0054     // of the unit in 'unitPos', so that distance[0..unitPos] will hold
0055     // the value. Store the number of mm per unit in 'MMperUnit'.
0056     for (int i = 0; MMperUnit == 0.0 && distanceUnitTable[i].name != nullptr; i++) {
0057         unitPos = distance.lastIndexOf(QString::fromLocal8Bit(distanceUnitTable[i].name));
0058         if (unitPos != -1) {
0059             MMperUnit = distanceUnitTable[i].mmPerUnit;
0060         }
0061     }
0062 
0063     // If no unit has been found -> error message, set *ok to false and
0064     // return 0.0.
0065     if (MMperUnit == 0.0) {
0066         qCCritical(OkularDviShellDebug) << "distance::convertToMM: no known unit found in the string '" << distance << "'.";
0067         if (ok) {
0068             *ok = false;
0069         }
0070         return 0.0;
0071     }
0072 
0073     QString val = distance.left(unitPos).simplified();
0074     return MMperUnit * val.toFloat(ok);
0075 }