summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorosnola <alonso@loria.fr>2017-05-11 10:21:17 +0200
committerDavid Tardon <dtardon@redhat.com>2017-07-19 15:22:00 +0200
commitcd0a7a0278cd6daf5e3d005d8e7a313daa175be2 (patch)
treeb5665071de109862fc08374dfc2af6f8ff9d7e23
parentc419a9c2d9b216c500e961445ad785955b6eeae9 (diff)
Try to retrieve more line/fill styles + correct textbox's rotation center.
Change-Id: I7fccc17b00e5e0d82dcca572ac600fb5bbdb6744
-rw-r--r--src/lib/FHCollector.cpp114
-rw-r--r--src/lib/FHCollector.h11
-rw-r--r--src/lib/FHParser.cpp76
-rw-r--r--src/lib/FHTypes.h19
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;