Files
core/DesktopEditor/agg-2.4/svg/svg_test.cpp
Elen.Subbotina b858608c6b .....
git-svn-id: svn://fileserver/activex/AVS/Sources/TeamlabOffice/trunk/ServerComponents@61952 954022d7-b5bf-4e40-9824-e11837661b57
2016-05-20 23:55:13 +03:00

410 lines
9.0 KiB
C++

#include <stdio.h>
#include <stdlib.h>
#include "agg_scanline_p.h"
#include "platform/agg_platform_support.h"
#include "ctrl/agg_slider_ctrl.h"
#include "agg_svg_exception.h"
#include "agg_svg_parser.h"
#include "agg_svg_indexation_interpreter.h"
#include "agg_svg_rendering_interpreter.h"
#include "agg_svg_attributes_map.h"
#include "agg_svg_rasterizer.h"
enum { flip_y_e = false };
class the_application : public agg::platform_support
{
agg::svg::dom_storage m_storage;
agg::svg::dom_storage::map_type m_id2elem_map;
agg::svg::attributes_map m_attr_map;
agg::svg::global_settings m_settings;
agg::svg::attributes m_attributes;
agg::svg::frame_buffer_rgba m_frame_buffer;
agg::svg::rasterizer m_rasterizer;
agg::svg::renderer_rgba m_renderer;
agg::svg::pipeline m_pipeline;
agg::svg::gradient_lut_cache m_gradient_lut_cache;
//agg::slider_ctrl<agg::rgba8> m_expand;
agg::slider_ctrl<agg::rgba8> m_gamma;
//agg::slider_ctrl<agg::rgba8> m_scale;
//agg::slider_ctrl<agg::rgba8> m_rotate;
enum tool_type_e {tool_none, tool_zoom, tool_pan};
tool_type_e m_current_tool;
int m_x1;
int m_y1;
int m_x2;
int m_y2;
bool m_drag_flag;
public:
the_application(agg::pix_format_e format, bool flip_y) :
agg::platform_support(format, flip_y),
//m_expand(5, 5, 256-5, 11, !flip_y),
m_gamma (5, 5, 256-5, 20, !flip_y),
//m_scale (256+5, 5, 512-5, 11, !flip_y),
//m_rotate(256+5, 5+15, 512-5, 11+15, !flip_y),
m_x1(0),
m_y1(0),
m_x2(0),
m_y2(0),
m_drag_flag(false),
m_attributes(m_settings),
m_renderer(m_rasterizer, m_frame_buffer),
m_current_tool(tool_none)
{
//add_ctrl(m_expand);
add_ctrl(m_gamma);
//add_ctrl(m_scale);
//add_ctrl(m_rotate);
//m_expand.label("Expand=%3.2f");
//m_expand.range(-1, 1.2);
//m_expand.value(0.0);
m_gamma.label("Gamma=%3.2f");
m_gamma.range(0.0, 3.0);
m_gamma.value(1.0);
//m_scale.label("Scale=%3.2f");
//m_scale.range(0.2, 10.0);
//m_scale.value(1.0);
//m_rotate.label("Rotate=%3.2f");
//m_rotate.range(-180.0, 180.0);
//m_rotate.value(0.0);
}
void swap_int(int* n1, int* n2)
{
int temp;
temp = *n1;
*n1 = *n2;
*n2 = temp;
}
void normalize_rect(int* x1, int* y1, int* x2, int* y2)
{
if (*x1 > *x2)
{
swap_int(x1, x2);
}
if (*y1 > *y2)
{
swap_int(y1, y2);
}
}
void update_zoom()
{
if (m_current_tool == tool_zoom)
{
int x1 = m_x1;
int y1 = m_y1;
int x2 = m_x2;
int y2 = m_y2;
normalize_rect(&x1, &y1, &x2, &y2);
m_attributes.set_zoom(x1, y1, x2, y2);
}
else if (m_current_tool == tool_pan)
{
int offset_x = m_x2 - m_x1;
int offset_y = m_y2 - m_y1;
int x1 = -offset_x;
int y1 = -offset_y;
int x2 = rbuf_window().width() - offset_x;
int y2 = rbuf_window().height() - offset_y;
m_attributes.set_zoom(x1, y1, x2, y2);
}
}
void indexation()
{
agg::svg::indexation_interpreter consumer(m_id2elem_map);
m_storage.traverse(consumer);
m_id2elem_map.sort_state(agg::svg::on);
}
void reset()
{
m_id2elem_map.clear();
m_attributes.clear();
m_renderer.reset();
}
void parse_svg(const char* fname)
{
if(!fname)
return;
m_attributes.initial_zoom();
m_storage.clear();
reset();
agg::svg::parser p(m_storage, m_attr_map);
p.parse(fname);
indexation();
}
void on_resize(int sx, int sy)
{
m_frame_buffer.create(sx, sy, flip_y_e);
}
void draw(agg::rendering_buffer& rbuf, double expand, double gamma)
{
agg::svg::renderer_rgba::pixfmt_type pixfmt(rbuf);
agg::svg::renderer_rgba::renderer_base_type rbase(pixfmt);
m_rasterizer.gamma(gamma);
m_settings.gamma(gamma);
m_attributes.window(0, 0, rbuf.width(), rbuf.height());
m_frame_buffer.clear(agg::svg::color_type(255, 255, 255));
m_renderer.attach(m_frame_buffer);
agg::svg::rendering_interpreter rin( m_pipeline,
m_attributes,
m_renderer,
m_id2elem_map,
m_gradient_lut_cache
);
#ifdef EXPAND_PATHS
rin.expand(expand);
#endif
m_storage.traverse(rin);
assert(0 == m_attributes.num_sessions());
if (m_settings.gamma() != 1.0)
{
m_frame_buffer.pixfmt().apply_gamma_inv(m_settings.gamma_lut());
}
if(m_frame_buffer.is_valid())
{
rbase.copy_from(m_frame_buffer.ren_buf());
if (m_current_tool == tool_zoom)
{
agg::rgba8 color(0, 0, 0, 255);
rbase.blend_hline(m_x1, m_y1, m_x2, color, agg::cover_full);
rbase.blend_hline(m_x1, m_y2, m_x2, color, agg::cover_full);
rbase.blend_vline(m_x1, m_y1, m_y2, color, agg::cover_full);
rbase.blend_vline(m_x2, m_y1, m_y2, color, agg::cover_full);
}
}
else
{
rbase.clear(agg::svg::color_type(255, 255, 255));
}
}
virtual void on_draw()
{
try
{
typedef agg::pixfmt_bgra32 pixfmt;
typedef agg::renderer_base<pixfmt> renderer_base;
typedef agg::renderer_scanline_aa_solid<renderer_base> renderer_solid;
pixfmt pixf(rbuf_window());
renderer_base rb(pixf);
renderer_solid ren(rb);
rb.clear(agg::rgba(1,1,1));
agg::rasterizer_scanline_aa<> ras;
agg::scanline_p8 sl;
//ras.gamma(agg::gamma_power(m_gamma.value()));
start_timer();
draw(rbuf_window(), 0.0/*m_expand.value()*/, m_gamma.value());
double tm = elapsed_time();
ras.gamma(agg::gamma_none());
//agg::render_ctrl(ras, sl, rb, m_expand);
agg::render_ctrl(ras, sl, rb, m_gamma);
//agg::render_ctrl(ras, sl, rb, m_scale);
//agg::render_ctrl(ras, sl, rb, m_rotate);
char buf[128];
agg::gsv_text t;
t.size(10.0);
t.flip(true);
agg::conv_stroke<agg::gsv_text> pt(t);
pt.width(1.5);
//sprintf(buf, "Vertices=%d Time=%.3f ms", vertex_count, tm);
sprintf(buf, "Time=%.3f ms", tm);
t.start_point(4.0, 40.0);
t.text(buf);
ras.add_path(pt);
ren.color(agg::rgba(0,0,0));
agg::render_scanlines(ras, sl, ren);
}
catch (agg::svg::exception&)
{
}
}
virtual void on_mouse_button_down(int x, int y, unsigned flags)
{
if (flags & agg::mouse_left)
m_current_tool = tool_zoom;
if (flags & agg::mouse_right)
m_current_tool = tool_pan;
m_x1 = x;
m_y1 = y;
m_x2 = x;
m_y2 = y;
m_drag_flag = true;
}
virtual void on_mouse_move(int x, int y, unsigned flags)
{
if(flags == 0)
{
m_drag_flag = false;
}
if (m_drag_flag)
{
m_x2 = x;
m_y2 = y;
if (m_current_tool == tool_zoom)
{
force_redraw();
}
else if (m_current_tool == tool_pan)
{
update_zoom();
m_x1 = x;
m_y1 = y;
force_redraw();
}
}
}
void zoom_out(int x, int y)
{
int d = 100;
int x1 = -d;
int y1 = -d;
int x2 = rbuf_window().width() + d;
int y2 = rbuf_window().height() + d;
int w = x2 - x1;
int h = y2 - y1;
int cx = x1 + w/2;
int cy = y1 + h/2;
int dx = x - cx;
int dy = y - cy;
m_attributes.set_zoom(x1 + dx, y1 + dy, x2 + dx, y2 + dy);
force_redraw();
}
virtual void on_mouse_button_up(int x, int y, unsigned flags)
{
if ((flags & agg::kbd_shift) && m_x1 == x && m_y1 == y)
{
zoom_out(x,y);
m_drag_flag = false;
m_current_tool = tool_none;
}
if (m_drag_flag)
{
if (m_current_tool == tool_zoom)
{
if(x != m_x1 && y != m_y1)
{
m_x2 = x;
m_y2 = y;
update_zoom();
}
force_redraw();
}
m_drag_flag = false;
}
m_current_tool = tool_none;
}
virtual void on_key(int x, int y, unsigned key, unsigned flags)
{
if(key == agg::key_home)
{
m_attributes.initial_zoom();
force_redraw();
}
}
};
int agg_main(int argc, char* argv[])
{
the_application app(agg::svg::pix_format, flip_y_e);
const char* fname = "tiger.svg";
if(argc <= 1)
{
FILE* fd = fopen(app.full_file_name(fname), "r");
if(fd == 0)
{
app.message("Usage: svg_test <svg_file>\n"
"Download http://antigrain.com/svg/tiger.svg");
return 1;
}
fclose(fd);
}
else
{
fname = argv[1];
}
try
{
app.parse_svg(app.full_file_name(fname));
}
catch (agg::svg::exception& e)
{
app.message(e.msg());
return 1;
}
if(app.init(512, 600, agg::window_resize))
{
return app.run();
}
return 1;
}