<commit_before>// Copyright (c) 2020 The Orbit Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "TextRenderer.h"

#include <freetype-gl/shader.h>
#include <freetype-gl/vertex-buffer.h>

#include "App.h"
#include "GlCanvas.h"
#include "GlUtils.h"
#include "Params.h"
#include "Path.h"

typedef struct {
  float x, y, z;     // position
  float s, t;        // texture
  float r, g, b, a;  // color
} vertex_t;

TextRenderer::TextRenderer()
    : m_Atlas(NULL),
      m_Buffer(NULL),
      m_Font(NULL),
      m_Canvas(NULL),
      m_Initialized(false),
      m_DrawOutline(false) {}

TextRenderer::~TextRenderer() {
  if (m_Font) {
    texture_font_delete(m_Font);
  }

  if (m_Buffer) {
    vertex_buffer_delete(m_Buffer);
  }
}

void TextRenderer::Init() {
  if (m_Initialized) return;

  m_Font = NULL;
  int atlasSize = 2 * 1024;
  m_Atlas = texture_atlas_new(atlasSize, atlasSize, 1);

  const auto exePath = Path::GetExecutablePath();
  const auto fontFileName = exePath + "fonts/Vera.ttf";

  static float fsize = GParams.font_size;
  m_Buffer = vertex_buffer_new("vertex:3f,tex_coord:2f,color:4f");
  m_Font = texture_font_new_from_file(m_Atlas, fsize, fontFileName.c_str());
  current_font_size_ = static_cast<int>(fsize);
  for (int i = 10; i <= 100; i += 1) {
    m_FontsBySize[i] =
        texture_font_new_from_file(m_Atlas, i, fontFileName.c_str());
  }

  m_Pen.x = 0;
  m_Pen.y = 0;

  glGenTextures(1, &m_Atlas->id);

  const auto vertShaderFileName = exePath + "shaders/v3f-t2f-c4f.vert";
  const auto fragShaderFileName = exePath + "shaders/v3f-t2f-c4f.frag";
  m_Shader =
      shader_load(vertShaderFileName.c_str(), fragShaderFileName.c_str());

  mat4_set_identity(&m_Proj);
  mat4_set_identity(&m_Model);
  mat4_set_identity(&m_View);

  m_Initialized = true;
}

void TextRenderer::SetFontSize(int size) {
  texture_font_t* font = m_FontsBySize[size];
  if (font) {
    m_Font = font;
    current_font_size_ = size;
  }
}

int TextRenderer::GetFontSize() {
  return current_font_size_;
}

void TextRenderer::Display(Batcher* batcher) {
  if (m_DrawOutline) {<commit_msg>Fix memory leaks in TextRenderer<commit_after>// Copyright (c) 2020 The Orbit Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "TextRenderer.h"

#include <freetype-gl/shader.h>
#include <freetype-gl/vertex-buffer.h>

#include "App.h"
#include "GlCanvas.h"
#include "GlUtils.h"
#include "Params.h"
#include "Path.h"

typedef struct {
  float x, y, z;     // position
  float s, t;        // texture
  float r, g, b, a;  // color
} vertex_t;

TextRenderer::TextRenderer()
    : m_Atlas(nullptr),
      m_Buffer(nullptr),
      m_Font(nullptr),
      m_Canvas(nullptr),
      m_Initialized(false),
      m_DrawOutline(false) {}

TextRenderer::~TextRenderer() {
  // Freetype-gl doesn't handle nullptr in its
  // delete functions, hence the checks.

  if (m_Font) {
    texture_font_delete(m_Font);
  }

  for (const auto& pair : m_FontsBySize) {
    texture_font_delete(pair.second);
  }
  m_FontsBySize.clear();

  if (m_Buffer) {
    vertex_buffer_delete(m_Buffer);
  }

  if (m_Atlas) {
    texture_atlas_delete(m_Atlas);
  }
}

void TextRenderer::Init() {
  if (m_Initialized) return;

  int atlasSize = 2 * 1024;
  m_Atlas = texture_atlas_new(atlasSize, atlasSize, 1);

  const auto exePath = Path::GetExecutablePath();
  const auto fontFileName = exePath + "fonts/Vera.ttf";

  static float fsize = GParams.font_size;
  m_Buffer = vertex_buffer_new("vertex:3f,tex_coord:2f,color:4f");
  m_Font = texture_font_new_from_file(m_Atlas, fsize, fontFileName.c_str());
  current_font_size_ = static_cast<int>(fsize);
  for (int i = 10; i <= 100; i += 1) {
    m_FontsBySize[i] =
        texture_font_new_from_file(m_Atlas, i, fontFileName.c_str());
  }

  m_Pen.x = 0;
  m_Pen.y = 0;

  glGenTextures(1, &m_Atlas->id);

  const auto vertShaderFileName = exePath + "shaders/v3f-t2f-c4f.vert";
  const auto fragShaderFileName = exePath + "shaders/v3f-t2f-c4f.frag";
  m_Shader =
      shader_load(vertShaderFileName.c_str(), fragShaderFileName.c_str());

  mat4_set_identity(&m_Proj);
  mat4_set_identity(&m_Model);
  mat4_set_identity(&m_View);

  m_Initialized = true;
}

void TextRenderer::SetFontSize(int size) {
  texture_font_t* font = m_FontsBySize[size];
  if (font) {
    m_Font = font;
    current_font_size_ = size;
  }
}

int TextRenderer::GetFontSize() { return current_font_size_; }

void TextRenderer::Display(Batcher* batcher) {
  if (m_DrawOutline) {
{'fraction_non_alphanumeric': 0.13067814854682455, 'fraction_numerical': 0.013347685683530678, 'mean_word_length': 3.9903329752953813, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 11, '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': '5154041', 'n_tokens_mistral': 1826, 'n_tokens_neox': 1774, 'n_words': 363}