diff options
author | ALONSO Laurent <laurent.alonso@inria.fr> | 2019-04-09 18:03:29 +0200 |
---|---|---|
committer | ALONSO Laurent <laurent.alonso@inria.fr> | 2019-04-09 18:03:29 +0200 |
commit | 95696d9b23be351b60ab9d17ff0bb890af85c4d7 (patch) | |
tree | c3441054a5124efe6252243c57d73307a2dd86f1 | |
parent | 3cecd5ac1183ed8ed9ee92bae33ff231a84bb781 (diff) |
iwa[key,pages]:try harder to retrieve the position if autoresized
Change-Id: Ib38a6889c0b8b8756b8cd7343c75efd10e6a20f3
-rw-r--r-- | src/lib/IWAParser.cpp | 166 | ||||
-rw-r--r-- | src/lib/IWAParser.h | 3 | ||||
-rw-r--r-- | src/lib/KEY6Parser.cpp | 5 | ||||
-rw-r--r-- | src/lib/NUM3Parser.cpp | 4 | ||||
-rw-r--r-- | src/lib/NUM3Parser.h | 2 |
5 files changed, 113 insertions, 67 deletions
diff --git a/src/lib/IWAParser.cpp b/src/lib/IWAParser.cpp index 6c41b7f..d11905e 100644 --- a/src/lib/IWAParser.cpp +++ b/src/lib/IWAParser.cpp @@ -576,6 +576,60 @@ bool IWAParser::dispatchShapeWithMessage(const IWAMessage &msg, unsigned type) return false; } +void IWAParser::updateGeometryUsingTextRef(unsigned id, IWORKGeometry &geometry, unsigned flags) +{ + // no horizontal auto resize or width unknown + if ((flags&1)==1 || geometry.m_size.m_width<=0) return; + const ObjectMessage msg(*this, id); + if (!msg) + return; + if (msg.getType()==IWAObjectType::TextRef) + { + auto textRef=readRef(get(msg),1); + if (!textRef) + { + ETONYEK_DEBUG_MSG(("IWAParser::updateGeometryUsingTextRef: can not find the text reference\n")); + return; + } + updateGeometryUsingTextRef(get(textRef),geometry, flags); + return; + } + if (msg.getType()!=IWAObjectType::Text) + { + ETONYEK_DEBUG_MSG(("IWAParser::updateGeometryUsingTextRef: unexpected object type, type=%d\n", int(msg.getType()))); + return; + } + if (!get(msg).message(5)) + return; + // ok, let find the paragraph style for pos=0 + for (const auto &it : get(msg).message(5).message(1)) + { + if (it.uint32(1) && get(it.uint32(1))!=0) continue; + const optional<unsigned> &styleRef = readRef(it, 2); + if (!styleRef) return; + + const IWORKStylePtr_t &style = queryParagraphStyle(get(styleRef)); + if (!bool(style)) return; + if (geometry.m_size.m_width>0 && style->has<property::Alignment>()) + { + switch (style->get<property::Alignment>()) + { + case IWORK_ALIGNMENT_RIGHT : + geometry.m_position.m_x -= geometry.m_size.m_width; + break; + case IWORK_ALIGNMENT_CENTER : + geometry.m_position.m_x -= geometry.m_size.m_width/2.; + break; + case IWORK_ALIGNMENT_LEFT : + case IWORK_ALIGNMENT_JUSTIFY : + case IWORK_ALIGNMENT_AUTOMATIC: + default: + break; + } + } + } +} + bool IWAParser::parseText(const unsigned id, bool createNoteAsFootnote, const std::function<void(unsigned, IWORKStylePtr_t)> &openPageFunction) { assert(bool(m_currentText)); @@ -1164,14 +1218,21 @@ bool IWAParser::parseDrawableShape(const IWAMessage &msg, bool isConnectionLine) m_collector.startLevel(); const optional<IWAMessage> &shape = msg.message(1).optional(); + const optional<unsigned> &textRef = readRef(msg, 2); + if (shape) { const optional<IWAMessage> &placement = get(shape).message(1).optional(); + IWORKStylePtr_t style; + const optional<unsigned> styleRef = readRef(get(shape), 2); + if (styleRef) + style=queryGraphicStyle(get(styleRef)); const optional<IWAMessage> &path = get(shape).message(3).optional(); if (placement) { IWORKGeometryPtr_t geometry; - parseShapePlacement(get(placement), geometry); + unsigned flags=3; + parseShapePlacement(get(placement), geometry, flags); if (geometry && (geometry->m_naturalSize.m_width<=0 || geometry->m_naturalSize.m_height<=0) && path) { // try to retrieve the shape's size in the path @@ -1185,13 +1246,28 @@ bool IWAParser::parseDrawableShape(const IWAMessage &msg, bool isConnectionLine) break; } } + if (geometry && (flags&1)==0 && textRef) // correct horizontal position + updateGeometryUsingTextRef(get(textRef), *geometry, flags); + if (geometry && (flags&2)==0 && geometry->m_size.m_height>0 && style && style->has<property::VerticalAlignment>()) + { + // correct vertical position + switch (style->get<property::VerticalAlignment>()) + { + case IWORK_VERTICAL_ALIGNMENT_MIDDLE: + geometry->m_position.m_y -= geometry->m_size.m_height/2.; + break; + case IWORK_VERTICAL_ALIGNMENT_BOTTOM: + geometry->m_position.m_y -= geometry->m_size.m_height; + break; + case IWORK_VERTICAL_ALIGNMENT_TOP: + default: + break; + } + } + m_collector.collectGeometry(geometry); } - IWORKStylePtr_t style; - const optional<unsigned> styleRef = readRef(get(shape), 2); - if (styleRef) - style=queryGraphicStyle(get(styleRef)); // look for arrow Keynote 6 if (get(shape).message(4) || get(shape).message(5)) { @@ -1388,18 +1464,14 @@ bool IWAParser::parseDrawableShape(const IWAMessage &msg, bool isConnectionLine) } } bool hasText=false; - if (!isConnectionLine) + if (!isConnectionLine && textRef) { - const optional<unsigned> &textRef = readRef(msg, 2); - if (textRef) + m_currentText = m_collector.createText(m_langManager, true); + parseText(get(textRef)); + if (!m_currentText->empty()) { - m_currentText = m_collector.createText(m_langManager, true); - parseText(get(textRef)); - if (!m_currentText->empty()) - { - hasText=true; - m_collector.collectText(m_currentText); - } + hasText=true; + m_collector.collectText(m_currentText); } } @@ -1431,9 +1503,10 @@ bool IWAParser::parseGroup(const IWAMessage &msg) return true; } -bool IWAParser::parseShapePlacement(const IWAMessage &msg, IWORKGeometryPtr_t &geometry) +bool IWAParser::parseShapePlacement(const IWAMessage &msg, IWORKGeometryPtr_t &geometry, unsigned &flags) { geometry = make_shared<IWORKGeometry>(); + flags=3; // no auto resize const optional<IWAMessage> &g = msg.message(1).optional(); if (g) @@ -1446,50 +1519,14 @@ bool IWAParser::parseShapePlacement(const IWAMessage &msg, IWORKGeometryPtr_t &g geometry->m_naturalSize = geometry->m_size = get(size); if (get(g).uint32(3)) { - switch (get(get(g).uint32(3))) - { - case 0: // centered x, centered y - { - // the position is the position of the center of the shape - // (often auto grow textboxes) - if (pos && size && get(size).m_width>0 && get(size).m_height>0) - { - geometry->m_position.m_x -= get(size).m_width/2.; - geometry->m_position.m_y -= get(size).m_height/2.; - break; - } - static bool first=true; - if (first) - { - ETONYEK_DEBUG_MSG(("IWAParser::parseShapePlacement: Ooops, find some centered shape\n")); - first=false; - } - break; - } - case 1: // fixed x, centered y - { - if (pos && size && get(size).m_height>0) - { - geometry->m_position.m_y -= get(size).m_height/2.; - break; - } - static bool first=true; - if (first) - { - ETONYEK_DEBUG_MSG(("IWAParser::parseShapePlacement: Ooops, find some y centered shape\n")); - first=false; - } - break; - } - // case 2: centered x, fixed y? - case 3 : // normal - break; - case 7 : // horizontal flip + flags=get(get(g).uint32(3)); + // flags&1 : horizontal position is fixed + // flags&2 : vertical position is fixed + if (flags&4) // horizontal flip geometry->m_horizontalFlip = true; - break; - default : - ETONYEK_DEBUG_MSG(("IWAParser::parseShapePlacement: unknown transformation %u\n", get(get(g).uint32(3)))); - break; + if (flags&0xFFF8) + { + ETONYEK_DEBUG_MSG(("IWAParser::parseShapePlacement: unknown transformation %u\n", flags)); } } if (get(g).float_(4)) @@ -1503,7 +1540,8 @@ bool IWAParser::parseShapePlacement(const IWAMessage &msg, IWORKGeometryPtr_t &g bool IWAParser::parseShapePlacement(const IWAMessage &msg) { IWORKGeometryPtr_t geometry; - const bool retval = parseShapePlacement(msg, geometry); + unsigned flags; + const bool retval = parseShapePlacement(msg, geometry, flags); m_collector.collectGeometry(geometry); return retval; } @@ -1514,7 +1552,10 @@ void IWAParser::parseMask(unsigned id, IWORKGeometryPtr_t &geometry, IWORKPathPt if (!msg) return; if (get(msg).message(1)) - parseShapePlacement(get(get(msg).message(1)), geometry); + { + unsigned flags; + parseShapePlacement(get(get(msg).message(1)), geometry, flags); + } // if (get(msg).message(2)) same code as parseDrawableShape } @@ -2250,7 +2291,8 @@ bool IWAParser::parseImage(const IWAMessage &msg) IWORKGeometryPtr_t geometry; if (msg.message(1)) { - parseShapePlacement(get(msg.message(1)), geometry); + unsigned flags; + parseShapePlacement(get(msg.message(1)), geometry, flags); m_collector.collectGeometry(geometry); } diff --git a/src/lib/IWAParser.h b/src/lib/IWAParser.h index 0c2e3c7..ede852a 100644 --- a/src/lib/IWAParser.h +++ b/src/lib/IWAParser.h @@ -111,8 +111,9 @@ protected: void parseAuthorInComment(unsigned id); void parseCustomFormat(unsigned id); - virtual bool parseShapePlacement(const IWAMessage &msg, IWORKGeometryPtr_t &geometry); + virtual bool parseShapePlacement(const IWAMessage &msg, IWORKGeometryPtr_t &geometry, unsigned &flags); void parseMask(unsigned id, IWORKGeometryPtr_t &geometry, IWORKPathPtr_t &path); + void updateGeometryUsingTextRef(unsigned id, IWORKGeometry &geometry, unsigned flags); const IWORKStylePtr_t queryCharacterStyle(unsigned id) const; const IWORKStylePtr_t queryParagraphStyle(unsigned id) const; diff --git a/src/lib/KEY6Parser.cpp b/src/lib/KEY6Parser.cpp index 748a478..9f83a95 100644 --- a/src/lib/KEY6Parser.cpp +++ b/src/lib/KEY6Parser.cpp @@ -184,7 +184,10 @@ bool KEY6Parser::parsePlaceholder(const unsigned id) IWORKGeometryPtr_t geometry; const IWAMessageField &placement = get(shape).message(1); if (placement) - parseShapePlacement(get(placement), geometry); + { + unsigned flags; + parseShapePlacement(get(placement), geometry, flags); + } assert(!m_currentText); m_currentText = m_collector.createText(m_langManager); parseText(get(textRef)); diff --git a/src/lib/NUM3Parser.cpp b/src/lib/NUM3Parser.cpp index 0126152..45a0656 100644 --- a/src/lib/NUM3Parser.cpp +++ b/src/lib/NUM3Parser.cpp @@ -42,10 +42,10 @@ bool NUM3Parser::parseSheet(unsigned id) return true; } -bool NUM3Parser::parseShapePlacement(const IWAMessage &msg, IWORKGeometryPtr_t &geometry) +bool NUM3Parser::parseShapePlacement(const IWAMessage &msg, IWORKGeometryPtr_t &geometry, unsigned &flags) { geometry = std::make_shared<IWORKGeometry>(); - + flags=3; // no auto resize const boost::optional<IWAMessage> &g = msg.message(1).optional(); if (g) { diff --git a/src/lib/NUM3Parser.h b/src/lib/NUM3Parser.h index 65266c5..bae9912 100644 --- a/src/lib/NUM3Parser.h +++ b/src/lib/NUM3Parser.h @@ -24,7 +24,7 @@ public: private: bool parseDocument() override; - bool parseShapePlacement(const IWAMessage &msg, IWORKGeometryPtr_t &geometry) override; + bool parseShapePlacement(const IWAMessage &msg, IWORKGeometryPtr_t &geometry, unsigned &flags) override; bool parseStickyNote(const IWAMessage &msg) override; bool parseSheet(unsigned id); |