KoShape *KPrPlaceholderPictureStrategy::createShape(KoDocumentResourceManager *rm) { KoShape * shape = 0; KUrl url = KFileDialog::getOpenUrl(); if ( !url.isEmpty() ) { shape = KPrPlaceholderStrategy::createShape(rm); KoImageCollection *collection = rm->imageCollection(); Q_ASSERT(collection); QString tmpFile; if (KIO::NetAccess::download(url, tmpFile, 0)) { QImage image(tmpFile); if (!image.isNull()) { //setSuffix(url.prettyUrl()); KoImageData *data = collection->createImageData(image); if (data->isValid()) { shape->setUserData( data ); // TODO the pic should be fit into the space provided shape->setSize( data->imageSize() ); } } } else { kWarning() << "open image " << url.prettyUrl() << "failed"; } } return shape; }
void PictureShape::saveOdf(KoShapeSavingContext &context) const { // make sure we have a valid image data pointer before saving KoImageData *imageData = qobject_cast<KoImageData*>(userData()); if (imageData == 0) { return; } KoXmlWriter &writer = context.xmlWriter(); writer.startElement("draw:frame"); saveOdfAttributes(context, OdfAllAttributes); writer.startElement("draw:image"); // In the spec, only the xlink:href attribute is marked as mandatory, cool :) QString name = context.imageHref(imageData); writer.addAttribute("xlink:type", "simple"); writer.addAttribute("xlink:show", "embed"); writer.addAttribute("xlink:actuate", "onLoad"); writer.addAttribute("xlink:href", name); saveText(context); writer.endElement(); // draw:image QSizeF scaleFactor(imageData->imageSize().width() / size().width(), imageData->imageSize().height() / size().height()); saveOdfClipContour(context, scaleFactor); writer.endElement(); // draw:frame context.addDataCenter(m_imageCollection); }
void PictureShape::waitUntilReady(const KoViewConverter &converter, bool asynchronous) const { KoImageData *imageData = qobject_cast<KoImageData*>(userData()); if (imageData == 0) { return; } if (asynchronous) { // get pixmap and schedule it if not QSize pixels = converter.documentToView(QRectF(QPointF(0,0), size())).size().toSize(); QImage image = imageData->image(); if (image.isNull()) { return; } m_printQualityRequestedSize = pixels; if (image.size().width() < pixels.width()) { // don't scale up. pixels = image.size(); } m_printQualityImage = image.scaled(pixels, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); } else { QSize pixmapSize = calcOptimalPixmapSize(converter.documentToView(QRectF(QPointF(0,0), size())).size(), imageData->image().size()); QString key(generate_key(imageData->key(), pixmapSize)); if (QPixmapCache::find(key) == 0) { QPixmap pixmap = imageData->pixmap(pixmapSize); QPixmapCache::insert(key, pixmap); } } }
bool PictureShape::loadFromUrl( KUrl &url ) { KoImageData * data = m_imageCollection->getImage(url); if ( data ) { setUserData( data ); // don't set the size of the shape to the size of the picture, but instead keep the // area of the shape constant, and only change the aspect ratio to be that of the image QSizeF oldsize = size(); QSizeF newsize = data->imageSize(); qreal oldarea = oldsize.width() * oldsize.height(); qreal newarea = newsize.width() * newsize.height(); newsize *= sqrt(oldarea / newarea); setSize(newsize); } return data != 0; }
void KritaShape::waitUntilReady() const { if (m_d && m_d->doc && m_d->doc->image()) // all done return; KoImageData *data = dynamic_cast<KoImageData*>(KoShape::userData()); if (data == 0 || data->image().isNull()) return; // no data available at all, so don't try to wait later on. KritaShape *me = const_cast<KritaShape*>(this); m_mutex.lock(); me->tryLoadFromImageData(data); m_waiter.wait(&m_mutex); m_mutex.unlock(); }
void KPrPicturesImport::pictureImported(KJob *job) { KoShape *shape = m_factory->createDefaultShape(); if (shape) { KIO::StoredTransferJob *transferJob = qobject_cast<KIO::StoredTransferJob*>(job); Q_ASSERT(transferJob); KoImageData *imageData = m_doc->resourceManager()->imageCollection()->createImageData(transferJob->data()); if (imageData->isValid()) { shape->setUserData(imageData); // make sure the picture fits on the page QSizeF imageSize = imageData->imageSize(); QSizeF pageSize = m_masterPage->size(); qreal zoom = 1; if (imageSize.width() > pageSize.width() || imageSize.height() > pageSize.height()) { zoom = pageSize.width() / imageSize.width(); zoom = qMin(zoom, pageSize.height() / imageSize.height()); } imageSize *= zoom; shape->setSize(imageSize); // center the picture on the page QPointF pos( pageSize.width() / 2- imageSize.width() / 2, pageSize.height() / 2 - imageSize.height() / 2 ); shape->setPosition(pos); KoPAPageBase *page = m_doc->newPage(m_masterPage); KoShapeLayer *layer = dynamic_cast<KoShapeLayer *>(page->shapes().first()); if (layer) { layer->addShape(shape); new KoPAPageInsertCommand(m_doc, page, m_currentPage, m_cmd); m_currentPage = page; } else { delete page; delete shape; } } else { kWarning(33001) << "imageData not valid"; delete shape; } } else { kWarning(33001) << "shape not created"; } import(); }
KoShape *PictureShapeFactory::createShape(const KoProperties *params, KoDocumentResourceManager *documentResources) const { PictureShape *shape = static_cast<PictureShape*>(createDefaultShape(documentResources)); if (params->contains("qimage")) { QImage image = params->property("qimage").value<QImage>(); Q_ASSERT(!image.isNull()); if (shape->imageCollection()) { KoImageData *data = shape->imageCollection()->createImageData(image); shape->setUserData(data); shape->setSize(data->imageSize()); shape->update(); } } return shape; }
KoShape * KPrPlaceholderPictureStrategy::createShape( const QMap<QString, KoDataCenter *> & dataCenterMap ) { KoShape * shape = 0; KUrl url = KFileDialog::getOpenUrl(); if ( !url.isEmpty() ) { shape = KPrPlaceholderStrategy::createShape( dataCenterMap ); KoImageCollection * collection = dynamic_cast<KoImageCollection *>( dataCenterMap.value( "ImageCollection" ) ); KoImageData * data = collection->getImage( url ); if ( data ) { shape->setUserData( data ); // TODO th pic should be fit into the space provided shape->setSize( data->imageSize() ); } } return shape; }
void LoadWaiter::setImageData(const QImage &image) { if (m_pictureShape == 0) return; // ugh, the shape got deleted meanwhile //KIO::StoredTransferJob *transferJob = qobject_cast<KIO::StoredTransferJob*>(job); //Q_ASSERT(transferJob); if (m_pictureShape->imageCollection()) { KoImageData *data = m_pictureShape->imageCollection()->createImageData(image); if (data) { m_pictureShape->setUserData(data); // check if the shape still size of the default shape and resize in that case if (qFuzzyCompare(m_pictureShape->size().width(), 50.0)) { m_pictureShape->setSize(data->imageSize()); } } } deleteLater(); }
bool PictureShape::loadOdf(const KoXmlElement &element, KoShapeLoadingContext &context) { loadOdfAttributes(element, context, OdfAllAttributes); if (loadOdfFrame(element, context)) { // load contour (clip) KoImageData *imageData = qobject_cast<KoImageData*>(userData()); QSizeF scaleFactor(size().width() / imageData->imageSize().width(), size().height() / imageData->imageSize().height()); loadOdfClipContour(element, context, scaleFactor); // this is needed so that the image is already normalized when calling waitUntilReady e.g. by cstester m_clippingRect.normalize(imageData->imageSize()); return true; } return false; }
QString PictureShape::saveStyle(KoGenStyle& style, KoShapeSavingContext& context) const { if(transparency() > 0.0) { style.addProperty("draw:image-opacity", QString("%1%").arg((1.0 - transparency()) * 100.0)); } // this attribute is need to work around a bug in LO 3.4 to make it recognice us as an // image and not just any shape. But we shouldn't produce illegal odf so: only for testing! // style.addAttribute("style:parent-style-name", "dummy"); // Mirroring if (m_mirrorMode != MirrorNone) { QString mode; if (m_mirrorMode & MirrorHorizontal) mode = "horizontal"; else if (m_mirrorMode & MirrorHorizontalOnEven) mode = "horizontal-on-even"; else if (m_mirrorMode & MirrorHorizontalOnOdd) mode = "horizontal-on-odd"; if (m_mirrorMode & MirrorVertical) { if (!mode.isEmpty()) mode += ' '; mode += "vertical"; } style.addProperty("style:mirror", mode); } switch(m_colorMode) { case Standard: style.addProperty("draw:color-mode", "standard"); break; case Greyscale: style.addProperty("draw:color-mode", "greyscale"); break; case Watermark: style.addProperty("draw:color-mode", "watermark"); break; case Mono: style.addProperty("draw:color-mode", "mono"); break; } KoImageData *imageData = qobject_cast<KoImageData*>(userData()); if (imageData != 0) { QSizeF imageSize = imageData->imageSize(); ClippingRect rect = m_clippingRect; rect.normalize(imageSize); rect.bottom = 1.0 - rect.bottom; rect.right = 1.0 - rect.right; if (!qFuzzyCompare(rect.left + rect.right + rect.top + rect.bottom, qreal(0))) { style.addProperty("fo:clip", QString("rect(%1pt, %2pt, %3pt, %4pt)") .arg(rect.top * imageSize.height()) .arg(rect.right * imageSize.width()) .arg(rect.bottom * imageSize.height()) .arg(rect.left * imageSize.width()) ); } } return KoTosContainer::saveStyle(style, context); }
QBrush Surface::loadOdfPatternStyle(const KoStyleStack &styleStack, KoOdfLoadingContext &context, const QSizeF &size) { QString styleName = styleStack.property(KoXmlNS::draw, "fill-image-name"); KoXmlElement* e = context.stylesReader().drawStyles("fill-image")[styleName]; if (! e) return QBrush(); const QString href = e->attributeNS(KoXmlNS::xlink, "href", QString()); if (href.isEmpty()) return QBrush(); QString strExtension; const int result = href.lastIndexOf("."); if (result >= 0) { strExtension = href.mid(result + 1); // As we are using KoPicture, the extension should be without the dot. } QString filename(href); KoImageData data; data.setImage(href, context.store()); if (data.errorCode() != KoImageData::Success) return QBrush(); // read the pattern repeat style QString style = styleStack.property(KoXmlNS::style, "repeat"); kDebug(35001) << "pattern style =" << style; QSize imageSize = data.image().size(); if (style == "stretch") { imageSize = size.toSize(); } else { // optional attributes which can override original image size if (styleStack.hasProperty(KoXmlNS::draw, "fill-image-height") && styleStack.hasProperty(KoXmlNS::draw, "fill-image-width")) { QString height = styleStack.property(KoXmlNS::draw, "fill-image-height"); qreal newHeight = 0.0; if (height.endsWith('%')) newHeight = 0.01 * height.remove('%').toDouble() * imageSize.height(); else newHeight = KoUnit::parseValue(height); QString width = styleStack.property(KoXmlNS::draw, "fill-image-width"); qreal newWidth = 0.0; if (width.endsWith('%')) newWidth = 0.01 * width.remove('%').toDouble() * imageSize.width(); else newWidth = KoUnit::parseValue(width); if (newHeight > 0.0) imageSize.setHeight(static_cast<int>(newHeight)); if (newWidth > 0.0) imageSize.setWidth(static_cast<int>(newWidth)); } } kDebug(35001) << "shape size =" << size; kDebug(35001) << "original image size =" << data.image().size(); kDebug(35001) << "resulting image size =" << imageSize; QBrush resultBrush(QPixmap::fromImage(data.image()).scaled(imageSize)); if (style == "repeat") { QTransform matrix; if (styleStack.hasProperty(KoXmlNS::draw, "fill-image-ref-point")) { // align pattern to the given size QString align = styleStack.property(KoXmlNS::draw, "fill-image-ref-point"); kDebug(35001) << "pattern align =" << align; if (align == "top-left") matrix.translate(0, 0); else if (align == "top") matrix.translate(0.5*size.width(), 0); else if (align == "top-right") matrix.translate(size.width(), 0); else if (align == "left") matrix.translate(0, 0.5*size.height()); else if (align == "center") matrix.translate(0.5*size.width(), 0.5*size.height()); else if (align == "right") matrix.translate(size.width(), 0.5*size.height()); else if (align == "bottom-left") matrix.translate(0, size.height()); else if (align == "bottom") matrix.translate(0.5*size.width(), size.height()); else if (align == "bottom-right") matrix.translate(size.width(), size.height()); } if (styleStack.hasProperty(KoXmlNS::draw, "fill-image-ref-point-x")) { QString pointX = styleStack.property(KoXmlNS::draw, "fill-image-ref-point-x"); matrix.translate(0.01 * pointX.remove('%').toDouble() * imageSize.width(), 0); } if (styleStack.hasProperty(KoXmlNS::draw, "fill-image-ref-point-y")) { QString pointY = styleStack.property(KoXmlNS::draw, "fill-image-ref-point-y"); matrix.translate(0, 0.01 * pointY.remove('%').toDouble() * imageSize.height()); } resultBrush.setTransform(matrix); } return resultBrush; }