~centralelyon2010/inkscape/imagelinks2

« back to all changes in this revision

Viewing changes to src/dyna-draw-context.cpp

  • Committer: JazzyNico
  • Date: 2011-08-29 20:25:30 UTC
  • Revision ID: nicoduf@yahoo.fr-20110829202530-6deuoz11q90usldv
Code refactoring and merging with trunk (revision 10599).

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#define __SP_DYNA_DRAW_CONTEXT_C__
2
 
 
3
1
/*
4
2
 * Handwriting-like drawing mode
5
3
 *
8
6
 *   Lauris Kaplinski <lauris@kaplinski.com>
9
7
 *   bulia byak <buliabyak@users.sf.net>
10
8
 *   MenTaLguY <mental@rydia.net>
 
9
 *   Abhishek Sharma
11
10
 *
12
11
 * The original dynadraw code:
13
12
 *   Paul Haeberli <paul@sgi.com>
34
33
 
35
34
#include "svg/svg.h"
36
35
#include "display/canvas-bpath.h"
37
 
#include <2geom/isnan.h>
 
36
#include "display/cairo-utils.h"
 
37
#include <2geom/math-utils.h>
38
38
#include <2geom/pathvector.h>
39
39
#include <2geom/bezier-utils.h>
40
40
#include "display/curve.h"
59
59
#include "sp-shape.h"
60
60
#include "sp-path.h"
61
61
#include "sp-text.h"
 
62
#include "display/sp-canvas.h"
62
63
#include "display/canvas-bpath.h"
63
64
#include "display/canvas-arena.h"
64
65
#include "livarot/Shape.h"
65
66
 
66
67
#include "dyna-draw-context.h"
67
68
 
 
69
using Inkscape::DocumentUndo;
 
70
 
68
71
#define DDC_RED_RGBA 0xff0000ff
69
72
 
70
73
#define TOLERANCE_CALLIGRAPHIC 0.1
437
440
    double trace_thick = 1;
438
441
    if (dc->trace_bg) {
439
442
        // pick single pixel
440
 
        NRPixBlock pb;
441
 
        int x = (int) floor(brush_w[Geom::X]);
442
 
        int y = (int) floor(brush_w[Geom::Y]);
443
 
        nr_pixblock_setup_fast(&pb, NR_PIXBLOCK_MODE_R8G8B8A8P, x, y, x+1, y+1, TRUE);
444
 
        sp_canvas_arena_render_pixblock(SP_CANVAS_ARENA(sp_desktop_drawing(SP_EVENT_CONTEXT(dc)->desktop)), &pb);
445
 
        const unsigned char *s = NR_PIXBLOCK_PX(&pb);
446
 
        double R = s[0] / 255.0;
447
 
        double G = s[1] / 255.0;
448
 
        double B = s[2] / 255.0;
449
 
        double A = s[3] / 255.0;
 
443
        double R, G, B, A;
 
444
        Geom::IntRect area = Geom::IntRect::from_xywh(brush_w.floor(), Geom::IntPoint(1, 1));
 
445
        cairo_surface_t *s = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 1, 1);
 
446
        sp_canvas_arena_render_surface(SP_CANVAS_ARENA(sp_desktop_drawing(SP_EVENT_CONTEXT(dc)->desktop)), s, area);
 
447
        ink_cairo_surface_average_color_premul(s, R, G, B, A);
 
448
        cairo_surface_destroy(s);
450
449
        double max = MAX (MAX (R, G), B);
451
450
        double min = MIN (MIN (R, G), B);
452
451
        double L = A * (max + min)/2 + (1 - A); // blend with white bg
581
580
            Geom::Point hatch_unit_vector(0,0);
582
581
            Geom::Point nearest(0,0);
583
582
            Geom::Point pointer(0,0);
584
 
            Geom::Matrix motion_to_curve(Geom::identity());
 
583
            Geom::Affine motion_to_curve(Geom::identity());
585
584
 
586
585
            if (event->motion.state & GDK_CONTROL_MASK) { // hatching - sense the item
587
586
 
599
598
                    }
600
599
 
601
600
                    // calculate pointer point in the guide item's coords
602
 
                    motion_to_curve = sp_item_dt2i_affine(selected) * sp_item_i2doc_affine(selected);
 
601
                    motion_to_curve = selected->dt2i_affine() * selected->i2doc_affine();
603
602
                    pointer = motion_dt * motion_to_curve;
604
603
 
605
604
                    // calculate the nearest point on the guide path
778
777
                if (dc->hatch_spacing == 0 && hatch_dist != 0) {
779
778
                    // Haven't set spacing yet: gray, center free, update radius live
780
779
                    Geom::Point c = desktop->w2d(motion_w);
781
 
                    Geom::Matrix const sm (Geom::Scale(hatch_dist, hatch_dist) * Geom::Translate(c));
 
780
                    Geom::Affine const sm (Geom::Scale(hatch_dist, hatch_dist) * Geom::Translate(c));
782
781
                    sp_canvas_item_affine_absolute(dc->hatch_area, sm);
783
782
                    sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(dc->hatch_area), 0x7f7f7fff, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT);
784
783
                    sp_canvas_item_show(dc->hatch_area);
785
784
                } else if (dc->dragging && !dc->hatch_escaped) {
786
785
                    // Tracking: green, center snapped, fixed radius
787
786
                    Geom::Point c = motion_dt;
788
 
                    Geom::Matrix const sm (Geom::Scale(dc->hatch_spacing, dc->hatch_spacing) * Geom::Translate(c));
 
787
                    Geom::Affine const sm (Geom::Scale(dc->hatch_spacing, dc->hatch_spacing) * Geom::Translate(c));
789
788
                    sp_canvas_item_affine_absolute(dc->hatch_area, sm);
790
789
                    sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(dc->hatch_area), 0x00FF00ff, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT);
791
790
                    sp_canvas_item_show(dc->hatch_area);
792
791
                } else if (dc->dragging && dc->hatch_escaped) {
793
792
                    // Tracking escaped: red, center free, fixed radius
794
793
                    Geom::Point c = motion_dt;
795
 
                    Geom::Matrix const sm (Geom::Scale(dc->hatch_spacing, dc->hatch_spacing) * Geom::Translate(c));
 
794
                    Geom::Affine const sm (Geom::Scale(dc->hatch_spacing, dc->hatch_spacing) * Geom::Translate(c));
796
795
 
797
796
                    sp_canvas_item_affine_absolute(dc->hatch_area, sm);
798
797
                    sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(dc->hatch_area), 0xFF0000ff, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT);
801
800
                    // Not drawing but spacing set: gray, center snapped, fixed radius
802
801
                    Geom::Point c = (nearest + dc->hatch_spacing * hatch_unit_vector) * motion_to_curve.inverse();
803
802
                    if (!IS_NAN(c[Geom::X]) && !IS_NAN(c[Geom::Y])) {
804
 
                        Geom::Matrix const sm (Geom::Scale(dc->hatch_spacing, dc->hatch_spacing) * Geom::Translate(c));
 
803
                        Geom::Affine const sm (Geom::Scale(dc->hatch_spacing, dc->hatch_spacing) * Geom::Translate(c));
805
804
                        sp_canvas_item_affine_absolute(dc->hatch_area, sm);
806
805
                        sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(dc->hatch_area), 0x7f7f7fff, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT);
807
806
                        sp_canvas_item_show(dc->hatch_area);
1002
1001
    if (!dc->accumulated->is_empty()) {
1003
1002
        if (!dc->repr) {
1004
1003
            /* Create object */
1005
 
            Inkscape::XML::Document *xml_doc = sp_document_repr_doc(desktop->doc());
 
1004
            Inkscape::XML::Document *xml_doc = desktop->doc()->getReprDoc();
1006
1005
            Inkscape::XML::Node *repr = xml_doc->createElement("svg:path");
1007
1006
 
1008
1007
            /* Set style */
1012
1011
 
1013
1012
            SPItem *item=SP_ITEM(desktop->currentLayer()->appendChildRepr(dc->repr));
1014
1013
            Inkscape::GC::release(dc->repr);
1015
 
            item->transform = sp_item_i2doc_affine(SP_ITEM(desktop->currentLayer())).inverse();
 
1014
            item->transform = SP_ITEM(desktop->currentLayer())->i2doc_affine().inverse();
1016
1015
            item->updateRepr();
1017
1016
        }
1018
1017
        Geom::PathVector pathv = dc->accumulated->get_pathvector() * desktop->dt2doc();
1040
1039
        dc->repr = NULL;
1041
1040
    }
1042
1041
 
1043
 
    sp_document_done(sp_desktop_document(desktop), SP_VERB_CONTEXT_CALLIGRAPHIC,
1044
 
                     _("Draw calligraphic stroke"));
 
1042
    DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_CALLIGRAPHIC,
 
1043
                       _("Draw calligraphic stroke"));
1045
1044
}
1046
1045
 
1047
1046
static void
1084
1083
            return false; // failure
1085
1084
        }
1086
1085
 
1087
 
        Geom::CubicBezier const * dc_cal1_firstseg  = dynamic_cast<Geom::CubicBezier const *>( dc->cal1->first_segment() );
1088
 
        Geom::CubicBezier const * rev_cal2_firstseg = dynamic_cast<Geom::CubicBezier const *>( rev_cal2->first_segment() );
1089
 
        Geom::CubicBezier const * dc_cal1_lastseg   = dynamic_cast<Geom::CubicBezier const *>( dc->cal1->last_segment() );
1090
 
        Geom::CubicBezier const * rev_cal2_lastseg  = dynamic_cast<Geom::CubicBezier const *>( rev_cal2->last_segment() );
1091
 
 
1092
 
        if (
1093
 
            !dc_cal1_firstseg ||
1094
 
            !rev_cal2_firstseg ||
1095
 
            !dc_cal1_lastseg ||
1096
 
            !rev_cal2_lastseg
1097
 
            ) {
1098
 
            rev_cal2->unref();
1099
 
            dc->cal1->reset();
1100
 
            dc->cal2->reset();
1101
 
            return false; // failure
1102
 
        }
 
1086
        Geom::Curve const * dc_cal1_firstseg  = dc->cal1->first_segment();
 
1087
        Geom::Curve const * rev_cal2_firstseg = rev_cal2->first_segment();
 
1088
        Geom::Curve const * dc_cal1_lastseg   = dc->cal1->last_segment();
 
1089
        Geom::Curve const * rev_cal2_lastseg  = rev_cal2->last_segment();
1103
1090
 
1104
1091
        dc->accumulated->reset(); /*  Is this required ?? */
1105
1092
 
1106
1093
        dc->accumulated->append(dc->cal1, false);
1107
1094
 
1108
 
        add_cap(dc->accumulated, (*dc_cal1_lastseg)[3], (*rev_cal2_firstseg)[0], dc->cap_rounding);
 
1095
        add_cap(dc->accumulated, dc_cal1_lastseg->finalPoint(), rev_cal2_firstseg->initialPoint(), dc->cap_rounding);
1109
1096
 
1110
1097
        dc->accumulated->append(rev_cal2, true);
1111
1098
 
1112
 
        add_cap(dc->accumulated, (*rev_cal2_lastseg)[3], (*dc_cal1_firstseg)[0], dc->cap_rounding);
 
1099
        add_cap(dc->accumulated, rev_cal2_lastseg->finalPoint(), dc_cal1_firstseg->initialPoint(), dc->cap_rounding);
1113
1100
 
1114
1101
        dc->accumulated->closepath();
1115
1102
 
1284
1271
  fill-column:99
1285
1272
  End:
1286
1273
*/
1287
 
// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
 
1274
// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :