~centralelyon2010/inkscape/imagelinks2

« back to all changes in this revision

Viewing changes to src/helper/png-write.cpp

  • Committer: Ted Gould
  • Date: 2008-11-21 05:24:08 UTC
  • Revision ID: ted@canonical.com-20081121052408-tilucis2pjrrpzxx
MergeĀ fromĀ fe-moved

Show diffs side-by-side

added added

removed removed

Lines of Context:
19
19
#include <interface.h>
20
20
#include <libnr/nr-pixops.h>
21
21
#include <libnr/nr-translate-scale-ops.h>
 
22
#include <2geom/rect.h>
22
23
#include <glib/gmessages.h>
23
24
#include <png.h>
24
25
#include "png-write.h"
386
387
 *
387
388
 * \return true if succeeded (or if no action was taken), false if an error occurred.
388
389
 */
 
390
bool sp_export_png_file (SPDocument *doc, gchar const *filename,
 
391
                   double x0, double y0, double x1, double y1,
 
392
                   unsigned long int width, unsigned long int height, double xdpi, double ydpi,
 
393
                   unsigned long bgcolor,
 
394
                   unsigned int (*status) (float, void *),
 
395
                   void *data, bool force_overwrite,
 
396
                   GSList *items_only)
 
397
{
 
398
    return sp_export_png_file(doc, filename, Geom::Rect(Geom::Point(x0,y0),Geom::Point(x1,y1)),
 
399
                              width, height, xdpi, ydpi, bgcolor, status, data, force_overwrite, items_only);
 
400
}
389
401
bool
390
402
sp_export_png_file(SPDocument *doc, gchar const *filename,
391
 
                   double x0, double y0, double x1, double y1,
 
403
                   Geom::Rect const &area,
392
404
                   unsigned long width, unsigned long height, double xdpi, double ydpi,
393
405
                   unsigned long bgcolor,
394
406
                   unsigned (*status)(float, void *),
399
411
    g_return_val_if_fail(filename != NULL, false);
400
412
    g_return_val_if_fail(width >= 1, false);
401
413
    g_return_val_if_fail(height >= 1, false);
402
 
 
403
 
    if (!force_overwrite && !sp_ui_overwrite_file(filename)) {
 
414
    g_return_val_if_fail(!area.hasZeroArea(), false);
 
415
 
 
416
    //Make relative paths absolute, if possible:
 
417
    gchar *path = 0;
 
418
    if (!g_path_is_absolute(filename) && doc->uri) {
 
419
        gchar *dirname = g_path_get_dirname(doc->uri);
 
420
        if (dirname) {
 
421
            path = g_build_filename(dirname, filename, NULL);
 
422
            g_free(dirname);
 
423
        }
 
424
    }
 
425
    if (!path) {
 
426
        path = g_strdup(filename);
 
427
    }
 
428
 
 
429
    if (!force_overwrite && !sp_ui_overwrite_file(path)) {
404
430
        /* Remark: We return true so as not to invoke an error dialog in case export is cancelled
405
431
           by the user; currently this is safe because the callers only act when false is returned.
406
432
           If this changes in the future we need better distinction of return types (e.g., use int)
417
443
 
418
444
    sp_document_ensure_up_to_date(doc);
419
445
 
420
 
    /* Go to document coordinates */
421
 
    {
422
 
        gdouble const t = y0;
423
 
        y0 = sp_document_height(doc) - y1;
424
 
        y1 = sp_document_height(doc) - t;
425
 
    }
 
446
    /* Calculate translation by transforming to document coordinates (flipping Y)*/
 
447
    Geom::Point translation = Geom::Point(-area[Geom::X][0], area[Geom::Y][1] - sp_document_height(doc));
426
448
 
427
 
    /*
 
449
    /*  This calculation is only valid when assumed that (x0,y0)= area.corner(0) and (x1,y1) = area.corner(2)
428
450
     * 1) a[0] * x0 + a[2] * y1 + a[4] = 0.0
429
451
     * 2) a[1] * x0 + a[3] * y1 + a[5] = 0.0
430
452
     * 3) a[0] * x1 + a[2] * y1 + a[4] = width
440
462
     * (2) a[5] = -a[3] * y1
441
463
     */
442
464
 
443
 
    Geom::Matrix const affine(Geom::Translate(-x0, -y0)
444
 
                            * Geom::Scale(width / (x1 - x0),
445
 
                                        height / (y1 - y0)));
 
465
    Geom::Matrix const affine(Geom::Translate(translation)
 
466
                            * Geom::Scale(width / area.width(),
 
467
                                        height / area.height()));
446
468
 
447
469
    //SP_PRINT_MATRIX("SVG2PNG", &affine);
448
470
 
475
497
    if ((width < 256) || ((width * height) < 32768)) {
476
498
        ebp.px = nr_pixelstore_64K_new(FALSE, 0);
477
499
        ebp.sheight = 65536 / (4 * width);
478
 
        write_status = sp_png_write_rgba_striped(doc, filename, width, height, xdpi, ydpi, sp_export_get_rows, &ebp);
 
500
        write_status = sp_png_write_rgba_striped(doc, path, width, height, xdpi, ydpi, sp_export_get_rows, &ebp);
479
501
        nr_pixelstore_64K_free(ebp.px);
480
502
    } else {
481
503
        ebp.px = g_new(guchar, 4 * 64 * width);
482
504
        ebp.sheight = 64;
483
 
        write_status = sp_png_write_rgba_striped(doc, filename, width, height, xdpi, ydpi, sp_export_get_rows, &ebp);
 
505
        write_status = sp_png_write_rgba_striped(doc, path, width, height, xdpi, ydpi, sp_export_get_rows, &ebp);
484
506
        g_free(ebp.px);
485
507
    }
486
508
 
494
516
    prefs->setInt("/options/blurquality/value", saved_quality);
495
517
    prefs->setInt("/options/filterquality/value", saved_filter_quality);
496
518
 
 
519
    g_free(path);
 
520
 
497
521
    return write_status;
498
522
}
499
523