예제 #1
0
/* ------------------------------------ *
 *  Functions which updates the display *
 * ------------------------------------ */
void OptimizedPrint(LONG x, struct line_node *line, LONG line_nr, LONG width, struct InstData *data)
{
  ENTER();

  do
  {
    LONG twidth;

    twidth = PrintLine(x, line, line_nr, TRUE, data);
    line_nr++;

    if(twidth != width && x+twidth < (LONG)line->line.Length && line_nr <= data->maxlines)
    {
      x += twidth;
      width = LineCharsWidth(line->line.Contents+x+width, data) + width - twidth;
    }
    else
      break;
  }
  while(TRUE);

  LEAVE();
}
예제 #2
0
LONG PrintLine(LONG x, struct line_node *line, LONG line_nr, BOOL doublebuffer, struct InstData *data)
{
  STRPTR text = line->line.Contents;
  LONG length;
  struct RastPort *rp = &data->doublerp;

  ENTER();

  length  = LineCharsWidth(text+x, data);

  if(doublebuffer == FALSE)
    rp = &data->copyrp;

  if((line_nr > 0) && (data->update) && !(data->flags & FLG_Quiet) && data->rport != NULL && data->shown == TRUE)
  {
    LONG c_length = length;
    LONG startx = 0, stopx = 0;
    LONG starty = 0, xoffset = ((data->height-rp->TxBaseline+1)>>1)+1;
    LONG flow = 0;
    UWORD *styles = line->line.Styles;
    UWORD *colors = line->line.Colors;
    struct marking block;
    BOOL cursor = FALSE;

    if(line->line.Color && x == 0 && line->line.Length == 1)
      line->line.Color = FALSE;

    if(doublebuffer == FALSE)
    {
      starty = data->ypos+(data->height * (line_nr-1));
      xoffset = data->xpos;
    }

    flow = FlowSpace(line->line.Flow, text+x, data);
    Move(rp, xoffset+flow, starty+rp->TxBaseline);

    if(Enabled(data))
    {
      struct line_node *blkline;

      NiceBlock(&data->blockinfo, &block);

      blkline = block.startline->next;

      if(block.startline == block.stopline)
      {
        if(block.startline == line)
        {
          startx = block.startx;
          stopx = block.stopx;
        }
      }
      else
      {
        if(block.startline == line)
        {
          startx = block.startx;
          stopx = line->line.Length;
        }
        else
        {
          if(block.stopline == line)
          {
            stopx = block.stopx;
          }
          else
          {
            while((blkline != block.stopline) && (!stopx))
            {
              if(blkline == line)
              {
                stopx = line->line.Length;
              }
              blkline = blkline->next;
            }
          }
        }
      }
    }

    {
      UWORD blockstart = 0;
      UWORD blockwidth = 0;
      struct RastPort *old = muiRenderInfo(data->object)->mri_RastPort;

      if(startx < x+c_length && stopx > x)
      {
        if(startx > x)
          blockstart = TextLength(&data->tmprp, text+x, startx-x);
        else
          startx = x;

        blockwidth = ((stopx >= c_length+x) ? data->innerwidth-(blockstart+flow) : TextLength(&data->tmprp, text+startx, stopx-startx));
      }
      else if(!(data->flags & (FLG_ReadOnly | FLG_Ghosted)) &&
              line == data->actualline && data->CPos_X >= x &&
              data->CPos_X < x+c_length && !Enabled(data) &&
              (data->flags & FLG_Active || data->inactiveCursor == TRUE))
      {
        cursor = TRUE;
        blockstart = TextLength(&data->tmprp, text+x, data->CPos_X-x);

        // calculate the cursor width
        // if it is set to 6 then we should find out how the width of the current char is
        if(data->CursorWidth == 6)
          blockwidth = TextLength(&data->tmprp, (*(text+data->CPos_X) < ' ') ? (char *)" " : (char *)(text+data->CPos_X), 1);
        else
          blockwidth = data->CursorWidth;
      }

      SetDrMd(rp, JAM1);
      muiRenderInfo(data->object)->mri_RastPort = rp;

      // clear the background first
      DoMethod(data->object, MUIM_DrawBackground, xoffset, starty,
                                                  flow+blockstart, data->height,
                                                  (data->flags & FLG_InVGrp) ? 0 : data->xpos,
                                                  (data->flags & FLG_InVGrp) ? data->height*(data->visual_y+line_nr-2) : data->realypos+data->height * (data->visual_y+line_nr-2),
                                                  0);

      if(blockwidth)
      {
        ULONG color;

        // in case the gadget is in inactive state we use a different background
        // color for our selected area
        if((data->flags & FLG_Active) == 0 && (data->flags & FLG_Activated) == 0 &&
           (data->flags & FLG_ActiveOnClick) != 0)
        {
          color = data->inactivecolor;
        }
        else
          color = data->markedcolor;

        // if selectmode == 2 then a whole line should be drawn as being marked, so
        // we have to start at xoffset instead of xoffset+flow+blockstart.
        // Please note that the second part of the following "empiric" evaluation should
        // prevent that centered or right aligned lines are not correctly marked right
        // from the beginning of the line. However, it seems to be not cover 100% of all different
        // cases so that the evaluation if a line should be completely marked should be probably
        // moved elsewhere in future.
        if(data->selectmode == 2 ||
           (flow && data->selectmode != 1 && startx-x == 0 && cursor == FALSE &&
            ((data->blockinfo.startline != data->blockinfo.stopline) || x > 0)))
        {
          SetAPen(rp, color);
          RectFill(rp, xoffset, starty, xoffset+flow+blockwidth-1, starty+data->height-1);
        }
        else
        {
          SetAPen(rp, cursor ? data->cursorcolor : color);
          RectFill(rp, xoffset+flow+blockstart, starty, xoffset+flow+blockstart+blockwidth-1, starty+data->height-1);

          // if the gadget is in inactive state we just draw a skeleton cursor instead
          if(cursor == TRUE &&
             (data->flags & FLG_Active) == 0 && (data->flags & FLG_Activated) == 0)
          {
            DoMethod(data->object, MUIM_DrawBackground, xoffset+flow+blockstart+1, starty+1,
                                                        blockwidth-2, data->height-2,
                                                        (data->flags & FLG_InVGrp) ? 0 : data->xpos,
                                                        (data->flags & FLG_InVGrp) ? data->height*(data->visual_y+line_nr-2) : data->realypos+data->height * (data->visual_y+line_nr-2),
                                                        0);
          }
        }
      }


      {
        LONG  x_start = xoffset+blockstart+blockwidth,
            y_start = starty,
            x_width = data->innerwidth-(blockstart+blockwidth),
            y_width = data->height,
            x_ptrn = blockstart+blockwidth,
            y_ptrn = data->height*(data->visual_y+line_nr-2);

        if(blockwidth)
        {
          x_start += flow;
          x_width -= flow;
          x_ptrn += flow;
        }
        if(!(data->flags & FLG_InVGrp))
        {
          x_ptrn += data->xpos;
          y_ptrn += data->realypos;
        }

        DoMethod(data->object, MUIM_DrawBackground, x_start, y_start, x_width, y_width, x_ptrn, y_ptrn);
      }
      muiRenderInfo(data->object)->mri_RastPort = old;
    }

    if(doublebuffer == FALSE)
      AddClipping(data);

    SetAPen(rp, (line->line.Color ? data->highlightcolor : data->textcolor));

    while(c_length)
    {
      LONG p_length = c_length;

      SetSoftStyle(rp, convert(GetStyle(x, line)), AskSoftStyle(rp));
      if(styles)
      {
        while(*styles-1 <= x)
        {
          styles += 2;
        }
        if(*styles-x-1 < p_length)
        {
          p_length = *styles-x-1;
        }
      }

      if(colors)
      {
        while(*colors-1 <= x)
        {
          SetAPen(rp, ConvertPen(*(colors+1), line->line.Color, data));
          colors += 2;
        }
        if(*colors-x-1 < p_length)
        {
          p_length = *colors-x-1;
        }
      }

/*      if(stopx)
      {
        if((startx > x) && (startx-x < p_length))
        {
          p_length = startx-x;
          SetAPen(rp, 3);
        }
        else
        {
          if((stopx > x) && (stopx-x < p_length))
          {
            p_length = stopx-x;
            SetAPen(rp, 4);
          }
          else
            SetAPen(rp, (line->color ? data->highlightcolor : data->textcolor));
        }
      }
*/

      if(text[x+p_length-1] < ' ')
        Text(rp, text+x, p_length-1);
      else
        Text(rp, text+x, p_length);

      x += p_length;
      c_length -= p_length;
    }
    SetSoftStyle(rp, FS_NORMAL, AskSoftStyle(rp));

    if(line->line.Separator)
    {
        WORD  LeftX, LeftWidth,
            RightX, RightWidth,
            Y, Height;

      LeftX = xoffset;
      LeftWidth = flow-3;
      RightX = rp->cp_x+3;
      RightWidth = xoffset+data->innerwidth - RightX;
      Y = starty;
      Height = (line->line.Separator & LNSF_Thick) ? 2 : 1;

      if(line->line.Separator & LNSF_Middle)
        Y += (data->height/2)-Height;
      else
      {
        if(line->line.Separator & LNSF_Bottom)
          Y += data->height-(2*Height);
      }

      if(line->line.Separator & LNSF_StrikeThru || line->line.Length == 1)
      {
        LeftWidth = data->innerwidth;
      }
      else
      {
        DrawSeparator(rp, RightX, Y, RightWidth, Height, data);
      }
      DrawSeparator(rp, LeftX, Y, LeftWidth, Height, data);
    }


    if(data->flags & FLG_Ghosted)
    {
      UWORD *oldPattern = (UWORD *)rp->AreaPtrn;
      UBYTE oldSize = rp->AreaPtSz;
      UWORD newPattern[] = {0x1111, 0x4444};

      if(doublebuffer == TRUE)
      {
        ULONG ptrn1 = 0x11111111;
        ULONG ptrn2 = 0x44444444;

        ptrn1 = ptrn1>>((data->xpos-xoffset)%16);
        ptrn2 = ptrn2>>((data->xpos-xoffset)%16);

        if((data->height*(data->visual_y+line_nr-2))%2 == 0)
        {
          newPattern[0] = ptrn2;
          newPattern[1] = ptrn1;
        }
        else
        {
          newPattern[0] = ptrn1;
          newPattern[1] = ptrn2;
        }
      }
예제 #3
0
/*--------------------------*
 * Merge two lines into one *
 *--------------------------*/
BOOL MergeLines(struct line_node *line, struct InstData *data)
{
  struct line_node *next;
  char  *newbuffer;
  LONG  visual, oldvisual, line_nr;
  LONG  emptyline = FALSE;
  LONG  color = line->line.Color;
  UWORD flow = line->line.Flow;
  UWORD separator = line->line.Separator;

  ENTER();

  data->HasChanged = TRUE;
  if(line->line.Length == 1)
  {
    emptyline = TRUE;
    color = line->next->line.Color;
    flow = line->next->line.Flow;
    separator = line->next->line.Separator;
  }
  visual = line->visual + line->next->visual;

  if((newbuffer = MyAllocPooled(data->mypool, line->line.Length+line->next->line.Length+1)) != NULL)
  {
    memcpy(newbuffer, line->line.Contents, line->line.Length-1);
    memcpy(newbuffer+line->line.Length-1, line->next->line.Contents, line->next->line.Length+1);
    MyFreePooled(data->mypool, line->line.Contents);
    MyFreePooled(data->mypool, line->next->line.Contents);

    if(emptyline == TRUE)
    {
      if(line->line.Styles != NULL)
        MyFreePooled(data->mypool, line->line.Styles);

      line->line.Styles = line->next->line.Styles;

      if(line->line.Colors != NULL)
        MyFreePooled(data->mypool, line->line.Colors);

      line->line.Colors = line->next->line.Colors;
    }
    else
    {
      UWORD *styles;
      UWORD *styles1 = line->line.Styles;
      UWORD *styles2 = line->next->line.Styles;
      UWORD *colors;
      UWORD *colors1 = line->line.Colors;
      UWORD *colors2 = line->next->line.Colors;
      UWORD length = 12;

      if(styles1 != NULL)
        length += *((long *)styles1-1) - 4;
      if(styles2 != NULL)
        length += *((long *)styles2-1) - 4;

      if((styles = MyAllocPooled(data->mypool, length)) != NULL)
      {
        unsigned short* t_styles = styles;
        unsigned short  style = 0;

        SHOWVALUE(DBF_CLIPBOARD, length);
        SHOWVALUE(DBF_CLIPBOARD, styles);
        SHOWVALUE(DBF_CLIPBOARD, styles1);
        SHOWVALUE(DBF_CLIPBOARD, styles2);

        if(styles2 != NULL)
        {
          unsigned short* t_styles2 = styles2;

          while(*t_styles2++ == 1)
          {
            if(*t_styles2 > 0xff)
              style &= *t_styles2++;
            else
              style |= *t_styles2++;
          }
        }

        if(styles1 != NULL)
        {
          while(*styles1 != EOS)
          {
            if((*styles1 == line->line.Length) && ((~*(styles1+1) & style) == (*(styles1+1)  ^ 0xffff)))
            {
              style &= *(styles1+1);
              styles1 += 2;
            }
            else
            {
              *styles++ = *styles1++;
              *styles++ = *styles1++;
            }
          }
          SHOWVALUE(DBF_CLIPBOARD, line->line.Styles);
          MyFreePooled(data->mypool, line->line.Styles);
        }

        if(styles2 != NULL)
        {
          while(*styles2 != EOS)
          {
            if((*styles2 == 1)  && (!(*(styles2+1) & style)))
            {
              styles2 += 2;
            }
            else
            {
              *styles++ = *styles2++ + line->line.Length - 1;
              *styles++ = *styles2++;
            }
          }
          SHOWVALUE(DBF_CLIPBOARD, line->next->line.Styles);
          MyFreePooled(data->mypool, line->next->line.Styles);
        }
        *styles = EOS;
        line->line.Styles = t_styles;
      }

      length = 12;

      if(colors1 != NULL)
        length += *((long *)colors1-1) - 4;
      if(colors2 != NULL)
        length += *((long *)colors2-1) - 4;

      if((colors = MyAllocPooled(data->mypool, length)) != NULL)
      {
        UWORD *t_colors = colors;
        UWORD end_color = 0;

        SHOWVALUE(DBF_CLIPBOARD, length);
        SHOWVALUE(DBF_CLIPBOARD, colors);
        SHOWVALUE(DBF_CLIPBOARD, colors1);
        SHOWVALUE(DBF_CLIPBOARD, colors2);

        if(colors1 != NULL)
        {
          while(*colors1 < line->line.Length && *colors1 != 0xffff)
          {
            *colors++ = *colors1++;
            end_color = *colors1;
            *colors++ = *colors1++;
          }
          SHOWVALUE(DBF_CLIPBOARD, line->line.Colors);
          MyFreePooled(data->mypool, line->line.Colors);
        }

        if(end_color && (colors2 == NULL || *colors2 != 1))
        {
          *colors++ = line->line.Length;
          *colors++ = 0;
        }

        if(colors2 != NULL)
        {
          if(*colors2 == 1 && *(colors2+1) == end_color)
            colors2 += 2;

          while(*colors2 != 0xffff)
          {
            *colors++ = *colors2++ + line->line.Length - 1;
            *colors++ = *colors2++;
          }
          SHOWVALUE(DBF_CLIPBOARD, line->next->line.Colors);
          MyFreePooled(data->mypool, line->next->line.Colors);
        }
        *colors = 0xffff;
        line->line.Colors = t_colors;
      }
    }

    line->line.Contents = newbuffer;
    line->line.Length  = strlen(newbuffer);

    next = line->next;
    line->next = line->next->next;
    if(line->next != NULL)
      line->next->previous = line;
    oldvisual = line->visual;
    line->visual = VisualHeight(line, data);
    line->line.Color = color;
    line->line.Flow = flow;
    line->line.Separator = separator;

    FreeLine(next, data);

    line_nr = LineToVisual(line, data);

    // handle that we have to scroll up/down due to word wrapping
    // that occurrs when merging lines
    if(visual > line->visual)
    {
      data->totallines -= 1;
      if(line_nr+line->visual-1 < data->maxlines)
      {
        if(emptyline && line_nr > 0)
        {
          if(data->fastbackground)
          {
            ScrollUp(line_nr - 1, 1, data);
            SetCursor(data->CPos_X, data->actualline, TRUE, data);
          }
          else
            DumpText(data->visual_y+line_nr-1, line_nr-1, data->maxlines, TRUE, data);
        }
        else
        {
          if(data->fastbackground)
            ScrollUp(line_nr + line->visual - 1, 1, data);
          else
            DumpText(data->visual_y+line_nr+line->visual-1, line_nr+line->visual-1, data->maxlines, TRUE, data);
        }
      }
    }
    else if(visual < line->visual)
    {
      data->totallines += 1;
      if(line_nr+line->visual-1 < data->maxlines)
        ScrollDown(line_nr + line->visual - 2, 1, data);
    }

    if(!(emptyline && (line_nr + line->visual - 1 < data->maxlines)))
    {
      LONG t_oldvisual = oldvisual;
      LONG t_line_nr   = line_nr;
      ULONG c = 0;

      while((--t_oldvisual) && (t_line_nr++ <= data->maxlines))
        c = c + LineCharsWidth(line->line.Contents+c, data);

      while((c < line->line.Length) && (t_line_nr <= data->maxlines))
        c = c + PrintLine(c, line, t_line_nr++, TRUE, data);
    }

    if(line_nr + oldvisual == 1 && line->visual == visual-1)
    {
      data->visual_y--;
      data->totallines -= 1;

      if(data->fastbackground)
        DumpText(data->visual_y, 0, visual-1, TRUE, data);
      else
        DumpText(data->visual_y, 0, data->maxlines, TRUE, data);
    }

    RETURN(TRUE);
    return(TRUE);
  }
  else
  {
    RETURN(FALSE);
    return(FALSE);
  }
}
예제 #4
0
static void UpdateChange(LONG x, struct line_node *line, LONG length, const char *characters, struct UserAction *buffer, struct InstData *data)
{
  LONG diff;
  LONG skip=0;
  LONG line_nr;
  LONG orgline_nr;
  LONG width=0;
  LONG lineabove_width=0;

  ENTER();

  line_nr = LineToVisual(line, data);
  orgline_nr = line_nr;

  do
  {
    // don't exceed the line length!
    if(skip > (LONG)line->line.Length)
      break;

    width = LineCharsWidth(line->line.Contents + skip, data);
    if(width > 0 && skip + width < x)
    {
      lineabove_width = width;
      skip += width;
      line_nr++;
    }
    else
      break;
  }
  while(TRUE);

  if(characters != NULL)
  {
    strcpyback(line->line.Contents+x+length, line->line.Contents+x);
    memcpy(line->line.Contents+x, characters, length);
    width += length;
    line->line.Length += length;
    if(buffer != NULL)
    {
      UWORD style = buffer->del.style;

      AddStyleToLine(x, line, 1, (style & BOLD) ? BOLD : ~BOLD, data);
      AddStyleToLine(x, line, 1, (style & ITALIC) ? ITALIC : ~ITALIC, data);
      AddStyleToLine(x, line, 1, (style & UNDERLINE) ? UNDERLINE : ~UNDERLINE, data);
      line->line.Flow = buffer->del.flow;
      line->line.Separator = buffer->del.separator;
    }
  }
  else
  {
    strlcpy(line->line.Contents+x, line->line.Contents+x+length, line->line.Length);
    width -= length;
    line->line.Length -= length;
  }

  diff = VisualHeight(line, data) - line->visual;
  if(diff != 0)
  {
    LONG movement;

    movement = orgline_nr + line->visual - 1;

    line->visual += diff;
    data->totallines += diff;

    if(diff > 0)
    {
      if(movement < data->maxlines)
        ScrollDown(movement, diff, data);
    }
    else
    {
      movement = orgline_nr + line->visual - 1;
      if(movement <= data->maxlines)
        ScrollUp(movement, -diff, data);
    }
  }

  if(orgline_nr != line_nr)
  {
    if(lineabove_width != LineCharsWidth(line->line.Contents+skip-lineabove_width, data))
    {
      LONG newwidth;

      newwidth = PrintLine(skip-lineabove_width, line, line_nr-1, TRUE, data) - lineabove_width;
      skip  += newwidth;
      width -= newwidth;
      if(skip >= (LONG)line->line.Length)
      {
        LEAVE();
        return;
      }
    }
  }

  OptimizedPrint(skip, line, line_nr, width, data);
  ScrollIntoDisplay(data);
  data->HasChanged = TRUE;

  LEAVE();
}