1
//-------------------------------------------------------------------------------------
2
// This file is part of the Lomse library.
3
// Copyright (c) 2010 Lomse project
5
// Lomse is free software; you can redistribute it and/or modify it under the
6
// terms of the GNU General Public License as published by the Free Software Foundation,
7
// either version 3 of the License, or (at your option) any later version.
9
// Lomse is distributed in the hope that it will be useful, but WITHOUT ANY
10
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
11
// PARTICULAR PURPOSE. See the GNU General Public License for more details.
13
// You should have received a copy of the GNU General Public License along
14
// with Lomse; if not, see <http://www.gnu.org/licenses/>.
16
// For any comment, suggestion or feature request, please contact the manager of
17
// the project at cecilios@users.sourceforge.net
20
// -------------------------
21
// This file is based on Anti-Grain Geometry version 2.4 examples' code.
22
// Anti-Grain Geometry (AGG) is copyright (C) 2002-2005 Maxim Shemanarev
23
// (http://www.antigrain.com). AGG 2.4 is distributed under BSD license.
25
//-------------------------------------------------------------------------------------
27
#include "lomse_agg_drawer.h"
29
#include "lomse_exceptions.h"
30
#include "lomse_screen_renderer.h" //PathAttributes
31
//#include "lomse_gm_basic.h"
33
//using namespace std;
39
//---------------------------------------------------------------------------------------
40
AggDrawer::AggDrawer(path_storage& storage, attr_storage& attr_storage)
43
, m_attr_storage(attr_storage)
47
//---------------------------------------------------------------------------------------
48
AggDrawer::~AggDrawer()
52
////---------------------------------------------------------------------------------------
53
//void AggDrawer::remove_all()
55
// m_storage.remove_all();
56
// m_attr_storage.remove_all();
57
// m_attr_stack.remove_all();
58
// m_transform.reset();
61
//---------------------------------------------------------------------------------------
62
void AggDrawer::begin_path()
65
unsigned idx = m_storage.start_new_path();
66
m_attr_storage.add(PathAttributes(cur_attr(), idx));
69
//---------------------------------------------------------------------------------------
70
void AggDrawer::end_path()
72
if(m_attr_storage.size() == 0)
74
throw exception("end_path : The path was not begun");
76
PathAttributes attr = cur_attr();
77
unsigned idx = m_attr_storage[m_attr_storage.size() - 1].index;
79
m_attr_storage[m_attr_storage.size() - 1] = attr;
83
//---------------------------------------------------------------------------------------
84
void AggDrawer::move_to(double x, double y)
86
m_storage.move_to(x, y);
89
//---------------------------------------------------------------------------------------
90
void AggDrawer::move_to_rel(double x, double y)
92
m_storage.rel_to_abs(&x, &y);
93
m_storage.move_to(x, y);
96
//---------------------------------------------------------------------------------------
97
void AggDrawer::line_to(double x, double y)
99
m_storage.line_to(x, y);
102
//---------------------------------------------------------------------------------------
103
void AggDrawer::line_to_rel(double x, double y)
105
m_storage.rel_to_abs(&x, &y);
106
m_storage.line_to(x, y);
109
//---------------------------------------------------------------------------------------
110
void AggDrawer::hline_to(double x)
114
if(m_storage.total_vertices())
116
m_storage.vertex(m_storage.total_vertices() - 1, &x2, &y2);
117
m_storage.line_to(x, y2);
121
//---------------------------------------------------------------------------------------
122
void AggDrawer::hline_to_rel(double x)
126
if(m_storage.total_vertices())
128
m_storage.vertex(m_storage.total_vertices() - 1, &x2, &y2);
130
m_storage.line_to(x, y2);
134
//---------------------------------------------------------------------------------------
135
void AggDrawer::vline_to(double y)
139
if(m_storage.total_vertices())
141
m_storage.vertex(m_storage.total_vertices() - 1, &x2, &y2);
142
m_storage.line_to(x2, y);
146
//---------------------------------------------------------------------------------------
147
void AggDrawer::vline_to_rel(double y)
151
if(m_storage.total_vertices())
153
m_storage.vertex(m_storage.total_vertices() - 1, &x2, &y2);
155
m_storage.line_to(x2, y);
159
//---------------------------------------------------------------------------------------
160
void AggDrawer::cubic_bezier(double x1, double y1, double x, double y)
162
m_storage.curve3(x1, y1, x, y);
165
//---------------------------------------------------------------------------------------
166
void AggDrawer::cubic_bezier_rel(double x1, double y1, double x, double y)
168
m_storage.rel_to_abs(&x1, &y1);
169
m_storage.rel_to_abs(&x, &y);
170
m_storage.curve3(x1, y1, x, y);
173
//---------------------------------------------------------------------------------------
174
void AggDrawer::cubic_bezier(double x, double y)
176
m_storage.curve3(x, y);
179
//---------------------------------------------------------------------------------------
180
void AggDrawer::cubic_bezier_rel(double x, double y)
182
m_storage.curve3_rel(x, y);
185
//---------------------------------------------------------------------------------------
186
void AggDrawer::quadratic_bezier(double x1, double y1, double x2, double y2,
189
m_storage.curve4(x1, y1, x2, y2, x, y);
191
//---------------------------------------------------------------------------------------
192
void AggDrawer::quadratic_bezier_rel(double x1, double y1, double x2, double y2,
195
m_storage.rel_to_abs(&x1, &y1);
196
m_storage.rel_to_abs(&x2, &y2);
197
m_storage.rel_to_abs(&x, &y);
198
m_storage.curve4(x1, y1, x2, y2, x, y);
201
//---------------------------------------------------------------------------------------
202
void AggDrawer::quadratic_bezier(double x2, double y2, double x, double y)
204
m_storage.curve4(x2, y2, x, y);
207
//---------------------------------------------------------------------------------------
208
void AggDrawer::quadratic_bezier_rel(double x2, double y2, double x, double y)
210
m_storage.curve4_rel(x2, y2, x, y);
213
//---------------------------------------------------------------------------------------
214
void AggDrawer::close_subpath()
216
m_storage.end_poly(path_flags_close);
219
//---------------------------------------------------------------------------------------
220
PathAttributes& AggDrawer::cur_attr()
222
if(m_attr_stack.size() == 0)
224
throw exception("cur_attr : Attribute stack is empty");
226
return m_attr_stack[m_attr_stack.size() - 1];
229
//---------------------------------------------------------------------------------------
230
void AggDrawer::push_attr()
232
m_attr_stack.add(m_attr_stack.size() ?
233
m_attr_stack[m_attr_stack.size() - 1] :
237
//---------------------------------------------------------------------------------------
238
void AggDrawer::pop_attr()
240
if(m_attr_stack.size() == 0)
242
throw exception("pop_attr : Attribute stack is empty");
244
m_attr_stack.remove_last();
247
//---------------------------------------------------------------------------------------
248
void AggDrawer::fill(const rgba8& f)
250
PathAttributes& attr = cur_attr();
252
attr.fill_flag = true;
255
//---------------------------------------------------------------------------------------
256
void AggDrawer::stroke(const rgba8& s)
258
PathAttributes& attr = cur_attr();
259
attr.stroke_color = s;
260
attr.stroke_flag = true;
263
//---------------------------------------------------------------------------------------
264
void AggDrawer::even_odd(bool flag)
266
cur_attr().even_odd_flag = flag;
269
//---------------------------------------------------------------------------------------
270
void AggDrawer::stroke_width(double w)
272
cur_attr().stroke_width = w;
275
//---------------------------------------------------------------------------------------
276
void AggDrawer::fill_none()
278
cur_attr().fill_flag = false;
281
//---------------------------------------------------------------------------------------
282
void AggDrawer::stroke_none()
284
cur_attr().stroke_flag = false;
287
//---------------------------------------------------------------------------------------
288
void AggDrawer::fill_opacity(double op)
290
cur_attr().fill_color.opacity(op);
293
//---------------------------------------------------------------------------------------
294
void AggDrawer::stroke_opacity(double op)
296
cur_attr().stroke_color.opacity(op);
299
//---------------------------------------------------------------------------------------
300
void AggDrawer::line_join(line_join_e join)
302
cur_attr().line_join = join;
305
//---------------------------------------------------------------------------------------
306
void AggDrawer::line_cap(line_cap_e cap)
308
cur_attr().line_cap = cap;
311
//---------------------------------------------------------------------------------------
312
void AggDrawer::miter_limit(double ml)
314
cur_attr().miter_limit = ml;
317
//---------------------------------------------------------------------------------------
318
trans_affine& AggDrawer::transform()
320
return cur_attr().transform;
323
//---------------------------------------------------------------------------------------
324
void AggDrawer::add_path(VertexSource& vs, unsigned path_id, bool solid_path)
326
m_storage.concat_path(vs, path_id);
332
////---------------------------------------------------------------------------------------
333
//void AggDrawer::flip_text(bool flip)
335
// m_fontEngine.flip_y(flip);
338
////---------------------------------------------------------------------------------------
339
//void AggDrawer::font(const char* fontName, double height, bool bold, bool italic,
340
// FontCacheType ch, double angle)
342
//m_textAngle = angle;
343
//m_fontHeight = height;
344
//m_fontCacheType = ch;
346
//m_fontEngine.load_font(fontName, 0,
347
// (ch == VectorFontCache) ?
348
// agg::glyph_ren_outline :
349
// agg::glyph_ren_agg_gray8);
350
//m_fontEngine.hinting(m_textHints);
351
//m_fontEngine.height((ch == VectorFontCache) ? height : worldToScreen(height));
354
////---------------------------------------------------------------------------------------
355
//double AggDrawer::font_height() const
357
// return m_fontHeight;
360
////---------------------------------------------------------------------------------------
361
//void AggDrawer::text_alignment(TextAlignment alignX, TextAlignment alignY)
363
// m_textAlignX = alignX;
364
// m_textAlignY = alignY;
367
////---------------------------------------------------------------------------------------
368
//double AggDrawer::text_width(const char* str)
372
// bool first = true;
375
// const agg::glyph_cache* glyph = m_fontCacheManager.glyph(*str);
378
// if(!first) m_fontCacheManager.add_kerning(&x, &y);
379
// x += glyph->advance_x;
380
// y += glyph->advance_y;
385
// return (m_fontCacheType == VectorFontCache) ? x : screenToWorld(x);
388
////---------------------------------------------------------------------------------------
389
//bool AggDrawer::text_hints() const
391
// return m_textHints;
394
////---------------------------------------------------------------------------------------
395
//void AggDrawer::text_hints(bool hints)
397
// m_textHints = hints;
400
//---------------------------------------------------------------------------------------
401
void AggDrawer::text(double x, double y, const char* str, bool roundOff,
402
double ddx, double ddy)
407
// switch(m_textAlignX)
409
// case AlignCenter: dx = -textWidth(str) * 0.5; break;
410
// case AlignRight: dx = -textWidth(str); break;
415
// double asc = font_height();
416
// const agg::glyph_cache* glyph = m_fontCacheManager.glyph('H');
419
// asc = glyph->bounds.y2 - glyph->bounds.y1;
422
// if(m_fontCacheType == RasterFontCache)
424
// asc = screenToWorld(asc);
427
// switch(m_textAlignY)
429
// case AlignCenter: dy = -asc * 0.5; break;
430
// case AlignTop: dy = -asc; break;
434
// if(m_fontEngine.flip_y()) dy = -dy;
436
// agg::trans_affine mtx;
438
// double start_x = x + dx;
439
// double start_y = y + dy;
443
// start_x = int(start_x);
444
// start_y = int(start_y);
449
// mtx *= agg::trans_affine_translation(-x, -y);
450
// mtx *= agg::trans_affine_rotation(m_textAngle);
451
// mtx *= agg::trans_affine_translation(x, y);
453
// agg::conv_transform<FontCacheManager::path_adaptor_type> tr(m_fontCacheManager.path_adaptor(), mtx);
455
// if(m_fontCacheType == RasterFontCache)
457
// worldToScreen(start_x, start_y);
461
// for (i = 0; str[i]; i++)
463
// glyph = m_fontCacheManager.glyph(str[i]);
466
// if(i) m_fontCacheManager.add_kerning(&start_x, &start_y);
467
// m_fontCacheManager.init_embedded_adaptors(glyph, start_x, start_y);
469
// if(glyph->data_type == agg::glyph_data_outline)
471
// m_path.remove_all();
472
// //m_path.add_path(tr, 0, false);
473
// m_path.concat_path(tr,0); // JME
477
// if(glyph->data_type == agg::glyph_data_gray8)
479
// render(m_fontCacheManager.gray8_adaptor(),
480
// m_fontCacheManager.gray8_scanline());
482
// start_x += glyph->advance_x;
483
// start_y += glyph->advance_y;