void SimpleSurface::applyFilter (Surface *inSrc, const Rect &inRect, ImagePoint inOffset, Filter *inFilter) { if (!mBase) return; FilterList f; f.push_back (inFilter); Rect src_rect (inRect.w, inRect.h); Rect dest = GetFilteredObjectRect (f, src_rect); inSrc->IncRef (); Surface *result = FilterBitmap (f, inSrc, src_rect, dest, false, ImagePoint (inRect.x, inRect.y)); dest.Translate (inOffset.x, inOffset.y); src_rect = Rect (0, 0, result->Width (), result->Height ()); int dx = dest.x; int dy = dest.y; dest = dest.Intersect (Rect (0, 0, mWidth, mHeight)); dest.Translate (-dx, -dy); dest = dest.Intersect (src_rect); dest.Translate (dx, dy); int bpp = BytesPP (); RenderTarget t = BeginRender (dest, false); //printf("Copy back @ %d,%d %dx%d + (%d,%d)\n", dest.x, dest.y, t.Width(), t.Height(), dx, dy); for (int y = 0; y < t.Height (); y++) memcpy ((void *)(t.Row (y + dest.y) + ((dest.x) * bpp)), result->Row (y - dy) - (dx * bpp), dest.w * bpp); EndRender (); result->DecRef (); }
static bool parse_filter(const string &filter, FilterList &pkg_filters, ObjFilterList &obj_filters, StrFilterList &str_filters) { // -fname=foo exact // -fname:foo glob // -fname/foo/ regex // -fname/foo/i iregex // the manpage calls REG_BASIC "obsolete" so we default to extended bool neg = false; size_t at = 0; while (filter.length() > at && filter[at] == '!') { neg = !neg; ++at; } if (filter.compare(at, string::npos, "broken") == 0) { auto pf = filter::PackageFilter::broken(neg); if (!pf) return false; pkg_filters.push_back(move(pf)); return true; } #ifdef PKGDEPDB_ENABLE_REGEX string regex; bool icase = false; auto parse_regex = [&]() -> bool { if (static_cast<unsigned char>(filter[at] - 'a') > ('z'-'a') && static_cast<unsigned char>(filter[at] - 'A') > ('Z'-'A') && static_cast<unsigned char>(filter[at] - '0') > ('9'-'0')) { // parse the regex enclosed using the character from filter[4] char unquote = filter[at]; if (unquote == '(') unquote = ')'; else if (unquote == '{') unquote = '}'; else if (unquote == '[') unquote = ']'; else if (unquote == '<') unquote = '>'; if (filter.length() < at+2) { fprintf(stderr, "empty filter content: %s\n", filter.c_str()); return false; } regex = filter.substr(at+1); icase = false; if (regex[regex.length()-1] == 'i') { if (regex[regex.length()-2] == unquote) { icase = true; regex.erase(regex.length()-2); } } else if (regex[regex.length()-1] == unquote) regex.pop_back(); return true; } return false; }; #endif auto parsematch = [&]() -> rptr<filter::Match> { if (filter[at] == '=') return filter::Match::CreateExact(move(filter.substr(at+1))); else if (filter[at] == ':') return filter::Match::CreateGlob(move(filter.substr(at+1))); #ifdef PKGDEPDB_ENABLE_REGEX else if (parse_regex()) return filter::Match::CreateRegex(move(regex), icase); #endif return nullptr; }; #define ADDFILTER2(TYPE, NAME, FUNC, DEST) do { \ if (filter.compare(at, sizeof(#NAME)-1, #NAME) == 0) { \ at += sizeof(#NAME)-1; \ auto match = parsematch(); \ if (!match) \ return false; \ DEST.push_back(move(filter::TYPE::FUNC(move(match), neg))); \ return true; \ } } while(0) #define ADDFILTER(TYPE, NAME, DEST) ADDFILTER2(TYPE, NAME, NAME, DEST) #define MAKE_PKGFILTER(NAME) ADDFILTER(PackageFilter, NAME, pkg_filters) MAKE_PKGFILTER(name); MAKE_PKGFILTER(group); MAKE_PKGFILTER(depends); MAKE_PKGFILTER(optdepends); MAKE_PKGFILTER(makedepends); MAKE_PKGFILTER(checkdepends); MAKE_PKGFILTER(alldepends); MAKE_PKGFILTER(provides); MAKE_PKGFILTER(conflicts); MAKE_PKGFILTER(replaces); MAKE_PKGFILTER(pkglibdepends); MAKE_PKGFILTER(pkglibrpath); MAKE_PKGFILTER(pkglibrunpath); MAKE_PKGFILTER(pkglibinterp); MAKE_PKGFILTER(contains); #undef MAKE_PKGFILTER #define MAKE_OBJFILTER(NAME) ADDFILTER2(ObjectFilter, lib##NAME, NAME, obj_filters) MAKE_OBJFILTER(name); MAKE_OBJFILTER(depends); MAKE_OBJFILTER(path); MAKE_OBJFILTER(rpath); MAKE_OBJFILTER(runpath); MAKE_OBJFILTER(interp); #undef MAKE_OBJFILTER ADDFILTER2(StringFilter, file, filter, str_filters); return false; }
bool Node::walk(WalkSink &inWalker, NodeType::Type inType) const { FilterList filter; filter.push_back(inType); return walk(inWalker, &filter); }