|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "trastercm.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/fill.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tregion.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tstroke.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tvectorimage.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/ttileset.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/ttilesaver.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/toonzimageutils.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "skeletonlut.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tpixelutils.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include <stack></stack>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
using namespace SkeletonLut;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Shinya Kitaoka |
120a6e |
namespace { // Utility Function
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void computeSeeds(const TRasterCM32P &r, TStroke *stroke,
|
|
Shinya Kitaoka |
120a6e |
std::vector<std::pair<tpoint, int="">> &seeds) {</std::pair<tpoint,>
|
|
Shinya Kitaoka |
120a6e |
int length = (int)stroke->getLength();
|
|
Shinya Kitaoka |
120a6e |
TRect bbox = r->getBounds();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TPoint oldP;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < length; i++) {
|
|
Shinya Kitaoka |
120a6e |
TPoint p = convert(stroke->getPointAtLength(i));
|
|
Shinya Kitaoka |
120a6e |
if (p == oldP || !bbox.contains(p)) continue;
|
|
Shinya Kitaoka |
120a6e |
seeds.push_back(
|
|
Shinya Kitaoka |
120a6e |
std::pair<tpoint, int="">(p, (r->pixels(p.y) + p.x)->getPaint()));</tpoint,>
|
|
Shinya Kitaoka |
120a6e |
oldP = p;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void fillArea(const TRasterCM32P &ras, TRegion *r, int colorId,
|
|
Shinya Kitaoka |
120a6e |
bool onlyUnfilled, bool fillPaints, bool fillInks) {
|
|
Shinya Kitaoka |
120a6e |
TRect bbox = convert(r->getBBox());
|
|
Shinya Kitaoka |
120a6e |
bbox *= ras->getBounds();
|
|
Shinya Kitaoka |
120a6e |
ras->lock();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (int i = bbox.y0; i <= bbox.y1; i++) {
|
|
Shinya Kitaoka |
120a6e |
TPixelCM32 *line = ras->pixels(i);
|
|
Shinya Kitaoka |
120a6e |
std::vector<double> intersections;</double>
|
|
Shinya Kitaoka |
120a6e |
r->computeScanlineIntersections(i, intersections);
|
|
Shinya Kitaoka |
120a6e |
assert(!(intersections.size() & 0x1));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (UINT j = 0; j < intersections.size(); j += 2) {
|
|
Shinya Kitaoka |
120a6e |
if (intersections[j] == intersections[j + 1]) continue;
|
|
Shinya Kitaoka |
120a6e |
int from = std::max(tfloor(intersections[j]), bbox.x0);
|
|
Shinya Kitaoka |
120a6e |
int to = std::min(tceil(intersections[j + 1]), bbox.x1);
|
|
Shinya Kitaoka |
120a6e |
TPixelCM32 *pix = line + from;
|
|
Shinya Kitaoka |
120a6e |
for (int k = from; k < to; k++, pix++) {
|
|
Shinya Kitaoka |
120a6e |
if (fillPaints && (!onlyUnfilled || pix->getPaint() == 0))
|
|
Shinya Kitaoka |
120a6e |
pix->setPaint(colorId);
|
|
Shinya Kitaoka |
120a6e |
if (fillInks) pix->setInk(colorId);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
ras->unlock();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void restoreColors(const TRasterCM32P &r,
|
|
Shinya Kitaoka |
120a6e |
const std::vector<std::pair<tpoint, int="">> &seeds) {</std::pair<tpoint,>
|
|
Shinya Kitaoka |
120a6e |
FillParameters params;
|
|
shun-iwasawa |
f9d3f0 |
// in order to make the paint to protlude behind the line
|
|
shun-iwasawa |
f9d3f0 |
params.m_prevailing = false;
|
|
Shinya Kitaoka |
120a6e |
for (UINT i = 0; i < seeds.size(); i++) {
|
|
Shinya Kitaoka |
120a6e |
params.m_p = seeds[i].first;
|
|
Shinya Kitaoka |
120a6e |
params.m_styleId = seeds[i].second;
|
|
Shinya Kitaoka |
120a6e |
fill(r, params);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*!
|
|
Shinya Kitaoka |
120a6e |
Return true if all \b pixels in \b rect are pure paint; otherwise return
|
|
Shinya Kitaoka |
120a6e |
false.
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Shinya Kitaoka |
120a6e |
bool areRectPixelsPurePaint(TPixelCM32 *pixels, TRect rect, int wrap) {
|
|
Shinya Kitaoka |
120a6e |
int dx = rect.x1 - rect.x0;
|
|
Shinya Kitaoka |
120a6e |
TPixelCM32 *pix = pixels + rect.y0 * wrap + rect.x0;
|
|
Shinya Kitaoka |
120a6e |
int x, y;
|
|
Shinya Kitaoka |
120a6e |
for (y = rect.y0; y <= rect.y1; y++, pix += wrap - dx - 1)
|
|
Shinya Kitaoka |
120a6e |
for (x = rect.x0; x <= rect.x1; x++, pix++)
|
|
Shinya Kitaoka |
120a6e |
if (!pix->isPurePaint()) return false;
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*!
|
|
Shinya Kitaoka |
120a6e |
Return true if all \b pixels in \b rect are transparent; otherwise return
|
|
Shinya Kitaoka |
120a6e |
false.
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Shinya Kitaoka |
120a6e |
bool areRectPixelsTransparent(TPixel32 *pixels, TRect rect, int wrap) {
|
|
Shinya Kitaoka |
120a6e |
int dx = rect.x1 - rect.x0;
|
|
Shinya Kitaoka |
120a6e |
TPixel32 *pix = pixels + rect.y0 * wrap + rect.x0;
|
|
Shinya Kitaoka |
120a6e |
int x, y;
|
|
Shinya Kitaoka |
120a6e |
for (y = rect.y0; y <= rect.y1; y++, pix += wrap - dx - 1)
|
|
Shinya Kitaoka |
120a6e |
for (x = rect.x0; x <= rect.x1; x++, pix++)
|
|
Shinya Kitaoka |
120a6e |
if (pix->m <= 0) return false;
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Shinya Kitaoka |
120a6e |
} // namespace
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//=============================================================================
|
|
Toshihiro Shimizu |
890ddd |
// AreaFiller
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
AreaFiller::AreaFiller(const TRasterCM32P &ras)
|
|
Shinya Kitaoka |
120a6e |
: m_ras(ras)
|
|
Shinya Kitaoka |
120a6e |
, m_bounds(ras->getBounds())
|
|
Shinya Kitaoka |
120a6e |
, m_pixels(ras->pixels())
|
|
Shinya Kitaoka |
120a6e |
, m_wrap(ras->getWrap())
|
|
Shinya Kitaoka |
120a6e |
, m_color(0) {
|
|
Shinya Kitaoka |
120a6e |
m_ras->lock();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
AreaFiller::~AreaFiller() { m_ras->unlock(); }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Shinya Kitaoka |
120a6e |
// questa funzione viene chiamata dopo il fill rect delle aree, e colora gli
|
|
Shinya Kitaoka |
120a6e |
// inchiostri di tipo "autoink"
|
|
Shinya Kitaoka |
120a6e |
// che confinano con le aree appena fillate con il rect. rbefore e' il rect del
|
|
Shinya Kitaoka |
120a6e |
// raster prima del rectfill.
|
|
Shinya Kitaoka |
120a6e |
void fillautoInks(TRasterCM32P &rin, TRect &rect, const TRasterCM32P &rbefore,
|
|
Shinya Kitaoka |
120a6e |
TPalette *plt) {
|
|
Shinya Kitaoka |
120a6e |
assert(plt);
|
|
Shinya Kitaoka |
120a6e |
TRasterCM32P r = rin->extract(rect);
|
|
Shinya Kitaoka |
120a6e |
assert(r->getSize() == rbefore->getSize());
|
|
Shinya Kitaoka |
120a6e |
int i, j;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < r->getLy(); i++) {
|
|
Shinya Kitaoka |
120a6e |
TPixelCM32 *pix = r->pixels(i);
|
|
Shinya Kitaoka |
120a6e |
TPixelCM32 *pixb = rbefore->pixels(i);
|
|
Shinya Kitaoka |
120a6e |
for (j = 0; j < r->getLx(); j++, pix++, pixb++) {
|
|
Shinya Kitaoka |
120a6e |
int paint = pix->getPaint();
|
|
Shinya Kitaoka |
120a6e |
int tone = pix->getTone();
|
|
Shinya Kitaoka |
120a6e |
int ink = pix->getInk();
|
|
Shinya Kitaoka |
120a6e |
if (paint != pixb->getPaint() && tone > 0 && tone < 255 && ink != paint &&
|
|
Shinya Kitaoka |
120a6e |
plt->getStyle(ink)->getFlags() != 0)
|
|
Shinya Kitaoka |
120a6e |
inkFill(rin, TPoint(j, i) + rect.getP00(), paint, 0, NULL, &rect);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void AreaFiller::rectFill(const TRect &rect, int color, bool onlyUnfilled,
|
|
Shinya Kitaoka |
120a6e |
bool fillPaints, bool fillInks) {
|
|
Shinya Kitaoka |
120a6e |
// Viene trattato il caso fillInks
|
|
Shinya Kitaoka |
120a6e |
/*- FillInkのみの場合 -*/
|
|
Shinya Kitaoka |
120a6e |
if (!fillPaints) {
|
|
Shinya Kitaoka |
120a6e |
assert(fillInks);
|
|
Shinya Kitaoka |
120a6e |
assert(m_ras->getBounds().contains(rect));
|
|
Shinya Kitaoka |
120a6e |
for (int y = rect.y0; y <= rect.y1; y++) {
|
|
Shinya Kitaoka |
120a6e |
TPixelCM32 *pix = m_ras->pixels(y) + rect.x0;
|
|
Shinya Kitaoka |
120a6e |
for (int x = rect.x0; x <= rect.x1; x++, pix++) pix->setInk(color);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TRect r = m_bounds * rect;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int dx = r.x1 - r.x0;
|
|
Shinya Kitaoka |
120a6e |
int dy = (r.y1 - r.y0) * m_wrap;
|
|
Shinya Kitaoka |
120a6e |
if (dx < 2 || dy < 2) // rect degenere(area contenuta nulla), skippo.
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
std::vector<int> frameSeed(2 * (r.getLx() + r.getLy() - 2));</int>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int x, y, count1, count2;
|
|
Shinya Kitaoka |
120a6e |
/*- ptrをRect範囲のスタート地点に移動 -*/
|
|
Shinya Kitaoka |
120a6e |
Pixel *ptr = m_pixels + r.y0 * m_wrap + r.x0;
|
|
Shinya Kitaoka |
120a6e |
count1 = 0;
|
|
Shinya Kitaoka |
120a6e |
count2 = r.y1 - r.y0 + 1;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Se il rettangolo non contiene il bordo del raster e se tutti i pixels
|
|
Shinya Kitaoka |
120a6e |
// contenuti nel rettangolo sono pure paint non deve fare nulla!
|
|
Shinya Kitaoka |
120a6e |
if (!rect.contains(m_bounds) && areRectPixelsPurePaint(m_pixels, r, m_wrap))
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Viene riempito frameSeed con tutti i paint delle varie aree del rettangolo
|
|
Shinya Kitaoka |
120a6e |
// di contorno.
|
|
Shinya Kitaoka |
120a6e |
// Viene verificato se i pixels del rettangolo sono tutti pure paint.
|
|
Shinya Kitaoka |
120a6e |
/*- 輪郭のPaintのIDをframeseed内に格納 -*/
|
|
Shinya Kitaoka |
120a6e |
for (y = r.y0; y <= r.y1; y++, ptr += m_wrap, count1++, count2++) {
|
|
Shinya Kitaoka |
120a6e |
if (r.x0 > 0) frameSeed[count1] = ptr->getPaint();
|
|
Shinya Kitaoka |
120a6e |
if (r.x1 < m_ras->getLx() - 1) frameSeed[count2] = (ptr + dx)->getPaint();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
ptr = m_pixels + r.y0 * m_wrap + r.x0 + 1;
|
|
Shinya Kitaoka |
120a6e |
count1 = count2;
|
|
Shinya Kitaoka |
120a6e |
count2 = count1 + r.x1 - r.x0 - 1;
|
|
Shinya Kitaoka |
120a6e |
for (x = r.x0 + 1; x < r.x1; x++, ptr++, count1++, count2++) {
|
|
Shinya Kitaoka |
120a6e |
if (r.y0 > 0) frameSeed[count1] = ptr->getPaint();
|
|
Shinya Kitaoka |
120a6e |
if (r.y1 < m_ras->getLy() - 1) frameSeed[count2] = (ptr + dy)->getPaint();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
assert(count2 == 2 * (r.getLx() + r.getLy() - 2));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Viene fillato l'interno e il bordo del rettangolo rect con color
|
|
Shinya Kitaoka |
120a6e |
Pixel *pix = m_pixels + r.y0 * m_wrap + r.x0;
|
|
Shinya Kitaoka |
120a6e |
if (onlyUnfilled)
|
|
Shinya Kitaoka |
120a6e |
for (y = r.y0; y <= r.y1; y++, pix += m_wrap - dx - 1) {
|
|
Shinya Kitaoka |
120a6e |
for (x = r.x0; x <= r.x1; x++, pix++) {
|
|
Shinya Kitaoka |
120a6e |
if (pix->getPaint() == 0) // BackgroundStyle
|
|
Shinya Kitaoka |
120a6e |
pix->setPaint(color);
|
|
Shinya Kitaoka |
120a6e |
if (fillInks) pix->setInk(color);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
for (y = r.y0; y <= r.y1; y++, pix += m_wrap - dx - 1) {
|
|
Shinya Kitaoka |
120a6e |
for (x = r.x0; x <= r.x1; x++, pix++) {
|
|
Shinya Kitaoka |
120a6e |
pix->setPaint(color);
|
|
Shinya Kitaoka |
120a6e |
if (fillInks) pix->setInk(color);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Vengono fillati i pixel del rettangolo con i paint (mantenuti in frameSeed)
|
|
Shinya Kitaoka |
120a6e |
// che
|
|
Shinya Kitaoka |
120a6e |
// c'erano prima di fillare l'intero rettangolo, in questo modo si riportano
|
|
Shinya Kitaoka |
120a6e |
// al colore originale le aree che non sono chiuse e non dovevano essere
|
|
Shinya Kitaoka |
120a6e |
// fillate.
|
|
Shinya Kitaoka |
120a6e |
count1 = 0;
|
|
Shinya Kitaoka |
120a6e |
FillParameters params;
|
|
shun-iwasawa |
f9d3f0 |
// in order to make the paint to protlude behind the line
|
|
shun-iwasawa |
f9d3f0 |
params.m_prevailing = false;
|
|
Shinya Kitaoka |
120a6e |
if (r.x0 > 0)
|
|
Shinya Kitaoka |
120a6e |
for (y = r.y0; y <= r.y1; y++) {
|
|
Shinya Kitaoka |
120a6e |
params.m_p = TPoint(r.x0, y);
|
|
Shinya Kitaoka |
120a6e |
params.m_styleId = frameSeed[count1++];
|
|
Shinya Kitaoka |
120a6e |
fill(m_ras, params);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
count1 += r.y1 - r.y0 + 1;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (r.x1 < m_ras->getLx() - 1)
|
|
Shinya Kitaoka |
120a6e |
for (y = r.y0; y <= r.y1; y++) {
|
|
Shinya Kitaoka |
120a6e |
params.m_p = TPoint(r.x1, y);
|
|
Shinya Kitaoka |
120a6e |
params.m_styleId = frameSeed[count1++];
|
|
Shinya Kitaoka |
120a6e |
fill(m_ras, params);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
count1 += r.y1 - r.y0 + 1;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (r.y0 > 0)
|
|
Shinya Kitaoka |
120a6e |
for (x = r.x0 + 1; x < r.x1; x++) {
|
|
Shinya Kitaoka |
120a6e |
params.m_p = TPoint(x, r.y0);
|
|
Shinya Kitaoka |
120a6e |
params.m_styleId = frameSeed[count1++];
|
|
Shinya Kitaoka |
120a6e |
fill(m_ras, params);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
count1 += r.x1 - r.x0 - 1;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (r.y1 < m_ras->getLy() - 1)
|
|
Shinya Kitaoka |
120a6e |
for (x = r.x0 + 1; x < r.x1; x++) {
|
|
Shinya Kitaoka |
120a6e |
params.m_p = TPoint(x, r.y1);
|
|
Shinya Kitaoka |
120a6e |
params.m_styleId = frameSeed[count1++];
|
|
Shinya Kitaoka |
120a6e |
fill(m_ras, params);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void AreaFiller::strokeFill(TStroke *stroke, int colorId, bool onlyUnfilled,
|
|
Shinya Kitaoka |
120a6e |
bool fillPaints, bool fillInks) {
|
|
Shinya Kitaoka |
120a6e |
stroke->transform(TTranslation(convert(m_ras->getCenter())));
|
|
Shinya Kitaoka |
120a6e |
m_ras->lock();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
std::vector<std::pair<tpoint, int="">> seeds;</std::pair<tpoint,>
|
|
Shinya Kitaoka |
120a6e |
computeSeeds(m_ras, stroke, seeds);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TVectorImage app;
|
|
Shinya Kitaoka |
120a6e |
app.addStroke(stroke);
|
|
Shinya Kitaoka |
120a6e |
app.findRegions();
|
|
Shinya Kitaoka |
120a6e |
for (UINT i = 0; i < app.getRegionCount(); i++)
|
|
Shinya Kitaoka |
120a6e |
fillArea(m_ras, app.getRegion(i), colorId, onlyUnfilled, fillPaints,
|
|
Shinya Kitaoka |
120a6e |
fillInks);
|
|
Shinya Kitaoka |
120a6e |
app.removeStroke(0);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
stroke->transform(TTranslation(convert(-m_ras->getCenter())));
|
|
Shinya Kitaoka |
120a6e |
restoreColors(m_ras, seeds);
|
|
Shinya Kitaoka |
120a6e |
m_ras->unlock();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//=============================================================================
|
|
Toshihiro Shimizu |
890ddd |
// FullColorAreaFiller
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
FullColorAreaFiller::FullColorAreaFiller(const TRaster32P &ras)
|
|
Shinya Kitaoka |
120a6e |
: m_ras(ras)
|
|
Shinya Kitaoka |
120a6e |
, m_bounds(ras->getBounds())
|
|
Shinya Kitaoka |
120a6e |
, m_pixels(ras->pixels())
|
|
Shinya Kitaoka |
120a6e |
, m_wrap(ras->getWrap())
|
|
Shinya Kitaoka |
120a6e |
, m_color(0) {
|
|
Shinya Kitaoka |
120a6e |
m_ras->lock();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
FullColorAreaFiller::~FullColorAreaFiller() { m_ras->unlock(); }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void FullColorAreaFiller::rectFill(const TRect &rect,
|
|
Shinya Kitaoka |
120a6e |
const FillParameters ¶ms,
|
|
Shinya Kitaoka |
120a6e |
bool onlyUnfilled) {
|
|
Shinya Kitaoka |
120a6e |
TRect bbox = m_ras->getBounds();
|
|
Shinya Kitaoka |
120a6e |
TRect r = rect * bbox;
|
|
Shinya Kitaoka |
120a6e |
if (r.isEmpty()) return;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TRaster32P workRas = m_ras->extract(r);
|
|
Shinya Kitaoka |
120a6e |
TRaster32P copy = workRas->clone();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TPixel32 color = params.m_palette->getStyle(params.m_styleId)->getMainColor();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Fillo tutto il quadaratino con color
|
|
Shinya Kitaoka |
120a6e |
int x, y;
|
|
Shinya Kitaoka |
120a6e |
for (y = 0; y < workRas->getLy(); y++) {
|
|
Shinya Kitaoka |
120a6e |
TPixel32 *line = workRas->pixels(y);
|
|
Shinya Kitaoka |
120a6e |
for (x = 0; x < workRas->getLx(); x++)
|
|
Shinya Kitaoka |
120a6e |
*(line + x) = overPix(color, workRas->pixels(y)[x]);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
FillParameters paramsApp = params;
|
|
Shinya Kitaoka |
120a6e |
TPixel32 refColor;
|
|
Shinya Kitaoka |
120a6e |
for (y = 0; y < workRas->getLy(); y++) {
|
|
Shinya Kitaoka |
120a6e |
paramsApp.m_p = TPoint(0, y);
|
|
Shinya Kitaoka |
120a6e |
if (y == 0 ||
|
|
Shinya Kitaoka |
120a6e |
refColor != workRas->pixels(paramsApp.m_p.y)[paramsApp.m_p.x]) {
|
|
Shinya Kitaoka |
120a6e |
fill(workRas, copy, paramsApp);
|
|
Shinya Kitaoka |
120a6e |
refColor = workRas->pixels(paramsApp.m_p.y)[paramsApp.m_p.x];
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
for (y = 0; y < workRas->getLy(); y++) {
|
|
Shinya Kitaoka |
120a6e |
paramsApp.m_p = TPoint(workRas->getLx() - 1, y);
|
|
Shinya Kitaoka |
120a6e |
if (y == 0 ||
|
|
Shinya Kitaoka |
120a6e |
refColor != workRas->pixels(paramsApp.m_p.y)[paramsApp.m_p.x]) {
|
|
Shinya Kitaoka |
120a6e |
fill(workRas, copy, paramsApp);
|
|
Shinya Kitaoka |
120a6e |
refColor = workRas->pixels(paramsApp.m_p.y)[paramsApp.m_p.x];
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (x = 0; x < workRas->getLx(); x++) {
|
|
Shinya Kitaoka |
120a6e |
paramsApp.m_p = TPoint(x, 0);
|
|
Shinya Kitaoka |
120a6e |
if (x == 0 ||
|
|
Shinya Kitaoka |
120a6e |
refColor != workRas->pixels(paramsApp.m_p.y)[paramsApp.m_p.x]) {
|
|
Shinya Kitaoka |
120a6e |
fill(workRas, copy, paramsApp);
|
|
Shinya Kitaoka |
120a6e |
refColor = workRas->pixels(paramsApp.m_p.y)[paramsApp.m_p.x];
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
for (x = 0; x < workRas->getLx(); x++) {
|
|
Shinya Kitaoka |
120a6e |
paramsApp.m_p = TPoint(x, workRas->getLy() - 1);
|
|
Shinya Kitaoka |
120a6e |
if (x == 0 ||
|
|
Shinya Kitaoka |
120a6e |
refColor != workRas->pixels(paramsApp.m_p.y)[paramsApp.m_p.x]) {
|
|
Shinya Kitaoka |
120a6e |
fill(workRas, copy, paramsApp);
|
|
Shinya Kitaoka |
120a6e |
refColor = workRas->pixels(paramsApp.m_p.y)[paramsApp.m_p.x];
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//=============================================================================
|
|
Toshihiro Shimizu |
890ddd |
// InkSegmenter
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
const int damInk = 3;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#define GROW_FACTOR 2.51
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
class InkSegmenter {
|
|
Shinya Kitaoka |
120a6e |
int m_lx, m_ly, m_wrap;
|
|
Shinya Kitaoka |
120a6e |
int m_displaceVector[8];
|
|
Shinya Kitaoka |
120a6e |
TPixelCM32 *m_buf;
|
|
Shinya Kitaoka |
120a6e |
TRect m_bBox;
|
|
Shinya Kitaoka |
120a6e |
TRasterCM32P m_r;
|
|
Shinya Kitaoka |
120a6e |
TTileSaverCM32 *m_saver;
|
|
Shinya Kitaoka |
120a6e |
float m_growFactor;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
InkSegmenter(const TRasterCM32P &r, float growFactor, TTileSaverCM32 *saver)
|
|
Shinya Kitaoka |
120a6e |
: m_r(r)
|
|
Shinya Kitaoka |
120a6e |
, m_lx(r->getLx())
|
|
Shinya Kitaoka |
120a6e |
, m_ly(r->getLy())
|
|
Shinya Kitaoka |
120a6e |
, m_wrap(r->getWrap())
|
|
Shinya Kitaoka |
120a6e |
, m_buf((TPixelCM32 *)r->getRawData())
|
|
Shinya Kitaoka |
120a6e |
, m_bBox(r->getBounds())
|
|
Shinya Kitaoka |
120a6e |
, m_saver(saver)
|
|
Shinya Kitaoka |
120a6e |
, m_growFactor(growFactor) {
|
|
Shinya Kitaoka |
120a6e |
m_displaceVector[0] = -m_wrap - 1;
|
|
Shinya Kitaoka |
120a6e |
m_displaceVector[1] = -m_wrap;
|
|
Shinya Kitaoka |
120a6e |
m_displaceVector[2] = -m_wrap + 1;
|
|
Shinya Kitaoka |
120a6e |
m_displaceVector[3] = -1;
|
|
Shinya Kitaoka |
120a6e |
m_displaceVector[4] = +1;
|
|
Shinya Kitaoka |
120a6e |
m_displaceVector[5] = m_wrap - 1;
|
|
Shinya Kitaoka |
120a6e |
m_displaceVector[6] = m_wrap;
|
|
Shinya Kitaoka |
120a6e |
m_displaceVector[7] = m_wrap + 1;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
//-----------------------------------------------------------------------------
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
bool compute(const TPoint &pin, int ink, bool isSelective) {
|
|
Shinya Kitaoka |
120a6e |
TPixelCM32 *pix;
|
|
Shinya Kitaoka |
120a6e |
int distance;
|
|
Shinya Kitaoka |
120a6e |
TPixelCM32 *master;
|
|
Shinya Kitaoka |
120a6e |
TPoint mp, sp;
|
|
Shinya Kitaoka |
120a6e |
TPixelCM32 *slave;
|
|
Shinya Kitaoka |
120a6e |
TPixelCM32 *d11, *d12, *d21, *d22;
|
|
Shinya Kitaoka |
120a6e |
TPoint d1p1, d1p2, d2p1, d2p2;
|
|
Shinya Kitaoka |
120a6e |
TPoint p = pin;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (!m_bBox.contains(p)) return false;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if ((m_buf + p.y * m_wrap + p.x)->isPurePaint() &&
|
|
Shinya Kitaoka |
120a6e |
((p = nearestInk(p, 2)) == TPoint(-1, -1)))
|
|
Shinya Kitaoka |
120a6e |
return false;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
pix = m_buf + p.y * m_wrap + p.x;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/*-- 同じインクの場合はreturn --*/
|
|
Shinya Kitaoka |
120a6e |
if (pix->getInk() == ink) return false;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (!ConnectionTable[neighboursCode(pix, p)]) {
|
|
Shinya Kitaoka |
120a6e |
master = slave = pix;
|
|
Shinya Kitaoka |
120a6e |
mp = sp = p;
|
|
Shinya Kitaoka |
120a6e |
distance = 0;
|
|
Shinya Kitaoka |
120a6e |
} else
|
|
Shinya Kitaoka |
120a6e |
distance = findTwinPoints(pix, p, master, mp, slave, sp);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (distance == -1) return false;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (!findDam(master, mp, slave, sp, distance, d11, d1p1, d12, d1p2))
|
|
Shinya Kitaoka |
120a6e |
d11 = d12 = d21 = d22 = 0;
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
findDamRev(master, mp, slave, sp, distance, d21, d2p1, d22, d2p2);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// vector<pair<tpixelcm32*, int=""> > oldInks;</pair<tpixelcm32*,>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
drawSegment(d1p1, d1p2, damInk, m_saver);
|
|
Shinya Kitaoka |
120a6e |
drawSegment(d2p1, d2p2, damInk, m_saver);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
inkSegmentFill(p, ink, isSelective, m_saver);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// UINT i;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
drawSegment(d1p1, d1p2, ink, m_saver);
|
|
Shinya Kitaoka |
120a6e |
drawSegment(d2p1, d2p2, ink, m_saver);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/* for (i=0; i
|
|
Shinya Kitaoka |
120a6e |
(oldInks[i].first)->setInk(ink);*/
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
private:
|
|
Shinya Kitaoka |
120a6e |
void drawSegment(
|
|
Shinya Kitaoka |
120a6e |
const TPoint &p0, const TPoint &p1, int ink,
|
|
Shinya Kitaoka |
120a6e |
/*vector<pair<tpixelcm32*, int=""> >& oldInks,*/ TTileSaverCM32 *saver);</pair<tpixelcm32*,>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int findTwinPoints(TPixelCM32 *pix, const TPoint &p, TPixelCM32 *&master,
|
|
Shinya Kitaoka |
120a6e |
TPoint &mp, TPixelCM32 *&slave, TPoint &sp);
|
|
Shinya Kitaoka |
120a6e |
int searchForNearestSlave(TPixelCM32 *pix1, TPixelCM32 *pix2,
|
|
Shinya Kitaoka |
120a6e |
const TPoint &p1, TPoint &p2, TPixelCM32 *&slave,
|
|
Shinya Kitaoka |
120a6e |
TPoint &sp);
|
|
Shinya Kitaoka |
120a6e |
int rearrangePoints(TPixelCM32 *&master, TPoint &mp, TPixelCM32 *&slave,
|
|
Shinya Kitaoka |
120a6e |
int s_prewalker, TPoint &sp, int walk);
|
|
Shinya Kitaoka |
120a6e |
int rearrangePointsRev(TPixelCM32 *&master, TPoint &mp, TPixelCM32 *&slave,
|
|
Shinya Kitaoka |
120a6e |
int s_prewalker, TPoint &sp, int walk);
|
|
Shinya Kitaoka |
120a6e |
int dragSlave(TPoint mp, TPixelCM32 *&slave, int &s_prewalker, TPoint &sp);
|
|
Shinya Kitaoka |
120a6e |
int dragSlaveRev(TPoint mp, TPixelCM32 *&slave, int &s_prewalker, TPoint &sp,
|
|
Shinya Kitaoka |
120a6e |
TPixelCM32 *first_slave);
|
|
Shinya Kitaoka |
120a6e |
bool findDam(TPixelCM32 *master, TPoint mp, TPixelCM32 *slave, TPoint sp,
|
|
Shinya Kitaoka |
120a6e |
int distance, TPixelCM32 *&d11, TPoint &d1p1, TPixelCM32 *&d12,
|
|
Shinya Kitaoka |
120a6e |
TPoint &d1p2);
|
|
Shinya Kitaoka |
120a6e |
void findDamRev(TPixelCM32 *master, TPoint mp, TPixelCM32 *slave, TPoint sp,
|
|
Shinya Kitaoka |
120a6e |
int distance, TPixelCM32 *&d11, TPoint &d1p1,
|
|
Shinya Kitaoka |
120a6e |
TPixelCM32 *&d12, TPoint &d1p2);
|
|
Shinya Kitaoka |
120a6e |
int nextPointIsGoodRev(TPoint mp, TPoint sp, TPixelCM32 *slave,
|
|
Shinya Kitaoka |
120a6e |
int s_prewalker, int distance);
|
|
Shinya Kitaoka |
120a6e |
int nextPointIsGood(TPoint mp, TPoint sp, TPixelCM32 *slave, int s_prewalker,
|
|
Shinya Kitaoka |
120a6e |
int distance);
|
|
Shinya Kitaoka |
120a6e |
void inkSegmentFill(const TPoint &p, int ink, bool isSelective,
|
|
Shinya Kitaoka |
120a6e |
TTileSaverCM32 *saver);
|
|
Shinya Kitaoka |
120a6e |
TPoint nearestInk(const TPoint &p, int ray);
|
|
Shinya Kitaoka |
120a6e |
inline int stepReversed(TPixelCM32 *walker, int prewalker, int &distance,
|
|
Shinya Kitaoka |
120a6e |
const TPoint &p1, TPoint &p2);
|
|
Shinya Kitaoka |
120a6e |
inline int stepForward(TPixelCM32 *walker, int prewalker, int &distance,
|
|
Shinya Kitaoka |
120a6e |
const TPoint &p1, TPoint &p2);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TPixelCM32 *ePix(TPixelCM32 *br) { return (br + 1); }
|
|
Shinya Kitaoka |
120a6e |
TPixelCM32 *wPix(TPixelCM32 *br) { return (br - 1); }
|
|
Shinya Kitaoka |
120a6e |
TPixelCM32 *nPix(TPixelCM32 *br) { return (br + m_wrap); }
|
|
Shinya Kitaoka |
120a6e |
TPixelCM32 *sPix(TPixelCM32 *br) { return (br - m_wrap); }
|
|
Shinya Kitaoka |
120a6e |
TPixelCM32 *swPix(TPixelCM32 *br) { return (br - m_wrap - 1); }
|
|
Shinya Kitaoka |
120a6e |
TPixelCM32 *nwPix(TPixelCM32 *br) { return (br + m_wrap - 1); }
|
|
Shinya Kitaoka |
120a6e |
TPixelCM32 *nePix(TPixelCM32 *br) { return (br + m_wrap + 1); }
|
|
Shinya Kitaoka |
120a6e |
TPixelCM32 *sePix(TPixelCM32 *br) { return (br - m_wrap + 1); }
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
UCHAR neighboursCode(TPixelCM32 *seed, const TPoint &p) {
|
|
Shinya Kitaoka |
120a6e |
// assert(p == TPoint((seed-m_buf)%m_wrap, (seed-m_buf)/m_wrap));
|
|
Shinya Kitaoka |
120a6e |
bool w = (p.x > 0), e = (p.x < m_lx - 1), s = (p.y > 0),
|
|
Shinya Kitaoka |
120a6e |
n = (p.y < m_ly - 1);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return (((s && w) ? ((!swPix(seed)->isPurePaint())) : 0) |
|
|
Shinya Kitaoka |
120a6e |
((s) ? ((!sPix(seed)->isPurePaint()) << 1) : 0) |
|
|
Shinya Kitaoka |
120a6e |
((s && e) ? ((!sePix(seed)->isPurePaint()) << 2) : 0) |
|
|
Shinya Kitaoka |
120a6e |
((w) ? ((!wPix(seed)->isPurePaint()) << 3) : 0) |
|
|
Shinya Kitaoka |
120a6e |
((e) ? ((!ePix(seed)->isPurePaint()) << 4) : 0) |
|
|
Shinya Kitaoka |
120a6e |
((n && w) ? ((!nwPix(seed)->isPurePaint()) << 5) : 0) |
|
|
Shinya Kitaoka |
120a6e |
((n) ? ((!nPix(seed)->isPurePaint()) << 6) : 0) |
|
|
Shinya Kitaoka |
120a6e |
((n && e) ? ((!nePix(seed)->isPurePaint()) << 7) : 0));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
#define DRAW_SEGMENT(a, b, da, db, istr1, istr2, block) \
|
|
Shinya Kitaoka |
120a6e |
{ \
|
|
Shinya Kitaoka |
120a6e |
d = 2 * db - da; \
|
|
Shinya Kitaoka |
120a6e |
incr_1 = 2 * db; \
|
|
Shinya Kitaoka |
120a6e |
incr_2 = 2 * (db - da); \
|
|
Shinya Kitaoka |
120a6e |
while (a < da) { \
|
|
Shinya Kitaoka |
120a6e |
if (d <= 0) { \
|
|
Shinya Kitaoka |
120a6e |
d += incr_1; \
|
|
Shinya Kitaoka |
120a6e |
a++; \
|
|
Shinya Kitaoka |
120a6e |
istr1; \
|
|
Shinya Kitaoka |
120a6e |
} else { \
|
|
Shinya Kitaoka |
120a6e |
d += incr_2; \
|
|
Shinya Kitaoka |
120a6e |
a++; \
|
|
Shinya Kitaoka |
120a6e |
b++; \
|
|
Shinya Kitaoka |
120a6e |
istr2; \
|
|
Shinya Kitaoka |
120a6e |
} \
|
|
Shinya Kitaoka |
120a6e |
block; \
|
|
Shinya Kitaoka |
120a6e |
} \
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
#define SET_INK \
|
|
Shinya Kitaoka |
120a6e |
{ \
|
|
Shinya Kitaoka |
120a6e |
if (saver) saver->save(TPoint(x1 + x, y1 + y)); \
|
|
Shinya Kitaoka |
120a6e |
/*if (buf->getInk()!=damInk)*/ \
|
|
Shinya Kitaoka |
120a6e |
/* oldInks.push_back(pair<tpixelcm32*, int="">(buf, buf->getInk()));*/ \</tpixelcm32*,>
|
|
Shinya Kitaoka |
120a6e |
buf->setInk(ink); \
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void InkSegmenter::drawSegment(
|
|
Shinya Kitaoka |
120a6e |
const TPoint &p0, const TPoint &p1, int ink,
|
|
Shinya Kitaoka |
120a6e |
/*vector<pair<tpixelcm32*, int=""> >& oldInks,*/ TTileSaverCM32 *saver) {</pair<tpixelcm32*,>
|
|
Shinya Kitaoka |
120a6e |
int x, y, dx, dy, d, incr_1, incr_2;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int x1 = p0.x;
|
|
Shinya Kitaoka |
120a6e |
int y1 = p0.y;
|
|
Shinya Kitaoka |
120a6e |
int x2 = p1.x;
|
|
Shinya Kitaoka |
120a6e |
int y2 = p1.y;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (x1 > x2) {
|
|
Shinya Kitaoka |
120a6e |
tswap(x1, x2);
|
|
Shinya Kitaoka |
120a6e |
tswap(y1, y2);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TPixelCM32 *buf = m_r->pixels() + y1 * m_wrap + x1;
|
|
Shinya Kitaoka |
120a6e |
/*if (buf->getInk()!=damInk)
|
|
Shinya Kitaoka |
120a6e |
oldInks.push_back(pair<tpixelcm32*, int="">(buf, buf->getInk()));</tpixelcm32*,>
|
|
Shinya Kitaoka |
120a6e |
if ((m_r->pixels() + y2*m_wrap + x2)->getInk()!=damInk)
|
|
Shinya Kitaoka |
120a6e |
oldInks.push_back(pair<tpixelcm32*, int="">(m_r->pixels() + y2*m_wrap +</tpixelcm32*,>
|
|
Shinya Kitaoka |
120a6e |
x2, (m_r->pixels() + y2*m_wrap + x2)->getInk()));*/
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (saver) {
|
|
Shinya Kitaoka |
120a6e |
saver->save(p0);
|
|
Shinya Kitaoka |
120a6e |
saver->save(p1);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
buf->setInk(ink);
|
|
Shinya Kitaoka |
120a6e |
(m_r->pixels() + y2 * m_wrap + x2)->setInk(ink);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
dx = x2 - x1;
|
|
Shinya Kitaoka |
120a6e |
dy = y2 - y1;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
x = y = 0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (dy >= 0) {
|
|
Shinya Kitaoka |
120a6e |
if (dy <= dx)
|
|
Shinya Kitaoka |
120a6e |
DRAW_SEGMENT(x, y, dx, dy, (buf++), (buf += m_wrap + 1), SET_INK)
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
DRAW_SEGMENT(y, x, dy, dx, (buf += m_wrap), (buf += m_wrap + 1), SET_INK)
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
dy = -dy;
|
|
Shinya Kitaoka |
120a6e |
if (dy <= dx)
|
|
Shinya Kitaoka |
120a6e |
DRAW_SEGMENT(x, y, dx, dy, (buf++), (buf -= (m_wrap - 1)), SET_INK)
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
DRAW_SEGMENT(y, x, dy, dx, (buf -= m_wrap), (buf -= (m_wrap - 1)),
|
|
Shinya Kitaoka |
120a6e |
SET_INK)
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void InkSegmenter::inkSegmentFill(const TPoint &p, int ink, bool isSelective,
|
|
Shinya Kitaoka |
120a6e |
TTileSaverCM32 *saver) {
|
|
Shinya Kitaoka |
120a6e |
int x = p.x, y = p.y;
|
|
Shinya Kitaoka |
120a6e |
int lx = m_r->getLx();
|
|
Shinya Kitaoka |
120a6e |
int ly = m_r->getLy();
|
|
Shinya Kitaoka |
120a6e |
TPixelCM32 *pixels = (TPixelCM32 *)m_r->getRawData();
|
|
Shinya Kitaoka |
120a6e |
TPixelCM32 *pix = pixels + p.y * m_wrap + x;
|
|
Shinya Kitaoka |
120a6e |
int oldInk;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (pix->isPurePaint() || pix->getInk() == ink) return;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (isSelective) oldInk = pix->getInk();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
std::stack<tpoint> seeds;</tpoint>
|
|
Shinya Kitaoka |
120a6e |
seeds.push(p);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
while (!seeds.empty()) {
|
|
Shinya Kitaoka |
120a6e |
TPoint seed = seeds.top();
|
|
Shinya Kitaoka |
120a6e |
seeds.pop();
|
|
Shinya Kitaoka |
120a6e |
// if(!m_r->getBounds().contains(seed)) continue;
|
|
Shinya Kitaoka |
120a6e |
x = seed.x;
|
|
Shinya Kitaoka |
120a6e |
y = seed.y;
|
|
Shinya Kitaoka |
120a6e |
TPixelCM32 *pix = pixels + (y * m_wrap + x);
|
|
Shinya Kitaoka |
120a6e |
if (pix->isPurePaint() || pix->getInk() == ink || pix->getInk() == damInk ||
|
|
Shinya Kitaoka |
120a6e |
(isSelective && pix->getInk() != oldInk))
|
|
Shinya Kitaoka |
120a6e |
continue;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (saver) saver->save(seed);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
pix->setInk(ink);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (x > 0) seeds.push(TPoint(x - 1, y));
|
|
Shinya Kitaoka |
120a6e |
if (y > 0) seeds.push(TPoint(x, y - 1));
|
|
Shinya Kitaoka |
120a6e |
if (y < ly - 1) seeds.push(TPoint(x, y + 1));
|
|
Shinya Kitaoka |
120a6e |
if (x < lx - 1) seeds.push(TPoint(x + 1, y));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (x == lx - 1 || x == 0 || y == ly - 1 || y == 0) continue;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (ePix(pix)->getInk() == damInk || wPix(pix)->getInk() == damInk ||
|
|
Shinya Kitaoka |
120a6e |
sPix(pix)->getInk() == damInk || nPix(pix)->getInk() == damInk ||
|
|
Shinya Kitaoka |
120a6e |
nePix(pix)->getInk() == damInk || sePix(pix)->getInk() == damInk ||
|
|
Shinya Kitaoka |
120a6e |
swPix(pix)->getInk() == damInk || nwPix(pix)->getInk() == damInk)
|
|
Shinya Kitaoka |
120a6e |
continue;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
seeds.push(TPoint(x - 1, y - 1));
|
|
Shinya Kitaoka |
120a6e |
seeds.push(TPoint(x - 1, y + 1));
|
|
Shinya Kitaoka |
120a6e |
seeds.push(TPoint(x + 1, y - 1));
|
|
Shinya Kitaoka |
120a6e |
seeds.push(TPoint(x + 1, y + 1));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TPoint InkSegmenter::nearestInk(const TPoint &p, int ray) {
|
|
Shinya Kitaoka |
120a6e |
int i, j;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
for (j = std::max(p.y - ray, 0); j <= std::min(p.y + ray, m_ly - 1); j++)
|
|
Shinya Kitaoka |
120a6e |
for (i = std::max(p.x - ray, 0); i <= std::min(p.x + ray, m_lx - 1); i++)
|
|
Shinya Kitaoka |
120a6e |
if (!(m_buf + j * m_wrap + i)->isPurePaint()) return TPoint(i, j);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return TPoint(-1, -1);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int InkSegmenter::findTwinPoints(TPixelCM32 *pix, const TPoint &p,
|
|
Shinya Kitaoka |
120a6e |
TPixelCM32 *&master, TPoint &mp,
|
|
Shinya Kitaoka |
120a6e |
TPixelCM32 *&slave, TPoint &sp) {
|
|
Shinya Kitaoka |
120a6e |
TPixelCM32 *row_p1, *col_p1, *row_p2, *col_p2;
|
|
Shinya Kitaoka |
120a6e |
int distance;
|
|
Shinya Kitaoka |
120a6e |
int row_x1, row_x2, col_y1, col_y2;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
row_p1 = pix - 1;
|
|
Shinya Kitaoka |
120a6e |
row_x1 = p.x - 1;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
while (row_x1 + 1 < m_lx && !(row_p1 + 1)->isPurePaint()) {
|
|
Shinya Kitaoka |
120a6e |
row_p1++;
|
|
Shinya Kitaoka |
120a6e |
row_x1++;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
row_p2 = pix + 1;
|
|
Shinya Kitaoka |
120a6e |
row_x2 = p.x + 1;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
while (row_x2 - 1 > 0 && !(row_p2 - 1)->isPurePaint()) {
|
|
Shinya Kitaoka |
120a6e |
row_p2--;
|
|
Shinya Kitaoka |
120a6e |
row_x2--;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
master = row_p1;
|
|
Shinya Kitaoka |
120a6e |
mp.x = row_x1;
|
|
Shinya Kitaoka |
120a6e |
mp.y = p.y;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
col_p1 = pix - m_wrap;
|
|
Shinya Kitaoka |
120a6e |
col_y1 = p.y - 1;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
while (col_y1 + 1 < m_ly && !(col_p1 + m_wrap)->isPurePaint()) {
|
|
Shinya Kitaoka |
120a6e |
col_p1 += m_wrap;
|
|
Shinya Kitaoka |
120a6e |
col_y1++;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
col_p2 = pix + m_wrap;
|
|
Shinya Kitaoka |
120a6e |
col_y2 = p.y + 1;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
while (col_y2 - 1 > 0 && !(col_p2 - 1)->isPurePaint()) {
|
|
Shinya Kitaoka |
120a6e |
col_p2 -= m_wrap;
|
|
Shinya Kitaoka |
120a6e |
col_y2--;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (row_x1 - row_x2 <= col_y1 - col_y2) {
|
|
Shinya Kitaoka |
120a6e |
master = row_p1;
|
|
Shinya Kitaoka |
120a6e |
mp = TPoint(row_x1, p.y);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TPoint auxp(row_x2, p.y);
|
|
Shinya Kitaoka |
120a6e |
if ((distance =
|
|
Shinya Kitaoka |
120a6e |
searchForNearestSlave(row_p1, row_p2, mp, auxp, slave, sp)) != 0)
|
|
Shinya Kitaoka |
120a6e |
return distance;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
master = col_p1;
|
|
Shinya Kitaoka |
120a6e |
mp = TPoint(p.x, col_y1);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
auxp = TPoint(p.x, col_y2);
|
|
Shinya Kitaoka |
120a6e |
if ((distance = searchForNearestSlave(col_p1, col_p2, mp, auxp, slave,
|
|
Shinya Kitaoka |
120a6e |
sp)) == 0 /*&& !is_connecting(p1)*/)
|
|
Shinya Kitaoka |
120a6e |
return -1;
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
master = col_p1;
|
|
Shinya Kitaoka |
120a6e |
mp = TPoint(p.x, col_y1);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TPoint auxp(p.x, col_y2);
|
|
Shinya Kitaoka |
120a6e |
if ((distance =
|
|
Shinya Kitaoka |
120a6e |
searchForNearestSlave(col_p1, col_p2, mp, auxp, slave, sp)) != 0)
|
|
Shinya Kitaoka |
120a6e |
return distance;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
master = row_p1;
|
|
Shinya Kitaoka |
120a6e |
mp = TPoint(row_x1, p.y);
|
|
Shinya Kitaoka |
120a6e |
auxp = TPoint(row_x2, p.y);
|
|
Shinya Kitaoka |
120a6e |
if ((distance = searchForNearestSlave(row_p1, row_p2, mp, auxp, slave,
|
|
Shinya Kitaoka |
120a6e |
sp)) == 0 /*&& !is_connecting(p1)*/)
|
|
Shinya Kitaoka |
120a6e |
return -1;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return distance;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
inline void newP(int next, TPoint &p) {
|
|
Shinya Kitaoka |
120a6e |
switch (next) {
|
|
Shinya Kitaoka |
120a6e |
case 0:
|
|
Shinya Kitaoka |
120a6e |
case 3:
|
|
Shinya Kitaoka |
120a6e |
case 5:
|
|
Shinya Kitaoka |
120a6e |
p.x -= 1;
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case 2:
|
|
Shinya Kitaoka |
120a6e |
case 4:
|
|
Shinya Kitaoka |
120a6e |
case 7:
|
|
Shinya Kitaoka |
120a6e |
p.x += 1;
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
switch (next) {
|
|
Shinya Kitaoka |
120a6e |
case 0:
|
|
Shinya Kitaoka |
120a6e |
case 1:
|
|
Shinya Kitaoka |
120a6e |
case 2:
|
|
Shinya Kitaoka |
120a6e |
p.y -= 1;
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case 5:
|
|
Shinya Kitaoka |
120a6e |
case 6:
|
|
Shinya Kitaoka |
120a6e |
case 7:
|
|
Shinya Kitaoka |
120a6e |
p.y += 1;
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
inline int InkSegmenter::stepReversed(TPixelCM32 *walker, int prewalker,
|
|
Shinya Kitaoka |
120a6e |
int &distance, const TPoint &p1,
|
|
Shinya Kitaoka |
120a6e |
TPoint &p2) {
|
|
Shinya Kitaoka |
120a6e |
int next = NextPointTableRev[(neighboursCode(walker, p2) << 3) | prewalker];
|
|
Shinya Kitaoka |
120a6e |
newP(next, p2);
|
|
Shinya Kitaoka |
120a6e |
distance = norm2(p1 - p2);
|
|
Shinya Kitaoka |
120a6e |
return next;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*------------------------------------------------------------------------*/
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
inline int InkSegmenter::stepForward(TPixelCM32 *walker, int prewalker,
|
|
Shinya Kitaoka |
120a6e |
int &distance, const TPoint &p1,
|
|
Shinya Kitaoka |
120a6e |
TPoint &p2) {
|
|
Shinya Kitaoka |
120a6e |
int next = NextPointTable[(neighboursCode(walker, p2) << 3) | prewalker];
|
|
Shinya Kitaoka |
120a6e |
newP(next, p2);
|
|
Shinya Kitaoka |
120a6e |
distance = norm2(p1 - p2);
|
|
Shinya Kitaoka |
120a6e |
return next;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int InkSegmenter::searchForNearestSlave(TPixelCM32 *pix1, TPixelCM32 *pix2,
|
|
Shinya Kitaoka |
120a6e |
const TPoint &p1, TPoint &p2,
|
|
Shinya Kitaoka |
120a6e |
TPixelCM32 *&slave, TPoint &sp) {
|
|
Shinya Kitaoka |
120a6e |
int curr_distance, new_distance;
|
|
Shinya Kitaoka |
120a6e |
UCHAR prewalker, next;
|
|
Shinya Kitaoka |
120a6e |
TPixelCM32 *walker;
|
|
Shinya Kitaoka |
120a6e |
TPoint currp2;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
currp2 = p2;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
curr_distance = norm2(p1 - p2);
|
|
Shinya Kitaoka |
120a6e |
walker = pix2;
|
|
Shinya Kitaoka |
120a6e |
slave = pix2;
|
|
Shinya Kitaoka |
120a6e |
sp = p2;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
prewalker = FirstPreseedTable[neighboursCode(walker, p2)];
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
next = stepForward(walker, prewalker, new_distance, p1, p2);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (curr_distance != 0 && new_distance < curr_distance) {
|
|
Shinya Kitaoka |
120a6e |
while (p2.x > 0 && p2.x < m_lx - 1 && p2.y > 0 && p2.y < m_ly - 1 &&
|
|
Shinya Kitaoka |
120a6e |
new_distance < curr_distance && new_distance != 0) {
|
|
Shinya Kitaoka |
120a6e |
curr_distance = new_distance;
|
|
Shinya Kitaoka |
120a6e |
sp.x = p2.x;
|
|
Shinya Kitaoka |
120a6e |
sp.y = p2.y;
|
|
Shinya Kitaoka |
120a6e |
walker = walker + m_displaceVector[next];
|
|
Shinya Kitaoka |
120a6e |
slave = walker;
|
|
Shinya Kitaoka |
120a6e |
prewalker = (~next) & 0x7;
|
|
Shinya Kitaoka |
120a6e |
next = stepForward(walker, prewalker, new_distance, p1, p2);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (new_distance != 0) return curr_distance;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
curr_distance = norm2(p1 - p2);
|
|
Shinya Kitaoka |
120a6e |
walker = pix2;
|
|
Shinya Kitaoka |
120a6e |
p2 = currp2;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
UCHAR code = neighboursCode(walker, p2);
|
|
Shinya Kitaoka |
120a6e |
next = FirstPreseedTable[code];
|
|
Shinya Kitaoka |
120a6e |
next = NextPointTable[(code << 3) | next];
|
|
Shinya Kitaoka |
120a6e |
prewalker = next;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
next = stepReversed(walker, prewalker, new_distance, p1, p2);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (p2.x > 0 && p2.x < m_lx - 1 && p2.y > 0 && p2.y < m_ly - 1 &&
|
|
Shinya Kitaoka |
120a6e |
curr_distance != 0 && new_distance < curr_distance) {
|
|
Shinya Kitaoka |
120a6e |
while (new_distance < curr_distance && new_distance > 0) {
|
|
Shinya Kitaoka |
120a6e |
curr_distance = new_distance;
|
|
Shinya Kitaoka |
120a6e |
sp = p2;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
walker = walker + m_displaceVector[next];
|
|
Shinya Kitaoka |
120a6e |
slave = walker;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
prewalker = (~next) & 0x7;
|
|
Shinya Kitaoka |
120a6e |
next = stepReversed(walker, prewalker, new_distance, p1, p2);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (new_distance != 0) return curr_distance;
|
|
Shinya Kitaoka |
120a6e |
} else if (new_distance != 0)
|
|
Shinya Kitaoka |
120a6e |
return curr_distance;
|
|
Shinya Kitaoka |
120a6e |
return 0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int InkSegmenter::rearrangePoints(TPixelCM32 *&master, TPoint &mp,
|
|
Shinya Kitaoka |
120a6e |
TPixelCM32 *&slave, int s_prewalker,
|
|
Shinya Kitaoka |
120a6e |
TPoint &sp, int walk) {
|
|
Shinya Kitaoka |
120a6e |
int s_next;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
while (walk-- && sp.x > 0 && sp.x < m_lx - 1 && sp.y > 0 && sp.y < m_ly - 1) {
|
|
Shinya Kitaoka |
120a6e |
s_next =
|
|
Shinya Kitaoka |
120a6e |
NextPointTableRev[((neighboursCode(slave, sp)) << 3) | s_prewalker];
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
newP(s_next, sp);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
slave = slave + m_displaceVector[s_next];
|
|
Shinya Kitaoka |
120a6e |
s_prewalker = (~s_next) & 0x7;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
return 1;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int InkSegmenter::rearrangePointsRev(TPixelCM32 *&master, TPoint &mp,
|
|
Shinya Kitaoka |
120a6e |
TPixelCM32 *&slave, int s_prewalker,
|
|
Shinya Kitaoka |
120a6e |
TPoint &sp, int walk) {
|
|
Shinya Kitaoka |
120a6e |
int s_next;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
while (walk-- && sp.x > 0 && sp.x < m_lx - 1 && sp.y > 0 && sp.y < m_ly - 1) {
|
|
Shinya Kitaoka |
120a6e |
s_next = NextPointTable[((neighboursCode(slave, sp)) << 3) | s_prewalker];
|
|
Shinya Kitaoka |
120a6e |
// s_next = NEXT_POINT_24(*slave, s_prewalker);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
newP(s_next, sp);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
slave = slave + m_displaceVector[s_next];
|
|
Shinya Kitaoka |
120a6e |
s_prewalker = (~s_next) & 0x7;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
return 1;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int InkSegmenter::dragSlave(TPoint mp, TPixelCM32 *&slave, int &s_prewalker,
|
|
Shinya Kitaoka |
120a6e |
TPoint &sp) {
|
|
Shinya Kitaoka |
120a6e |
int distance, s_next, new_distance;
|
|
Shinya Kitaoka |
120a6e |
int ret = 0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
distance = norm2(mp - sp);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
s_next = stepForward(slave, s_prewalker, new_distance, mp, sp);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
while (sp.x > 0 && sp.x < m_lx - 1 && sp.y > 0 && sp.y < m_ly - 1 &&
|
|
Shinya Kitaoka |
120a6e |
(new_distance < distance ||
|
|
Shinya Kitaoka |
120a6e |
nextPointIsGood(mp, sp, slave + m_displaceVector[s_next],
|
|
Shinya Kitaoka |
120a6e |
(~s_next) & 0x7, distance))) {
|
|
Shinya Kitaoka |
120a6e |
if (!ret) ret = 1;
|
|
Shinya Kitaoka |
120a6e |
distance = new_distance;
|
|
Shinya Kitaoka |
120a6e |
slave = slave + m_displaceVector[s_next];
|
|
Shinya Kitaoka |
120a6e |
s_prewalker = (~s_next) & 0x7;
|
|
Shinya Kitaoka |
120a6e |
s_next = stepForward(slave, s_prewalker, new_distance, mp, sp);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
newP(((~s_next) & 0x7), sp);
|
|
Shinya Kitaoka |
120a6e |
return ret;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int InkSegmenter::dragSlaveRev(TPoint mp, TPixelCM32 *&slave, int &s_prewalker,
|
|
Shinya Kitaoka |
120a6e |
TPoint &sp, TPixelCM32 *first_slave) {
|
|
Shinya Kitaoka |
120a6e |
int distance, new_distance, s_next;
|
|
Shinya Kitaoka |
120a6e |
int ret = 0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
distance = norm2(mp - sp);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
s_next = stepReversed(slave, s_prewalker, new_distance, mp, sp);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
while (sp.x > 0 && sp.x < m_lx - 1 && sp.y > 0 && sp.y < m_ly - 1 &&
|
|
Shinya Kitaoka |
120a6e |
(new_distance < distance ||
|
|
Shinya Kitaoka |
120a6e |
nextPointIsGoodRev(mp, sp, slave + m_displaceVector[s_next],
|
|
Shinya Kitaoka |
120a6e |
(~s_next) & 0x7, distance))) {
|
|
Shinya Kitaoka |
120a6e |
if (!ret) ret = 1;
|
|
Shinya Kitaoka |
120a6e |
distance = new_distance;
|
|
Shinya Kitaoka |
120a6e |
slave = slave + m_displaceVector[s_next];
|
|
Shinya Kitaoka |
120a6e |
if (slave == first_slave) return -1;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
s_prewalker = (~s_next) & 0x7;
|
|
Shinya Kitaoka |
120a6e |
s_next = stepReversed(slave, s_prewalker, new_distance, mp, sp);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
newP(((~s_next) & 0x7), sp);
|
|
Shinya Kitaoka |
120a6e |
return ret;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool InkSegmenter::findDam(TPixelCM32 *master, TPoint mp, TPixelCM32 *slave,
|
|
Shinya Kitaoka |
120a6e |
TPoint sp, int distance, TPixelCM32 *&d11,
|
|
Shinya Kitaoka |
120a6e |
TPoint &d1p1, TPixelCM32 *&d12, TPoint &d1p2)
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Shinya Kitaoka |
120a6e |
int ref_distance, m_prewalker, s_prewalker, m_next, next, ret;
|
|
Shinya Kitaoka |
120a6e |
unsigned int walkalone = 0;
|
|
Shinya Kitaoka |
120a6e |
TPixelCM32 *first_slave, *first_master;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
first_slave = slave;
|
|
Shinya Kitaoka |
120a6e |
first_master = master;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
ref_distance = tround(m_growFactor * ((float)distance + 1));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_prewalker = FirstPreseedTable[neighboursCode(master, mp)];
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (!ConnectionTable[neighboursCode(master, mp)])
|
|
Shinya Kitaoka |
120a6e |
s_prewalker = FirstPreseedTableRev[neighboursCode(slave, sp)];
|
|
Shinya Kitaoka |
120a6e |
else {
|
|
Shinya Kitaoka |
120a6e |
UCHAR code = neighboursCode(slave, sp);
|
|
Shinya Kitaoka |
120a6e |
next = FirstPreseedTable[code];
|
|
Shinya Kitaoka |
120a6e |
next = NextPointTable[(code << 3) | next];
|
|
Shinya Kitaoka |
120a6e |
s_prewalker = next;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
while (mp.x > 0 && mp.x < m_lx - 1 && mp.y > 0 && mp.y < m_ly - 1 &&
|
|
Shinya Kitaoka |
120a6e |
distance < ref_distance &&
|
|
Shinya Kitaoka |
120a6e |
!(((m_next = NextPointTable[((neighboursCode(master, mp)) << 3) |
|
|
Shinya Kitaoka |
120a6e |
m_prewalker]) == s_prewalker) &&
|
|
Shinya Kitaoka |
120a6e |
master == slave)) {
|
|
Shinya Kitaoka |
120a6e |
newP(m_next, mp);
|
|
Shinya Kitaoka |
120a6e |
master = master + m_displaceVector[m_next];
|
|
Shinya Kitaoka |
120a6e |
m_prewalker = (~m_next) & 0x7;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
ret = dragSlaveRev(mp, slave, s_prewalker, sp, first_slave);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (ret == -1) return false;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (ret == 0)
|
|
Shinya Kitaoka |
120a6e |
walkalone++;
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
walkalone = 0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (master == first_master) break;
|
|
Shinya Kitaoka |
120a6e |
distance = norm2(mp - sp);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (walkalone > 0)
|
|
Shinya Kitaoka |
120a6e |
rearrangePoints(master, mp, slave, s_prewalker, sp, walkalone);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
d11 = master;
|
|
Shinya Kitaoka |
120a6e |
d1p1 = mp;
|
|
Shinya Kitaoka |
120a6e |
d12 = slave;
|
|
Shinya Kitaoka |
120a6e |
d1p2 = sp;
|
|
Shinya Kitaoka |
120a6e |
return 1;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void InkSegmenter::findDamRev(TPixelCM32 *master, TPoint mp, TPixelCM32 *slave,
|
|
Shinya Kitaoka |
120a6e |
TPoint sp, int distance, TPixelCM32 *&d11,
|
|
Shinya Kitaoka |
120a6e |
TPoint &d1p1, TPixelCM32 *&d12, TPoint &d1p2)
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Shinya Kitaoka |
120a6e |
int ref_distance, m_prewalker, s_prewalker, m_next, next;
|
|
Shinya Kitaoka |
120a6e |
unsigned int walkalone = 0;
|
|
Shinya Kitaoka |
120a6e |
TPixelCM32 *first_master;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
first_master = master;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
ref_distance = tround(GROW_FACTOR * ((float)distance + 1));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_prewalker = FirstPreseedTableRev[neighboursCode(master, mp)];
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (!ConnectionTable[neighboursCode(master, mp)]) {
|
|
Shinya Kitaoka |
120a6e |
UCHAR code = neighboursCode(slave, sp);
|
|
Shinya Kitaoka |
120a6e |
next = FirstPreseedTableRev[code];
|
|
Shinya Kitaoka |
120a6e |
next = NextPointTableRev[(code << 3) | next];
|
|
Shinya Kitaoka |
120a6e |
s_prewalker = next;
|
|
Shinya Kitaoka |
120a6e |
} else
|
|
Shinya Kitaoka |
120a6e |
s_prewalker = FirstPreseedTable[neighboursCode(slave, sp)];
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
while (mp.x > 0 && mp.x < m_lx - 1 && mp.y > 0 && mp.y < m_ly - 1 &&
|
|
Shinya Kitaoka |
120a6e |
distance < ref_distance &&
|
|
Shinya Kitaoka |
120a6e |
!(((m_next = NextPointTableRev[((neighboursCode(master, mp)) << 3) |
|
|
Shinya Kitaoka |
120a6e |
m_prewalker]) == s_prewalker) &&
|
|
Shinya Kitaoka |
120a6e |
master == slave)) {
|
|
Shinya Kitaoka |
120a6e |
newP(m_next, mp);
|
|
Shinya Kitaoka |
120a6e |
master = master + m_displaceVector[m_next];
|
|
Shinya Kitaoka |
120a6e |
m_prewalker = (~m_next) & 0x7;
|
|
Shinya Kitaoka |
120a6e |
if (!dragSlave(mp, slave, s_prewalker, sp))
|
|
Shinya Kitaoka |
120a6e |
walkalone++;
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
walkalone = 0;
|
|
Shinya Kitaoka |
120a6e |
if (master == first_master) break;
|
|
Shinya Kitaoka |
120a6e |
distance = norm2(mp - sp);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (walkalone > 0)
|
|
Shinya Kitaoka |
120a6e |
rearrangePointsRev(master, mp, slave, s_prewalker, sp, walkalone);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
d11 = master;
|
|
Shinya Kitaoka |
120a6e |
d1p1 = mp;
|
|
Shinya Kitaoka |
120a6e |
d12 = slave;
|
|
Shinya Kitaoka |
120a6e |
d1p2 = sp;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int InkSegmenter::nextPointIsGood(TPoint mp, TPoint sp, TPixelCM32 *slave,
|
|
Shinya Kitaoka |
120a6e |
int s_prewalker, int distance) {
|
|
Shinya Kitaoka |
120a6e |
int s_next;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
s_next = NextPointTable[((neighboursCode(slave, sp)) << 3) | s_prewalker];
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
newP(s_next, sp);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return (norm2(mp - sp) <= distance);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int InkSegmenter::nextPointIsGoodRev(TPoint mp, TPoint sp, TPixelCM32 *slave,
|
|
Shinya Kitaoka |
120a6e |
int s_prewalker, int distance) {
|
|
Shinya Kitaoka |
120a6e |
int s_next;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
s_next = NextPointTableRev[((neighboursCode(slave, sp)) << 3) | s_prewalker];
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
newP(s_next, sp);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return (norm2(mp - sp) <= distance);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool inkSegment(const TRasterCM32P &r, const TPoint &p, int ink,
|
|
Shinya Kitaoka |
120a6e |
float growFactor, bool isSelective, TTileSaverCM32 *saver) {
|
|
Shinya Kitaoka |
120a6e |
r->lock();
|
|
Shinya Kitaoka |
120a6e |
InkSegmenter is(r, growFactor, saver);
|
|
Shinya Kitaoka |
120a6e |
bool ret = is.compute(p, ink, isSelective);
|
|
Shinya Kitaoka |
120a6e |
r->unlock();
|
|
Shinya Kitaoka |
120a6e |
return ret;
|
|
Toshihiro Shimizu |
890ddd |
}
|