예제 #1
0
파일: resize.c 프로젝트: skoneka/screen
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);
        }
    }
}
예제 #2
0
파일: resize.c 프로젝트: amade/screen
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;
    }
}
예제 #3
0
파일: resize.c 프로젝트: amade/screen
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);
        }
    }
}
예제 #4
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;
	}