//========================================================================
//
// FixedPoint.h
//
// Fixed point type, with C++ operators.
//
// Copyright 2004 Glyph & Cog, LLC
//
//========================================================================

#ifndef FIXEDPOINT_H
#define FIXEDPOINT_H

#include "poppler-config.h"

#if USE_FIXEDPOINT

#ifdef USE_GCC_PRAGMAS
#pragma interface
#endif

#include <stdio.h>
#include <stdlib.h>
#include "gtypes.h"

#define fixptShift 16
#define fixptMaskL ((1 << fixptShift) - 1)
#define fixptMaskH (~fixptMaskL)

typedef long long FixPtInt64;

class FixedPoint {
public:

  FixedPoint() { val = 0; }
  FixedPoint(const FixedPoint &x) { val = x.val; }
  FixedPoint(double x) { val = (int)(x * (1 << fixptShift) + 0.5); }
  FixedPoint(int x) { val = x << fixptShift; }
  FixedPoint(long x) { val = x << fixptShift; }

  operator float()
    { return (float) val * ((float)1 / (float)(1 << fixptShift)); }
  operator double()
    { return (double) val * (1.0 / (double)(1 << fixptShift)); }
  operator int()
    { return val >> fixptShift; }

  int get16Dot16() { return val; }

  FixedPoint operator =(FixedPoint x) { val = x.val; return *this; }

  int operator ==(FixedPoint x) { return val == x.val; }
  int operator ==(double x) { return *this == (FixedPoint)x; }
  int operator ==(int x) { return *this == (FixedPoint)x; }
  int operator ==(long x) { return *this == (FixedPoint)x; }

  int operator !=(FixedPoint x) { return val != x.val; }
  int operator !=(double x) { return *this != (FixedPoint)x; }
  int operator !=(int x) { return *this != (FixedPoint)x; }
  int operator !=(long x) { return *this != (FixedPoint)x; }

  int operator <(FixedPoint x) { return val < x.val; }
  int operator <(double x) { return *this < (FixedPoint)x; }
  int operator <(int x) { return *this < (FixedPoint)x; }
  int operator <(long x) { return *this < (FixedPoint)x; }

  int operator <=(FixedPoint x) { return val <= x.val; }
  int operator <=(double x) { return *this <= (FixedPoint)x; }
  int operator <=(int x) { return *this <= (FixedPoint)x; }
  int operator <=(long x) { return *this <= (FixedPoint)x; }

  int operator >(FixedPoint x) { return val > x.val; }
  int operator >(double x) { return *this > (FixedPoint)x; }
  int operator >(int x) { return *this > (FixedPoint)x; }
  int operator >(long x) { return *this > (FixedPoint)x; }

  int operator >=(FixedPoint x) { return val >= x.val; }
  int operator >=(double x) { return *this >= (FixedPoint)x; }
  int operator >=(int x) { return *this >= (FixedPoint)x; }
  int operator >=(long x) { return *this >= (FixedPoint)x; }

  FixedPoint operator -() { return make(-val); }

  FixedPoint operator +(FixedPoint x) { return make(val + x.val); }
  FixedPoint operator +(double x) { return *this + (FixedPoint)x; }
  FixedPoint operator +(int x) { return *this + (FixedPoint)x; }
  FixedPoint operator +(long x) { return *this + (FixedPoint)x; }

  FixedPoint operator +=(FixedPoint x) { val = val + x.val; return *this; }
  FixedPoint operator +=(double x) { return *this += (FixedPoint)x; }
  FixedPoint operator +=(int x) { return *this += (FixedPoint)x; }
  FixedPoint operator +=(long x) { return *this += (FixedPoint)x; }

  FixedPoint operator -(FixedPoint x) { return make(val - x.val); }
  FixedPoint operator -(double x) { return *this - (FixedPoint)x; }
  FixedPoint operator -(int x) { return *this - (FixedPoint)x; }
  FixedPoint operator -(long x) { return *this - (FixedPoint)x; }

  FixedPoint operator -=(FixedPoint x) { val = val - x.val; return *this; }
  FixedPoint operator -=(double x) { return *this -= (FixedPoint)x; }
  FixedPoint operator -=(int x) { return *this -= (FixedPoint)x; }
  FixedPoint operator -=(long x) { return *this -= (FixedPoint)x; }

  FixedPoint operator *(FixedPoint x) { return make(mul(val, x.val)); }
  FixedPoint operator *(double x) { return *this * (FixedPoint)x; }
  FixedPoint operator *(int x) { return *this * (FixedPoint)x; }
  FixedPoint operator *(long x) { return *this * (FixedPoint)x; }

  FixedPoint operator *=(FixedPoint x) { val = mul(val, x.val); return *this; }
  FixedPoint operator *=(double x) { return *this *= (FixedPoint)x; }
  FixedPoint operator *=(int x) { return *this *= (FixedPoint)x; }
  FixedPoint operator *=(long x) { return *this *= (FixedPoint)x; }

  FixedPoint operator /(FixedPoint x) { return make(div(val, x.val)); }
  FixedPoint operator /(double x) { return *this / (FixedPoint)x; }
  FixedPoint operator /(int x) { return *this / (FixedPoint)x; }
  FixedPoint operator /(long x) { return *this / (FixedPoint)x; }

  FixedPoint operator /=(FixedPoint x) { val = div(val, x.val); return *this; }
  FixedPoint operator /=(double x) { return *this /= (FixedPoint)x; }
  FixedPoint operator /=(int x) { return *this /= (FixedPoint)x; }
  FixedPoint operator /=(long x) { return *this /= (FixedPoint)x; }

  static FixedPoint abs(FixedPoint x) { return make(::abs(x.val)); }

  static int floor(FixedPoint x) { return x.val >> fixptShift; }

  static int ceil(FixedPoint x)
    { return (x.val & fixptMaskL) ? ((x.val >> fixptShift) + 1)
	                          : (x.val >> fixptShift); }

  static int round(FixedPoint x)
    { return (x.val + (1 << (fixptShift - 1))) >> fixptShift; }

  // Computes (x+y)/2 avoiding overflow and LSbit accuracy issues.
  static FixedPoint avg(FixedPoint x, FixedPoint y)
    { return make((x.val >> 1) + (y.val >> 1) + ((x.val | y.val) & 1)); }


  static FixedPoint sqrt(FixedPoint x);

  static FixedPoint pow(FixedPoint x, FixedPoint y);

  // Compute *result = x/y; return false if there is an underflow or
  // overflow.
  static GBool divCheck(FixedPoint x, FixedPoint y, FixedPoint *result);

  // Compute abs(m11*m22 - m12*m21) >= epsilon, handling the case
  // where the multiplications overflow.
  static GBool checkDet(FixedPoint m11, FixedPoint m12,
                       FixedPoint m21, FixedPoint m22,
                       FixedPoint epsilon);

private:

  static FixedPoint make(int valA) { FixedPoint x; x.val = valA; return x; }

  static int mul(int x, int y);
  static int div(int x, int y);

  int val;                // fixed point: (n-fixptShift).(fixptShift)
};

#endif // USE_FIXEDPOINT

#endif
