/*-- (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;
}
//-----------------------------------------------------------------------------
// questa funzione viene chiamata dopo il fill rect delle aree, e colora gli
// inchiostri di tipo "autoink"
// che confinano con le aree appena fillate con il rect. rbefore e' il rect del
// raster prima del rectfill.
void fillautoInks(TRasterCM32P &rin, TRect &rect, const TRasterCM32P &rbefore,
                  TPalette *plt) {
  assert(plt);
  TRasterCM32P r = rin->extract(rect);
  assert(r->getSize() == rbefore->getSize());
  int i, j;

  for (i = 0; i < r->getLy(); i++) {
    TPixelCM32 *pix  = r->pixels(i);
    TPixelCM32 *pixb = rbefore->pixels(i);
    for (j = 0; j < r->getLx(); j++, pix++, pixb++) {
      int paint = pix->getPaint();
      int tone  = pix->getTone();
      int ink   = pix->getInk();
      if (paint != pixb->getPaint() && tone > 0 && tone < 255 && ink != paint &&
          plt->getStyle(ink)->getFlags() != 0)
        inkFill(rin, TPoint(j, i) + rect.getP00(), paint, 0, NULL, &rect);
    }
  }
}
Exemple #3
0
void Convert2Tlv::doFill(TRasterCM32P &rout, const TRaster32P &rin)
{
	//prima passata: si filla  solo partendo da pixel senza inchiostro, senza antialiasing(tone==255)
	for (int i = 0; i < rin->getLy(); i++) {
		TPixel *pixin = rin->pixels(i);
		TPixelCM32 *pixout = rout->pixels(i);
		for (int j = 0; j < rin->getLx(); j++, pixin++, pixout++) {
			if (!(pixout->getTone() == 255 && pixout->getPaint() == 0 && pixin->m == 255))
				continue;

			std::map<TPixel, int>::const_iterator it;
			int paintIndex;
			if ((it = m_colorMap.find(*pixin)) == m_colorMap.end()) {
				if (m_colorTolerance > 0)
					it = findNearestColor(*pixin);
				// if (it==colorMap.end() && (int)colorMap.size()>origColorCount) //se non l'ho trovato tra i colori origari, lo cerco in quelli nuovi, ma in questo caso deve essere esattamente uguale(tolerance = 0)
				//	 it  = findNearestColor(*pixin, colorMap, colorTolerance, origColorCount, colorMap.size()-1);

				if (it == m_colorMap.end() && m_lastIndex < 4096) {
					m_colorMap[*pixin] = ++m_lastIndex;
					paintIndex = m_lastIndex;
				} else if (it != m_colorMap.end()) {
					m_colorMap[*pixin] = it->second;
					paintIndex = it->second;
				}
			} else
				paintIndex = it->second;
			FillParameters params;
			params.m_p = TPoint(j, i);
			params.m_styleId = paintIndex;
			params.m_emptyOnly = true;
			fill(rout, params);
			//if (*((ULONG *)rout->getRawData())!=0xff)
			//  {
			//  int cavolo=0;
			//  }
		}
	}

	//seconda passata: se son rimasti pixel antialiasati non fillati, si fillano, cercando nelle vicinanze un pixel di paint puro per capire il colore da usare
	for (int i = 0; i < rin->getLy(); i++) {
		TPixel *pixin = rin->pixels(i);
		TPixelCM32 *pixout = rout->pixels(i);
		for (int j = 0; j < rin->getLx(); j++, pixin++, pixout++) {
			if (!(pixout->getTone() > 0 && pixout->getTone() < 255 && pixout->getPaint() == 0 && pixin->m == 255))
				continue;

			TPoint p = getClosestPurePaint(rout, i, j);
			if (p.x == -1)
				continue;

			//pixout->setPaint( paintIndex);
			FillParameters params;
			params.m_p = TPoint(j, i);
			params.m_styleId = (rout->pixels(p.y) + p.x)->getPaint();
			params.m_emptyOnly = true;

			fill(rout, params);
		}
	}

	//infine, si filla di trasparente lo sfondo, percorrendo il bordo, nel caso di trasbordamenti di colore
	TPixelCM32 *pixCm;
	TPixel *pix;

	pixCm = rout->pixels(0);
	pix = rin->pixels(0);
	FillParameters params;
	params.m_styleId = 0;

	for (int i = 0; i < rout->getLx(); i++, pixCm++, pix++)
		if (pixCm->getTone() == 255 && pixCm->getPaint() != 0 && pix->m == 0) {
			params.m_p = TPoint(i, 0);
			fill(rout, params);
		}

	pixCm = rout->pixels(rout->getLy() - 1);
	pix = rin->pixels(rout->getLy() - 1);
	for (int i = 0; i < rout->getLx(); i++, pixCm++, pix++)
		if (pixCm->getTone() == 255 && pixCm->getPaint() != 0 && pix->m == 0) {
			params.m_p = TPoint(i, rout->getLy() - 1);
			fill(rout, params);
		}
	int wrapCM = rout->getWrap();
	int wrap = rin->getWrap();

	pixCm = rout->pixels(0);
	pix = rin->pixels(0);
	for (int i = 0; i < rin->getLy(); i++, pixCm += wrapCM, pix += wrap)
		if (pixCm->getTone() == 255 && pixCm->getPaint() != 0 && pix->m == 0) {
			params.m_p = TPoint(0, i);
			fill(rout, params);
		}
	pixCm = rout->pixels(0) + rout->getLx() - 1;
	pix = rin->pixels(0) + rin->getLx() - 1;
	for (int i = 0; i < rin->getLy(); i++, pixCm += wrapCM, pix += wrap)
		if (pixCm->getTone() == 255 && pixCm->getPaint() != 0 && pix->m == 0) {
			params.m_p = TPoint(rout->getLx() - 1, i);
			fill(rout, params);
		}
}