~valavanisalex/ubuntu/oneiric/inkscape/inkscape_0.48.1-2ubuntu4

« back to all changes in this revision

Viewing changes to src/display/canvas-axonomgrid.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Kees Cook, Ted Gould, Kees Cook
  • Date: 2009-06-24 14:00:43 UTC
  • mfrom: (1.1.8 upstream)
  • Revision ID: james.westby@ubuntu.com-20090624140043-07stp20mry48hqup
Tags: 0.47~pre0-0ubuntu1
* New upstream release

[ Ted Gould ]
* debian/control: Adding libgsl0 and removing version specifics on boost

[ Kees Cook ]
* debian/watch: updated to run uupdate and mangle pre-release versions.
* Dropped patches that have been taken upstream:
  - 01_mips
  - 02-poppler-0.8.3
  - 03-chinese-inkscape
  - 05_fix_latex_patch
  - 06_gcc-4.4
  - 07_cdr2svg
  - 08_skip-bad-utf-on-pdf-import
  - 09_gtk-clist
  - 10_belarussian
  - 11_libpng
  - 12_desktop
  - 13_slider
  - 100_svg_import_improvements
  - 102_sp_pattern_painter_free
  - 103_bitmap_type_print

Show diffs side-by-side

added added

removed removed

Lines of Context:
19
19
 
20
20
#include "sp-canvas-util.h"
21
21
#include "canvas-axonomgrid.h"
22
 
#include "util/mathfns.h" 
23
 
#include "2geom/geom.h"
 
22
#include "util/mathfns.h"
 
23
#include "2geom/line.h"
24
24
#include "display-forward.h"
25
25
#include <libnr/nr-pixops.h>
26
26
 
36
36
#include "desktop.h"
37
37
 
38
38
#include "document.h"
39
 
#include "prefs-utils.h"
 
39
#include "preferences.h"
40
40
 
41
41
#define SAFE_SETPIXEL   //undefine this when it is certain that setpixel is never called with invalid params
42
42
 
70
70
        g = NR_RGBA32_G (rgba);
71
71
        b = NR_RGBA32_B (rgba);
72
72
        a = NR_RGBA32_A (rgba);
73
 
        guchar * p = buf->buf + (y - buf->rect.y0) * buf->buf_rowstride + (x - buf->rect.x0) * 3;
 
73
        guchar * p = buf->buf + (y - buf->rect.y0) * buf->buf_rowstride + (x - buf->rect.x0) * 4;
74
74
        p[0] = NR_COMPOSEN11_1111 (r, a, p[0]);
75
75
        p[1] = NR_COMPOSEN11_1111 (g, a, p[1]);
76
76
        p[2] = NR_COMPOSEN11_1111 (b, a, p[2]);
137
137
        a = NR_RGBA32_A (rgba);
138
138
        y0 = MAX (buf->rect.y0, ys);
139
139
        y1 = MIN (buf->rect.y1, ye + 1);
140
 
        p = buf->buf + (y0 - buf->rect.y0) * buf->buf_rowstride + (x - buf->rect.x0) * 3;
 
140
        p = buf->buf + (y0 - buf->rect.y0) * buf->buf_rowstride + (x - buf->rect.x0) * 4;
141
141
        for (y = y0; y < y1; y++) {
142
142
            p[0] = NR_COMPOSEN11_1111 (r, a, p[0]);
143
143
            p[1] = NR_COMPOSEN11_1111 (g, a, p[1]);
193
193
CanvasAxonomGrid::CanvasAxonomGrid (SPNamedView * nv, Inkscape::XML::Node * in_repr, SPDocument * in_doc)
194
194
    : CanvasGrid(nv, in_repr, in_doc, GRID_AXONOMETRIC)
195
195
{
196
 
    gridunit = sp_unit_get_by_abbreviation( prefs_get_string_attribute("options.grids.axonom", "units") );
 
196
    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
 
197
    gridunit = sp_unit_get_by_abbreviation( prefs->getString("/options/grids/axonom/units").data() );
197
198
    if (!gridunit)
198
199
        gridunit = &sp_unit_get_by_id(SP_UNIT_PX);
199
 
    origin[NR::X] = sp_units_get_pixels( prefs_get_double_attribute ("options.grids.axonom", "origin_x", 0.0), *(gridunit) );
200
 
    origin[NR::Y] = sp_units_get_pixels( prefs_get_double_attribute ("options.grids.axonom", "origin_y", 0.0), *(gridunit) );
201
 
    color = prefs_get_int_attribute("options.grids.axonom", "color", 0x0000ff20);
202
 
    empcolor = prefs_get_int_attribute("options.grids.axonom", "empcolor", 0x0000ff40);
203
 
    empspacing = prefs_get_int_attribute("options.grids.axonom", "empspacing", 5);
204
 
    lengthy = sp_units_get_pixels( prefs_get_double_attribute ("options.grids.axonom", "spacing_y", 1.0), *(gridunit) );
205
 
    angle_deg[X] = prefs_get_double_attribute ("options.grids.axonom", "angle_x", 30.0);
206
 
    angle_deg[Z] = prefs_get_double_attribute ("options.grids.axonom", "angle_z", 30.0);
 
200
    origin[Geom::X] = sp_units_get_pixels( prefs->getDouble("/options/grids/axonom/origin_x", 0.0), *gridunit );
 
201
    origin[Geom::Y] = sp_units_get_pixels( prefs->getDouble("/options/grids/axonom/origin_y", 0.0), *gridunit );
 
202
    color = prefs->getInt("/options/grids/axonom/color", 0x0000ff20);
 
203
    empcolor = prefs->getInt("/options/grids/axonom/empcolor", 0x0000ff40);
 
204
    empspacing = prefs->getInt("/options/grids/axonom/empspacing", 5);
 
205
    lengthy = sp_units_get_pixels( prefs->getDouble("/options/grids/axonom/spacing_y", 1.0), *gridunit );
 
206
    angle_deg[X] = prefs->getDouble("/options/grids/axonom/angle_x", 30.0);
 
207
    angle_deg[Z] = prefs->getDouble("/options/grids/axonom/angle_z", 30.0);
207
208
    angle_deg[Y] = 0;
208
209
 
209
210
    angle_rad[X] = deg_to_rad(angle_deg[X]);
211
212
    angle_rad[Z] = deg_to_rad(angle_deg[Z]);
212
213
    tan_angle[Z] = tan(angle_rad[Z]);
213
214
 
214
 
    snapper = new CanvasAxonomGridSnapper(this, namedview, 0);
 
215
    snapper = new CanvasAxonomGridSnapper(this, &namedview->snap_manager, 0);
215
216
 
216
217
    if (repr) readRepr();
217
218
}
299
300
{
300
301
    gchar const *value;
301
302
    if ( (value = repr->attribute("originx")) ) {
302
 
        sp_nv_read_length(value, SP_UNIT_ABSOLUTE | SP_UNIT_DEVICE, &origin[NR::X], &gridunit);
303
 
        origin[NR::X] = sp_units_get_pixels(origin[NR::X], *(gridunit));
 
303
        sp_nv_read_length(value, SP_UNIT_ABSOLUTE | SP_UNIT_DEVICE, &origin[Geom::X], &gridunit);
 
304
        origin[Geom::X] = sp_units_get_pixels(origin[Geom::X], *(gridunit));
304
305
    }
305
306
    if ( (value = repr->attribute("originy")) ) {
306
 
        sp_nv_read_length(value, SP_UNIT_ABSOLUTE | SP_UNIT_DEVICE, &origin[NR::Y], &gridunit);
307
 
        origin[NR::Y] = sp_units_get_pixels(origin[NR::Y], *(gridunit));
 
307
        sp_nv_read_length(value, SP_UNIT_ABSOLUTE | SP_UNIT_DEVICE, &origin[Geom::Y], &gridunit);
 
308
        origin[Geom::Y] = sp_units_get_pixels(origin[Geom::Y], *(gridunit));
308
309
    }
309
310
 
310
311
    if ( (value = repr->attribute("spacingy")) ) {
349
350
    }
350
351
 
351
352
    if ( (value = repr->attribute("visible")) ) {
352
 
        visible = (strcmp(value,"true") == 0);
 
353
        visible = (strcmp(value,"false") != 0 && strcmp(value, "0") != 0);
353
354
    }
354
355
 
355
356
    if ( (value = repr->attribute("enabled")) ) {
356
357
        g_assert(snapper != NULL);
357
 
        snapper->setEnabled(strcmp(value,"true") == 0);
 
358
        snapper->setEnabled(strcmp(value,"false") != 0 && strcmp(value, "0") != 0);
358
359
    }
359
360
 
 
361
    if ( (value = repr->attribute("snapvisiblegridlinesonly")) ) {
 
362
                g_assert(snapper != NULL);
 
363
                snapper->setSnapVisibleOnly(strcmp(value,"false") != 0 && strcmp(value, "0") != 0);
 
364
        }
 
365
 
360
366
    for (GSList *l = canvasitems; l != NULL; l = l->next) {
361
367
        sp_canvas_item_request_update ( SP_CANVAS_ITEM(l->data) );
362
368
    }
386
392
 
387
393
_wr.setUpdating (true);
388
394
 
389
 
    Inkscape::UI::Widget::RegisteredUnitMenu *_rumg = new Inkscape::UI::Widget::RegisteredUnitMenu();
390
 
    Inkscape::UI::Widget::RegisteredScalarUnit *_rsu_ox = new Inkscape::UI::Widget::RegisteredScalarUnit();
391
 
    Inkscape::UI::Widget::RegisteredScalarUnit *_rsu_oy = new Inkscape::UI::Widget::RegisteredScalarUnit();
392
 
    Inkscape::UI::Widget::RegisteredScalarUnit *_rsu_sy = new Inkscape::UI::Widget::RegisteredScalarUnit();
 
395
    Inkscape::UI::Widget::RegisteredUnitMenu *_rumg = Gtk::manage( new Inkscape::UI::Widget::RegisteredUnitMenu(
 
396
            _("Grid _units:"), "units", _wr, repr, doc) );
 
397
    Inkscape::UI::Widget::RegisteredScalarUnit *_rsu_ox = Gtk::manage( new Inkscape::UI::Widget::RegisteredScalarUnit(
 
398
            _("_Origin X:"), _("X coordinate of grid origin"), "originx", *_rumg, _wr, repr, doc) );
 
399
    Inkscape::UI::Widget::RegisteredScalarUnit *_rsu_oy = Gtk::manage( new Inkscape::UI::Widget::RegisteredScalarUnit(
 
400
            _("O_rigin Y:"), _("Y coordinate of grid origin"), "originy", *_rumg, _wr, repr, doc) );
 
401
    Inkscape::UI::Widget::RegisteredScalarUnit *_rsu_sy = Gtk::manage( new Inkscape::UI::Widget::RegisteredScalarUnit(
 
402
            _("Spacing _Y:"), _("Base length of z-axis"), "spacingy", *_rumg, _wr, repr, doc) );
393
403
    Inkscape::UI::Widget::RegisteredScalar *_rsu_ax = Gtk::manage( new Inkscape::UI::Widget::RegisteredScalar(
394
404
            _("Angle X:"), _("Angle of x-axis"), "gridanglex", _wr, repr, doc ) );
395
405
    Inkscape::UI::Widget::RegisteredScalar *_rsu_az = Gtk::manage(  new Inkscape::UI::Widget::RegisteredScalar(
397
407
 
398
408
    Inkscape::UI::Widget::RegisteredColorPicker *_rcp_gcol = Gtk::manage(
399
409
        new Inkscape::UI::Widget::RegisteredColorPicker(
400
 
            _("Grid line _color:"), _("Grid line color"), _("Color of grid lines"), 
 
410
            _("Grid line _color:"), _("Grid line color"), _("Color of grid lines"),
401
411
            "color", "opacity", _wr, repr, doc));
402
412
 
403
413
    Inkscape::UI::Widget::RegisteredColorPicker *_rcp_gmcol = Gtk::manage(
404
414
        new Inkscape::UI::Widget::RegisteredColorPicker(
405
 
            _("Ma_jor grid line color:"), _("Major grid line color"), 
 
415
            _("Ma_jor grid line color:"), _("Major grid line color"),
406
416
            _("Color of the major (highlighted) grid lines"),
407
417
            "empcolor", "empopacity", _wr, repr, doc));
408
418
 
409
 
    Inkscape::UI::Widget::RegisteredSuffixedInteger *_rsi = new Inkscape::UI::Widget::RegisteredSuffixedInteger();
410
 
 
411
 
    Inkscape::UI::Widget::ScalarUnit * sutemp = NULL;
412
 
    _rumg->init (_("Grid _units:"), "units", _wr, repr, doc);
413
 
    _rsu_ox->init (_("_Origin X:"), _("X coordinate of grid origin"),
414
 
                  "originx", *_rumg, _wr, repr, doc);
415
 
        sutemp = _rsu_ox->getSU();
416
 
        sutemp->setDigits(4);
417
 
        sutemp->setIncrements(0.1, 1.0);
418
 
    _rsu_oy->init (_("O_rigin Y:"), _("Y coordinate of grid origin"),
419
 
                  "originy", *_rumg, _wr, repr, doc);
420
 
        sutemp = _rsu_oy->getSU();
421
 
        sutemp->setDigits(4);
422
 
        sutemp->setIncrements(0.1, 1.0);
423
 
    _rsu_sy->init (_("Spacing _Y:"), _("Base length of z-axis"),
424
 
                  "spacingy", *_rumg, _wr, repr, doc);
425
 
        sutemp = _rsu_sy->getSU();
426
 
        sutemp->setDigits(4);
427
 
        sutemp->setIncrements(0.1, 1.0);
428
 
    _rsi->init (_("_Major grid line every:"), _("lines"), "empspacing", _wr, repr, doc);
 
419
    Inkscape::UI::Widget::RegisteredSuffixedInteger *_rsi = Gtk::manage( new Inkscape::UI::Widget::RegisteredSuffixedInteger(
 
420
            _("_Major grid line every:"), "", _("lines"), "empspacing", _wr, repr, doc ) );
 
421
 
 
422
    _rsu_ox->setDigits(4);
 
423
    _rsu_ox->setIncrements(0.1, 1.0);
 
424
 
 
425
    _rsu_oy->setDigits(4);
 
426
    _rsu_oy->setIncrements(0.1, 1.0);
 
427
 
 
428
    _rsu_sy->setDigits(4);
 
429
    _rsu_sy->setIncrements(0.1, 1.0);
 
430
 
429
431
_wr.setUpdating (false);
430
432
 
431
433
    Gtk::Widget const *const widget_array[] = {
432
 
        _rumg->_label,       _rumg->_sel,
433
 
        0,                  _rsu_ox->getSU(),
434
 
        0,                  _rsu_oy->getSU(),
435
 
        0,                  _rsu_sy->getSU(),
 
434
        0,       _rumg,
 
435
        0,                  _rsu_ox,
 
436
        0,                  _rsu_oy,
 
437
        0,                  _rsu_sy,
436
438
        0,                  _rsu_ax,
437
439
        0,                  _rsu_az,
438
440
        _rcp_gcol->_label,   _rcp_gcol,
439
441
        0,                  0,
440
442
        _rcp_gmcol->_label,  _rcp_gmcol,
441
 
        _rsi->_label,        &_rsi->_hbox,
 
443
        0,                   _rsi,
442
444
    };
443
445
 
444
446
    attach_all (*table, widget_array, sizeof(widget_array));
447
449
    _rumg->setUnit (gridunit);
448
450
 
449
451
    gdouble val;
450
 
    val = origin[NR::X];
 
452
    val = origin[Geom::X];
451
453
    val = sp_pixels_get_units (val, *(gridunit));
452
454
    _rsu_ox->setValue (val);
453
 
    val = origin[NR::Y];
 
455
    val = origin[Geom::Y];
454
456
    val = sp_pixels_get_units (val, *(gridunit));
455
457
    _rsu_oy->setValue (val);
456
458
    val = lengthy;
486
488
    _rumg.setUnit (gridunit);
487
489
 
488
490
    gdouble val;
489
 
    val = origin[NR::X];
 
491
    val = origin[Geom::X];
490
492
    val = sp_pixels_get_units (val, *(gridunit));
491
493
    _rsu_ox.setValue (val);
492
 
    val = origin[NR::Y];
 
494
    val = origin[Geom::Y];
493
495
    val = sp_pixels_get_units (val, *(gridunit));
494
496
    _rsu_oy.setValue (val);
495
497
    val = lengthy;
512
514
 
513
515
 
514
516
void
515
 
CanvasAxonomGrid::Update (NR::Matrix const &affine, unsigned int /*flags*/)
 
517
CanvasAxonomGrid::Update (Geom::Matrix const &affine, unsigned int /*flags*/)
516
518
{
517
519
    ow = origin * affine;
518
 
    sw = NR::Point(fabs(affine[0]),fabs(affine[3]));
 
520
    sw = Geom::Point(fabs(affine[0]),fabs(affine[3]));
519
521
 
520
522
    for(int dim = 0; dim < 2; dim++) {
521
523
        gint scaling_factor = empspacing;
536
538
 
537
539
    }
538
540
 
539
 
    spacing_ylines = sw[NR::X] * lengthy  /(tan_angle[X] + tan_angle[Z]);
540
 
    lyw            = sw[NR::Y] * lengthy;
541
 
    lxw_x          = (lengthy / tan_angle[X]) * sw[NR::X];
542
 
    lxw_z          = (lengthy / tan_angle[Z]) * sw[NR::X];
 
541
    spacing_ylines = sw[Geom::X] * lengthy  /(tan_angle[X] + tan_angle[Z]);
 
542
    lyw            = sw[Geom::Y] * lengthy;
 
543
    lxw_x          = (lengthy / tan_angle[X]) * sw[Geom::X];
 
544
    lxw_z          = (lengthy / tan_angle[Z]) * sw[Geom::X];
543
545
 
544
546
    if (empspacing == 0) {
545
547
        scaled = TRUE;
551
553
CanvasAxonomGrid::Render (SPCanvasBuf *buf)
552
554
{
553
555
    //set correct coloring, depending preference (when zoomed out, always major coloring or minor coloring)
 
556
    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
554
557
    guint32 _empcolor;
555
 
    bool preference = prefs_get_int_attribute ("options.grids", "no_emphasize_when_zoomedout", 0) == 1;
 
558
    bool preference = prefs->getBool("/options/grids/no_emphasize_when_zoomedout", false);
556
559
    if( scaled && preference ) {
557
560
        _empcolor = color;
558
561
    } else {
564
567
    // bc = buffer patch coordinates
565
568
 
566
569
    // tl = topleft ; br = bottomright
567
 
    NR::Point buf_tl_gc;
568
 
    NR::Point buf_br_gc;
569
 
    buf_tl_gc[NR::X] = buf->rect.x0 - ow[NR::X];
570
 
    buf_tl_gc[NR::Y] = buf->rect.y0 - ow[NR::Y];
571
 
    buf_br_gc[NR::X] = buf->rect.x1 - ow[NR::X];
572
 
    buf_br_gc[NR::Y] = buf->rect.y1 - ow[NR::Y];
 
570
    Geom::Point buf_tl_gc;
 
571
    Geom::Point buf_br_gc;
 
572
    buf_tl_gc[Geom::X] = buf->rect.x0 - ow[Geom::X];
 
573
    buf_tl_gc[Geom::Y] = buf->rect.y0 - ow[Geom::Y];
 
574
    buf_br_gc[Geom::X] = buf->rect.x1 - ow[Geom::X];
 
575
    buf_br_gc[Geom::Y] = buf->rect.y1 - ow[Geom::Y];
573
576
 
574
577
    gdouble x;
575
578
    gdouble y;
577
580
    // render the three separate line groups representing the main-axes
578
581
 
579
582
    // x-axis always goes from topleft to bottomright. (0,0) - (1,1)
580
 
    gdouble const xintercept_y_bc = (buf_tl_gc[NR::X] * tan_angle[X]) - buf_tl_gc[NR::Y] ;
 
583
    gdouble const xintercept_y_bc = (buf_tl_gc[Geom::X] * tan_angle[X]) - buf_tl_gc[Geom::Y] ;
581
584
    gdouble const xstart_y_sc = ( xintercept_y_bc - floor(xintercept_y_bc/lyw)*lyw ) + buf->rect.y0;
582
 
    gint const xlinestart = (gint) Inkscape::round( (xstart_y_sc - buf->rect.x0*tan_angle[X] -ow[NR::Y]) / lyw );
 
585
    gint const xlinestart = (gint) Inkscape::round( (xstart_y_sc - buf->rect.x0*tan_angle[X] -ow[Geom::Y]) / lyw );
583
586
    gint xlinenum = xlinestart;
584
587
    // lines starting on left side.
585
588
    for (y = xstart_y_sc; y < buf->rect.y1; y += lyw, xlinenum++) {
611
614
    }
612
615
 
613
616
    // y-axis lines (vertical)
614
 
    gdouble const ystart_x_sc = floor (buf_tl_gc[NR::X] / spacing_ylines) * spacing_ylines + ow[NR::X];
615
 
    gint const  ylinestart = (gint) Inkscape::round((ystart_x_sc - ow[NR::X]) / spacing_ylines);
 
617
    gdouble const ystart_x_sc = floor (buf_tl_gc[Geom::X] / spacing_ylines) * spacing_ylines + ow[Geom::X];
 
618
    gint const  ylinestart = (gint) Inkscape::round((ystart_x_sc - ow[Geom::X]) / spacing_ylines);
616
619
    gint ylinenum = ylinestart;
617
620
    for (x = ystart_x_sc; x < buf->rect.x1; x += spacing_ylines, ylinenum++) {
618
621
        gint const x0 = (gint) Inkscape::round(x);
625
628
    }
626
629
 
627
630
    // z-axis always goes from bottomleft to topright. (0,1) - (1,0)
628
 
    gdouble const zintercept_y_bc = (buf_tl_gc[NR::X] * -tan_angle[Z]) - buf_tl_gc[NR::Y] ;
 
631
    gdouble const zintercept_y_bc = (buf_tl_gc[Geom::X] * -tan_angle[Z]) - buf_tl_gc[Geom::Y] ;
629
632
    gdouble const zstart_y_sc = ( zintercept_y_bc - floor(zintercept_y_bc/lyw)*lyw ) + buf->rect.y0;
630
 
    gint const  zlinestart = (gint) Inkscape::round( (zstart_y_sc + buf->rect.x0*tan_angle[Z] - ow[NR::Y]) / lyw );
 
633
    gint const  zlinestart = (gint) Inkscape::round( (zstart_y_sc + buf->rect.x0*tan_angle[Z] - ow[Geom::Y]) / lyw );
631
634
    gint zlinenum = zlinestart;
632
635
    // lines starting from left side
633
636
    for (y = zstart_y_sc; y < buf->rect.y1; y += lyw, zlinenum++) {
658
661
    }
659
662
}
660
663
 
661
 
CanvasAxonomGridSnapper::CanvasAxonomGridSnapper(CanvasAxonomGrid *grid, SPNamedView const *nv, NR::Coord const d) : LineSnapper(nv, d)
 
664
CanvasAxonomGridSnapper::CanvasAxonomGridSnapper(CanvasAxonomGrid *grid, SnapManager *sm, Geom::Coord const d) : LineSnapper(sm, d)
662
665
{
663
666
    this->grid = grid;
664
667
}
665
668
 
 
669
/**
 
670
 *  \return Snap tolerance (desktop coordinates); depends on current zoom so that it's always the same in screen pixels
 
671
 */
 
672
Geom::Coord CanvasAxonomGridSnapper::getSnapperTolerance() const
 
673
{
 
674
        SPDesktop const *dt = _snapmanager->getDesktop();
 
675
        double const zoom =  dt ? dt->current_zoom() : 1;
 
676
        return _snapmanager->snapprefs.getGridTolerance() / zoom;
 
677
}
 
678
 
 
679
bool CanvasAxonomGridSnapper::getSnapperAlwaysSnap() const
 
680
{
 
681
    return _snapmanager->snapprefs.getGridTolerance() == 10000; //TODO: Replace this threshold of 10000 by a constant; see also tolerance-slider.cpp
 
682
}
 
683
 
666
684
LineSnapper::LineList
667
 
CanvasAxonomGridSnapper::_getSnapLines(NR::Point const &p) const
 
685
CanvasAxonomGridSnapper::_getSnapLines(Geom::Point const &p) const
668
686
{
669
687
    LineList s;
670
688
 
672
690
        return s;
673
691
    }
674
692
 
675
 
    /* This is to make sure we snap to only visible grid lines */
676
 
    double scaled_spacing_h = grid->spacing_ylines; // this is spacing of visible lines if screen pixels
677
 
    double scaled_spacing_v = grid->lyw; // vertical
678
 
 
679
 
    // convert screen pixels to px
680
 
    // FIXME: after we switch to snapping dist in screen pixels, this will be unnecessary
681
 
    if (SP_ACTIVE_DESKTOP) {
682
 
        scaled_spacing_h /= SP_ACTIVE_DESKTOP->current_zoom();
683
 
        scaled_spacing_v /= SP_ACTIVE_DESKTOP->current_zoom();
684
 
    }
 
693
    double spacing_h;
 
694
    double spacing_v;
 
695
 
 
696
    if (getSnapVisibleOnly()) {
 
697
                // Only snapping to visible grid lines
 
698
                spacing_h = grid->spacing_ylines; // this is the spacing of the visible grid lines measured in screen pixels
 
699
                spacing_v = grid->lyw; // vertical
 
700
                // convert screen pixels to px
 
701
                // FIXME: after we switch to snapping dist in screen pixels, this will be unnecessary
 
702
                SPDesktop const *dt = _snapmanager->getDesktop();
 
703
                if (dt) {
 
704
                        spacing_h /= dt->current_zoom();
 
705
                        spacing_v /= dt->current_zoom();
 
706
                }
 
707
        } else {
 
708
                // Snapping to any grid line, whether it's visible or not
 
709
                spacing_h = grid->lengthy  /(grid->tan_angle[X] + grid->tan_angle[Z]);
 
710
                spacing_v = grid->lengthy;
 
711
 
 
712
        }
685
713
 
686
714
    // In an axonometric grid, any point will be surrounded by 6 grid lines:
687
715
    // - 2 vertical grid lines, one left and one right from the point
688
716
    // - 2 angled z grid lines, one above and one below the point
689
717
    // - 2 angled x grid lines, one above and one below the point
690
 
    
 
718
 
691
719
    // Calculate the x coordinate of the vertical grid lines
692
 
    NR::Coord x_max = Inkscape::Util::round_to_upper_multiple_plus(p[NR::X], scaled_spacing_h, grid->origin[NR::X]);
693
 
    NR::Coord x_min = Inkscape::Util::round_to_lower_multiple_plus(p[NR::X], scaled_spacing_h, grid->origin[NR::X]);
694
 
    
 
720
    Geom::Coord x_max = Inkscape::Util::round_to_upper_multiple_plus(p[Geom::X], spacing_h, grid->origin[Geom::X]);
 
721
    Geom::Coord x_min = Inkscape::Util::round_to_lower_multiple_plus(p[Geom::X], spacing_h, grid->origin[Geom::X]);
 
722
 
695
723
    // Calculate the y coordinate of the intersection of the angled grid lines with the y-axis
696
 
    double y_proj_along_z = p[NR::Y] - grid->tan_angle[Z]*(p[NR::X] - grid->origin[NR::X]);  
697
 
    double y_proj_along_x = p[NR::Y] + grid->tan_angle[X]*(p[NR::X] - grid->origin[NR::X]);    
698
 
    double y_proj_along_z_max = Inkscape::Util::round_to_upper_multiple_plus(y_proj_along_z, scaled_spacing_v, grid->origin[NR::Y]);
699
 
    double y_proj_along_z_min = Inkscape::Util::round_to_lower_multiple_plus(y_proj_along_z, scaled_spacing_v, grid->origin[NR::Y]);    
700
 
    double y_proj_along_x_max = Inkscape::Util::round_to_upper_multiple_plus(y_proj_along_x, scaled_spacing_v, grid->origin[NR::Y]);
701
 
    double y_proj_along_x_min = Inkscape::Util::round_to_lower_multiple_plus(y_proj_along_x, scaled_spacing_v, grid->origin[NR::Y]);
702
 
    
 
724
    double y_proj_along_z = p[Geom::Y] - grid->tan_angle[Z]*(p[Geom::X] - grid->origin[Geom::X]);
 
725
    double y_proj_along_x = p[Geom::Y] + grid->tan_angle[X]*(p[Geom::X] - grid->origin[Geom::X]);
 
726
    double y_proj_along_z_max = Inkscape::Util::round_to_upper_multiple_plus(y_proj_along_z, spacing_v, grid->origin[Geom::Y]);
 
727
    double y_proj_along_z_min = Inkscape::Util::round_to_lower_multiple_plus(y_proj_along_z, spacing_v, grid->origin[Geom::Y]);
 
728
    double y_proj_along_x_max = Inkscape::Util::round_to_upper_multiple_plus(y_proj_along_x, spacing_v, grid->origin[Geom::Y]);
 
729
    double y_proj_along_x_min = Inkscape::Util::round_to_lower_multiple_plus(y_proj_along_x, spacing_v, grid->origin[Geom::Y]);
 
730
 
 
731
    // Calculate the versor for the angled grid lines
 
732
    Geom::Point vers_x = Geom::Point(1, -grid->tan_angle[X]);
 
733
    Geom::Point vers_z = Geom::Point(1, grid->tan_angle[Z]);
 
734
 
703
735
    // Calculate the normal for the angled grid lines
704
 
    NR::Point norm_x = NR::rot90(NR::Point(1, -grid->tan_angle[X]));
705
 
    NR::Point norm_z = NR::rot90(NR::Point(1, grid->tan_angle[Z]));
706
 
    
707
 
    // The four angled grid lines form a parallellogram, enclosing the point
708
 
    // One of the two vertical grid lines divides this parallellogram in two triangles
709
 
    // We will now try to find out in which half (i.e. triangle) our point is, and return 
710
 
    // only the three grid lines defining that triangle 
711
 
    
712
 
    // The vertical grid line is at the intersection of two angled grid lines. 
 
736
    Geom::Point norm_x = Geom::rot90(vers_x);
 
737
    Geom::Point norm_z = Geom::rot90(vers_z);
 
738
 
 
739
    // The four angled grid lines form a parallelogram, enclosing the point
 
740
    // One of the two vertical grid lines divides this parallelogram in two triangles
 
741
    // We will now try to find out in which half (i.e. triangle) our point is, and return
 
742
    // only the three grid lines defining that triangle
 
743
 
 
744
    // The vertical grid line is at the intersection of two angled grid lines.
713
745
    // Now go find that intersection!
714
 
    Geom::Point result;
715
 
    Geom::IntersectorKind is = line_intersection(norm_x.to_2geom(), norm_x[NR::Y]*y_proj_along_x_max,
716
 
                                           norm_z.to_2geom(), norm_z[NR::Y]*y_proj_along_z_max,
717
 
                                           result);
718
 
                         
719
 
    // Determine which half of the parallellogram to use 
 
746
    Geom::Point p_x(0, y_proj_along_x_max);
 
747
    Geom::Line line_x(p_x, p_x + vers_x);
 
748
    Geom::Point p_z(0, y_proj_along_z_max);
 
749
        Geom::Line line_z(p_z, p_z + vers_z);
 
750
 
 
751
    Geom::OptCrossing inters = Geom::OptCrossing(); // empty by default
 
752
        try
 
753
        {
 
754
                inters = Geom::intersection(line_x, line_z);
 
755
        }
 
756
        catch (Geom::InfiniteSolutions e)
 
757
        {
 
758
                // We're probably dealing with parallel lines; this is useless!
 
759
                return s;
 
760
        }
 
761
 
 
762
    // Determine which half of the parallelogram to use
720
763
    bool use_left_half = true;
721
764
    bool use_right_half = true;
722
 
    
723
 
    if (is == Geom::intersects) {
724
 
        use_left_half = (p[NR::X] - grid->origin[NR::X]) < result[Geom::X];
725
 
        use_right_half = !use_left_half; 
 
765
 
 
766
    if (inters) {
 
767
        Geom::Point inters_pt = line_x.pointAt((*inters).ta);
 
768
        use_left_half = (p[Geom::X] - grid->origin[Geom::X]) < inters_pt[Geom::X];
 
769
        use_right_half = !use_left_half;
726
770
    }
727
 
    
728
 
    //std::cout << "intersection at " << result << " leads to use_left_half = " << use_left_half << " and use_right_half = " << use_right_half << std::endl;
729
 
       
 
771
 
730
772
    // Return the three grid lines which define the triangle that encloses our point
731
773
    // If we didn't find an intersection above, all 6 grid lines will be returned
732
774
    if (use_left_half) {
733
 
        s.push_back(std::make_pair(norm_z, NR::Point(grid->origin[NR::X], y_proj_along_z_max)));
734
 
        s.push_back(std::make_pair(norm_x, NR::Point(grid->origin[NR::X], y_proj_along_x_min)));
735
 
        s.push_back(std::make_pair(component_vectors[NR::X], NR::Point(x_max, 0)));            
 
775
        s.push_back(std::make_pair(norm_z, Geom::Point(grid->origin[Geom::X], y_proj_along_z_max)));
 
776
        s.push_back(std::make_pair(norm_x, Geom::Point(grid->origin[Geom::X], y_proj_along_x_min)));
 
777
        s.push_back(std::make_pair(component_vectors[Geom::X], Geom::Point(x_max, 0)));
736
778
    }
737
 
    
 
779
 
738
780
    if (use_right_half) {
739
 
        s.push_back(std::make_pair(norm_z, NR::Point(grid->origin[NR::X], y_proj_along_z_min)));
740
 
        s.push_back(std::make_pair(norm_x, NR::Point(grid->origin[NR::X], y_proj_along_x_max)));
741
 
        s.push_back(std::make_pair(component_vectors[NR::X], NR::Point(x_min, 0)));        
742
 
    } 
743
 
    
 
781
        s.push_back(std::make_pair(norm_z, Geom::Point(grid->origin[Geom::X], y_proj_along_z_min)));
 
782
        s.push_back(std::make_pair(norm_x, Geom::Point(grid->origin[Geom::X], y_proj_along_x_max)));
 
783
        s.push_back(std::make_pair(component_vectors[Geom::X], Geom::Point(x_min, 0)));
 
784
    }
 
785
 
744
786
    return s;
745
787
}
746
788
 
747
 
void CanvasAxonomGridSnapper::_addSnappedLine(SnappedConstraints &sc, NR::Point const snapped_point, NR::Coord const snapped_distance, NR::Point const normal_to_line, NR::Point const point_on_line) const 
 
789
void CanvasAxonomGridSnapper::_addSnappedLine(SnappedConstraints &sc, Geom::Point const snapped_point, Geom::Coord const snapped_distance, SnapSourceType const &source, Geom::Point const normal_to_line, Geom::Point const point_on_line) const
748
790
{
749
 
    SnappedLine dummy = SnappedLine(snapped_point, snapped_distance, getSnapperTolerance(), getSnapperAlwaysSnap(), normal_to_line, point_on_line);
 
791
    SnappedLine dummy = SnappedLine(snapped_point, snapped_distance, source, Inkscape::SNAPTARGET_GRID, getSnapperTolerance(), getSnapperAlwaysSnap(), normal_to_line, point_on_line);
750
792
    sc.grid_lines.push_back(dummy);
751
793
}
752
794
 
 
795
void CanvasAxonomGridSnapper::_addSnappedPoint(SnappedConstraints &sc, Geom::Point const snapped_point, Geom::Coord const snapped_distance, SnapSourceType const &source) const
 
796
{
 
797
        SnappedPoint dummy = SnappedPoint(snapped_point, source, Inkscape::SNAPTARGET_GRID, snapped_distance, getSnapperTolerance(), getSnapperAlwaysSnap(), true);
 
798
        sc.points.push_back(dummy);
 
799
}
 
800
 
 
801
bool CanvasAxonomGridSnapper::ThisSnapperMightSnap() const
 
802
{
 
803
    return _snap_enabled && _snapmanager->snapprefs.getSnapToGrids() && _snapmanager->snapprefs.getSnapModeBBoxOrNodes();
 
804
}
753
805
 
754
806
 
755
807
}; // namespace Inkscape