<commit_before>// Filename: dynamicTextFont.cxx
// Created by:  drose (08Feb02)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license.  You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// <EMAIL> .
//
////////////////////////////////////////////////////////////////////

#include "dynamicTextFont.h"

#ifdef HAVE_FREETYPE

#include "config_text.h"
#include "config_util.h"
#include "config_express.h"
#include "virtualFileSystem.h"

bool DynamicTextFont::_update_cleared_glyphs = text_update_cleared_glyphs;

FT_Library DynamicTextFont::_ft_library;
bool DynamicTextFont::_ft_initialized = false;
bool DynamicTextFont::_ft_ok = false;

TypeHandle DynamicTextFont::_type_handle;


// This constant determines how big a particular point size font
// appears to be.  By convention, 10 points is 1 unit (e.g. 1 foot)
// high.
static const float points_per_unit = 10.0f;

// A universal typographic convention.
static const float points_per_inch = 72.0f;

////////////////////////////////////////////////////////////////////
//     Function: DynamicTextFont::Constructor
//       Access: Published
//  Description: The constructor expects the name of some font file
//               that FreeType can read, along with face_index,
//               indicating which font within the file to load
//               (usually 0).
////////////////////////////////////////////////////////////////////
DynamicTextFont::
DynamicTextFont(const Filename &font_filename, int face_index) {
  initialize();

  if (!_ft_ok) {
    text_cat.error()
      << "Unable to read font " << font_filename
      << ": FreeType library not initialized properly.\n";
    return;
  }

  bool exists = false;
  int error;
  Filename path(font_filename);
  if (use_vfs) {
    VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
    vfs->resolve_filename(path, get_model_path());
    exists = vfs->read_file(path, _raw_font_data);
    if (exists) {
      error = FT_New_Memory_Face(_ft_library, 
                                 (const FT_Byte *)_raw_font_data.data(),
                                 _raw_font_data.length(),
                                 face_index, &_face);
    }
  } else {
    path.resolve_filename(get_model_path());
    exists = path.exists();
    if (exists) {
      string os_specific = path.to_os_specific();
      error = FT_New_Face(_ft_library, os_specific.c_str(),
                          face_index, &_face);
    }
  }

  if (!exists) {
    text_cat.error()
      << "Unable to find font file " << font_filename << "\n";
  } else {
    if (error == FT_Err_Unknown_File_Format) {
      text_cat.error()
        << "Unable to read font " << font_filename << ": unknown file format.\n";
    } else if (error) {
      text_cat.error()
        << "Unable to read font " << font_filename << ": invalid.\n";

    } else {
      string name = _face->family_name;
      if (_face->style_name != NULL) {
        name += " ";
        name += _face->style_name;
      }
      set_name(name);

      text_cat.info()
        << "Loaded font " << get_name() << "\n";
      _is_valid = true;
      reset_scale();

      if (text_cat.is_debug()) {
        text_cat.debug()
          << *this << " has " << _face->num_charmaps << " charmaps:\n";
        for (int i = 0; i < _face->num_charmaps; i++) {
          text_cat.debug(false) << " " << (void *)_face->charmaps[i];
        }
        text_cat.debug(false) << "\n";
        text_cat.debug()
          << "default charmap is " << (void *)_face->charmap << "\n";
      }
      if (_face->charmap == NULL) {
        // If for some reason FreeType didn't set us up a charmap,
        // then set it up ourselves.
        if (_face->num_charmaps == 0) {
          text_cat.warning()
            << *this << " has no charmaps available.\n";
        } else {
          text_cat.warning()
            << *this << " has no default Unicode charmap.\n";
          if (_face->num_charmaps > 1) {
            text_cat.warning()
              << "Choosing arbitrary charmap of " << _face->num_charmaps 
              << ".\n";
          }
          FT_Set_Charmap(_face, _face->charmaps[0]);
        }
      }
    }
  }
}

////////////////////////////////////////////////////////////////////
//     Function: DynamicTextFont::Constructor
//       Access: Published
//  Description: This constructor accepts a table of data representing<commit_msg>reword warning to make it less confusing<commit_after>// Filename: dynamicTextFont.cxx
// Created by:  drose (08Feb02)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license.  You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// <EMAIL> .
//
////////////////////////////////////////////////////////////////////

#include "dynamicTextFont.h"

#ifdef HAVE_FREETYPE

#include "config_text.h"
#include "config_util.h"
#include "config_express.h"
#include "virtualFileSystem.h"

bool DynamicTextFont::_update_cleared_glyphs = text_update_cleared_glyphs;

FT_Library DynamicTextFont::_ft_library;
bool DynamicTextFont::_ft_initialized = false;
bool DynamicTextFont::_ft_ok = false;

TypeHandle DynamicTextFont::_type_handle;


// This constant determines how big a particular point size font
// appears to be.  By convention, 10 points is 1 unit (e.g. 1 foot)
// high.
static const float points_per_unit = 10.0f;

// A universal typographic convention.
static const float points_per_inch = 72.0f;

////////////////////////////////////////////////////////////////////
//     Function: DynamicTextFont::Constructor
//       Access: Published
//  Description: The constructor expects the name of some font file
//               that FreeType can read, along with face_index,
//               indicating which font within the file to load
//               (usually 0).
////////////////////////////////////////////////////////////////////
DynamicTextFont::
DynamicTextFont(const Filename &font_filename, int face_index) {
  initialize();

  if (!_ft_ok) {
    text_cat.error()
      << "Unable to read font " << font_filename
      << ": FreeType library not initialized properly.\n";
    return;
  }

  bool exists = false;
  int error;
  Filename path(font_filename);
  if (use_vfs) {
    VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
    vfs->resolve_filename(path, get_model_path());
    exists = vfs->read_file(path, _raw_font_data);
    if (exists) {
      error = FT_New_Memory_Face(_ft_library, 
                                 (const FT_Byte *)_raw_font_data.data(),
                                 _raw_font_data.length(),
                                 face_index, &_face);
    }
  } else {
    path.resolve_filename(get_model_path());
    exists = path.exists();
    if (exists) {
      string os_specific = path.to_os_specific();
      error = FT_New_Face(_ft_library, os_specific.c_str(),
                          face_index, &_face);
    }
  }

  if (!exists) {
    text_cat.error()
      << "Unable to find font file " << font_filename << "\n";
  } else {
    if (error == FT_Err_Unknown_File_Format) {
      text_cat.error()
        << "Unable to read font " << font_filename << ": unknown file format.\n";
    } else if (error) {
      text_cat.error()
        << "Unable to read font " << font_filename << ": invalid.\n";

    } else {
      string name = _face->family_name;
      if (_face->style_name != NULL) {
        name += " ";
        name += _face->style_name;
      }
      set_name(name);

      text_cat.info()
        << "Loaded font " << get_name() << "\n";
      _is_valid = true;
      reset_scale();

      if (text_cat.is_debug()) {
        text_cat.debug()
          << *this << " has " << _face->num_charmaps << " charmaps:\n";
        for (int i = 0; i < _face->num_charmaps; i++) {
          text_cat.debug(false) << " " << (void *)_face->charmaps[i];
        }
        text_cat.debug(false) << "\n";
        text_cat.debug()
          << "default charmap is " << (void *)_face->charmap << "\n";
      }
      if (_face->charmap == NULL) {
        // If for some reason FreeType didn't set us up a charmap,
        // then set it up ourselves.
        if (_face->num_charmaps == 0) {
          text_cat.warning()
            << *this << " has no charmaps available.\n";
        } else {
          text_cat.warning()
            << *this << " has no default Unicode charmap.\n";
          if (_face->num_charmaps > 1) {
            text_cat.warning()
              << "Arbitrarily choosing first of " 
              << _face->num_charmaps << " charmaps.\n";
          }
          FT_Set_Charmap(_face, _face->charmaps[0]);
        }
      }
    }
  }
}

////////////////////////////////////////////////////////////////////
//     Function: DynamicTextFont::Constructor
//       Access: Published
//  Description: This constructor accepts a table of data representing
{'fraction_non_alphanumeric': 0.18744769874476988, 'fraction_numerical': 0.005439330543933054, 'mean_word_length': 1.8660071942446044, 'pattern_counts': {'":': 6, '<': 135, '<?xml version=': 0, '>': 35, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3203867', 'n_tokens_mistral': 2803, 'n_tokens_neox': 2726, 'n_words': 737}