LCOV - code coverage report
Current view: top level - roff/troff - hvunits.h (source / functions) Hit Total Coverage
Test: GNU roff Lines: 107 133 80.5 %
Date: 2026-01-16 17:51:41 Functions: 34 38 89.5 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* Copyright 1989-2024 Free Software Foundation, Inc.
       2             :      Written by James Clark (jjc@jclark.com)
       3             : 
       4             : This file is part of groff, the GNU roff typesetting system.
       5             : 
       6             : groff is free software; you can redistribute it and/or modify it under
       7             : the terms of the GNU General Public License as published by the Free
       8             : Software Foundation, either version 3 of the License, or
       9             : (at your option) any later version.
      10             : 
      11             : groff is distributed in the hope that it will be useful, but WITHOUT ANY
      12             : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      13             : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      14             : for more details.
      15             : 
      16             : You should have received a copy of the GNU General Public License
      17             : along with this program.  If not, see <http://www.gnu.org/licenses/>. */
      18             : 
      19             : #include <stdckdint.h>
      20             : 
      21             : class vunits {
      22             :   int n;
      23             : public:
      24             :   vunits();
      25             :   vunits(units);
      26             :   units to_units();
      27             :   bool is_zero();
      28             :   vunits& operator +=(const vunits&);
      29             :   vunits& operator -=(const vunits&);
      30             :   // scale n by x/y
      31             :   friend inline vunits scale(vunits n, units x, units y);
      32             :   friend inline vunits scale(vunits n, vunits x, vunits y);
      33             :   friend inline vunits operator +(const vunits&, const vunits&);
      34             :   friend inline vunits operator -(const vunits&, const vunits&);
      35             :   friend inline vunits operator -(const vunits&);
      36             :   friend inline int operator /(const vunits&, const vunits&);
      37             :   friend inline vunits operator /(const vunits&, int);
      38             :   friend inline vunits operator *(const vunits&, int);
      39             :   friend inline vunits operator *(int, const vunits&);
      40             :   friend inline bool operator <(const vunits&, const vunits&);
      41             :   friend inline bool operator >(const vunits&, const vunits&);
      42             :   friend inline bool operator <=(const vunits&, const vunits&);
      43             :   friend inline bool operator >=(const vunits&, const vunits&);
      44             :   friend inline bool operator ==(const vunits&, const vunits&);
      45             :   friend inline bool operator !=(const vunits&, const vunits&);
      46             : };
      47             : 
      48             : extern const vunits V0;
      49             : 
      50             : class hunits {
      51             :   int n;
      52             : public:
      53             :   hunits();
      54             :   hunits(units);
      55             :   units to_units();
      56             :   bool is_zero();
      57             :   hunits& operator +=(const hunits&);
      58             :   hunits& operator -=(const hunits&);
      59             :   // scale n by x/y
      60             :   friend inline hunits scale(hunits n, units x, units y);
      61             :   friend inline hunits scale(hunits n, double x);
      62             :   friend inline hunits operator +(const hunits&, const hunits&);
      63             :   friend inline hunits operator -(const hunits&, const hunits&);
      64             :   friend inline hunits operator -(const hunits&);
      65             :   friend inline int operator /(const hunits&, const hunits&);
      66             :   friend inline hunits operator /(const hunits&, int);
      67             :   friend inline hunits operator *(const hunits&, int);
      68             :   friend inline hunits operator *(int, const hunits&);
      69             :   friend inline bool operator <(const hunits&, const hunits&);
      70             :   friend inline bool operator >(const hunits&, const hunits&);
      71             :   friend inline bool operator <=(const hunits&, const hunits&);
      72             :   friend inline bool operator >=(const hunits&, const hunits&);
      73             :   friend inline bool operator ==(const hunits&, const hunits&);
      74             :   friend inline bool operator !=(const hunits&, const hunits&);
      75             : };
      76             : 
      77             : extern const hunits H0;
      78             : 
      79             : extern bool read_vunits(vunits *, unsigned char si);
      80             : extern bool read_hunits(hunits *, unsigned char si);
      81             : extern bool read_vunits(vunits *, unsigned char si, vunits prev_value);
      82             : extern bool read_hunits(hunits *, unsigned char si, hunits prev_value);
      83             : 
      84     8842634 : inline vunits:: vunits() : n(0)
      85             : {
      86     8842634 : }
      87             : 
      88     9526943 : inline units vunits::to_units()
      89             : {
      90             :   units r;
      91     9526943 :   if (ckd_mul(&r, n, vresolution))
      92           0 :     warning(WARN_RANGE, "integer multiplication saturated");
      93     9526943 :   return r;
      94             : }
      95             : 
      96             : inline bool vunits::is_zero()
      97             : {
      98             :   return n == 0;
      99             : }
     100             : 
     101     1968238 : inline vunits operator +(const vunits & x, const vunits & y)
     102             : {
     103     1968238 :   vunits r;
     104     1968238 :   r = x;
     105     1968238 :   if (ckd_add(&r.n, r.n, y.n))
     106           0 :     warning(WARN_RANGE, "integer addition saturated");
     107     1968238 :   return r;
     108             : }
     109             : 
     110      449726 : inline vunits operator -(const vunits & x, const vunits & y)
     111             : {
     112      449726 :   vunits r;
     113      449726 :   r = x;
     114      449726 :   if (ckd_sub(&r.n, r.n, y.n))
     115           0 :     warning(WARN_RANGE, "integer subtraction saturated");
     116      449726 :   return r;
     117             : }
     118             : 
     119     2159376 : inline vunits operator -(const vunits & x)
     120             : {
     121     2159376 :   vunits r;
     122             :   // Why?  Consider -(INT_MIN) in two's complement.
     123     2159376 :   if (ckd_mul(&r.n, x.n, -1))
     124           0 :     warning(WARN_RANGE, "integer multiplication saturated");
     125     2159376 :   return r;
     126             : }
     127             : 
     128           0 : inline int operator /(const vunits & x, const vunits & y)
     129             : {
     130           0 :   return x.n / y.n;
     131             : }
     132             : 
     133           0 : inline vunits operator /(const vunits & x, int n)
     134             : {
     135           0 :   vunits r;
     136           0 :   r = x;
     137           0 :   r.n /= n;
     138           0 :   return r;
     139             : }
     140             : 
     141           0 : inline vunits operator *(const vunits & x, int n)
     142             : {
     143           0 :   vunits r;
     144           0 :   r = x;
     145           0 :   if (ckd_mul(&r.n, x.n, n))
     146           0 :     warning(WARN_RANGE, "integer multiplication saturated");
     147           0 :   return r;
     148             : }
     149             : 
     150           4 : inline vunits operator *(int n, const vunits & x)
     151             : {
     152           4 :   vunits r;
     153           4 :   r = x;
     154           4 :   if (ckd_mul(&r.n, n, x.n))
     155           0 :     warning(WARN_RANGE, "integer multiplication saturated");
     156           4 :   return r;
     157             : }
     158             : 
     159     4868366 : inline bool operator <(const vunits & x, const vunits & y)
     160             : {
     161     4868366 :   return x.n < y.n;
     162             : }
     163             : 
     164     2923172 : inline bool operator >(const vunits & x, const vunits & y)
     165             : {
     166     2923172 :   return x.n > y.n;
     167             : }
     168             : 
     169       27577 : inline bool operator <=(const vunits & x, const vunits & y)
     170             : {
     171       27577 :   return x.n <= y.n;
     172             : }
     173             : 
     174     1940676 : inline bool operator >=(const vunits & x, const vunits & y)
     175             : {
     176     1940676 :   return x.n >= y.n;
     177             : }
     178             : 
     179        4781 : inline bool operator ==(const vunits & x, const vunits & y)
     180             : {
     181        4781 :   return x.n == y.n;
     182             : }
     183             : 
     184           0 : inline bool operator !=(const vunits & x, const vunits & y)
     185             : {
     186           0 :   return x.n != y.n;
     187             : }
     188             : 
     189     2825803 : inline vunits& vunits::operator +=(const vunits & x)
     190             : {
     191     2825803 :   n += x.n;
     192     2825803 :   return *this;
     193             : }
     194             : 
     195           2 : inline vunits& vunits::operator -=(const vunits & x)
     196             : {
     197           2 :   n -= x.n;
     198           2 :   return *this;
     199             : }
     200             : 
     201   127365568 : inline hunits:: hunits() : n(0)
     202             : {
     203   127365568 : }
     204             : 
     205    15124461 : inline units hunits::to_units()
     206             : {
     207             :   units r;
     208    15124461 :   if (ckd_mul(&r, n, hresolution))
     209           0 :     warning(WARN_RANGE, "integer multiplication saturated");
     210    15124461 :   return r;
     211             : }
     212             : 
     213      809950 : inline bool hunits::is_zero()
     214             : {
     215      809950 :   return n == 0;
     216             : }
     217             : 
     218    68881371 : inline hunits operator +(const hunits & x, const hunits & y)
     219             : {
     220    68881371 :   hunits r;
     221    68881371 :   r = x;
     222    68881371 :   if (ckd_add(&r.n, r.n, y.n))
     223           0 :     warning(WARN_RANGE, "integer addition saturated");
     224    68881371 :   return r;
     225             : }
     226             : 
     227     6073180 : inline hunits operator -(const hunits & x, const hunits & y)
     228             : {
     229     6073180 :   hunits r;
     230     6073180 :   r = x;
     231     6073180 :   if (ckd_sub(&r.n, r.n, y.n))
     232           0 :     warning(WARN_RANGE, "integer subtraction saturated");
     233     6073180 :   return r;
     234             : }
     235             : 
     236        2259 : inline hunits operator -(const hunits & x)
     237             : {
     238        2259 :   hunits r;
     239        2259 :   r = x;
     240             :   // Why?  Consider -(INT_MIN) in two's complement.
     241        2259 :   if (ckd_mul(&r.n, x.n, -1))
     242           0 :     warning(WARN_RANGE, "integer multiplication saturated");
     243        2259 :   return r;
     244             : }
     245             : 
     246         310 : inline int operator /(const hunits & x, const hunits & y)
     247             : {
     248         310 :   return x.n / y.n;
     249             : }
     250             : 
     251      375881 : inline hunits operator /(const hunits & x, int n)
     252             : {
     253      375881 :   hunits r;
     254      375881 :   r = x;
     255      375881 :   r.n /= n;
     256      375881 :   return r;
     257             : }
     258             : 
     259        1243 : inline hunits operator *(const hunits & x, int n)
     260             : {
     261        1243 :   hunits r;
     262        1243 :   r = x;
     263        1243 :   if (ckd_mul(&r.n, x.n, n))
     264           0 :     warning(WARN_RANGE, "integer multiplication saturated");
     265        1243 :   return r;
     266             : }
     267             : 
     268          92 : inline hunits operator *(int n, const hunits & x)
     269             : {
     270          92 :   hunits r;
     271          92 :   r = x;
     272          92 :   if (ckd_mul(&r.n, x.n, n))
     273           0 :     warning(WARN_RANGE, "integer multiplication saturated");
     274          92 :   return r;
     275             : }
     276             : 
     277    47742339 : inline bool operator <(const hunits & x, const hunits & y)
     278             : {
     279    47742339 :   return x.n < y.n;
     280             : }
     281             : 
     282     1213074 : inline bool operator >(const hunits & x, const hunits & y)
     283             : {
     284     1213074 :   return x.n > y.n;
     285             : }
     286             : 
     287    47587802 : inline bool operator <=(const hunits & x, const hunits & y)
     288             : {
     289    47587802 :   return x.n <= y.n;
     290             : }
     291             : 
     292          49 : inline bool operator >=(const hunits & x, const hunits & y)
     293             : {
     294          49 :   return x.n >= y.n;
     295             : }
     296             : 
     297       53849 : inline bool operator ==(const hunits & x, const hunits & y)
     298             : {
     299       53849 :   return x.n == y.n;
     300             : }
     301             : 
     302         147 : inline bool operator !=(const hunits & x, const hunits & y)
     303             : {
     304         147 :   return x.n != y.n;
     305             : }
     306             : 
     307    73464080 : inline hunits& hunits::operator +=(const hunits & x)
     308             : {
     309    73464080 :   n += x.n;
     310    73464080 :   return *this;
     311             : }
     312             : 
     313      689118 : inline hunits& hunits::operator -=(const hunits & x)
     314             : {
     315      689118 :   n -= x.n;
     316      689118 :   return *this;
     317             : }
     318             : 
     319     1591979 : inline hunits scale(hunits n, units x, units y)
     320             : {
     321     1591979 :   hunits r;
     322     1591979 :   r.n = scale(n.n, x, y);
     323     1591979 :   return r;
     324             : }
     325             : 
     326        3112 : inline vunits scale(vunits n, units x, units y)
     327             : {
     328        3112 :   vunits r;
     329        3112 :   r.n = scale(n.n, x, y);
     330        3112 :   return r;
     331             : }
     332             : 
     333             : inline vunits scale(vunits n, vunits x, vunits y)
     334             : {
     335             :   vunits r;
     336             :   r.n = scale(n.n, x.n, y.n);
     337             :   return r;
     338             : }
     339             : 
     340             : inline hunits scale(hunits n, double x)
     341             : {
     342             :   hunits r;
     343             :   r.n = int(n.n * x);
     344             :   return r;
     345             : }
     346             : 
     347             : inline units scale(units n, double x)
     348             : {
     349             :   return int(n * x);
     350             : }
     351             : 
     352        7909 : inline units points_to_units(units n)
     353             : {
     354        7909 :   return scale(n, units_per_inch, 72);
     355             : }
     356             : 
     357             : // Local Variables:
     358             : // fill-column: 72
     359             : // mode: C++
     360             : // End:
     361             : // vim: set cindent noexpandtab shiftwidth=2 textwidth=72:

Generated by: LCOV version 1.14