int main(int argc, char** argv) { Mat img; FILE* f = 0; char _filename[1024]; if( argc == 1 ) { printf("Usage: peopledetect (<image_filename> | <image_list>.txt)\n"); return 0; } img = imread(argv[1]); if( img.data ) { strcpy(_filename, argv[1]); } else { f = fopen(argv[1], "rt"); if(!f) { fprintf( stderr, "ERROR: the specified file could not be loaded\n"); return -1; } } HOGDescriptor hog; hog.setSVMDetector(HOGDescriptor::getDefaultPeopleDetector()); namedWindow("people detector", 1); for(;;) { char* filename = _filename; if(f) { if(!fgets(filename, (int)sizeof(_filename)-2, f)) break; //while(*filename && isspace(*filename)) // ++filename; if(filename[0] == '#') continue; int l = strlen(filename); while(l > 0 && isspace(filename[l-1])) --l; filename[l] = '\0'; img = imread(filename); } printf("%s:\n", filename); if(!img.data) continue; fflush(stdout); vector<Rect> found, found_filtered; double t = (double)getTickCount(); // run the detector with default parameters. to get a higher hit-rate // (and more false alarms, respectively), decrease the hitThreshold and // groupThreshold (set groupThreshold to 0 to turn off the grouping completely). hog.detectMultiScale(img, found, 0, Size(8,8), Size(32,32), 1.05, 2); t = (double)getTickCount() - t; printf("tdetection time = %gms\n", t*1000./cv::getTickFrequency()); size_t i, j; for( i = 0; i < found.size(); i++ ) { Rect r = found[i]; for( j = 0; j < found.size(); j++ ) if( j != i && (r & found[j]) == r) break; if( j == found.size() ) found_filtered.push_back(r); } for( i = 0; i < found_filtered.size(); i++ ) { Rect r = found_filtered[i]; // the HOG detector returns slightly larger rectangles than the real objects. // so we slightly shrink the rectangles to get a nicer output. r.x += cvRound(r.width*0.1); r.width = cvRound(r.width*0.8); r.y += cvRound(r.height*0.07); r.height = cvRound(r.height*0.8); rectangle(img, r.tl(), r.br(), cv::Scalar(0,255,0), 3); } imshow("people detector", img); int c = waitKey(0) & 255; if( c == 'q' || c == 'Q' || !f) break; } if(f) fclose(f); return 0; }
Rect MotionDetection::SupplementRect(Rect rect, int videoWidth, int videoHeight) { int topLeftX = rect.x; int topLeftY = rect.y; int bottomRightX = rect.br().x; int bottomRightY = rect.br().y; int widthValue = rect.width; int heightValue = rect.height; Size scalingWindow(rect.width,rect.height); //Boundry detection (Might be changed later due to the different requirement) //there are at least 9 possibilites where the rectangle is // |1 2 3| // |4 5 6| // |7 8 9| if(topLeftX < 0 && topLeftY < 0 && IsBetweenTwoInt(bottomRightX,1,videoWidth) && IsBetweenTwoInt(bottomRightY,1,videoHeight) ) //in 1 { cout << "get in 1" << endl; return Rect(Point(0,0),scalingWindow); } else if(IsBetweenTwoInt(topLeftX,0,videoWidth-1) && topLeftY < 0 && IsBetweenTwoInt(bottomRightX,1,videoWidth) && IsBetweenTwoInt(bottomRightY,1,videoHeight)) // in 2 { cout << "get in 2" << endl; return Rect(Point(topLeftX,0),scalingWindow); } else if(IsBetweenTwoInt(topLeftX,1,videoWidth-1) && topLeftY < 0 && bottomRightX > videoWidth && IsBetweenTwoInt(bottomRightY,1,videoHeight)) // in 3 { cout << "get in 3" << endl; return Rect(Point(videoWidth - widthValue,0), scalingWindow); } else if(topLeftX < 0 && IsBetweenTwoInt(topLeftY,0,videoHeight-1) && IsBetweenTwoInt(bottomRightX,1,videoWidth) && IsBetweenTwoInt(bottomRightY,1,videoHeight)) // in 4 { cout << "get in 4" << endl; return Rect(Point(0,topLeftY),scalingWindow); } else if(IsBetweenTwoInt(topLeftX,0,videoWidth-1) && IsBetweenTwoInt(topLeftY,0,videoHeight-1) && IsBetweenTwoInt(bottomRightX,1,videoWidth) && IsBetweenTwoInt(bottomRightY,1,videoHeight)) // in 5 { cout << "get in 5" << endl; return Rect(Point(topLeftX,topLeftY),scalingWindow); } else if(IsBetweenTwoInt(topLeftX,0,videoWidth-1) && IsBetweenTwoInt(topLeftY,0,videoHeight-1) && bottomRightX > videoWidth && IsBetweenTwoInt(bottomRightY,1,videoHeight)) // in 6 { cout << "get in 6" << endl; return Rect(Point(videoWidth - widthValue,topLeftY),scalingWindow); } else if(topLeftX < 0 && IsBetweenTwoInt(topLeftY,1,videoHeight-1) && IsBetweenTwoInt(bottomRightX,1,videoWidth)-1 && bottomRightY > videoHeight) // in 7 { cout << "get in 7" << endl; return Rect(Point(0,videoHeight-heightValue),scalingWindow); } else if(IsBetweenTwoInt(topLeftX,0,videoWidth) && IsBetweenTwoInt(topLeftY,1,videoHeight-1) && IsBetweenTwoInt(bottomRightX,1,videoWidth) && bottomRightY > 0) // in 8 { cout << "get in 8" << endl; return Rect(Point(topLeftX,videoHeight-heightValue),scalingWindow); } else if(IsBetweenTwoInt(topLeftX,0,videoHeight-1) && IsBetweenTwoInt(topLeftY,1,videoHeight-1) && bottomRightX > videoWidth && bottomRightY > videoHeight) // in 9 { cout << "get in 9" << endl; return Rect(Point(videoWidth - widthValue,videoHeight - heightValue),scalingWindow); } }
//-----------------------------------【main( )函数】-------------------------------------------- // 描述:控制台应用程序的入口函数,我们的程序从这里开始 //------------------------------------------------------------------------------------------------- int main( int argc, const char** argv ) { ShowHelpText(); VideoCapture cap; Rect trackWindow; int hsize = 16; float hranges[] = {0,180}; const float* phranges = hranges; cap.open(0); if( !cap.isOpened() ) { cout << "不能初始化摄像头\n"; } namedWindow( "Histogram", 0 ); namedWindow( "CamShift Demo", 0 ); setMouseCallback( "CamShift Demo", onMouse, 0 ); createTrackbar( "Vmin", "CamShift Demo", &vmin, 256, 0 ); createTrackbar( "Vmax", "CamShift Demo", &vmax, 256, 0 ); createTrackbar( "Smin", "CamShift Demo", &smin, 256, 0 ); Mat frame, hsv, hue, mask, hist, histimg = Mat::zeros(200, 320, CV_8UC3), backproj; bool paused = false; for(;;) { if( !paused ) { cap >> frame; if( frame.empty() ) break; } frame.copyTo(image); if( !paused ) { cvtColor(image, hsv, COLOR_BGR2HSV); if( trackObject ) { int _vmin = vmin, _vmax = vmax; inRange(hsv, Scalar(0, smin, MIN(_vmin,_vmax)), Scalar(180, 256, MAX(_vmin, _vmax)), mask); int ch[] = {0, 0}; hue.create(hsv.size(), hsv.depth()); mixChannels(&hsv, 1, &hue, 1, ch, 1); if( trackObject < 0 ) { Mat roi(hue, selection), maskroi(mask, selection); calcHist(&roi, 1, 0, maskroi, hist, 1, &hsize, &phranges); normalize(hist, hist, 0, 255, CV_MINMAX); trackWindow = selection; trackObject = 1; histimg = Scalar::all(0); int binW = histimg.cols / hsize; Mat buf(1, hsize, CV_8UC3); for( int i = 0; i < hsize; i++ ) buf.at<Vec3b>(i) = Vec3b(saturate_cast<uchar>(i*180./hsize), 255, 255); cvtColor(buf, buf, CV_HSV2BGR); for( int i = 0; i < hsize; i++ ) { int val = saturate_cast<int>(hist.at<float>(i)*histimg.rows/255); rectangle( histimg, Point(i*binW,histimg.rows), Point((i+1)*binW,histimg.rows - val), Scalar(buf.at<Vec3b>(i)), -1, 8 ); } } calcBackProject(&hue, 1, 0, hist, backproj, &phranges); backproj &= mask; RotatedRect trackBox = CamShift(backproj, trackWindow, TermCriteria( CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 10, 1 )); if( trackWindow.area() <= 1 ) { int cols = backproj.cols, rows = backproj.rows, r = (MIN(cols, rows) + 5)/6; trackWindow = Rect(trackWindow.x - r, trackWindow.y - r, trackWindow.x + r, trackWindow.y + r) & Rect(0, 0, cols, rows); } if( backprojMode ) cvtColor( backproj, image, COLOR_GRAY2BGR ); ellipse( image, trackBox, Scalar(0,0,255), 3, CV_AA ); } } else if( trackObject < 0 ) paused = false; if( selectObject && selection.width > 0 && selection.height > 0 ) { Mat roi(image, selection); bitwise_not(roi, roi); } imshow( "CamShift Demo", image ); imshow( "Histogram", histimg ); char c = (char)waitKey(10); if( c == 27 ) break; switch(c) { case 'b': backprojMode = !backprojMode; break; case 'c': trackObject = 0; histimg = Scalar::all(0); break; case 'h': showHist = !showHist; if( !showHist ) destroyWindow( "Histogram" ); else namedWindow( "Histogram", 1 ); break; case 'p': paused = !paused; break; default: ; } }
bool Layer_SphereDistort::accelerated_render(Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const { RENDER_TRANSFORMED_IF_NEED(__FILE__, __LINE__) /* Things to consider: 1) Block expansion for distortion (ouch... quality level??) 2) Bounding box clipping 3) Super sampling for better visual quality (based on the quality level?) 4) Interpolation type for sampling (based on quality level?) //things to defer until after super sampling, non-linear interpolation */ //bounding box reject Vector center=param_center.get(Vector()); double radius=param_radius.get(double()); double percent=param_amount.get(double()); int type=param_type.get(int()); bool clip=param_clip.get(bool()); { Rect sphr; sphr.set_point(center[0]-radius,center[1]-radius); sphr.expand(center[0]+radius,center[1]+radius); //get the bounding box of the transform Rect windr; //and the bounding box of the rendering windr.set_point(renddesc.get_tl()[0],renddesc.get_tl()[1]); windr.expand(renddesc.get_br()[0],renddesc.get_br()[1]); //test bounding boxes for collision if( (type == TYPE_NORMAL && !intersect(sphr,windr)) || (type == TYPE_DISTH && (sphr.minx >= windr.maxx || windr.minx >= sphr.maxx)) || (type == TYPE_DISTV && (sphr.miny >= windr.maxy || windr.miny >= sphr.maxy)) ) { //synfig::warning("Spherize: Bounding box reject"); if (clip) { surface->set_wh(renddesc.get_w(), renddesc.get_h()); surface->clear(); return true; } else return context.accelerated_render(surface,quality,renddesc,cb); } //synfig::warning("Spherize: Bounding box accept"); } //Ok, so we overlap some... now expand the window for rendering RendDesc r = renddesc; Surface background; Real pw = renddesc.get_pw(),ph = renddesc.get_ph(); int nl=0,nt=0,nr=0,nb=0, nw=0,nh=0; Point tl = renddesc.get_tl(), br = renddesc.get_br(); { //must enlarge window by pixel coordinates so go! //need to figure out closest and farthest point and distort THOSE Point origin[4] = {tl,tl,br,br}; Vector v[4] = {Vector(0,br[1]-tl[1]), Vector(br[0]-tl[0],0), Vector(0,tl[1]-br[1]), Vector(tl[0]-br[0],0)}; Point close(0,0); Real t = 0; Rect expandr(tl,br); //expandr.set_point(tl[0],tl[1]); //expandr.expand(br[0],br[1]); //synfig::warning("Spherize: Loop through lines and stuff"); for(int i=0; i<4; ++i) { //synfig::warning("Spherize: %d", i); Vector p_o = center-origin[i]; //project onto left line t = (p_o*v[i])/v[i].mag_squared(); //clamp if(t < 0) t = 0; if(t > 1) t = 1; close = origin[i] + v[i]*t; //now get transforms and expand the rectangle to accommodate Point p = sphtrans(close,center,radius,percent,type); expandr.expand(p[0],p[1]); p = sphtrans(origin[i],center,radius,percent,type); expandr.expand(p[0],p[1]); p = sphtrans(origin[i]+v[i],center,radius,percent,type); expandr.expand(p[0],p[1]); } /*synfig::warning("Spherize: Bounding box (%f,%f)-(%f,%f)", expandr.minx,expandr.miny,expandr.maxx,expandr.maxy);*/ //now that we have the bounding rectangle of ALL the pixels (should be...) //order it so that it's in the same orientation as the tl,br pair //synfig::warning("Spherize: Organize like tl,br"); Point ntl(0,0),nbr(0,0); //sort x if(tl[0] < br[0]) { ntl[0] = expandr.minx; nbr[0] = expandr.maxx; } else { ntl[0] = expandr.maxx; nbr[0] = expandr.minx; } //sort y if(tl[1] < br[1]) { ntl[1] = expandr.miny; nbr[1] = expandr.maxy; } else { ntl[1] = expandr.maxy; nbr[1] = expandr.miny; } //now expand the window as needed Vector temp = ntl-tl; //pixel offset nl = (int)(temp[0]/pw)-1; nt = (int)(temp[1]/ph)-1; temp = nbr - br; nr = (int)(temp[0]/pw)+1; nb = (int)(temp[1]/ph)+1; nw = renddesc.get_w() + nr - nl; nh = renddesc.get_h() + nb - nt; //synfig::warning("Spherize: Setting subwindow (%d,%d) (%d,%d) (%d,%d)",nl,nt,nr,nb,nw,nh); r.set_subwindow(nl,nt,nw,nh); /*r = renddesc; nw = r.get_w(), nh = r.get_h(); nl = 0, nt = 0;*/ } //synfig::warning("Spherize: render background"); if(!context.accelerated_render(&background,quality,r,cb)) { synfig::warning("SphereDistort: Layer below failed"); return false; } //now distort and check to make sure we aren't overshooting our bounds here int w = renddesc.get_w(), h = renddesc.get_h(); surface->set_wh(w,h); Point sample = tl, sub = tl, trans(0,0); float xs = 0,ys = 0; int y=0,x=0; Real invpw = 1/pw, invph = 1/ph; Surface::pen p = surface->begin(); Point rtl = r.get_tl(); //synfig::warning("Spherize: About to transform"); for(y = 0; y < h; ++y, sample[1] += ph, p.inc_y()) { sub = sample; for(x = 0; x < w; ++x, sub[0] += pw, p.inc_x()) { bool clipped; trans=sphtrans(sub,center,radius,percent,type,clipped); if(clip && clipped) { p.put_value(Color::alpha()); continue; } xs = (trans[0]-rtl[0])*invpw; ys = (trans[1]-rtl[1])*invph; if(!(xs >= 0 && xs < nw && ys >= 0 && ys < nh)) { //synfig::warning("Spherize: we failed to account for %f,%f",xs,ys); p.put_value(context.get_color(trans));//Color::alpha()); continue; } //sample at that pixel location based on the quality if(quality <= 4) // cubic p.put_value(background.cubic_sample(xs,ys)); else if(quality <= 5) // cosine p.put_value(background.cosine_sample(xs,ys)); else if(quality <= 6) // linear p.put_value(background.linear_sample(xs,ys)); else // nearest p.put_value(background[round_to_int(ys)][round_to_int(xs)]); } p.dec_x(w); } return true; }
void LayerBase::drawWithOpenGL(const Region& clip, GLint textureName, const GGLSurface& t) const { const DisplayHardware& hw(graphicPlane(0).displayHardware()); const uint32_t fbHeight = hw.getHeight(); const State& s(drawingState()); // bind our texture validateTexture(textureName); glEnable(GL_TEXTURE_2D); // Dithering... if (s.flags & ISurfaceComposer::eLayerDither) { glEnable(GL_DITHER); } else { glDisable(GL_DITHER); } if (UNLIKELY(s.alpha < 0xFF)) { // We have an alpha-modulation. We need to modulate all // texture components by alpha because we're always using // premultiplied alpha. // If the texture doesn't have an alpha channel we can // use REPLACE and switch to non premultiplied alpha // blending (SRCA/ONE_MINUS_SRCA). GLenum env, src; if (needsBlending()) { env = GL_MODULATE; src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA; } else { env = GL_REPLACE; src = GL_SRC_ALPHA; } const GGLfixed alpha = (s.alpha << 16)/255; glColor4x(alpha, alpha, alpha, alpha); glEnable(GL_BLEND); glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA); glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, env); } else { glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glColor4x(0x10000, 0x10000, 0x10000, 0x10000); if (needsBlending()) { GLenum src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA; glEnable(GL_BLEND); glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA); } else { glDisable(GL_BLEND); } } if (UNLIKELY(transformed() || !(mFlags & DisplayHardware::DRAW_TEXTURE_EXTENSION) )) { //StopWatch watch("GL transformed"); Region::iterator iterator(clip); if (iterator) { // always use high-quality filtering with fast configurations bool fast = !(mFlags & DisplayHardware::SLOW_CONFIG); if (!fast && s.flags & ISurfaceComposer::eLayerFilter) { glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); } const GLfixed texCoords[4][2] = { { 0, 0 }, { 0, 0x10000 }, { 0x10000, 0x10000 }, { 0x10000, 0 } }; glMatrixMode(GL_TEXTURE); glLoadIdentity(); if (!(mFlags & DisplayHardware::NPOT_EXTENSION)) { // find the smallest power-of-two that will accommodate our surface GLuint tw = 1 << (31 - clz(t.width)); GLuint th = 1 << (31 - clz(t.height)); if (tw < t.width) tw <<= 1; if (th < t.height) th <<= 1; // this divide should be relatively fast because it's // a power-of-two (optimized path in libgcc) GLfloat ws = GLfloat(t.width) /tw; GLfloat hs = GLfloat(t.height)/th; glScalef(ws, hs, 1.0f); } glEnableClientState(GL_TEXTURE_COORD_ARRAY); glVertexPointer(2, GL_FIXED, 0, mVertices); glTexCoordPointer(2, GL_FIXED, 0, texCoords); Rect r; while (iterator.iterate(&r)) { const GLint sy = fbHeight - (r.top + r.height()); glScissor(r.left, sy, r.width(), r.height()); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); } if (!fast && s.flags & ISurfaceComposer::eLayerFilter) { glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); } glDisableClientState(GL_TEXTURE_COORD_ARRAY); } } else { Region::iterator iterator(clip); if (iterator) { Rect r; GLint crop[4] = { 0, t.height, t.width, -t.height }; glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, crop); int x = tx(); int y = ty(); y = fbHeight - (y + t.height); while (iterator.iterate(&r)) { const GLint sy = fbHeight - (r.top + r.height()); glScissor(r.left, sy, r.width(), r.height()); glDrawTexiOES(x, y, 0, t.width, t.height); } } } }
void DrumSprite::RegistListener(cocos2d::experimental::AudioProfile& _audioProfile) { // Make sprite1 touchable auto listener1 = EventListenerTouchOneByOne::create(); listener1->setSwallowTouches(true); listener1->onTouchBegan = [&](Touch* touch, Event* event) { auto target = static_cast<Sprite*>(event->getCurrentTarget()); Vec2 locationInNode = target->convertToNodeSpace(touch->getLocation()); Size s = target->getContentSize(); Rect rect = Rect(0, 0, s.width, s.height); //log("touched!"); if (rect.containsPoint(locationInNode)) { //this->setSpriteFrame(SpriteFrame::create("main/drum4_sel.png", Rect(0, 0, 457, 282))); //auto temp = static_cast<AudioTestScene*>(target->getParent()); //log("sprite began... x = %f, y = %f", locationInNode.x, locationInNode.y); //target->setOpacity(180); //log("%s",this->_musicFile); //log(musicFile->_string) ; _id = AudioEngine::play2d(this->_musicFile->c_str(), false, 1.0f, &_audioProfile); int id = _id; //log("_idBack: %d", _id); // if (id != AudioEngine::INVALID_AUDIO_ID) { // log("--"); // } //} this->setTexture(_selSprite->c_str()); this->getParent()->setZOrder(60); Size visibleSize = Director::getInstance()->getVisibleSize(); //score auto scene = (MainGameScene*)(this->getParent()->getParent()); auto note = (NoteNode*)scene->getChildByTag(scene->_curTag); if (note != nullptr) { float dist = note->getPositionX() - visibleSize.width * 0.1; if (this->getParent()->getTag() == note->_type) { ScoreUtil::SetScore(dist, scene); } } return true; } return false; }; listener1->onTouchEnded = [&](Touch* touch, Event* event) { auto target = static_cast<Sprite*>(event->getCurrentTarget()); this->setTexture(_sprite->c_str()); this->getParent()->setZOrder(this->_order); //this->setSpriteFrame(SpriteFrame::create("main/drum4.png", Rect(0, 0, 417, 242))); // log("sprite onTouchesEnded.. "); //target->setOpacity(255); //auto temp = static_cast<AudioTestScene*>(target->getParent()); //AudioEngine::stop(_id); // if (target == sprite2) // { // containerForSprite1->setLocalZOrder(100); // } // else if (target == sprite1) // { // containerForSprite1->setLocalZOrder(0); // } //log("moved!"); }; listener1->retain(); (this->getParent()->getParent())->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener1, this); }
void HierarchyPanel::listGameObjects(int* indent, int* y, int* total, GameObject* gameObject) { Rect rect; Rect expandRect; bool display = false; //*total = *y; *total = *total + 1; rect.x = position.x + (10 * *indent); rect.height = ITEM_HEIGHT; rect.y = position.y + rect.height + (*y * rect.height) + ITEM_HEIGHT; rect.width = position.width; if(totalDisplay >= maxDisplay) { rect.width -= 20; } expandRect = Rect(rect.x, rect.y, expandTexture->getWidth(), expandTexture->getHeight()); if(*y <= maxDisplay && *y >= 0) { display = true; } if(display == true) { Rect labelRect(rect.x + expandTexture->getWidth(), rect.y, rect.width - ((position.x + rect.x) - position.x + expandTexture->getWidth()), rect.height); Rect clickRect(position.x, rect.y, rect.width, rect.height); if(selectedGo != NULL && gameObject->getName() == selectedGo->getName()) { Gui::drawTexture(Rect(position.x, rect.y, rect.width, rect.height), selectedTexture.get()); } Gui::label(labelRect, gameObject->getName()); if(Input::getMouseButtonDown(0) == true) { if(clickRect.contains(Input::getMousePosition()) == true && expandRect.contains(Input::getMousePosition()) == false) { selectedGo = gameObject; } } } *y = *y + 1; if(display == true) { if(gameObject->getTransform()->getChildCount() > 0) { if(gameObject->getTag() != "expanded") { Gui::drawTexture(expandRect, expandTexture); } else { GuiUtility::rotateAroundPivot(90, Vector2(rect.x + (expandTexture->getWidth() / 2), rect.y + (expandTexture->getHeight() / 2))); Gui::drawTexture(expandRect, expandTexture); GuiUtility::rotateAroundPivot(-90, Vector2(rect.x + (expandTexture->getWidth() / 2), rect.y + (expandTexture->getHeight() / 2))); } } if(Input::getMouseButtonDown(0) == true) { if(expandRect.contains(Input::getMousePosition()) == true) { if(gameObject->getTag() != "expanded") gameObject->setTag("expanded"); else if(gameObject->getTag() == "expanded") gameObject->setTag(""); } } } if(gameObject->getTag() != "expanded") { return; } *indent = *indent + 1; for(int i = 0; i < gameObject->getTransform()->getChildCount(); i++) { listGameObjects(indent, y, total, gameObject->getTransform()->getChild(i)->getGameObject()); } *indent = *indent - 1; }
void Inventory::addItem(InventoryObject *draggedObject) { items.pushBack(draggedObject); listView->pushBackCustomItem(draggedObject->getPicture()); EventListenerTouchOneByOne *backgroundListener = EventListenerTouchOneByOne::create(); backgroundListener->setSwallowTouches(true); backgroundListener->onTouchBegan = [draggedObject, this](Touch *touch, Event *event) { auto target = static_cast<ImageView *>(event->getCurrentTarget()); Size s = target->getContentSize(); Point locationInNode = target->convertToNodeSpace(touch->getLocation()); locationInNode = Point(locationInNode.x + s.width * 0.5f, locationInNode.y + s.height * 0.5f); Rect rect = Rect(0, 0, s.width, s.height); if (rect.containsPoint(locationInNode)) { draggedObject->startDrag(); simpleLayout->addChild(draggedObject->getPictureDrag()); draggedObject->getPictureDrag()->setPosition(touch->getLocation()); return true; } return false; }; backgroundListener->onTouchMoved = [draggedObject,this](Touch *touch, Event *event) { if(draggedObject->getPictureDrag() != nullptr) draggedObject->getPictureDrag()->setPosition(touch->getLocation()); }; backgroundListener->onTouchEnded = [draggedObject,this](Touch *touch, Event *event) { log("onTouchEnded draggedObject=%d", draggedObject ? draggedObject->getId() : 0); if(draggedObject->getPictureDrag() != nullptr) draggedObject->getPictureDrag()->setVisible(false); Vector<CollectObject *> gameObjects = FirstScene::getInstance()->getGameObjectsLayer()->getGameObjects(); for(int i = 0; i < gameObjects.size(); ++i) { log("collect obj=%d",gameObjects.at(i)->getId()); Size size = gameObjects.at(i)->getSpriteMain()->getContentSize(); Rect rect = Rect(0, 0, size.width, size.height); Point locationInNode = gameObjects.at(i)->getSpriteMain()->convertToNodeSpace(touch->getLocation()); //locationInNode = Point(locationInNode.x , locationInNode.y - size.height * 0.5f); log("!!!locationInNode=%f %f",locationInNode.x, locationInNode.y); if (rect.containsPoint(locationInNode)) { log("AHTUNG"); } } for(int i = 0; i < items.size(); ++i) { InventoryObject *droppedObject = items.at(i); Size s = droppedObject->getPicture()->getContentSize(); Rect rect = Rect(0, 0, s.width, s.height); Point locationInNode = droppedObject->getPicture()->convertToNodeSpace(touch->getLocation()); locationInNode = Point(locationInNode.x + s.width * 0.5f, locationInNode.y + s.height * 0.5f); log("2onTouchEnded draggedObject=%d obj=%d locationInNode=%f %f", draggedObject ? draggedObject->getId() : 0, droppedObject ? droppedObject->getId() : 0, locationInNode.x,locationInNode.y); if (droppedObject != draggedObject && rect.containsPoint(locationInNode)) { ValueMap *draggedObjectData = DataManager::getInstance()->getItemByID(draggedObject->getId()); ValueMap *draggedObjectCraft = &draggedObjectData->at("craft").asValueMap(); ValueMap *droppedObjectData = DataManager::getInstance()->getItemByID(droppedObject->getId()); ValueMap *droppedObjectCraft = &droppedObjectData->at("craft").asValueMap(); ValueVector draggedObjectCraftItems = draggedObjectCraft->at("items").asValueVector(); bool shouldCraft = false; for(int i = 0; i < draggedObjectCraftItems.size(); ++i) { if(draggedObjectCraftItems.at(i).asInt() == droppedObject->getId()) { shouldCraft = true; break; } } if(shouldCraft) { int draggedCapacity = draggedObjectCraft->at("capacity").asInt(); --draggedCapacity; draggedObjectCraft->at("capacity") = draggedCapacity; int droppedCapacity = droppedObjectCraft->at("capacity").asInt(); --droppedCapacity; droppedObjectCraft->at("capacity") = droppedCapacity; log("carft %d", draggedObjectCraft->at("result").asInt()); if(draggedObjectCraft->at("result").asInt() != 0) { addItem(InventoryObject::create(draggedObjectCraft->at("result").asInt())); } if(!draggedCapacity) { draggedObject->getPicture()->removeFromParent(); } if(!droppedCapacity) { droppedObject->getPicture()->removeFromParent(); } log("GOT IT! draggedCapacity=%d droppedCapacity=%d",draggedCapacity,droppedCapacity); DataManager::getInstance()->save(); } break; } } }; _eventDispatcher->addEventListenerWithSceneGraphPriority(backgroundListener, draggedObject->getPicture()); }
bool Rect::Contains(const Rect& rect) const { return (rect.x() >= x() && rect.right() <= right() && rect.y() >= y() && rect.bottom() <= bottom()); }
static void ComputeRectsForInsetBoxShadow(IntSize aBlurRadius, IntSize aSpreadRadius, IntRect& aOutOuterRect, IntRect& aOutInnerRect, IntMargin& aOutPathMargins, const Rect& aDestRect, const Rect& aShadowClipRect, bool aHasBorderRadius, const RectCornerRadii& aInnerClipRectRadii) { IntSize rectBufferSize = aBlurRadius + aSpreadRadius; float cornerWidth = 0; float cornerHeight = 0; if (aHasBorderRadius) { for (size_t i = 0; i < 4; i++) { cornerWidth = std::max(cornerWidth, aInnerClipRectRadii[i].width); cornerHeight = std::max(cornerHeight, aInnerClipRectRadii[i].height); } } // Create the inner rect to be the smallest possible size based on // blur / spread / corner radii IntMargin innerMargin = IntMargin(ceil(cornerHeight) + rectBufferSize.height, ceil(cornerWidth) + rectBufferSize.width, ceil(cornerHeight) + rectBufferSize.height, ceil(cornerWidth) + rectBufferSize.width); aOutPathMargins = innerMargin; // If we have a negative spread radius, we would not have enough // size to actually do the blur. So the min size must be the abs() of the blur // and spread radius. IntSize minBlurSize(std::abs(aSpreadRadius.width) + std::abs(aBlurRadius.width), std::abs(aSpreadRadius.height) + std::abs(aBlurRadius.height)); IntMargin minInnerMargins = IntMargin(ceil(cornerHeight) + minBlurSize.height, ceil(cornerWidth) + minBlurSize.width, ceil(cornerHeight) + minBlurSize.height, ceil(cornerWidth) + minBlurSize.width); IntSize minInnerSize(minInnerMargins.LeftRight() + 1, minInnerMargins.TopBottom() + 1); if (aShadowClipRect.height < minInnerSize.height) { minInnerSize.height = aShadowClipRect.height; } if (aShadowClipRect.width < minInnerSize.width) { minInnerSize.width = aShadowClipRect.width; } // Then expand the outer rect based on the size between the inner/outer rects IntSize minOuterSize(minInnerSize); IntMargin outerRectMargin(rectBufferSize.height, rectBufferSize.width, rectBufferSize.height, rectBufferSize.width); minOuterSize.width += outerRectMargin.LeftRight(); minOuterSize.height += outerRectMargin.TopBottom(); aOutOuterRect = IntRect(IntPoint(), minOuterSize); aOutInnerRect = IntRect(IntPoint(rectBufferSize.width, rectBufferSize.height), minInnerSize); if (aShadowClipRect.IsEmpty()) { aOutInnerRect.width = 0; aOutInnerRect.height = 0; } }
already_AddRefed<mozilla::gfx::SourceSurface> gfxAlphaBoxBlur::GetInsetBlur(IntMargin& aExtendDestBy, IntMargin& aSlice, const Rect aDestinationRect, const Rect aShadowClipRect, const IntSize& aBlurRadius, const IntSize& aSpreadRadius, const RectCornerRadii& aInnerClipRadii, const Color& aShadowColor, const bool& aHasBorderRadius, const Point aShadowOffset, bool& aMovedOffset, DrawTarget* aDestDrawTarget) { if (!gBlurCache) { gBlurCache = new BlurCache(); } IntRect outerRect; IntRect innerRect; ComputeRectsForInsetBoxShadow(aBlurRadius, aSpreadRadius, outerRect, innerRect, aSlice, aDestinationRect, aShadowClipRect, aHasBorderRadius, aInnerClipRadii); // If we have a shadow offset larger than the min rect, // there's no clean way we can properly create a min rect with the offset // in the correct place and still render correctly. In those cases, // fallback to just rendering the dest rect as is. bool useDestRect = (std::abs(aShadowOffset.x) > aSlice.left) || (std::abs(aShadowOffset.y) > aSlice.top); aMovedOffset = false; if (useDestRect) { aDestinationRect.ToIntRect(&outerRect); aShadowClipRect.ToIntRect(&innerRect); aMovedOffset = true; } BlurCacheData* cached = gBlurCache->LookupInsetBoxShadow(outerRect.Size(), innerRect.Size(), aBlurRadius, aSpreadRadius, &aInnerClipRadii, aShadowColor, aHasBorderRadius, aDestDrawTarget->GetBackendType()); if (cached && !useDestRect) { aExtendDestBy = cached->mExtendDest; // Need to extend it twice: once for the outer rect and once for the inner rect. aSlice += aExtendDestBy; aSlice += aExtendDestBy; // So we don't forget the actual cached blur RefPtr<SourceSurface> cachedBlur = cached->mBlur; return cachedBlur.forget(); } // Dirty rect and skip rect are null for the min inset shadow. // When rendering inset box shadows, we respect the spread radius by changing // the shape of the unblurred shadow, and can pass a spread radius of zero here. IntSize zeroSpread(0, 0); gfxContext* minGfxContext = Init(ThebesRect(outerRect), zeroSpread, aBlurRadius, nullptr, nullptr); if (!minGfxContext) { return nullptr; } DrawTarget* minDrawTarget = minGfxContext->GetDrawTarget(); RefPtr<Path> maskPath = GetBoxShadowInsetPath(minDrawTarget, IntRectToRect(outerRect), IntRectToRect(innerRect), aHasBorderRadius, aInnerClipRadii); Color black(0.f, 0.f, 0.f, 1.f); minGfxContext->SetColor(black); minGfxContext->SetPath(maskPath); minGfxContext->Fill(); IntPoint topLeft; RefPtr<SourceSurface> minMask = DoBlur(minDrawTarget, &topLeft); if (!minMask) { return nullptr; } RefPtr<SourceSurface> minInsetBlur = CreateBoxShadow(minMask, aShadowColor); if (!minInsetBlur) { return nullptr; } IntRect blurRect(topLeft, minInsetBlur->GetSize()); aExtendDestBy = blurRect - outerRect; if (useDestRect) { // Since we're just going to paint the actual rect to the destination aSlice.SizeTo(0, 0, 0, 0); } else { aSlice += aExtendDestBy; aSlice += aExtendDestBy; CacheInsetBlur(outerRect.Size(), innerRect.Size(), aBlurRadius, aSpreadRadius, &aInnerClipRadii, aShadowColor, aHasBorderRadius, aDestDrawTarget->GetBackendType(), aExtendDestBy, minInsetBlur); } return minInsetBlur.forget(); }
/* static */ void gfxAlphaBoxBlur::BlurRectangle(gfxContext* aDestinationCtx, const gfxRect& aRect, RectCornerRadii* aCornerRadii, const gfxPoint& aBlurStdDev, const Color& aShadowColor, const gfxRect& aDirtyRect, const gfxRect& aSkipRect) { IntSize blurRadius = CalculateBlurRadius(aBlurStdDev); IntRect rect = RoundedToInt(ToRect(aRect)); IntMargin extendDestBy; IntMargin slice; RefPtr<SourceSurface> boxShadow = GetBlur(aDestinationCtx, rect.Size(), blurRadius, aCornerRadii, aShadowColor, extendDestBy, slice); if (!boxShadow) { return; } DrawTarget& destDrawTarget = *aDestinationCtx->GetDrawTarget(); destDrawTarget.PushClipRect(ToRect(aDirtyRect)); // Copy the right parts from boxShadow into destDrawTarget. The middle parts // will be stretched, border-image style. Rect srcOuter(Point(), Size(boxShadow->GetSize())); Rect srcInner = srcOuter; srcInner.Deflate(Margin(slice)); rect.Inflate(extendDestBy); Rect dstOuter(rect); Rect dstInner(rect); dstInner.Deflate(Margin(slice)); Rect skipRect = ToRect(aSkipRect); if (srcInner.IsEqualInterior(srcOuter)) { MOZ_ASSERT(dstInner.IsEqualInterior(dstOuter)); // The target rect is smaller than the minimal size so just draw the surface destDrawTarget.DrawSurface(boxShadow, dstInner, srcInner); } else { DrawBoxShadows(destDrawTarget, boxShadow, dstOuter, dstInner, srcOuter, srcInner, skipRect); // Middle part RepeatOrStretchSurface(destDrawTarget, boxShadow, RectWithEdgesTRBL(dstInner.Y(), dstInner.XMost(), dstInner.YMost(), dstInner.X()), RectWithEdgesTRBL(srcInner.Y(), srcInner.XMost(), srcInner.YMost(), srcInner.X()), skipRect); } // A note about anti-aliasing and seems between adjacent parts: // We don't explicitly disable anti-aliasing in the DrawSurface calls above, // so if there's a transform on destDrawTarget that is not pixel-aligned, // there will be seams between adjacent parts of the box-shadow. It's hard to // avoid those without the use of an intermediate surface. // You might think that we could avoid those by just turning of AA, but there // is a problem with that: Box-shadow rendering needs to clip out the // element's border box, and we'd like that clip to have anti-aliasing - // especially if the element has rounded corners! So we can't do that unless // we have a way to say "Please anti-alias the clip, but don't antialias the // destination rect of the DrawSurface call". // On OS X there is an additional problem with turning off AA: CoreGraphics // will not just fill the pixels that have their pixel center inside the // filled shape. Instead, it will fill all the pixels which are partially // covered by the shape. So for pixels on the edge between two adjacent parts, // all those pixels will be painted to by both parts, which looks very bad. destDrawTarget.PopClip(); }
static void DrawBoxShadows(DrawTarget& aDestDrawTarget, SourceSurface* aSourceBlur, Rect aDstOuter, Rect aDstInner, Rect aSrcOuter, Rect aSrcInner, Rect aSkipRect) { // Corners: top left, top right, bottom left, bottom right DrawCorner(aDestDrawTarget, aSourceBlur, RectWithEdgesTRBL(aDstOuter.Y(), aDstInner.X(), aDstInner.Y(), aDstOuter.X()), RectWithEdgesTRBL(aSrcOuter.Y(), aSrcInner.X(), aSrcInner.Y(), aSrcOuter.X()), aSkipRect); DrawCorner(aDestDrawTarget, aSourceBlur, RectWithEdgesTRBL(aDstOuter.Y(), aDstOuter.XMost(), aDstInner.Y(), aDstInner.XMost()), RectWithEdgesTRBL(aSrcOuter.Y(), aSrcOuter.XMost(), aSrcInner.Y(), aSrcInner.XMost()), aSkipRect); DrawCorner(aDestDrawTarget, aSourceBlur, RectWithEdgesTRBL(aDstInner.YMost(), aDstInner.X(), aDstOuter.YMost(), aDstOuter.X()), RectWithEdgesTRBL(aSrcInner.YMost(), aSrcInner.X(), aSrcOuter.YMost(), aSrcOuter.X()), aSkipRect); DrawCorner(aDestDrawTarget, aSourceBlur, RectWithEdgesTRBL(aDstInner.YMost(), aDstOuter.XMost(), aDstOuter.YMost(), aDstInner.XMost()), RectWithEdgesTRBL(aSrcInner.YMost(), aSrcOuter.XMost(), aSrcOuter.YMost(), aSrcInner.XMost()), aSkipRect); // Edges: top, left, right, bottom RepeatOrStretchSurface(aDestDrawTarget, aSourceBlur, RectWithEdgesTRBL(aDstOuter.Y(), aDstInner.XMost(), aDstInner.Y(), aDstInner.X()), RectWithEdgesTRBL(aSrcOuter.Y(), aSrcInner.XMost(), aSrcInner.Y(), aSrcInner.X()), aSkipRect); RepeatOrStretchSurface(aDestDrawTarget, aSourceBlur, RectWithEdgesTRBL(aDstInner.Y(), aDstInner.X(), aDstInner.YMost(), aDstOuter.X()), RectWithEdgesTRBL(aSrcInner.Y(), aSrcInner.X(), aSrcInner.YMost(), aSrcOuter.X()), aSkipRect); RepeatOrStretchSurface(aDestDrawTarget, aSourceBlur, RectWithEdgesTRBL(aDstInner.Y(), aDstOuter.XMost(), aDstInner.YMost(), aDstInner.XMost()), RectWithEdgesTRBL(aSrcInner.Y(), aSrcOuter.XMost(), aSrcInner.YMost(), aSrcInner.XMost()), aSkipRect); RepeatOrStretchSurface(aDestDrawTarget, aSourceBlur, RectWithEdgesTRBL(aDstInner.YMost(), aDstInner.XMost(), aDstOuter.YMost(), aDstInner.X()), RectWithEdgesTRBL(aSrcInner.YMost(), aSrcInner.XMost(), aSrcOuter.YMost(), aSrcInner.X()), aSkipRect); }
void ARX_UNICODE_FormattingInRect(Font * font, const std::string & text, const Rect & rect, Color col, long * textHeight = 0, long * numChars = 0, bool computeOnly = false) { std::string::const_iterator itLastLineBreak = text.begin(); std::string::const_iterator itLastWordBreak = text.begin(); std::string::const_iterator it = text.begin(); int maxLineWidth; if(rect.right == Rect::Limits::max()) { maxLineWidth = std::numeric_limits<int>::max(); } else { maxLineWidth = rect.width(); } arx_assert(maxLineWidth > 0); int penY = rect.top; if(textHeight) { *textHeight = 0; } if(numChars) { *numChars = 0; } // Ensure we can at least draw one line... if(penY + font->GetLineHeight() > rect.bottom) { return; } for(it = text.begin(); it != text.end(); ++it) { // Line break ? bool isLineBreak = false; if(*it == '\n' || *it == '*') { isLineBreak = true; } else { // Word break ? if(*it == ' ' || *it == '\t') { itLastWordBreak = it; } // Check length of string up to this point Vec2i size = font->GetTextSize(itLastLineBreak, it + 1); if(size.x > maxLineWidth) { // Too long ? isLineBreak = true; if(itLastWordBreak > itLastLineBreak) { // Draw a line from the last line break up to the last word break it = itLastWordBreak; } else if(it == itLastLineBreak) { // Not enough space to render even one character! break; } else { // The current word is too long to fit on a line, force a line break } } } // If we have to draw a line // OR // This is the last character of the string if(isLineBreak || it + 1 == text.end()) { std::string::const_iterator itTextStart = itLastLineBreak; std::string::const_iterator itTextEnd; itTextEnd = (isLineBreak) ? it : it + 1; // Draw the line if(!computeOnly) { font->Draw(rect.left, penY, itTextStart, itTextEnd, col); } if(it != text.end()) { itLastLineBreak = it + 1; } penY += font->GetLineHeight(); // Validate that the new line will fit inside the rect... if(penY + font->GetLineHeight() > rect.bottom) { break; } } } // Return text height if(textHeight) { *textHeight = penY - rect.top; } // Return num characters displayed if(numChars) { *numChars = it - text.begin(); } }
bool BootAnimation::android() { initTexture(&mAndroid[0], mAssets, "images/android-logo-mask.png"); initTexture(&mAndroid[1], mAssets, "images/android-logo-shine.png"); // clear screen glShadeModel(GL_FLAT); glDisable(GL_DITHER); glDisable(GL_SCISSOR_TEST); glClearColor(0,0,0,1); glClear(GL_COLOR_BUFFER_BIT); eglSwapBuffers(mDisplay, mSurface); glEnable(GL_TEXTURE_2D); glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); const GLint xc = (mWidth - mAndroid[0].w) / 2; const GLint yc = (mHeight - mAndroid[0].h) / 2; const Rect updateRect(xc, yc, xc + mAndroid[0].w, yc + mAndroid[0].h); glScissor(updateRect.left, mHeight - updateRect.bottom, updateRect.width(), updateRect.height()); // Blend state glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); const nsecs_t startTime = systemTime(); do { nsecs_t now = systemTime(); double time = now - startTime; float t = 4.0f * float(time / us2ns(16667)) / mAndroid[1].w; GLint offset = (1 - (t - floorf(t))) * mAndroid[1].w; GLint x = xc - offset; glDisable(GL_SCISSOR_TEST); glClear(GL_COLOR_BUFFER_BIT); glEnable(GL_SCISSOR_TEST); glDisable(GL_BLEND); glBindTexture(GL_TEXTURE_2D, mAndroid[1].name); glDrawTexiOES(x, yc, 0, mAndroid[1].w, mAndroid[1].h); glDrawTexiOES(x + mAndroid[1].w, yc, 0, mAndroid[1].w, mAndroid[1].h); glEnable(GL_BLEND); glBindTexture(GL_TEXTURE_2D, mAndroid[0].name); glDrawTexiOES(xc, yc, 0, mAndroid[0].w, mAndroid[0].h); EGLBoolean res = eglSwapBuffers(mDisplay, mSurface); if (res == EGL_FALSE) break; // 12fps: don't animate too fast to preserve CPU const nsecs_t sleepTime = 83333 - ns2us(systemTime() - now); if (sleepTime > 0) usleep(sleepTime); checkExit(); } while (!exitPending()); glDeleteTextures(1, &mAndroid[0].name); glDeleteTextures(1, &mAndroid[1].name); return false; }
bool Rect::Intersects(const Rect& rect) const { return !(rect.x() >= right() || rect.right() <= x() || rect.y() >= bottom() || rect.bottom() <= y()); }
void PropColumnMenu::onTouchEnded(Touch *pTouch, Event *pEvent) { Point point = pTouch->getLocation(); Rect rect = Rect::ZERO; rect.origin = m_propColumn->convertToWorldSpace(Point::ZERO); rect.size = m_propColumn->getContentSize(); if (rect.containsPoint(point)) { point = m_propColumn->convertToNodeSpace(point); int x = (int)point.x / GRID_WIDTH; int y = (int)point.y / GRID_HEIGHT; y = ROW - y - 1; m_propVec[m_editProp->getTag()]->setVisible(true); this->swapProp(m_editProp->getTag(), y*COL+x); } else { if (m_editProp->getOpacity() == 255) { GAME_UILAYER->getOperationMenu()->addDrugs(2001); ControlButton* btn = GAME_UILAYER->getOperationMenu()->getDrugsBtn(); btn->stopAllActions(); ScaleTo* scaleTo = ScaleTo::create(0.1f, 1.0f); btn->runAction(scaleTo); m_propVec[m_editProp->getTag()]->removeFromParent(); m_propVec[m_editProp->getTag()] = NULL; } else { float r = CCRANDOM_0_1(); if (r ==1) r = 0; BgMap* bgMap = GAME_SCENE->getCurrBgMap(); MapPoint playerPosition = MapPoint(Player::sharePlayer()->getPosition()); MapPoint point = MapPointZero; std::vector<MapPoint> mapVec; M_INT lenght = 1; do { mapVec = playerPosition.getMapPointVectorForDistance(lenght); unsigned int index = 0; for (; index<mapVec.size(); index++) { if (GAME_SCENE->getMapPointForProp(MapPoint(mapVec.at(index))) == NULL) { point = MapPoint(mapVec.at(index)); } } CC_BREAK_IF(!point.equals(MapPointZero)); lenght++; } while (1); PropIconShow* show = m_propVec[m_editProp->getTag()]; m_propVec[m_editProp->getTag()] = NULL; show->setVisible(true); show->retain(); show->removeFromParent(); show->setPosition(point.getCCPointValue()); bgMap->addChild(show, BgMap::getZOrderZero(bgMap)); show->release(); show->setScale(0.8f); GAME_SCENE->insterMapPointForProp(show, point); show->setOpacity(0); FadeIn* fadeIn = FadeIn::create(0.1f); JumpBy* jumpBy = JumpBy::create(0.3f, Point::ZERO, 30, 1); Spawn* spawn = Spawn::create(fadeIn, jumpBy, NULL); show->runAction(spawn); } } m_editProp->removeFromParent(); m_editProp = NULL; }
Rect Rect::Subtract(const Rect& rect) const { // boundary cases: if (!Intersects(rect)) return *this; if (rect.Contains(*this)) return Rect(); int32_t rx = x(); int32_t ry = y(); int32_t rr = right(); int32_t rb = bottom(); if (rect.y() <= y() && rect.bottom() >= bottom()) { // complete intersection in the y-direction if (rect.x() <= x()) { rx = rect.right(); } else { rr = rect.x(); } } else if (rect.x() <= x() && rect.right() >= right()) { // complete intersection in the x-direction if (rect.y() <= y()) { ry = rect.bottom(); } else { rb = rect.y(); } } return Rect(rx, ry, rr - rx, rb - ry); }
Rect UIWidget::getChildrenRect() { Rect rect = m_rect; rect.expand(-m_padding.top, -m_padding.right, -m_padding.bottom, -m_padding.left); return rect; }
bool Rect::SharesEdgeWith(const Rect& rect) const { return (y() == rect.y() && height() == rect.height() && (x() == rect.right() || right() == rect.x())) || (x() == rect.x() && width() == rect.width() && (y() == rect.bottom() || bottom() == rect.y())); }
bool UIAnchorLayout::updateWidget(const UIWidgetPtr& widget, const UIAnchorGroupPtr& anchorGroup, UIWidgetPtr first) { UIWidgetPtr parentWidget = getParentWidget(); if(!parentWidget) return false; if(first == widget) { g_logger.error(stdext::format("child '%s' of parent widget '%s' is recursively anchored to itself, please fix this", widget->getId(), parentWidget->getId())); return false; } if(!first) first = widget; Rect newRect = widget->getRect(); bool verticalMoved = false; bool horizontalMoved = false; // calculates new rect based on anchors for(const UIAnchorPtr& anchor : anchorGroup->getAnchors()) { // skip invalid anchors if(anchor->getHookedEdge() == Fw::AnchorNone) continue; // determine hooked widget UIWidgetPtr hookedWidget = anchor->getHookedWidget(widget, parentWidget); // skip invalid anchors if(!hookedWidget) continue; if(hookedWidget != getParentWidget()) { // update this hooked widget anchors auto it = m_anchorsGroups.find(hookedWidget); if(it != m_anchorsGroups.end()) { const UIAnchorGroupPtr& hookedAnchorGroup = it->second; if(!hookedAnchorGroup->isUpdated()) updateWidget(hookedWidget, hookedAnchorGroup, first); } } int point = anchor->getHookedPoint(hookedWidget, parentWidget); switch(anchor->getAnchoredEdge()) { case Fw::AnchorHorizontalCenter: newRect.moveHorizontalCenter(point + widget->getMarginLeft() - widget->getMarginRight()); horizontalMoved = true; break; case Fw::AnchorLeft: if(!horizontalMoved) { newRect.moveLeft(point + widget->getMarginLeft()); horizontalMoved = true; } else newRect.setLeft(point + widget->getMarginLeft()); break; case Fw::AnchorRight: if(!horizontalMoved) { newRect.moveRight(point - widget->getMarginRight()); horizontalMoved = true; } else newRect.setRight(point - widget->getMarginRight()); break; case Fw::AnchorVerticalCenter: newRect.moveVerticalCenter(point + widget->getMarginTop() - widget->getMarginBottom()); verticalMoved = true; break; case Fw::AnchorTop: if(!verticalMoved) { newRect.moveTop(point + widget->getMarginTop()); verticalMoved = true; } else newRect.setTop(point + widget->getMarginTop()); break; case Fw::AnchorBottom: if(!verticalMoved) { newRect.moveBottom(point - widget->getMarginBottom()); verticalMoved = true; } else newRect.setBottom(point - widget->getMarginBottom()); break; default: break; } } bool changed = false; if(widget->setRect(newRect)) changed = true; anchorGroup->setUpdated(true); return changed; }
vector<detection> HogDetector::detect( ClassifierParams& params ) { Mat frame = params.frame; vector<Rect> rectDetections; vector<detection> detectionsToReturn; int detectionId = 0; Mat grayClone; cv::cvtColor(frame, grayClone, CV_BGR2GRAY); gpuMat.upload(grayClone); hogGpuDetector.detectMultiScale(gpuMat,rectDetections); gpuMat.release(); grayClone.release(); /*auto cl = frame.clone(); for_each(begin(rectDetections), end(rectDetections), [&](Rect b) { Rect rect = b; Scalar color = Scalar( 0,255,0 ); rectangle( cl, rect.tl(), rect.br(), color); }); PngSaver::save("falseDetections", cl); PngSaver::incrementCount(); cl.release();*/ int size = rectDetections.size(); int* status = new int[size]; memset(status, KEEP, size*sizeof(int)); for(int i = 0; i < size - 1; i++) { for(int j = i+1; j < size; j++) { if(status[i] == KEEP && status[j] == KEEP) { int min; if(rectDetections[i].area() < rectDetections[j].area()) min = i; else min = j; Rect intersection = rectDetections[i] & rectDetections[j]; if(intersection.area() > 0.4*rectDetections[min].area()) { status[min] = DISCARD; } } } } for(int i = 0; i < size; i++) if(status[i] == KEEP) { detection det = {detectionId++, rectDetections[i]}; detectionsToReturn.push_back(det); } delete[] status; return detectionsToReturn; }
bool Layer_SphereDistort::accelerated_cairorender(Context context, cairo_t *cr, int quality, const RendDesc &renddesc_, ProgressCallback *cb)const { /* Things to consider: 1) Block expansion for distortion (ouch... quality level??) 2) Bounding box clipping 3) Super sampling for better visual quality (based on the quality level?) 4) Interpolation type for sampling (based on quality level?) //things to defer until after super sampling, non-linear interpolation */ Vector center=param_center.get(Vector()); double radius=param_radius.get(double()); double percent=param_amount.get(double()); int type=param_type.get(int()); bool clip=param_clip.get(bool()); RendDesc renddesc(renddesc_); // Untransform the render desc if(!cairo_renddesc_untransform(cr, renddesc)) return false; //bounding box reject { Rect sphr; sphr.set_point(center[0]-radius,center[1]-radius); sphr.expand(center[0]+radius,center[1]+radius); //get the bounding box of the transform Rect windr; //and the bounding box of the rendering windr.set_point(renddesc.get_tl()[0],renddesc.get_tl()[1]); windr.expand(renddesc.get_br()[0],renddesc.get_br()[1]); //test bounding boxes for collision if( (type == TYPE_NORMAL && !intersect(sphr,windr)) || (type == TYPE_DISTH && (sphr.minx >= windr.maxx || windr.minx >= sphr.maxx)) || (type == TYPE_DISTV && (sphr.miny >= windr.maxy || windr.miny >= sphr.maxy)) ) { if (clip) { cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR); cairo_paint(cr); return true; } else return context.accelerated_cairorender(cr,quality,renddesc,cb); } } //Ok, so we overlap some... now expand the window for rendering RendDesc r = renddesc; cairo_surface_t* background, *result; int nl=0,nt=0,nr=0,nb=0, nw=0,nh=0; // grab the current renddesc interesting values const Real pw = renddesc.get_pw(),ph = renddesc.get_ph(); const Point tl = renddesc.get_tl(), br = renddesc.get_br(); const int w = renddesc.get_w(), h = renddesc.get_h(); { //must enlarge window by pixel coordinates so go! //need to figure out closest and farthest point and distort THOSE Point origin[4] = {tl,tl,br,br}; Vector v[4] = {Vector(0,br[1]-tl[1]), Vector(br[0]-tl[0],0), Vector(0,tl[1]-br[1]), Vector(tl[0]-br[0],0)}; Point close(0,0); Real t = 0; Rect expandr(tl,br); //expandr.set_point(tl[0],tl[1]); //expandr.expand(br[0],br[1]); for(int i=0; i<4; ++i) { Vector p_o = center-origin[i]; //project onto left line t = (p_o*v[i])/v[i].mag_squared(); //clamp if(t < 0) t = 0; if(t > 1) t = 1; close = origin[i] + v[i]*t; //now get transforms and expand the rectangle to accommodate Point p = sphtrans(close,center,radius,percent,type); expandr.expand(p[0],p[1]); p = sphtrans(origin[i],center,radius,percent,type); expandr.expand(p[0],p[1]); p = sphtrans(origin[i]+v[i],center,radius,percent,type); expandr.expand(p[0],p[1]); } //now that we have the bounding rectangle of ALL the pixels (should be...) //order it so that it's in the same orientation as the tl,br pair Point ntl(0,0),nbr(0,0); //sort x if(tl[0] < br[0]) { ntl[0] = expandr.minx; nbr[0] = expandr.maxx; } else { ntl[0] = expandr.maxx; nbr[0] = expandr.minx; } //sort y if(tl[1] < br[1]) { ntl[1] = expandr.miny; nbr[1] = expandr.maxy; } else { ntl[1] = expandr.maxy; nbr[1] = expandr.miny; } //now expand the window as needed Vector temp = ntl-tl; //pixel offset nl = (int)(temp[0]/pw)-1; nt = (int)(temp[1]/ph)-1; temp = nbr - br; nr = (int)(temp[0]/pw)+1; nb = (int)(temp[1]/ph)+1; nw = renddesc.get_w() + nr - nl; nh = renddesc.get_h() + nb - nt; r.set_subwindow(nl,nt,nw,nh); } // New values for expanded const double wpw =r.get_pw(); const double wph =r.get_ph(); const double wtlx=r.get_tl()[0]; const double wtly=r.get_tl()[1]; // now we know the sice of the needed background, create the cairo surface background=cairo_surface_create_similar(cairo_get_target(cr), CAIRO_CONTENT_COLOR_ALPHA, nw, nh); result=cairo_surface_create_similar(cairo_get_target(cr), CAIRO_CONTENT_COLOR_ALPHA, w, h); // render the background cairo_t* subcr=cairo_create(background); cairo_scale(subcr, 1/wpw, 1/wph); cairo_translate(subcr, -wtlx, -wtly); if(!context.accelerated_cairorender(subcr,quality,r,cb)) { synfig::warning("Cairo SphereDistort: Layer below failed"); return false; } cairo_destroy(subcr); //now distort and check to make sure we aren't overshooting our bounds here Point sample = tl, sub = tl, trans(0,0); float xs = 0,ys = 0; int y=0,x=0; Real invpw = 1/pw, invph = 1/ph; Point rtl = r.get_tl(); CairoSurface cresult(result); if(!cresult.map_cairo_image()) { synfig::warning("Sphere Distort: map cairo surface failed"); return false; } CairoSurface cbackground(background); if(!cbackground.map_cairo_image()) { synfig::warning("Sphere Distort: map cairo surface failed"); return false; } for(y = 0; y < h; ++y, sample[1] += ph) { sub = sample; for(x = 0; x < w; ++x, sub[0] += pw) { bool clipped; trans=sphtrans(sub,center,radius,percent,type,clipped); if(clip && clipped) { cresult[y][x]=CairoColor::alpha(); continue; } xs = (trans[0]-rtl[0])*invpw; ys = (trans[1]-rtl[1])*invph; if(!(xs >= 0 && xs < nw && ys >= 0 && ys < nh)) { cresult[y][x]=context.get_cairocolor(trans).premult_alpha(); continue; } //sample at that pixel location based on the quality if(quality <= 4) // cubic cresult[y][x]=cbackground.cubic_sample_cooked(xs, ys).premult_alpha(); else if(quality <= 5) // cosine cresult[y][x]=cbackground.cosine_sample_cooked(xs, ys).premult_alpha(); else if(quality <= 6) // linear cresult[y][x]=cbackground.linear_sample_cooked(xs, ys).premult_alpha(); else // nearest cresult[y][x]=cbackground[round_to_int(ys)][round_to_int(xs)].premult_alpha(); } } cresult.unmap_cairo_image(); cbackground.unmap_cairo_image(); cairo_surface_destroy(background); cairo_save(cr); cairo_translate(cr, tl[0], tl[1]); cairo_scale(cr, pw, ph); cairo_set_source_surface(cr, result, 0, 0); cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); cairo_paint(cr); cairo_restore(cr); cairo_surface_destroy(result); return true; }
int main ( int argc, char **argv ) { printf("argc:%d, argv[0]:%s\n",argc,argv[0]); assert(argc>=2); char* filename = argv[1]; int contourType = CV_RETR_EXTERNAL; if(argc==3 && argv[2][0]=='T'){ contourType = CV_RETR_TREE; } Mat imgRGB = imread(filename); Mat imgGrey = imread(filename,0); if(imgGrey.empty()){ cout << "No valid filename for the image"<<endl; return -1; } Mat imgCanny; Mat imgDil; Mat imgErode; //blur( imgGrey, imgGrey, Size(2,2) ); Canny(imgGrey,imgCanny,60,150,3); // clear image hearder imgCanny(Range(0,19), Range::all()).setTo(0); namedWindow("test", CV_WINDOW_AUTOSIZE ); imshow("test",imgCanny); Mat se90 = getStructuringElement( MORPH_RECT,Size(7,1),Point(2,0)); Mat se0 = getStructuringElement( MORPH_RECT,Size(1,5),Point(0,3)); dilate(imgCanny,imgDil,se90); dilate(imgDil,imgDil,se0); namedWindow("canny", CV_WINDOW_AUTOSIZE ); imshow( "canny", imgCanny ); namedWindow("dilate", CV_WINDOW_AUTOSIZE ); imshow( "dilate", imgDil ); //cvFloodFill Mat seD = getStructuringElement( MORPH_CROSS,Size(3,3),Point(1,1)); erode(imgDil,imgErode,seD); erode(imgErode,imgErode,seD); int height = imgErode.rows; int width = imgErode.cols; /*cout<<"rows:"<<width<<" cols:"<<height << endl; imgErode.col(0).setTo(255); imgErode.col(width-1).setTo(255); imgErode.row(height-1).setTo(255);*/ namedWindow("erode", CV_WINDOW_AUTOSIZE ); imshow( "erode", imgErode); vector<vector<Point> > v; vector<Vec4i> hierarchy; findContours(imgErode, v, hierarchy, contourType, CV_CHAIN_APPROX_SIMPLE); vector<vector<Point> > contours_poly(v.size()); vector<Rect> outputRect; for(int i = 0; i < v.size(); i++) { //printf("%d,%d\n", v[i][0].x, v[i][0].y); //approxPolyDP( Mat(v[i]), contours_poly[i], 3, true ); Rect rect = boundingRect(Mat(v[i])); if(rect.area()>20&&rect.height>3){ cout<<rect.area()<<endl; outputRect.push_back(rect); Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) ); // Draws the rect in the original image and show it rectangle(imgRGB, rect.tl(), rect.br(), color,2,8, 0); } } namedWindow("result", CV_WINDOW_AUTOSIZE ); imshow( "result", imgRGB); cout << "output Rectangle"<< endl; for(int i = 0; i < outputRect.size(); i++){ Rect rect = outputRect[i]; printf("x:%d y:%d w:%d h:%d\n",rect.x,rect.y,rect.width,rect.height); } cvWaitKey(0); return 0; }
Point MotionDetection::GetRectangleCenter(Rect rect) { return Point((rect.br().x + rect.tl().x)/2, (rect.br().y + rect.tl().y)/2); }
void ToolLoopManager::calculateDirtyArea(const gfx::Rect& strokeBounds) { // Save the current dirty area if it's needed Region prevDirtyArea; if (m_toolLoop->getTracePolicy() == TracePolicy::Last) prevDirtyArea = m_dirtyArea; // Start with a fresh dirty area m_dirtyArea.clear(); if (!strokeBounds.isEmpty()) { // Expand the dirty-area with the pen width Rect r1, r2; m_toolLoop->getPointShape()->getModifiedArea( m_toolLoop, strokeBounds.x, strokeBounds.y, r1); m_toolLoop->getPointShape()->getModifiedArea( m_toolLoop, strokeBounds.x+strokeBounds.w-1, strokeBounds.y+strokeBounds.h-1, r2); m_dirtyArea.createUnion(m_dirtyArea, Region(r1.createUnion(r2))); } // Apply offset mode Point offset(m_toolLoop->getOffset()); m_dirtyArea.offset(-offset); // Merge new dirty area with the previous one (for tools like line // or rectangle it's needed to redraw the previous position and // the new one) if (m_toolLoop->getTracePolicy() == TracePolicy::Last) m_dirtyArea.createUnion(m_dirtyArea, prevDirtyArea); // Apply tiled mode TiledMode tiledMode = m_toolLoop->getTiledMode(); if (tiledMode != TiledMode::NONE) { int w = m_toolLoop->sprite()->width(); int h = m_toolLoop->sprite()->height(); Region sprite_area(Rect(0, 0, w, h)); Region outside; outside.createSubtraction(m_dirtyArea, sprite_area); switch (tiledMode) { case TiledMode::X_AXIS: outside.createIntersection(outside, Region(Rect(-w*10000, 0, w*20000, h))); break; case TiledMode::Y_AXIS: outside.createIntersection(outside, Region(Rect(0, -h*10000, w, h*20000))); break; } Rect outsideBounds = outside.bounds(); if (outsideBounds.x < 0) outside.offset(w * (1+((-outsideBounds.x) / w)), 0); if (outsideBounds.y < 0) outside.offset(0, h * (1+((-outsideBounds.y) / h))); int x1 = outside.bounds().x; while (true) { Region in_sprite; in_sprite.createIntersection(outside, sprite_area); outside.createSubtraction(outside, in_sprite); m_dirtyArea.createUnion(m_dirtyArea, in_sprite); outsideBounds = outside.bounds(); if (outsideBounds.isEmpty()) break; else if (outsideBounds.x+outsideBounds.w > w) outside.offset(-w, 0); else if (outsideBounds.y+outsideBounds.h > h) outside.offset(x1-outsideBounds.x, -h); else break; } } }
//found the human body in the frame and return the foundRect as vector //The parameter Mat frame will be drawen on several rectangles void MotionDetection::PeopleDetectByHOG( Mat frame , Mat mask, double ScaleFactor, HOGDescriptor hog) { Mat frameCopy = frame.clone(); resize(frameCopy, frameCopy, Size(), ScaleFactor, ScaleFactor, INTER_AREA); cout << frameCopy.size() << endl; // imshow("test1",frameCopy); vector<Rect> found, found_filtered; //do detection //if the size of src image is too small, the program will be error as assertion fault hog.detectMultiScale(frameCopy, found, 0, Size(8,8), Size(32,32), 1.05, 2); // hog.detectMultiScale(frameCopy, found); //remove nested rectangle size_t i, j; for( i = 0; i < found.size(); i++ ) { Rect r = found[i]; for( j = 0; j < found.size(); j++ ) if( j != i && (r & found[j]) == r) break; if( j == found.size() ) found_filtered.push_back(r); } Mat drawing = Mat::zeros(frameCopy.size(),CV_8UC1); for( i = 0; i < found_filtered.size(); i++ ) { Rect r = found_filtered[i]; // the HOG detector returns slightly larger rectangles than the real objects. // so we slightly shrink the rectangles to get a nicer output. // r.x += cvRound(r.width*0.1); // r.width = cvRound(r.width*0.8); // r.y += cvRound(r.height*0.07); // r.height = cvRound(r.height*0.8); r = Rect_AdjustSizeAroundCenter(r,0.55,0.8); //rectangle(frame, r.tl(), r.br(), cv::Scalar(0,255,0), 1); //rectangle(img, r.tl(), r.br(), cv::Scalar(0,255,0), 1); // int tlx = r.tl().x, tly = r.tl().y; // for(int j = tlx; j < (tlx + r.width) ; j++) // { // for(int ii = tly; ii < (tly + r.height); ii++) // { // frameCopy_mask.at<uchar>(Point(j,ii)) = 255; // } // } rectangle( drawing, r.tl(), r.br(), Scalar(255,255,255), -1, 8, 0); } // imshow("test2",drawing); //recover to the original size resize(drawing, drawing, Size(), 1/ScaleFactor, 1/ScaleFactor, INTER_NEAREST); if(option_str == "-h") { static int counter = 0; String output_str = outPut_Mask_Path + NumberToString(++counter) + ".png"; imwrite(output_str, drawing); } //add the new mask on the final mask //!!problem: the convert between float and int will affect the size of video resolution //After doing the convert from float to int, the new video resolution must be smaller than //the orginal one, which is beacuse we always do the downScale; therefore, we use the smaller //size as the counter in order not to encounter the array problem for(int i = 0; i < drawing.cols; i ++) { for(int j = 0; j < drawing.rows; j++) { Point p = Point(i,j); if(drawing.at<uchar>(p) == 255) mask.at<uchar>(p) += mask_add_step; } } // imshow("test3",mask); }
void UITextEdit::update(bool focusCursor) { if(!m_updatesEnabled) return; std::string text = getDisplayedText(); m_drawText = text; int textLength = text.length(); // prevent glitches if(m_rect.isEmpty()) return; // map glyphs positions Size textBoxSize; const std::vector<Point>& glyphsPositions = m_font->calculateGlyphsPositions(text, m_textAlign, &textBoxSize); const Rect *glyphsTextureCoords = m_font->getGlyphsTextureCoords(); const Size *glyphsSize = m_font->getGlyphsSize(); int glyph; // update rect size if(!m_rect.isValid() || m_textHorizontalAutoResize || m_textVerticalAutoResize) { textBoxSize += Size(m_padding.left + m_padding.right, m_padding.top + m_padding.bottom) + m_textOffset.toSize(); Size size = getSize(); if(size.width() <= 0 || (m_textHorizontalAutoResize && !m_textWrap)) size.setWidth(textBoxSize.width()); if(size.height() <= 0 || m_textVerticalAutoResize) size.setHeight(textBoxSize.height()); setSize(size); } // resize just on demand if(textLength > (int)m_glyphsCoords.size()) { m_glyphsCoords.resize(textLength); m_glyphsTexCoords.resize(textLength); } Point oldTextAreaOffset = m_textVirtualOffset; if(textBoxSize.width() <= getPaddingRect().width()) m_textVirtualOffset.x = 0; if(textBoxSize.height() <= getPaddingRect().height()) m_textVirtualOffset.y = 0; // readjust start view area based on cursor position m_cursorInRange = false; if(focusCursor && m_autoScroll) { if(m_cursorPos > 0 && textLength > 0) { assert(m_cursorPos <= textLength); Rect virtualRect(m_textVirtualOffset, m_rect.size() - Size(m_padding.left+m_padding.right, 0)); // previous rendered virtual rect int pos = m_cursorPos - 1; // element before cursor glyph = (uchar)text[pos]; // glyph of the element before cursor Rect glyphRect(glyphsPositions[pos], glyphsSize[glyph]); // if the cursor is not on the previous rendered virtual rect we need to update it if(!virtualRect.contains(glyphRect.topLeft()) || !virtualRect.contains(glyphRect.bottomRight())) { // calculate where is the first glyph visible Point startGlyphPos; startGlyphPos.y = std::max<int>(glyphRect.bottom() - virtualRect.height(), 0); startGlyphPos.x = std::max<int>(glyphRect.right() - virtualRect.width(), 0); // find that glyph for(pos = 0; pos < textLength; ++pos) { glyph = (uchar)text[pos]; glyphRect = Rect(glyphsPositions[pos], glyphsSize[glyph]); glyphRect.setTop(std::max<int>(glyphRect.top() - m_font->getYOffset() - m_font->getGlyphSpacing().height(), 0)); glyphRect.setLeft(std::max<int>(glyphRect.left() - m_font->getGlyphSpacing().width(), 0)); // first glyph entirely visible found if(glyphRect.topLeft() >= startGlyphPos) { m_textVirtualOffset.x = glyphsPositions[pos].x; m_textVirtualOffset.y = glyphsPositions[pos].y - m_font->getYOffset(); break; } } } } else { m_textVirtualOffset = Point(0,0); } m_cursorInRange = true; } else { if(m_cursorPos > 0 && textLength > 0) { Rect virtualRect(m_textVirtualOffset, m_rect.size() - Size(2*m_padding.left+m_padding.right, 0) ); // previous rendered virtual rect int pos = m_cursorPos - 1; // element before cursor glyph = (uchar)text[pos]; // glyph of the element before cursor Rect glyphRect(glyphsPositions[pos], glyphsSize[glyph]); if(virtualRect.contains(glyphRect.topLeft()) && virtualRect.contains(glyphRect.bottomRight())) m_cursorInRange = true; } else { m_cursorInRange = true; } } bool fireAreaUpdate = false; if(oldTextAreaOffset != m_textVirtualOffset) fireAreaUpdate = true; Rect textScreenCoords = m_rect; textScreenCoords.expandLeft(-m_padding.left); textScreenCoords.expandRight(-m_padding.right); textScreenCoords.expandBottom(-m_padding.bottom); textScreenCoords.expandTop(-m_padding.top); m_drawArea = textScreenCoords; if(textScreenCoords.size() != m_textVirtualSize) { m_textVirtualSize = textScreenCoords.size(); fireAreaUpdate = true; } Size totalSize = textBoxSize; if(totalSize.width() < m_textVirtualSize.width()) totalSize.setWidth(m_textVirtualSize.height()); if(totalSize.height() < m_textVirtualSize.height()) totalSize.setHeight(m_textVirtualSize.height()); if(m_textTotalSize != totalSize) { m_textTotalSize = totalSize; fireAreaUpdate = true; } if(m_textAlign & Fw::AlignBottom) { m_drawArea.translate(0, textScreenCoords.height() - textBoxSize.height()); } else if(m_textAlign & Fw::AlignVerticalCenter) { m_drawArea.translate(0, (textScreenCoords.height() - textBoxSize.height()) / 2); } else { // AlignTop } if(m_textAlign & Fw::AlignRight) { m_drawArea.translate(textScreenCoords.width() - textBoxSize.width(), 0); } else if(m_textAlign & Fw::AlignHorizontalCenter) { m_drawArea.translate((textScreenCoords.width() - textBoxSize.width()) / 2, 0); } else { // AlignLeft } for(int i = 0; i < textLength; ++i) { glyph = (uchar)text[i]; m_glyphsCoords[i].clear(); // skip invalid glyphs if(glyph < 32 && glyph != (uchar)'\n') continue; // calculate initial glyph rect and texture coords Rect glyphScreenCoords(glyphsPositions[i], glyphsSize[glyph]); Rect glyphTextureCoords = glyphsTextureCoords[glyph]; // first translate to align position if(m_textAlign & Fw::AlignBottom) { glyphScreenCoords.translate(0, textScreenCoords.height() - textBoxSize.height()); } else if(m_textAlign & Fw::AlignVerticalCenter) { glyphScreenCoords.translate(0, (textScreenCoords.height() - textBoxSize.height()) / 2); } else { // AlignTop // nothing to do } if(m_textAlign & Fw::AlignRight) { glyphScreenCoords.translate(textScreenCoords.width() - textBoxSize.width(), 0); } else if(m_textAlign & Fw::AlignHorizontalCenter) { glyphScreenCoords.translate((textScreenCoords.width() - textBoxSize.width()) / 2, 0); } else { // AlignLeft // nothing to do } // only render glyphs that are after startRenderPosition if(glyphScreenCoords.bottom() < m_textVirtualOffset.y || glyphScreenCoords.right() < m_textVirtualOffset.x) continue; // bound glyph topLeft to startRenderPosition if(glyphScreenCoords.top() < m_textVirtualOffset.y) { glyphTextureCoords.setTop(glyphTextureCoords.top() + (m_textVirtualOffset.y - glyphScreenCoords.top())); glyphScreenCoords.setTop(m_textVirtualOffset.y); } if(glyphScreenCoords.left() < m_textVirtualOffset.x) { glyphTextureCoords.setLeft(glyphTextureCoords.left() + (m_textVirtualOffset.x - glyphScreenCoords.left())); glyphScreenCoords.setLeft(m_textVirtualOffset.x); } // subtract startInternalPos glyphScreenCoords.translate(-m_textVirtualOffset); // translate rect to screen coords glyphScreenCoords.translate(textScreenCoords.topLeft()); // only render if glyph rect is visible on screenCoords if(!textScreenCoords.intersects(glyphScreenCoords)) continue; // bound glyph bottomRight to screenCoords bottomRight if(glyphScreenCoords.bottom() > textScreenCoords.bottom()) { glyphTextureCoords.setBottom(glyphTextureCoords.bottom() + (textScreenCoords.bottom() - glyphScreenCoords.bottom())); glyphScreenCoords.setBottom(textScreenCoords.bottom()); } if(glyphScreenCoords.right() > textScreenCoords.right()) { glyphTextureCoords.setRight(glyphTextureCoords.right() + (textScreenCoords.right() - glyphScreenCoords.right())); glyphScreenCoords.setRight(textScreenCoords.right()); } // render glyph m_glyphsCoords[i] = glyphScreenCoords; m_glyphsTexCoords[i] = glyphTextureCoords; } if(fireAreaUpdate) onTextAreaUpdate(m_textVirtualOffset, m_textVirtualSize, m_textTotalSize); g_app.repaint(); }
double DetectorTester::computeOverlap(Rect a, Rect b) const { double intersectionArea = (a & b).area(); double unionArea = a.area() + b.area() - intersectionArea; return intersectionArea / unionArea; }
void Texture::copyFromScreen(const Rect& screenRect) { bind(); glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, screenRect.x(), screenRect.y(), screenRect.width(), screenRect.height()); }