<commit_before>/* bzflag
* Copyright (c) 1993 - 2005 <NAME>
*
* This package is free software;  you can redistribute it and/or
* modify it under the terms of the license found in the file
* named COPYING that should have accompanied this file.
*
* THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/

// BZFlag common header
#include "common.h"

// Interface headers
#include "ImageFont.h"
#include "BitmapFont.h"

// System headers
#include <string>
#include <string.h>
#include <assert.h>

// Common implementation headers
#include "bzfgl.h"
#include "bzfio.h"
#include "MediaFile.h"

BitmapFont::BitmapFont()
{
  loaded = false;
  for (int i = 0; i < MAX_TEXTURE_FONT_CHARS; i++) {
    bitmaps[i] = 0;
    fontMetrics[i].charWidth = -1;
  }
}

BitmapFont::~BitmapFont()
{
  for (int i = 0; i < MAX_TEXTURE_FONT_CHARS; i++) {
    if (bitmaps[i])
      delete[] bitmaps[i];
  }
}

void BitmapFont::build(void)
{
  if (texture.size() < 1) {
    DEBUG2("Font %s does not have an associated texture name, not loading\n", texture.c_str());
    return;
  }

  int width, height;
  std::string textureAndDir = "fonts/" + texture;
  unsigned char* image = MediaFile::readImage(textureAndDir, &width, &height);

  for (int i = 0; i < numberOfCharacters; i++) {
    delete[] bitmaps[i];
    const int h = fontMetrics[i].endY - fontMetrics[i].startY;
    const int w = fontMetrics[i].endX - fontMetrics[i].startX;
    const int sx = fontMetrics[i].startX;
    const int ey = fontMetrics[i].endY;
    const int bytesPerRow = ((w + 31) / 8) & ~3;
    bitmaps[i] = new unsigned char[h * bytesPerRow + 4];

    const int IT = 80;	// intensity threshold
    for (int j = 0; j < h; j++) {
      const unsigned char* srcRow = &image[4*((height-ey+j)*width+sx)];
      unsigned char* dstData = bitmaps[i] + j * bytesPerRow;
  
      int b;
      for (b = 0; b < w - 7; b += 8) {
        unsigned char data = 0;

        if (srcRow[4*(b+0)] >= IT) data |= 0x80u;
        if (srcRow[4*(b+1)] >= IT) data |= 0x40u;
        if (srcRow[4*(b+2)] >= IT) data |= 0x20u;
        if (srcRow[4*(b+3)] >= IT) data |= 0x10u;
        if (srcRow[4*(b+4)] >= IT) data |= 0x08u;
        if (srcRow[4*(b+5)] >= IT) data |= 0x04u;
        if (srcRow[4*(b+6)] >= IT) data |= 0x02u;
        if (srcRow[4*(b+7)] >= IT) data |= 0x01u;
        *dstData++ = data;
      }
  
      unsigned char data = 0;
      switch (w - b) {
        case 7:
          if (srcRow[4*(b+6)] >= IT) data |= 0x02u;
        case 6:
          if (srcRow[4*(b+5)] >= IT) data |= 0x04u;
        case 5:
          if (srcRow[4*(b+4)] >= IT) data |= 0x08u;
        case 4:
          if (srcRow[4*(b+3)] >= IT) data |= 0x10u;
        case 3:
          if (srcRow[4*(b+2)] >= IT) data |= 0x20u;
        case 2:
          if (srcRow[4*(b+1)] >= IT) data |= 0x40u;
        case 1:
          if (srcRow[4*(b+0)] >= IT) data |= 0x80u;
          *dstData++ = data;
      }
    }
  }
  delete[] image;
  loaded = true;
}


void BitmapFont::free(void)
{
  loaded = false;
}

void BitmapFont::filter(bool /*dofilter*/)
{
}

void BitmapFont::drawString(float scale, GLfloat color[3], const char *str,
			    int len)
{
  // BitmapFont cannot scale, should never be asked to
  assert(scale == 1.0f);

  if (!str)
    return;

  if (!loaded)
    build();

  if (!loaded)
    return;

  if (color[0] >= 0)
    glColor3fv(color);

  glRasterPos3f(0, 0, 0);

  int charToUse = 0;
  for (int i = 0; i < len; i++) {
    const char space = ' '; // decimal 32
    if (str[i] < space)
      charToUse = space;
    else if (str[i] > (numberOfCharacters + space))
      charToUse = space;
    else
      charToUse = str[i];


    charToUse -= space;

    const float dx = float(fontMetrics[charToUse].fullWidth);
    if (charToUse == 0) {
      glBitmap(0, 0, 0, 0, dx, 0, 0);
    } else {
      const int h = fontMetrics[charToUse].endY - fontMetrics[charToUse].startY;
      const int w = fontMetrics[charToUse].endX - fontMetrics[charToUse].startX;
      glBitmap(w, h, float(-fontMetrics[charToUse].initialDist), 0, dx, 0, bitmaps[charToUse]);
    }
  }
  if (color[0] >= 0)
    glColor4f(1, 1, 1, 1);
}


// Local Variables: ***
// mode: C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8
<commit_msg>do not reset color after drawing, unnecessary (hopefully), gets overwritten in case of underlining later anyway<commit_after>/* bzflag
* Copyright (c) 1993 - 2005 <NAME>
*
* This package is free software;  you can redistribute it and/or
* modify it under the terms of the license found in the file
* named COPYING that should have accompanied this file.
*
* THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/

// BZFlag common header
#include "common.h"

// Interface headers
#include "ImageFont.h"
#include "BitmapFont.h"

// System headers
#include <string>
#include <string.h>
#include <assert.h>

// Common implementation headers
#include "bzfgl.h"
#include "bzfio.h"
#include "MediaFile.h"

BitmapFont::BitmapFont()
{
  loaded = false;
  for (int i = 0; i < MAX_TEXTURE_FONT_CHARS; i++) {
    bitmaps[i] = 0;
    fontMetrics[i].charWidth = -1;
  }
}

BitmapFont::~BitmapFont()
{
  for (int i = 0; i < MAX_TEXTURE_FONT_CHARS; i++) {
    if (bitmaps[i])
      delete[] bitmaps[i];
  }
}

void BitmapFont::build(void)
{
  if (texture.size() < 1) {
    DEBUG2("Font %s does not have an associated texture name, not loading\n", texture.c_str());
    return;
  }

  int width, height;
  std::string textureAndDir = "fonts/" + texture;
  unsigned char* image = MediaFile::readImage(textureAndDir, &width, &height);

  for (int i = 0; i < numberOfCharacters; i++) {
    delete[] bitmaps[i];
    const int h = fontMetrics[i].endY - fontMetrics[i].startY;
    const int w = fontMetrics[i].endX - fontMetrics[i].startX;
    const int sx = fontMetrics[i].startX;
    const int ey = fontMetrics[i].endY;
    const int bytesPerRow = ((w + 31) / 8) & ~3;
    bitmaps[i] = new unsigned char[h * bytesPerRow + 4];

    const int IT = 80;	// intensity threshold
    for (int j = 0; j < h; j++) {
      const unsigned char* srcRow = &image[4*((height-ey+j)*width+sx)];
      unsigned char* dstData = bitmaps[i] + j * bytesPerRow;
  
      int b;
      for (b = 0; b < w - 7; b += 8) {
        unsigned char data = 0;

        if (srcRow[4*(b+0)] >= IT) data |= 0x80u;
        if (srcRow[4*(b+1)] >= IT) data |= 0x40u;
        if (srcRow[4*(b+2)] >= IT) data |= 0x20u;
        if (srcRow[4*(b+3)] >= IT) data |= 0x10u;
        if (srcRow[4*(b+4)] >= IT) data |= 0x08u;
        if (srcRow[4*(b+5)] >= IT) data |= 0x04u;
        if (srcRow[4*(b+6)] >= IT) data |= 0x02u;
        if (srcRow[4*(b+7)] >= IT) data |= 0x01u;
        *dstData++ = data;
      }
  
      unsigned char data = 0;
      switch (w - b) {
        case 7:
          if (srcRow[4*(b+6)] >= IT) data |= 0x02u;
        case 6:
          if (srcRow[4*(b+5)] >= IT) data |= 0x04u;
        case 5:
          if (srcRow[4*(b+4)] >= IT) data |= 0x08u;
        case 4:
          if (srcRow[4*(b+3)] >= IT) data |= 0x10u;
        case 3:
          if (srcRow[4*(b+2)] >= IT) data |= 0x20u;
        case 2:
          if (srcRow[4*(b+1)] >= IT) data |= 0x40u;
        case 1:
          if (srcRow[4*(b+0)] >= IT) data |= 0x80u;
          *dstData++ = data;
      }
    }
  }
  delete[] image;
  loaded = true;
}


void BitmapFont::free(void)
{
  loaded = false;
}

void BitmapFont::filter(bool /*dofilter*/)
{
}

void BitmapFont::drawString(float scale, GLfloat color[3], const char *str,
			    int len)
{
  // BitmapFont cannot scale, should never be asked to
  assert(scale == 1.0f);

  if (!str)
    return;

  if (!loaded)
    build();

  if (!loaded)
    return;

  if (color[0] >= 0)
    glColor3fv(color);

  glRasterPos3f(0, 0, 0);

  int charToUse = 0;
  for (int i = 0; i < len; i++) {
    const char space = ' '; // decimal 32
    if (str[i] < space)
      charToUse = space;
    else if (str[i] > (numberOfCharacters + space))
      charToUse = space;
    else
      charToUse = str[i];


    charToUse -= space;

    const float dx = float(fontMetrics[charToUse].fullWidth);
    if (charToUse == 0) {
      glBitmap(0, 0, 0, 0, dx, 0, 0);
    } else {
      const int h = fontMetrics[charToUse].endY - fontMetrics[charToUse].startY;
      const int w = fontMetrics[charToUse].endX - fontMetrics[charToUse].startX;
      glBitmap(w, h, float(-fontMetrics[charToUse].initialDist), 0, dx, 0, bitmaps[charToUse]);
    }
  }
}


// Local Variables: ***
// mode: C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8

{'fraction_non_alphanumeric': 0.16502242152466368, 'fraction_numerical': 0.03172645739910314, 'mean_word_length': 2.6651602300739525, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 46, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3910356', 'n_tokens_mistral': 3496, 'n_tokens_neox': 3255, 'n_words': 928}