Logo Search packages:      
Sourcecode: yudit version File versions

void STextView::textChanged ( void *  src,
const STextDataEvent event 
) [private]

This is called by the STextData

Definition at line 807 of file STextView.cpp.

References STextDataEvent::attribute, STextData::getLogicalMap(), STextData::getMaxTextIndex(), STextData::getMinTextIndex(), getTextLocation(), STextIndex::index, STextData::isLR(), STextIndex::line, SBinVector< Type >::size(), STextData::size(), wrapAndPosition(), SLocation::x, and SLocation::y.

{
  /* The whole text has been cleared */
  if (textData.size()==0)
  {
     wrapAndPosition(); 
     SWindow* w = getWindow ();
     if (w)
     {
       /* request a redraw and clear the whole area */
       w->redraw (true, location.x, location.y, size.width, size.height);
     }
     return;
  }
  /* overdraw */
  int odw = (int) lineHeight / 3 + 1; 
  STextIndex tb = textData.getMinTextIndex (event);
  STextIndex te = textData.getMaxTextIndex (event);


  unsigned int oldsize = lineSpan.size();
  unsigned int oldspan = sane_index (lineSpan, oldsize);
  bool oldlr =  textData.isLR(tb.line);

  SV_UINT oldbreaks;


  if (tb.line == te.line && tb.line < oldsize && tb.line < breaks.size())
  {
    /* This is still the old breaks */
    oldbreaks = breaks[tb.line]; 
  }

  /* change in text contents */
  SV_UINT mapBefore = textData.getLogicalMap(tb.line);
  SV_UINT mapAfter = mapBefore;
  if (!event.attribute)
  {
    /* For efficiency, multiline guys will make it only partial */
    if (multiline)
    {
      /* was recalc */
      wrapAndPosition (tb.line, te.line+1, 
         (int)textData.size() - (int) lineSpan.size());
    }
    else
    {
      wrapAndPosition ();
    }
    mapAfter = textData.getLogicalMap(tb.line);
    /* find the highest and visual index */
  }

  SWindow* w = getWindow();
  if (w == 0)
  {
    /* This is a strange place to return - but we needed to rebuild indeces */
    return;
  }

  unsigned int newsize = lineSpan.size();

  unsigned int newspan = sane_index (lineSpan, newsize);
  bool samebreak = false;

  bool newlr =  textData.isLR(tb.line);
  bool drawwholeline = (newlr != oldlr && tb.line == te.line);
  if (tb.line == te.line && tb.line < newsize && tb.line <breaks.size())
  {
    SV_UINT o = oldbreaks;
    SV_UINT n = breaks[tb.line]; 
    samebreak = (o.size() == n.size());
    if (samebreak)
    {
      /* of course it break at the end */
      for (unsigned int i=0; i+1<n.size(); i++)
      {
        /* break changed or it was before the text change */
        /* for attribute break can not change */
        if (!event.attribute && (n[i] != o[i] || tb.index <= n[i])) 
        {
          samebreak = false;
          break;
        }
        /* break is between begin and end */
        if (n[i] >= tb.index && n[i] <= te.index)
        {
          drawwholeline = true;
        }
      }
    }
  }
  if (tb.line == te.line && drawwholeline)
  {
    tb.index = 0;
    te.index = mapAfter.size();
  }

  /* adjust tb te */
  if (tb.line == te.line && !drawwholeline && samebreak)
  {
    unsigned int i;
    /* find out lowest common stuff in map */
    unsigned int min = mapAfter.size() < mapBefore.size()
      ? mapAfter.size() : mapBefore.size();

    /* make logical to visual maps */
    SS_UINT * mapa = new SS_UINT[mapAfter.size()+1];
    CHECK_NEW (mapa);
    for (i=0; i<mapAfter.size(); i++) mapa[i] = mapAfter[i];

    SS_UINT * mapb = new SS_UINT[mapBefore.size()+1];
    CHECK_NEW (mapb);
    for (i=0; i<mapBefore.size(); i++) mapb[i] = mapBefore[i];

    unsigned int lowestvis = min;
    for (i=0; i<min; i++)
    {
      if (mapb[i] != mapa[i])
      {
        tb.index = mapa[i];
        lowestvis = i;
        break;
      }
      /* at least from here it changed yeah... */
      if (mapa[i] == tb.index)
      {
        lowestvis = i;
        break;
      }
    }
    if (i==0)
    {
      if (mapAfter.size()> 0)
      {
        tb.index = mapAfter[0];
      }
      else
      {
        tb.index = 0;
      }
     lowestvis=0;
    }
    /* find out if there is something between zero and lowes vis */
    for (i=0; i<lowestvis; i++)
    {
      /* we can have one glyph difference  */
      if (mapa[i]+1 >= tb.index)
      {
        tb.index = mapa[i];
        lowestvis = i;
        break;
      }
    }
    // if still between lowest and end there is a lower index, take 0.
    for (i=lowestvis; i<mapAfter.size(); i++)
    {
      if (mapa[i] <= tb.index)
      {
        /* find the smallest */
        unsigned int smallest = mapa[i];
        while (++i < mapAfter.size())
        {
           if (mapa[i] < smallest) smallest = mapa[i];
        }
        if (smallest > 0) smallest--;
        tb.index = smallest; 
        break;
      }
    }
   
    /* for attribute te.index is also used and mapafter = mapbefore */
    if (event.attribute && te.index < mapAfter.size())
    {
      unsigned int vis = mapAfter[te.index];
      unsigned int max = mapAfter.size();
      for (i=mapAfter.size(); i>vis; i--)
      {
        if (mapa[i-1] < te.index)
        {
          te.index= max;
          break;
        }
        max = mapa[i-1];
      }
    }
    else
    {
      te.index = mapAfter.size();
    }
    delete [] mapa;
    delete [] mapb;
  }

  SLocation lb = getTextLocation (tb);
  SLocation le = getTextLocation (te);

  /*
   * Get smallest and biggest. 
   */
  if (tb.line == te.line && samebreak && le.y == lb.y)
  {
    if (le.x < lb.x)
    {
       int tmp = lb.x; lb.x = le.x; le.x = tmp;
    }
    for (unsigned int i=tb.index; i<=te.index; i++)
    {
      SLocation l = getTextLocation (STextIndex(tb.line, i));
      if (l.x < lb.x) lb = l;
      if (l.x > le.x) le = l;
      l = getTextLocation (STextIndex(tb.line, i), false);
      if (l.x < lb.x) lb = l;
      if (l.x > le.x) le = l;
    }
  }

//fprintf (stderr, "lb.x =%d, le.x=%u\n", lb.x, le.x);
  /* make sure we are inside the window */
  if (lb.y + (int)lineHeight < 0) lb.y = -(int)lineHeight;
  if (le.y > location.y + (int)size.height) le.y =  size.height + location.y;

  /* Text content did not change, only the attribute */

  int starty = (lb.y > 5) ? lb.y - odw: 0;
  unsigned int lheight = lineHeight + 2*odw;

  if (event.attribute)
  {
    /* single */
    if (lb.y == le.y && samebreak)
    {
      /* we add 1 to make sure it is non-null positive */
      w->redraw (true, lb.x-odw, starty, (unsigned int) (le.x-lb.x)+2*odw, lheight);
    }
    else // multiline - redraw whole thing.
    {
      le = getTextLocation (STextIndex (te.line, textData.size(te.line)));
      if (lb.y < le.y) /* always */
      {
        w->redraw (true, location.x, starty, 
                size.width, lheight + (unsigned int)(le.y-lb.y));
      }
      else /* I dont know what happened - redraw */
      {
        w->redraw (true, location.x, location.y, size.width, size.height);
      }
    }
    return;
  }

  /* Change is inside a single paragraph */
  if (tb.line == te.line && oldsize == newsize && oldspan == newspan)
  {
    /* The whole change is on the same line (breaks did not change)  */
    if (lb.y == le.y && samebreak)
    {
      bool lrline  = textData.isLR (tb.line);
      int wid = 0;
      if (lrline)
      {
         //lb.x = lb.x;
         wid = (int) size.width; /* till end of line */
      }
      else
      {
         lb.x = 0;
         wid = le.x + location.x;
      }
      /* redraw till end of line */
      w->redraw (true, lb.x-odw, starty, (unsigned int) wid + 2*odw, lheight);
    }
    else /* This is a multi-line paragraph change. redraw till end */
    {
      le = getTextLocation (STextIndex (te.line, textData.size(te.line)));
      if (le.y > lb.y) /* always */
      {
        w->redraw (true, location.x, starty, 
            size.width, lheight + (unsigned int)(le.y-lb.y));
      }
      else /* I dont know what happened - redraw */
      {
        w->redraw (true, location.x, location.y, size.width, size.height);
      }
      
    }
    return;
  }
  /* Multi-paragraph change. Is it visible? */
  if (starty < location.y + (int) size.height)
  {
    w->redraw (true, location.x, starty, 
        size.width, location.y + (int)size.height - starty);
  }
}


Generated by  Doxygen 1.6.0   Back to index