void ChangeScreenSize(int wi, int he, int change_fore) { struct win *p; struct canvas *cv; int wwi; debug2("ChangeScreenSize from (%d,%d) ", D_width, D_height); debug3("to (%d,%d) (change_fore: %d)\n",wi, he, change_fore); cv = &D_canvas; cv->c_xe = wi - 1; cv->c_ys = (D_has_hstatus == HSTATUS_FIRSTLINE); cv->c_ye = he - 1 - ((cv->c_slperp && cv->c_slperp->c_slnext) || captionalways) - (D_has_hstatus == HSTATUS_LASTLINE); cv->c_blank.l_height = cv->c_ye - cv->c_ys + 1; if (cv->c_slperp) { ResizeCanvas(cv); RecreateCanvasChain(); RethinkDisplayViewports(); } if (D_forecv == 0) D_forecv = D_cvlist; if (D_forecv) D_fore = Layer2Window(D_forecv->c_layer); D_width = wi; D_height = he; CheckMaxSize(wi); if (D_CWS) { D_defwidth = D_CO; D_defheight = D_LI; } else { if (D_CZ0 && (wi == Z0width || wi == Z1width) && (D_CO == Z0width || D_CO == Z1width)) D_defwidth = D_CO; else D_defwidth = wi; D_defheight = he; } debug2("Default size: (%d,%d)\n", D_defwidth, D_defheight); if (change_fore) ResizeLayersToCanvases(); if (change_fore == 2 && D_CWS == NULL && displays->d_next == 0) { /* adapt all windows - to be removed ? */ for (p = windows; p; p = p->w_next) { debug1("Trying to change window %d.\n", p->w_number); wwi = wi; if (p->w_savelayer && p->w_savelayer->l_cvlist == 0) ResizeLayer(p->w_savelayer, wwi, he, 0); } } }
void ResizeLayersToCanvases() { Canvas *cv; Layer *l; int lx, ly; D_kaablamm = 0; for (cv = D_cvlist; cv; cv = cv->c_next) { l = cv->c_layer; if (l == 0) continue; if (l->l_width == cv->c_xe - cv->c_xs + 1 && l->l_height == cv->c_ye - cv->c_ys + 1) { continue; } if (MayResizeLayer(l)) { ResizeLayer(l, cv->c_xe - cv->c_xs + 1, cv->c_ye - cv->c_ys + 1, display); } /* normalize window, see screen.c */ lx = cv->c_layer->l_x; ly = cv->c_layer->l_y; if (ly + cv->c_yoff < cv->c_ys) { cv->c_yoff = cv->c_ys - ly; RethinkViewportOffsets(cv); } else if (ly + cv->c_yoff > cv->c_ye) { cv->c_yoff = cv->c_ye - ly; RethinkViewportOffsets(cv); } if (lx + cv->c_xoff < cv->c_xs) { int n = cv->c_xs - (lx + cv->c_xoff); if (n < (cv->c_xe - cv->c_xs + 1) / 2) n = (cv->c_xe - cv->c_xs + 1) / 2; if (cv->c_xoff + n > cv->c_xs) n = cv->c_xs - cv->c_xoff; cv->c_xoff += n; RethinkViewportOffsets(cv); } else if (lx + cv->c_xoff > cv->c_xe) { int n = lx + cv->c_xoff - cv->c_xe; if (n < (cv->c_xe - cv->c_xs + 1) / 2) n = (cv->c_xe - cv->c_xs + 1) / 2; if (cv->c_xoff - n + cv->c_layer->l_width - 1 < cv->c_xe) n = cv->c_xoff + cv->c_layer->l_width - 1 - cv->c_xe; cv->c_xoff -= n; RethinkViewportOffsets(cv); } } Redisplay(0); if (D_kaablamm) { kaablamm(); D_kaablamm = 0; } }
void ChangeScreenSize(int wi, int he, int change_fore) { Window *p; Canvas *cv; int wwi; cv = &D_canvas; cv->c_xe = wi - 1; cv->c_ys = ((cv->c_slperp && cv->c_slperp->c_slnext) || captionalways) * captiontop + (D_has_hstatus == HSTATUS_FIRSTLINE); cv->c_ye = he - 1 - ((cv->c_slperp && cv->c_slperp->c_slnext) || captionalways) * !captiontop - (D_has_hstatus == HSTATUS_LASTLINE); cv->c_blank.l_height = cv->c_ye - cv->c_ys + 1; if (cv->c_slperp) { ResizeCanvas(cv); RecreateCanvasChain(); RethinkDisplayViewports(); } if (D_forecv == 0) D_forecv = D_cvlist; if (D_forecv) D_fore = Layer2Window(D_forecv->c_layer); D_width = wi; D_height = he; CheckMaxSize(wi); if (D_CWS) { D_defwidth = D_CO; D_defheight = D_LI; } else { if (D_CZ0 && (wi == Z0width || wi == Z1width) && (D_CO == Z0width || D_CO == Z1width)) D_defwidth = D_CO; else D_defwidth = wi; D_defheight = he; } if (change_fore) ResizeLayersToCanvases(); if (change_fore == 2 && D_CWS == NULL && displays->d_next == 0) { /* adapt all windows - to be removed ? */ for (p = windows; p; p = p->w_next) { wwi = wi; if (p->w_savelayer && p->w_savelayer->l_cvlist == 0) ResizeLayer(p->w_savelayer, wwi, he, 0); } } }
bool GuillotineImageAtlas::Insert(const Image& image, Rectui* rect, bool* flipped, unsigned int* layerIndex) { if (m_layers.empty()) // On créé une première couche s'il n'y en a pas m_layers.resize(1); // Cette fonction ne fait qu'insérer un rectangle de façon virtuelle, l'insertion des images se fait après for (unsigned int i = 0; i < m_layers.size(); ++i) { Layer& layer = m_layers[i]; // Une fois qu'un certain nombre de rectangles ont étés libérés d'une couche, on fusionne les rectangles libres if (layer.freedRectangles > 10) // Valeur totalement arbitraire { while (layer.binPack.MergeFreeRectangles()); // Tant qu'une fusion est possible layer.freedRectangles = 0; // Et on repart de zéro } if (layer.binPack.Insert(rect, flipped, 1, false, m_rectChoiceHeuristic, m_rectSplitHeuristic)) { // Insertion réussie dans l'une des couches, on place le glyphe en file d'attente layer.queuedGlyphs.resize(layer.queuedGlyphs.size()+1); QueuedGlyph& glyph = layer.queuedGlyphs.back(); glyph.flipped = *flipped; glyph.image = image; // Merci le Copy-On-Write glyph.rect = *rect; *layerIndex = i; return true; } else if (i == m_layers.size() - 1) // Dernière itération ? { // Dernière couche, et le glyphe ne rentre pas, peut-on agrandir la taille de l'image ? Vector2ui newSize = layer.binPack.GetSize()*2; if (newSize == Vector2ui::Zero()) newSize.Set(s_atlasStartSize); if (ResizeLayer(layer, newSize)) { // Oui on peut ! layer.binPack.Expand(newSize); // On ajuste l'atlas virtuel // Et on relance la boucle sur la nouvelle dernière couche i--; } else { // On ne peut plus agrandir la dernière couche, il est temps d'en créer une nouvelle newSize.Set(s_atlasStartSize); Layer newLayer; if (!ResizeLayer(newLayer, newSize)) { // Impossible d'allouer une nouvelle couche, nous manquons probablement de mémoire (ou le glyphe est trop grand) NazaraError("Failed to allocate new layer, we are probably out of memory"); return false; } newLayer.binPack.Reset(newSize); m_layers.emplace_back(std::move(newLayer)); // Insertion du layer // On laisse la boucle insérer toute seule le rectangle à la prochaine itération } } } NazaraInternalError("Unknown error"); // Normalement on ne peut pas arriver ici return false; }