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
//---------------------------------------------------------