Commit 3868b82a authored by Matus Uzak's avatar Matus Uzak
Browse files

libmso: Use reserve achor in case OfficeArtClientAnchor is missing.

* Sometimes OfficeArtClientAnchor, which provides some client specific data to obtain
  shape dimensions and position is missing.  Each client should decide what to do
  in this case.  For MS-DOC client, the data can be accessed based on the character
  position (CP) in the document.  I could not reproduce the problem after re-save in
  MS Office 2000/2003/2007.  The test files attached to Bug 275290 is a well known broken file.
  I left an assert to obtain test data for inline shapes with missing OfficeArtClientAnchor.

BUG:275290
parent b3df9f8c
......@@ -226,6 +226,7 @@ private:
PptToOdp* const ppttoodp;
QRectF getRect(const MSO::OfficeArtClientAnchor&);
QRectF getReserveRect(void);
QString getPicturePath(const quint32 pib);
bool onlyClientData(const MSO::OfficeArtClientData& o);
void processClientData(const MSO::OfficeArtClientTextBox* ct,
......@@ -289,6 +290,11 @@ QRectF PptToOdp::DrawClient::getRect(const MSO::OfficeArtClientAnchor& o)
if (a) {
return ::getRect(*a);
}
return QRectF();
}
QRectF PptToOdp::DrawClient::getReserveRect(void)
{
//NOTE: No PPT test files at the moment.
return QRect(0, 0, 1, 1);
}
QString PptToOdp::DrawClient::getPicturePath(const quint32 pib)
......
......@@ -35,10 +35,18 @@ public:
public:
virtual ~Client() {}
/**
* Get the bounding rect that defines the position of the diagram
* in the hosting document.
* Get the bounding rect that defines the position and dimensions of
* the shape in the hosting document.
**/
virtual QRectF getRect(const MSO::OfficeArtClientAnchor&) = 0;
/**
* Get the bounding rect that defines the position and dimensions of
* the shape in the hosting document if OfficeArtClientAnchor is
* missing.
*/
virtual QRectF getReserveRect(void) = 0;
/**
* Get the path in the ODF document that corresponds to the
* image generated from the image with the given pib.
......
......@@ -76,8 +76,11 @@ ODrawToOdf::getRect(const OfficeArtSpContainer &o)
return QRect(r.xLeft, r.yTop, r.xRight - r.xLeft, r.yBottom - r.yTop);
} else if (o.clientAnchor && client) {
return client->getRect(*o.clientAnchor);
} else if (o.shapeProp.fHaveAnchor && client) {
return client->getReserveRect();
} else {
return QRectF();
}
return QRect(0, 0, 1, 1);
}
QRectF
......
......@@ -87,6 +87,12 @@ QRectF ODrawClient::getRect(const MSO::OfficeArtClientAnchor& clientAnchor)
return QRectF();
}
QRectF ODrawClient::getReserveRect(void)
{
//NOTE: No XLS test files at the moment.
return QRectF();
}
QRectF ODrawClient::getGlobalRect(const MSO::OfficeArtClientAnchor &clientAnchor)
{
const MSO::XlsOfficeArtClientAnchor* anchor = clientAnchor.anon.get<MSO::XlsOfficeArtClientAnchor>();
......
......@@ -31,6 +31,7 @@ class ODrawClient : public ODrawToOdf::Client
public:
explicit ODrawClient(Swinder::Sheet* sheet);
virtual QRectF getRect(const MSO::OfficeArtClientAnchor& anchor);
virtual QRectF getReserveRect(void);
QRectF getGlobalRect(const MSO::OfficeArtClientAnchor& anchor);
virtual QString getPicturePath(const quint32 pib);
virtual bool onlyClientData(const MSO::OfficeArtClientData &o);
......
......@@ -61,14 +61,27 @@ WordsGraphicsHandler::DrawClient::getRect(const MSO::OfficeArtClientAnchor& ca)
plcfSpa = gh->m_drawings->getSpaMom();
}
if (!plcfSpa) {
kDebug(30513) << "MISSING plcfSpa, returning QRect(0, 0, 1, 1)";
return QRect(0, 0, 1, 1);
kDebug(30513) << "MISSING plcfSpa, returning QRectF()";
return QRectF();
}
PLCFIterator<Word97::FSPA> it(plcfSpa->at(a->clientAnchor));
Word97::FSPA* spa = it.current();
return QRectF(spa->xaLeft, spa->yaTop, (spa->xaRight - spa->xaLeft), (spa->yaBottom - spa->yaTop));
}
QRectF
WordsGraphicsHandler::DrawClient::getReserveRect(void)
{
//At least for floating MS-ODRAW shapes the SPA structure for the current
//CP is provided by the GraphicsHandler. No test files for inline shapes
//at the moment.
Word97::FSPA* spa = gh->m_pSpa;
//DO NOT remove the assert, please send the file to: matus.uzak@ixonos.com
Q_ASSERT(spa);
return QRectF(spa->xaLeft, spa->yaTop, (spa->xaRight - spa->xaLeft), (spa->yaBottom - spa->yaTop));
}
QString
WordsGraphicsHandler::DrawClient::getPicturePath(const quint32 pib)
{
......
......@@ -202,7 +202,7 @@ void WordsGraphicsHandler::init()
{
kDebug(30513);
parseOfficeArtContainer();
parseOfficeArtContainers();
//create default GraphicStyle using information from OfficeArtDggContainer
defineDefaultGraphicStyle(m_mainStyles);
......@@ -251,6 +251,13 @@ DrawStyle WordsGraphicsHandler::getBgDrawStyle()
void WordsGraphicsHandler::handleInlineObject(const wvWare::PictureData& data)
{
//TODO: The globalCP might be required to obtain the SPA structure for
//inline MS-ODRAW shapes whith missing OfficeArtClientAnchor.
//TODO: It seems that both inline and floating objects have placement and
//dimensions stored in SPA structures. Check the OfficeArtClientAnchor for
//the index into plcfSpa.
kDebug(30513) ;
quint32 size = (data.picf->lcb - data.picf->cbHeader);
......@@ -380,8 +387,10 @@ void WordsGraphicsHandler::handleFloatingObject(unsigned int globalCP)
PLCFIterator<Word97::FSPA> it(plcfSpa->at(0));
for (size_t i = 0; i < plcfSpa->count(); i++, ++it) {
#ifdef DEBUG_GHANDLER
kDebug(30513) << "FSPA start:" << it.currentStart();
kDebug(30513) << "FSPA spid:" << it.current()->spid;
#endif
if ((it.currentStart() + threshold) == globalCP) {
bool inStylesXml = m_document->writingHeader();
......@@ -393,6 +402,9 @@ void WordsGraphicsHandler::handleFloatingObject(unsigned int globalCP)
m_zIndex = 1;
locateDrawing((dg->groupShape).data(), it.current(), (uint)it.current()->spid, out);
//reset global attributes
m_pSpa = 0;
return;
}
}
......@@ -574,7 +586,7 @@ void WordsGraphicsHandler::processDrawingObject(const MSO::OfficeArtSpContainer&
}
}
void WordsGraphicsHandler::parseOfficeArtContainer()
void WordsGraphicsHandler::parseOfficeArtContainers()
{
kDebug(30513);
......
......@@ -91,6 +91,7 @@ private:
{
private:
virtual QRectF getRect(const MSO::OfficeArtClientAnchor&);
virtual QRectF getReserveRect(void);
virtual QString getPicturePath(const quint32 pib);
virtual bool onlyClientData(const MSO::OfficeArtClientData& o);
virtual void processClientData(const MSO::OfficeArtClientTextBox* ct,
......@@ -178,9 +179,10 @@ private:
void init(void);
/**
* Parse the OfficeArtDggContainer data from the Table stream.
* Parse the OfficeArtDggContainer data and OfficeArtDgContainer data for
* both the body and the header document from the Table stream.
*/
void parseOfficeArtContainer(void);
void parseOfficeArtContainers(void);
/**
* Parse floating pictures data from the WordDocument stream.
......@@ -309,10 +311,6 @@ private:
// Specifies the type, size and border information for an inline picture.
wvWare::SharedPtr<const wvWare::Word97::PICF> m_picf;
//TODO: It seems that both inline and floating objects have placement and
//dimensions stored in SPA structures. Check the OfficeArtClientAnchor for
//the index into plcfSpa.
//structure that specifies placement of a floating object
wvWare::Word97::FSPA* m_pSpa;
};
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment