// C++ code Copyright (C) David R. Evans G4AMJ/NQ0I

// grey scale class

#include <defines.h>
#include <gf.h>
#include <surface.h>

#include <ctype.h>
#include <iostream.h>
#include <stdlib.h>

// constructor
grey_font::grey_font(const uint16 width, const uint16 height) : index(0)
{ if ((uint32)width * height > MAX_SIZE) then
    fatal_error((DREstring)"Cannot create grey_font with " +
		 DREstring10((uint32)width * height) + (DREstring)" entries");

  w = width;
  h = height;

  font_number = ++fonts_created;
}

// resize the font
int grey_font::resize(const uint16 width, const uint16 height)
{ if ((width == w) && (height == h)) then
    return 0;

  if ((uint32)width * height > MAX_SIZE) then
    fatal_error((DREstring)"Cannot resize grey_font with " +
		 DREstring10((uint32)width * height) + (DREstring)" entries");

  return _rebuild(width, height);
}

// add a character to the internal buffer
void grey_font::operator+=(const uint32 n)
{ if ((n < 0) || (n > max_character_number(w, h))) then
    fatal_error((DREstring)"Parameter " + DREstring10(n) +
		(DREstring)" out of range in grey_font::operator+=(const int)");

  if (index >= GREY_FONT_BUFFER_SIZE) then
    fatal_error("Buffer overflow in grey_font::operator+=(const int)");

  buffer[index++] = n + bias;
}

// are the contents of the buffer null?
boolean grey_font::null(void) const
{ boolean return_value;

  if (!index) then
    return true;
  
  return_value = true;
  for (int char_nr = 0; char_nr < index; char_nr++)
  { if ((int)(buffer[char_nr]) != bias) then
      return_value = false;
  }
  return return_value;
}

// set a bit in a memory mapped square
void grey_font::_set_bit(char* ptr, const int i, const int j, const int value)
{ // calculate the bit number
  int bit_nr = 0;
  bit_nr += j;
  bit_nr += (i * h);
// byte number
  const int byte_nr = bit_nr / 8;
  bit_nr = bit_nr % 8;
  if (value) then
  { const byte mask = (0x80 >> bit_nr);
    ptr[byte_nr] |= mask;
  }
  else    // set the bit to zero
  { byte mask = (0x80 >> bit_nr);
    mask = ~mask;
    ptr[byte_nr] &= mask;
  }
}

// set a bit in a memory mapped square
int grey_font::_get_bit(char* ptr, const int i, const int j)
{ // calculate the bit number
  int bit_nr = 0;
  bit_nr += j;
  bit_nr += (i * h);
// byte number
  const int byte_nr = bit_nr / 8;
  bit_nr = bit_nr % 8;
  const byte mask = (0x80 >> bit_nr);
  return (ptr[byte_nr] & mask ? 1 : 0);
}

int grey_font::fonts_created = 0;

