|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "tools/stylepicker.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tcolorstyles.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tstroke.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tofflinegl.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tvectorrenderdata.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tvectorimage.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "ttoonzimage.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "trasterimage.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/dpiscale.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tpixelutils.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tregion.h"
|
|
shun-iwasawa |
2d0135 |
#include "toonzqt/gutil.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
shun-iwasawa |
21c135 |
#include <qrect></qrect>
|
|
shun-iwasawa |
21c135 |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
shun-iwasawa |
f2e168 |
StylePicker::StylePicker(const QWidget *parent, const TImageP &image)
|
|
shun-iwasawa |
f2e168 |
: m_widget(parent), m_image(image), m_palette(image->getPalette()) {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
shun-iwasawa |
f2e168 |
StylePicker::StylePicker(const QWidget *parent, const TImageP &image,
|
|
shun-iwasawa |
f2e168 |
const TPaletteP &palette)
|
|
shun-iwasawa |
f2e168 |
: m_widget(parent), m_image(image), m_palette(palette) {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TPoint StylePicker::getRasterPoint(const TPointD &p) const {
|
|
Shinya Kitaoka |
120a6e |
if (TToonzImageP ti = m_image) {
|
|
Shinya Kitaoka |
120a6e |
// DpiScale dpiScale(ti);
|
|
Shinya Kitaoka |
120a6e |
TDimension size = ti->getSize();
|
|
Shinya Kitaoka |
120a6e |
return TPoint(tround(0.5 * size.lx + p.x), /// dpiScale.getSx()),
|
|
Shinya Kitaoka |
120a6e |
tround(0.5 * size.ly + p.y)); /// dpiScale.getSy()));
|
|
Shinya Kitaoka |
120a6e |
} else if (TRasterImageP ri = m_image) {
|
|
Shinya Kitaoka |
120a6e |
// DpiScale dpiScale(ri);
|
|
Shinya Kitaoka |
120a6e |
TDimension size = ri->getRaster()->getSize();
|
|
Shinya Kitaoka |
120a6e |
return TPoint(tround(0.5 * size.lx + p.x), // /dpiScale.getSx()),
|
|
Shinya Kitaoka |
120a6e |
tround(0.5 * size.ly + p.y)); // /dpiScale.getSy()));
|
|
Shinya Kitaoka |
120a6e |
} else
|
|
Shinya Kitaoka |
120a6e |
return TPoint(tround(p.x), tround(p.y));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Shinya Kitaoka |
120a6e |
/*-- (StylePickerTool内で)LineとAreaを切り替えてPickできる。mode: 0=Area,
|
|
Shinya Kitaoka |
120a6e |
* 1=Line, 2=Line&Areas(default) --*/
|
|
shun-iwasawa |
2d0135 |
int StylePicker::pickStyleId(const TPointD &pos, double radius, double scale2,
|
|
Shinya Kitaoka |
120a6e |
int mode) const {
|
|
Shinya Kitaoka |
120a6e |
int styleId = 0;
|
|
Shinya Kitaoka |
120a6e |
if (TToonzImageP ti = m_image) {
|
|
Shinya Kitaoka |
120a6e |
TRasterCM32P ras = ti->getRaster();
|
|
Shinya Kitaoka |
120a6e |
TPoint point = getRasterPoint(pos);
|
|
Shinya Kitaoka |
120a6e |
if (!ras->getBounds().contains(point)) return -1;
|
|
Shinya Kitaoka |
120a6e |
TPixelCM32 col = ras->pixels(point.y)[point.x];
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
switch (mode) {
|
|
Shinya Kitaoka |
120a6e |
case 0: // AREAS
|
|
Shinya Kitaoka |
120a6e |
styleId = col.getPaint();
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case 1: // LINES
|
|
Shinya Kitaoka |
120a6e |
styleId = col.getInk();
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case 2: // ALL (Line & Area)
|
|
Shinya Kitaoka |
120a6e |
default:
|
|
Shinya Kitaoka |
120a6e |
styleId = col.isPurePaint() ? col.getPaint() : col.getInk();
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} else if (TRasterImageP ri = m_image) {
|
|
Shinya Kitaoka |
120a6e |
const TPalette *palette = m_palette.getPointer();
|
|
Shinya Kitaoka |
120a6e |
if (!palette) return -1;
|
|
Shinya Kitaoka |
120a6e |
TRaster32P ras = ri->getRaster();
|
|
Shinya Kitaoka |
120a6e |
if (!ras) return -1;
|
|
Shinya Kitaoka |
120a6e |
TPoint point = getRasterPoint(pos);
|
|
Shinya Kitaoka |
120a6e |
if (!ras->getBounds().contains(point)) return -1;
|
|
Shinya Kitaoka |
120a6e |
TPixel32 col = ras->pixels(point.y)[point.x];
|
|
Shinya Kitaoka |
120a6e |
styleId = palette->getClosestStyle(col);
|
|
Shinya Kitaoka |
120a6e |
} else if (TVectorImageP vi = m_image) {
|
|
Shinya Kitaoka |
120a6e |
// prima cerca lo stile della regione piu' vicina
|
|
shun-iwasawa |
21c135 |
TRegion *r = vi->getRegion(pos);
|
|
Shinya Kitaoka |
120a6e |
if (r) styleId = r->getStyle();
|
|
Shinya Kitaoka |
120a6e |
bool strokeFound;
|
|
Shinya Kitaoka |
120a6e |
double dist2, w, thick;
|
|
Shinya Kitaoka |
120a6e |
UINT index;
|
|
Shinya Kitaoka |
120a6e |
//! funzionerebbe ancora meglio con un getNearestStroke che considera
|
|
Shinya Kitaoka |
120a6e |
// la thickness, cioe' la min distance dalla outline e non dalla centerLine
|
|
Shinya Kitaoka |
120a6e |
strokeFound = vi->getNearestStroke(pos, w, index, dist2);
|
|
Shinya Kitaoka |
120a6e |
if (strokeFound) {
|
|
shun-iwasawa |
f2e168 |
int devPixRatio = getDevicePixelRatio(m_widget);
|
|
shun-iwasawa |
2d0135 |
dist2 *= scale2;
|
|
Shinya Kitaoka |
120a6e |
TStroke *stroke = vi->getStroke(index);
|
|
Shinya Kitaoka |
120a6e |
thick = stroke->getThickPoint(w).thick;
|
|
shun-iwasawa |
2d0135 |
double len2 = thick * thick * scale2;
|
|
shun-iwasawa |
2d0135 |
const double minDist2 =
|
|
shun-iwasawa |
2d0135 |
(styleId == 0) ? radius * radius * (double)(devPixRatio * devPixRatio)
|
|
shun-iwasawa |
2d0135 |
: 0;
|
|
shun-iwasawa |
2d0135 |
double checkDist = std::max(minDist2, len2);
|
|
shun-iwasawa |
2d0135 |
if (dist2 < checkDist) {
|
|
Shinya Kitaoka |
120a6e |
assert(stroke);
|
|
Shinya Kitaoka |
120a6e |
styleId = stroke->getStyle();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
return styleId;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
/*--- Toonz Raster LevelのToneを拾う。 ---*/
|
|
shun-iwasawa |
21c135 |
int StylePicker::pickTone(const TPointD &pos) const {
|
|
Shinya Kitaoka |
120a6e |
if (TToonzImageP ti = m_image) {
|
|
Shinya Kitaoka |
120a6e |
TRasterCM32P ras = ti->getRaster();
|
|
Shinya Kitaoka |
120a6e |
if (!ras) return -1;
|
|
Shinya Kitaoka |
120a6e |
TPoint point = getRasterPoint(pos);
|
|
Shinya Kitaoka |
120a6e |
if (!ras->getBounds().contains(point)) return -1;
|
|
Shinya Kitaoka |
120a6e |
TPixelCM32 col = ras->pixels(point.y)[point.x];
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return col.getTone();
|
|
Shinya Kitaoka |
120a6e |
} else
|
|
Shinya Kitaoka |
120a6e |
return -1;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
shun-iwasawa |
2d0135 |
TPixel32 StylePicker::pickColor(const TPointD &pos, double radius,
|
|
shun-iwasawa |
2d0135 |
double scale2) const {
|
|
Shinya Kitaoka |
120a6e |
TToonzImageP ti = m_image;
|
|
Shinya Kitaoka |
120a6e |
TRasterImageP ri = m_image;
|
|
shun-iwasawa |
21c135 |
TVectorImageP vi = m_image;
|
|
Shinya Kitaoka |
120a6e |
if (!!ri) // !!ti || !!ri)
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
TRasterP raster;
|
|
Shinya Kitaoka |
120a6e |
// if(ti)
|
|
Shinya Kitaoka |
120a6e |
// raster = ti->getRGBM(true);
|
|
Shinya Kitaoka |
120a6e |
// else
|
|
Shinya Kitaoka |
120a6e |
raster = ri->getRaster();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TPoint point = getRasterPoint(pos);
|
|
Shinya Kitaoka |
120a6e |
if (!raster->getBounds().contains(point)) return TPixel32::Transparent;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TRaster32P raster32 = raster;
|
|
Shinya Kitaoka |
120a6e |
if (raster32) return raster32->pixels(point.y)[point.x];
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TRasterGR8P rasterGR8 = raster;
|
|
Shinya Kitaoka |
120a6e |
if (rasterGR8) return toPixel32(rasterGR8->pixels(point.y)[point.x]);
|
|
shun-iwasawa |
21c135 |
} else if (vi) {
|
|
Shinya Kitaoka |
120a6e |
const TPalette *palette = m_palette.getPointer();
|
|
Shinya Kitaoka |
120a6e |
if (!palette) return TPixel32::Transparent;
|
|
shun-iwasawa |
2d0135 |
int styleId = pickStyleId(pos, radius, scale2);
|
|
Shinya Kitaoka |
120a6e |
if (0 <= styleId && styleId < palette->getStyleCount())
|
|
Shinya Kitaoka |
120a6e |
return palette->getStyle(styleId)->getAverageColor();
|
|
shun-iwasawa |
21c135 |
} else if (ti) {
|
|
shun-iwasawa |
21c135 |
const TPalette *palette = m_palette.getPointer();
|
|
shun-iwasawa |
21c135 |
if (!palette) return TPixel32::Transparent;
|
|
shun-iwasawa |
2d0135 |
int paintId = pickStyleId(pos, radius, scale2, 0);
|
|
shun-iwasawa |
2d0135 |
int inkId = pickStyleId(pos, radius, scale2, 1);
|
|
shun-iwasawa |
21c135 |
int tone = pickTone(pos);
|
|
shun-iwasawa |
21c135 |
TPixel32 ink, paint;
|
|
shun-iwasawa |
21c135 |
if (0 <= inkId && inkId < palette->getStyleCount())
|
|
shun-iwasawa |
21c135 |
ink = palette->getStyle(inkId)->getAverageColor();
|
|
shun-iwasawa |
21c135 |
if (0 <= paintId && paintId < palette->getStyleCount())
|
|
shun-iwasawa |
21c135 |
paint = palette->getStyle(paintId)->getAverageColor();
|
|
shun-iwasawa |
21c135 |
|
|
shun-iwasawa |
21c135 |
if (tone == 0)
|
|
shun-iwasawa |
21c135 |
return ink;
|
|
shun-iwasawa |
21c135 |
else if (tone == 255)
|
|
shun-iwasawa |
21c135 |
return paint;
|
|
shun-iwasawa |
21c135 |
else
|
|
shun-iwasawa |
21c135 |
return blend(ink, paint, tone, TPixelCM32::getMaxTone());
|
|
shun-iwasawa |
21c135 |
}
|
|
shun-iwasawa |
21c135 |
return TPixel32::Transparent;
|
|
shun-iwasawa |
21c135 |
}
|
|
shun-iwasawa |
21c135 |
|
|
shun-iwasawa |
21c135 |
//---------------------------------------------------------
|
|
shun-iwasawa |
21c135 |
|
|
shun-iwasawa |
d5045c |
TPixel64 StylePicker::pickColor16(const TPointD &pos, double radius,
|
|
shun-iwasawa |
d5045c |
double scale2) const {
|
|
shun-iwasawa |
d5045c |
TToonzImageP ti = m_image;
|
|
shun-iwasawa |
d5045c |
TRasterImageP ri = m_image;
|
|
shun-iwasawa |
d5045c |
TVectorImageP vi = m_image;
|
|
shun-iwasawa |
d5045c |
assert(ri && !ti && !vi);
|
|
shun-iwasawa |
d5045c |
if (!ri || ti || vi) return TPixel64::Transparent;
|
|
shun-iwasawa |
d5045c |
TRasterP raster = ri->getRaster();
|
|
shun-iwasawa |
d5045c |
if (raster->getPixelSize() != 8) return TPixel64::Transparent;
|
|
shun-iwasawa |
d5045c |
TPoint point = getRasterPoint(pos);
|
|
shun-iwasawa |
d5045c |
if (!raster->getBounds().contains(point)) return TPixel64::Transparent;
|
|
shun-iwasawa |
d5045c |
TRaster64P raster64 = raster;
|
|
shun-iwasawa |
d5045c |
if (!raster64) return TPixel64::Transparent;
|
|
shun-iwasawa |
d5045c |
return raster64->pixels(point.y)[point.x];
|
|
shun-iwasawa |
d5045c |
}
|
|
shun-iwasawa |
481b59 |
|
|
shun-iwasawa |
481b59 |
//---------------------------------------------------------
|
|
shun-iwasawa |
481b59 |
|
|
shun-iwasawa |
481b59 |
TPixelF StylePicker::pickColor32F(const TPointD &pos, double radius,
|
|
shun-iwasawa |
481b59 |
double scale2) const {
|
|
shun-iwasawa |
481b59 |
TToonzImageP ti = m_image;
|
|
shun-iwasawa |
481b59 |
TRasterImageP ri = m_image;
|
|
shun-iwasawa |
481b59 |
TVectorImageP vi = m_image;
|
|
shun-iwasawa |
481b59 |
assert(ri && !ti && !vi);
|
|
shun-iwasawa |
481b59 |
if (!ri || ti || vi) return TPixelF::Transparent;
|
|
shun-iwasawa |
481b59 |
TRasterP raster = ri->getRaster();
|
|
shun-iwasawa |
481b59 |
if (raster->getPixelSize() != 16) return TPixelF::Transparent;
|
|
shun-iwasawa |
481b59 |
TPoint point = getRasterPoint(pos);
|
|
shun-iwasawa |
481b59 |
if (!raster->getBounds().contains(point)) return TPixelF::Transparent;
|
|
shun-iwasawa |
481b59 |
TRasterFP rasterF = raster;
|
|
shun-iwasawa |
481b59 |
if (!rasterF) return TPixelF::Transparent;
|
|
shun-iwasawa |
481b59 |
return rasterF->pixels(point.y)[point.x];
|
|
shun-iwasawa |
481b59 |
}
|
|
shun-iwasawa |
481b59 |
|
|
shun-iwasawa |
d5045c |
//---------------------------------------------------------
|
|
shun-iwasawa |
d5045c |
|
|
shun-iwasawa |
21c135 |
TPixel32 StylePicker::pickAverageColor(const TRectD &rect) const {
|
|
shun-iwasawa |
21c135 |
TRasterImageP ri = m_image;
|
|
shun-iwasawa |
21c135 |
assert(ri);
|
|
shun-iwasawa |
21c135 |
if (!!ri) {
|
|
shun-iwasawa |
21c135 |
TRasterP raster;
|
|
shun-iwasawa |
21c135 |
raster = ri->getRaster();
|
|
shun-iwasawa |
21c135 |
|
|
shun-iwasawa |
21c135 |
TPoint topLeft = getRasterPoint(rect.getP00());
|
|
shun-iwasawa |
21c135 |
TPoint bottomRight = getRasterPoint(rect.getP11());
|
|
shun-iwasawa |
21c135 |
|
|
shun-iwasawa |
21c135 |
if (!raster->getBounds().overlaps(TRect(topLeft, bottomRight)))
|
|
shun-iwasawa |
21c135 |
return TPixel32::Transparent;
|
|
shun-iwasawa |
21c135 |
|
|
shun-iwasawa |
21c135 |
topLeft.x = std::max(0, topLeft.x);
|
|
shun-iwasawa |
21c135 |
topLeft.y = std::max(0, topLeft.y);
|
|
shun-iwasawa |
21c135 |
bottomRight.x = std::min(raster->getLx(), bottomRight.x);
|
|
shun-iwasawa |
21c135 |
bottomRight.y = std::min(raster->getLy(), bottomRight.y);
|
|
shun-iwasawa |
21c135 |
|
|
shun-iwasawa |
21c135 |
TRaster32P raster32 = raster;
|
|
shun-iwasawa |
21c135 |
assert(raster32);
|
|
shun-iwasawa |
21c135 |
if (raster32) {
|
|
shun-iwasawa |
21c135 |
UINT r = 0, g = 0, b = 0, m = 0, size = 0;
|
|
shun-iwasawa |
21c135 |
for (int y = topLeft.y; y < bottomRight.y; y++) {
|
|
shun-iwasawa |
21c135 |
TPixel32 *p = &raster32->pixels(y)[topLeft.x];
|
|
shun-iwasawa |
21c135 |
for (int x = topLeft.x; x < bottomRight.x; x++, p++) {
|
|
shun-iwasawa |
21c135 |
r += p->r;
|
|
shun-iwasawa |
21c135 |
g += p->g;
|
|
shun-iwasawa |
21c135 |
b += p->b;
|
|
shun-iwasawa |
21c135 |
m += p->m;
|
|
shun-iwasawa |
21c135 |
size++;
|
|
shun-iwasawa |
21c135 |
}
|
|
shun-iwasawa |
21c135 |
}
|
|
shun-iwasawa |
21c135 |
|
|
shun-iwasawa |
21c135 |
if (size)
|
|
shun-iwasawa |
21c135 |
return TPixel32(r / size, g / size, b / size, m / size);
|
|
shun-iwasawa |
21c135 |
else
|
|
shun-iwasawa |
21c135 |
return TPixel32::Transparent;
|
|
shun-iwasawa |
21c135 |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
return TPixel32::Transparent;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
shun-iwasawa |
d5045c |
TPixel64 StylePicker::pickAverageColor16(const TRectD &rect) const {
|
|
shun-iwasawa |
d5045c |
TRasterImageP ri = m_image;
|
|
shun-iwasawa |
d5045c |
assert(ri);
|
|
shun-iwasawa |
481b59 |
if (!!ri) {
|
|
shun-iwasawa |
481b59 |
TRasterP raster;
|
|
shun-iwasawa |
481b59 |
raster = ri->getRaster();
|
|
shun-iwasawa |
481b59 |
|
|
shun-iwasawa |
481b59 |
TPoint topLeft = getRasterPoint(rect.getP00());
|
|
shun-iwasawa |
481b59 |
TPoint bottomRight = getRasterPoint(rect.getP11());
|
|
shun-iwasawa |
481b59 |
|
|
shun-iwasawa |
481b59 |
if (!raster->getBounds().overlaps(TRect(topLeft, bottomRight)))
|
|
shun-iwasawa |
481b59 |
return TPixel64::Transparent;
|
|
shun-iwasawa |
481b59 |
|
|
shun-iwasawa |
481b59 |
topLeft.x = std::max(0, topLeft.x);
|
|
shun-iwasawa |
481b59 |
topLeft.y = std::max(0, topLeft.y);
|
|
shun-iwasawa |
481b59 |
bottomRight.x = std::min(raster->getLx(), bottomRight.x);
|
|
shun-iwasawa |
481b59 |
bottomRight.y = std::min(raster->getLy(), bottomRight.y);
|
|
shun-iwasawa |
481b59 |
|
|
shun-iwasawa |
481b59 |
TRaster64P raster64 = raster;
|
|
shun-iwasawa |
481b59 |
assert(raster64);
|
|
shun-iwasawa |
481b59 |
if (raster64) {
|
|
shun-iwasawa |
481b59 |
UINT r = 0, g = 0, b = 0, m = 0, size = 0;
|
|
shun-iwasawa |
481b59 |
for (int y = topLeft.y; y < bottomRight.y; y++) {
|
|
shun-iwasawa |
481b59 |
TPixel64 *p = &raster64->pixels(y)[topLeft.x];
|
|
shun-iwasawa |
481b59 |
for (int x = topLeft.x; x < bottomRight.x; x++, p++) {
|
|
shun-iwasawa |
481b59 |
r += p->r;
|
|
shun-iwasawa |
481b59 |
g += p->g;
|
|
shun-iwasawa |
481b59 |
b += p->b;
|
|
shun-iwasawa |
481b59 |
m += p->m;
|
|
shun-iwasawa |
481b59 |
size++;
|
|
shun-iwasawa |
481b59 |
}
|
|
shun-iwasawa |
481b59 |
}
|
|
shun-iwasawa |
481b59 |
|
|
shun-iwasawa |
481b59 |
if (size)
|
|
shun-iwasawa |
481b59 |
return TPixel64(r / size, g / size, b / size, m / size);
|
|
shun-iwasawa |
481b59 |
else
|
|
shun-iwasawa |
481b59 |
return TPixel64::Transparent;
|
|
shun-iwasawa |
481b59 |
}
|
|
shun-iwasawa |
481b59 |
}
|
|
shun-iwasawa |
481b59 |
return TPixel64::Transparent;
|
|
shun-iwasawa |
481b59 |
}
|
|
shun-iwasawa |
481b59 |
|
|
shun-iwasawa |
481b59 |
//---------------------------------------------------------
|
|
shun-iwasawa |
481b59 |
|
|
shun-iwasawa |
481b59 |
TPixelF StylePicker::pickAverageColor32F(const TRectD &rect) const {
|
|
shun-iwasawa |
481b59 |
TRasterImageP ri = m_image;
|
|
shun-iwasawa |
481b59 |
assert(ri);
|
|
shun-iwasawa |
481b59 |
if (!ri) return TPixelF::Transparent;
|
|
shun-iwasawa |
481b59 |
TRasterFP raster = ri->getRaster();
|
|
shun-iwasawa |
481b59 |
if (!raster) return TPixelF::Transparent;
|
|
shun-iwasawa |
d5045c |
|
|
shun-iwasawa |
d5045c |
TPoint topLeft = getRasterPoint(rect.getP00());
|
|
shun-iwasawa |
d5045c |
TPoint bottomRight = getRasterPoint(rect.getP11());
|
|
shun-iwasawa |
d5045c |
|
|
shun-iwasawa |
d5045c |
if (!raster->getBounds().overlaps(TRect(topLeft, bottomRight)))
|
|
shun-iwasawa |
481b59 |
return TPixelF::Transparent;
|
|
shun-iwasawa |
d5045c |
|
|
shun-iwasawa |
d5045c |
topLeft.x = std::max(0, topLeft.x);
|
|
shun-iwasawa |
d5045c |
topLeft.y = std::max(0, topLeft.y);
|
|
shun-iwasawa |
d5045c |
bottomRight.x = std::min(raster->getLx(), bottomRight.x);
|
|
shun-iwasawa |
d5045c |
bottomRight.y = std::min(raster->getLy(), bottomRight.y);
|
|
shun-iwasawa |
d5045c |
|
|
shun-iwasawa |
481b59 |
float r = 0, g = 0, b = 0, m = 0, size = 0;
|
|
shun-iwasawa |
d5045c |
for (int y = topLeft.y; y < bottomRight.y; y++) {
|
|
shun-iwasawa |
481b59 |
TPixelF *p = &raster->pixels(y)[topLeft.x];
|
|
shun-iwasawa |
d5045c |
for (int x = topLeft.x; x < bottomRight.x; x++, p++) {
|
|
shun-iwasawa |
d5045c |
r += p->r;
|
|
shun-iwasawa |
d5045c |
g += p->g;
|
|
shun-iwasawa |
d5045c |
b += p->b;
|
|
shun-iwasawa |
d5045c |
m += p->m;
|
|
shun-iwasawa |
d5045c |
size++;
|
|
shun-iwasawa |
d5045c |
}
|
|
shun-iwasawa |
d5045c |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
shun-iwasawa |
d5045c |
if (size)
|
|
shun-iwasawa |
481b59 |
return TPixelF(r / size, g / size, b / size, m / size);
|
|
shun-iwasawa |
d5045c |
else
|
|
shun-iwasawa |
481b59 |
return TPixelF::Transparent;
|
|
shun-iwasawa |
d5045c |
}
|
|
shun-iwasawa |
d5045c |
|
|
shun-iwasawa |
d5045c |
//---------------------------------------------------------
|
|
shun-iwasawa |
d5045c |
|
|
shun-iwasawa |
d5045c |
namespace {
|
|
Shinya Kitaoka |
120a6e |
TPixel32 getAverageColor(const TRect &rect) {
|
|
Shinya Kitaoka |
120a6e |
GLenum fmt =
|
|
Campbell Barton |
d869b5 |
#if defined(TNZ_MACHINE_CHANNEL_ORDER_BGRM)
|
|
Shinya Kitaoka |
120a6e |
GL_RGBA;
|
|
Campbell Barton |
d869b5 |
#elif defined(TNZ_MACHINE_CHANNEL_ORDER_MBGR)
|
|
Shinya Kitaoka |
120a6e |
GL_ABGR_EXT;
|
|
Campbell Barton |
d869b5 |
#elif defined(TNZ_MACHINE_CHANNEL_ORDER_RGBM)
|
|
Shinya Kitaoka |
120a6e |
GL_RGBA;
|
|
Campbell Barton |
d869b5 |
#elif defined(TNZ_MACHINE_CHANNEL_ORDER_MRGB)
|
|
Shinya Kitaoka |
120a6e |
GL_BGRA;
|
|
Toshihiro Shimizu |
890ddd |
#else
|
|
Toshihiro Shimizu |
890ddd |
// Error PLATFORM NOT SUPPORTED
|
|
Shinya Kitaoka |
120a6e |
#error "unknown channel order!"
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Shinya Kitaoka |
120a6e |
UINT r = 0, g = 0, b = 0, m = 0;
|
|
Shinya Kitaoka |
120a6e |
std::vector<tpixel32> buffer(rect.getLx() * rect.getLy());</tpixel32>
|
|
shun-iwasawa |
d5045c |
glReadPixels(rect.x0, rect.y0, rect.getLx(), rect.getLy(), fmt, TGL_TYPE,
|
|
shun-iwasawa |
d5045c |
&buffer[0]);
|
|
Shinya Kitaoka |
120a6e |
int size = rect.getLx() * rect.getLy();
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < size; i++) {
|
|
Shinya Kitaoka |
120a6e |
r += buffer[i].r;
|
|
Shinya Kitaoka |
120a6e |
g += buffer[i].g;
|
|
Shinya Kitaoka |
120a6e |
b += buffer[i].b;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
shun-iwasawa |
d5045c |
return TPixel32(b / size, g / size, r / size, TPixel32::maxChannelValue);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TPixel32 getAverageColor(TStroke *stroke) {
|
|
Shinya Kitaoka |
120a6e |
GLenum fmt =
|
|
Campbell Barton |
d869b5 |
#if defined(TNZ_MACHINE_CHANNEL_ORDER_BGRM)
|
|
Shinya Kitaoka |
120a6e |
GL_RGBA;
|
|
Campbell Barton |
d869b5 |
#elif defined(TNZ_MACHINE_CHANNEL_ORDER_MBGR)
|
|
Shinya Kitaoka |
120a6e |
GL_ABGR_EXT;
|
|
Campbell Barton |
d869b5 |
#elif defined(TNZ_MACHINE_CHANNEL_ORDER_RGBM)
|
|
Shinya Kitaoka |
120a6e |
GL_RGBA;
|
|
Campbell Barton |
d869b5 |
#elif defined(TNZ_MACHINE_CHANNEL_ORDER_MRGB)
|
|
Shinya Kitaoka |
120a6e |
GL_BGRA;
|
|
Toshihiro Shimizu |
890ddd |
#else
|
|
Toshihiro Shimizu |
890ddd |
// Error PLATFORM NOT SUPPORTED
|
|
Shinya Kitaoka |
120a6e |
#error "unknown channel order"
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// leggo il buffer e mi prendo i pixels
|
|
Shinya Kitaoka |
120a6e |
UINT r = 0, g = 0, b = 0, m = 0;
|
|
Shinya Kitaoka |
120a6e |
TRect rect = convert(stroke->getBBox());
|
|
Shinya Kitaoka |
120a6e |
std::vector<tpixel32> buffer(rect.getLx() * rect.getLy());</tpixel32>
|
|
Shinya Kitaoka |
120a6e |
glReadPixels(rect.x0, rect.y0, rect.getLx(), rect.getLy(), fmt,
|
|
Shinya Kitaoka |
120a6e |
GL_UNSIGNED_BYTE, &buffer[0]);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// calcolo le regioni dello stroke
|
|
Shinya Kitaoka |
120a6e |
TVectorImage aux;
|
|
Shinya Kitaoka |
120a6e |
aux.addStroke(stroke);
|
|
Shinya Kitaoka |
120a6e |
aux.transform(TTranslation(convert(-rect.getP00())));
|
|
Shinya Kitaoka |
120a6e |
aux.findRegions();
|
|
Shinya Kitaoka |
120a6e |
int regionCount = aux.getRegionCount();
|
|
Shinya Kitaoka |
120a6e |
int size = 0, lx = rect.getLx();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (int j = 0; j < regionCount; j++) {
|
|
Shinya Kitaoka |
120a6e |
TRegion *reg = aux.getRegion(j);
|
|
Shinya Kitaoka |
120a6e |
TRect regRect = convert(reg->getBBox());
|
|
Shinya Kitaoka |
120a6e |
for (int y = regRect.y0; y < regRect.y1; y++) {
|
|
Shinya Kitaoka |
120a6e |
std::vector<double> intersections;</double>
|
|
Shinya Kitaoka |
120a6e |
reg->computeScanlineIntersections(y, intersections);
|
|
Shinya Kitaoka |
120a6e |
assert(!(intersections.size() & 0x1));
|
|
Shinya Kitaoka |
120a6e |
for (UINT i = 0; i < intersections.size(); i += 2) {
|
|
Shinya Kitaoka |
120a6e |
if (intersections[i] == intersections[i + 1]) continue;
|
|
Shinya Kitaoka |
120a6e |
int firstInters = (int)intersections[i];
|
|
Shinya Kitaoka |
120a6e |
int secondInters = (int)intersections[i + 1];
|
|
Shinya Kitaoka |
120a6e |
for (int x = firstInters + 1; x < secondInters - 1; x++) {
|
|
Shinya Kitaoka |
120a6e |
r += buffer[y * lx + x].r;
|
|
Shinya Kitaoka |
120a6e |
g += buffer[y * lx + x].g;
|
|
Shinya Kitaoka |
120a6e |
b += buffer[y * lx + x].b;
|
|
Shinya Kitaoka |
120a6e |
size++;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (size != 0)
|
|
Shinya Kitaoka |
120a6e |
return TPixel32(b / size, g / size, r / size, 255);
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
return TPixel32(buffer[0].b, buffer[0].g, buffer[0].r, 255);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
shun-iwasawa |
21c135 |
} // namespace
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TPixel32 StylePicker::pickColor(const TRectD &area) const {
|
|
Shinya Kitaoka |
120a6e |
// TRectD rect=area.enlarge(-1,-1);
|
|
Shinya Kitaoka |
120a6e |
return getAverageColor(convert(area));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TPixel32 StylePicker::pickColor(TStroke *stroke) const {
|
|
Shinya Kitaoka |
120a6e |
return getAverageColor(stroke);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|