void hrDrawChatBox(featom *atom, regionhandle region)
{
    fonthandle currentfont;
    sdword     x,y,i;
    char       name[128];

    hrChatBoxRegion = region;

    currentfont = fontMakeCurrent(playernamefont);

    primRectSolid2(&region->rect,colRGB(0,0,0));
    feStaticRectangleDraw(region);

    x = region->rect.x0+10;
    y = region->rect.y0;

    for (i=0;i<NUM_CHAT_LINES;i++)
    {
        if (chathistory[i].message[0]!=0)
        {
            x = region->rect.x0;
            sprintf(name,"%s >",tpGameCreated.playerInfo[chathistory[i].packetheader.frame].PersonalName);
            fontPrintf(x,y,tpGameCreated.playerInfo[chathistory[i].packetheader.frame].baseColor,"%s",name);
            x+=fontWidth(name)+10;
            //fontShadowSet(FS_E | FS_SE | FS_S);
            fontPrintf(x,y,hrChatTextColor,"%s",chathistory[i].message);
            //fontShadowSet(FS_NONE);
            y+= fontHeight(" ");
        }
    }

    fontMakeCurrent(currentfont);
}
Beispiel #2
0
sdword DrawTextBlock(char *s, sdword x, sdword y, sdword width, sdword height, color c)
{
    char *oldpos;
    char oldline[100], line[100];
    bool justified, done;

    if(FirstWordNULL(s))
        return(y);
    done = FALSE;
    while (!done)
    {
        justified = FALSE;
        line[0] = 0;
        while (!justified)
        {
            strcpy(oldline, line);
            oldpos = s;
            s = getWord(line, s);

            if (s[0] == '\n')
            {
                justified = TRUE;
                s++;
                while ( s[0] == ' ' ) s++;
            }
            else
            {
                if (fontWidth(line) > width)
                {
                    strcpy(line, oldline);
                    s = oldpos;
                    while ( s[0] == ' ' ) s++;

                    justified = TRUE;
                }
                if (s[0] == 0)
                {
                    justified = TRUE;
                    done      = TRUE;
                }
            }
        }

        fontPrintf(x, y, c, "%s", line);
        y += fontHeight(" ");
        if (y > (y + height))
            done = TRUE;
    }
    y += fontHeight(" ");
    return(y);
}
void hrChatTextEntry(char *name, featom *atom)
{
    char *string;
    ChatPacket temp;
    sdword     width;
    fonthandle fhsave;
    char  testwidth[MAX_CHATSTRING_LENGTH+40];

    if (FEFIRSTCALL(atom))
    {
        // initialize button here
        ChatTextEntryBox = (textentryhandle)atom->pData;
        uicTextEntryInit(ChatTextEntryBox,UICTE_NoLossOfFocus|UICTE_ChatTextEntry);
        uicTextBufferResize(ChatTextEntryBox,MAX_CHATSTRING_LENGTH-2);
        return;
    }

    switch (uicTextEntryMessage(atom))
    {
        case CM_AcceptText :
            string = ((textentryhandle)atom->pData)->textBuffer;
            sendChatMessage(ALL_PLAYER_MASK^PLAYER_MASK(sigsPlayerIndex),string,(uword)sigsPlayerIndex);
            dbgMessagef("text entry: %s",string);
            strcpy(temp.message,string);
            temp.packetheader.frame = (uword)sigsPlayerIndex;
            hrProcessPacket((struct ChatPacket *)&temp);
            uicTextEntrySet(ChatTextEntryBox,"",0);
        break;
        case CM_KeyPressed :
            fhsave = fontMakeCurrent(((textentryhandle)atom->pData)->currentFont); //select the appropriate font
            sprintf(testwidth, "%s >  %s", playerNames[sigsPlayerIndex], ((textentryhandle)atom->pData)->textBuffer);
            width = fontWidth(testwidth);
            fontMakeCurrent(fhsave);
            if (width > (atom->width-30))
            {
                uicBackspaceCharacter((textentryhandle)atom->pData);
            }
        break;
    }
}
Beispiel #4
0
void WidgetScroll::construct(FrameType type, Window* client, int cWidth, int cHeight) { start_func
    assert(cWidth >= -1);
    assert(cHeight >= -1);

    frameType = type;
    clientArea = client;
    dragMode = FRAME_DRAG_NONE;
    scrollX = scrollY = 0;
    hScrollLine = vScrollLine = fontHeight();
    scrollRepeatTicks = scrollRepeatDelay = 0;
    haveFocus = 0;
    whyDirty = FRAME_DIRTY_ALL;

    // Calculate our constants
    scrollbarButtonSize = fontHeight();
    scrollbarButtonXPad = (scrollbarButtonSize - fontWidth("f", FONT_WIDGET)) / 2;

    if ((frameType == FRAMETYPE_BEVEL) || (frameType == FRAMETYPE_BEVEL_BK)) {
        frameThickness = FRAME_BEVELTHICKNESS;
    }
    else if (frameType == FRAMETYPE_LINE) {
        frameThickness = FRAME_LINETHICKNESS;
    }
    else {
        frameThickness = 0;
    }

    if (client) {
        client->setParent(this);
        if (cWidth == -1) cWidth = client->getWidth();
        if (cHeight == -1) cHeight = client->getHeight();
    }
    else {
        if (cWidth == -1) cWidth = 0;
        if (cHeight == -1) cHeight = 0;
    }
    
    resize(cWidth + frameThickness * 2, cHeight + frameThickness * 2);
}
Beispiel #5
0
/*-----------------------------------------------------------------------------
    Name        : trkTrackValuesDisplayFn
    Description : Renders all the track values
    Inputs      :
    Outputs     :
    Return      :
----------------------------------------------------------------------------*/
void trkTrackValuesDisplayFn(void)
{
    sdword index, range;
    sdword x, y, xMin, xMax, xMed, width, height;
    real32 delta, timeElapsed;
    rectangle rect;

    if (keyIsStuck(TRK_ToggleKey))
    {
        keyClearSticky(TRK_ToggleKey);
        trkTrackingVisual ^= TRUE;
    }

    if (!trkTrackingVisual || trkTrackIndex == 0)
    {
        return;
    }

    /*
    if (timeElapsed == 0.0f)
    {
        return;
    }
    */

    height = fontHeight(" ") + 1;
    y = (MAIN_WindowHeight - (height * trkTrackIndex)) / 2;
    width = fontWidth("+100M") + 1;
    x = MAIN_WindowWidth - width * 2 - TRK_TrackWidth;
    xMin = x + width;
    xMax = xMin + TRK_TrackWidth;
    xMed = (xMin + xMax) / 2;
    for (index = 0; index < trkTrackIndex; index++, y += height)
    {
        timeElapsed = *trkValue[index].timer - trkValue[index].lastTime;
        trkValue[index].lastTime = *trkValue[index].timer;
        if (timeElapsed == 0.0f)
        {
            continue;
        }
        //print the name of the value
        fontPrint(x - fontWidth(trkValue[index].name), y, trkValue[index].c, trkValue[index].name);
        delta = abs(*trkValue[index].value - trkValue[index].lastValue) / timeElapsed;//see how much it has changed
        if (delta == 0.0f)
        {   //don't do anything else if it has not changed
            continue;
        }
        //find what range to print in
        if (delta / trkRangeString[0].base > 10.0f)
        {   //if it's bigger than the biggest range
            continue;
        }
        for (range = 0; trkRangeString[range].minusString; range++)
        {
            if (delta / trkRangeString[range].base >= 1.0f)
            {   //if this is the right range
                //get the real delta and bias it against the base
                delta = (trkValue[index].lastValue - *trkValue[index].value) / timeElapsed / trkRangeString[range].base;
                rect.y0 = y;
                rect.y1 = y + height - 1;
                if (delta < 0.0f)
                {
                    rect.x0 = xMed + (sdword)(delta * (real32)TRK_TrackWidth / 20.0f);
                    rect.x1 = xMed;
                }
                else
                {
                    rect.x0 = xMed;
                    rect.x1 = xMed + (sdword)(delta * (real32)TRK_TrackWidth / 20.0f);
                }
                dbgAssert(rect.x0 != rect.x1);
                primRectSolid2(&rect, trkValue[index].c);
                fontPrint(xMin - fontWidth(trkRangeString[range].minusString) - 1, y, colWhite, trkRangeString[range].minusString);
                fontPrint(xMax + 1, y, colWhite, trkRangeString[range].plusString);
                break;
            }
        }
        trkValue[index].lastValue = *trkValue[index].value;
    }
}
Beispiel #6
0
void tmTechInfoDraw(featom *atom, regionhandle region)
{
    fonthandle  currentFont;
    sdword      x,y, width;
    char       *pos, *oldpos;
    char        stringtoprint[650];
    bool        justified, done;

    tmTechInfoRegion = region;

    feStaticRectangleDraw(region); //draw standard rectangle

    currentFont = fontMakeCurrent(tmTechListFont);

    x = region->rect.x0 + 15;
    y = region->rect.y0 + 5 ;

    if (tmtechinfo != -1)
    {
        fontPrintf(x,y,TM_SelectionTextColor,"%s",RaceSpecificTechTypeToNiceString(tmtechinfo, universe.curPlayerPtr->race));

        y += TM_VertSpacing + fontHeight(" ");

        // Bad bad design, my fault [Drew] doh!
        if (tmtechinfo==DDDFDFGFTech)
            if (universe.curPlayerPtr->race==R1)
                strcpy(stringtoprint,strGetString(strR1DDDFTechinfo));
            else
                strcpy(stringtoprint,strGetString(strR2DFGFTechinfo));
        else if (tmtechinfo==CloakDefenseFighter)
            if (universe.curPlayerPtr->race==R1)
                strcpy(stringtoprint,strGetString(strR1CloakFighterinfo));
            else
                strcpy(stringtoprint,strGetString(strR2DefenseFighterTechinfo));
        else
            if (universe.curPlayerPtr->race==R1)
                strcpy(stringtoprint,strGetString(tmtechinfo+strTechInfoOffsetR1));
            else
                strcpy(stringtoprint,strGetString(tmtechinfo+strTechInfoOffsetR2));

        pos = stringtoprint;

        done = FALSE;
        while (!done)
        {
            justified = FALSE;
            tline[0]=0;
            while (!justified)
            {
                strcpy(oldtline, tline);
                oldpos = pos;
                pos = getWord(tline, pos);

                if (pos[0] == '\n')
                {
                    justified = TRUE;
                    pos++;
                    while ( pos[0] == ' ' ) pos++;
                }
                else
                {
                    if ( (width=fontWidth(tline)) > TM_InfoWidth - 15)
                    {
                        strcpy(tline, oldtline);
                        pos = oldpos;
                        while ( pos[0] == ' ' ) pos++;

                        justified = TRUE;
                    }
                    if (pos[0]==0)
                    {
                        justified = TRUE;
                        done      = TRUE;
                    }
                }
            }

            fontPrintf(x,y,TM_StandardTextColor,"%s",tline);
            y += fontHeight(" ");
            if (y > region->rect.y1 + fontHeight(" ")) done=TRUE;
        }
    }

    fontMakeCurrent(currentFont);
}
Beispiel #7
0
void tmDialogDraw(featom *atom, regionhandle region)
{
    sdword      x,y, width;
    char       *pos, *oldpos;
    char        stringtoprint[650];
    bool        justified, done;
    fonthandle oldfont;

    char tmKASMissing[] = "Hello there, fellow space travellers!  Until somebdoy gives me some new lines in KAS, that is all I can say.";

    tmDialogRegion = region;

    oldfont = fontMakeCurrent(tmFont);

    feStaticRectangleDraw(region);                          //draw regular rectangle as backdrop

    x = region->rect.x0 + 15;
    y = region->rect.y0 + 5 ;

    if (tmKASDialog[tmDialogPhrase])
        strcpy(stringtoprint,tmKASDialog[tmDialogPhrase]);
    else
        strcpy(stringtoprint,tmKASMissing);

    y += TM_VertSpacing + fontHeight(" ");

    pos = stringtoprint;

    done = FALSE;
    while (!done)
    {
        justified = FALSE;
        tline[0]=0;
        while (!justified)
        {
            strcpy(oldtline, tline);
            oldpos = pos;
            pos = getWord(tline, pos);

            if (pos[0] == '\n')
            {
                justified = TRUE;
                pos++;
                while ( pos[0] == ' ' ) pos++;
            }
            else
            {
                if ( (width=fontWidth(tline)) > TM_InfoWidth - 15)
                {
                    strcpy(tline, oldtline);
                    pos = oldpos;
                    while ( pos[0] == ' ' ) pos++;

                    justified = TRUE;
                }
                if (pos[0]==0)
                {
                    justified = TRUE;
                    done      = TRUE;
                }
            }
        }

        fontPrintf(x,y,TM_StandardTextColor,"%s",tline);
        y += fontHeight(" ");
        if (y > region->rect.y1 + fontHeight(" ")) done=TRUE;

    }
    fontMakeCurrent(oldfont);
}
Beispiel #8
0
/*-----------------------------------------------------------------------------
    Name        : gcChatTextDraw
    Description : draws the chat history window and prompts for text entry.
    Inputs      : standard draw callbacks.
    Outputs     : none
    Return      : void
----------------------------------------------------------------------------*/
void gcChatTextDraw(featom *atom, regionhandle region)
{
    fonthandle      oldfont;
    sdword          x,y=region->rect.y0,lines=0;
    char            temp[512], *string;
    Node           *walk=NULL;
    chathistory    *chat;

    if (!mrRenderMainScreen) return;

    oldfont = fontMakeCurrent(chathistoryfont);
    fontShadowSet(FS_SE, colBlack);

    if (InChatMode)
    {
        switch (MessageToAllies)
        {
            case GC_ChatToAllies:
                //sprintf(temp,"To Allies: ");
                string = strGetString(strToAllies);
            break;
            case GC_ChatToAll:
                //sprintf(temp,"Say: ");
                string = strGetString(strSay);
            break;
            case GC_RUTransfer:
                //sprintf(temp,"RU Amount: ");
                string = strGetString(strRUAmount);
            break;
        }

        x = region->rect.x0;
        fontPrint(x,y,colWhite,string);
        y+= fontHeight(" ");
        lines++;
    }

    if (curPosition != NULL)
    {
        walk = curPosition;
    }

    if (walk!=NULL)
    {
        do
        {
            x = region->rect.x0;

            chat = listGetStructOfNode(walk);

            switch (chat->messageType)
            {
                case GC_NORMALMESSAGE:
                {
                    sprintf(temp,"<%s>",playerNames[chat->playerindex]);
                    fontPrint(x,y,tpGameCreated.playerInfo[chat->playerindex].baseColor,temp);
                    x+=fontWidth(temp);

                    sprintf(temp,"  %s",chat->chatstring);
                    fontPrint(x,y,gcGameNormalChatColor,temp);
                }
                break;
                case GC_WHISPEREDMESSAGE:
                {
                    sprintf(temp,"<%s>",playerNames[chat->playerindex]);
                    fontPrint(x,y,tpGameCreated.playerInfo[chat->playerindex].baseColor,temp);
                    x+=fontWidth(temp);

                    sprintf(temp, strGetString(strWhisperedMessage));
                    fontPrint(x,y,gcGameWhisperedColor, temp);
                    x+=fontWidth(temp);

                    sprintf(temp,"  %s",chat->chatstring);
                    fontPrint(x,y,gcGamePrivateChatColor,temp);
                }
                break;
                case GC_TEXTMESSAGE:
                {
                    fontPrint(x,y,chat->col,chat->chatstring);
                }
                break;
                case GC_BUFFERSTART:
                {
                    if (ViewingBuffer)
                    {
                        //sprintf(temp,"^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^");
                        fontPrint(x,y,gcGameNormalChatColor,strGetString(strStartOfBuffer));
                    }
                }
                break;
                case GC_BUFFEREND:
                {
                    if (ViewingBuffer)
                    {
                        //sprintf(temp,"v v v v v v v v v v v v v v v v v v v v v v v v");
                        fontPrint(x,y,gcGameNormalChatColor,strGetString(strEndOfBuffer));
                    }
                }
                break;
                case GC_WRAPMESSAGE:
                {
                    x+= chat->indent;
                    fontPrint(x,y,chat->col,chat->chatstring);
                }
                break;
            }

            y += fontHeight(" ");
            lines++;

            walk = walk->next;
        }
        while ((walk!=NULL) && (lines < maxlines));

        if ((ScrollDownAutoBaby==NULL) && (!ViewingBuffer) && (curPosition->next != NULL))
        {
            ScrollDownAutoBaby = taskCallBackRegister(gcScrollDownAuto, 0, NULL, GC_SCROLL_TIME);
        }
    }

    fontShadowSet(FS_NONE, colBlack);
    fontMakeCurrent(oldfont);
}
Beispiel #9
0
/*-----------------------------------------------------------------------------
    Name        : gcAddChatItemToList
    Description : this function adds a chat item to the chat history list
    Inputs      : chat item to add.
    Outputs     : none
    Return      : none
----------------------------------------------------------------------------*/
void gcAddChatItemToList(chathistory *chat)
{
    sdword width, nCharacters, addwidth, length;
    char   temp[256];
    chathistory *wrap;
    color  col;

    switch (chat->messageType)
    {
        case GC_NORMALMESSAGE:
        {
            sprintf(temp,"<%s>  ",playerNames[chat->playerindex]);
            width = fontWidth(temp);
            col = gcGameNormalChatColor;
        }
        break;
        case GC_WHISPEREDMESSAGE:
        {
            sprintf(temp,"<%s>%s  ",playerNames[chat->playerindex], strGetString(strWhisperedMessage));
            width = fontWidth(temp);
            col = gcGamePrivateChatColor;
        }
        break;
        case GC_WRAPMESSAGE:
        {
            width = chat->indent;
            col = chat->col;
        }
        break;
        case GC_TEXTMESSAGE:
        {
            width = 0;
            col = chat->col;
        }
        break;
        default:
        {
            width = 0;
        }
        break;
    }

    if (width+fontWidth(chat->chatstring) > chatwidth)
    {
        wrap = (chathistory *)memAlloc(sizeof(chathistory),"InGameChat",NonVolatile);
        strcpy(wrap->userName, chat->userName);
        wrap->playerindex = chat->playerindex;
        wrap->messageType = GC_WRAPMESSAGE;
        wrap->col         = col;
        wrap->indent      = 0;

        nCharacters = strlen(chat->chatstring);
        addwidth = fontWidth(chat->chatstring);
        while (nCharacters>0 && width + addwidth > chatwidth)
        {
            addwidth = fontWidthN(chat->chatstring,nCharacters);
            nCharacters--;
        }

        length = nCharacters;

        while ((chat->chatstring[nCharacters] != ' ') && (nCharacters > 0) )
        {
            nCharacters--;
        }
        if (nCharacters == 0)
        {
            strcpy(wrap->chatstring, chat->chatstring + length);
            chat->chatstring[length] = 0;
        }
        else
        {
            strcpy(wrap->chatstring, chat->chatstring + nCharacters + 1);
            chat->chatstring[nCharacters] = 0;
        }

        listAddNodeBefore(chathistorylist.tail, &chat->link, chat);

        if (curPosition==chathistorylist.tail)
        {
            curPosition = curPosition->prev;
        }

        if (chathistorylist.num>GC_ChatHistoryMax)
        {
            if (curPosition == chathistorylist.head)
            {
                curPosition = curPosition->next;
            }
            listDeleteNode(chathistorylist.head);
        }

        gcAddChatItemToList(wrap);
    }
    else
    {
        listAddNodeBefore(chathistorylist.tail, &chat->link, chat);
    }

    if (curPosition==chathistorylist.tail)
    {
        curPosition = curPosition->prev;
    }

    if (chathistorylist.num>GC_ChatHistoryMax)
    {
        if (curPosition == chathistorylist.head)
        {
            curPosition = curPosition->next;
        }
        listDeleteNode(chathistorylist.head);
    }

//    reset = TRUE;
}
//------------------------------------------------------------------------------
GDChart & GDChart::createChart()
{
  create(width_,height_);

  bool isIntergerOnlyValues = true;
  intptr_t i, j, xCount = 0, x, y, x0 = 0, y0 = 0;
  // calc min max
  ldouble minValue = DBL_MAX, maxValue = -DBL_MAX;
  for( i = data_.count() - 1; i >= 0; i-- ){
    j = data_[i].count();
    xCount = tmax(xCount,j);
    const Array<ldouble> & data = data_[i];
    for( j = data.count() - 1; j >= 0; j-- ){
      volatile intmax_t v = intmax_t(data[j]);
      volatile ldouble lv = ldouble(v);
      if( lv != data[j] ) isIntergerOnlyValues = false;
      minValue = tmin(minValue,data[j]);
      maxValue = tmax(maxValue,data[j]);
    }
  }
  ldouble yAxis = (maxValue - minValue) / (height_ - topBorder_ - bottomBorder_);
  intptr_t leftBorderDelta = 0, rightBorderDelta = 0, topBorderDelta = 0, bottomBorderDelta = 0;
  // clear image
  fill(0,0,colorAllocate(255,255,255));
  // draw lines
  intptr_t lineColor = colorAllocate(230,230,230);
  // draw vert grid lines
  for( j = 0; j < xCount; j++ ){
    x = (width_ - leftBorder_ - rightBorder_) * j / (xCount - 1) + leftBorder_;
    line(x,topBorder_,x,height_ - bottomBorder_,lineColor);
  }
  intptr_t yLabelColor = makeColor(ldouble(j),ldouble(j),ldouble(j));
  for( y = topBorder_; uintptr_t(y) <= height_ - bottomBorder_; y += fontHeight(font_) * 2 ){
    ldouble v = maxValue - (y - topBorder_) * yAxis;
    // draw horiz grid line
    line(leftBorder_,y,width_ - rightBorder_,y,lineColor);
    // draw ylabel
    utf8::String label;
    if( isIntergerOnlyValues ){
      label = printTraffic(intmax_t(v),true);//utf8::String::print("%"PRIdPTR,intptr_t(v));
    }
    else {
      label = utf8::String::print("%.2"PRF_LDBL"f",v);
    }
    uintptr_t sz = label.size();
    x = leftBorder_ - sz * fontWidth(font_);
    string(GD::font(font_),x,y,label.c_str(),yLabelColor);
    if( x < 0 && -x > leftBorderDelta ) leftBorderDelta = -x;
  }
  // draw data lines
  for( i = 0; uintptr_t(i) < data_.count(); i++ ){
    intptr_t color = makeColor(ldouble(i + 1),ldouble(i + 1),ldouble(i + 1));
    const Array<ldouble> & data = data_[i];
    for( j = 0; uintptr_t(j) < data.count(); j++ ){
      x = (width_ - leftBorder_ - rightBorder_) * j / (xCount - 1) + leftBorder_;
      y = intptr_t(height_ - topBorder_ - bottomBorder_ - (data[j] - minValue) / yAxis) + topBorder_;
      if( j > 0 ) line(x0,y0,x,y,color);
      x0 = x;
      y0 = y;
    }
  }
  intptr_t xBarSize = 2, yBarSize = 2;
  intptr_t barColor = colorAllocate(255,0,0);
  intptr_t xLabelColor = makeColor(ldouble(i + 1),ldouble(i + 1),ldouble(i + 1));
  for( i = 0; uintptr_t(i) < data_.count(); i++ ){
    const Array<ldouble> & data = data_[i];
    for( j = 0; uintptr_t(j) < data.count(); j++ ){
      x = (width_ - leftBorder_ - rightBorder_) * j / (xCount - 1) + leftBorder_;
      y = intptr_t(height_ - topBorder_ - bottomBorder_ - (data[j] - minValue) / yAxis) + topBorder_;
      // draw bar
      filledRectangle(
        tmax(leftBorder_,uintptr_t(x - xBarSize)),
        tmax(topBorder_,uintptr_t(y - yBarSize)),
        tmin(width_ - rightBorder_,uintptr_t(x + xBarSize)),
        tmin(height_ - bottomBorder_,uintptr_t(y + yBarSize)),
        barColor
      );
      x0 = x;
      y0 = y;
      // draw xlabel
      y = height_ - bottomBorder_ + xBarSize;
      utf8::String label(utf8::String::print("%"PRIdPTR,intptr_t(j + xlvs_)));
      string(GD::font(font_),x + xBarSize,y,label.c_str(),xLabelColor);
      if( y + fontHeight(font_) >= height_ )
        bottomBorderDelta = y + fontHeight(font_) - height_ + 1;
      x = x + xBarSize + fontWidth(font_) * label.size();
      if( uintptr_t(x) >= width_ ) rightBorderDelta = x - width_ + 1;
    }
  }
  if( leftBorderDelta != 0 || rightBorderDelta != 0 || topBorderDelta != 0 || bottomBorderDelta != 0 ){
    GDChart chart(*this);
    chart.leftBorder_ += leftBorderDelta;
    chart.rightBorder_ += rightBorderDelta;
    chart.topBorder_ += topBorderDelta;
    chart.bottomBorder_ += bottomBorderDelta;
    chart.createChart();
    xchg(image_,chart.image_);
    xchg(png_,chart.png_);
    xchg(pngSize_,chart.pngSize_);
  }
  else {
    gdFree(png_);
    png_ = pngPtrEx(&pngSize_,9);
  }
  return *this;
}
void TextRender::paint(QPainter* painter)
{
    if (!iTerm)
        return;

    painter->save();
    painter->setFont(iFont);

    int y=0;
    if (iTerm->backBufferScrollPos() != 0 && iTerm->backBuffer().size()>0) {
        int from = iTerm->backBuffer().size() - iTerm->backBufferScrollPos();
        if(from<0)
            from=0;
        int to = iTerm->backBuffer().size();
        if(to-from > iTerm->termSize().height())
            to = from + iTerm->termSize().height();
        paintFromBuffer(painter, iTerm->backBuffer(), from, to, y);
        if(to-from < iTerm->termSize().height() && iTerm->buffer().size()>0) {
            int to2 = iTerm->termSize().height() - (to-from);
            if(to2 > iTerm->buffer().size())
                to2 = iTerm->buffer().size();
            paintFromBuffer(painter, iTerm->buffer(), 0, to2, y);
        }
    } else {
        int count = qMin(iTerm->termSize().height(), iTerm->buffer().size());
        paintFromBuffer(painter, iTerm->buffer(), 0, count, y);
    }

    // cursor
    if (iTerm->showCursor()) {
        painter->setOpacity(0.5);
        QPoint cursor = cursorPixelPos();
        QSize csize = cursorPixelSize();
        painter->setPen(Qt::transparent);
        painter->setBrush(iColorTable[Terminal::defaultFgColor]);
        painter->drawRect(cursor.x(), cursor.y(), csize.width(), csize.height());
    }

    // selection
    QRect selection = iTerm->selection();
    if (!selection.isNull()) {
        painter->setOpacity(0.5);
        painter->setPen(Qt::transparent);
        painter->setBrush(Qt::blue);
        QPoint start, end;

        if (selection.top() == selection.bottom()) {
            start = charsToPixels(selection.topLeft());
            end = charsToPixels(selection.bottomRight());
            painter->drawRect(start.x(), start.y(),
                              end.x()-start.x()+fontWidth(), end.y()-start.y()+fontHeight());
        } else {
            start = charsToPixels(selection.topLeft());
            end = charsToPixels(QPoint(iTerm->termSize().width(), selection.top()));
            painter->drawRect(start.x(), start.y(),
                              end.x()-start.x()+fontWidth(), end.y()-start.y()+fontHeight());

            start = charsToPixels(QPoint(1, selection.top()+1));
            end = charsToPixels(QPoint(iTerm->termSize().width(), selection.bottom()-1));
            painter->drawRect(start.x(), start.y(),
                              end.x()-start.x()+fontWidth(), end.y()-start.y()+fontHeight());

            start = charsToPixels(QPoint(1, selection.bottom()));
            end = charsToPixels(selection.bottomRight());
            painter->drawRect(start.x(), start.y(),
                              end.x()-start.x()+fontWidth(), end.y()-start.y()+fontHeight());
        }
    }

    painter->restore();
}