diff options
author | osnola <alonso@loria.fr> | 2017-05-11 10:21:17 +0200 |
---|---|---|
committer | David Tardon <dtardon@redhat.com> | 2017-07-19 15:22:00 +0200 |
commit | cd0a7a0278cd6daf5e3d005d8e7a313daa175be2 (patch) | |
tree | b5665071de109862fc08374dfc2af6f8ff9d7e23 | |
parent | c419a9c2d9b216c500e961445ad785955b6eeae9 (diff) |
Try to retrieve more line/fill styles + correct textbox's rotation center.
Change-Id: I7fccc17b00e5e0d82dcca572ac600fb5bbdb6744
-rw-r--r-- | src/lib/FHCollector.cpp | 114 | ||||
-rw-r--r-- | src/lib/FHCollector.h | 11 | ||||
-rw-r--r-- | src/lib/FHParser.cpp | 76 | ||||
-rw-r--r-- | src/lib/FHTypes.h | 19 |
4 files changed, 195 insertions, 25 deletions
diff --git a/src/lib/FHCollector.cpp b/src/lib/FHCollector.cpp index bb1432f..ec73cc9 100644 --- a/src/lib/FHCollector.cpp +++ b/src/lib/FHCollector.cpp @@ -239,7 +239,8 @@ libfreehand::FHCollector::FHCollector() : m_pageInfo(), m_fhTail(), m_block(), m_transforms(), m_paths(), m_strings(), m_names(), m_lists(), m_layers(), m_groups(), m_clipGroups(), m_currentTransforms(), m_fakeTransforms(), m_compositePaths(), m_pathTexts(), m_tStrings(), m_fonts(), m_paragraphs(), m_tabs(), m_textBloks(), m_textObjects(), m_charProperties(), - m_paragraphProperties(), m_rgbColors(), m_basicFills(), m_propertyLists(), m_basicLines(), m_displayTexts(), m_graphicStyles(), + m_paragraphProperties(), m_rgbColors(), m_basicFills(), m_propertyLists(), + m_basicLines(), m_customProcs(), m_patternLines(), m_displayTexts(), m_graphicStyles(), m_attributeHolders(), m_data(), m_dataLists(), m_images(), m_multiColorLists(), m_linearFills(), m_tints(), m_lensFills(), m_radialFills(), m_newBlends(), m_filterAttributeHolders(), m_opacityFilters(), m_shadowFilters(), m_glowFilters(), m_tileFills(), m_symbolClasses(), m_symbolInstances(), m_patternFills(), @@ -389,6 +390,16 @@ void libfreehand::FHCollector::collectBasicLine(unsigned recordId, const FHBasic m_basicLines[recordId] = line; } +void libfreehand::FHCollector::collectCustomProc(unsigned recordId, const FHCustomProc &line) +{ + m_customProcs[recordId] = line; +} + +void libfreehand::FHCollector::collectPatternLine(unsigned recordId, const FHPatternLine &line) +{ + m_patternLines[recordId] = line; +} + void libfreehand::FHCollector::collectTileFill(unsigned recordId, const FHTileFill &fill) { m_tileFills[recordId] = fill; @@ -1417,7 +1428,11 @@ void libfreehand::FHCollector::_outputTextObject(const libfreehand::FHTextObject textObjectProps.insert("svg:height", height); textObjectProps.insert("svg:width", width); if (!FH_ALMOST_ZERO(rotation)) + { textObjectProps.insert("librevenge:rotate", rotation * 180.0 / M_PI); + textObjectProps.insert("librevenge:rotate-cx",xmid); + textObjectProps.insert("librevenge:rotate-cy",ymid); + } painter->startTextObject(textObjectProps); const std::vector<unsigned> *elements = _findTStringElements(textObject->m_tStringId); @@ -1731,7 +1746,11 @@ void libfreehand::FHCollector::_outputDisplayText(const libfreehand::FHDisplayTe textObjectProps.insert(padding[i],0,librevenge::RVNG_POINT); } if (!FH_ALMOST_ZERO(rotation)) + { textObjectProps.insert("librevenge:rotate", rotation * 180.0 / M_PI); + textObjectProps.insert("librevenge:rotate-cx",xmid); + textObjectProps.insert("librevenge:rotate-cy",ymid); + } if (displayText->m_justify==4) // top-down: checkme do nothing textObjectProps.insert("style:writing-mode", "tb-lr"); painter->startTextObject(textObjectProps); @@ -2039,6 +2058,7 @@ void libfreehand::FHCollector::_appendFillProperties(librevenge::RVNGPropertyLis _appendRadialFill(propList, _findRadialFill(iter->second)); _appendTileFill(propList, _findTileFill(iter->second)); _appendPatternFill(propList, _findPatternFill(iter->second)); + _appendCustomProcFill(propList, _findCustomProc(iter->second)); } } else @@ -2057,6 +2077,7 @@ void libfreehand::FHCollector::_appendFillProperties(librevenge::RVNGPropertyLis _appendRadialFill(propList, _findRadialFill(fillId)); _appendTileFill(propList, _findTileFill(fillId)); _appendPatternFill(propList, _findPatternFill(fillId)); + _appendCustomProcFill(propList, _findCustomProc(fillId)); } else { @@ -2090,6 +2111,8 @@ void libfreehand::FHCollector::_appendStrokeProperties(librevenge::RVNGPropertyL if (iter != propertyList->m_elements.end()) { _appendBasicLine(propList, _findBasicLine(iter->second)); + _appendPatternLine(propList, _findPatternLine(iter->second)); + _appendCustomProcLine(propList, _findCustomProc(iter->second)); } } else @@ -2101,7 +2124,11 @@ void libfreehand::FHCollector::_appendStrokeProperties(librevenge::RVNGPropertyL _appendStrokeProperties(propList, graphicStyle->m_parentId); unsigned strokeId = _findStrokeId(*graphicStyle); if (strokeId) + { _appendBasicLine(propList, _findBasicLine(strokeId)); + _appendPatternLine(propList, _findPatternLine(strokeId)); + _appendCustomProcLine(propList, _findCustomProc(strokeId)); + } else { const FHFilterAttributeHolder *filterAttributeHolder = _findFilterAttributeHolder(*graphicStyle); @@ -2130,6 +2157,18 @@ void libfreehand::FHCollector::_appendBasicFill(librevenge::RVNGPropertyList &pr propList.insert("draw:fill-color", "#000000"); } +void libfreehand::FHCollector::_appendCustomProcFill(librevenge::RVNGPropertyList &propList, const libfreehand::FHCustomProc *fill) +{ + if (!fill || fill->m_ids.empty()) + return; + propList.insert("draw:fill", "solid"); + librevenge::RVNGString color = getColorString(fill->m_ids[0]); + if (!color.empty()) + propList.insert("draw:fill-color", color); + else + propList.insert("draw:fill-color", "#000000"); +} + unsigned libfreehand::FHCollector::_findContentId(unsigned graphicStyleId) { if (graphicStyleId) @@ -2461,6 +2500,33 @@ void libfreehand::FHCollector::_appendBasicLine(librevenge::RVNGPropertyList &pr _appendArrowPath(propList, _findArrowPath(basicLine->m_endArrowId), false); } +void libfreehand::FHCollector::_appendCustomProcLine(librevenge::RVNGPropertyList &propList, const libfreehand::FHCustomProc *customProc) +{ + if (!customProc) + return; + propList.insert("draw:stroke", "solid"); + librevenge::RVNGString color; + if (!customProc->m_ids.empty()) + color= getColorString(customProc->m_ids[0]); + if (!color.empty()) + propList.insert("svg:stroke-color", color); + if (!customProc->m_widths.empty()) + propList.insert("svg:stroke-width", customProc->m_widths[0], librevenge::RVNG_POINT); +} + +void libfreehand::FHCollector::_appendPatternLine(librevenge::RVNGPropertyList &propList, const libfreehand::FHPatternLine *patternLine) +{ + if (!patternLine) + return; + propList.insert("draw:stroke", "solid"); + librevenge::RVNGString color = getColorString(patternLine->m_colorId, patternLine->m_percentPattern); + if (!color.empty()) + propList.insert("svg:stroke-color", color); + else if (!propList["svg:stroke-color"]) // set to default + propList.insert("svg:stroke-color", "#000000"); + propList.insert("svg:stroke-width", patternLine->m_width); +} + const libfreehand::FHPath *libfreehand::FHCollector::_findPath(unsigned id) { if (!id) @@ -2681,6 +2747,26 @@ const libfreehand::FHBasicLine *libfreehand::FHCollector::_findBasicLine(unsigne return 0; } +const libfreehand::FHCustomProc *libfreehand::FHCollector::_findCustomProc(unsigned id) +{ + if (!id) + return 0; + std::map<unsigned, FHCustomProc>::const_iterator iter = m_customProcs.find(id); + if (iter != m_customProcs.end()) + return &(iter->second); + return 0; +} + +const libfreehand::FHPatternLine *libfreehand::FHCollector::_findPatternLine(unsigned id) +{ + if (!id) + return 0; + std::map<unsigned, FHPatternLine>::const_iterator iter = m_patternLines.find(id); + if (iter != m_patternLines.end()) + return &(iter->second); + return 0; +} + const libfreehand::FHRGBColor *libfreehand::FHCollector::_findRGBColor(unsigned id) { if (!id) @@ -2834,7 +2920,7 @@ unsigned libfreehand::FHCollector::_findFillId(const libfreehand::FHGraphicStyle // Add other fills if we support them if (_findBasicFill(valueId) || _findLinearFill(valueId) || _findLensFill(valueId) || _findRadialFill(valueId) - || _findTileFill(valueId) || _findPatternFill(valueId)) + || _findTileFill(valueId) || _findPatternFill(valueId) || _findCustomProc(valueId)) fillId = valueId; } return fillId; @@ -2889,15 +2975,27 @@ librevenge::RVNGBinaryData libfreehand::FHCollector::getImageData(unsigned id) return data; } -librevenge::RVNGString libfreehand::FHCollector::getColorString(unsigned id) +librevenge::RVNGString libfreehand::FHCollector::getColorString(unsigned id, double tintVal) { + FHRGBColor col; const FHRGBColor *color = _findRGBColor(id); if (color) - return _getColorString(*color); - const FHTintColor *tint = _findTintColor(id); - if (tint) - return _getColorString(getRGBFromTint(*tint)); - return librevenge::RVNGString(); + col=*color; + else + { + const FHTintColor *tint = _findTintColor(id); + if (!tint) + return librevenge::RVNGString(); + col=getRGBFromTint(*tint); + } + if (tintVal<=0 || tintVal>=1) + return _getColorString(col); + + FHRGBColor finalColor; + finalColor.m_red = col.m_red * tintVal + (1 - tintVal) * 65536; + finalColor.m_green = col.m_green * tintVal + (1 - tintVal) * 65536; + finalColor.m_blue = col.m_blue * tintVal + (1 - tintVal) * 65536; + return _getColorString(finalColor); } libfreehand::FHRGBColor libfreehand::FHCollector::getRGBFromTint(const FHTintColor &tint) diff --git a/src/lib/FHCollector.h b/src/lib/FHCollector.h index 846e423..d51a198 100644 --- a/src/lib/FHCollector.h +++ b/src/lib/FHCollector.h @@ -73,6 +73,8 @@ public: void collectLinearFill(unsigned recordId, const FHLinearFill &fill); void collectRadialFill(unsigned recordId, const FHRadialFill &fill); void collectBasicLine(unsigned recordId, const FHBasicLine &line); + void collectPatternLine(unsigned recordId, const FHPatternLine &line); + void collectCustomProc(unsigned recordId, const FHCustomProc &lineFill); void collectTileFill(unsigned recordId, const FHTileFill &fill); void collectPatternFill(unsigned recordId, const FHPatternFill &fill); void collectLinePattern(unsigned recordId, const FHLinePattern &line); @@ -130,6 +132,9 @@ private: void _appendStrokeProperties(librevenge::RVNGPropertyList &propList, unsigned graphicStyleId); void _appendBasicFill(librevenge::RVNGPropertyList &propList, const FHBasicFill *basicFill); void _appendBasicLine(librevenge::RVNGPropertyList &propList, const FHBasicLine *basicLine); + void _appendPatternLine(librevenge::RVNGPropertyList &propList, const FHPatternLine *basicLine); + void _appendCustomProcFill(librevenge::RVNGPropertyList &propList, const FHCustomProc *customProc); + void _appendCustomProcLine(librevenge::RVNGPropertyList &propList, const FHCustomProc *customProc); void _appendLinearFill(librevenge::RVNGPropertyList &propList, const FHLinearFill *linearFill); void _appendLensFill(librevenge::RVNGPropertyList &propList, const FHLensFill *lensFill); void _appendRadialFill(librevenge::RVNGPropertyList &propList, const FHRadialFill *radialFill); @@ -164,6 +169,8 @@ private: const FHLinePattern *_findLinePattern(unsigned id); const FHPath *_findArrowPath(unsigned id); const FHBasicLine *_findBasicLine(unsigned id); + const FHCustomProc *_findCustomProc(unsigned id); + const FHPatternLine *_findPatternLine(unsigned id); const FHRGBColor *_findRGBColor(unsigned id); const FHTintColor *_findTintColor(unsigned id); const FHDisplayText *_findDisplayText(unsigned id); @@ -174,7 +181,7 @@ private: const FWGlowFilter *_findFWGlowFilter(unsigned id); const FHFilterAttributeHolder *_findFilterAttributeHolder(unsigned id); const librevenge::RVNGBinaryData *_findData(unsigned id); - librevenge::RVNGString getColorString(unsigned id); + librevenge::RVNGString getColorString(unsigned id, double tint=1); unsigned _findFillId(const FHGraphicStyle &graphicStyle); unsigned _findStrokeId(const FHGraphicStyle &graphicStyle); const FHFilterAttributeHolder *_findFilterAttributeHolder(const FHGraphicStyle &graphicStyle); @@ -214,6 +221,8 @@ private: std::map<unsigned, FHBasicFill> m_basicFills; std::map<unsigned, FHPropList> m_propertyLists; std::map<unsigned, FHBasicLine> m_basicLines; + std::map<unsigned, FHCustomProc> m_customProcs; + std::map<unsigned, FHPatternLine> m_patternLines; std::map<unsigned, FHDisplayText> m_displayTexts; std::map<unsigned, FHGraphicStyle> m_graphicStyles; std::map<unsigned, FHAttributeHolder> m_attributeHolders; diff --git a/src/lib/FHParser.cpp b/src/lib/FHParser.cpp index e483a06..00e4430 100644 --- a/src/lib/FHParser.cpp +++ b/src/lib/FHParser.cpp @@ -611,7 +611,7 @@ void libfreehand::FHParser::readArrowPath(librevenge::RVNGInputStream *input, li { double x = _readCoordinate(input); double y = _readCoordinate(input); - std::pair<double, double> tmpPoint = std::make_pair(x, y); + std::pair<double, double> tmpPoint = std::make_pair(72.*x, 72.*y); segment.push_back(tmpPoint); } if (segment.size() == 3) @@ -727,10 +727,8 @@ void libfreehand::FHParser::readBlock(librevenge::RVNGInputStream *input, libfre for (unsigned j = 3; j; --j) _readRecordId(input); input->seek(1, librevenge::RVNG_SEEK_CUR); - for (unsigned k = 4; k; --k) + for (unsigned k = m_version < 10 ? 1 : 4; k; --k) _readRecordId(input); - if (m_version < 10) - input->seek(-6, librevenge::RVNG_SEEK_CUR); } FH_DEBUG_MSG(("Parsing Block: layerListId 0x%x\n", layerListId)); if (collector) @@ -885,11 +883,40 @@ void libfreehand::FHParser::readContourFill(librevenge::RVNGInputStream *input, } } -void libfreehand::FHParser::readCustomProc(librevenge::RVNGInputStream *input, libfreehand::FHCollector * /* collector */) +void libfreehand::FHParser::readCustomProc(librevenge::RVNGInputStream *input, libfreehand::FHCollector *collector) { + FHCustomProc line; unsigned short size = readU16(input); - _readRecordId(input); - input->seek(4+10*size, librevenge::RVNG_SEEK_CUR); + _readRecordId(input); // name + input->seek(4, librevenge::RVNG_SEEK_CUR); // ?, and N + for (int i=0; i<size; ++i) + { + int type=readU8(input); + switch (type) + { + case 0: + input->seek(7, librevenge::RVNG_SEEK_CUR); + line.m_ids.push_back(_readRecordId(input)); + break; + case 2: + case 3: + case 4: + input->seek(3, librevenge::RVNG_SEEK_CUR); + if (type==2) + line.m_widths.push_back(_readCoordinate(input)); + else if (type==3) + line.m_params.push_back(_readCoordinate(input)); + else + line.m_angles.push_back(_readCoordinate(input)); + input->seek(2, librevenge::RVNG_SEEK_CUR); + break; + default: + input->seek(9, librevenge::RVNG_SEEK_CUR); + break; + } + } + if (collector) + collector->collectCustomProc(m_currentRecord+1, line); } void libfreehand::FHParser::readDataList(librevenge::RVNGInputStream *input, libfreehand::FHCollector *collector) @@ -1706,16 +1733,24 @@ void libfreehand::FHParser::readPatternFill(librevenge::RVNGInputStream *input, void libfreehand::FHParser::readPatternLine(librevenge::RVNGInputStream *input, libfreehand::FHCollector *collector) { - FHBasicLine line; + FHPatternLine line; line.m_colorId = _readRecordId(input); - /* Here are 8 bytes correspoding to 8 lines of 8x8 pattern. - One bit per pixel. We skip the for the time being. */ - input->seek(8, librevenge::RVNG_SEEK_CUR); + int numOnes=0; + for (size_t j=0; j < 8; ++j) + { + uint8_t val=static_cast<uint8_t>(readU8(input)); + for (int b=0; b < 8; b++) + { + if (val&1) ++numOnes; + val = uint8_t(val>>1); + } + } + line.m_percentPattern=float(numOnes)/64.f; line.m_mitter = _readCoordinate(input) / 72.0; line.m_width = _readCoordinate(input) / 72.0; input->seek(4, librevenge::RVNG_SEEK_CUR); if (collector) - collector->collectBasicLine(m_currentRecord+1, line); + collector->collectPatternLine(m_currentRecord+1, line); } void libfreehand::FHParser::readPerspectiveEnvelope(librevenge::RVNGInputStream *input, libfreehand::FHCollector * /* collector */) @@ -1813,14 +1848,23 @@ void libfreehand::FHParser::readPropLst(librevenge::RVNGInputStream *input, libf collector->collectPropList(m_currentRecord+1, propertyList); } -void libfreehand::FHParser::readPSFill(librevenge::RVNGInputStream *input, libfreehand::FHCollector * /* collector */) +void libfreehand::FHParser::readPSFill(librevenge::RVNGInputStream *input, libfreehand::FHCollector *collector) { - input->seek(4, librevenge::RVNG_SEEK_CUR); + FHBasicFill fill; + fill.m_colorId = _readRecordId(input); + _readRecordId(input); // command string + if (collector) + collector->collectBasicFill(m_currentRecord+1, fill); } -void libfreehand::FHParser::readPSLine(librevenge::RVNGInputStream *input, libfreehand::FHCollector * /* collector */) +void libfreehand::FHParser::readPSLine(librevenge::RVNGInputStream *input, libfreehand::FHCollector *collector) { - input->seek(8, librevenge::RVNG_SEEK_CUR); + FHBasicLine line; + line.m_colorId = _readRecordId(input); + _readRecordId(input); // command string + line.m_width = _readCoordinate(input) / 72.0; + if (collector) + collector->collectBasicLine(m_currentRecord+1, line); } void libfreehand::FHParser::readRadialFill(librevenge::RVNGInputStream *input, libfreehand::FHCollector *collector) diff --git a/src/lib/FHTypes.h b/src/lib/FHTypes.h index 595ae22..ae46c36 100644 --- a/src/lib/FHTypes.h +++ b/src/lib/FHTypes.h @@ -198,6 +198,25 @@ struct FHBasicLine m_endArrowId(0), m_mitter(0.0), m_width(0.0) {} }; +struct FHPatternLine +{ + unsigned m_colorId; + double m_percentPattern; // percentage of 1 in the pattern + double m_mitter; + double m_width; + FHPatternLine() + : m_colorId(0), m_percentPattern(1), m_mitter(0.0), m_width(0.0) {} +}; + +struct FHCustomProc +{ + std::vector<unsigned> m_ids; + std::vector<double> m_widths; + std::vector<double> m_params; + std::vector<double> m_angles; + FHCustomProc() : m_ids(), m_widths(), m_params(), m_angles() {} +}; + struct FHBasicFill { unsigned m_colorId; |