135
137
class ImageIpelet : public Ipelet {
137
virtual int IpelibVersion() const { return IPELIB_VERSION; }
138
virtual int NumFunctions() const { return 3; }
139
virtual const char *SubLabel(int function) const;
140
virtual const char *Label() const { return "Insert image"; }
141
virtual void Run(int, IpePage *page, IpeletHelper *helper);
143
void InsertBitmap(IpePage *page, IpeletHelper *helper, QString name);
144
void InsertJpeg(IpePage *page, IpeletHelper *helper, QString name);
145
void Fail(QString msg);
146
void Fail(const char *msg) { Fail(QLatin1String(msg)); }
147
bool ReadJpegInfo(QFile &file);
148
IpeRect ComputeRect(IpeletHelper *helper);
139
virtual int ipelibVersion() const { return IPELIB_VERSION; }
140
virtual bool run(int fn, IpeletData *data, IpeletHelper *helper);
143
bool insertBitmap(QString name);
144
bool insertJpeg(QString name);
145
void fail(QString msg);
146
void fail(const char *msg) { fail(QLatin1String(msg)); }
147
bool readJpegInfo(QFile &file);
152
IpeBitmap::TColorSpace iColorSpace;
154
Bitmap::TColorSpace iColorSpace;
153
155
int iBitsPerComponent;
154
IpeVector iDotsPerInch;
157
159
// --------------------------------------------------------------------
159
const char * const sublabel[] = {
161
"Insert bitmap image",
162
"Insert bitmap from clipboard"
165
const char *ImageIpelet::SubLabel(int function) const
167
return sublabel[function];
170
void ImageIpelet::Run(int fn, IpePage *page, IpeletHelper *helper)
161
bool ImageIpelet::run(int fn, IpeletData *data, IpeletHelper *helper)
174
166
name = QFileDialog::getOpenFileName();
175
167
if (name.isNull())
180
InsertJpeg(page, helper, name);
183
InsertBitmap(page, helper, name);
172
return insertBitmap(name);
174
return insertJpeg(name);
185
175
case 2: // bitmap from clipboard
186
InsertBitmap(page, helper, QString::null);
176
return insertBitmap(QString::null);
193
void ImageIpelet::Fail(QString msg)
182
void ImageIpelet::fail(QString msg)
195
QMessageBox::information(0, QLatin1String("Insert image ipelet"),
196
QLatin1String("<qt>") + msg
197
+ QLatin1String("</qt>"), QLatin1String("Dismiss"));
184
QMessageBox::warning(0, QLatin1String("Insert image ipelet"),
185
QLatin1String("<qt>") + msg
186
+ QLatin1String("</qt>"),
187
QLatin1String("Dismiss"));
200
190
// --------------------------------------------------------------------
202
IpeRect ImageIpelet::ComputeRect(IpeletHelper *helper)
192
Rect ImageIpelet::computeRect()
204
IpeVector frame = helper->Document()->layout().iFrameSize;
194
Vector frame = iData->iDoc->cascade()->findLayout()->iFrameSize;
206
double dx = (iWidth * 72.0) / iDotsPerInch.iX;
207
double dy = (iHeight * 72.0) / iDotsPerInch.iY;
196
double dx = (iWidth * 72.0) / iDotsPerInch.x;
197
double dy = (iHeight * 72.0) / iDotsPerInch.y;
209
199
double xfactor = 1.0;
211
xfactor = frame.iX / dx;
201
xfactor = frame.x / dx;
212
202
double yfactor = 1.0;
214
yfactor = frame.iY / dy;
204
yfactor = frame.y / dy;
215
205
double factor = (xfactor < yfactor) ? xfactor : yfactor;
216
IpeRect rect(IpeVector::Zero, factor * IpeVector(dx, dy));
217
IpeVector v = 0.5 * IpeVector(frame.iX - (rect.Min().iX + rect.Max().iX),
218
frame.iY - (rect.Min().iY + rect.Max().iY));
219
return IpeRect(rect.Min() + v, rect.Max() + v);
206
Rect rect(Vector::ZERO, factor * Vector(dx, dy));
207
Vector v = 0.5 * Vector(frame.x - (rect.left() + rect.right()),
208
frame.y - (rect.bottom() + rect.top()));
209
return Rect(rect.bottomLeft() + v, rect.topRight() + v);
222
212
// --------------------------------------------------------------------
224
214
// 72 points per inch
225
215
const double InchPerMeter = (1000.0 / 25.4);
227
void ImageIpelet::InsertBitmap(IpePage *page, IpeletHelper *helper,
217
bool ImageIpelet::insertBitmap(QString name)
230
qDebug("InsertBitmap");
219
ipeDebug("insertBitmap");
232
221
if (name.isNull()) {
233
222
QClipboard *cb = QApplication::clipboard();
234
qDebug("about to retrieve image");
223
ipeDebug("about to retrieve image");
235
224
im = cb->image();
236
qDebug("image retrieved %d", im.width());
225
ipeDebug("image retrieved %d", im.width());
237
226
if (im.isNull()) {
238
Fail("The clipboard contains no image, or perhaps\n"
227
fail("The clipboard contains no image, or perhaps\n"
239
228
"an image in a format not supported by Qt.");
243
232
if (!im.load(name)) {
244
Fail("The image could not be loaded.\n"
233
fail("The image could not be loaded.\n"
245
234
"Perhaps the format is not supported by Qt.");
249
QImage im1 = im.convertToFormat(QImage::Format_RGB32);
238
QImage im1 = im.convertToFormat(QImage::Format_ARGB32);
250
239
iWidth = im1.width();
251
240
iHeight = im1.height();
252
iDotsPerInch = IpeVector(72, 72);
241
iDotsPerInch = Vector(72, 72);
254
243
if (im1.dotsPerMeterX())
255
iDotsPerInch.iX = double(im1.dotsPerMeterX()) / InchPerMeter;
244
iDotsPerInch.x = double(im1.dotsPerMeterX()) / InchPerMeter;
256
245
if (im1.dotsPerMeterY())
257
iDotsPerInch.iY = double(im1.dotsPerMeterY()) / InchPerMeter;
246
iDotsPerInch.y = double(im1.dotsPerMeterY()) / InchPerMeter;
259
248
bool isGray = im1.allGray();
260
iColorSpace = isGray ? IpeBitmap::EDeviceGray : IpeBitmap::EDeviceRGB;
249
bool hasAlpha = false;
252
iColorSpace = isGray ? Bitmap::EDeviceGray : Bitmap::EDeviceRGB;
261
253
int datalen = iWidth * iHeight * (isGray ? 1 : 3);
262
IpeBuffer data(datalen);
254
Buffer data(datalen);
263
255
char *d = data.data();
264
256
for (int y = 0; y < iHeight; ++y) {
265
257
uint *p = (uint *) im1.scanLine(y);
266
258
for (int x = 0; x < iWidth; ++x) {
259
if (qAlpha(*p) != 0xff) {
261
colorKey = (*p & 0x00ffffff);
268
264
*d++ = qRed(*p++);
277
IpeBitmap bitmap(iWidth, iHeight, iColorSpace, 8, data,
278
IpeBitmap::EDirect, true);
279
IpeImage *obj = new IpeImage(ComputeRect(helper), bitmap);
280
page->push_back(IpePgObject(IpePgObject::ESecondary,
281
helper->CurrentLayer(), obj));
273
// determine if image has a color key
274
bool hasColorKey = hasAlpha;
276
for (int y = 0; hasColorKey && y < iHeight; ++y) {
277
uint *p = (uint *) im1.scanLine(y);
278
for (int x = 0; hasColorKey && x < iWidth; ++x, ++p) {
279
int alpha = qAlpha(*p);
280
if ((alpha == 0 && *p != colorKey) ||
281
(alpha != 0 && alpha != 0xff) ||
282
(alpha == 0xff && (*p & 0x00ffffff) == colorKey))
288
ipeDebug("hasAlpha: %d, colorkeyed %d: %x", hasAlpha, hasColorKey, colorKey);
290
Bitmap bitmap(iWidth, iHeight, iColorSpace, 8, data, Bitmap::EDirect, true);
292
bitmap.setColorKey(colorKey);
294
Image *obj = new Image(computeRect(), bitmap);
295
iData->iPage->append(ESecondarySelected, iData->iLayer, obj);
284
299
// --------------------------------------------------------------------
286
bool ImageIpelet::ReadJpegInfo(QFile &file)
301
bool ImageIpelet::readJpegInfo(QFile &file)
288
303
static char jpg_id[] = "JFIF";
397
void ImageIpelet::InsertJpeg(IpePage *page, IpeletHelper *helper,
412
bool ImageIpelet::insertJpeg(QString name)
400
414
QFile file(name);
401
415
if (!file.open(QIODevice::ReadOnly)) {
402
Fail(QString(QLatin1String("Could not open file '%1'")).arg(name));
416
fail(QString(QLatin1String("Could not open file '%1'")).arg(name));
405
if (!ReadJpegInfo(file))
419
if (!readJpegInfo(file))
408
422
QByteArray a = file.readAll();
411
IpeBitmap bitmap(iWidth, iHeight, iColorSpace,
412
iBitsPerComponent, IpeBuffer(a.data(), a.size()),
413
IpeBitmap::EDCTDecode);
414
IpeImage *obj = new IpeImage(ComputeRect(helper), bitmap);
415
page->push_back(IpePgObject(IpePgObject::ESecondary,
416
helper->CurrentLayer(), obj));
425
Bitmap bitmap(iWidth, iHeight, iColorSpace,
426
iBitsPerComponent, Buffer(a.data(), a.size()),
428
Image *obj = new Image(computeRect(), bitmap);
429
iData->iPage->append(ESecondarySelected, iData->iLayer, obj);
419
433
// --------------------------------------------------------------------
421
IPELET_DECLARE Ipelet *NewIpelet()
435
IPELET_DECLARE Ipelet *newIpelet()
423
437
return new ImageIpelet;