Subversion Repositories DIN Is Noise

Rev

Rev 2097 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
964 jag 1
/*
2
* font_editor.cc
2302 jag 3
* DIN Is Noise is copyright (c) 2006-2025 Jagannathan Sampath
1713 jag 4
* DIN Is Noise is released under GNU Public License 2.0
1479 jag 5
* For more information, please visit https://dinisnoise.org/
964 jag 6
*/
7
 
8
#include <fstream>
9
#include <iostream>
10
#include "font_editor.h"
11
#include "font.h"
12
#include "input.h"
13
#include "console.h"
14
 
15
using namespace std;
16
 
1789 jag 17
font_editor::font_editor (font& f, const string& settingsf, const string& helpf) :
1883 jag 18
  curve_editor (settingsf),
1789 jag 19
  fn (f),
20
  glyphs (f.get_chars()),
21
  moving(false) {
964 jag 22
  prep_edit ();
23
  edit_char (0);
24
}
25
 
26
font_editor::~font_editor () {
27
  leave ();
28
}
29
 
30
void font_editor::leave () {
31
  save_font ();
32
}
33
 
34
void font_editor::save_font () {
35
  save_char (ichar);
36
  prep_save ();
37
}
38
 
39
void font_editor::edit_char (int i) {
40
  if (i > -1 && i < (int) glyphs.size()) {
41
    char c = chars[i];
42
    gl = glyphs[c];
43
    lines = gl.lines;
44
    cons << "char = " << c << " nlines = " << lines.size () << eol;
45
  }
46
}
47
 
48
void font_editor::save_char (int i) {
49
  if (i > -1 && i < (int)glyphs.size()) {
50
    gl.lines = lines;
51
    glyphs[chars[i]] = gl;
52
  }
53
}
54
 
55
void font_editor::prep_edit () {
56
  chars.clear ();
57
  for (map<char, glyph>::iterator i = glyphs.begin (), j = glyphs.end(); i != j; ++i) {
58
    const pair<char, glyph>& p = *i;
59
    glyph g (p.second);
60
    vector<line>& lines = g.lines;
61
    for (int s = 0, t = lines.size(); s < t; ++s) {
62
      vector < point<int> >& points = lines[s].points;
63
      for (int m = 0, n = points.size(); m < n; ++m) {
64
        point<int>& pt = points[m];
65
        float wx, wy;
1789 jag 66
        basic_editor::obj2win (pt.x / fnt.cellsize.x, pt.y / fnt.cellsize.x, wx, wy);
964 jag 67
        pt.x = wx;
68
        pt.y = wy;
69
      }
70
    }
71
    chars.push_back (p.first);
72
    glyphs[p.first] = g;
73
  }
74
}
75
 
76
void font_editor::prep_save () {
77
  map<char, glyph> fg (glyphs);
78
  for (map<char, glyph>::iterator i = fg.begin (), j = fg.end(); i != j; ++i) {
79
    const pair<char, glyph>& p = *i;
80
    glyph g(p.second);
81
    vector<line>& lines = g.lines;
82
    for (int s = 0, t = lines.size(); s < t; ++s) {
83
      vector < point<int> >& points = lines[s].points;
84
      for (int m = 0, n = points.size(); m < n; ++m) {
85
        point<int>& pt = points[m];
86
        float ox, oy;
87
        basic_editor::win2obj (pt.x, pt.y, ox, oy);
1789 jag 88
        pt.x = ox * fnt.cellsize.x;
89
        pt.y = oy * fnt.cellsize.y;
964 jag 90
      }
91
    }
92
    g.find_width_height ();
93
    fg[p.first] = g;
94
 
95
  }
96
  fn.set_chars (fg);
97
}
98
 
99
int font_editor::handle_input () {
100
 
101
  basic_editor::handle_input ();
102
 
103
  if (keypressed (SDLK_F1)) helptext ();
104
 
105
  if (keypressed (SDLK_f)) {
106
    float x, y; snap (x, y);
107
    scratch_points.push_back (point<float>(x, y));
108
  }
109
 
110
  if (keypressed (SDLK_g)) {
111
    if (scratch_points.size() > 1) lines.push_back (line(scratch_points));
112
    scratch_points.clear ();
113
  }
114
 
115
  if (keypressed (SDLK_r)) {
116
    if (moving) moving = false;
117
    else {
118
      cur = hittest ();
119
      if (cur()) moving = true; else cons << "no hit" << eol;
120
    }
121
  } else if (moving) move ();
122
 
123
  if (keypressed (SDLK_i)) {
124
    if (ins()) {
125
      float x, y; snap (x, y);
126
      lines[ins.l].insert (ins.v, x, y);
127
      ins = line_hit();
128
    } else ins = hittest ();
129
  }
130
 
131
  if (keypressed (SDLK_v)) {
132
    del = hittest ();
133
    if (del()) {
134
      if (keydown (SDLK_LSHIFT))
135
        lines.erase (lines.begin() + del.l);
136
      else {
137
        if (lines[del.l].remove (del.v) < 2) lines.erase (lines.begin() + del.l);
138
      }
139
    }
140
  }
141
 
142
  if (keypressedd (SDLK_LEFTBRACKET)) {
143
    if (ichar > 0) {
144
      save_char (ichar--);
145
      edit_char (ichar);
146
    }
147
  }
148
 
149
  if (keypressedd (SDLK_RIGHTBRACKET)) {
150
    if (ichar < ((int)chars.size() - 1)) {
151
      save_char (ichar++);
152
      edit_char (ichar);
153
    }
154
  }
155
 
156
  if (keypressed (SDLK_RETURN)) {
157
    save_font ();
158
  }
159
 
160
  return true;
161
}
162
 
163
void font_editor::draw () {
164
  project ();
165
    basic_editor::draw ();
166
    mark_area ();
167
    draw_lines ();
168
    draw_scratch_line ();
169
  unproject ();
170
}
171
 
172
line_hit font_editor::hittest () {
173
  float x, y; snap (x, y);
174
  cons << x << ' ' << y << eol;
175
  for (int i = 0, j = lines.size(); i < j; ++i) {
176
    const line& l = lines[i];
177
    for (int p = 0, q = l.points.size(); p < q; ++p) {
178
      const point<int>& pt = l.points[p];
179
      if ((pt.x == x) && (pt.y == y)) return line_hit (i, p);
180
    }
181
  }
182
  return line_hit ();
183
}
184
 
185
void font_editor::draw_scratch_line () {
186
  if (int npts = scratch_points.size ()) {
187
    float x, y; snap (x, y);
188
    glColor3f (0.7, 0.4, 0);
189
    glBegin (GL_LINE_STRIP);
190
      for (int i = 0; i < npts; ++i) glVertex2f (scratch_points[i].x, scratch_points[i].y);
191
      glVertex2f (x, y);
192
    glEnd();
193
  }
194
}
195
 
196
void font_editor::draw_lines () {
197
  glColor3f (1, 0.8, 0);
198
  for (int i = 0, j = lines.size(); i < j; ++i) lines[i].draw ();
199
}
200
 
201
void font_editor::move () {
202
  float x, y;
203
  snap (x, y);
204
  lines[cur.l].set (cur.v, x, y);
205
}
206
 
207
void font_editor::mark_area () {
208
  glColor3f (0.5, 0.25, 0.25);
209
  float wx, wy, ox = 0, oy = 2, owx, owy;
1789 jag 210
  basic_editor::obj2win (fnt.charwidth.max / fnt.cellsize.x, fnt.charheight.max / fnt.cellsize.y, wx, wy);
964 jag 211
  basic_editor::obj2win (ox, oy, owx, owy);
212
  glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
213
    glRectf (0, 0, wx, wy);
214
  glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
215
  glBegin (GL_LINES);
216
    glVertex2f (owx, owy);
217
    glVertex2f (wx, owy);
218
  glEnd ();
219
}
220
 
221
 
222