|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/rasterstrokegenerator.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "trastercm.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/rasterbrush.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "trop.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
RasterStrokeGenerator::RasterStrokeGenerator(const TRasterCM32P &raster,
|
|
Shinya Kitaoka |
120a6e |
Tasks task, ColorType colorType,
|
|
Shinya Kitaoka |
120a6e |
int styleId, const TThickPoint &p,
|
|
Shinya Kitaoka |
120a6e |
bool selective, int selectedStyle,
|
|
manongjohn |
f027d1 |
bool lockAlpha, bool keepAntialias,
|
|
shun-iwasawa |
975eb1 |
bool isPaletteOrder)
|
|
Shinya Kitaoka |
120a6e |
: m_raster(raster)
|
|
Shinya Kitaoka |
120a6e |
, m_boxOfRaster(TRect(raster->getSize()))
|
|
Shinya Kitaoka |
120a6e |
, m_styleId(styleId)
|
|
Shinya Kitaoka |
120a6e |
, m_selective(selective)
|
|
Shinya Kitaoka |
120a6e |
, m_task(task)
|
|
Shinya Kitaoka |
120a6e |
, m_colorType(colorType)
|
|
Shinya Kitaoka |
120a6e |
, m_eraseStyle(4095)
|
|
Shinya Kitaoka |
120a6e |
, m_selectedStyle(selectedStyle)
|
|
Shinya Kitaoka |
120a6e |
, m_keepAntiAlias(keepAntialias)
|
|
shun-iwasawa |
975eb1 |
, m_doAnArc(false)
|
|
manongjohn |
f027d1 |
, m_isPaletteOrder(isPaletteOrder)
|
|
manongjohn |
f027d1 |
, m_modifierLockAlpha(lockAlpha) {
|
|
Shinya Kitaoka |
120a6e |
TThickPoint pp = p;
|
|
Shinya Kitaoka |
120a6e |
m_points.push_back(pp);
|
|
Shinya Kitaoka |
120a6e |
if (task == ERASE) m_styleId = m_eraseStyle;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
RasterStrokeGenerator::~RasterStrokeGenerator() {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
shun-iwasawa |
cd7d6a |
void RasterStrokeGenerator::add(const TThickPoint &p) {
|
|
Shinya Kitaoka |
120a6e |
TThickPoint pp = p;
|
|
Shinya Kitaoka |
120a6e |
TThickPoint mid((m_points.back() + pp) * 0.5,
|
|
Shinya Kitaoka |
120a6e |
(p.thick + m_points.back().thick) * 0.5);
|
|
Shinya Kitaoka |
120a6e |
m_points.push_back(mid);
|
|
Shinya Kitaoka |
120a6e |
m_points.push_back(pp);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Disegna il tratto interamente
|
|
justburner |
e250b7 |
void RasterStrokeGenerator::generateStroke(bool isPencil,
|
|
justburner |
e250b7 |
bool isStraight) const {
|
|
Shinya Kitaoka |
120a6e |
std::vector<tthickpoint> points(m_points);</tthickpoint>
|
|
Shinya Kitaoka |
120a6e |
int size = points.size();
|
|
Shinya Kitaoka |
120a6e |
// Prende un buffer trasparente di appoggio
|
|
Shinya Kitaoka |
120a6e |
TRect box = getBBox(points);
|
|
Shinya Kitaoka |
120a6e |
TPoint newOrigin = box.getP00();
|
|
Shinya Kitaoka |
120a6e |
TRasterCM32P rasBuffer(box.getSize());
|
|
Shinya Kitaoka |
120a6e |
rasBuffer->clear();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Trasla i punti secondo il nuovo sitema di riferimento
|
|
Shinya Kitaoka |
120a6e |
translatePoints(points, newOrigin);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
std::vector<tthickpoint> partialPoints;</tthickpoint>
|
|
Shinya Kitaoka |
120a6e |
if (size == 1) {
|
|
Shinya Kitaoka |
120a6e |
rasterBrush(rasBuffer, points, m_styleId, !isPencil);
|
|
Shinya Kitaoka |
120a6e |
placeOver(m_raster, rasBuffer, newOrigin);
|
|
Shinya Kitaoka |
120a6e |
} else if (size <= 3) {
|
|
Shinya Kitaoka |
120a6e |
std::vector<tthickpoint> partialPoints;</tthickpoint>
|
|
justburner |
e250b7 |
if (isStraight && size == 3) {
|
|
justburner |
e250b7 |
partialPoints.push_back(points[0]);
|
|
justburner |
e250b7 |
partialPoints.push_back(points[2]);
|
|
justburner |
e250b7 |
} else {
|
|
justburner |
e250b7 |
partialPoints.push_back(points[0]);
|
|
justburner |
e250b7 |
partialPoints.push_back(points[1]);
|
|
justburner |
e250b7 |
}
|
|
Shinya Kitaoka |
120a6e |
rasterBrush(rasBuffer, partialPoints, m_styleId, !isPencil);
|
|
Shinya Kitaoka |
120a6e |
placeOver(m_raster, rasBuffer, newOrigin);
|
|
shun-iwasawa |
443318 |
} else if (size % 2 == 1) /*-- In the case of odd numbers --*/
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
int strokeCount = (size - 1) / 2 - 1;
|
|
Shinya Kitaoka |
120a6e |
std::vector<tthickpoint> partialPoints;</tthickpoint>
|
|
Shinya Kitaoka |
120a6e |
partialPoints.push_back(points[0]);
|
|
Shinya Kitaoka |
120a6e |
partialPoints.push_back(points[1]);
|
|
Shinya Kitaoka |
120a6e |
rasterBrush(rasBuffer, partialPoints, m_styleId, !isPencil);
|
|
Shinya Kitaoka |
120a6e |
placeOver(m_raster, rasBuffer, newOrigin);
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < strokeCount; i++) {
|
|
Shinya Kitaoka |
120a6e |
partialPoints.clear();
|
|
Shinya Kitaoka |
120a6e |
rasBuffer->clear();
|
|
Shinya Kitaoka |
120a6e |
partialPoints.push_back(points[i * 2 + 1]);
|
|
Shinya Kitaoka |
120a6e |
partialPoints.push_back(points[i * 2 + 2]);
|
|
Shinya Kitaoka |
120a6e |
partialPoints.push_back(points[i * 2 + 3]);
|
|
Shinya Kitaoka |
120a6e |
if (i == strokeCount - 1) partialPoints.push_back(points[i * 2 + 4]);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
rasterBrush(rasBuffer, partialPoints, m_styleId, !isPencil);
|
|
Shinya Kitaoka |
120a6e |
placeOver(m_raster, rasBuffer, newOrigin);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
std::vector<tthickpoint> partialPoints;</tthickpoint>
|
|
Shinya Kitaoka |
120a6e |
partialPoints.push_back(points[0]);
|
|
Shinya Kitaoka |
120a6e |
partialPoints.push_back(points[1]);
|
|
Shinya Kitaoka |
120a6e |
rasterBrush(rasBuffer, partialPoints, m_styleId, !isPencil);
|
|
Shinya Kitaoka |
120a6e |
placeOver(m_raster, rasBuffer, newOrigin);
|
|
Shinya Kitaoka |
120a6e |
if (size > 2) {
|
|
Shinya Kitaoka |
120a6e |
partialPoints.clear();
|
|
Shinya Kitaoka |
120a6e |
std::vector<tthickpoint>::iterator it = points.begin();</tthickpoint>
|
|
Shinya Kitaoka |
120a6e |
it++;
|
|
Shinya Kitaoka |
120a6e |
partialPoints.insert(partialPoints.begin(), it, points.end());
|
|
Shinya Kitaoka |
120a6e |
rasterBrush(rasBuffer, partialPoints, m_styleId, !isPencil);
|
|
Shinya Kitaoka |
120a6e |
placeOver(m_raster, rasBuffer, newOrigin);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TRect RasterStrokeGenerator::generateLastPieceOfStroke(bool isPencil,
|
|
justburner |
e250b7 |
bool closeStroke,
|
|
justburner |
e250b7 |
bool isStraight) {
|
|
Shinya Kitaoka |
120a6e |
std::vector<tthickpoint> points;</tthickpoint>
|
|
Shinya Kitaoka |
120a6e |
int size = m_points.size();
|
|
Shinya Kitaoka |
120a6e |
|
|
justburner |
e250b7 |
if (isStraight) {
|
|
justburner |
e250b7 |
points.push_back(m_points[0]);
|
|
justburner |
e250b7 |
points.push_back(m_points[2]);
|
|
justburner |
e250b7 |
} else if (size == 3) {
|
|
Shinya Kitaoka |
120a6e |
points.push_back(m_points[0]);
|
|
Shinya Kitaoka |
120a6e |
points.push_back(m_points[1]);
|
|
Shinya Kitaoka |
120a6e |
} else if (size == 1)
|
|
Shinya Kitaoka |
120a6e |
points.push_back(m_points[0]);
|
|
Shinya Kitaoka |
120a6e |
else {
|
|
Shinya Kitaoka |
120a6e |
points.push_back(m_points[size - 4]);
|
|
Shinya Kitaoka |
120a6e |
points.push_back(m_points[size - 3]);
|
|
Shinya Kitaoka |
120a6e |
points.push_back(m_points[size - 2]);
|
|
Shinya Kitaoka |
120a6e |
if (closeStroke) points.push_back(m_points[size - 1]);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TRect box = getBBox(points);
|
|
Shinya Kitaoka |
120a6e |
TPoint newOrigin = box.getP00();
|
|
Shinya Kitaoka |
120a6e |
TRasterCM32P rasBuffer(box.getSize());
|
|
Shinya Kitaoka |
120a6e |
rasBuffer->clear();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Trasla i punti secondo il nuovo sitema di riferimento
|
|
Shinya Kitaoka |
120a6e |
translatePoints(points, newOrigin);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
rasterBrush(rasBuffer, points, m_styleId, !isPencil);
|
|
Shinya Kitaoka |
120a6e |
placeOver(m_raster, rasBuffer, newOrigin);
|
|
Shinya Kitaoka |
120a6e |
return box;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Ritorna il rettangolo contenente i dischi generati con centri in "points" e
|
|
Shinya Kitaoka |
120a6e |
// diametro "points.thick" +3 pixel a bordo
|
|
Shinya Kitaoka |
120a6e |
TRect RasterStrokeGenerator::getBBox(
|
|
Shinya Kitaoka |
120a6e |
const std::vector<tthickpoint> &points) const {</tthickpoint>
|
|
Shinya Kitaoka |
120a6e |
double x0 = (std::numeric_limits<double>::max)(),</double>
|
|
Shinya Kitaoka |
120a6e |
y0 = (std::numeric_limits<double>::max)(),</double>
|
|
Shinya Kitaoka |
120a6e |
x1 = -(std::numeric_limits<double>::max)(),</double>
|
|
Shinya Kitaoka |
120a6e |
y1 = -(std::numeric_limits<double>::max)();</double>
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < (int)points.size(); i++) {
|
|
shun-iwasawa |
443318 |
double radius = points[i].thick * 0.5;
|
|
Shinya Kitaoka |
120a6e |
if (points[i].x - radius < x0) x0 = points[i].x - radius;
|
|
Shinya Kitaoka |
120a6e |
if (points[i].x + radius > x1) x1 = points[i].x + radius;
|
|
Shinya Kitaoka |
120a6e |
if (points[i].y - radius < y0) y0 = points[i].y - radius;
|
|
Shinya Kitaoka |
120a6e |
if (points[i].y + radius > y1) y1 = points[i].y + radius;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
return TRect(TPoint((int)floor(x0 - 3), (int)floor(y0 - 3)),
|
|
Shinya Kitaoka |
120a6e |
TPoint((int)ceil(x1 + 3), (int)ceil(y1 + 3)));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Ricalcola i punti in un nuovo sistema di riferimento
|
|
Shinya Kitaoka |
120a6e |
void RasterStrokeGenerator::translatePoints(std::vector<tthickpoint> &points,</tthickpoint>
|
|
Shinya Kitaoka |
120a6e |
const TPoint &newOrigin) const {
|
|
Shinya Kitaoka |
120a6e |
TPointD p(newOrigin.x, newOrigin.y);
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < (int)points.size(); i++) points[i] -= p;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Effettua la over.
|
|
Shinya Kitaoka |
120a6e |
void RasterStrokeGenerator::placeOver(const TRasterCM32P &out,
|
|
Shinya Kitaoka |
120a6e |
const TRasterCM32P &in,
|
|
Shinya Kitaoka |
120a6e |
const TPoint &p) const {
|
|
Shinya Kitaoka |
120a6e |
TRect inBox = in->getBounds() + p;
|
|
Shinya Kitaoka |
120a6e |
TRect outBox = out->getBounds();
|
|
Shinya Kitaoka |
120a6e |
TRect box = inBox * outBox;
|
|
Shinya Kitaoka |
120a6e |
if (box.isEmpty()) return;
|
|
Shinya Kitaoka |
120a6e |
TRasterCM32P rOut = out->extract(box);
|
|
Shinya Kitaoka |
120a6e |
TRect box2 = box - p;
|
|
Shinya Kitaoka |
120a6e |
TRasterCM32P rIn = in->extract(box2);
|
|
Shinya Kitaoka |
120a6e |
for (int y = 0; y < rOut->getLy(); y++) {
|
|
shun-iwasawa |
443318 |
/*--Finger Tool Boundary Conditions --*/
|
|
Shinya Kitaoka |
120a6e |
if (m_task == FINGER && (y == 0 || y == rOut->getLy() - 1)) continue;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TPixelCM32 *inPix = rIn->pixels(y);
|
|
Shinya Kitaoka |
120a6e |
TPixelCM32 *outPix = rOut->pixels(y);
|
|
Shinya Kitaoka |
120a6e |
TPixelCM32 *outEnd = outPix + rOut->getLx();
|
|
Shinya Kitaoka |
120a6e |
for (; outPix < outEnd; ++inPix, ++outPix) {
|
|
Shinya Kitaoka |
120a6e |
if (m_task == BRUSH) {
|
|
Shinya Kitaoka |
120a6e |
int inTone = inPix->getTone();
|
|
Shinya Kitaoka |
120a6e |
int outTone = outPix->getTone();
|
|
manongjohn |
f936c0 |
if (inPix->isPureInk() && !m_selective && !m_modifierLockAlpha) {
|
|
Shinya Kitaoka |
120a6e |
*outPix = TPixelCM32(inPix->getInk(), outPix->getPaint(), inTone);
|
|
Shinya Kitaoka |
120a6e |
continue;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
manongjohn |
f936c0 |
if (m_modifierLockAlpha && !outPix->isPureInk() &&
|
|
manongjohn |
f936c0 |
outPix->getPaint() == 0 && outPix->getTone() == 255) {
|
|
manongjohn |
f936c0 |
*outPix = TPixelCM32(outPix->getInk(), outPix->getPaint(), outTone);
|
|
manongjohn |
f936c0 |
continue;
|
|
manongjohn |
f936c0 |
}
|
|
Shinya Kitaoka |
120a6e |
if (outPix->isPureInk() && m_selective) {
|
|
shun-iwasawa |
975eb1 |
if (!m_isPaletteOrder || m_aboveStyleIds.contains(outPix->getInk())) {
|
|
shun-iwasawa |
975eb1 |
*outPix = TPixelCM32(outPix->getInk(), outPix->getPaint(), outTone);
|
|
shun-iwasawa |
975eb1 |
continue;
|
|
shun-iwasawa |
975eb1 |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (inTone <= outTone) {
|
|
justburner |
5aabe8 |
*outPix = TPixelCM32(inPix->getInk(), outPix->getPaint(),
|
|
justburner |
5aabe8 |
m_modifierLockAlpha ? outTone : inTone);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (m_task == ERASE) {
|
|
Shinya Kitaoka |
120a6e |
if (m_colorType == INK) {
|
|
Shinya Kitaoka |
120a6e |
if (!m_keepAntiAlias) {
|
|
Shinya Kitaoka |
120a6e |
if (inPix->getTone() == 0 &&
|
|
Shinya Kitaoka |
120a6e |
(!m_selective ||
|
|
Shinya Kitaoka |
120a6e |
(m_selective && outPix->getInk() == m_selectedStyle))) {
|
|
Shinya Kitaoka |
120a6e |
outPix->setTone(255);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} else if (inPix->getTone() < 255 &&
|
|
Shinya Kitaoka |
120a6e |
(!m_selective ||
|
|
Shinya Kitaoka |
120a6e |
(m_selective && outPix->getInk() == m_selectedStyle))) {
|
|
Shinya Kitaoka |
120a6e |
outPix->setTone(
|
|
Shinya Kitaoka |
120a6e |
std::max(outPix->getTone(), 255 - inPix->getTone()));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (m_colorType == PAINT) {
|
|
Shinya Kitaoka |
120a6e |
if (inPix->getTone() == 0 &&
|
|
Shinya Kitaoka |
120a6e |
(!m_selective ||
|
|
Shinya Kitaoka |
120a6e |
(m_selective && outPix->getPaint() == m_selectedStyle)))
|
|
Shinya Kitaoka |
120a6e |
outPix->setPaint(0);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (m_colorType == INKNPAINT) {
|
|
Shinya Kitaoka |
120a6e |
if (inPix->getTone() < 255 &&
|
|
Shinya Kitaoka |
120a6e |
(!m_selective ||
|
|
Shinya Kitaoka |
120a6e |
(m_selective && outPix->getPaint() == m_selectedStyle)))
|
|
Shinya Kitaoka |
120a6e |
outPix->setPaint(0);
|
|
Shinya Kitaoka |
120a6e |
if (!m_keepAntiAlias) {
|
|
Shinya Kitaoka |
120a6e |
if (inPix->getTone() == 0 &&
|
|
Shinya Kitaoka |
120a6e |
(!m_selective ||
|
|
Shinya Kitaoka |
120a6e |
(m_selective && outPix->getInk() == m_selectedStyle))) {
|
|
Shinya Kitaoka |
120a6e |
outPix->setTone(255);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} else if (inPix->getTone() < 255 &&
|
|
Shinya Kitaoka |
120a6e |
(!m_selective ||
|
|
Shinya Kitaoka |
120a6e |
(m_selective && outPix->getInk() == m_selectedStyle))) {
|
|
Shinya Kitaoka |
120a6e |
outPix->setTone(
|
|
Shinya Kitaoka |
120a6e |
std::max(outPix->getTone(), 255 - inPix->getTone()));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} else if (m_task == PAINTBRUSH) {
|
|
Shinya Kitaoka |
120a6e |
if (!inPix->isPureInk()) continue;
|
|
manongjohn |
f027d1 |
int paintIdx = outPix->getPaint();
|
|
manongjohn |
f027d1 |
bool changePaint = (!m_selective && !m_modifierLockAlpha) ||
|
|
manongjohn |
f027d1 |
(m_selective && paintIdx == 0) ||
|
|
manongjohn |
f027d1 |
(m_modifierLockAlpha && paintIdx != 0);
|
|
Shinya Kitaoka |
120a6e |
if (m_colorType == INK)
|
|
Shinya Kitaoka |
120a6e |
*outPix = TPixelCM32(inPix->getInk(), outPix->getPaint(),
|
|
Shinya Kitaoka |
120a6e |
outPix->getTone());
|
|
Shinya Kitaoka |
120a6e |
if (m_colorType == PAINT)
|
|
Shinya Kitaoka |
120a6e |
if (changePaint)
|
|
Shinya Kitaoka |
120a6e |
*outPix = TPixelCM32(outPix->getInk(), inPix->getInk(),
|
|
Shinya Kitaoka |
120a6e |
outPix->getTone());
|
|
Shinya Kitaoka |
120a6e |
if (m_colorType == INKNPAINT)
|
|
Shinya Kitaoka |
120a6e |
*outPix =
|
|
Shinya Kitaoka |
120a6e |
TPixelCM32(inPix->getInk(),
|
|
Shinya Kitaoka |
120a6e |
changePaint ? inPix->getInk() : outPix->getPaint(),
|
|
Shinya Kitaoka |
120a6e |
outPix->getTone());
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/*-- Finger tool --*/
|
|
Shinya Kitaoka |
120a6e |
else if (m_task == FINGER) {
|
|
shun-iwasawa |
443318 |
/*-- Boundary Conditions --*/
|
|
Shinya Kitaoka |
120a6e |
if (outPix == rOut->pixels(y) || outPix == outEnd - 1) continue;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int inkId = inPix->getInk();
|
|
Shinya Kitaoka |
120a6e |
if (inkId == 0) continue;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TPixelCM32 *neighbourPixels[4];
|
|
shun-iwasawa |
443318 |
neighbourPixels[0] = outPix - 1; /* left */
|
|
shun-iwasawa |
443318 |
neighbourPixels[1] = outPix + 1; /* right */
|
|
shun-iwasawa |
443318 |
neighbourPixels[2] = outPix - rOut->getWrap(); /* top */
|
|
shun-iwasawa |
443318 |
neighbourPixels[3] = outPix + rOut->getWrap(); /* bottom */
|
|
Shinya Kitaoka |
120a6e |
int count = 0;
|
|
Shinya Kitaoka |
120a6e |
int tone = outPix->getTone();
|
|
Shinya Kitaoka |
120a6e |
|
|
shun-iwasawa |
443318 |
/*--- When Invert is off: Fill hole operation ---*/
|
|
Shinya Kitaoka |
120a6e |
if (!m_selective) {
|
|
shun-iwasawa |
443318 |
/*-- For 4 neighborhood pixels --*/
|
|
Shinya Kitaoka |
120a6e |
int minTone = tone;
|
|
Shinya Kitaoka |
120a6e |
for (int p = 0; p < 4; p++) {
|
|
shun-iwasawa |
443318 |
/*-- Count up the items that have darker lines (lower Tone) than the
|
|
shun-iwasawa |
443318 |
* current pixel. --*/
|
|
Shinya Kitaoka |
120a6e |
if (neighbourPixels[p]->getTone() < tone) {
|
|
Shinya Kitaoka |
120a6e |
count++;
|
|
Shinya Kitaoka |
120a6e |
if (neighbourPixels[p]->getTone() < minTone)
|
|
Shinya Kitaoka |
120a6e |
minTone = neighbourPixels[p]->getTone();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
shun-iwasawa |
443318 |
/*--- If 3 or more surrounding pixels are darker, replace with the
|
|
shun-iwasawa |
443318 |
* minimum Tone ---*/
|
|
Shinya Kitaoka |
120a6e |
if (count <= 2) continue;
|
|
Shinya Kitaoka |
120a6e |
*outPix = TPixelCM32(inkId, outPix->getPaint(), minTone);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
shun-iwasawa |
443318 |
/*--- When Invert is ON: Operation to trim protrusion ---*/
|
|
Shinya Kitaoka |
120a6e |
else {
|
|
Shinya Kitaoka |
120a6e |
if (outPix->isPurePaint() || outPix->getInk() != inkId) continue;
|
|
Shinya Kitaoka |
120a6e |
|
|
shun-iwasawa |
443318 |
/*-- For 4 neighborhood pixels --*/
|
|
Shinya Kitaoka |
120a6e |
int maxTone = tone;
|
|
Shinya Kitaoka |
120a6e |
for (int p = 0; p < 4; p++) {
|
|
Shinya Kitaoka |
120a6e |
/*--
|
|
shun-iwasawa |
443318 |
* Count up items whose Ink# is not Current or whose line is thinner
|
|
shun-iwasawa |
443318 |
* than your Pixel (Tone is higher).
|
|
Shinya Kitaoka |
120a6e |
* --*/
|
|
Shinya Kitaoka |
120a6e |
if (neighbourPixels[p]->getInk() != inkId) {
|
|
Shinya Kitaoka |
120a6e |
count++;
|
|
Shinya Kitaoka |
120a6e |
maxTone = 255;
|
|
Shinya Kitaoka |
120a6e |
} else if (neighbourPixels[p]->getTone() > tone) {
|
|
Shinya Kitaoka |
120a6e |
count++;
|
|
Shinya Kitaoka |
120a6e |
if (neighbourPixels[p]->getTone() > maxTone)
|
|
Shinya Kitaoka |
120a6e |
maxTone = neighbourPixels[p]->getTone();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
shun-iwasawa |
443318 |
/*--- If 3 or more surrounding pixels are thinner, replace with the
|
|
shun-iwasawa |
443318 |
* maximum Tone ---*/
|
|
Shinya Kitaoka |
120a6e |
if (count <= 2) continue;
|
|
Shinya Kitaoka |
120a6e |
*outPix = TPixelCM32((maxTone == 255) ? 0 : inkId, outPix->getPaint(),
|
|
Shinya Kitaoka |
120a6e |
maxTone);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
justburner |
e250b7 |
TRect RasterStrokeGenerator::getLastRect(bool isStraight) const {
|
|
Shinya Kitaoka |
120a6e |
std::vector<tthickpoint> points;</tthickpoint>
|
|
Shinya Kitaoka |
120a6e |
int size = m_points.size();
|
|
Shinya Kitaoka |
120a6e |
|
|
justburner |
e250b7 |
if (isStraight) {
|
|
justburner |
e250b7 |
points.push_back(m_points[0]);
|
|
justburner |
e250b7 |
points.push_back(m_points[2]);
|
|
justburner |
e250b7 |
} else if (size == 3) {
|
|
Shinya Kitaoka |
120a6e |
points.push_back(m_points[0]);
|
|
Shinya Kitaoka |
120a6e |
points.push_back(m_points[1]);
|
|
Shinya Kitaoka |
120a6e |
} else if (size == 1)
|
|
Shinya Kitaoka |
120a6e |
points.push_back(m_points[0]);
|
|
Shinya Kitaoka |
120a6e |
else {
|
|
Shinya Kitaoka |
120a6e |
points.push_back(m_points[size - 4]);
|
|
Shinya Kitaoka |
120a6e |
points.push_back(m_points[size - 3]);
|
|
Shinya Kitaoka |
120a6e |
points.push_back(m_points[size - 2]);
|
|
Shinya Kitaoka |
120a6e |
points.push_back(m_points[size - 1]);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
return getBBox(points);
|
|
Toshihiro Shimizu |
890ddd |
}
|