|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "tiio_pli.h"
|
|
Toshihiro Shimizu |
890ddd |
//#include "tstrokeoutline.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tsystem.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "pli_io.h"
|
|
Toshihiro Shimizu |
890ddd |
//#include "tstrokeutil.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tregion.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tsimplecolorstyles.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tpalette.h"
|
|
Toshihiro Shimizu |
890ddd |
//#include "tspecialstyleid.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tiio.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tconvert.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tcontenthistory.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tstroke.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
typedef TVectorImage::IntersectionBranch IntersectionBranch;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//=============================================================================
|
|
Toshihiro Shimizu |
890ddd |
const TSolidColorStyle ConstStyle(TPixel32::Black);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
static TSolidColorStyle *CurrStyle = NULL;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
namespace {
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
d1f6c4 |
class PliOuputStream final : public TOutputStreamInterface {
|
|
Shinya Kitaoka |
120a6e |
std::vector<tstyleparam> *m_stream;</tstyleparam>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
PliOuputStream(std::vector<tstyleparam> *stream) : m_stream(stream) {}</tstyleparam>
|
|
Shinya Kitaoka |
473e70 |
TOutputStreamInterface &operator<<(double x) override {
|
|
Shinya Kitaoka |
120a6e |
m_stream->push_back(TStyleParam(x));
|
|
Shinya Kitaoka |
120a6e |
return *this;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
473e70 |
TOutputStreamInterface &operator<<(int x) override {
|
|
Shinya Kitaoka |
120a6e |
m_stream->push_back(TStyleParam(x));
|
|
Shinya Kitaoka |
120a6e |
return *this;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
473e70 |
TOutputStreamInterface &operator<<(std::string x) override {
|
|
Shinya Kitaoka |
120a6e |
m_stream->push_back(TStyleParam(x));
|
|
Shinya Kitaoka |
120a6e |
return *this;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
473e70 |
TOutputStreamInterface &operator<<(USHORT x) override {
|
|
Shinya Kitaoka |
120a6e |
m_stream->push_back(TStyleParam(x));
|
|
Shinya Kitaoka |
120a6e |
return *this;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
473e70 |
TOutputStreamInterface &operator<<(BYTE x) override {
|
|
Shinya Kitaoka |
120a6e |
m_stream->push_back(TStyleParam(x));
|
|
Shinya Kitaoka |
120a6e |
return *this;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
473e70 |
TOutputStreamInterface &operator<<(const TRaster32P &x) override {
|
|
Shinya Kitaoka |
120a6e |
m_stream->push_back(TStyleParam(x));
|
|
Shinya Kitaoka |
120a6e |
return *this;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
d1f6c4 |
class PliInputStream final : public TInputStreamInterface {
|
|
Shinya Kitaoka |
120a6e |
std::vector<tstyleparam> *m_stream;</tstyleparam>
|
|
Shinya Kitaoka |
120a6e |
VersionNumber m_version;
|
|
Shinya Kitaoka |
120a6e |
int m_count;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
PliInputStream(std::vector<tstyleparam> *stream, int majorVersion,</tstyleparam>
|
|
Shinya Kitaoka |
120a6e |
int minorVersion)
|
|
Shinya Kitaoka |
120a6e |
: m_stream(stream), m_version(majorVersion, minorVersion), m_count(0) {}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
TInputStreamInterface &operator>>(double &x) override {
|
|
Shinya Kitaoka |
120a6e |
assert((*m_stream)[m_count].m_type == TStyleParam::SP_DOUBLE);
|
|
Shinya Kitaoka |
120a6e |
x = (*m_stream)[m_count++].m_numericVal;
|
|
Shinya Kitaoka |
120a6e |
return *this;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
473e70 |
TInputStreamInterface &operator>>(int &x) override {
|
|
Shinya Kitaoka |
120a6e |
assert((*m_stream)[m_count].m_type == TStyleParam::SP_INT);
|
|
Shinya Kitaoka |
120a6e |
x = (int)(*m_stream)[m_count++].m_numericVal;
|
|
Shinya Kitaoka |
120a6e |
return *this;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
473e70 |
TInputStreamInterface &operator>>(std::string &x) override {
|
|
Shinya Kitaoka |
120a6e |
if ((*m_stream)[m_count].m_type == TStyleParam::SP_INT)
|
|
Shinya Kitaoka |
120a6e |
x = std::to_string(static_cast<int>((*m_stream)[m_count++].m_numericVal));</int>
|
|
Shinya Kitaoka |
120a6e |
else {
|
|
Shinya Kitaoka |
120a6e |
assert((*m_stream)[m_count].m_type == TStyleParam::SP_STRING);
|
|
Shinya Kitaoka |
120a6e |
x = (*m_stream)[m_count++].m_string;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
return *this;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
473e70 |
TInputStreamInterface &operator>>(BYTE &x) override {
|
|
Shinya Kitaoka |
120a6e |
assert((*m_stream)[m_count].m_type == TStyleParam::SP_BYTE);
|
|
Shinya Kitaoka |
120a6e |
x = (BYTE)(*m_stream)[m_count++].m_numericVal;
|
|
Shinya Kitaoka |
120a6e |
return *this;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
473e70 |
TInputStreamInterface &operator>>(USHORT &x) override {
|
|
Shinya Kitaoka |
120a6e |
assert((*m_stream)[m_count].m_type == TStyleParam::SP_USHORT);
|
|
Shinya Kitaoka |
120a6e |
x = (USHORT)(*m_stream)[m_count++].m_numericVal;
|
|
Shinya Kitaoka |
120a6e |
return *this;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
473e70 |
TInputStreamInterface &operator>>(TRaster32P &x) override {
|
|
Shinya Kitaoka |
120a6e |
assert((*m_stream)[m_count].m_type == TStyleParam::SP_RASTER);
|
|
Shinya Kitaoka |
120a6e |
x = (*m_stream)[m_count++].m_r;
|
|
Shinya Kitaoka |
120a6e |
return *this;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
VersionNumber versionNumber() const override { return m_version; }
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TPixel32 getColor(const TStroke *stroke) {
|
|
Shinya Kitaoka |
120a6e |
// const TStrokeStyle* style = stroke->getStyle();
|
|
Shinya Kitaoka |
120a6e |
// const TSolidColorStrokeStyle* style = dynamic_cast
|
|
Shinya Kitaoka |
120a6e |
// TSolidColorStrokeStyle*>( );
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// if(style) return style->getAverageColor();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return TPixel32::Transparent;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*
|
|
Shinya Kitaoka |
120a6e |
Crea la palette dei colori, in funzione di quelli
|
|
Toshihiro Shimizu |
890ddd |
trovati dalla funzione findColor
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Shinya Kitaoka |
120a6e |
UINT findColor(const TPixel32 &color, const std::vector<tpixel> &colorArray) {</tpixel>
|
|
Shinya Kitaoka |
120a6e |
for (UINT i = 0; i < colorArray.size(); i++)
|
|
Shinya Kitaoka |
120a6e |
if (colorArray[i] == color) return i;
|
|
Shinya Kitaoka |
120a6e |
return colorArray.size();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void buildPalette(ParsedPli *pli, const TImageP img) {
|
|
Shinya Kitaoka |
120a6e |
if (!pli->m_palette_tags.empty()) return;
|
|
Shinya Kitaoka |
120a6e |
TVectorImageP tempVecImg = img;
|
|
Shinya Kitaoka |
120a6e |
TPalette *vPalette = tempVecImg->getPalette();
|
|
Shinya Kitaoka |
120a6e |
unsigned int i;
|
|
Shinya Kitaoka |
120a6e |
// if (pli->m_idWrittenColorsArray.empty())
|
|
Shinya Kitaoka |
120a6e |
// {
|
|
Shinya Kitaoka |
120a6e |
// assert(vPalette);
|
|
Shinya Kitaoka |
120a6e |
// pli->m_idWrittenColorsArray.resize(vPalette->getStyleCount());
|
|
Shinya Kitaoka |
120a6e |
// }
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// se c'e' una reference image, uso il primo stile della palette per
|
|
Shinya Kitaoka |
120a6e |
// memorizzare il path
|
|
Shinya Kitaoka |
120a6e |
TFilePath fp;
|
|
Shinya Kitaoka |
120a6e |
if ((fp = vPalette->getRefImgPath()) != TFilePath()) {
|
|
Shinya Kitaoka |
120a6e |
TStyleParam styleParam("refimage" + ::to_string(fp));
|
|
Shinya Kitaoka |
120a6e |
StyleTag *refImageTag = new StyleTag(0, 0, 1, &styleParam);
|
|
Shinya Kitaoka |
120a6e |
pli->m_palette_tags.push_back((PliObjectTag *)refImageTag);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// per scrivere le pages della palette, uso in modo improprio uno stile: il
|
|
Shinya Kitaoka |
120a6e |
// primo stile
|
|
Shinya Kitaoka |
120a6e |
// della paletta(o il secondo, se c'e' una refimage) ha tutti parametri
|
|
Shinya Kitaoka |
120a6e |
// stringa, che coincidono con i nomi delle pages
|
|
Shinya Kitaoka |
120a6e |
// ilcampo m_id viene usato anche per mettere il frameIndex(per multi palette)
|
|
Shinya Kitaoka |
120a6e |
assert(vPalette->getPageCount());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
std::vector<tstyleparam> pageNames(vPalette->getPageCount());</tstyleparam>
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < pageNames.size(); i++)
|
|
Shinya Kitaoka |
120a6e |
pageNames[i] = TStyleParam(::to_string(vPalette->getPage(i)->getName()));
|
|
Shinya Kitaoka |
120a6e |
StyleTag *pageNamesTag =
|
|
Shinya Kitaoka |
120a6e |
new StyleTag(0, 0, pageNames.size(), pageNames.data());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
pli->m_palette_tags.push_back((PliObjectTag *)pageNamesTag);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/*
|
|
Shinya Kitaoka |
120a6e |
for(i=1 ; i<pli->m_idWrittenColorsArray.size(); i++ )</pli->
|
|
Shinya Kitaoka |
120a6e |
pli->m_idWrittenColorsArray[i]=false;
|
|
Shinya Kitaoka |
120a6e |
pli->m_idWrittenColorsArray[0]=true;
|
|
Shinya Kitaoka |
120a6e |
*/
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
for (i = 1; i < (unsigned)vPalette->getStyleCount(); i++) {
|
|
Shinya Kitaoka |
120a6e |
TColorStyle *style = vPalette->getStyle(i);
|
|
Shinya Kitaoka |
120a6e |
TPalette::Page *page = vPalette->getStylePage(i);
|
|
Shinya Kitaoka |
120a6e |
if (!page) continue;
|
|
Shinya Kitaoka |
120a6e |
int pageIndex = 65535;
|
|
Shinya Kitaoka |
120a6e |
// if (page)
|
|
Shinya Kitaoka |
120a6e |
pageIndex = page->getIndex();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// TColorStyle*style = tempVecImg->getPalette()->getStyle(styleId);
|
|
Shinya Kitaoka |
120a6e |
std::vector<tstyleparam> stream;</tstyleparam>
|
|
Shinya Kitaoka |
120a6e |
PliOuputStream chan(&stream);
|
|
Shinya Kitaoka |
120a6e |
style->save(chan); // viene riempito lo stream;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
assert(pageIndex >= 0 && pageIndex <= 65535);
|
|
Shinya Kitaoka |
120a6e |
StyleTag *styleTag =
|
|
Shinya Kitaoka |
120a6e |
new StyleTag(i, pageIndex, stream.size(), stream.data());
|
|
Shinya Kitaoka |
120a6e |
pli->m_palette_tags.push_back((PliObjectTag *)styleTag);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (vPalette->isAnimated()) {
|
|
Shinya Kitaoka |
120a6e |
std::set<int> keyFrames;</int>
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < (unsigned)vPalette->getStyleCount(); i++)
|
|
Shinya Kitaoka |
120a6e |
for (int j = 0; j < vPalette->getKeyframeCount(i); j++)
|
|
Shinya Kitaoka |
120a6e |
keyFrames.insert(vPalette->getKeyframe(i, j));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
std::set<int>::const_iterator it = keyFrames.begin();</int>
|
|
Shinya Kitaoka |
120a6e |
for (; it != keyFrames.end(); ++it) {
|
|
Shinya Kitaoka |
120a6e |
int frame = *it;
|
|
Shinya Kitaoka |
120a6e |
vPalette->setFrame(frame);
|
|
Shinya Kitaoka |
120a6e |
StyleTag *pageNamesTag = new StyleTag(
|
|
Shinya Kitaoka |
120a6e |
frame, 0, 0, 0); // lo so, e' orrendo. devo mettere un numero intero
|
|
Shinya Kitaoka |
120a6e |
pli->m_palette_tags.push_back((PliObjectTag *)pageNamesTag);
|
|
Shinya Kitaoka |
120a6e |
for (i = 1; i < (unsigned)vPalette->getStyleCount(); i++) {
|
|
Shinya Kitaoka |
120a6e |
if (vPalette->isKeyframe(i, frame)) {
|
|
Shinya Kitaoka |
120a6e |
TColorStyle *style = vPalette->getStyle(i);
|
|
Shinya Kitaoka |
120a6e |
TPalette::Page *page = vPalette->getStylePage(i);
|
|
Shinya Kitaoka |
120a6e |
if (!page) continue;
|
|
Shinya Kitaoka |
120a6e |
int pageIndex = 65535;
|
|
Shinya Kitaoka |
120a6e |
// if (page)
|
|
Shinya Kitaoka |
120a6e |
pageIndex = page->getIndex();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// TColorStyle*style = tempVecImg->getPalette()->getStyle(styleId);
|
|
Shinya Kitaoka |
120a6e |
std::vector<tstyleparam> stream;</tstyleparam>
|
|
Shinya Kitaoka |
120a6e |
PliOuputStream chan(&stream);
|
|
Shinya Kitaoka |
120a6e |
style->save(chan); // viene riempito lo stream;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
assert(pageIndex >= 0 && pageIndex <= 65535);
|
|
Shinya Kitaoka |
120a6e |
StyleTag *styleTag =
|
|
Shinya Kitaoka |
120a6e |
new StyleTag(i, pageIndex, stream.size(), stream.data());
|
|
Shinya Kitaoka |
120a6e |
pli->m_palette_tags.push_back((PliObjectTag *)styleTag);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
} // unnamed namespace
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//===========================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*
|
|
Toshihiro Shimizu |
890ddd |
Classe locale per la scrittura di un frame del livello.
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Shinya Kitaoka |
d1f6c4 |
class TImageWriterPli final : public TImageWriter {
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
TImageWriterPli(const TFilePath &, const TFrameId &frameId,
|
|
Shinya Kitaoka |
120a6e |
TLevelWriterPli *);
|
|
Shinya Kitaoka |
120a6e |
~TImageWriterPli() {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
private:
|
|
Shinya Kitaoka |
120a6e |
UCHAR m_precision;
|
|
Shinya Kitaoka |
120a6e |
// double m_maxThickness;
|
|
Shinya Kitaoka |
120a6e |
// not implemented
|
|
Shinya Kitaoka |
120a6e |
TImageWriterPli(const TImageWriterPli &);
|
|
Shinya Kitaoka |
120a6e |
TImageWriterPli &operator=(const TImageWriterPli &src);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
473e70 |
void save(const TImageP &) override;
|
|
Shinya Kitaoka |
120a6e |
TFrameId m_frameId;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
private:
|
|
Shinya Kitaoka |
120a6e |
TLevelWriterPli *m_lwp;
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//=============
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TImageP TImageReaderPli::load() {
|
|
Shinya Kitaoka |
120a6e |
if (!m_lrp->m_doesExist)
|
|
Shinya Kitaoka |
120a6e |
throw TImageException(getFilePath(), "Error file doesn't exist");
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
UINT majorVersionNumber, minorVersionNumber;
|
|
Shinya Kitaoka |
120a6e |
m_lrp->m_pli->getVersion(majorVersionNumber, minorVersionNumber);
|
|
Shinya Kitaoka |
120a6e |
assert(majorVersionNumber > 5 ||
|
|
Shinya Kitaoka |
120a6e |
(majorVersionNumber == 5 && minorVersionNumber >= 5));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return doLoad();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//===========================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Campbell Barton |
8c6c57 |
static void readRegionVersion4x(IntersectionDataTag *tag, TVectorImage *img) {
|
|
Shinya Kitaoka |
6f0974 |
#ifndef NEW_REGION_FILL
|
|
Shinya Kitaoka |
120a6e |
img->setFillData(tag->m_branchArray, tag->m_branchCount);
|
|
Shinya Kitaoka |
6f0974 |
#endif
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
namespace {
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
struct CreateStrokeData {
|
|
Shinya Kitaoka |
120a6e |
int m_styleId;
|
|
Shinya Kitaoka |
120a6e |
TStroke::OutlineOptions m_options;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
CreateStrokeData() : m_styleId(-1) {}
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void createStroke(ThickQuadraticChainTag *quadTag, TVectorImage *outVectImage,
|
|
Shinya Kitaoka |
120a6e |
const CreateStrokeData &data) {
|
|
Shinya Kitaoka |
120a6e |
std::vector<tthickquadratic *=""> chunks(quadTag->m_numCurves);</tthickquadratic>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
for (UINT k = 0; k < quadTag->m_numCurves; k++)
|
|
Shinya Kitaoka |
120a6e |
chunks[k] = &quadTag->m_curve[k];
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TStroke *stroke = TStroke::create(chunks);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
assert(data.m_styleId != -1);
|
|
Shinya Kitaoka |
120a6e |
stroke->setStyle(data.m_styleId);
|
|
Shinya Kitaoka |
120a6e |
stroke->outlineOptions() = data.m_options;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (quadTag->m_isLoop) stroke->setSelfLoop();
|
|
Shinya Kitaoka |
120a6e |
// stroke->setSketchMode(groupTag->m_type==GroupTag::SKETCH_STROKE);
|
|
Shinya Kitaoka |
120a6e |
outVectImage->addStroke(stroke, false);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
} // namespace
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
shun-iwasawa |
27b0cf |
static void createGroup(GroupTag *groupTag, TVectorImage *vi,
|
|
shun-iwasawa |
27b0cf |
CreateStrokeData &data) {
|
|
Shinya Kitaoka |
120a6e |
int count = vi->getStrokeCount();
|
|
Shinya Kitaoka |
120a6e |
for (int j = 0; j < groupTag->m_numObjects; j++) {
|
|
Shinya Kitaoka |
120a6e |
if (groupTag->m_object[j]->m_type == PliTag::COLOR_NGOBJ)
|
|
Shinya Kitaoka |
120a6e |
data.m_styleId = ((ColorTag *)groupTag->m_object[j])->m_color[0];
|
|
Shinya Kitaoka |
120a6e |
else if (groupTag->m_object[j]->m_type == PliTag::OUTLINE_OPTIONS_GOBJ)
|
|
Shinya Kitaoka |
120a6e |
data.m_options =
|
|
Shinya Kitaoka |
120a6e |
((StrokeOutlineOptionsTag *)groupTag->m_object[j])->m_options;
|
|
Shinya Kitaoka |
120a6e |
else if (groupTag->m_object[j]->m_type == PliTag::GROUP_GOBJ)
|
|
Shinya Kitaoka |
120a6e |
createGroup((GroupTag *)groupTag->m_object[j], vi, data);
|
|
Shinya Kitaoka |
120a6e |
else {
|
|
Shinya Kitaoka |
120a6e |
assert(groupTag->m_object[j]->m_type ==
|
|
Shinya Kitaoka |
120a6e |
PliTag::THICK_QUADRATIC_CHAIN_GOBJ);
|
|
Shinya Kitaoka |
120a6e |
createStroke((ThickQuadraticChainTag *)groupTag->m_object[j], vi, data);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
vi->group(count, vi->getStrokeCount() - count);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TImageP TImageReaderPli::doLoad() {
|
|
Shinya Kitaoka |
120a6e |
CreateStrokeData strokeData;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// preparo l'immagine da restituire
|
|
Shinya Kitaoka |
120a6e |
TVectorImage *outVectImage = new TVectorImage(true);
|
|
Shinya Kitaoka |
120a6e |
// fisso il colore di default a nero opaco
|
|
Shinya Kitaoka |
120a6e |
// TPixel currentColor=TPixel::Black;
|
|
Shinya Kitaoka |
120a6e |
// TStrokeStyle *currStyle = NULL;
|
|
Shinya Kitaoka |
120a6e |
// chiudo tutto dentro un blocco try per cautelarmi
|
|
Shinya Kitaoka |
120a6e |
// dalle eccezioni generate in lettura
|
|
Shinya Kitaoka |
120a6e |
// try
|
|
Shinya Kitaoka |
120a6e |
//{
|
|
Shinya Kitaoka |
120a6e |
// un contatore
|
|
Shinya Kitaoka |
120a6e |
UINT i;
|
|
Shinya Kitaoka |
120a6e |
outVectImage->setAutocloseTolerance(m_lrp->m_pli->getAutocloseTolerance());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
ImageTag *imageTag;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
imageTag = m_lrp->m_pli->loadFrame(m_frameId);
|
|
Shinya Kitaoka |
120a6e |
if (!imageTag)
|
|
Shinya Kitaoka |
120a6e |
throw TImageException(m_path, "Corrupted or invalid image data");
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_lrp->m_mapOfImage[m_frameId].second == false)
|
|
Shinya Kitaoka |
120a6e |
m_lrp->m_mapOfImage[m_frameId].second = true;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// per tutti gli oggetti presenti nel tag
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < imageTag->m_numObjects; i++) {
|
|
Shinya Kitaoka |
120a6e |
switch (imageTag->m_object[i]->m_type) {
|
|
Shinya Kitaoka |
120a6e |
case PliTag::GROUP_GOBJ:
|
|
Shinya Kitaoka |
120a6e |
assert(((GroupTag *)imageTag->m_object[i])->m_type == GroupTag::STROKE);
|
|
Shinya Kitaoka |
120a6e |
createGroup((GroupTag *)imageTag->m_object[i], outVectImage, strokeData);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
case PliTag::INTERSECTION_DATA_GOBJ:
|
|
Shinya Kitaoka |
120a6e |
readRegionVersion4x((IntersectionDataTag *)imageTag->m_object[i],
|
|
Shinya Kitaoka |
120a6e |
outVectImage);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
case PliTag::THICK_QUADRATIC_CHAIN_GOBJ:
|
|
Shinya Kitaoka |
120a6e |
// aggiunge le stroke quadratiche
|
|
Shinya Kitaoka |
120a6e |
createStroke((ThickQuadraticChainTag *)imageTag->m_object[i],
|
|
Shinya Kitaoka |
120a6e |
outVectImage, strokeData);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
case PliTag::COLOR_NGOBJ: {
|
|
Shinya Kitaoka |
120a6e |
// aggiunge curve quadratiche con spessore costante
|
|
Shinya Kitaoka |
120a6e |
ColorTag *colorTag = (ColorTag *)imageTag->m_object[i];
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
assert(colorTag->m_numColors == 1);
|
|
Shinya Kitaoka |
120a6e |
strokeData.m_styleId = colorTag->m_color[0];
|
|
Shinya Kitaoka |
120a6e |
// isSketch=(colorTag->m_color[0] < c_maxSketchColorNum);
|
|
Shinya Kitaoka |
120a6e |
// isSketch=(colorTag->m_color[0] < c_maxSketchColorNum);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
case PliTag::OUTLINE_OPTIONS_GOBJ:
|
|
Shinya Kitaoka |
120a6e |
// adds outline options data
|
|
Shinya Kitaoka |
120a6e |
strokeData.m_options =
|
|
Shinya Kitaoka |
120a6e |
((StrokeOutlineOptionsTag *)imageTag->m_object[i])->m_options;
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Jeremy Bullock |
e122a9 |
case PliTag::AUTOCLOSE_TOLERANCE_GOBJ:
|
|
Jeremy Bullock |
e122a9 |
// aggiunge curve quadratiche con spessore costante
|
|
Jeremy Bullock |
e122a9 |
AutoCloseToleranceTag *toleranceTag =
|
|
Jeremy Bullock |
e122a9 |
(AutoCloseToleranceTag *)imageTag->m_object[i];
|
|
Jeremy Bullock |
e122a9 |
assert(toleranceTag->m_autoCloseTolerance >= 0);
|
|
Jeremy Bullock |
e122a9 |
outVectImage->setAutocloseTolerance(
|
|
Jeremy Bullock |
e122a9 |
((double)toleranceTag->m_autoCloseTolerance) / 1000);
|
|
Jeremy Bullock |
e122a9 |
break;
|
|
Shinya Kitaoka |
120a6e |
} // switch(groupTag->m_object[j]->m_type)
|
|
Shinya Kitaoka |
120a6e |
} // for (i=0; i<imagetag->m_numObjects; i++)</imagetag->
|
|
Shinya Kitaoka |
6f0974 |
|
|
Shinya Kitaoka |
6f0974 |
//} // try
|
|
Shinya Kitaoka |
6f0974 |
|
|
Shinya Kitaoka |
120a6e |
// catch(...) // cosi' e' inutile o raccolgo qualcosa prima di rilanciare o lo
|
|
Shinya Kitaoka |
120a6e |
// elimino
|
|
Shinya Kitaoka |
6f0974 |
//{
|
|
Shinya Kitaoka |
6f0974 |
// throw;
|
|
Shinya Kitaoka |
6f0974 |
// }
|
|
Shinya Kitaoka |
6f0974 |
|
|
Shinya Kitaoka |
120a6e |
// if (regionsComputed) //WARNING !!! la seedFill mette il flag a ValidRegion a
|
|
Shinya Kitaoka |
120a6e |
// TRUE
|
|
Shinya Kitaoka |
120a6e |
// outVectImage->seedFill(); //le vecchie immagini hanno il seed
|
|
Shinya Kitaoka |
120a6e |
// (version<3.1)
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#ifdef _DEBUG
|
|
Shinya Kitaoka |
120a6e |
outVectImage->checkIntersections();
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
shun_iwasawa |
597034 |
outVectImage->findRegions();
|
|
shun_iwasawa |
597034 |
|
|
Shinya Kitaoka |
120a6e |
return TImageP(outVectImage);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TDimension TImageReaderPli::getSize() const { return TDimension(-1, -1); }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TRect TImageReaderPli::getBBox() const { return TRect(); }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//=============================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TImageWriterPli::TImageWriterPli(const TFilePath &f, const TFrameId &frameId,
|
|
Shinya Kitaoka |
120a6e |
TLevelWriterPli *pli)
|
|
Shinya Kitaoka |
120a6e |
: TImageWriter(f)
|
|
Shinya Kitaoka |
120a6e |
, m_frameId(frameId)
|
|
Shinya Kitaoka |
120a6e |
, m_lwp(pli)
|
|
Shinya Kitaoka |
120a6e |
, m_precision(2)
|
|
Toshihiro Shimizu |
890ddd |
//, m_maxThickness(0)
|
|
Shinya Kitaoka |
120a6e |
{}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Campbell Barton |
8c6c57 |
static void putStroke(TStroke *stroke, int &currStyleId,
|
|
Campbell Barton |
8c6c57 |
std::vector<pliobjecttag *=""> &tags) {</pliobjecttag>
|
|
Shinya Kitaoka |
120a6e |
double maxThickness = 0;
|
|
manongjohn |
cb224b |
bool nonStdOutline = false;
|
|
Shinya Kitaoka |
120a6e |
assert(stroke);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int chunkCount = stroke->getChunkCount();
|
|
Shinya Kitaoka |
120a6e |
std::vector<tthickquadratic> strokeChain(chunkCount);</tthickquadratic>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int styleId = stroke->getStyle();
|
|
Shinya Kitaoka |
120a6e |
assert(styleId >= 0);
|
|
Shinya Kitaoka |
120a6e |
if (currStyleId == -1 || styleId != currStyleId) {
|
|
Shinya Kitaoka |
120a6e |
currStyleId = styleId;
|
|
Shinya Kitaoka |
120a6e |
std::unique_ptr<tuint32[]> color(new TUINT32[1]);</tuint32[]>
|
|
Shinya Kitaoka |
120a6e |
color[0] = (TUINT32)styleId;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
std::unique_ptr<colortag> colorTag(new ColorTag(</colortag>
|
|
Shinya Kitaoka |
120a6e |
ColorTag::SOLID, ColorTag::STROKE_COLOR, 1, std::move(color)));
|
|
Shinya Kitaoka |
120a6e |
tags.push_back(colorTag.release());
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// If the outline options are non-standard (not round), add the outline infos
|
|
Shinya Kitaoka |
120a6e |
TStroke::OutlineOptions &options = stroke->outlineOptions();
|
|
Shinya Kitaoka |
120a6e |
if (options.m_capStyle != TStroke::OutlineOptions::ROUND_CAP ||
|
|
manongjohn |
cb224b |
options.m_joinStyle != TStroke::OutlineOptions::ROUND_JOIN ||
|
|
manongjohn |
cb224b |
options.m_miterLower != 0.0 || options.m_miterUpper != 4.0) {
|
|
Shinya Kitaoka |
120a6e |
StrokeOutlineOptionsTag *outlineOptionsTag =
|
|
Shinya Kitaoka |
120a6e |
new StrokeOutlineOptionsTag(options);
|
|
Shinya Kitaoka |
120a6e |
tags.push_back((PliObjectTag *)outlineOptionsTag);
|
|
manongjohn |
cb224b |
nonStdOutline = true;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
UINT k;
|
|
Shinya Kitaoka |
120a6e |
for (k = 0; k < (UINT)chunkCount; ++k) {
|
|
Shinya Kitaoka |
120a6e |
const TThickQuadratic *q = stroke->getChunk(k);
|
|
Shinya Kitaoka |
120a6e |
maxThickness =
|
|
Shinya Kitaoka |
120a6e |
std::max({maxThickness, q->getThickP0().thick, q->getThickP1().thick});
|
|
Shinya Kitaoka |
120a6e |
strokeChain[k] = *q;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
maxThickness = std::max(maxThickness,
|
|
Shinya Kitaoka |
120a6e |
stroke->getChunk(chunkCount - 1)->getThickP2().thick);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
ThickQuadraticChainTag *quadChainTag =
|
|
Shinya Kitaoka |
120a6e |
new ThickQuadraticChainTag(k, &strokeChain[0], maxThickness);
|
|
Shinya Kitaoka |
120a6e |
quadChainTag->m_isLoop = stroke->isSelfLoop();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// pli->addTag((PliObjectTag *)quadChainTag);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
tags.push_back((PliObjectTag *)quadChainTag);
|
|
Shinya Kitaoka |
120a6e |
// pli->addTag(groupTag[count++]);
|
|
manongjohn |
cb224b |
|
|
manongjohn |
cb224b |
if (nonStdOutline) {
|
|
manongjohn |
cb224b |
// Restore default outline settings
|
|
manongjohn |
cb224b |
TStroke::OutlineOptions resetoptions;
|
|
manongjohn |
cb224b |
StrokeOutlineOptionsTag *outlineOptionsTag =
|
|
manongjohn |
cb224b |
new StrokeOutlineOptionsTag(resetoptions);
|
|
manongjohn |
cb224b |
tags.push_back((PliObjectTag *)outlineOptionsTag);
|
|
manongjohn |
cb224b |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Shinya Kitaoka |
120a6e |
GroupTag *makeGroup(TVectorImageP &vi, int &currStyleId, int &index,
|
|
Shinya Kitaoka |
120a6e |
int currDepth);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
void TImageWriterPli::save(const TImageP &img) {
|
|
Jeremy Bullock |
e122a9 |
// Allocate an image
|
|
Shinya Kitaoka |
120a6e |
TVectorImageP tempVecImg = img;
|
|
Shinya Kitaoka |
120a6e |
int currStyleId = -1;
|
|
Shinya Kitaoka |
120a6e |
if (!tempVecImg) throw TImageException(m_path, "No data to save");
|
|
Shinya Kitaoka |
120a6e |
|
|
Jeremy Bullock |
e122a9 |
// Check that the frame about to insert is not already present
|
|
Jeremy Bullock |
e122a9 |
// So you do not increase the number of current frames
|
|
Shinya Kitaoka |
120a6e |
++m_lwp->m_frameNumber;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
std::unique_ptr<intersectionbranch[]> v;</intersectionbranch[]>
|
|
Shinya Kitaoka |
120a6e |
UINT intersectionSize = tempVecImg->getFillData(v);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// alloco l'oggetto m_lwp->m_pli ( di tipo ParsedPli ) che si occupa di
|
|
Shinya Kitaoka |
120a6e |
// costruire la struttura
|
|
Shinya Kitaoka |
120a6e |
if (!m_lwp->m_pli) {
|
|
Shinya Kitaoka |
120a6e |
m_lwp->m_pli.reset(new ParsedPli(m_lwp->m_frameNumber, m_precision, 40,
|
|
Shinya Kitaoka |
120a6e |
tempVecImg->getAutocloseTolerance()));
|
|
Shinya Kitaoka |
120a6e |
m_lwp->m_pli->setCreator(m_lwp->m_creator);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Jeremy Bullock |
e122a9 |
|
|
Shinya Kitaoka |
120a6e |
buildPalette(m_lwp->m_pli.get(), img);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
ParsedPli *pli = m_lwp->m_pli.get();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/*
|
|
Shinya Kitaoka |
120a6e |
comunico che il numero di frame e' aumentato (il parsed lo riceve nel
|
|
Shinya Kitaoka |
120a6e |
solo nel costruttore)
|
|
Shinya Kitaoka |
120a6e |
*/
|
|
Shinya Kitaoka |
120a6e |
pli->setFrameCount(m_lwp->m_frameNumber);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// alloco la struttura che conterra' i tag per la vector image corrente
|
|
Shinya Kitaoka |
120a6e |
std::vector<pliobjecttag *=""> tags;</pliobjecttag>
|
|
Shinya Kitaoka |
120a6e |
// tags = new std::vector<pliobjecttag *="">;</pliobjecttag>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Store the precision scale to be used in saving the quadratics
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
int precisionScale = sq(128);
|
|
Shinya Kitaoka |
120a6e |
pli->precisionScale() = precisionScale;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
PliTag *tag = new PrecisionScaleTag(precisionScale);
|
|
Shinya Kitaoka |
120a6e |
tags.push_back((PliObjectTag *)tag);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Jeremy Bullock |
e122a9 |
// Store the auto close tolerance
|
|
Jeremy Bullock |
e122a9 |
double pliTolerance = m_lwp->m_pli->getAutocloseTolerance();
|
|
Jeremy Bullock |
e122a9 |
// write the tag if the frame's tolerance has been changed or
|
|
Jeremy Bullock |
e122a9 |
// if the first frame's tolerance (and therefore the level's tolerance)
|
|
Jeremy Bullock |
e122a9 |
// has been changed.
|
|
Jeremy Bullock |
e122a9 |
if (!areAlmostEqual(tempVecImg->getAutocloseTolerance(), 1.15, 0.001) ||
|
|
Jeremy Bullock |
e122a9 |
!areAlmostEqual(pliTolerance, 1.15, 0.001)) {
|
|
Jeremy Bullock |
e122a9 |
int tolerance =
|
|
Jeremy Bullock |
e122a9 |
(int)((roundf(tempVecImg->getAutocloseTolerance() * 100) / 100) * 1000);
|
|
Jeremy Bullock |
e122a9 |
PliTag *tag = new AutoCloseToleranceTag(tolerance);
|
|
Jeremy Bullock |
e122a9 |
tags.push_back((PliObjectTag *)tag);
|
|
Jeremy Bullock |
e122a9 |
pli->setVersion(120, 0);
|
|
Jeremy Bullock |
e122a9 |
} else {
|
|
Jeremy Bullock |
e122a9 |
pli->setVersion(71, 0);
|
|
Jeremy Bullock |
e122a9 |
}
|
|
Shinya Kitaoka |
120a6e |
// recupero il numero di stroke dall'immagine
|
|
Shinya Kitaoka |
120a6e |
int numStrokes = tempVecImg->getStrokeCount();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int i = 0;
|
|
Shinya Kitaoka |
120a6e |
while (i < (UINT)numStrokes) {
|
|
Shinya Kitaoka |
120a6e |
if (tempVecImg->isStrokeGrouped(i))
|
|
Shinya Kitaoka |
120a6e |
tags.push_back(makeGroup(tempVecImg, currStyleId, i, 1));
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
putStroke(tempVecImg->getStroke(i++), currStyleId, tags);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (intersectionSize > 0) {
|
|
Shinya Kitaoka |
120a6e |
PliTag *tag = new IntersectionDataTag(intersectionSize, std::move(v));
|
|
Shinya Kitaoka |
120a6e |
tags.push_back((PliObjectTag *)tag);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int tagsSize = tags.size();
|
|
Shinya Kitaoka |
120a6e |
std::unique_ptr<imagetag> imageTagPtr(new ImageTag(</imagetag>
|
|
Shinya Kitaoka |
120a6e |
m_frameId, tagsSize, (tagsSize > 0) ? tags.data() : nullptr));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
pli->addTag(imageTagPtr.release());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// il ritorno e' fissato a false in quanto la
|
|
Shinya Kitaoka |
120a6e |
// scrittura avviene alla distruzione dello scrittore di livelli
|
|
Shinya Kitaoka |
120a6e |
return; // davedere false;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//=============================================================================
|
|
Toshihiro Shimizu |
890ddd |
TLevelWriterPli::TLevelWriterPli(const TFilePath &path, TPropertyGroup *winfo)
|
|
Shinya Kitaoka |
120a6e |
: TLevelWriter(path, winfo), m_frameNumber(0) {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TLevelWriterPli::~TLevelWriterPli() {
|
|
Shinya Kitaoka |
120a6e |
if (!m_pli) {
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
try {
|
|
Shinya Kitaoka |
120a6e |
// aggiungo il tag della palette
|
|
Shinya Kitaoka |
120a6e |
CurrStyle = NULL;
|
|
Shinya Kitaoka |
120a6e |
assert(!m_pli->m_palette_tags.empty());
|
|
Shinya Kitaoka |
120a6e |
std::unique_ptr<grouptag> groupTag(</grouptag>
|
|
Shinya Kitaoka |
120a6e |
new GroupTag(GroupTag::PALETTE, m_pli->m_palette_tags.size(),
|
|
Shinya Kitaoka |
120a6e |
m_pli->m_palette_tags.data()));
|
|
Shinya Kitaoka |
120a6e |
m_pli->addTag(groupTag.release(), true);
|
|
Shinya Kitaoka |
120a6e |
if (m_contentHistory) {
|
|
Shinya Kitaoka |
120a6e |
QString his = m_contentHistory->serialize();
|
|
Shinya Kitaoka |
120a6e |
std::unique_ptr<texttag> textTag(new TextTag(his.toStdString()));</texttag>
|
|
Shinya Kitaoka |
120a6e |
m_pli->addTag(textTag.release(), true);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
m_pli->writePli(m_path);
|
|
Shinya Kitaoka |
120a6e |
} catch (...) {
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TImageWriterP TLevelWriterPli::getFrameWriter(TFrameId fid) {
|
|
Shinya Kitaoka |
120a6e |
TImageWriterPli *iwm = new TImageWriterPli(m_path, fid, this);
|
|
Shinya Kitaoka |
120a6e |
return TImageWriterP(iwm);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//=============================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TLevelReaderPli::TLevelReaderPli(const TFilePath &path)
|
|
Shinya Kitaoka |
120a6e |
: TLevelReader(path)
|
|
Shinya Kitaoka |
120a6e |
, m_palette(0)
|
|
Shinya Kitaoka |
120a6e |
, m_paletteCount(0)
|
|
Shinya Kitaoka |
120a6e |
, m_doesExist(false)
|
|
Shinya Kitaoka |
120a6e |
, m_pli(0)
|
|
Shinya Kitaoka |
120a6e |
, m_readPalette(true)
|
|
Shinya Kitaoka |
120a6e |
, m_level()
|
|
Shinya Kitaoka |
120a6e |
, m_init(false) {
|
|
Shinya Kitaoka |
120a6e |
if (!(m_doesExist = TFileStatus(path).doesExist()))
|
|
Shinya Kitaoka |
120a6e |
throw TImageException(getFilePath(), "Error file doesn't exist");
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TLevelReaderPli::~TLevelReaderPli() { delete m_pli; }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TImageReaderP TLevelReaderPli::getFrameReader(TFrameId fid) {
|
|
Shinya Kitaoka |
120a6e |
TImageReaderPli *irm = new TImageReaderPli(m_path, fid, this);
|
|
Shinya Kitaoka |
120a6e |
return TImageReaderP(irm);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TPalette *readPalette(GroupTag *paletteTag, int majorVersion,
|
|
Shinya Kitaoka |
120a6e |
int minorVersion) {
|
|
Shinya Kitaoka |
120a6e |
bool newPli = (majorVersion > 5 || (majorVersion == 5 && minorVersion >= 6));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// wstring pageName(L"colors");
|
|
Shinya Kitaoka |
120a6e |
TPalette *palette = new TPalette();
|
|
Shinya Kitaoka |
120a6e |
// palette->addStyleToPage(0, pageName);
|
|
Shinya Kitaoka |
120a6e |
// palette->setStyle(0,TPixel32(255,255,255,0));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// palette->setVersion(isNew?0:-1);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// tolgo dalla pagina lo stile #1
|
|
Shinya Kitaoka |
120a6e |
palette->getPage(0)->removeStyle(1);
|
|
Shinya Kitaoka |
120a6e |
int frame = -1;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// int m = page->getStyleCount();
|
|
Shinya Kitaoka |
120a6e |
bool pagesRead = false;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// i primi due styletag della palette sono speciali;
|
|
Shinya Kitaoka |
120a6e |
// il primo, che potrebbe non esserci, contiene l'eventuale reference image
|
|
Shinya Kitaoka |
120a6e |
// path;
|
|
Shinya Kitaoka |
120a6e |
// il secondo, che c'e' sempre contiene i nomi delle pagine.
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (unsigned int i = 0; i < paletteTag->m_numObjects; i++) {
|
|
Shinya Kitaoka |
120a6e |
StyleTag *styleTag = (StyleTag *)paletteTag->m_object[i];
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (i == 0 && styleTag->m_numParams == 1 &&
|
|
Shinya Kitaoka |
120a6e |
strncmp(styleTag->m_param[0].m_string.c_str(), "refimage", 8) ==
|
|
Shinya Kitaoka |
120a6e |
0) // questo stile contiene l'eventuale refimagepath
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
palette->setRefImgPath(
|
|
Shinya Kitaoka |
120a6e |
TFilePath(styleTag->m_param[0].m_string.c_str() + 8));
|
|
Shinya Kitaoka |
120a6e |
continue;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
assert(styleTag->m_type == PliTag::STYLE_NGOBJ);
|
|
Shinya Kitaoka |
120a6e |
int id = styleTag->m_id;
|
|
Shinya Kitaoka |
120a6e |
int pageIndex = styleTag->m_pageIndex;
|
|
Shinya Kitaoka |
120a6e |
if (!pagesRead && newPli) // quewsto stile contiene le stringhe dei nomi
|
|
Shinya Kitaoka |
120a6e |
// delle pagine della paletta!
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
pagesRead = true;
|
|
Shinya Kitaoka |
120a6e |
assert(id == 0 && pageIndex == 0);
|
|
Shinya Kitaoka |
120a6e |
assert(palette->getPageCount() == 1);
|
|
Shinya Kitaoka |
120a6e |
for (int j = 0; j < styleTag->m_numParams; j++) {
|
|
Shinya Kitaoka |
120a6e |
assert(styleTag->m_param[j].m_type == TStyleParam::SP_STRING);
|
|
Shinya Kitaoka |
120a6e |
if (j == 0)
|
|
Shinya Kitaoka |
120a6e |
palette->getPage(0)->setName(
|
|
Shinya Kitaoka |
120a6e |
::to_wstring(styleTag->m_param[j].m_string));
|
|
Shinya Kitaoka |
120a6e |
else {
|
|
Shinya Kitaoka |
120a6e |
palette->addPage(::to_wstring(styleTag->m_param[j].m_string));
|
|
Shinya Kitaoka |
120a6e |
// palette->getPage(j)->addStyle(TPixel32::Red);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
continue;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (styleTag->m_numParams ==
|
|
Shinya Kitaoka |
120a6e |
0) // styletag contiene il frame di una multipalette!
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
frame = styleTag->m_id;
|
|
Shinya Kitaoka |
120a6e |
palette->setFrame(frame);
|
|
Shinya Kitaoka |
120a6e |
continue;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
TPalette::Page *page = 0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (pageIndex < 65535) // questo valore pseciale significa che il colore
|
|
Shinya Kitaoka |
120a6e |
// non sta in alcuna pagina
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
page = palette->getPage(pageIndex);
|
|
Shinya Kitaoka |
120a6e |
assert(page);
|
|
Shinya Kitaoka |
120a6e |
} else
|
|
Shinya Kitaoka |
120a6e |
continue; // i pli prima salvavano pure i colori non usati...evito di
|
|
Shinya Kitaoka |
120a6e |
// caricarli!
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
std::vector<tstyleparam> params(styleTag->m_numParams);</tstyleparam>
|
|
Shinya Kitaoka |
120a6e |
for (int j = 0; j < styleTag->m_numParams; j++)
|
|
Shinya Kitaoka |
120a6e |
params[j] = styleTag->m_param[j];
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
PliInputStream chan(¶ms, majorVersion, minorVersion);
|
|
Shinya Kitaoka |
120a6e |
TColorStyle *style = TColorStyle::load(chan); // leggo params
|
|
Shinya Kitaoka |
120a6e |
assert(id > 0);
|
|
Shinya Kitaoka |
120a6e |
if (id < palette->getStyleCount()) {
|
|
Shinya Kitaoka |
120a6e |
if (frame > -1) {
|
|
Shinya Kitaoka |
120a6e |
TColorStyle *oldStyle = palette->getStyle(id);
|
|
Shinya Kitaoka |
120a6e |
oldStyle->copy(*style);
|
|
Shinya Kitaoka |
120a6e |
palette->setKeyframe(id, frame);
|
|
Shinya Kitaoka |
120a6e |
} else
|
|
Shinya Kitaoka |
120a6e |
palette->setStyle(id, style);
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
assert(frame ==
|
|
Shinya Kitaoka |
120a6e |
-1); // uno stile animato, ci deve gia' essere nella paletta!
|
|
Shinya Kitaoka |
120a6e |
while (palette->getStyleCount() < id) palette->addStyle(TPixel32::Red);
|
|
Shinya Kitaoka |
120a6e |
if (page)
|
|
Shinya Kitaoka |
120a6e |
page->addStyle(palette->addStyle(style));
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
palette->addStyle(style);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (id > 0 && page && frame == -1) page->addStyle(id);
|
|
Shinya Kitaoka |
120a6e |
// m = page->getStyleCount();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
palette->setFrame(0);
|
|
Shinya Kitaoka |
120a6e |
return palette;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*
|
|
Toshihiro Shimizu |
890ddd |
Carico le informazioni relative al livello
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TLevelReaderPli::doReadPalette(bool doReadIt) { m_readPalette = doReadIt; }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
QString TLevelReaderPli::getCreator() {
|
|
Shinya Kitaoka |
120a6e |
loadInfo();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (m_pli) return m_pli->getCreator();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return "";
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TLevelP TLevelReaderPli::loadInfo() {
|
|
Shinya Kitaoka |
120a6e |
if (m_init) return m_level;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_init = true;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// m_level = TLevelP();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// TLevelP level;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// chiudo tutto dentro un blocco try per cautelarmi
|
|
Shinya Kitaoka |
120a6e |
// dalle eccezioni generate in lettura
|
|
Shinya Kitaoka |
120a6e |
try {
|
|
Shinya Kitaoka |
120a6e |
// alloco l'oggetto parsed
|
|
Shinya Kitaoka |
120a6e |
assert(!m_pli);
|
|
Shinya Kitaoka |
120a6e |
m_pli = new ParsedPli(getFilePath());
|
|
Shinya Kitaoka |
120a6e |
UINT majorVersionNumber, minorVersionNumber;
|
|
Shinya Kitaoka |
120a6e |
m_pli->getVersion(majorVersionNumber, minorVersionNumber);
|
|
Shinya Kitaoka |
120a6e |
if (majorVersionNumber <= 5 &&
|
|
Shinya Kitaoka |
120a6e |
(majorVersionNumber != 5 || minorVersionNumber < 5))
|
|
Shinya Kitaoka |
120a6e |
return m_level;
|
|
Shinya Kitaoka |
120a6e |
TPalette *palette = 0;
|
|
Shinya Kitaoka |
120a6e |
m_pli->loadInfo(m_readPalette, palette, m_contentHistory);
|
|
Shinya Kitaoka |
120a6e |
if (palette) m_level->setPalette(palette);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < m_pli->getFrameCount(); i++)
|
|
Shinya Kitaoka |
120a6e |
m_level->setFrame(m_pli->getFrameNumber(i), TVectorImageP());
|
|
Shinya Kitaoka |
120a6e |
} catch (std::exception &e) {
|
|
Shinya Kitaoka |
120a6e |
TSystem::outputDebug(e.what());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
throw TImageException(getFilePath(), "Unknow error on reading file");
|
|
Shinya Kitaoka |
120a6e |
} catch (...) {
|
|
Shinya Kitaoka |
120a6e |
throw;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return m_level;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TImageReaderPli::TImageReaderPli(const TFilePath &f, const TFrameId &frameId,
|
|
Shinya Kitaoka |
120a6e |
TLevelReaderPli *pli)
|
|
Shinya Kitaoka |
120a6e |
: TImageReader(f), m_frameId(frameId), m_lrp(pli) {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//=============================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
GroupTag *makeGroup(TVectorImageP &vi, int &currStyleId, int &index,
|
|
Shinya Kitaoka |
120a6e |
int currDepth) {
|
|
Shinya Kitaoka |
120a6e |
std::vector<pliobjecttag *=""> tags;</pliobjecttag>
|
|
Shinya Kitaoka |
120a6e |
int i = index;
|
|
Shinya Kitaoka |
120a6e |
while (i < (UINT)vi->getStrokeCount() &&
|
|
Shinya Kitaoka |
120a6e |
vi->getCommonGroupDepth(i, index) >= currDepth) {
|
|
Shinya Kitaoka |
120a6e |
int strokeDepth = vi->getGroupDepth(i);
|
|
Shinya Kitaoka |
120a6e |
if (strokeDepth == currDepth)
|
|
Shinya Kitaoka |
120a6e |
putStroke(vi->getStroke(i++), currStyleId, tags);
|
|
Shinya Kitaoka |
120a6e |
else if (strokeDepth > currDepth)
|
|
Shinya Kitaoka |
120a6e |
tags.push_back(makeGroup(vi, currStyleId, i, currDepth + 1));
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
assert(false);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
index = i;
|
|
Shinya Kitaoka |
120a6e |
return new GroupTag(GroupTag::STROKE, tags.size(), tags.data());
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//=============================================================================
|