summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorosnola <alonso@loria.fr>2017-05-11 10:51:46 +0200
committerDavid Tardon <dtardon@redhat.com>2017-07-19 15:22:02 +0200
commit2f2f99bbc52402fd0a913d429349798fac598f88 (patch)
tree4888f936ad2c14265c5df027239fa5399e3a7087
parentcd0a7a0278cd6daf5e3d005d8e7a313daa175be2 (diff)
v3: try to retrieve the text effect, v4: try to retrieve more complex textbox
Note: The v4’s textboxes are some tables which can contain many rows and many columns. Currently, when a textbox contains several cells, I set its size to the table’s dimension. If we can chain textbox, we can do better (i.e. I begin to code it, look for HAVE_CHAINED_TEXTBOX in FHCollector.cpp) Change-Id: I886911f4bc5cc3a6aa878c0be96699030862d3f8
-rw-r--r--src/lib/FHCollector.cpp307
-rw-r--r--src/lib/FHCollector.h7
-rw-r--r--src/lib/FHConstants.h15
-rw-r--r--src/lib/FHParser.cpp71
-rw-r--r--src/lib/FHTypes.h26
5 files changed, 344 insertions, 82 deletions
diff --git a/src/lib/FHCollector.cpp b/src/lib/FHCollector.cpp
index ec73cc9..c79bb31 100644
--- a/src/lib/FHCollector.cpp
+++ b/src/lib/FHCollector.cpp
@@ -238,14 +238,14 @@ private:
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_pathTexts(), m_tStrings(), m_fonts(), m_tEffects(), m_paragraphs(), m_tabs(), m_textBloks(), m_textObjects(), m_charProperties(),
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(),
m_linePatterns(), m_arrowPaths(),
- m_strokeId(0), m_fillId(0), m_contentId(0), m_visitedObjects()
+ m_strokeId(0), m_fillId(0), m_contentId(0), m_textBoxNumberId(0), m_visitedObjects()
{
}
@@ -339,6 +339,11 @@ void libfreehand::FHCollector::collectAGDFont(unsigned recordId, const FHAGDFont
m_fonts[recordId] = font;
}
+void libfreehand::FHCollector::collectTEffect(unsigned recordId, const FHTEffect &tEffect)
+{
+ m_tEffects[recordId] = tEffect;
+}
+
void libfreehand::FHCollector::collectParagraph(unsigned recordId, const FHParagraph &paragraph)
{
m_paragraphs[recordId] = paragraph;
@@ -1380,93 +1385,192 @@ void libfreehand::FHCollector::_outputTextObject(const libfreehand::FHTextObject
if (!painter || !textObject)
return;
- double xa = textObject->m_startX;
- double ya = textObject->m_startY;
- double xb = textObject->m_startX + textObject->m_width;
- double yb = textObject->m_startY + textObject->m_height;
- double xc = xa;
- double yc = yb;
- unsigned xFormId = textObject->m_xFormId;
- if (xFormId)
+ double width=textObject->m_width;
+ double height=textObject->m_height;
+ unsigned num[]= {textObject->m_colNum,textObject->m_rowNum};
+ double decalX[]= {width+textObject->m_colSep,0};
+ double decalY[]= {0, height+textObject->m_rowSep};
+ if (textObject->m_rowBreakFirst)
{
- const FHTransform *trafo = _findTransform(xFormId);
- if (trafo)
+ std::swap(num[0],num[1]);
+ std::swap(decalX[0],decalX[1]);
+ std::swap(decalY[0],decalY[1]);
+ }
+ for (int i=0; i<2; ++i)
+ {
+ if (num[i]<=0 || num[i]>10)
{
- trafo->applyToPoint(xa, ya);
- trafo->applyToPoint(xb, yb);
- trafo->applyToPoint(xc, yc);
+ FH_DEBUG_MSG(("libfreehand::FHCollector::_outputTextObject: the number of row/col seems bad\n"));
+ num[i]=1;
}
}
- std::stack<FHTransform> groupTransforms(m_currentTransforms);
- while (!groupTransforms.empty())
+ ++m_textBoxNumberId;
+ for (unsigned dim0=0; dim0<num[0]; ++dim0)
{
- groupTransforms.top().applyToPoint(xa, ya);
- groupTransforms.top().applyToPoint(xb, yb);
- groupTransforms.top().applyToPoint(xc, yc);
- groupTransforms.pop();
- }
- _normalizePoint(xa, ya);
- _normalizePoint(xb, yb);
- _normalizePoint(xc, yc);
+ for (unsigned dim1=0; dim1<num[1]; ++dim1)
+ {
+ unsigned id = dim0*num[1]+dim1;
+ double rotation = 0, finalHeight = 0, finalWidth = 0, xmid=0, ymid=0;
+ bool useShapeBox=false;
+ if ((width<=0 || height<=0) && textObject->m_pathId)
+ {
+ /* the position are not set for TFOnPath, so we must look for the shape box
+
+ Note: the width and height seem better, the x,y position are still quite random :-~
+ */
+ FHBoundingBox bbox;
+ _getBBofSomething(textObject->m_pathId, bbox);
+ useShapeBox=true;
+ xmid=0.5*(bbox.m_xmin+bbox.m_xmax);
+ ymid=0.5*(bbox.m_ymin+bbox.m_ymax);
+ width=finalWidth=(bbox.m_xmax-bbox.m_xmin);
+ height=finalHeight=(bbox.m_ymax-bbox.m_ymin);
+ }
+ if (!useShapeBox)
+ {
+#ifdef HAVE_CHAINED_TEXTBOX
+ // useme when we can chain frames in Draw
+ double startX=textObject->m_startX+dim0*decalX[0]+dim1*decalX[1];
+ double startY=textObject->m_startY+dim0*decalY[0]+dim1*decalY[1];
+#else
+ /* if the number of row/column is greater than 1, we have a
+ big problem. Let increase the text-box size to contain all
+ the chained text-boxes...
+ */
+ double startX=textObject->m_startX;
+ double startY=textObject->m_startY;
+ width += (num[0]-1)*decalX[0]+(num[1]-1)*decalX[1];
+ height += (num[0]-1)*decalY[0]+(num[1]-1)*decalY[1];
+#endif
+ double xa = startX;
+ double ya = startY;
+ double xb = startX + width;
+ double yb = startY + height;
+ double xc = xa;
+ double yc = yb;
+ unsigned xFormId = textObject->m_xFormId;
+ if (xFormId)
+ {
+ const FHTransform *trafo = _findTransform(xFormId);
+ if (trafo)
+ {
+ trafo->applyToPoint(xa, ya);
+ trafo->applyToPoint(xb, yb);
+ trafo->applyToPoint(xc, yc);
+ }
+ }
+ std::stack<FHTransform> groupTransforms(m_currentTransforms);
+ while (!groupTransforms.empty())
+ {
+ groupTransforms.top().applyToPoint(xa, ya);
+ groupTransforms.top().applyToPoint(xb, yb);
+ groupTransforms.top().applyToPoint(xc, yc);
+ groupTransforms.pop();
+ }
+ _normalizePoint(xa, ya);
+ _normalizePoint(xb, yb);
+ _normalizePoint(xc, yc);
- for (std::vector<FHTransform>::const_iterator iter = m_fakeTransforms.begin(); iter != m_fakeTransforms.end(); ++iter)
- {
- iter->applyToPoint(xa, ya);
- iter->applyToPoint(xb, yb);
- iter->applyToPoint(xc, yc);
- }
+ for (std::vector<FHTransform>::const_iterator iter = m_fakeTransforms.begin(); iter != m_fakeTransforms.end(); ++iter)
+ {
+ iter->applyToPoint(xa, ya);
+ iter->applyToPoint(xb, yb);
+ iter->applyToPoint(xc, yc);
+ }
- double rotation = atan2(yb-yc, xb-xc);
- double height = sqrt((xc-xa)*(xc-xa) + (yc-ya)*(yc-ya));
- double width = sqrt((xc-xb)*(xc-xb) + (yc-yb)*(yc-yb));
- double xmid = (xa + xb) / 2.0;
- double ymid = (ya + yb) / 2.0;
+ rotation = atan2(yb-yc, xb-xc);
+ finalHeight = sqrt((xc-xa)*(xc-xa) + (yc-ya)*(yc-ya));
+ finalWidth = sqrt((xc-xb)*(xc-xb) + (yc-yb)*(yc-yb));
+ xmid = (xa + xb) / 2.0;
+ ymid = (ya + yb) / 2.0;
+ }
- librevenge::RVNGPropertyList textObjectProps;
- textObjectProps.insert("svg:x", xmid - textObject->m_width / 2.0);
- textObjectProps.insert("svg:y", ymid + textObject->m_height / 2.0);
- 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);
+ librevenge::RVNGPropertyList textObjectProps;
+ textObjectProps.insert("svg:x", xmid - width / 2.0);
+ textObjectProps.insert("svg:y", ymid + height / 2.0);
+ textObjectProps.insert("svg:height", finalHeight);
+ textObjectProps.insert("svg:width", finalWidth);
+ 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);
+ }
+#ifdef HAVE_CHAINED_TEXTBOX
+ if (id)
+ {
+ librevenge::RVNGString name;
+ name.sprintf("Textbox%d-%d",m_textBoxNumberId,id);
+ textObjectProps.insert("librevenge:frame-name",name);
+ }
+ if (id+1!=num[0]*num[1])
+ {
+ librevenge::RVNGString name;
+ name.sprintf("Textbox%d-%d",m_textBoxNumberId,id+1);
+ textObjectProps.insert("librevenge:next-frame-name",name);
+ }
+#endif
+ painter->startTextObject(textObjectProps);
- const std::vector<unsigned> *elements = _findTStringElements(textObject->m_tStringId);
- if (elements && !elements->empty())
- {
- for (std::vector<unsigned>::const_iterator iter = elements->begin(); iter != elements->end(); ++iter)
- _outputParagraph(_findParagraph(*iter), painter);
- }
+ if (id==0)
+ {
+ const std::vector<unsigned> *elements = _findTStringElements(textObject->m_tStringId);
+ unsigned actPos=0;
+ if (elements && !elements->empty())
+ {
+ for (std::vector<unsigned>::const_iterator iter = elements->begin(); iter != elements->end(); ++iter)
+ _outputParagraph(_findParagraph(*iter), painter, actPos, textObject->m_beginPos, textObject->m_endPos);
+ }
+ }
+ painter->endTextObject();
- painter->endTextObject();
+#if !defined(HAVE_CHAINED_TEXTBOX)
+ break;
+#endif
+ }
+#if !defined(HAVE_CHAINED_TEXTBOX)
+ break;
+#endif
+ }
}
-void libfreehand::FHCollector::_outputParagraph(const libfreehand::FHParagraph *paragraph, librevenge::RVNGDrawingInterface *painter)
+void libfreehand::FHCollector::_outputParagraph(const libfreehand::FHParagraph *paragraph, librevenge::RVNGDrawingInterface *painter, unsigned &actPos, unsigned minPos, unsigned maxPos)
{
if (!painter || !paragraph)
return;
- librevenge::RVNGPropertyList propList;
- _appendParagraphProperties(propList, paragraph->m_paraStyleId);
- painter->openParagraph(propList);
-
+ bool paragraphOpened=false;
std::map<unsigned, std::vector<unsigned short> >::const_iterator iter = m_textBloks.find(paragraph->m_textBlokId);
if (iter != m_textBloks.end())
{
for (std::vector<std::pair<unsigned, unsigned> >::size_type i = 0; i < paragraph->m_charStyleIds.size(); ++i)
{
- _outputTextRun(&(iter->second), paragraph->m_charStyleIds[i].first,
- (i+1 < paragraph->m_charStyleIds.size() ? paragraph->m_charStyleIds[i+1].first : iter->second.size()) - paragraph->m_charStyleIds[i].first,
- paragraph->m_charStyleIds[i].second, painter);
+ if (actPos>=maxPos) break;
+ unsigned lastChar=i+1 < paragraph->m_charStyleIds.size() ? paragraph->m_charStyleIds[i+1].first : iter->second.size();
+ unsigned numChar=lastChar-paragraph->m_charStyleIds[i].first;
+ unsigned nextPos=actPos+numChar;
+ if (nextPos<minPos)
+ {
+ actPos=nextPos;
+ continue;
+ }
+ if (!paragraphOpened)
+ {
+ librevenge::RVNGPropertyList propList;
+ _appendParagraphProperties(propList, paragraph->m_paraStyleId);
+ painter->openParagraph(propList);
+ paragraphOpened=true;
+ }
+ unsigned fChar=paragraph->m_charStyleIds[i].first + (actPos<minPos ? minPos-actPos : 0);
+ numChar=lastChar-fChar;
+ if (actPos+numChar>maxPos) numChar=maxPos-actPos;
+ _outputTextRun(&(iter->second), fChar, numChar, paragraph->m_charStyleIds[i].second, painter);
+ actPos=nextPos;
}
-
}
-
- painter->closeParagraph();
+ ++actPos; // EOL
+ if (paragraphOpened)
+ painter->closeParagraph();
}
void libfreehand::FHCollector::_appendCharacterProperties(librevenge::RVNGPropertyList &propList, unsigned charPropsId)
@@ -1494,6 +1598,36 @@ void libfreehand::FHCollector::_appendCharacterProperties(librevenge::RVNGProper
propList.insert("fo:color", color);
}
}
+ FHTEffect const *eff=_findTEffect(charProps.m_tEffectId);
+ if (eff && eff->m_nameId)
+ {
+ std::map<unsigned, librevenge::RVNGString>::const_iterator iterString = m_strings.find(eff->m_nameId);
+ if (iterString != m_strings.end())
+ {
+ librevenge::RVNGString const &type=iterString->second;
+ if (type=="InlineEffect") // inside col1, outside col0
+ {
+ propList.insert("fo:font-weight", "bold");
+ librevenge::RVNGString color = getColorString(eff->m_colorId[1]);
+ if (!color.empty())
+ propList.insert("fo:color", color);
+ }
+ else if (type=="ShadowEffect")
+ propList.insert("fo:text-shadow", "1pt 1pt");
+ else if (type=="ZoomEffect")
+ {
+ propList.insert("style:font-relief", "embossed");
+ propList.insert("fo:text-shadow", "1pt -1pt");
+ librevenge::RVNGString color = getColorString(eff->m_colorId[0]);
+ if (!color.empty())
+ propList.insert("fo:color", color);
+ }
+ else
+ {
+ FH_DEBUG_MSG(("libfreehand::FHCollector::_appendCharacterProperties: find unknown effect %s\n",type.cstr()));
+ }
+ }
+ }
for (std::map<unsigned,double>::const_iterator it=charProps.m_idToDoubleMap.begin(); it!=charProps.m_idToDoubleMap.end(); ++it)
{
switch (it->first)
@@ -1551,6 +1685,37 @@ void libfreehand::FHCollector::_appendCharacterProperties(librevenge::RVNGProper
value.sprintf("%g%%",100.*charProps.m_baselineShift/fontSize);
propList.insert("style:text-position", value);
}
+ FHTEffect const *eff=_findTEffect(charProps.m_textEffsId);
+ if (eff && eff->m_shortNameId)
+ {
+ std::map<unsigned, librevenge::RVNGString>::const_iterator iterString = m_strings.find(eff->m_shortNameId);
+ if (iterString != m_strings.end())
+ {
+ librevenge::RVNGString const &type=iterString->second;
+ if (type=="inlin") // inside col1, outside col0
+ propList.insert("fo:font-weight", "bold");
+ else if (type=="otw stol")
+ propList.insert("style:text-outline", "true");
+ else if (type=="stob")
+ propList.insert("fo:font-style", "italic");
+ else if (type=="stsh")
+ propList.insert("fo:text-shadow", "1pt 1pt");
+ else if (type=="sthv")
+ propList.insert("fo:font-weight", "bold");
+ else if (type=="extrude")
+ {
+ propList.insert("style:font-relief", "embossed");
+ propList.insert("fo:text-shadow", "1pt -1pt");
+ librevenge::RVNGString color = getColorString(eff->m_colorId[0]);
+ if (!color.empty())
+ propList.insert("fo:color", color);
+ }
+ else
+ {
+ FH_DEBUG_MSG(("libfreehand::FHCollector::_appendCharacterProperties: find unknown effect %s\n",type.cstr()));
+ }
+ }
+ }
}
void libfreehand::FHCollector::_appendTabProperties(librevenge::RVNGPropertyList &propList, const libfreehand::FHTab &tab)
@@ -2607,6 +2772,16 @@ const libfreehand::FHTransform *libfreehand::FHCollector::_findTransform(unsigne
return 0;
}
+const libfreehand::FHTEffect *libfreehand::FHCollector::_findTEffect(unsigned id)
+{
+ if (!id)
+ return 0;
+ std::map<unsigned, FHTEffect>::const_iterator iter = m_tEffects.find(id);
+ if (iter != m_tEffects.end())
+ return &(iter->second);
+ return 0;
+}
+
const libfreehand::FHParagraph *libfreehand::FHCollector::_findParagraph(unsigned id)
{
if (!id)
diff --git a/src/lib/FHCollector.h b/src/lib/FHCollector.h
index d51a198..c1bea20 100644
--- a/src/lib/FHCollector.h
+++ b/src/lib/FHCollector.h
@@ -44,6 +44,7 @@ public:
void collectCompositePath(unsigned recordId, const FHCompositePath &compositePath);
void collectTString(unsigned recordId, const std::vector<unsigned> &elements);
void collectAGDFont(unsigned recordId, const FHAGDFont &font);
+ void collectTEffect(unsigned recordId, const FHTEffect &tEffect);
void collectParagraph(unsigned recordId, const FHParagraph &paragraph);
void collectTabTable(unsigned recordId, const std::vector<FHTab> &tabs);
void collectTextBlok(unsigned recordId, const std::vector<unsigned short> &characters);
@@ -99,7 +100,7 @@ private:
void _outputCompositePath(const FHCompositePath *compositePath, librevenge::RVNGDrawingInterface *painter);
void _outputPathText(const FHPathText *pathText, librevenge::RVNGDrawingInterface *painter);
void _outputTextObject(const FHTextObject *textObject, librevenge::RVNGDrawingInterface *painter);
- void _outputParagraph(const FHParagraph *paragraph, librevenge::RVNGDrawingInterface *painter);
+ void _outputParagraph(const FHParagraph *paragraph, librevenge::RVNGDrawingInterface *painter, unsigned &actPos, unsigned minPos, unsigned maxPos);
void _outputTextRun(const std::vector<unsigned short> *characters, unsigned offset, unsigned length,
unsigned charStyleId, librevenge::RVNGDrawingInterface *painter);
void _outputDisplayText(const FHDisplayText *displayText, librevenge::RVNGDrawingInterface *painter);
@@ -155,6 +156,7 @@ private:
const FHPathText *_findPathText(unsigned id);
const FHTextObject *_findTextObject(unsigned id);
const FHTransform *_findTransform(unsigned id);
+ const FHTEffect *_findTEffect(unsigned id);
const FHParagraph *_findParagraph(unsigned id);
const std::vector<FHTab> *_findTabTable(unsigned id);
const FHPropList *_findPropList(unsigned id);
@@ -211,6 +213,7 @@ private:
std::map<unsigned, FHPathText> m_pathTexts;
std::map<unsigned, std::vector<unsigned> > m_tStrings;
std::map<unsigned, FHAGDFont> m_fonts;
+ std::map<unsigned, FHTEffect> m_tEffects;
std::map<unsigned, FHParagraph> m_paragraphs;
std::map<unsigned, std::vector<FHTab> > m_tabs;
std::map<unsigned, std::vector<unsigned short> > m_textBloks;
@@ -249,7 +252,7 @@ private:
unsigned m_strokeId;
unsigned m_fillId;
unsigned m_contentId;
-
+ unsigned m_textBoxNumberId;
std::deque<unsigned> m_visitedObjects;
};
diff --git a/src/lib/FHConstants.h b/src/lib/FHConstants.h
index 126e56a..d0c07f2 100644
--- a/src/lib/FHConstants.h
+++ b/src/lib/FHConstants.h
@@ -53,16 +53,25 @@
#define FH_AGD_STYLE 0x0e1b
#define FH_AGD_SIZE 0x0e24
-#define FH_DISLAY_BODER 0x1302
+#define FH_DISLAY_BORDER 0x1302
#define FH_INSET_BOTTOM 0x130c
-#define FH_DIMENTSION_HEIGHT 0x131c
+#define FH_DIMENSION_HEIGHT 0x131c
+#define FH_ROWBREAK_FIRST 0x132a
+#define FH_COL_SEPARATOR 0x1344
#define FH_DIMENSION_LEFT 0x134c
#define FH_INSET_LEFT 0x1354
+#define FH_LINETABLE_ID 0x1369
+#define FH_COL_NUM 0x137b
+#define FH_ROW_NUM 0x1383
#define FH_INSET_RIGHT 0x13ac
+#define FH_ROW_SEPARATOR 0x13bc
+#define FH_TEXT_PATH_ID 0x13d1
#define FH_DIMENSION_TOP 0x13dc
#define FH_INSET_TOP 0x13e4
+#define FH_TEXT_END_POS 0x13fb
+#define FH_TEXT_BEGIN_POS 0x1403
#define FH_DIMENSION_WIDTH 0x140c
-#define FH_LINETABLE_ID 0x1369
+
#define FH_EFFECT_NAME 0x1a91
#define FH_UNDERLINE_COLOR_ID 0x1ab9
#define FH_UNDERLINE_DASH_ID 0x1ac1
diff --git a/src/lib/FHParser.cpp b/src/lib/FHParser.cpp
index 00e4430..982118e 100644
--- a/src/lib/FHParser.cpp
+++ b/src/lib/FHParser.cpp
@@ -1718,6 +1718,7 @@ void libfreehand::FHParser::readPathText(librevenge::RVNGInputStream *input, lib
void libfreehand::FHParser::readPathTextLineInfo(librevenge::RVNGInputStream *input, libfreehand::FHCollector * /* collector */)
{
+ // osnola: only try for N0=5, N1=2, N2=5
input->seek(46, librevenge::RVNG_SEEK_CUR);
}
@@ -2153,20 +2154,39 @@ void libfreehand::FHParser::readTaperedFillX(librevenge::RVNGInputStream *input,
collector->collectLinearFill(m_currentRecord+1, fill);
}
-void libfreehand::FHParser::readTEffect(librevenge::RVNGInputStream *input, libfreehand::FHCollector * /* collector */)
+void libfreehand::FHParser::readTEffect(librevenge::RVNGInputStream *input, libfreehand::FHCollector *collector)
{
+ FHTEffect eff;
input->seek(4, librevenge::RVNG_SEEK_CUR);
unsigned short num = readU16(input);
input->seek(2, librevenge::RVNG_SEEK_CUR);
for (unsigned i = 0; i < num; ++i)
{
unsigned short key = readU16(input);
- input->seek(2, librevenge::RVNG_SEEK_CUR);
+ unsigned short rec = readU16(input);
if (key == 2)
- _readRecordId(input);
+ {
+ unsigned id=_readRecordId(input);
+ switch (rec)
+ {
+ case 0x1a91:
+ eff.m_nameId=id;
+ break;
+ case 0x1ab9:
+ eff.m_colorId[0]=id;
+ break;
+ case 0x1ac1:
+ eff.m_colorId[1]=id;
+ break;
+ default:
+ break;
+ }
+ }
else
input->seek(4, librevenge::RVNG_SEEK_CUR);
}
+ if (collector)
+ collector->collectTEffect(m_currentRecord+1, eff);
}
void libfreehand::FHParser::readTextBlok(librevenge::RVNGInputStream *input, libfreehand::FHCollector *collector)
@@ -2186,23 +2206,34 @@ void libfreehand::FHParser::readTextBlok(librevenge::RVNGInputStream *input, lib
#endif
}
-void libfreehand::FHParser::readTextEffs(librevenge::RVNGInputStream *input, libfreehand::FHCollector * /* collector */)
+void libfreehand::FHParser::readTextEffs(librevenge::RVNGInputStream *input, libfreehand::FHCollector *collector)
{
unsigned num = readU16(input);
- input->seek(num==0 ? 20 : 22, librevenge::RVNG_SEEK_CUR);
+ FHTEffect eff;
+ eff.m_nameId=_readRecordId(input);
+ eff.m_shortNameId=_readRecordId(input);
+ input->seek(num==0 ? 16 : 18, librevenge::RVNG_SEEK_CUR);
+ int numId=0;
for (unsigned i = 0; i < num; ++i)
{
readU16(input);
unsigned rec = readU16(input);
if (rec == 7)
{
- input->seek(8, librevenge::RVNG_SEEK_CUR);
+ input->seek(6, librevenge::RVNG_SEEK_CUR);
+ unsigned id=_readRecordId(input);
if (readU32(input))
+ {
input->seek(-4, librevenge::RVNG_SEEK_CUR);
+ if (numId<2)
+ eff.m_colorId[numId++]=id;
+ }
}
else
input->seek(12, librevenge::RVNG_SEEK_CUR);
}
+ if (collector)
+ collector->collectTEffect(m_currentRecord+1, eff);
}
void libfreehand::FHParser::readTextObject(librevenge::RVNGInputStream *input, libfreehand::FHCollector *collector)
@@ -2223,7 +2254,7 @@ void libfreehand::FHParser::readTextObject(librevenge::RVNGInputStream *input, l
unsigned key = readU32(input);
switch (key & 0xffff)
{
- case FH_DIMENTSION_HEIGHT:
+ case FH_DIMENSION_HEIGHT:
textObject.m_height = _readCoordinate(input) / 72.0;
break;
case FH_DIMENSION_LEFT:
@@ -2235,6 +2266,30 @@ void libfreehand::FHParser::readTextObject(librevenge::RVNGInputStream *input, l
case FH_DIMENSION_WIDTH:
textObject.m_width = _readCoordinate(input) / 72.0;
break;
+ case FH_ROWBREAK_FIRST:
+ textObject.m_rowBreakFirst = readU32(input);
+ break;
+ case FH_COL_SEPARATOR:
+ textObject.m_colSep = _readCoordinate(input) / 72.0;
+ break;
+ case FH_COL_NUM:
+ textObject.m_colNum = readU32(input);
+ break;
+ case FH_ROW_SEPARATOR:
+ textObject.m_rowSep = _readCoordinate(input) / 72.0;
+ break;
+ case FH_ROW_NUM:
+ textObject.m_rowNum = readU32(input);
+ break;
+ case FH_TEXT_PATH_ID:
+ textObject.m_pathId=_readRecordId(input);
+ break;
+ case FH_TEXT_BEGIN_POS:
+ textObject.m_beginPos=readU32(input);
+ break;
+ case FH_TEXT_END_POS:
+ textObject.m_endPos=readU32(input);
+ break;
default:
if ((key >> 16) == 2)
_readRecordId(input);
@@ -2430,7 +2485,7 @@ void libfreehand::FHParser::readVMpObj(librevenge::RVNGInputStream *input, libfr
{
if (!charProps)
charProps.reset(new libfreehand::FHCharProperties());
- _readRecordId(input);
+ charProps->m_tEffectId = _readRecordId(input);
break;
}
case FH_TXT_COLOR_ID:
diff --git a/src/lib/FHTypes.h b/src/lib/FHTypes.h
index ae46c36..88ac93f 100644
--- a/src/lib/FHTypes.h
+++ b/src/lib/FHTypes.h
@@ -113,14 +113,23 @@ struct FHTextObject
unsigned m_xFormId;
unsigned m_tStringId;
unsigned m_vmpObjId;
+ unsigned m_pathId;
double m_startX;
double m_startY;
double m_width;
double m_height;
+ unsigned m_beginPos;
+ unsigned m_endPos;
+ unsigned m_colNum;
+ unsigned m_rowNum;
+ double m_colSep;
+ double m_rowSep;
+ unsigned m_rowBreakFirst;
FHTextObject()
- : m_graphicStyleId(0), m_xFormId(0), m_tStringId(0), m_vmpObjId(0),
- m_startX(0.0), m_startY(0.0), m_width(0.0), m_height(0.0) {}
+ : m_graphicStyleId(0), m_xFormId(0), m_tStringId(0), m_vmpObjId(0), m_pathId(0),
+ m_startX(0.0), m_startY(0.0), m_width(0.0), m_height(0.0), m_beginPos(0), m_endPos(0xffff),
+ m_colNum(1), m_rowNum(1), m_colSep(0.0), m_rowSep(0.0), m_rowBreakFirst(0) {}
};
struct FHParagraphProperties
@@ -142,9 +151,10 @@ struct FHCharProperties
double m_fontSize;
unsigned m_fontNameId;
unsigned m_fontId;
+ unsigned m_tEffectId;
std::map<unsigned,double> m_idToDoubleMap;
FHCharProperties()
- : m_textColorId(0), m_fontSize(12.0), m_fontNameId(0), m_fontId(0), m_idToDoubleMap() {}
+ : m_textColorId(0), m_fontSize(12.0), m_fontNameId(0), m_fontId(0), m_tEffectId(0), m_idToDoubleMap() {}
};
struct FHRGBColor
@@ -274,6 +284,16 @@ struct FH3ParaProperties
FH3ParaProperties() : m_offset(0) {}
};
+struct FHTEffect
+{
+ unsigned m_nameId;
+ unsigned m_shortNameId;
+ unsigned m_colorId[2];
+ FHTEffect() : m_nameId(0), m_shortNameId(0)
+ {
+ for (int i=0; i<2; ++i) m_colorId[i]=0;
+ }
+};
struct FHDisplayText
{
unsigned m_graphicStyleId;