| |
| |
| #ifndef XPRESS |
| |
| #include "tiio_pli.h" |
| |
| #include "tsystem.h" |
| #include "pli_io.h" |
| |
| #include "tregion.h" |
| #include "tsimplecolorstyles.h" |
| #include "tpalette.h" |
| |
| #include "tiio.h" |
| #include "tconvert.h" |
| #include "tcontenthistory.h" |
| #include "tstroke.h" |
| |
| typedef TVectorImage::IntersectionBranch IntersectionBranch; |
| |
| |
| const TSolidColorStyle ConstStyle(TPixel32::Black); |
| |
| static TSolidColorStyle *CurrStyle = NULL; |
| |
| namespace |
| { |
| |
| |
| |
| class PliOuputStream : public TOutputStreamInterface |
| { |
| std::vector<TStyleParam> *m_stream; |
| |
| public: |
| PliOuputStream(std::vector<TStyleParam> *stream) : m_stream(stream) {} |
| TOutputStreamInterface &operator<<(double x) |
| { |
| m_stream->push_back(TStyleParam(x)); |
| return *this; |
| } |
| TOutputStreamInterface &operator<<(int x) |
| { |
| m_stream->push_back(TStyleParam(x)); |
| return *this; |
| } |
| TOutputStreamInterface &operator<<(std::string x) |
| { |
| m_stream->push_back(TStyleParam(x)); |
| return *this; |
| } |
| TOutputStreamInterface &operator<<(USHORT x) |
| { |
| m_stream->push_back(TStyleParam(x)); |
| return *this; |
| } |
| TOutputStreamInterface &operator<<(BYTE x) |
| { |
| m_stream->push_back(TStyleParam(x)); |
| return *this; |
| } |
| TOutputStreamInterface &operator<<(const TRaster32P &x) |
| { |
| m_stream->push_back(TStyleParam(x)); |
| return *this; |
| } |
| }; |
| |
| |
| |
| class PliInputStream : public TInputStreamInterface |
| { |
| std::vector<TStyleParam> *m_stream; |
| VersionNumber m_version; |
| int m_count; |
| |
| public: |
| PliInputStream(std::vector<TStyleParam> *stream, |
| int majorVersion, int minorVersion) |
| : m_stream(stream), m_version(majorVersion, minorVersion), m_count(0) {} |
| |
| TInputStreamInterface &operator>>(double &x) |
| { |
| assert((*m_stream)[m_count].m_type == TStyleParam::SP_DOUBLE); |
| x = (*m_stream)[m_count++].m_numericVal; |
| return *this; |
| } |
| TInputStreamInterface &operator>>(int &x) |
| { |
| assert((*m_stream)[m_count].m_type == TStyleParam::SP_INT); |
| x = (int)(*m_stream)[m_count++].m_numericVal; |
| return *this; |
| } |
| TInputStreamInterface &operator>>(std::string &x) |
| { |
| if ((*m_stream)[m_count].m_type == TStyleParam::SP_INT) |
| x = toString((int)(*m_stream)[m_count++].m_numericVal); |
| else { |
| assert((*m_stream)[m_count].m_type == TStyleParam::SP_STRING); |
| x = (*m_stream)[m_count++].m_string; |
| } |
| return *this; |
| } |
| TInputStreamInterface &operator>>(BYTE &x) |
| { |
| assert((*m_stream)[m_count].m_type == TStyleParam::SP_BYTE); |
| x = (BYTE)(*m_stream)[m_count++].m_numericVal; |
| return *this; |
| } |
| TInputStreamInterface &operator>>(USHORT &x) |
| { |
| assert((*m_stream)[m_count].m_type == TStyleParam::SP_USHORT); |
| x = (USHORT)(*m_stream)[m_count++].m_numericVal; |
| return *this; |
| } |
| TInputStreamInterface &operator>>(TRaster32P &x) |
| { |
| assert((*m_stream)[m_count].m_type == TStyleParam::SP_RASTER); |
| x = (*m_stream)[m_count++].m_r; |
| return *this; |
| } |
| |
| VersionNumber versionNumber() const { return m_version; } |
| }; |
| |
| |
| |
| TPixel32 getColor(const TStroke *stroke) |
| { |
| |
| |
| |
| |
| |
| return TPixel32::Transparent; |
| } |
| |
| |
| |
| |
| |
| |
| |
| UINT findColor(const TPixel32 &color, const std::vector<TPixel> &colorArray) |
| { |
| for (UINT i = 0; i < colorArray.size(); i++) |
| if (colorArray[i] == color) |
| return i; |
| return colorArray.size(); |
| } |
| |
| |
| |
| void buildPalette(ParsedPli *pli, const TImageP img) |
| { |
| if (!pli->m_palette_tags.empty()) |
| return; |
| TVectorImageP tempVecImg = img; |
| TPalette *vPalette = tempVecImg->getPalette(); |
| unsigned int i; |
| |
| |
| |
| |
| |
| |
| |
| TFilePath fp; |
| if ((fp = vPalette->getRefImgPath()) != TFilePath()) { |
| TStyleParam styleParam("refimage" + toString(fp)); |
| StyleTag *refImageTag = new StyleTag(0, 0, 1, &styleParam); |
| pli->m_palette_tags.push_back((PliObjectTag *)refImageTag); |
| } |
| |
| |
| |
| |
| assert(vPalette->getPageCount()); |
| |
| std::vector<TStyleParam> pageNames(vPalette->getPageCount()); |
| for (i = 0; i < pageNames.size(); i++) |
| pageNames[i] = TStyleParam(toString(vPalette->getPage(i)->getName())); |
| StyleTag *pageNamesTag = new StyleTag(0, 0, pageNames.size(), pageNames.data()); |
| |
| pli->m_palette_tags.push_back((PliObjectTag *)pageNamesTag); |
| |
| |
| |
| |
| |
| |
| |
| for (i = 1; i < (unsigned)vPalette->getStyleCount(); i++) { |
| TColorStyle *style = vPalette->getStyle(i); |
| TPalette::Page *page = vPalette->getStylePage(i); |
| if (!page) |
| continue; |
| int pageIndex = 65535; |
| |
| pageIndex = page->getIndex(); |
| |
| |
| std::vector<TStyleParam> stream; |
| PliOuputStream chan(&stream); |
| style->save(chan); |
| |
| assert(pageIndex >= 0 && pageIndex <= 65535); |
| StyleTag *styleTag = new StyleTag(i, pageIndex, stream.size(), stream.data()); |
| pli->m_palette_tags.push_back((PliObjectTag *)styleTag); |
| } |
| |
| if (vPalette->isAnimated()) { |
| std::set<int> keyFrames; |
| for (i = 0; i < (unsigned)vPalette->getStyleCount(); i++) |
| for (int j = 0; j < vPalette->getKeyframeCount(i); j++) |
| keyFrames.insert(vPalette->getKeyframe(i, j)); |
| |
| std::set<int>::const_iterator it = keyFrames.begin(); |
| for (; it != keyFrames.end(); ++it) { |
| int frame = *it; |
| vPalette->setFrame(frame); |
| StyleTag *pageNamesTag = new StyleTag(frame, 0, 0, 0); |
| pli->m_palette_tags.push_back((PliObjectTag *)pageNamesTag); |
| for (i = 1; i < (unsigned)vPalette->getStyleCount(); i++) { |
| if (vPalette->isKeyframe(i, frame)) { |
| TColorStyle *style = vPalette->getStyle(i); |
| TPalette::Page *page = vPalette->getStylePage(i); |
| if (!page) |
| continue; |
| int pageIndex = 65535; |
| |
| pageIndex = page->getIndex(); |
| |
| |
| std::vector<TStyleParam> stream; |
| PliOuputStream chan(&stream); |
| style->save(chan); |
| |
| assert(pageIndex >= 0 && pageIndex <= 65535); |
| StyleTag *styleTag = new StyleTag(i, pageIndex, stream.size(), stream.data()); |
| pli->m_palette_tags.push_back((PliObjectTag *)styleTag); |
| } |
| } |
| } |
| } |
| } |
| |
| |
| |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| class TImageWriterPli : public TImageWriter |
| { |
| public: |
| TImageWriterPli(const TFilePath &, const TFrameId &frameId, TLevelWriterPli *); |
| ~TImageWriterPli() {} |
| |
| private: |
| UCHAR m_precision; |
| |
| |
| TImageWriterPli(const TImageWriterPli &); |
| TImageWriterPli &operator=(const TImageWriterPli &src); |
| |
| public: |
| void save(const TImageP &); |
| TFrameId m_frameId; |
| |
| private: |
| TLevelWriterPli *m_lwp; |
| }; |
| |
| |
| |
| TImageP TImageReaderPli::load() |
| { |
| if (!m_lrp->m_doesExist) |
| throw TImageException(getFilePath(), "Error file doesn't exist"); |
| |
| UINT majorVersionNumber, minorVersionNumber; |
| m_lrp->m_pli->getVersion(majorVersionNumber, minorVersionNumber); |
| assert(majorVersionNumber > 5 || (majorVersionNumber == 5 && minorVersionNumber >= 5)); |
| |
| return doLoad(); |
| } |
| |
| |
| |
| void readRegionVersion4x(IntersectionDataTag *tag, TVectorImage *img) |
| { |
| #ifndef NEW_REGION_FILL |
| img->setFillData(tag->m_branchArray, tag->m_branchCount); |
| #endif |
| } |
| |
| |
| |
| namespace |
| { |
| |
| struct CreateStrokeData { |
| int m_styleId; |
| TStroke::OutlineOptions m_options; |
| |
| CreateStrokeData() : m_styleId(-1) {} |
| }; |
| |
| void createStroke(ThickQuadraticChainTag *quadTag, TVectorImage *outVectImage, const CreateStrokeData &data) |
| { |
| std::vector<TThickQuadratic *> chunks(quadTag->m_numCurves); |
| |
| for (UINT k = 0; k < quadTag->m_numCurves; k++) |
| chunks[k] = &quadTag->m_curve[k]; |
| |
| TStroke *stroke = TStroke::create(chunks); |
| |
| assert(data.m_styleId != -1); |
| stroke->setStyle(data.m_styleId); |
| stroke->outlineOptions() = data.m_options; |
| |
| if (quadTag->m_isLoop) |
| stroke->setSelfLoop(); |
| |
| outVectImage->addStroke(stroke, false); |
| } |
| |
| } |
| |
| |
| |
| void createGroup(GroupTag *groupTag, TVectorImage *vi, CreateStrokeData &data) |
| { |
| int count = vi->getStrokeCount(); |
| for (int j = 0; j < groupTag->m_numObjects; j++) { |
| if (groupTag->m_object[j]->m_type == PliTag::COLOR_NGOBJ) |
| data.m_styleId = ((ColorTag *)groupTag->m_object[j])->m_color[0]; |
| else if (groupTag->m_object[j]->m_type == PliTag::OUTLINE_OPTIONS_GOBJ) |
| data.m_options = ((StrokeOutlineOptionsTag *)groupTag->m_object[j])->m_options; |
| else if (groupTag->m_object[j]->m_type == PliTag::GROUP_GOBJ) |
| createGroup((GroupTag *)groupTag->m_object[j], vi, data); |
| else { |
| assert(groupTag->m_object[j]->m_type == PliTag::THICK_QUADRATIC_CHAIN_GOBJ); |
| createStroke((ThickQuadraticChainTag *)groupTag->m_object[j], vi, data); |
| } |
| } |
| |
| vi->group(count, vi->getStrokeCount() - count); |
| } |
| |
| |
| |
| TImageP TImageReaderPli::doLoad() |
| { |
| CreateStrokeData strokeData; |
| |
| |
| TVectorImage |
| *outVectImage = new TVectorImage(true); |
| |
| |
| |
| |
| |
| |
| |
| |
| UINT i; |
| outVectImage->setAutocloseTolerance(m_lrp->m_pli->getAutocloseTolerance()); |
| |
| ImageTag *imageTag; |
| |
| imageTag = m_lrp->m_pli->loadFrame(m_frameId); |
| if (!imageTag) |
| throw TImageException(m_path, "Corrupted or invalid image data"); |
| |
| if (m_lrp->m_mapOfImage[m_frameId].second == false) |
| m_lrp->m_mapOfImage[m_frameId].second = true; |
| |
| |
| for (i = 0; i < imageTag->m_numObjects; i++) { |
| switch (imageTag->m_object[i]->m_type) { |
| case PliTag::GROUP_GOBJ: { |
| assert(((GroupTag *)imageTag->m_object[i])->m_type == GroupTag::STROKE); |
| createGroup((GroupTag *)imageTag->m_object[i], outVectImage, strokeData); |
| } |
| CASE PliTag::INTERSECTION_DATA_GOBJ : readRegionVersion4x((IntersectionDataTag *)imageTag->m_object[i], outVectImage); |
| |
| |
| CASE PliTag::THICK_QUADRATIC_CHAIN_GOBJ : createStroke((ThickQuadraticChainTag *)imageTag->m_object[i], outVectImage, strokeData); |
| |
| |
| CASE PliTag::COLOR_NGOBJ: |
| { |
| ColorTag *colorTag = (ColorTag *)imageTag->m_object[i]; |
| |
| assert(colorTag->m_numColors == 1); |
| strokeData.m_styleId = colorTag->m_color[0]; |
| |
| |
| } |
| |
| |
| CASE PliTag::OUTLINE_OPTIONS_GOBJ : strokeData.m_options = ((StrokeOutlineOptionsTag *)imageTag->m_object[i])->m_options; |
| |
| DEFAULT:; |
| } |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| #ifdef _DEBUG |
| outVectImage->checkIntersections(); |
| #endif |
| |
| return TImageP(outVectImage); |
| } |
| |
| |
| |
| TDimension TImageReaderPli::getSize() const |
| { |
| return TDimension(-1, -1); |
| } |
| |
| |
| |
| TRect TImageReaderPli::getBBox() const |
| { |
| return TRect(); |
| } |
| |
| |
| |
| TImageWriterPli::TImageWriterPli( |
| const TFilePath &f, |
| const TFrameId &frameId, |
| TLevelWriterPli *pli) |
| : TImageWriter(f), m_frameId(frameId), m_lwp(pli), m_precision(2) |
| |
| { |
| } |
| |
| |
| |
| void putStroke(TStroke *stroke, int &currStyleId, std::vector<PliObjectTag *> &tags) |
| { |
| double maxThickness = 0; |
| assert(stroke); |
| |
| int chunkCount = stroke->getChunkCount(); |
| std::vector<TThickQuadratic> strokeChain(chunkCount); |
| |
| int styleId = stroke->getStyle(); |
| assert(styleId >= 0); |
| if (currStyleId == -1 || styleId != currStyleId) { |
| currStyleId = styleId; |
| std::unique_ptr<TUINT32[]> color(new TUINT32[1]); |
| color[0] = (TUINT32)styleId; |
| |
| std::unique_ptr<ColorTag> colorTag(new ColorTag(ColorTag::SOLID, ColorTag::STROKE_COLOR, 1, std::move(color))); |
| tags.push_back(colorTag.release()); |
| } |
| |
| |
| TStroke::OutlineOptions &options = stroke->outlineOptions(); |
| if (options.m_capStyle != TStroke::OutlineOptions::ROUND_CAP || |
| options.m_joinStyle != TStroke::OutlineOptions::ROUND_JOIN) { |
| StrokeOutlineOptionsTag *outlineOptionsTag = new StrokeOutlineOptionsTag(options); |
| tags.push_back((PliObjectTag *)outlineOptionsTag); |
| } |
| |
| UINT k; |
| for (k = 0; k < (UINT)chunkCount; ++k) { |
| const TThickQuadratic *q = stroke->getChunk(k); |
| maxThickness = tmax(maxThickness, q->getThickP0().thick, q->getThickP1().thick); |
| strokeChain[k] = *q; |
| } |
| maxThickness = tmax(maxThickness, stroke->getChunk(chunkCount - 1)->getThickP2().thick); |
| |
| ThickQuadraticChainTag *quadChainTag = new ThickQuadraticChainTag(k, &strokeChain[0], maxThickness); |
| quadChainTag->m_isLoop = stroke->isSelfLoop(); |
| |
| |
| |
| tags.push_back((PliObjectTag *)quadChainTag); |
| |
| } |
| |
| |
| GroupTag *makeGroup(TVectorImageP &vi, int &currStyleId, int &index, int currDepth); |
| |
| void TImageWriterPli::save(const TImageP &img) |
| { |
| |
| TVectorImageP tempVecImg = img; |
| int currStyleId = -1; |
| if (!tempVecImg) |
| throw TImageException(m_path, "No data to save"); |
| |
| |
| |
| ++m_lwp->m_frameNumber; |
| |
| std::unique_ptr<IntersectionBranch[]> v; |
| UINT intersectionSize = tempVecImg->getFillData(v); |
| |
| |
| if (!m_lwp->m_pli) { |
| m_lwp->m_pli.reset(new ParsedPli(m_lwp->m_frameNumber, m_precision, 40, tempVecImg->getAutocloseTolerance())); |
| m_lwp->m_pli->setCreator(m_lwp->m_creator); |
| } |
| buildPalette(m_lwp->m_pli.get(), img); |
| |
| ParsedPli *pli = m_lwp->m_pli.get(); |
| |
| |
| |
| |
| |
| pli->setFrameCount(m_lwp->m_frameNumber); |
| |
| |
| std::vector<PliObjectTag *> tags; |
| |
| |
| |
| { |
| int precisionScale = sq(128); |
| pli->precisionScale() = precisionScale; |
| |
| PliTag *tag = new PrecisionScaleTag(precisionScale); |
| tags.push_back((PliObjectTag *)tag); |
| } |
| |
| |
| int numStrokes = tempVecImg->getStrokeCount(); |
| |
| int i = 0; |
| while (i < (UINT)numStrokes) { |
| if (tempVecImg->isStrokeGrouped(i)) |
| tags.push_back(makeGroup(tempVecImg, currStyleId, i, 1)); |
| else |
| putStroke(tempVecImg->getStroke(i++), currStyleId, tags); |
| } |
| |
| if (intersectionSize > 0) { |
| PliTag *tag = new IntersectionDataTag(intersectionSize, std::move(v)); |
| tags.push_back((PliObjectTag *)tag); |
| } |
| |
| int tagsSize = tags.size(); |
| std::unique_ptr<ImageTag> imageTagPtr(new ImageTag(m_frameId, tagsSize, (tagsSize > 0) ? tags.data() : nullptr)); |
| |
| pli->addTag(imageTagPtr.release()); |
| |
| |
| |
| return; |
| } |
| |
| |
| TLevelWriterPli::TLevelWriterPli(const TFilePath &path, TPropertyGroup *winfo) |
| : TLevelWriter(path, winfo) |
| , m_frameNumber(0) |
| { |
| } |
| |
| |
| |
| TLevelWriterPli::~TLevelWriterPli() |
| { |
| if (!m_pli) { |
| return; |
| } |
| try { |
| |
| CurrStyle = NULL; |
| assert(!m_pli->m_palette_tags.empty()); |
| std::unique_ptr<GroupTag> groupTag(new GroupTag(GroupTag::PALETTE, m_pli->m_palette_tags.size(), m_pli->m_palette_tags.data())); |
| m_pli->addTag(groupTag.release(), true); |
| if (m_contentHistory) { |
| QString his = m_contentHistory->serialize(); |
| std::unique_ptr<TextTag> textTag(new TextTag(his.toStdString())); |
| m_pli->addTag(textTag.release(), true); |
| } |
| m_pli->writePli(m_path); |
| } catch (...) { |
| } |
| } |
| |
| |
| |
| TImageWriterP TLevelWriterPli::getFrameWriter(TFrameId fid) |
| { |
| TImageWriterPli *iwm = new TImageWriterPli(m_path, fid, this); |
| return TImageWriterP(iwm); |
| } |
| |
| |
| |
| TLevelReaderPli::TLevelReaderPli(const TFilePath &path) |
| : TLevelReader(path), m_palette(0), m_paletteCount(0), m_doesExist(false), m_pli(0), m_readPalette(true), m_level(), m_init(false) |
| { |
| |
| if (!(m_doesExist = TFileStatus(path).doesExist())) |
| throw TImageException(getFilePath(), "Error file doesn't exist"); |
| } |
| |
| |
| |
| TLevelReaderPli::~TLevelReaderPli() |
| { |
| delete m_pli; |
| } |
| |
| |
| |
| TImageReaderP TLevelReaderPli::getFrameReader(TFrameId fid) |
| { |
| TImageReaderPli *irm = new TImageReaderPli(m_path, fid, this); |
| return TImageReaderP(irm); |
| } |
| |
| |
| |
| TPalette *readPalette(GroupTag *paletteTag, int majorVersion, int minorVersion) |
| { |
| bool newPli = (majorVersion > 5 || (majorVersion == 5 && minorVersion >= 6)); |
| |
| |
| TPalette *palette = new TPalette(); |
| |
| |
| |
| |
| |
| |
| palette->getPage(0)->removeStyle(1); |
| int frame = -1; |
| |
| |
| bool pagesRead = false; |
| |
| |
| |
| |
| |
| for (unsigned int i = 0; i < paletteTag->m_numObjects; i++) { |
| StyleTag *styleTag = (StyleTag *)paletteTag->m_object[i]; |
| |
| if (i == 0 && styleTag->m_numParams == 1 && |
| strncmp(styleTag->m_param[0].m_string.c_str(), "refimage", 8) == 0) |
| { |
| palette->setRefImgPath(TFilePath(styleTag->m_param[0].m_string.c_str() + 8)); |
| continue; |
| } |
| |
| assert(styleTag->m_type == PliTag::STYLE_NGOBJ); |
| int id = styleTag->m_id; |
| int pageIndex = styleTag->m_pageIndex; |
| if (!pagesRead && newPli) |
| { |
| pagesRead = true; |
| assert(id == 0 && pageIndex == 0); |
| assert(palette->getPageCount() == 1); |
| for (int j = 0; j < styleTag->m_numParams; j++) { |
| assert(styleTag->m_param[j].m_type == TStyleParam::SP_STRING); |
| if (j == 0) |
| palette->getPage(0)->setName(toWideString(styleTag->m_param[j].m_string)); |
| else { |
| palette->addPage(toWideString(styleTag->m_param[j].m_string)); |
| |
| } |
| } |
| continue; |
| } |
| if (styleTag->m_numParams == 0) |
| { |
| frame = styleTag->m_id; |
| palette->setFrame(frame); |
| continue; |
| } |
| TPalette::Page *page = 0; |
| |
| if (pageIndex < 65535) |
| { |
| page = palette->getPage(pageIndex); |
| assert(page); |
| } else |
| continue; |
| |
| std::vector<TStyleParam> params(styleTag->m_numParams); |
| for (int j = 0; j < styleTag->m_numParams; j++) |
| params[j] = styleTag->m_param[j]; |
| |
| PliInputStream chan(¶ms, majorVersion, minorVersion); |
| TColorStyle *style = TColorStyle::load(chan); |
| assert(id > 0); |
| if (id < palette->getStyleCount()) { |
| if (frame > -1) { |
| TColorStyle *oldStyle = palette->getStyle(id); |
| oldStyle->copy(*style); |
| palette->setKeyframe(id, frame); |
| } else |
| palette->setStyle(id, style); |
| } else { |
| assert(frame == -1); |
| while (palette->getStyleCount() < id) |
| palette->addStyle(TPixel32::Red); |
| if (page) |
| page->addStyle(palette->addStyle(style)); |
| else |
| palette->addStyle(style); |
| } |
| if (id > 0 && page && frame == -1) |
| page->addStyle(id); |
| |
| } |
| palette->setFrame(0); |
| return palette; |
| } |
| |
| |
| |
| |
| |
| void TLevelReaderPli::doReadPalette(bool doReadIt) |
| { |
| m_readPalette = doReadIt; |
| } |
| |
| QString TLevelReaderPli::getCreator() |
| { |
| loadInfo(); |
| |
| if (m_pli) |
| return m_pli->getCreator(); |
| |
| return ""; |
| } |
| |
| TLevelP TLevelReaderPli::loadInfo() |
| { |
| if (m_init) |
| return m_level; |
| |
| m_init = true; |
| |
| |
| |
| |
| |
| |
| |
| try { |
| |
| assert(!m_pli); |
| m_pli = new ParsedPli(getFilePath()); |
| UINT majorVersionNumber, minorVersionNumber; |
| m_pli->getVersion(majorVersionNumber, minorVersionNumber); |
| if (majorVersionNumber <= 5 && (majorVersionNumber != 5 || minorVersionNumber < 5)) |
| return m_level; |
| TPalette *palette = 0; |
| m_pli->loadInfo(m_readPalette, palette, m_contentHistory); |
| if (palette) |
| m_level->setPalette(palette); |
| |
| for (int i = 0; i < m_pli->getFrameCount(); i++) |
| m_level->setFrame(m_pli->getFrameNumber(i), TVectorImageP()); |
| } catch (std::exception &e) { |
| TSystem::outputDebug(e.what()); |
| |
| throw TImageException(getFilePath(), "Unknow error on reading file"); |
| } catch (...) { |
| throw; |
| } |
| |
| return m_level; |
| } |
| |
| |
| |
| TImageReaderPli::TImageReaderPli( |
| const TFilePath &f, |
| const TFrameId &frameId, |
| TLevelReaderPli *pli) |
| : TImageReader(f), m_frameId(frameId), m_lrp(pli) |
| { |
| } |
| |
| |
| |
| GroupTag *makeGroup(TVectorImageP &vi, int &currStyleId, int &index, int currDepth) |
| { |
| std::vector<PliObjectTag *> tags; |
| int i = index; |
| while (i < (UINT)vi->getStrokeCount() && vi->getCommonGroupDepth(i, index) >= currDepth) { |
| int strokeDepth = vi->getGroupDepth(i); |
| if (strokeDepth == currDepth) |
| putStroke(vi->getStroke(i++), currStyleId, tags); |
| else if (strokeDepth > currDepth) |
| tags.push_back(makeGroup(vi, currStyleId, i, currDepth + 1)); |
| else |
| assert(false); |
| } |
| index = i; |
| return new GroupTag(GroupTag::STROKE, tags.size(), tags.data()); |
| } |
| |
| |
| |
| #endif |
| |