~ubuntu-branches/ubuntu/karmic/photoprint/karmic

« back to all changes in this revision

Viewing changes to layout.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Milan Zamazal
  • Date: 2007-05-01 16:32:13 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20070501163213-ni1933khtg9fdvn5
Tags: 0.3.5-2
Move to unstable.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * layout.cpp - A superclass for layouts.
3
 
 *
4
 
 * Copyright (c) 2004 by Alastair M. Robinson
5
 
 * Distributed under the terms of the GNU General Public License -
6
 
 * see the file named "COPYING" for more details.
7
 
 *
8
 
 */
9
 
 
10
 
#include <iostream>
11
 
#include <string.h>
12
 
 
13
 
#include "dialogs.h"
14
 
#include "support/generaldialogs.h"
15
 
#include "pixbufthumbnail/egg-pixbuf-thumbnail.h"
16
 
#include "imagesource/pixbuf_from_imagesource.h"
17
 
#include "support/rotatepixbuf.h"
18
 
#include "support/maskpixbuf.h"
19
 
 
 
1
/*
 
2
 * layout.cpp - A superclass for layouts.
 
3
 *
 
4
 * Copyright (c) 2004 by Alastair M. Robinson
 
5
 * Distributed under the terms of the GNU General Public License -
 
6
 * see the file named "COPYING" for more details.
 
7
 *
 
8
 */
 
9
 
 
10
#include <iostream>
 
11
#include <string.h>
 
12
 
 
13
#include "dialogs.h"
 
14
#include "support/generaldialogs.h"
 
15
#include "pixbufthumbnail/egg-pixbuf-thumbnail.h"
 
16
#include "imagesource/pixbuf_from_imagesource.h"
 
17
#include "support/rotatepixbuf.h"
 
18
#include "support/maskpixbuf.h"
 
19
 
20
20
#include "imagesource/imagesource.h"
21
 
#include "imagesource/imagesource_gdkpixbuf.h"
22
 
#include "imagesource/imagesource_cms.h"
23
 
#include "imagesource/imagesource_util.h"
24
 
#include "imagesource/imagesource_mask.h"
25
 
#include "imagesource/imagesource_rotate.h"
26
 
#include "imagesource/imagesource_promote.h"
27
 
 
28
 
#include "photoprint_state.h"
29
 
#include "support/progress.h"
30
 
#include "util.h"
31
 
#include "support/layoutrectangle.h"
32
 
 
33
 
#include "layout.h"
34
 
 
35
 
using namespace std;
36
 
 
37
 
 
38
 
ConfigTemplate LayoutDB::Template[]=
39
 
{
40
 
        ConfigTemplate("LayoutType","NUp"),
41
 
        ConfigTemplate()
42
 
};
43
 
 
44
 
 
45
 
Layout_ImageInfo::Layout_ImageInfo(Layout &layout, const char *filename, int page, bool allowcropping, PP_ROTATION rotation)
46
 
        : page(page), allowcropping(allowcropping), crop_hpan(CENTRE), crop_vpan(CENTRE),
47
 
        rotation(rotation), layout(layout), maskfilename(NULL), thumbnail(NULL), mask(NULL), transformed(NULL), selected(false),
48
 
        customprofile(NULL), customintent(INTENT_DEFAULT)
49
 
{
50
 
        bool relative=true;
51
 
 
52
 
        if(filename[0]=='/' || filename[1]==':')
53
 
                relative=false;
54
 
 
55
 
        if(filename[0]=='\\' && filename[1]=='\\')
56
 
                relative=false;
57
 
 
58
 
        if(relative)
59
 
                this->filename=BuildAbsoluteFilename(filename);
60
 
        else
61
 
                this->filename=strdup(filename);
62
 
 
63
 
        GetThumbnail();
64
 
}
65
 
 
66
 
 
67
 
Layout_ImageInfo::Layout_ImageInfo(Layout &layout, Layout_ImageInfo *ii, int page, bool allowcropping, PP_ROTATION rotation)
68
 
        : page(page), allowcropping(allowcropping), crop_hpan(CENTRE), crop_vpan(CENTRE),
69
 
        rotation(rotation), layout(layout), maskfilename(NULL), thumbnail(NULL), mask(NULL), transformed(NULL), selected(false),
70
 
        customprofile(NULL), customintent(INTENT_DEFAULT)
71
 
{
72
 
        cerr << "Stealing existing image!" << endl;
73
 
 
74
 
        if(ii)
75
 
        {
76
 
                thumbnail=ii->thumbnail;
77
 
                ii->thumbnail=NULL;  // We steal the thumbnail from the old image!
78
 
                mask=ii->mask;
79
 
                ii->mask=NULL;  // And the mask too!
 
21
#include "imagesource/imagesource_gdkpixbuf.h"
 
22
#include "imagesource/imagesource_cms.h"
 
23
#include "imagesource/imagesource_util.h"
 
24
#include "imagesource/imagesource_mask.h"
 
25
#include "imagesource/imagesource_rotate.h"
 
26
#include "imagesource/imagesource_promote.h"
 
27
 
 
28
#include "photoprint_state.h"
 
29
#include "support/progress.h"
 
30
#include "util.h"
 
31
#include "support/layoutrectangle.h"
 
32
 
 
33
#include "layout.h"
 
34
 
 
35
using namespace std;
 
36
 
 
37
 
 
38
ConfigTemplate LayoutDB::Template[]=
 
39
{
 
40
        ConfigTemplate("LayoutType","NUp"),
 
41
        ConfigTemplate()
 
42
};
 
43
 
 
44
 
 
45
Layout_ImageInfo::Layout_ImageInfo(Layout &layout, const char *filename, int page, bool allowcropping, PP_ROTATION rotation)
 
46
        : PPEffectHeader(), page(page), allowcropping(allowcropping), crop_hpan(CENTRE), crop_vpan(CENTRE),
 
47
        rotation(rotation), layout(layout), maskfilename(NULL), thumbnail(NULL), mask(NULL), transformed(NULL), selected(false),
 
48
        customprofile(NULL), customintent(LCMSWRAPPER_INTENT_DEFAULT)
 
49
{
 
50
        bool relative=true;
 
51
 
 
52
        if(filename[0]=='/' || filename[1]==':')
 
53
                relative=false;
 
54
 
 
55
        if(filename[0]=='\\' && filename[1]=='\\')
 
56
                relative=false;
 
57
 
 
58
        if(relative)
 
59
                this->filename=BuildAbsoluteFilename(filename);
 
60
        else
 
61
                this->filename=strdup(filename);
 
62
 
 
63
        GetThumbnail();
 
64
}
 
65
 
 
66
 
 
67
Layout_ImageInfo::Layout_ImageInfo(Layout &layout, Layout_ImageInfo *ii, int page, bool allowcropping, PP_ROTATION rotation)
 
68
        : PPEffectHeader(), page(page), allowcropping(allowcropping), crop_hpan(CENTRE), crop_vpan(CENTRE),
 
69
        rotation(rotation), layout(layout), maskfilename(NULL), thumbnail(NULL), mask(NULL), transformed(NULL), selected(false),
 
70
        customprofile(NULL), customintent(LCMSWRAPPER_INTENT_DEFAULT)
 
71
{
 
72
        cerr << "Stealing existing image!" << endl;
 
73
 
 
74
        if(ii)
 
75
        {
 
76
                thumbnail=ii->thumbnail;
 
77
                ii->thumbnail=NULL;  // We steal the thumbnail from the old image!
 
78
                mask=ii->mask;
 
79
                ii->mask=NULL;  // And the mask too!
80
80
 
81
81
                customprofile=ii->customprofile;
82
82
                ii->customprofile=NULL; // And the custom profile!
83
83
                
84
84
                customintent=ii->customintent;
85
 
        
86
 
                if(ii->filename)
87
 
                        this->filename=strdup(ii->filename);
88
 
                if(ii->maskfilename)
89
 
                        this->maskfilename=strdup(ii->maskfilename);
90
 
 
91
 
                allowcropping=ii->allowcropping;
92
 
                crop_hpan=ii->crop_hpan;
93
 
                crop_vpan=ii->crop_vpan;
94
 
                rotation=ii->rotation;
95
 
        }
96
 
}
97
 
 
98
 
 
99
 
Layout_ImageInfo::~Layout_ImageInfo()
100
 
{
101
 
        if(thumbnail)
102
 
                g_object_unref(thumbnail);
103
 
        if(mask)
104
 
                g_object_unref(mask);
105
 
        if(transformed)
106
 
                g_object_unref(transformed);
107
 
        layout.imagelist=g_list_remove(layout.imagelist,this);
 
85
        
 
86
                if(ii->filename)
 
87
                        this->filename=strdup(ii->filename);
 
88
                if(ii->maskfilename)
 
89
                        this->maskfilename=strdup(ii->maskfilename);
 
90
 
 
91
                allowcropping=ii->allowcropping;
 
92
                crop_hpan=ii->crop_hpan;
 
93
                crop_vpan=ii->crop_vpan;
 
94
                rotation=ii->rotation;
 
95
        }
 
96
}
 
97
 
 
98
 
 
99
Layout_ImageInfo::~Layout_ImageInfo()
 
100
{
 
101
        if(thumbnail)
 
102
                g_object_unref(thumbnail);
 
103
        if(mask)
 
104
                g_object_unref(mask);
 
105
        if(transformed)
 
106
                g_object_unref(transformed);
 
107
        layout.imagelist=g_list_remove(layout.imagelist,this);
108
108
        if(customprofile)
109
109
                free(customprofile);
110
 
        free(filename);
111
 
}
112
 
 
113
 
 
114
 
void Layout_ImageInfo::DrawThumbnail(GtkWidget *widget,int xpos,int ypos,int width,int height)
115
 
{
116
 
        GdkPixbuf *thumbnail=GetThumbnail();
117
 
 
118
 
        if(transformed)
119
 
                g_object_unref(transformed);
120
 
        transformed=NULL;
121
 
        
122
 
        LayoutRectangle r(gdk_pixbuf_get_width(thumbnail),gdk_pixbuf_get_height(thumbnail));
123
 
        LayoutRectangle target(xpos,ypos,width,height);
124
 
 
125
 
        RectFit *fit=r.Fit(target,allowcropping,rotation,crop_hpan,crop_vpan);
126
 
 
127
 
        cerr << "Scaling thumbnail" << endl;
128
 
 
129
 
        GdkPixbuf *tmp;
130
 
        switch(fit->rotation)
131
 
        {
132
 
                case 0:
133
 
                        transformed=gdk_pixbuf_scale_simple(thumbnail,fit->width,fit->height,GDK_INTERP_NEAREST);
134
 
                        break;
135
 
                case 270:
136
 
                        tmp=gdk_pixbuf_rotate_simple(thumbnail,GDK_PIXBUF_ROTATE_CLOCKWISE);
137
 
                        transformed=gdk_pixbuf_scale_simple(tmp,fit->width,fit->height,GDK_INTERP_NEAREST);
138
 
                        g_object_unref(G_OBJECT(tmp));
139
 
                        break;
140
 
                case 180:
141
 
                        tmp=gdk_pixbuf_rotate_simple(thumbnail,GDK_PIXBUF_ROTATE_UPSIDEDOWN);
142
 
                        transformed=gdk_pixbuf_scale_simple(tmp,fit->width,fit->height,GDK_INTERP_NEAREST);
143
 
                        g_object_unref(G_OBJECT(tmp));
144
 
                        break;
145
 
                case 90:
146
 
                        tmp=gdk_pixbuf_rotate_simple(thumbnail,GDK_PIXBUF_ROTATE_COUNTERCLOCKWISE);
147
 
                        transformed=gdk_pixbuf_scale_simple(tmp,fit->width,fit->height,GDK_INTERP_NEAREST);
148
 
                        g_object_unref(G_OBJECT(tmp));
149
 
                        break;
150
 
        }
151
 
 
152
 
        int dw=fit->width;
153
 
        int dh=fit->height;
154
 
        
155
 
        if(dw > width)
156
 
                dw=width;
157
 
 
158
 
        if(dh > height)
159
 
                dh=height;
160
 
        
161
 
        if(dw>gdk_pixbuf_get_width(transformed))
162
 
        {
163
 
                cerr << "DW too high" << endl;
164
 
                dw=gdk_pixbuf_get_width(transformed);
165
 
        }
166
 
 
167
 
        if(dh>gdk_pixbuf_get_height(transformed))
168
 
        {
169
 
                cerr << "DH too high" << endl;
170
 
                dh=gdk_pixbuf_get_height(transformed);
171
 
        }
172
 
 
173
 
        cerr << "Done - drawing..." << endl;
174
 
        
175
 
        if(mask)
176
 
                maskpixbuf(transformed,fit->xoffset,fit->yoffset,dw,dh,mask);
177
 
 
178
 
        gdk_draw_pixbuf(widget->window,NULL,transformed,
179
 
                fit->xoffset,fit->yoffset,
180
 
                fit->xpos,fit->ypos,
181
 
                dw,dh,
182
 
                GDK_RGB_DITHER_NONE,0,0);
183
 
 
184
 
        cerr << "Done" << endl;
185
 
 
186
 
        delete fit;
187
 
}
188
 
 
189
 
 
190
 
void Layout_ImageInfo::SetMask(const char *filename)
191
 
{
192
 
        if(mask)
193
 
        {
194
 
                g_object_unref(mask);
195
 
                mask=NULL;
196
 
        }
197
 
        if(maskfilename)
198
 
        {
199
 
                free(maskfilename);
200
 
                maskfilename=NULL;
201
 
        }
202
 
        if(filename)
203
 
                maskfilename=strdup(filename);
204
 
}
205
 
 
206
 
 
207
 
GdkPixbuf *Layout_ImageInfo::GetThumbnail()
208
 
{
209
 
        GError *err=NULL;
210
 
 
211
 
        if(layout.state.batchmode)
212
 
                return(NULL);
213
 
 
214
 
        if(maskfilename && !mask)
215
 
        {
216
 
                mask=egg_pixbuf_get_thumbnail_for_file (maskfilename, EGG_PIXBUF_THUMBNAIL_LARGE, &err);
217
 
                cerr << "Attempting to load mask from: " << maskfilename << endl;
218
 
                if(!mask)
219
 
                {
220
 
                        cerr << "Failed." << endl;
221
 
                        try
222
 
                        {
223
 
                                ImageSource *src=ISLoadImage(maskfilename);
224
 
                                if(src)
225
 
                                {
226
 
                                        int w,h;
227
 
                                        w=(src->width*256)/src->height;
228
 
                                        h=256;
229
 
                                        if(w>256)
230
 
                                        {
231
 
                                                w=256;
232
 
                                                h=(src->height*256)/src->width;
233
 
                                        }
234
 
                                        src=ISScaleImageBySize(src,w,h,IS_SCALING_NEARESTNEIGHBOUR);
235
 
                                        mask=pixbuf_from_imagesource(src);
236
 
                                        delete src;
237
 
                                }
238
 
                        }
239
 
                        catch(const char *err)
240
 
                        {
241
 
                                cerr << "Error: " << err << endl;
242
 
                        }       
243
 
                        if(!mask)
244
 
                        {
245
 
                                if(err && err->message)
246
 
                                        cerr << "Error: " << err->message << endl;
247
 
                                else
248
 
                                        cerr << "Can't get mask thumbnail" << endl;
249
 
                                free(maskfilename);
250
 
                                maskfilename=NULL;
251
 
                        }
252
 
                }
253
 
        }
254
 
 
255
 
        if(thumbnail)
256
 
                return(thumbnail);
 
110
        free(filename);
 
111
}
 
112
 
 
113
 
 
114
void Layout_ImageInfo::DrawThumbnail(GtkWidget *widget,int xpos,int ypos,int width,int height)
 
115
{
 
116
        GdkPixbuf *thumbnail=GetThumbnail();
 
117
 
 
118
        if(transformed)
 
119
                g_object_unref(transformed);
 
120
        transformed=NULL;
 
121
        
 
122
        LayoutRectangle r(gdk_pixbuf_get_width(thumbnail),gdk_pixbuf_get_height(thumbnail));
 
123
        LayoutRectangle target(xpos,ypos,width,height);
 
124
 
 
125
        RectFit *fit=r.Fit(target,allowcropping,rotation,crop_hpan,crop_vpan);
 
126
 
 
127
        GdkPixbuf *tmp;
 
128
        switch(fit->rotation)
 
129
        {
 
130
                case 0:
 
131
                        transformed=gdk_pixbuf_scale_simple(thumbnail,fit->width,fit->height,GDK_INTERP_NEAREST);
 
132
                        break;
 
133
                case 270:
 
134
                        tmp=gdk_pixbuf_rotate_simple(thumbnail,GDK_PIXBUF_ROTATE_CLOCKWISE);
 
135
                        transformed=gdk_pixbuf_scale_simple(tmp,fit->width,fit->height,GDK_INTERP_NEAREST);
 
136
                        g_object_unref(G_OBJECT(tmp));
 
137
                        break;
 
138
                case 180:
 
139
                        tmp=gdk_pixbuf_rotate_simple(thumbnail,GDK_PIXBUF_ROTATE_UPSIDEDOWN);
 
140
                        transformed=gdk_pixbuf_scale_simple(tmp,fit->width,fit->height,GDK_INTERP_NEAREST);
 
141
                        g_object_unref(G_OBJECT(tmp));
 
142
                        break;
 
143
                case 90:
 
144
                        tmp=gdk_pixbuf_rotate_simple(thumbnail,GDK_PIXBUF_ROTATE_COUNTERCLOCKWISE);
 
145
                        transformed=gdk_pixbuf_scale_simple(tmp,fit->width,fit->height,GDK_INTERP_NEAREST);
 
146
                        g_object_unref(G_OBJECT(tmp));
 
147
                        break;
 
148
        }
 
149
 
 
150
        int dw=fit->width;
 
151
        int dh=fit->height;
 
152
        
 
153
        if(dw > width)
 
154
                dw=width;
 
155
 
 
156
        if(dh > height)
 
157
                dh=height;
 
158
        
 
159
        if(dw>gdk_pixbuf_get_width(transformed))
 
160
        {
 
161
                cerr << "DW too high" << endl;
 
162
                dw=gdk_pixbuf_get_width(transformed);
 
163
        }
 
164
 
 
165
        if(dh>gdk_pixbuf_get_height(transformed))
 
166
        {
 
167
                cerr << "DH too high" << endl;
 
168
                dh=gdk_pixbuf_get_height(transformed);
 
169
        }
 
170
 
 
171
        if(mask)
 
172
                maskpixbuf(transformed,fit->xoffset,fit->yoffset,dw,dh,mask);
 
173
 
 
174
        gdk_draw_pixbuf(widget->window,NULL,transformed,
 
175
                fit->xoffset,fit->yoffset,
 
176
                fit->xpos,fit->ypos,
 
177
                dw,dh,
 
178
                GDK_RGB_DITHER_NONE,0,0);
 
179
 
 
180
        delete fit;
 
181
}
 
182
 
 
183
 
 
184
void Layout_ImageInfo::SetMask(const char *filename)
 
185
{
 
186
        if(mask)
 
187
        {
 
188
                g_object_unref(mask);
 
189
                mask=NULL;
 
190
        }
 
191
        if(maskfilename)
 
192
        {
 
193
                free(maskfilename);
 
194
                maskfilename=NULL;
 
195
        }
 
196
        if(filename)
 
197
                maskfilename=strdup(filename);
 
198
        FlushThumbnail();
 
199
}
 
200
 
 
201
 
 
202
GdkPixbuf *Layout_ImageInfo::GetThumbnailNoEffects()
 
203
{
 
204
        GError *err=NULL;
 
205
 
 
206
        if(layout.state.batchmode)
 
207
                return(NULL);
 
208
 
 
209
        if(maskfilename && !mask)
 
210
        {
 
211
                mask=egg_pixbuf_get_thumbnail_for_file (maskfilename, EGG_PIXBUF_THUMBNAIL_LARGE, &err);
 
212
                cerr << "Attempting to load mask from: " << maskfilename << endl;
 
213
                if(!mask)
 
214
                {
 
215
                        cerr << "Failed." << endl;
 
216
                        try
 
217
                        {
 
218
                                ImageSource *src=ISLoadImage(maskfilename);
 
219
                                if(src)
 
220
                                {
 
221
                                        int w,h;
 
222
                                        w=(src->width*256)/src->height;
 
223
                                        h=256;
 
224
                                        if(w>256)
 
225
                                        {
 
226
                                                w=256;
 
227
                                                h=(src->height*256)/src->width;
 
228
                                        }
 
229
                                        src=ISScaleImageBySize(src,w,h,IS_SCALING_NEARESTNEIGHBOUR);
 
230
                                        mask=pixbuf_from_imagesource(src);
 
231
                                        delete src;
 
232
                                }
 
233
                        }
 
234
                        catch(const char *err)
 
235
                        {
 
236
                                cerr << "Error: " << err << endl;
 
237
                        }       
 
238
                        if(!mask)
 
239
                        {
 
240
                                if(err && err->message)
 
241
                                        cerr << "Error: " << err->message << endl;
 
242
                                else
 
243
                                        cerr << "Can't get mask thumbnail" << endl;
 
244
                                free(maskfilename);
 
245
                                maskfilename=NULL;
 
246
                        }
 
247
                }
 
248
        }
 
249
 
 
250
//      if(thumbnail)
 
251
//              return(thumbnail);
257
252
 
258
253
        cerr << "Thumbnail not cached - loading..." << endl;
259
254
 
260
255
        ImageSource *src=NULL;
261
 
                
262
 
        thumbnail=egg_pixbuf_get_thumbnail_for_file (filename, EGG_PIXBUF_THUMBNAIL_LARGE, &err);
263
 
 
264
 
        if(!thumbnail)
265
 
        {
 
256
                
 
257
        thumbnail=egg_pixbuf_get_thumbnail_for_file (filename, EGG_PIXBUF_THUMBNAIL_LARGE, &err);
 
258
 
 
259
        if(!thumbnail)
 
260
        {
266
261
                cerr << "Can't get pixbuf - loading thumbnail via ImageSource..." << endl;
267
 
                src=ISLoadImage(filename);
268
 
                if(src)
269
 
                {
270
 
                        int w,h;
271
 
                        w=(src->width*256)/src->height;
272
 
                        h=256;
273
 
                        if(w>256)
274
 
                        {
275
 
                                w=256;
276
 
                                h=(src->height*256)/src->width;
277
 
                        }
278
 
                        src=ISScaleImageBySize(src,w,h,IS_SCALING_NEARESTNEIGHBOUR);
279
 
                        thumbnail=pixbuf_from_imagesource(src);
280
 
                }
281
 
 
282
 
                if(!thumbnail)
283
 
                {
284
 
                        if(err && err->message)
285
 
                                throw err->message;
286
 
                        else
287
 
                                throw "Can't get thumbnail";
288
 
                }
289
 
        }
 
262
                src=ISLoadImage(filename);
 
263
                if(src)
 
264
                {
 
265
                        int w,h;
 
266
                        w=(src->width*256)/src->height;
 
267
                        h=256;
 
268
                        if(w>256)
 
269
                        {
 
270
                                w=256;
 
271
                                h=(src->height*256)/src->width;
 
272
                        }
 
273
                        src=ISScaleImageBySize(src,w,h,IS_SCALING_NEARESTNEIGHBOUR);
 
274
                        thumbnail=pixbuf_from_imagesource(src);
 
275
                }
 
276
 
 
277
                if(!thumbnail)
 
278
                {
 
279
                        if(err && err->message)
 
280
                                throw err->message;
 
281
                        else
 
282
                                throw "Can't get thumbnail";
 
283
                }
 
284
        }
290
285
 
291
286
        // If there's no display profile, then we can use the Default RGB profile instead...
292
287
        cerr << "Checking for Display Profile..." << endl;
293
288
        CMSProfile *targetprof;
294
289
        CMColourDevice target=CM_COLOURDEVICE_NONE;
295
 
        if((targetprof=layout.state.profilemanager.GetProfile(CM_COLOURDEVICE_DISPLAY)))
296
 
                target=CM_COLOURDEVICE_DISPLAY;
 
290
        if((targetprof=layout.state.profilemanager.GetProfile(CM_COLOURDEVICE_PRINTERPROOF)))
 
291
//              target=CM_COLOURDEVICE_DISPLAY;
 
292
                target=CM_COLOURDEVICE_PRINTERPROOF;
297
293
        else if((targetprof=layout.state.profilemanager.GetProfile(CM_COLOURDEVICE_DEFAULTRGB)))
298
294
                target=CM_COLOURDEVICE_DEFAULTRGB;
299
295
        if(targetprof)
318
314
                        if(emb)
319
315
                        {
320
316
                                cerr << "Creating embedded->monitor transform..." << endl;
321
 
                                if(emb->GetColourSpace()==IS_TYPE_CMYK)
 
317
                                if(emb->GetColourSpace()!=IS_TYPE_RGB)
322
318
                                {
323
 
//                                      Need to replace the RGB thumbnail with a CMYK version!
 
319
//                                      Need to replace the RGB thumbnail with a CMYK or Greyscale version!
324
320
                                        cerr << "Creating new thumbnail - CMYK->monitor" << endl;
325
 
                                        int w,h;
326
 
                                        w=(src->width*256)/src->height;
327
 
                                        h=256;
328
 
                                        if(w>256)
329
 
                                        {
330
 
                                                w=256;
331
 
                                                h=(src->height*256)/src->width;
332
 
                                        }
333
 
                                        src=ISScaleImageBySize(src,w,h,IS_SCALING_NEARESTNEIGHBOUR);
 
321
                                        int w,h;
 
322
                                        w=(src->width*256)/src->height;
 
323
                                        h=256;
 
324
                                        if(w>256)
 
325
                                        {
 
326
                                                w=256;
 
327
                                                h=(src->height*256)/src->width;
 
328
                                        }
 
329
                                        src=ISScaleImageBySize(src,w,h,IS_SCALING_NEARESTNEIGHBOUR);
334
330
                                        transform = layout.factory->GetTransform(target,emb,customintent);
335
331
                                        src=new ImageSource_CMS(src,transform);
336
332
                                        thumbnail=pixbuf_from_imagesource(src);
337
 
                                        transform=NULL; // Don't want to apply the transform a second time...
 
333
                                        transform=NULL; // Don't want to apply the transform a second time...
338
334
                                }
339
335
                                else
340
336
                                {
364
360
                delete src;             
365
361
        }
366
362
 
367
 
        return(thumbnail);
368
 
}
369
 
 
370
 
 
371
 
LayoutRectangle *Layout_ImageInfo::GetBounds()
372
 
{
373
 
        // Dummy function - override in subclasses!
374
 
        LayoutRectangle *result=new LayoutRectangle(0,0,100,100);
375
 
        return(result);
376
 
}
377
 
 
378
 
 
379
 
ImageSource *Layout_ImageInfo::GetImageSource(CMColourDevice target,CMTransformFactory *factory)
380
 
{
 
363
        return(thumbnail);
 
364
}
 
365
 
 
366
 
 
367
GdkPixbuf *Layout_ImageInfo::GetThumbnail()
 
368
{
 
369
        if(thumbnail)
 
370
                return(thumbnail);
 
371
 
 
372
        GdkPixbuf *tn=GetThumbnailNoEffects();
 
373
        if(tn)
 
374
        {
 
375
                ImageSource *src2=new ImageSource_GdkPixbuf(thumbnail);
 
376
                src2=ApplyEffects(src2,PPEFFECT_PRESCALE);
 
377
                GdkPixbuf *tn2=pixbuf_from_imagesource(src2);
 
378
                delete src2;
 
379
                g_object_unref(G_OBJECT(tn));
 
380
                thumbnail=tn2;
 
381
        }
 
382
        return(thumbnail);
 
383
}
 
384
 
 
385
 
 
386
LayoutRectangle *Layout_ImageInfo::GetBounds()
 
387
{
 
388
        // Dummy function - override in subclasses!
 
389
        LayoutRectangle *result=new LayoutRectangle(0,0,100,100);
 
390
        return(result);
 
391
}
 
392
 
 
393
 
 
394
ImageSource *Layout_ImageInfo::GetImageSource(CMColourDevice target,CMTransformFactory *factory)
 
395
{
381
396
        ImageSource *result=NULL;
382
 
        try
383
 
        {
384
 
                cerr << "Loading image " << endl;
385
 
                ImageSource *is=ISLoadImage(filename);
386
 
 
387
 
                IS_TYPE colourspace=layout.GetColourSpace(target);
388
 
 
389
 
                if(STRIP_ALPHA(is->type)==IS_TYPE_GREY)
390
 
                        is=new ImageSource_Promote(is,colourspace);
391
 
 
392
 
                if(STRIP_ALPHA(is->type)==IS_TYPE_BW)
393
 
                        is=new ImageSource_Promote(is,colourspace);
394
 
 
395
 
                CMSTransform *transform=NULL;
396
 
 
397
 
                if(factory)
 
397
        try
 
398
        {
 
399
                cerr << "Loading image " << endl;
 
400
                ImageSource *is=ISLoadImage(filename);
 
401
 
 
402
                is=ApplyEffects(is,PPEFFECT_PRESCALE);
 
403
 
 
404
                IS_TYPE colourspace=layout.GetColourSpace(target);
 
405
 
 
406
                if(STRIP_ALPHA(is->type)==IS_TYPE_GREY)
 
407
                        is=new ImageSource_Promote(is,colourspace);
 
408
 
 
409
                if(STRIP_ALPHA(is->type)==IS_TYPE_BW)
 
410
                        is=new ImageSource_Promote(is,colourspace);
 
411
 
 
412
                CMSTransform *transform=NULL;
 
413
 
 
414
                if(factory)
398
415
                {
399
416
                        CMSProfile *emb;
400
417
                        if(customprofile)
401
418
                                emb=new CMSProfile(customprofile);  // FIXME: Lifespan!
402
419
                        else
403
420
                                emb=is->GetEmbeddedProfile();
404
 
                        
405
 
                        if(emb)
406
 
                        {
407
 
                                cerr << "Has embedded / assigned profile..." << endl;
408
 
                                transform=factory->GetTransform(target,emb,customintent);  // FIXME: intent!
409
 
                        }
410
 
                        else
411
 
                        {
412
 
                                cerr << "No embedded profile - using default" << endl;
413
 
                                transform=factory->GetTransform(target,IS_TYPE(STRIP_ALPHA(is->type)),customintent);
414
 
                        }
415
 
        
416
 
                        if(transform)
417
 
                                is=new ImageSource_CMS(is,transform);
418
 
                }
419
 
                result=is;
420
 
        }
421
 
        catch(const char *err)
422
 
        {
423
 
                ErrorMessage_Dialog(err);
424
 
        }
425
 
        return(result);
426
 
}
427
 
 
428
 
 
429
 
ImageSource *Layout_ImageInfo::ApplyMask(ImageSource *is)
430
 
{
431
 
        if(maskfilename)
432
 
        {
433
 
                ImageSource *mask=ISLoadImage(maskfilename);
434
 
                if((is->width>is->height)^(mask->width>mask->height))
435
 
                {
436
 
                        mask=new ImageSource_Rotate(mask,90);
437
 
                        cerr << "Rotating mask" << endl;
438
 
                }
439
 
                mask=ISScaleImageBySize(mask,is->width,is->height,IS_SCALING_AUTOMATIC);
440
 
                is=new ImageSource_Mask(is,mask);
441
 
        }
442
 
        return(is);
443
 
}
444
 
 
445
 
 
446
 
bool Layout_ImageInfo::GetSelected()
447
 
{
448
 
        return(selected);
449
 
}
450
 
 
451
 
 
452
 
void Layout_ImageInfo::SetSelected(bool sel)
453
 
{
454
 
        selected=sel;
455
 
}
456
 
 
457
 
 
458
 
void Layout_ImageInfo::ToggleSelected()
459
 
{
460
 
        selected=!selected;
461
 
}
462
 
 
463
 
 
464
 
const char *Layout_ImageInfo::GetFilename()
465
 
{
466
 
        return(filename);
467
 
}
 
421
                        
 
422
                        if(emb)
 
423
                        {
 
424
                                cerr << "Has embedded / assigned profile..." << endl;
 
425
                                transform=factory->GetTransform(target,emb,customintent);  // FIXME: intent!
 
426
                        }
 
427
                        else
 
428
                        {
 
429
                                cerr << "No embedded profile - using default" << endl;
 
430
                                transform=factory->GetTransform(target,IS_TYPE(STRIP_ALPHA(is->type)),customintent);
 
431
                        }
 
432
        
 
433
                        if(transform)
 
434
                                is=new ImageSource_CMS(is,transform);
 
435
                }
 
436
                result=is;
 
437
        }
 
438
        catch(const char *err)
 
439
        {
 
440
                ErrorMessage_Dialog(err);
 
441
        }
 
442
        return(result);
 
443
}
 
444
 
 
445
 
 
446
ImageSource *Layout_ImageInfo::ApplyMask(ImageSource *is)
 
447
{
 
448
        if(maskfilename)
 
449
        {
 
450
                ImageSource *mask=ISLoadImage(maskfilename);
 
451
                if((is->width>is->height)^(mask->width>mask->height))
 
452
                {
 
453
                        mask=new ImageSource_Rotate(mask,90);
 
454
                        cerr << "Rotating mask" << endl;
 
455
                }
 
456
                mask=ISScaleImageBySize(mask,is->width,is->height,IS_SCALING_AUTOMATIC);
 
457
                is=new ImageSource_Mask(is,mask);
 
458
        }
 
459
        return(is);
 
460
}
 
461
 
 
462
 
 
463
bool Layout_ImageInfo::GetSelected()
 
464
{
 
465
        return(selected);
 
466
}
 
467
 
 
468
 
 
469
void Layout_ImageInfo::SetSelected(bool sel)
 
470
{
 
471
        selected=sel;
 
472
}
 
473
 
 
474
 
 
475
void Layout_ImageInfo::ToggleSelected()
 
476
{
 
477
        selected=!selected;
 
478
}
 
479
 
 
480
 
 
481
const char *Layout_ImageInfo::GetFilename()
 
482
{
 
483
        return(filename);
 
484
}
468
485
 
469
486
 
470
487
void Layout_ImageInfo::FlushThumbnail()
495
512
}
496
513
 
497
514
 
498
 
void Layout_ImageInfo::SetRenderingIntent(int intent)
 
515
void Layout_ImageInfo::SetRenderingIntent(LCMSWrapper_Intent intent)
499
516
{
500
517
        FlushThumbnail();
501
518
        customintent=intent;
502
519
}
503
520
 
504
521
 
505
 
int Layout_ImageInfo::GetRenderingIntent()
 
522
LCMSWrapper_Intent Layout_ImageInfo::GetRenderingIntent()
506
523
{
507
524
        return(customintent);
508
525
}
509
526
 
510
527
 
511
 
Layout::Layout(PhotoPrint_State &state,Layout *oldlayout)
512
 
        : xoffset(0), yoffset(0), pages(1), currentpage(0), backgroundfilename(NULL), background(NULL),
513
 
        backgroundtransformed(NULL), state(state), imagelist(NULL), iterator(NULL), factory(NULL)
514
 
{
 
528
Layout::Layout(PhotoPrint_State &state,Layout *oldlayout)
 
529
        : PageExtent(), xoffset(0), yoffset(0), pages(1), currentpage(0), backgroundfilename(NULL), background(NULL),
 
530
        backgroundtransformed(NULL), state(state), imagelist(NULL), iterator(NULL), factory(NULL), gc(NULL)
 
531
{
515
532
        factory=state.profilemanager.GetTransformFactory();
516
 
}
517
 
 
518
 
 
519
 
Layout::~Layout()
520
 
{
 
533
}
 
534
 
 
535
 
 
536
Layout::~Layout()
 
537
{
 
538
        if(gc)
 
539
                g_object_unref(G_OBJECT(gc));
521
540
        if(factory)
522
541
                delete factory;
523
 
        if(backgroundtransformed)
524
 
                g_object_unref(G_OBJECT(backgroundtransformed));
525
 
        backgroundtransformed=NULL;
526
 
 
527
 
        if(background)
528
 
                g_object_unref(G_OBJECT(background));
529
 
        background=NULL;
530
 
 
531
 
        if(backgroundfilename)
532
 
                free(backgroundfilename);
533
 
        backgroundfilename=NULL;
534
 
 
535
 
        if(imagelist)
536
 
        {
537
 
                for(unsigned int i=0;i<g_list_length(imagelist);++i)
538
 
                {
539
 
                        GList *element=g_list_nth(imagelist,i);
540
 
                        Layout_ImageInfo *ii=(Layout_ImageInfo *)element->data;
541
 
                        delete ii;
542
 
                }
543
 
        }
544
 
        g_list_free(imagelist);
545
 
}
546
 
 
547
 
 
548
 
void Layout::Clear()
549
 
{
550
 
        SetBackground(NULL);
551
 
        if(imagelist)
552
 
        {
553
 
                for(unsigned int i=0;i<g_list_length(imagelist);++i)
554
 
                {
555
 
                        GList *element=g_list_nth(imagelist,i);
556
 
                        Layout_ImageInfo *ii=(Layout_ImageInfo *)element->data;
557
 
                        delete ii;
558
 
                }
559
 
        }
560
 
        g_list_free(imagelist);
561
 
        imagelist=NULL;
562
 
        pages=1;
563
 
}
564
 
 
565
 
 
566
 
// DUMMY FUNCTION - should be overridden by subclasses
567
 
int Layout::AddImage(const char *filename,bool allowcropping,PP_ROTATION rotation)
568
 
{
569
 
        cerr << "AddImage: Dummy function - should be overridden" << endl;
570
 
        return(0);
571
 
}
572
 
 
573
 
 
574
 
// DUMMY FUNCTION - should be overridden by subclasses
575
 
void Layout::CopyImage(Layout_ImageInfo *ii)
576
 
{
577
 
        cerr << "CopyImage: Dummy function - should be overridden" << endl;
578
 
}
579
 
 
580
 
 
581
 
ImageSource *Layout::GetImageSource(int page,CMColourDevice target,CMTransformFactory *factory,int res)
582
 
{
583
 
        cerr << "GetImageSource: Dummy function - should be overridden" << endl;
584
 
        return(NULL);
585
 
}
586
 
 
587
 
 
588
 
IS_TYPE Layout::GetColourSpace(CMColourDevice target)
589
 
{
590
 
        enum IS_TYPE colourspace=IS_TYPE_RGB;
591
 
        CMSProfile *profile=state.profilemanager.GetProfile(target);
592
 
        if(profile)
593
 
        {
594
 
                colourspace=profile->GetColourSpace();
595
 
        }
596
 
        else
597
 
        {
598
 
                const char *cs=state.FindString("PrintColourSpace");
599
 
                if(strcmp(cs,"RGB")==0)
600
 
                        colourspace=IS_TYPE_RGB;
601
 
                else if(strcmp(cs,"CMYK")==0)
602
 
                        colourspace=IS_TYPE_CMYK;
603
 
                else
604
 
                        cerr << "PrintColourSpace is set to an unknown colour space!" << endl;
605
 
        }
606
 
        return(colourspace);
607
 
}
608
 
 
609
 
 
610
 
void Layout::TransferImages(Layout *oldlayout,Progress *p)
611
 
{
612
 
        if(currentpage>=pages);
613
 
        if(oldlayout)
614
 
        {
615
 
                int count=0,img=0;
616
 
                Layout_ImageInfo *ii=oldlayout->FirstImage();
617
 
                while(ii)
618
 
                {
619
 
                        ++count;
620
 
                        ii=oldlayout->NextImage();
621
 
                }
622
 
                ii=oldlayout->FirstImage();
623
 
                while(ii)
624
 
                {
625
 
                        ++img;
626
 
                        CopyImage(ii);
627
 
                        ii=oldlayout->NextImage();
628
 
                        if(p)
629
 
                        {
630
 
                                if(!(p->DoProgress(img,count)))
631
 
                                        ii=NULL;
632
 
                        }
633
 
                }
634
 
        }
635
 
        if(currentpage>=pages)
636
 
                currentpage=pages-1;
637
 
}
638
 
 
639
 
 
640
 
void Layout::DBToLayout(LayoutDB &db)
641
 
{
642
 
        state.printer.SetDriver(state.printoutput.FindString("Driver"));
643
 
}
644
 
 
645
 
 
646
 
void Layout::LayoutToDB(LayoutDB &db)
647
 
{
648
 
}
649
 
 
650
 
 
651
 
void Layout::Reflow()
652
 
{
653
 
}
654
 
 
655
 
 
656
 
GtkWidget *Layout::CreateWidget()
657
 
{
658
 
        return(NULL);
659
 
}
660
 
 
661
 
 
662
 
void Layout::RefreshWidget(GtkWidget *widget)
663
 
{
664
 
}
665
 
 
666
 
 
667
 
int Layout::GetCurrentPage()
668
 
{
669
 
        return(currentpage);
670
 
}
671
 
 
672
 
 
673
 
void Layout::SetCurrentPage(int page)
674
 
{
675
 
        currentpage=page;
676
 
}
677
 
 
678
 
 
679
 
void Layout::Print(Progress *p)
680
 
{
681
 
        state.printer.SetProgress(p);
682
 
        CMTransformFactory *factory=state.profilemanager.GetTransformFactory();
683
 
        for(int p=0;p<GetPages();++p)
684
 
        {
685
 
                ImageSource *is=GetImageSource(p,CM_COLOURDEVICE_PRINTER,factory);
686
 
                if(is)
687
 
                {
688
 
                        state.printer.Print(is,xoffset,yoffset);
689
 
                        delete is;
690
 
                }
691
 
        }
692
 
        delete factory;
693
 
        state.printer.SetProgress(NULL);
694
 
}
695
 
 
696
 
void (*Layout::SetUnitFunc())(GtkWidget *wid,enum Units unit)
697
 
{
698
 
        cerr << "This function should be overridden" << endl;
699
 
        return(NULL);
700
 
}
701
 
 
702
 
 
703
 
void Layout::DrawPreview(GtkWidget *widget,int xpos,int ypos,int width,int height)
704
 
{
705
 
        Layout_ImageInfo *ii=FirstImage();
706
 
 
707
 
        while(ii)
708
 
        {
709
 
                if(currentpage==ii->page)
710
 
                        ii->DrawThumbnail(widget,xpos,ypos,width,height);
711
 
                ii=NextImage();
712
 
        }
713
 
}
714
 
 
715
 
 
716
 
Layout_ImageInfo *Layout::FirstImage()
717
 
{
718
 
        iterator=imagelist;
719
 
        if(iterator)
720
 
                return((Layout_ImageInfo *)iterator->data);
721
 
        else
722
 
                return(NULL);
723
 
}
724
 
 
725
 
 
726
 
Layout_ImageInfo *Layout::NextImage()
727
 
{
728
 
        if(iterator)
729
 
                iterator=g_list_next(iterator);
730
 
        if(iterator)
731
 
                return((Layout_ImageInfo *)iterator->data);
732
 
        else
733
 
                return(NULL);
734
 
}
735
 
 
736
 
 
737
 
int Layout::GetPages()
738
 
{
739
 
        return(pages);
740
 
}
741
 
 
742
 
 
743
 
Layout_ImageInfo *Layout::FirstSelected()
744
 
{
745
 
        Layout_ImageInfo *ii=FirstImage();
746
 
        while(ii)
747
 
        {
748
 
                if(ii->GetSelected())
749
 
                        return(ii);
750
 
                ii=NextSelected();
751
 
        }
752
 
        return(NULL);
753
 
}
754
 
 
755
 
 
756
 
Layout_ImageInfo *Layout::NextSelected()
757
 
{
758
 
        Layout_ImageInfo *ii=NextImage();
759
 
        while(ii)
760
 
        {
761
 
                if(ii->GetSelected())
762
 
                        return(ii);
763
 
                ii=NextSelected();
764
 
        }
765
 
        return(NULL);
766
 
}
767
 
 
768
 
 
769
 
void Layout::SelectAll()
770
 
{
771
 
        Layout_ImageInfo *ii=FirstImage();
772
 
        while(ii)
773
 
        {
774
 
                ii->SetSelected(true);
775
 
                ii=NextImage();
776
 
        }
777
 
}
778
 
 
779
 
 
780
 
void Layout::SelectNone()
781
 
{
782
 
        Layout_ImageInfo *ii=FirstSelected();
783
 
        while(ii)
784
 
        {
785
 
                ii->SetSelected(false);
786
 
                ii=NextSelected();
787
 
        }
788
 
}
789
 
 
790
 
 
791
 
Layout_ImageInfo *Layout::ImageAtCoord(int x,int y)
792
 
{
793
 
        return(NULL);
794
 
}
795
 
 
796
 
 
797
 
int Layout::GetCapabilities()
798
 
{
799
 
        return(0);
800
 
}
801
 
 
802
 
 
803
 
void Layout::SetBackground(const char *filename)
804
 
{
805
 
        if(backgroundtransformed)
806
 
                g_object_unref(G_OBJECT(backgroundtransformed));
807
 
        backgroundtransformed=NULL;
808
 
 
809
 
        if(background)
810
 
                g_object_unref(G_OBJECT(background));
811
 
        background=NULL;
812
 
 
813
 
        if(backgroundfilename)
814
 
                free(backgroundfilename);
815
 
        backgroundfilename=NULL;
816
 
        
817
 
        cerr << "Setting background..." << endl;
818
 
        if(filename && strlen(filename)>0)
819
 
        {
820
 
                GError *err=NULL;
821
 
 
822
 
                backgroundfilename=strdup(filename);
823
 
 
824
 
                cerr << "Attempting to load background from: " << backgroundfilename << endl;
825
 
                background=egg_pixbuf_get_thumbnail_for_file (backgroundfilename, EGG_PIXBUF_THUMBNAIL_LARGE, &err);
826
 
                if(!background)
827
 
                {
828
 
                        cerr << "Failed." << endl;
829
 
                        try
830
 
                        {
831
 
                                ImageSource *src=ISLoadImage(backgroundfilename);
832
 
                                if(src)
833
 
                                {
834
 
                                        int w,h;
835
 
                                        w=(src->width*256)/src->height;
836
 
                                        h=256;
837
 
                                        if(w>256)
838
 
                                        {
839
 
                                                w=256;
840
 
                                                h=(src->height*256)/src->width;
841
 
                                        }
842
 
                                        src=ISScaleImageBySize(src,w,h,IS_SCALING_NEARESTNEIGHBOUR);
843
 
                                        background=pixbuf_from_imagesource(src);
844
 
                                        delete src;
845
 
                                }
846
 
                        }
847
 
                        catch(const char *err)
848
 
                        {
849
 
                                cerr << "Error: " << err << endl;
850
 
                        }       
851
 
                        if(!background)
852
 
                        {
853
 
                                if(err && err->message)
854
 
                                        cerr << "Error: " << err->message << endl;
855
 
                                else
856
 
                                        cerr << "Can't get mask thumbnail" << endl;
857
 
                                free(backgroundfilename);
858
 
                                backgroundfilename=NULL;
859
 
                        }
860
 
                }
861
 
        }
862
 
}
 
542
        if(backgroundtransformed)
 
543
                g_object_unref(G_OBJECT(backgroundtransformed));
 
544
        backgroundtransformed=NULL;
 
545
 
 
546
        if(background)
 
547
                g_object_unref(G_OBJECT(background));
 
548
        background=NULL;
 
549
 
 
550
        if(backgroundfilename)
 
551
                free(backgroundfilename);
 
552
        backgroundfilename=NULL;
 
553
 
 
554
        if(imagelist)
 
555
        {
 
556
                for(unsigned int i=0;i<g_list_length(imagelist);++i)
 
557
                {
 
558
                        GList *element=g_list_nth(imagelist,i);
 
559
                        Layout_ImageInfo *ii=(Layout_ImageInfo *)element->data;
 
560
                        delete ii;
 
561
                }
 
562
        }
 
563
        g_list_free(imagelist);
 
564
}
 
565
 
 
566
 
 
567
void Layout::Clear()
 
568
{
 
569
        SetBackground(NULL);
 
570
        if(imagelist)
 
571
        {
 
572
                for(unsigned int i=0;i<g_list_length(imagelist);++i)
 
573
                {
 
574
                        GList *element=g_list_nth(imagelist,i);
 
575
                        Layout_ImageInfo *ii=(Layout_ImageInfo *)element->data;
 
576
                        delete ii;
 
577
                }
 
578
        }
 
579
        g_list_free(imagelist);
 
580
        imagelist=NULL;
 
581
        pages=1;
 
582
}
 
583
 
 
584
 
 
585
// DUMMY FUNCTION - should be overridden by subclasses
 
586
int Layout::AddImage(const char *filename,bool allowcropping,PP_ROTATION rotation)
 
587
{
 
588
        cerr << "AddImage: Dummy function - should be overridden" << endl;
 
589
        return(0);
 
590
}
 
591
 
 
592
 
 
593
// DUMMY FUNCTION - should be overridden by subclasses
 
594
void Layout::CopyImage(Layout_ImageInfo *ii)
 
595
{
 
596
        cerr << "CopyImage: Dummy function - should be overridden" << endl;
 
597
}
 
598
 
 
599
 
 
600
ImageSource *Layout::GetImageSource(int page,CMColourDevice target,CMTransformFactory *factory,int res)
 
601
{
 
602
        cerr << "GetImageSource: Dummy function - should be overridden" << endl;
 
603
        return(NULL);
 
604
}
 
605
 
 
606
 
 
607
IS_TYPE Layout::GetColourSpace(CMColourDevice target)
 
608
{
 
609
        enum IS_TYPE colourspace=IS_TYPE_RGB;
 
610
        CMSProfile *profile=state.profilemanager.GetProfile(target);
 
611
        if(profile)
 
612
        {
 
613
                colourspace=profile->GetColourSpace();
 
614
        }
 
615
        else
 
616
        {
 
617
                const char *cs=state.FindString("PrintColourSpace");
 
618
                if(strcmp(cs,"RGB")==0)
 
619
                        colourspace=IS_TYPE_RGB;
 
620
                else if(strcmp(cs,"CMYK")==0)
 
621
                        colourspace=IS_TYPE_CMYK;
 
622
                else
 
623
                        cerr << "PrintColourSpace is set to an unknown colour space!" << endl;
 
624
        }
 
625
        return(colourspace);
 
626
}
 
627
 
 
628
 
 
629
void Layout::TransferImages(Layout *oldlayout,Progress *p)
 
630
{
 
631
        if(currentpage>=pages);
 
632
        if(oldlayout)
 
633
        {
 
634
                int count=0,img=0;
 
635
                Layout_ImageInfo *ii=oldlayout->FirstImage();
 
636
                while(ii)
 
637
                {
 
638
                        ++count;
 
639
                        ii=oldlayout->NextImage();
 
640
                }
 
641
                ii=oldlayout->FirstImage();
 
642
                while(ii)
 
643
                {
 
644
                        ++img;
 
645
                        CopyImage(ii);
 
646
                        ii=oldlayout->NextImage();
 
647
                        if(p)
 
648
                        {
 
649
                                if(!(p->DoProgress(img,count)))
 
650
                                        ii=NULL;
 
651
                        }
 
652
                }
 
653
        }
 
654
        if(currentpage>=pages)
 
655
                currentpage=pages-1;
 
656
}
 
657
 
 
658
 
 
659
void Layout::DBToLayout(LayoutDB &db)
 
660
{
 
661
        state.printer.SetDriver(state.printoutput.FindString("Driver"));
 
662
}
 
663
 
 
664
 
 
665
void Layout::LayoutToDB(LayoutDB &db)
 
666
{
 
667
}
 
668
 
 
669
 
 
670
void Layout::Reflow()
 
671
{
 
672
}
 
673
 
 
674
 
 
675
GtkWidget *Layout::CreateWidget()
 
676
{
 
677
        return(NULL);
 
678
}
 
679
 
 
680
 
 
681
void Layout::RefreshWidget(GtkWidget *widget)
 
682
{
 
683
}
 
684
 
 
685
 
 
686
int Layout::GetCurrentPage()
 
687
{
 
688
        return(currentpage);
 
689
}
 
690
 
 
691
 
 
692
void Layout::SetCurrentPage(int page)
 
693
{
 
694
        currentpage=page;
 
695
}
 
696
 
 
697
 
 
698
void Layout::Print(Progress *p)
 
699
{
 
700
        state.printer.SetProgress(p);
 
701
        CMTransformFactory *factory=state.profilemanager.GetTransformFactory();
 
702
        for(int p=0;p<GetPages();++p)
 
703
        {
 
704
                ImageSource *is=GetImageSource(p,CM_COLOURDEVICE_PRINTER,factory);
 
705
                if(is)
 
706
                {
 
707
                        state.printer.Print(is,xoffset,yoffset);
 
708
                        delete is;
 
709
                }
 
710
        }
 
711
        delete factory;
 
712
        state.printer.SetProgress(NULL);
 
713
}
 
714
 
 
715
void (*Layout::SetUnitFunc())(GtkWidget *wid,enum Units unit)
 
716
{
 
717
        cerr << "This function should be overridden" << endl;
 
718
        return(NULL);
 
719
}
 
720
 
 
721
 
 
722
void Layout::DrawPreviewBG(GtkWidget *widget,int xpos,int ypos,int width,int height)
 
723
{
 
724
        if(!gc)
 
725
        {
 
726
                bgcol.pixel=0;
 
727
                bgcol.red=65535;
 
728
                bgcol.green=65535;
 
729
                bgcol.blue=65535;
 
730
 
 
731
                // Use printer and monitor profiles to calculate "paper white".
 
732
                // If there's no display profile, then we can use the Default RGB profile instead...
 
733
                cerr << "Checking for Display Profile..." << endl;
 
734
                CMSProfile *targetprof;
 
735
                CMColourDevice target=CM_COLOURDEVICE_NONE;
 
736
                if((targetprof=state.profilemanager.GetProfile(CM_COLOURDEVICE_PRINTERPROOF)))
 
737
                        target=CM_COLOURDEVICE_PRINTERPROOF;
 
738
                else if((targetprof=state.profilemanager.GetProfile(CM_COLOURDEVICE_DEFAULTRGB)))
 
739
                        target=CM_COLOURDEVICE_DEFAULTRGB;
 
740
                if(targetprof)
 
741
                        delete targetprof;
 
742
 
 
743
 
 
744
                if(target!=CM_COLOURDEVICE_NONE)
 
745
                {
 
746
                        CMSTransform *transform=NULL;
 
747
                        cerr << "Creating default->monitor transform..." << endl;
 
748
                        transform = factory->GetTransform(target,IS_TYPE_RGB,LCMSWRAPPER_INTENT_DEFAULT);
 
749
                        if(transform)
 
750
                        {
 
751
                                cerr << "Applying transform..." << endl;
 
752
 
 
753
                                ISDataType rgbtriple[3];
 
754
                                rgbtriple[0]=bgcol.red;
 
755
                                rgbtriple[1]=bgcol.green;
 
756
                                rgbtriple[2]=bgcol.blue;
 
757
                                transform->Transform(rgbtriple,rgbtriple,1);
 
758
                                bgcol.red=rgbtriple[0];
 
759
                                bgcol.green=rgbtriple[1];
 
760
                                bgcol.blue=rgbtriple[2];
 
761
                        }
 
762
                }
 
763
 
 
764
                gc=gdk_gc_new(widget->window);
 
765
                gdk_gc_set_rgb_fg_color(gc,&bgcol);
 
766
        }
 
767
        gdk_draw_rectangle (widget->window,
 
768
                gc,TRUE,
 
769
                xpos,ypos,
 
770
                width,height);
 
771
 
 
772
        GetImageableArea();
 
773
        LayoutRectangle sr(leftmargin,topmargin,
 
774
                imageablewidth,imageableheight);
 
775
 
 
776
        double scale=width;
 
777
        scale/=pagewidth;
 
778
        sr.Scale(scale);
 
779
 
 
780
        gdk_draw_rectangle (widget->window,
 
781
                widget->style->mid_gc[widget->state],FALSE,
 
782
                xpos+sr.x,ypos+sr.y,sr.w,sr.h);
 
783
}
 
784
 
 
785
 
 
786
void Layout::DrawPreview(GtkWidget *widget,int xpos,int ypos,int width,int height)
 
787
{
 
788
        DrawPreviewBG(widget,xpos,ypos,width,height);
 
789
 
 
790
        Layout_ImageInfo *ii=FirstImage();
 
791
 
 
792
        while(ii)
 
793
        {
 
794
                if(currentpage==ii->page)
 
795
                        ii->DrawThumbnail(widget,xpos,ypos,width,height);
 
796
                ii=NextImage();
 
797
        }
 
798
}
 
799
 
 
800
 
 
801
Layout_ImageInfo *Layout::FirstImage()
 
802
{
 
803
        iterator=imagelist;
 
804
        if(iterator)
 
805
                return((Layout_ImageInfo *)iterator->data);
 
806
        else
 
807
                return(NULL);
 
808
}
 
809
 
 
810
 
 
811
Layout_ImageInfo *Layout::NextImage()
 
812
{
 
813
        if(iterator)
 
814
                iterator=g_list_next(iterator);
 
815
        if(iterator)
 
816
                return((Layout_ImageInfo *)iterator->data);
 
817
        else
 
818
                return(NULL);
 
819
}
 
820
 
 
821
 
 
822
int Layout::GetPages()
 
823
{
 
824
        return(pages);
 
825
}
 
826
 
 
827
 
 
828
Layout_ImageInfo *Layout::FirstSelected()
 
829
{
 
830
        Layout_ImageInfo *ii=FirstImage();
 
831
        while(ii)
 
832
        {
 
833
                if(ii->GetSelected())
 
834
                        return(ii);
 
835
                ii=NextSelected();
 
836
        }
 
837
        return(NULL);
 
838
}
 
839
 
 
840
 
 
841
Layout_ImageInfo *Layout::NextSelected()
 
842
{
 
843
        Layout_ImageInfo *ii=NextImage();
 
844
        while(ii)
 
845
        {
 
846
                if(ii->GetSelected())
 
847
                        return(ii);
 
848
                ii=NextSelected();
 
849
        }
 
850
        return(NULL);
 
851
}
 
852
 
 
853
 
 
854
void Layout::SelectAll()
 
855
{
 
856
        Layout_ImageInfo *ii=FirstImage();
 
857
        while(ii)
 
858
        {
 
859
                ii->SetSelected(true);
 
860
                ii=NextImage();
 
861
        }
 
862
}
 
863
 
 
864
 
 
865
void Layout::SelectNone()
 
866
{
 
867
        Layout_ImageInfo *ii=FirstSelected();
 
868
        while(ii)
 
869
        {
 
870
                ii->SetSelected(false);
 
871
                ii=NextSelected();
 
872
        }
 
873
}
 
874
 
 
875
 
 
876
Layout_ImageInfo *Layout::ImageAtCoord(int x,int y)
 
877
{
 
878
        return(NULL);
 
879
}
 
880
 
 
881
 
 
882
int Layout::GetCapabilities()
 
883
{
 
884
        return(0);
 
885
}
 
886
 
 
887
 
 
888
void Layout::SetBackground(const char *filename)
 
889
{
 
890
        if(backgroundtransformed)
 
891
                g_object_unref(G_OBJECT(backgroundtransformed));
 
892
        backgroundtransformed=NULL;
 
893
 
 
894
        if(background)
 
895
                g_object_unref(G_OBJECT(background));
 
896
        background=NULL;
 
897
 
 
898
        if(backgroundfilename)
 
899
                free(backgroundfilename);
 
900
        backgroundfilename=NULL;
 
901
        
 
902
        cerr << "Setting background..." << endl;
 
903
        if(filename && strlen(filename)>0)
 
904
        {
 
905
                GError *err=NULL;
 
906
 
 
907
                backgroundfilename=strdup(filename);
 
908
 
 
909
                cerr << "Attempting to load background from: " << backgroundfilename << endl;
 
910
                background=egg_pixbuf_get_thumbnail_for_file (backgroundfilename, EGG_PIXBUF_THUMBNAIL_LARGE, &err);
 
911
                if(!background)
 
912
                {
 
913
                        cerr << "Failed." << endl;
 
914
                        try
 
915
                        {
 
916
                                ImageSource *src=ISLoadImage(backgroundfilename);
 
917
                                if(src)
 
918
                                {
 
919
                                        int w,h;
 
920
                                        w=(src->width*256)/src->height;
 
921
                                        h=256;
 
922
                                        if(w>256)
 
923
                                        {
 
924
                                                w=256;
 
925
                                                h=(src->height*256)/src->width;
 
926
                                        }
 
927
                                        src=ISScaleImageBySize(src,w,h,IS_SCALING_NEARESTNEIGHBOUR);
 
928
                                        background=pixbuf_from_imagesource(src);
 
929
                                        delete src;
 
930
                                }
 
931
                        }
 
932
                        catch(const char *err)
 
933
                        {
 
934
                                cerr << "Error: " << err << endl;
 
935
                        }       
 
936
                        if(!background)
 
937
                        {
 
938
                                if(err && err->message)
 
939
                                        cerr << "Error: " << err->message << endl;
 
940
                                else
 
941
                                        cerr << "Can't get mask thumbnail" << endl;
 
942
                                free(backgroundfilename);
 
943
                                backgroundfilename=NULL;
 
944
                        }
 
945
                }
 
946
        }
 
947
}
863
948
 
864
949
 
865
950
void Layout::FlushThumbnails()
867
952
        delete factory;
868
953
        factory=new CMTransformFactory(state.profilemanager);
869
954
 
 
955
        // If the profile settings have changed, we'll flush the paper white
 
956
        // gc too, so it's regenerate with the new settings.
 
957
 
 
958
        if(gc)
 
959
                g_object_unref(G_OBJECT(gc));
 
960
        gc=NULL;
 
961
 
870
962
        Layout_ImageInfo *ii=FirstImage();
871
963
        while(ii)
872
964
        {