void kGUIText::InsertRichInfo(int index,int num) { int i; RICHINFO_DEF rid; assert(index<=m_richinfosize,"Cannot insert past end of string"); /* if at beginning or end of string then use "current" info */ if(index==m_richinfosize || !index) { rid.fontid=GetFontID(); rid.fontsize=GetFontSize(); rid.bgcolor=m_bgcolor; rid.fcolor=GetColor(); } else rid=*(GetRichInfoPtr(index-1)); m_richinfo.Alloc(m_richinfosize+num); m_richinfo.InsertEntry(m_richinfosize,index,num); for(i=0;i<num;++i) m_richinfo.SetEntry(index+i,rid); m_richinfosize+=num; StringChanged(); }
/* allocate the rich list and fill it with the default info */ void kGUIText::InitRichInfo(void) { int i; int num=GetLen(); RICHINFO_DEF tc; m_userichinfo=true; m_richinfo.Alloc(num); tc.fontid=GetFontID(); tc.fontsize=GetFontSize(); tc.bgcolor=m_bgcolor; tc.fcolor=GetColor(); for(i=0;i<num;++i) m_richinfo.SetEntry(i,tc); m_richinfosize=num; StringChanged(); }
void JButton::Render() { Frame ext = GetExt(); uint32_t clr = GetFgColor(); int skinFrame = m_NormalFrame; if (IsBlendAdd()) { g_pDrawServer->SetAdditive( true ); } if (m_bPressed && m_PressedFrame != -1) { skinFrame = m_PressedFrame; } if (!IsEnabled()) { if (m_DisabledFrame != -1) { skinFrame = m_DisabledFrame; } //clr = m_DisableFgColor; } if (IsHovered()) { clr = GetHoverFgColor(); if (m_HoverFrame != -1) { skinFrame = m_HoverFrame; } } g_pDrawServer->Flush(); if (GetSkinPackID() >= 0) { g_pDrawServer->DrawSprite( ext, GetSkinPackID(), skinFrame, GetBgColor() ); } g_pDrawServer->SetLinFilter( IsFilterFont() ); g_pDrawServer->Flush(); const char* text = GetText(); if (text && text[0] != 0) { // draw button text ext.w = g_pDrawServer->GetTextWidth( GetFontID(), text, GetFontHeight() ); ext.h = GetFontHeight(); ext = ApplyAlignment( ext, GetExt(), XAlign_Center, YAlign_Center ); if (m_ShadowColor != 0) { g_pDrawServer->DrawString( ext.x + m_ShadowShiftX, ext.y + m_ShadowShiftY, GetFontID(), GetText(), m_ShadowColor, GetFontHeight() ); g_pDrawServer->Flush(); } g_pDrawServer->DrawString( ext.x, ext.y, GetFontID(), GetText(), clr, GetFontHeight() ); } else if (m_GlyphID >= 0) { // draw button glyph ext.w = g_pDrawServer->GetFrameW( m_GlyphID, m_GlyphFrame ); ext.h = g_pDrawServer->GetFrameH( m_GlyphID, m_GlyphFrame ); ext = ApplyAlignment( ext, GetExt(), XAlign_Center, YAlign_Center ); g_pDrawServer->DrawSprite( ext.x, ext.y, m_GlyphID, m_GlyphFrame, GetFgColor() ); } g_pDrawServer->Flush(); if (IsBlendAdd()) { g_pDrawServer->SetAdditive( false ); } } // JButton::Render
void JObjectTree::RenderNode( JObject* pObject, const Frame& ext, bool bExpanded ) const { static int spID = g_pDrawServer->GetSpriteID( "button" ); int frameID = 11; int nCh = pObject->GetNChildren(); if (nCh > 0) { frameID = 12; float connectW = 4.0f; if (bExpanded) { frameID = 14; Frame rcLine; rcLine.x = ext.r() - 2.0f; rcLine.h = float( nCh - 1 )*m_NodeHeight; rcLine.w = 2.0f; rcLine.y = ext.y - rcLine.h*0.5f + m_NodeHeight*0.5f; g_pDrawServer->DrawRect( rcLine, m_ConnectColor ); connectW = 10.0f; } Frame rcConnect; rcConnect.x = ext.r() - 10.0f; rcConnect.h = 8.0f; rcConnect.w = connectW; rcConnect.y = ext.y + 3.0f; g_pDrawServer->DrawRect( rcConnect, m_ConnectColor ); } Vec2 mousePos; g_pWindowServer->GetMousePos( mousePos ); bool bHovered = ext.PtIn( mousePos.x, mousePos.y ); DWORD bgColor = GetBgColor(); DWORD fgColor = GetFgColor(); if (bHovered) { bgColor = GetHoverBgColor(); fgColor = GetHoverFgColor(); } g_pDrawServer->DrawSprite( ext.x, ext.y, spID, frameID, bgColor ); if (m_pSelected == pObject) { g_pDrawServer->DrawSprite( ext.x, ext.y, spID, 13, fgColor ); } g_pDrawServer->Flush(); float strW = g_pDrawServer->GetTextWidth( GetFontID(), pObject->GetName() ); Frame vp; Frame clipExt( ext ); clipExt.w -= 10.0f; bool bClip = (strW > clipExt.w); if (bClip) { vp = g_pRenderServer->GetViewport(); g_pRenderServer->SetViewport( clipExt ); } g_pDrawServer->DrawString( ext.x + m_NodeCaptionPos.x, ext.y + m_NodeCaptionPos.y, GetFontID(), pObject->GetName(), GetFgColor() ); g_pDrawServer->Flush(); if (bClip) { g_pRenderServer->SetViewport( vp ); } } // JObjectTree::RenderNode
/* get descender height ( pixels below the baseline ) */ const unsigned int kGUIText::GetDescHeight(void) { kGUIFace *face=kGUIFont::GetFace(GetFontID()); return(face->GetPixDescHeight(GetFontSize())); }
unsigned int kGUIFontInfo::GetFontHeight(void) { kGUIFace *face=kGUIFont::GetFace(GetFontID()); return(face->GetPixHeight(GetFontSize())); }
/* calc the pixel width and maximum pixel height for a given section */ void kGUIText::GetSubSize(int sstart,int slen,unsigned int *pixwidth,unsigned int *pixheight) { unsigned int width; unsigned int height; unsigned int maxheight; kGUIFace *face=0; unsigned int size; unsigned int *qw=0; unsigned int ch; /* current character */ unsigned int nb; /* number of bytes for current character */ /* optimize: two loops one for rich and one for plain */ width=0; if(GetUseRichInfo()==false) { /* plain mode, single font and size for whole string */ maxheight=GetLineHeight(); if(slen) { face=kGUIFont::GetFace(GetFontID()); size=GetFontSize(); kGUI::SelectFont(face,size); qw=face->GetQuickWidths(size); width=0; while(slen>0) { ch=GetChar(sstart,&nb); //assert(ch!=0,"reading past end of string!"); sstart+=nb; slen-=nb; if(ch=='\t') { int tw; tw=GetTabWidth(width); if(!tw) { /* use space width if no defined tabs */ if(qw && ' '<MAXCCACHE) width+=qw[' ']; else width+=face->GetCharWidth(' '); } width+=tw; } else { if(qw && ch<MAXCCACHE) width+=qw[ch]; else width+=face->GetCharWidth(ch); width+=m_letterspacing; } } } } else { /* rich string, can have diff font and size on each character */ maxheight=0; if(slen) { RICHINFO_DEF *ri; unsigned int lastfontid=0; size=0; while(slen>0) { ri=GetRichInfoPtr(sstart); if((ri->fontid!=lastfontid) || (ri->fontsize!=size)) { size=ri->fontsize; lastfontid=ri->fontid; face=kGUIFont::GetFace(lastfontid); kGUI::SelectFont(face,size); qw=face->GetQuickWidths(size); height=face->GetPixHeight(size); if(height>maxheight) maxheight=height; } ch=GetChar(sstart,&nb); assert(ch!=0,"reading past end of string!"); sstart+=nb; slen-=nb; if(ch=='\t') { int tw; tw=GetTabWidth(width); if(!tw) { /* use space width if no defined tabs */ if(qw && ' '<MAXCCACHE) width+=qw[' ']; else width+=face->GetCharWidth(' '); } width+=tw; } else { if(qw && ch<MAXCCACHE) width+=qw[ch]; else width+=face->GetCharWidth(ch); width+=m_letterspacing; } } } } if(pixwidth) pixwidth[0]=width; if(pixheight) pixheight[0]=maxheight; }
const unsigned int kGUIText::CalcFitWidth(unsigned int sstart,unsigned int slen,const unsigned int maxwidth,unsigned int *pixwidth) { int n; unsigned int size; unsigned int width,cwidth; kGUIFace *face=0; unsigned int *qw=0; unsigned int ch; /* current character */ unsigned int nb; /* number of bytes for current character */ n=0; width=0; if(slen) { if(GetUseRichInfo()==false) { face=kGUIFont::GetFace(GetFontID()); size=GetFontSize(); qw=face->GetQuickWidths(size); kGUI::SelectFont(face,size); while(slen>0) { ch=GetChar(sstart,&nb); //assert(ch!=0,"reading past end of string!"); sstart+=nb; slen-=nb; if(ch==10) break; if(ch=='\t') { cwidth=GetTabWidth(width); if(!cwidth) { if(qw && ' '<MAXCCACHE) cwidth=qw[' ']; else cwidth=face->GetCharWidth(' '); } } else { if(qw && ch<MAXCCACHE) cwidth=qw[ch]; else cwidth=face->GetCharWidth(ch); } if((width+cwidth)>maxwidth) break; n+=nb; width+=cwidth; } } else { RICHINFO_DEF *ri; unsigned int lastfontid=0; size=0; while(slen>0) { ri=GetRichInfoPtr(sstart); if((ri->fontid!=lastfontid) || (ri->fontsize!=size)) { size=ri->fontsize; lastfontid=ri->fontid; face=kGUIFont::GetFace(lastfontid); kGUI::SelectFont(face,size); qw=face->GetQuickWidths(size); } ch=GetChar(sstart,&nb); assert(ch!=0,"reading past end of string!"); sstart+=nb; slen-=nb; if(ch==10) break; if(ch=='\t') { cwidth=GetTabWidth(width); if(!cwidth) { if(qw && ' '<MAXCCACHE) cwidth=qw[' ']; else cwidth=face->GetCharWidth(' '); } } else { if(qw && ch<MAXCCACHE) cwidth=qw[ch]; else cwidth=face->GetCharWidth(ch); } if((width+cwidth)>maxwidth) break; n+=nb; width+=cwidth; } } } if(pixwidth) pixwidth[0]=width; return(n); }
void kGUIText::DrawSection(int sstart,int slen,int sx,int x,int y,int rowheight,kGUIColor color) { kGUIFace *face; int glyph_index; int font_height,font_above,font_below; const kGUICorners *clip; FT_Face ftface; int size; bool cachesize; int *cacheptr; unsigned int ch; /* current character */ unsigned int nb; /* number of bytes for current character */ int ry; bool isbold; size=GetFontSize(); if(!size) return; if(size<MAXQUICKSIZE) cachesize=true; else cachesize=false; face=kGUIFont::GetFace(GetFontID()); isbold=face->GetBold(); ftface=face->GetFace(); font_height=face->GetPixHeight(size); ry=y+rowheight-font_height; font_above = face->GetPixAscHeight(size); font_below = face->GetPixDescHeight(size); kGUI::SelectFont(face,size); clip=kGUI::GetClipCorners(); if(y>clip->by) return; while(slen>0) { /* get character in current string encoding mode */ ch=GetChar(sstart,&nb); if(!ch) return; sstart+=nb; slen-=nb; /* is this character in the cache? */ if( cachesize==true && (ch<MAXCCACHE)) cacheptr=face->m_quickcache[size][ch]; else cacheptr=0; if(cacheptr) { DrawChar( (char *)(cacheptr+5), x + cacheptr[2], y+font_above-cacheptr[3], cacheptr[0], cacheptr[1], color); x+=cacheptr[4]; x+=m_letterspacing; if(x>clip->rx) return; } else { if(ch=='\t') { int tw; tw=GetTabWidth(x-sx); if(!tw) { if( cachesize==true && (' '<MAXCCACHE)) { cacheptr=face->m_quickcache[size][(int)' ']; tw=cacheptr[4]; } else tw=face->GetCharWidth(' '); } x+=tw; x+=m_letterspacing; if(x>clip->rx) return; } else { glyph_index = FT_Get_Char_Index( ftface, ch ); if(glyph_index>0) { if(!FT_Load_Glyph(ftface, glyph_index, FT_LOAD_DEFAULT)) { if(!FT_Render_Glyph( ftface->glyph, ft_render_mode_normal )) { if(isbold) FT_GlyphSlot_Embolden(ftface->glyph); /* cache this character? */ if( cachesize==true && (ch<MAXCCACHE)) { int bsize=ftface->glyph->bitmap.width*ftface->glyph->bitmap.rows; cacheptr = new int[5+((bsize)/sizeof(int))+1]; face->m_quickcache[size][ch]=cacheptr; cacheptr[0]=ftface->glyph->bitmap.width; cacheptr[1]=ftface->glyph->bitmap.rows; cacheptr[2]=ftface->glyph->bitmap_left; cacheptr[3]=ftface->glyph->bitmap_top; cacheptr[4]=ftface->glyph->advance.x >> 6; memcpy(cacheptr+5,ftface->glyph->bitmap.buffer,bsize); } /* draw to screen using writepixel */ DrawChar( (char *)ftface->glyph->bitmap.buffer, x + ftface->glyph->bitmap_left, y+font_above-ftface->glyph->bitmap_top, ftface->glyph->bitmap.width, ftface->glyph->bitmap.rows, color); x+=ftface->glyph->advance.x >> 6; x+=m_letterspacing; if(x>clip->rx) return; } } } } } }
void kGUIText::DrawSectionRot(int sstart,int slen,float x,float y,float angle,kGUIColor color,float alpha) { kGUIFace *face=kGUIFont::GetFace(GetFontID()); int glyph_index; int font_height,font_above,font_below; FT_Face ftface; int size; FT_Glyph glyph2; FT_Matrix matrix; FT_BitmapGlyph bit; float dx,dy,adv; float advsin,advcos; float fax,fay; /* rotated font above */ unsigned int ch; /* current character */ unsigned int nb; /* number of bytes for current character */ ftface=face->GetFace(); size=GetFontSize(); if(!size) return; assert(size>0,"Cannot print size 0\n"); font_height=face->GetPixHeight(size); font_above = face->GetPixAscHeight(size); font_below = face->GetPixDescHeight(size); kGUI::SelectFont(face,size); matrix.xx = (FT_Fixed)( cos( angle ) * 0x10000L ); matrix.xy = (FT_Fixed)(-sin( angle ) * 0x10000L ); matrix.yx = (FT_Fixed)( sin( angle ) * 0x10000L ); matrix.yy = (FT_Fixed)( cos( angle ) * 0x10000L ); adv=0; advsin=sin(angle); advcos=cos(angle); fax=sin(angle-(2*PI)*0.025f)*font_above; fay=-(cos(angle-(2*PI)*0.025f)*font_above); /* todo, handle underline */ while(slen>0) { ch=GetChar(sstart,&nb); if(!ch) return; sstart+=nb; slen-=nb; /* todo, handle tabs, handle encoding */ glyph_index = FT_Get_Char_Index( ftface, ch ); if(glyph_index>0) { FT_Load_Glyph(ftface,glyph_index,FT_LOAD_DEFAULT); FT_Get_Glyph( ftface->glyph, &glyph2 ); FT_Glyph_Transform( glyph2, &matrix, 0 ); FT_Glyph_To_Bitmap( &glyph2, ft_render_mode_normal,0, 1); /* draw to screen using writepixel */ bit = (FT_BitmapGlyph)glyph2; dx=x+((advcos*adv)+fax); dy=y-((advsin*adv)+fay); DrawChar( (char *)bit->bitmap.buffer, dx + bit->left, dy -bit->top, bit->bitmap.width, bit->bitmap.rows, color,alpha); adv+=ftface->glyph->advance.x/64.0f; adv+=m_letterspacing; FT_Done_Glyph(glyph2); } } if(m_underline) kGUI::DrawLine(x+fax,y-fay,x+((advcos*adv)+fax),y-((advsin*adv)+fay),color,alpha); }