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 |