Esempio n. 1
0
/*-- (StylePickerTool内で)LineとAreaを切り替えてPickできる。mode: 0=Area, 1=Line, 2=Line&Areas(default)  --*/
int StylePicker::pickStyleId(const TPointD &pos, double radius2, int mode) const
{
	int styleId = 0;
	if (TToonzImageP ti = m_image) {
		TRasterCM32P ras = ti->getRaster();
		TPoint point = getRasterPoint(pos);
		if (!ras->getBounds().contains(point))
			return -1;
		TPixelCM32 col = ras->pixels(point.y)[point.x];

		switch (mode) {
		case 0: //AREAS
			styleId = col.getPaint();
			break;
		case 1: //LINES
			styleId = col.getInk();
			break;
		case 2: //ALL (Line & Area)
		default:
			styleId = col.isPurePaint() ? col.getPaint() : col.getInk();
			break;
		}
	} else if (TRasterImageP ri = m_image) {
		const TPalette *palette = m_palette.getPointer();
		if (!palette)
			return -1;
		TRaster32P ras = ri->getRaster();
		if (!ras)
			return -1;
		TPoint point = getRasterPoint(pos);
		if (!ras->getBounds().contains(point))
			return -1;
		TPixel32 col = ras->pixels(point.y)[point.x];
		styleId = palette->getClosestStyle(col);
	} else if (TVectorImageP vi = m_image) {
		// prima cerca lo stile della regione piu' vicina
		TRegion *r = vi->getRegion(pos);
		if (r)
			styleId = r->getStyle();
		// poi cerca quello della stroke, ma se prima aveva trovato una regione, richiede che
		// il click sia proprio sopra la stroke, altrimenti cerca la stroke piu' vicina (max circa 10 pixel)
		const double maxDist2 = (styleId == 0) ? 100.0 * radius2 : 0;
		bool strokeFound;
		double dist2, w, thick;
		UINT index;
		//!funzionerebbe ancora meglio con un getNearestStroke che considera
		//la thickness, cioe' la min distance dalla outline e non dalla centerLine
		strokeFound = vi->getNearestStroke(pos, w, index, dist2);
		if (strokeFound) {
			TStroke *stroke = vi->getStroke(index);
			thick = stroke->getThickPoint(w).thick;
			if (dist2 - thick * thick < maxDist2) {
				assert(stroke);
				styleId = stroke->getStyle();
			}
		}
	}
	return styleId;
}
Esempio n. 2
0
FullColorAreaFiller::FullColorAreaFiller(const TRaster32P &ras)
    : m_ras(ras)
    , m_bounds(ras->getBounds())
    , m_pixels(ras->pixels())
    , m_wrap(ras->getWrap())
    , m_color(0) {
  m_ras->lock();
}
Esempio n. 3
0
TImageP ImageFiller::build(int imFlags, void *extData)
{
	assert(imFlags == ImageManager::none);

	// Fetch image
	assert(extData);

	ImageLoader::BuildExtData *data = (ImageLoader::BuildExtData *)extData;
	assert(data->m_subs == 0);

	const std::string &srcImgId = data->m_sl->getImageId(data->m_fid);

	TImageP img = ImageManager::instance()->getImage(srcImgId, imFlags, extData);
	if (img) {
		TRasterImageP ri = img;
		if (ri) {
			TRaster32P ras = ri->getRaster();
			if (ras) {
				TRaster32P newRas = ras->clone();
				FullColorAreaFiller filler(newRas);

				TPaletteP palette = new TPalette();
				int styleId = palette->getPage(0)->addStyle(TPixel32::White);

				FillParameters params;
				params.m_palette = palette.getPointer();
				params.m_styleId = styleId;
				params.m_minFillDepth = 0;
				params.m_maxFillDepth = 15;
				filler.rectFill(newRas->getBounds(), params, false);

				TRasterImageP ri = TRasterImageP(newRas);
				return ri;
			}
		}
	}

	// Error case: return a dummy image (is it really required?)

	TRaster32P ras(10, 10);
	ras->fill(TPixel32(127, 0, 127, 127));

	return TRasterImageP(ras);
}
Esempio n. 4
0
void fill(const TRaster32P &ras, const TRaster32P &ref,
          const FillParameters &params, TTileSaverFullColor *saver) {
  TPixel32 *pix, *limit, *pix0, *oldpix;
  int oldy, xa, xb, xc, xd, dy;
  int oldxc, oldxd;
  int matte, oldMatte;
  int x = params.m_p.x, y = params.m_p.y;
  TRaster32P workRas = ref ? ref : ras;

  TRect bbbox = workRas->getBounds();

  if (!bbbox.contains(params.m_p)) return;

  TPaletteP plt  = params.m_palette;
  TPixel32 color = plt->getStyle(params.m_styleId)->getMainColor();
  int fillDepth =
      params.m_shiftFill ? params.m_maxFillDepth : params.m_minFillDepth;

  assert(fillDepth >= 0 && fillDepth < 16);
  fillDepth = ((15 - fillDepth) << 4) | (15 - fillDepth);

  // looking for any  pure transparent pixel along the border; if after filling
  // that pixel will be changed,
  // it means that I filled the bg and the savebox needs to be recomputed!
  TPixel32 borderIndex;
  TPixel32 *borderPix = 0;
  pix                 = workRas->pixels(0);
  int i;
  for (i = 0; i < workRas->getLx(); i++, pix++)  // border down
    if (pix->m == 0) {
      borderIndex = *pix;
      borderPix   = pix;
      break;
    }
  if (borderPix == 0)  // not found in border down...try border up (avoid left
                       // and right borders...so unlikely)
  {
    pix = workRas->pixels(workRas->getLy() - 1);
    for (i = 0; i < workRas->getLx(); i++, pix++)  // border up
      if (pix->m == 0) {
        borderIndex = *pix;
        borderPix   = pix;
        break;
      }
  }

  std::stack<FillSeed> seeds;
  std::map<int, std::vector<std::pair<int, int>>> segments;

  // fillRow(r, params.m_p, xa, xb, color ,saver);
  findSegment(workRas, params.m_p, xa, xb, color);
  segments[y].push_back(std::pair<int, int>(xa, xb));
  seeds.push(FillSeed(xa, xb, y, 1));
  seeds.push(FillSeed(xa, xb, y, -1));

  while (!seeds.empty()) {
    FillSeed fs = seeds.top();
    seeds.pop();

    xa   = fs.m_xa;
    xb   = fs.m_xb;
    oldy = fs.m_y;
    dy   = fs.m_dy;
    y    = oldy + dy;
    if (y > bbbox.y1 || y < bbbox.y0) continue;
    pix = pix0 = workRas->pixels(y) + xa;
    limit      = workRas->pixels(y) + xb;
    oldpix     = workRas->pixels(oldy) + xa;
    x          = xa;
    oldxd      = (std::numeric_limits<int>::min)();
    oldxc      = (std::numeric_limits<int>::max)();
    while (pix <= limit) {
      oldMatte  = threshMatte(oldpix->m, fillDepth);
      matte     = threshMatte(pix->m, fillDepth);
      bool test = false;
      if (segments.find(y) != segments.end())
        test = isPixelInSegment(segments[y], x);
      if (*pix != color && !test && matte >= oldMatte && matte != 255) {
        findSegment(workRas, TPoint(x, y), xc, xd, color);
        // segments[y].push_back(std::pair<int,int>(xc, xd));
        insertSegment(segments[y], std::pair<int, int>(xc, xd));
        if (xc < xa) seeds.push(FillSeed(xc, xa - 1, y, -dy));
        if (xd > xb) seeds.push(FillSeed(xb + 1, xd, y, -dy));
        if (oldxd >= xc - 1)
          oldxd = xd;
        else {
          if (oldxd >= 0) seeds.push(FillSeed(oldxc, oldxd, y, dy));
          oldxc = xc;
          oldxd = xd;
        }
        pix += xd - x + 1;
        oldpix += xd - x + 1;
        x += xd - x + 1;
      } else {
        pix++;
        oldpix++, x++;
      }
    }
    if (oldxd > 0) seeds.push(FillSeed(oldxc, oldxd, y, dy));
  }

  std::map<int, std::vector<std::pair<int, int>>>::iterator it;
  for (it = segments.begin(); it != segments.end(); it++) {
    TPixel32 *line    = ras->pixels(it->first);
    TPixel32 *refLine = 0;
    TPixel32 *refPix;
    if (ref) refLine = ref->pixels(it->first);
    std::vector<std::pair<int, int>> segmentVector = it->second;
    for (int i = 0; i < (int)segmentVector.size(); i++) {
      std::pair<int, int> segment = segmentVector[i];
      if (segment.second >= segment.first) {
        pix             = line + segment.first;
        if (ref) refPix = refLine + segment.first;
        int n;
        for (n = 0; n < segment.second - segment.first + 1; n++, pix++) {
          if (ref) {
            *pix = *refPix;
            refPix++;
          } else
            *pix = pix->m == 0 ? color : overPix(color, *pix);
        }
      }
    }
  }
}
Esempio n. 5
0
GLuint MeshTexturizer::Imp::textureAlloc(const TRaster32P &ras, const TRaster32P &aux,
										 int x, int y, int textureLx, int textureLy,
										 bool premultiplied)
{
	struct locals {
		static void clearMatte(const TRaster32P &ras, int xBegin, int yBegin, int xEnd, int yEnd)
		{
			for (int y = yBegin; y != yEnd; ++y) {
				TPixel32 *line = ras->pixels(y), *pixEnd = line + xEnd;

				for (TPixel32 *pix = line + xBegin; pix != pixEnd; ++pix)
					pix->m = 0;
			}
		}

		static void clearMatte_border(const TRaster32P &ras, int border0, int border1)
		{
			assert(border0 < border1);

			// Horizontal
			clearMatte(ras, border0, border0, ras->getLx() - border0, border1);
			clearMatte(ras, border0, ras->getLy() - border1, ras->getLx() - border0, ras->getLy() - border0);

			// Vertical
			clearMatte(ras, border0, border1, border1, ras->getLy() - border1);
			clearMatte(ras, ras->getLx() - border1, border1, ras->getLx() - border0, ras->getLy() - border1);
		}
	}; // locals

	// Prepare the texture tile
	assert(aux->getLx() >= textureLx + TOTAL_BORDER_2 && aux->getLy() >= textureLy + TOTAL_BORDER_2);

	TRect rasRect(x, y, x + textureLx - 1, y + textureLy - 1);
	rasRect = rasRect.enlarge(premultiplied ? COPIED_BORDER : COPIED_BORDER + NONPREM_BORDER);
	rasRect = rasRect * ras->getBounds();

	TRect auxRect(rasRect - TPoint(x - TOTAL_BORDER, y - TOTAL_BORDER));

	// An auxiliary raster must be used to supply the transparent border
	TRaster32P tex(aux->extract(0, 0, textureLx + TOTAL_BORDER_2 - 1, textureLy + TOTAL_BORDER_2 - 1));
	tex->clear();
	aux->extract(auxRect)->copy(ras->extract(rasRect));

	if (!premultiplied && NONPREM_BORDER > 0)
		locals::clearMatte_border(aux, TRANSP_BORDER - NONPREM_BORDER, TRANSP_BORDER);

	// Pass the raster into VRAM
	GLuint texId;
	glGenTextures(1, &texId);
	glBindTexture(GL_TEXTURE_2D, texId);

	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);	  // These must be used on a bound texture,
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);	  // and are remembered in the OpenGL context.
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // They can be set here, no need for
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // the user to do it.

	glPixelStorei(GL_UNPACK_ROW_LENGTH, tex->getWrap());
	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

	glTexImage2D(GL_TEXTURE_2D,
				 0,				   // one level only
				 GL_RGBA,		   // pixel channels count
				 tex->getLx(),	 // width
				 tex->getLy(),	 // height
				 0,				   // border size
				 TGL_FMT,		   // pixel format
				 GL_UNSIGNED_BYTE, // pixel data type
				 (GLvoid *)tex->getRawData());

	return texId;
}