void inkFill(const TRasterCM32P &r, const TPoint &pin, int ink, int searchRay, TTileSaverCM32 *saver, TRect *insideRect) { r->lock(); TPixelCM32 *pixels = (TPixelCM32 *)r->getRawData(); int oldInk; TPoint p = pin; if ((pixels + p.y * r->getWrap() + p.x)->isPurePaint() && (searchRay == 0 || (p = nearestInk(r, p, searchRay)) == TPoint(-1, -1))) { r->unlock(); return; } TPixelCM32 *pix = pixels + (p.y * r->getWrap() + p.x); if (pix->getInk() == ink) { r->unlock(); return; } oldInk = pix->getInk(); std::stack<TPoint> seeds; seeds.push(p); while (!seeds.empty()) { p = seeds.top(); seeds.pop(); if (!r->getBounds().contains(p)) continue; if (insideRect && !insideRect->contains(p)) continue; TPixelCM32 *pix = pixels + (p.y * r->getWrap() + p.x); if (pix->isPurePaint() || pix->getInk() != oldInk) continue; if (saver) saver->save(p); pix->setInk(ink); seeds.push(TPoint(p.x - 1, p.y - 1)); seeds.push(TPoint(p.x - 1, p.y)); seeds.push(TPoint(p.x - 1, p.y + 1)); seeds.push(TPoint(p.x, p.y - 1)); seeds.push(TPoint(p.x, p.y + 1)); seeds.push(TPoint(p.x + 1, p.y - 1)); seeds.push(TPoint(p.x + 1, p.y)); seeds.push(TPoint(p.x + 1, p.y + 1)); } r->unlock(); }
void InkSegmenter::drawSegment( const TPoint &p0, const TPoint &p1, int ink, /*vector<pair<TPixelCM32*, int> >& oldInks,*/ TTileSaverCM32 *saver) { int x, y, dx, dy, d, incr_1, incr_2; int x1 = p0.x; int y1 = p0.y; int x2 = p1.x; int y2 = p1.y; if (x1 > x2) { tswap(x1, x2); tswap(y1, y2); } TPixelCM32 *buf = m_r->pixels() + y1 * m_wrap + x1; /*if (buf->getInk()!=damInk) oldInks.push_back(pair<TPixelCM32*, int>(buf, buf->getInk())); if ((m_r->pixels() + y2*m_wrap + x2)->getInk()!=damInk) oldInks.push_back(pair<TPixelCM32*, int>(m_r->pixels() + y2*m_wrap + x2, (m_r->pixels() + y2*m_wrap + x2)->getInk()));*/ if (saver) { saver->save(p0); saver->save(p1); } buf->setInk(ink); (m_r->pixels() + y2 * m_wrap + x2)->setInk(ink); dx = x2 - x1; dy = y2 - y1; x = y = 0; if (dy >= 0) { if (dy <= dx) DRAW_SEGMENT(x, y, dx, dy, (buf++), (buf += m_wrap + 1), SET_INK) else DRAW_SEGMENT(y, x, dy, dx, (buf += m_wrap), (buf += m_wrap + 1), SET_INK) } else {
void AreaFiller::rectFill(const TRect &rect, int color, bool onlyUnfilled, bool fillPaints, bool fillInks) { // Viene trattato il caso fillInks /*- FillInkのみの場合 -*/ if (!fillPaints) { assert(fillInks); assert(m_ras->getBounds().contains(rect)); for (int y = rect.y0; y <= rect.y1; y++) { TPixelCM32 *pix = m_ras->pixels(y) + rect.x0; for (int x = rect.x0; x <= rect.x1; x++, pix++) pix->setInk(color); } return; } TRect r = m_bounds * rect; int dx = r.x1 - r.x0; int dy = (r.y1 - r.y0) * m_wrap; if (dx < 2 || dy < 2) // rect degenere(area contenuta nulla), skippo. return; std::vector<int> frameSeed(2 * (r.getLx() + r.getLy() - 2)); int x, y, count1, count2; /*- ptrをRect範囲のスタート地点に移動 -*/ Pixel *ptr = m_pixels + r.y0 * m_wrap + r.x0; count1 = 0; count2 = r.y1 - r.y0 + 1; // Se il rettangolo non contiene il bordo del raster e se tutti i pixels // contenuti nel rettangolo sono pure paint non deve fare nulla! if (!rect.contains(m_bounds) && areRectPixelsPurePaint(m_pixels, r, m_wrap)) return; // Viene riempito frameSeed con tutti i paint delle varie aree del rettangolo // di contorno. // Viene verificato se i pixels del rettangolo sono tutti pure paint. /*- 輪郭のPaintのIDをframeseed内に格納 -*/ for (y = r.y0; y <= r.y1; y++, ptr += m_wrap, count1++, count2++) { if (r.x0 > 0) frameSeed[count1] = ptr->getPaint(); if (r.x1 < m_ras->getLx() - 1) frameSeed[count2] = (ptr + dx)->getPaint(); } ptr = m_pixels + r.y0 * m_wrap + r.x0 + 1; count1 = count2; count2 = count1 + r.x1 - r.x0 - 1; for (x = r.x0 + 1; x < r.x1; x++, ptr++, count1++, count2++) { if (r.y0 > 0) frameSeed[count1] = ptr->getPaint(); if (r.y1 < m_ras->getLy() - 1) frameSeed[count2] = (ptr + dy)->getPaint(); } assert(count2 == 2 * (r.getLx() + r.getLy() - 2)); // Viene fillato l'interno e il bordo del rettangolo rect con color Pixel *pix = m_pixels + r.y0 * m_wrap + r.x0; if (onlyUnfilled) for (y = r.y0; y <= r.y1; y++, pix += m_wrap - dx - 1) { for (x = r.x0; x <= r.x1; x++, pix++) { if (pix->getPaint() == 0) // BackgroundStyle pix->setPaint(color); if (fillInks) pix->setInk(color); } } else for (y = r.y0; y <= r.y1; y++, pix += m_wrap - dx - 1) { for (x = r.x0; x <= r.x1; x++, pix++) { pix->setPaint(color); if (fillInks) pix->setInk(color); } } // Vengono fillati i pixel del rettangolo con i paint (mantenuti in frameSeed) // che // c'erano prima di fillare l'intero rettangolo, in questo modo si riportano // al colore originale le aree che non sono chiuse e non dovevano essere // fillate. count1 = 0; FillParameters params; // in order to make the paint to protlude behind the line params.m_prevailing = false; if (r.x0 > 0) for (y = r.y0; y <= r.y1; y++) { params.m_p = TPoint(r.x0, y); params.m_styleId = frameSeed[count1++]; fill(m_ras, params); } else count1 += r.y1 - r.y0 + 1; if (r.x1 < m_ras->getLx() - 1) for (y = r.y0; y <= r.y1; y++) { params.m_p = TPoint(r.x1, y); params.m_styleId = frameSeed[count1++]; fill(m_ras, params); } else count1 += r.y1 - r.y0 + 1; if (r.y0 > 0) for (x = r.x0 + 1; x < r.x1; x++) { params.m_p = TPoint(x, r.y0); params.m_styleId = frameSeed[count1++]; fill(m_ras, params); } else count1 += r.x1 - r.x0 - 1; if (r.y1 < m_ras->getLy() - 1) for (x = r.x0 + 1; x < r.x1; x++) { params.m_p = TPoint(x, r.y1); params.m_styleId = frameSeed[count1++]; fill(m_ras, params); } }