Rev 2097 |
Blame |
Compare with Previous |
Last modification |
View Log
| RSS feed
/*
* font_editor.cc
* DIN Is Noise is copyright (c) 2006-2025 Jagannathan Sampath
* DIN Is Noise is released under GNU Public License 2.0
* For more information, please visit https://dinisnoise.org/
*/
#include <fstream>
#include <iostream>
#include "font_editor.h"
#include "font.h"
#include "input.h"
#include "console.h"
using namespace std;
font_editor::font_editor (font& f, const string& settingsf, const string& helpf) :
curve_editor (settingsf),
fn (f),
glyphs (f.get_chars()),
moving(false) {
prep_edit ();
edit_char (0);
}
font_editor::~font_editor () {
leave ();
}
void font_editor::leave () {
save_font ();
}
void font_editor::save_font () {
save_char (ichar);
prep_save ();
}
void font_editor::edit_char (int i) {
if (i > -1 && i < (int) glyphs.size()) {
char c = chars[i];
gl = glyphs[c];
lines = gl.lines;
cons << "char = " << c << " nlines = " << lines.size () << eol;
}
}
void font_editor::save_char (int i) {
if (i > -1 && i < (int)glyphs.size()) {
gl.lines = lines;
glyphs[chars[i]] = gl;
}
}
void font_editor::prep_edit () {
chars.clear ();
for (map<char, glyph>::iterator i = glyphs.begin (), j = glyphs.end(); i != j; ++i) {
const pair<char, glyph>& p = *i;
glyph g (p.second);
vector<line>& lines = g.lines;
for (int s = 0, t = lines.size(); s < t; ++s) {
vector < point<int> >& points = lines[s].points;
for (int m = 0, n = points.size(); m < n; ++m) {
point<int>& pt = points[m];
float wx, wy;
basic_editor::obj2win (pt.x / fnt.cellsize.x, pt.y / fnt.cellsize.x, wx, wy);
pt.x = wx;
pt.y = wy;
}
}
chars.push_back (p.first);
glyphs[p.first] = g;
}
}
void font_editor::prep_save () {
map<char, glyph> fg (glyphs);
for (map<char, glyph>::iterator i = fg.begin (), j = fg.end(); i != j; ++i) {
const pair<char, glyph>& p = *i;
glyph g(p.second);
vector<line>& lines = g.lines;
for (int s = 0, t = lines.size(); s < t; ++s) {
vector < point<int> >& points = lines[s].points;
for (int m = 0, n = points.size(); m < n; ++m) {
point<int>& pt = points[m];
float ox, oy;
basic_editor::win2obj (pt.x, pt.y, ox, oy);
pt.x = ox * fnt.cellsize.x;
pt.y = oy * fnt.cellsize.y;
}
}
g.find_width_height ();
fg[p.first] = g;
}
fn.set_chars (fg);
}
int font_editor::handle_input () {
basic_editor::handle_input ();
if (keypressed (SDLK_F1)) helptext ();
if (keypressed (SDLK_f)) {
float x, y; snap (x, y);
scratch_points.push_back (point<float>(x, y));
}
if (keypressed (SDLK_g)) {
if (scratch_points.size() > 1) lines.push_back (line(scratch_points));
scratch_points.clear ();
}
if (keypressed (SDLK_r)) {
if (moving) moving = false;
else {
cur = hittest ();
if (cur()) moving = true; else cons << "no hit" << eol;
}
} else if (moving) move ();
if (keypressed (SDLK_i)) {
if (ins()) {
float x, y; snap (x, y);
lines[ins.l].insert (ins.v, x, y);
ins = line_hit();
} else ins = hittest ();
}
if (keypressed (SDLK_v)) {
del = hittest ();
if (del()) {
if (keydown (SDLK_LSHIFT))
lines.erase (lines.begin() + del.l);
else {
if (lines[del.l].remove (del.v) < 2) lines.erase (lines.begin() + del.l);
}
}
}
if (keypressedd (SDLK_LEFTBRACKET)) {
if (ichar > 0) {
save_char (ichar--);
edit_char (ichar);
}
}
if (keypressedd (SDLK_RIGHTBRACKET)) {
if (ichar < ((int)chars.size() - 1)) {
save_char (ichar++);
edit_char (ichar);
}
}
if (keypressed (SDLK_RETURN)) {
save_font ();
}
return true;
}
void font_editor::draw () {
project ();
basic_editor::draw ();
mark_area ();
draw_lines ();
draw_scratch_line ();
unproject ();
}
line_hit font_editor::hittest () {
float x, y; snap (x, y);
cons << x << ' ' << y << eol;
for (int i = 0, j = lines.size(); i < j; ++i) {
const line& l = lines[i];
for (int p = 0, q = l.points.size(); p < q; ++p) {
const point<int>& pt = l.points[p];
if ((pt.x == x) && (pt.y == y)) return line_hit (i, p);
}
}
return line_hit ();
}
void font_editor::draw_scratch_line () {
if (int npts = scratch_points.size ()) {
float x, y; snap (x, y);
glColor3f (0.7, 0.4, 0);
glBegin (GL_LINE_STRIP);
for (int i = 0; i < npts; ++i) glVertex2f (scratch_points[i].x, scratch_points[i].y);
glVertex2f (x, y);
glEnd();
}
}
void font_editor::draw_lines () {
glColor3f (1, 0.8, 0);
for (int i = 0, j = lines.size(); i < j; ++i) lines[i].draw ();
}
void font_editor::move () {
float x, y;
snap (x, y);
lines[cur.l].set (cur.v, x, y);
}
void font_editor::mark_area () {
glColor3f (0.5, 0.25, 0.25);
float wx, wy, ox = 0, oy = 2, owx, owy;
basic_editor::obj2win (fnt.charwidth.max / fnt.cellsize.x, fnt.charheight.max / fnt.cellsize.y, wx, wy);
basic_editor::obj2win (ox, oy, owx, owy);
glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
glRectf (0, 0, wx, wy);
glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
glBegin (GL_LINES);
glVertex2f (owx, owy);
glVertex2f (wx, owy);
glEnd ();
}