예제 #1
0
Math::Vector2 SpriteFont::MeasureText(std::string text)
{
    Math::Vector2 size(0, 0);
    Math::Vector2 pos(0, 0);

    char last = '\0';
    for (int i = 0; i < text.length(); i++)
    {
        char c = text[i];
        if (c != '\n')
        {
            pos.X += GetAdvanceX(c);
        }
        else
        {
            if (pos.X > size.X) size.X = pos.X;
            pos.X = 0;
            pos.Y += GetLineHeight();
        }

        last = c;
    }

    if (pos.X > size.X) size.X = pos.X;
    size.Y = pos.Y + GetLineHeight();

    return size;
}
예제 #2
0
void wxListBox::UpdateItems()
{
    // only refresh the items which must be refreshed
    if ( m_updateCount == -1 )
    {
        // refresh all
        wxLogTrace(_T("listbox"), _T("Refreshing all"));

        Refresh();
    }
    else
    {
        wxSize size = GetClientSize();
        wxRect rect;
        rect.width = size.x;
        rect.height = size.y;
        rect.y += m_updateFrom*GetLineHeight();
        rect.height = m_updateCount*GetLineHeight();

        // we don't need to calculate x position as we always refresh the
        // entire line(s)
        CalcScrolledPosition(0, rect.y, NULL, &rect.y);

        wxLogTrace(_T("listbox"), _T("Refreshing items %d..%d (%d-%d)"),
                   m_updateFrom, m_updateFrom + m_updateCount - 1,
                   rect.GetTop(), rect.GetBottom());

        Refresh(true, &rect);
    }
}
예제 #3
0
float CglFont::GetTextHeight_(const std::u8string& text, float* descender, int* numLines)
{
	if (text.empty()) {
		if (descender) *descender = 0.0f;
		if (numLines) *numLines = 0;
		return 0.0f;
	}

	float h = 0.0f, d = GetLineHeight() + GetDescender();
	unsigned int multiLine = 1;

	int pos = 0;
	while (pos < text.length()) {
		const char32_t u = Utf8GetNextChar(text, pos);
		switch(u) {
			// inlined colorcode
			case ColorCodeIndicator:
				pos = SkipColorCodes(text, pos - 1);
				if (pos<0) {
					pos = text.length();
				}
				break;

			// reset color
			case ColorResetIndicator:
				break;

			// newline
			case 0x0d: // CR+LF
				if (pos < text.length() && text[pos] == 0x0a)
					++pos;
			case 0x0a: // LF
				multiLine++;
				d = GetLineHeight() + GetDescender();
				break;

			// printable char
			default:
				const GlyphInfo& g = GetGlyph(u);
				if (g.descender < d) d = g.descender;
				if (multiLine < 2 && g.height > h) h = g.height; // only calc height for the first line
		}
	}

	if (multiLine>1) d -= (multiLine-1) * GetLineHeight();
	if (descender) *descender = d;
	if (numLines) *numLines = multiLine;

	return h;
}
예제 #4
0
void wxListBox::DoDraw(wxControlRenderer *renderer)
{
    // adjust the DC to account for scrolling
    wxDC& dc = renderer->GetDC();
    PrepareDC(dc);
    dc.SetFont(GetFont());

    // get the update rect
    wxRect rectUpdate = GetUpdateClientRect();

    int yTop, yBottom;
    CalcUnscrolledPosition(0, rectUpdate.GetTop(), NULL, &yTop);
    CalcUnscrolledPosition(0, rectUpdate.GetBottom(), NULL, &yBottom);

    // get the items which must be redrawn
    wxCoord lineHeight = GetLineHeight();
    size_t itemFirst = yTop / lineHeight,
           itemLast = (yBottom + lineHeight - 1) / lineHeight,
           itemMax = m_strings->GetCount();

    if ( itemFirst >= itemMax )
        return;

    if ( itemLast > itemMax )
        itemLast = itemMax;

    // do draw them
    wxLogTrace(_T("listbox"), _T("Repainting items %d..%d"),
               itemFirst, itemLast);

    DoDrawRange(renderer, itemFirst, itemLast);
}
예제 #5
0
void wxListBox::DoEnsureVisible(int n)
{
    if ( !m_showScrollbarY )
    {
        // nothing to do - everything is shown anyhow
        return;
    }

    int first;
    GetViewStart(0, &first);
    if ( first > n )
    {
        // we need to scroll upwards, so make the current item appear on top
        // of the shown range
        Scroll(0, n);
    }
    else
    {
        int last = first + GetClientSize().y / GetLineHeight() - 1;
        if ( last < n )
        {
            // scroll down: the current item appears at the bottom of the
            // range
            Scroll(0, n - (last - first));
        }
    }
}
예제 #6
0
void CEditView::GetCharBoundingRect( int nCol, int nRow, LPRECT prcChar ) const
{
	int nViewCol = m_pBuffer->ConvertBufferColToViewCol( nRow, nCol );
	int cyLine = GetLineHeight();
	prcChar->top = m_rcAll.top + ( nRow - GetTopIndex() ) * cyLine;
	prcChar->bottom = prcChar->top + cyLine;
	int cxChar = GetCharWidth();
	prcChar->left = m_rcAll.left + GetLeftMargin( TRUE, TRUE ) + ( nViewCol - GetLeftIndex() ) * cxChar;
	// for tabs, we want to expand the rect to represent the entire expanded width, not just one char's worth
	int cbChar = m_pBuffer->GetCharSize( nRow, nCol );
	prcChar->right = prcChar->left + cxChar * ( m_pBuffer->ConvertBufferColToViewCol( nRow, nCol + cbChar ) - nViewCol );
}
예제 #7
0
void wxListBox::UpdateScrollbars()
{
    wxSize size = GetClientSize();

    // is our height enough to show all items?
    int nLines = GetCount();
    wxCoord lineHeight = GetLineHeight();
    bool showScrollbarY = nLines*lineHeight > size.y;

    // check the width too if required
    wxCoord charWidth, maxWidth;
    bool showScrollbarX;
    if ( HasHorzScrollbar() )
    {
        charWidth = GetCharWidth();
        maxWidth = GetMaxWidth();
        showScrollbarX = maxWidth > size.x;
    }
    else // never show it
    {
        charWidth = maxWidth = 0;
        showScrollbarX = false;
    }

    // what should be the scrollbar range now?
    int scrollRangeX = showScrollbarX
                        ? (maxWidth + charWidth - 1) / charWidth + 2 // FIXME
                        : 0;
    int scrollRangeY = showScrollbarY
                        ? nLines +
                            (size.y % lineHeight + lineHeight - 1) / lineHeight
                        : 0;

    // reset scrollbars if something changed: either the visibility status
    // or the range of a scrollbar which is shown
    if ( (showScrollbarY != m_showScrollbarY) ||
         (showScrollbarX != m_showScrollbarX) ||
         (showScrollbarY && (scrollRangeY != m_scrollRangeY)) ||
         (showScrollbarX && (scrollRangeX != m_scrollRangeX)) )
    {
        int x, y;
        GetViewStart(&x, &y);
        SetScrollbars(charWidth, lineHeight,
                      scrollRangeX, scrollRangeY,
                      x, y);

        m_showScrollbarX = showScrollbarX;
        m_showScrollbarY = showScrollbarY;

        m_scrollRangeX = scrollRangeX;
        m_scrollRangeY = scrollRangeY;
    }
}
예제 #8
0
		void ChatWindow::Draw() {
			SPADES_MARK_FUNCTION();
			
			float winX = 4.f;
			float winY = killfeed ? 8.f :
			(float)renderer->ScreenHeight() * .5f;
			std::list<ChatEntry>::iterator it;
			
			float lHeight = GetLineHeight();
			
			float y = firstY;
			
			Vector4 shadowColor = {0, 0, 0, 0.5};
			
			for(it = entries.begin(); it != entries.end(); it++){
				ChatEntry& ent = *it;
				
				std::string msg = ent.msg;
				Vector4 color = GetColor(MsgColorRestore);
				float tx = 0.f, ty = y;
				float fade = ent.fade;
				if(ent.timeFade < 1.f)
					fade *= ent.timeFade;
				shadowColor.w = .5f * fade;
				color.w *= fade;
				for(size_t i = 0; i < msg.size(); i++){
					if(msg[i] == 13 || msg[i] == 10){
						tx = 0.f; ty += lHeight;
					}else if(msg[i] <= MsgColorMax){
						color = GetColor(msg[i]);
						color.w *= fade;
					}else{
						std::string ch(&msg[i], 1);
						font->Draw(ch,
								   MakeVector2(tx + winX + 1.f,
											   ty + winY + 1.f),
								   1.f, shadowColor);
						font->Draw(ch,
								   MakeVector2(tx + winX,
											   ty + winY),
								   1.f, color);
						tx += font->Measure(ch).x;
					}
				}
				
				y += ent.height;
			}
		}
예제 #9
0
Text::Text(FontCache* fc) {
	cache = fc;

    buffer = NULL;
    bufferAlpha = NULL;
    bufferW = bufferH = 0;

    statesL = 0;
    PushState();

   	SetFont(fc->GetDefaultFont());
    SetFontSize(DEFAULT_FONT_SIZE);

    penX = marginLeft;
    penY = marginTop + GetLineHeight();
}
예제 #10
0
파일: odcombo.cpp 프로젝트: beanhome/dev
wxSize wxVListBoxComboPopup::GetAdjustedSize( int minWidth, int prefHeight, int maxHeight )
{
    int height = 250;

    maxHeight -= 2;  // Must take borders into account

    if ( m_strings.GetCount() )
    {
        if ( prefHeight > 0 )
            height = prefHeight;

        if ( height > maxHeight )
            height = maxHeight;

        int totalHeight = GetTotalHeight(); // + 3;

        // Take borders into account on Mac or scrollbars always appear
#if defined(__WXMAC__)
        totalHeight += 2;
#endif
        if ( height >= totalHeight )
        {
            height = totalHeight;
        }
        else
        {
            // Adjust height to a multiple of the height of the first item
            // NB: Calculations that take variable height into account
            //     are unnecessary.
            int fih = GetLineHeight(0);
            height -= height % fih;
        }
    }
    else
        height = 50;

    CalcWidths();

    // Take scrollbar into account in width calculations
    int widestWidth = m_widestWidth + wxSystemSettings::GetMetric(wxSYS_VSCROLL_X);
    return wxSize(minWidth > widestWidth ? minWidth : widestWidth,
                  height+2);
}
예제 #11
0
int CUrlRichEditCtrl::FindUrlEx(const CPoint& point)
{
	int nUrl = m_aUrls.GetSize();
	
	while (nUrl--)
	{
		const URLITEM& urli = m_aUrls[nUrl];

		CRect rUrl(GetCharPos(urli.cr.cpMin), GetCharPos(urli.cr.cpMax));

		rUrl.bottom += GetLineHeight();
		
		if (rUrl.PtInRect(point))
			return nUrl;
	}

	// not found
	return -1;
}
예제 #12
0
void wxListBox::DoSetSize(int x, int y,
                          int width, int height,
                          int sizeFlags)
{
    if ( GetWindowStyle() & wxLB_INT_HEIGHT )
    {
        // we must round up the height to an entire number of rows

        // the client area must contain an int number of rows, so take borders
        // into account
        wxRect rectBorders = GetRenderer()->GetBorderDimensions(GetBorder());
        wxCoord hBorders = rectBorders.y + rectBorders.height;

        wxCoord hLine = GetLineHeight();
        height = ((height - hBorders + hLine - 1) / hLine)*hLine + hBorders;
    }

    wxListBoxBase::DoSetSize(x, y, width, height, sizeFlags);
}
예제 #13
0
void CCrystalEditView::ShowDropIndicator(const CPoint &point)
{
	if (! m_bDropPosVisible)
	{
		HideCursor();
		m_ptSavedCaretPos = GetCursorPos();
		m_bDropPosVisible = TRUE;
		::CreateCaret(m_hWnd, (HBITMAP) 1, 2, GetLineHeight());
	}
	m_ptDropPos = ClientToText(point);
	if (m_ptDropPos.x >= m_nOffsetChar)
	{
		SetCaretPos(TextToClient(m_ptDropPos));
		ShowCaret();
	}
	else
	{
		HideCaret();
	}
}
void FGameplayDebuggerCanvasContext::Print(const FColor& Color, const FString& String)
{
	FTaggedStringParser Parser(Color);
	Parser.ParseString(String);

	const float LineHeight = GetLineHeight();
	for (int32 NodeIdx = 0; NodeIdx < Parser.NodeList.Num(); NodeIdx++)
	{
		const FTaggedStringParser::FNode& NodeData = Parser.NodeList[NodeIdx];
		if (NodeData.bNewLine)
		{
			if (Canvas.IsValid() && (CursorY + LineHeight) > Canvas->ClipY)
			{
				DefaultX += Canvas->ClipX / 2;
				CursorY = 0.0f;
			}

			CursorX = DefaultX;
			CursorY += LineHeight;
		}

		if (NodeData.String.Len() > 0)
		{
			float SizeX = 0.0f, SizeY = 0.0f;
			MeasureString(NodeData.String, SizeX, SizeY);

			FCanvasTextItem TextItem(FVector2D::ZeroVector, FText::FromString(NodeData.String), Font.Get(), FLinearColor(NodeData.Color));
			if (FontRenderInfo.bEnableShadow)
			{
				TextItem.EnableShadow(FColor::Black, FVector2D(1, 1));
			}

			DrawItem(TextItem, CursorX, CursorY);
			CursorX += SizeX;
		}
	}

	MoveToNewLine();
}
예제 #15
0
파일: kguifont.cpp 프로젝트: CarlHuff/kgui
/* 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;
}
예제 #16
0
		void ChatWindow::AddMessage(const std::string &msg){
			SPADES_MARK_FUNCTION();
			
			ChatEntry ent;
			
			// get visible message string
			std::string str;
			float x = 0.f, maxW = GetWidth();
			float lh = GetLineHeight(), h = lh;
			size_t wordStart = std::string::npos;
			size_t wordStartOutPos;
			
			for(size_t i = 0; i < msg.size(); i++){
				if(msg[i] > MsgColorMax &&
				   msg[i] != 13 && msg[i] != 10){
					if(isWordChar(msg[i])){
						if(wordStart == std::string::npos){
							wordStart = msg.size();
							wordStartOutPos = str.size();
						}
					}else{
						wordStart = std::string::npos;
					}
					
					float w = font->Measure(std::string(&msg[i],1)).x;
					if(x + w > maxW){
						if(wordStart != std::string::npos &&
						   wordStart != str.size()){
							// adding a part of word.
							// do word wrapping
							
							std::string s = msg.substr(wordStart, i - wordStart + 1);
							float nw = font->Measure(s).x;
							if(nw <= maxW){
								// word wrap succeeds
								
								w = nw;
								x = w;
								h += lh;
								str.insert(wordStartOutPos, "\n");
								
								goto didWordWrap;
							}
							
						}
						x = 0; h += lh;
						str += 13;
					}
					x += w;
					str += msg[i];
				didWordWrap:;
				}else if(msg[i] == 13 || msg[i] == 10){
					x = 0; h += lh;
					str += 13;
				}else{
					str += msg[i];
				}
			}
			
			ent.height = h;
			ent.msg = msg;
			ent.fade = 0.f;
			ent.timeFade = 15.f;
			
			entries.push_front(ent);
			
			firstY -= h;
		}
예제 #17
0
void CTextWrap::WrapTextConsole(std::list<word>& words, float maxWidth, float maxHeight)
{
	if (words.empty() || (GetLineHeight()<=0.0f))
		return;
	const bool splitAllWords = false;
	const unsigned int maxLines = (unsigned int)std::floor(std::max(0.0f, maxHeight / GetLineHeight()));

	line* currLine;
	word linebreak;
	linebreak.isLineBreak = true;

	bool addEllipsis = false;
	bool currLineValid = false; // true if there was added any data to the current line

	std::list<word>::iterator wi = words.begin();

	std::list<line> lines;
	lines.push_back(line());
	currLine = &(lines.back());
	currLine->start = words.begin();

	for (; ;) {
		currLineValid = true;
		if (wi->isLineBreak) {
			currLine->forceLineBreak = true;
			currLine->end = wi;

			// start a new line after the '\n'
			lines.push_back(line());
			currLineValid = false;
			currLine = &(lines.back());
			currLine->start = wi;
			++currLine->start;
		} else {
			currLine->width += wi->width;
			currLine->end = wi;

			if (currLine->width > maxWidth) {
				currLine->width -= wi->width;

				// line grew too long by adding the last word, insert a LineBreak
				const bool splitLastWord = (wi->width > (0.5 * maxWidth));
				const float freeWordSpace = (maxWidth - currLine->width);

				if (splitAllWords || splitLastWord) {
					// last word W is larger than 0.5 * maxLineWidth, split it into
					// get 'L'eft and 'R'ight parts of the split (wL becomes Left, *wi becomes R)

					bool restart = (currLine->start == wi);
					// turns *wi into R
					word wL = SplitWord(*wi, freeWordSpace);

					if (splitLastWord && wL.width == 0.0f) {
						// With smart splitting it can happen that the word isn't split at all,
						// this can cause a race condition when the word is longer than maxWidth.
						// In this case we have to force an unaesthetic split.
						wL = SplitWord(*wi, freeWordSpace, false);
					}

					// increase by the width of the L-part of *wi
					currLine->width += wL.width;

					// insert the L-part right before R
					wi = words.insert(wi, wL);
					if (restart)
						currLine->start = wi;
					++wi;
				}

				// insert the forced linebreak (either after W or before R)
				linebreak.pos = wi->pos;
				currLine->end = words.insert(wi, linebreak);

				while (wi != words.end() && wi->isSpace)
					wi = words.erase(wi);

				lines.push_back(line());
				currLineValid = false;
				currLine = &(lines.back());
				currLine->start = wi;
				--wi; // compensate the wi++ downwards
			}
		}

		++wi;

		if (wi == words.end()) {
			break;
		}

		if (lines.size() > maxLines) {
			addEllipsis = true;
			break;
		}
	}

	// empty row
	if (!currLineValid || (currLine->start == words.end() && !currLine->forceLineBreak)) {
		lines.pop_back();
		currLine = &(lines.back());
	}

	// if we had to cut the text because of missing space, add an ellipsis
	if (addEllipsis)
		AddEllipsis(lines, words, maxWidth);

	wi = currLine->end;
	++wi;
	wi = words.erase(wi, words.end());
}
예제 #18
0
CBSurface *CBFontTT::RenderTextToTexture(const WideString &text, int width, TTextAlign align, int maxHeight, int &textOffset) {
	TextLineList lines;
	WrapText(text, width, maxHeight, lines);


	TextLineList::iterator it;

	int textHeight = lines.size() * (m_MaxCharHeight + m_Ascender);
	SDL_Surface *surface = SDL_CreateRGBSurface(0, width, textHeight, 32, 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000);

	SDL_LockSurface(surface);

	int posY = (int)GetLineHeight() - (int)m_Descender;

	for (it = lines.begin(); it != lines.end(); ++it) {
		TextLine *line = (*it);
		int posX = 0;

		switch (align) {
		case TAL_CENTER:
			posX += (width - line->GetWidth()) / 2;
			break;

		case TAL_RIGHT:
			posX += width - line->GetWidth();
			break;
		}


		textOffset = 0;
		for (size_t i = 0; i < line->GetText().length(); i++) {
			wchar_t ch = line->GetText()[i];

			GlyphInfo *glyph = m_GlyphCache->GetGlyph(ch);
			if (!glyph) continue;

			textOffset = std::max(textOffset, glyph->GetBearingY());
		}


		int origPosX = posX;

		wchar_t prevChar = L'\0';
		for (size_t i = 0; i < line->GetText().length(); i++) {
			wchar_t ch = line->GetText()[i];

			GlyphInfo *glyph = m_GlyphCache->GetGlyph(ch);
			if (!glyph) continue;

			float kerning = 0;
			if (prevChar != L'\0') kerning = GetKerning(prevChar, ch);
			posX += (int)kerning;


			if (glyph->GetBearingY() > 0) {
				int i = 10;
			}

			SDL_Rect rect;
			rect.x = posX + glyph->GetBearingX();
			rect.y = posY - glyph->GetBearingY() + textOffset;
			rect.w = glyph->GetImage()->w;
			rect.h = glyph->GetImage()->h;

			BlitSurface(glyph->GetImage(), surface, &rect);

			prevChar = ch;
			posX += (int)(glyph->GetAdvanceX());
			posY += (int)(glyph->GetAdvanceY());
		}

		if (m_IsUnderline) {
			for (int i = origPosX; i < origPosX + line->GetWidth(); i++) {
				Uint8 *buf = (Uint8 *)surface->pixels + (int)(m_UnderlinePos + m_Ascender) * surface->pitch;
				Uint32 *buf32 = (Uint32 *)buf;

				buf32[i] = SDL_MapRGBA(surface->format, 255, 255, 255, 255);
			}
		}

		SDL_UnlockSurface(surface);

		delete line;
		line = NULL;
		posY += GetLineHeight();
	}

	CBSurfaceSDL *wmeSurface = new CBSurfaceSDL(Game);
	if (SUCCEEDED(wmeSurface->CreateFromSDLSurface(surface))) {
		SDL_FreeSurface(surface);
		return wmeSurface;
	} else {
		SDL_FreeSurface(surface);
		delete wmeSurface;
		return NULL;
	}
}
예제 #19
0
파일: Frame.cpp 프로젝트: spacechase0/SFGUI
RenderQueue* BREW::CreateFrameDrawable( SharedPtr<const Frame> frame ) const {
	sf::Color border_color( GetProperty<sf::Color>( "BorderColor", frame ) );
	sf::Color color( GetProperty<sf::Color>( "Color", frame ) );
	sf::Color background_color( GetProperty<sf::Color>( "BackgroundColor", frame ) );
	float border_width( GetProperty<float>( "BorderWidth", frame ) );
	const std::string& font_name( GetProperty<std::string>( "FontName", frame ) );
	unsigned int font_size( GetProperty<unsigned int>( "FontSize", frame ) );
	const sf::Font& font( *GetResourceManager().GetFont( font_name ) );
	float label_padding( GetProperty<float>( "LabelPadding", frame ) );

	float line_height = GetLineHeight( font, font_size );

	RenderQueue* queue( new RenderQueue );

	// Right
	queue->Add(
		Renderer::Get().CreateLine(
			sf::Vector2f( frame->GetAllocation().width - border_width, line_height / 2.f ),
			sf::Vector2f( frame->GetAllocation().width - border_width, frame->GetAllocation().height - border_width ),
			border_color,
			border_width
		)
	);

	// Bottom
	queue->Add(
		Renderer::Get().CreateLine(
			sf::Vector2f( frame->GetAllocation().width, frame->GetAllocation().height - border_width ),
			sf::Vector2f( 0.f, frame->GetAllocation().height - border_width ),
			border_color,
			border_width
		)
	);

	// Left
	queue->Add(
		Renderer::Get().CreateLine(
			sf::Vector2f( 0.f, frame->GetAllocation().height - border_width ),
			sf::Vector2f( 0.f, line_height / 2.f ),
			border_color,
			border_width
		)
	);

	float label_start_x = line_height;
	float label_end_x = line_height;

	float alignment = frame->GetAlignment().x;

	if( frame->GetLabel().getSize() > 0 ) {
		sf::Vector2f metrics = GetTextMetrics( frame->GetLabel(), font, font_size );
		metrics.x += ( 2 * label_padding );

		label_start_x += ( alignment * ( frame->GetAllocation().width - 2 * line_height - metrics.x ) );
		label_end_x += ( metrics.x + alignment * ( frame->GetAllocation().width - 2 * line_height - metrics.x ) );

		sf::Text text( frame->GetLabel(), font, font_size );
		text.setPosition( label_start_x + label_padding, .0f );
		text.setColor( color );
		queue->Add( Renderer::Get().CreateText( text, background_color ) );
	}

	// Top Left
	queue->Add(
		Renderer::Get().CreateLine(
			sf::Vector2f( 0.f, line_height / 2.f ),
			sf::Vector2f( label_start_x, line_height / 2.f ),
			border_color,
			border_width
		)
	);

	// Top Right
	queue->Add(
		Renderer::Get().CreateLine(
			sf::Vector2f( label_end_x, line_height / 2.f ),
			sf::Vector2f( frame->GetAllocation().width - border_width, line_height / 2.f ),
			border_color,
			border_width
		)
	);

	return queue;
}
예제 #20
0
int CBFontTT::GetLetterHeight() {
	return GetLineHeight();
}
예제 #21
0
const float Text::GetHeight() const
{
    return GetLineHeight() * mNumLines;
}
예제 #22
0
void CglFont::RenderString(float x, float y, const float& scaleX, const float& scaleY, const std::string& str)
{
	/**
	 * NOTE:
	 * Font rendering does not use display lists, but VAs. It's actually faster
	 * (450% faster with a 7600GT!) for these reasons:
	 *
	 * 1. When using DLs, we can not group multiple glyphs into one glBegin/End pair
	 *    because glTranslatef can not go between such a pair.
	 * 2. We can now eliminate all glPushMatrix/PopMatrix pairs related to font rendering
	 *    because the transformations are calculated on the fly. These are just a couple of
	 *    floating point multiplications and shouldn't be too expensive.
	 */

	const float startx = x;
	const float lineHeight_ = scaleY * GetLineHeight();
	unsigned int length = (unsigned int)str.length();
	const std::u8string& ustr = toustring(str);

	va.EnlargeArrays(length * 4, 0, VA_SIZE_2DT);

	int skippedLines;
	bool colorChanged;
	const GlyphInfo* g = NULL;
	float4 newColor = textColor;
	char32_t c;
	int i = 0;

	do {
		const bool endOfString = SkipColorCodesAndNewLines(ustr, &i, &newColor, &colorChanged, &skippedLines, &baseTextColor);

		if (endOfString)
			return;

		c = Utf8GetNextChar(str,i);

		if (colorChanged) {
			if (autoOutlineColor) {
				SetColors(&newColor,NULL);
			} else {
				SetTextColor(&newColor);
			}
		}
		const GlyphInfo* c_g = &GetGlyph(c);
		if (skippedLines>0) {
			x  = startx;
			y -= skippedLines * lineHeight_;
		} else if (g) {
			x += scaleX * GetKerning(*g, *c_g);
		}

		g = c_g;

		const auto&  tc = g->texCord;
		const float dx0 = (scaleX * g->size.x0()) + x, dy0 = (scaleY * g->size.y0()) + y;
		const float dx1 = (scaleX * g->size.x1()) + x, dy1 = (scaleY * g->size.y1()) + y;

		va.AddVertexQ2dT(dx0, dy1, tc.x0(), tc.y1());
		va.AddVertexQ2dT(dx0, dy0, tc.x0(), tc.y0());
		va.AddVertexQ2dT(dx1, dy0, tc.x1(), tc.y0());
		va.AddVertexQ2dT(dx1, dy1, tc.x1(), tc.y1());
	} while(true);
}
예제 #23
0
void CglFont::RenderStringOutlined(float x, float y, const float& scaleX, const float& scaleY, const std::string& str)
{
	const float shiftX = (scaleX/fontSize) * GetOutlineWidth(), shiftY = (scaleY/fontSize) * GetOutlineWidth();

	const float startx = x;
	const float lineHeight_ = scaleY * GetLineHeight();
	const std::u8string& ustr = toustring(str);
	const size_t length = str.length();

	va.EnlargeArrays(length * 4, 0, VA_SIZE_2DT);
	va2.EnlargeArrays(length * 4, 0, VA_SIZE_2DT);

	int skippedLines;
	bool colorChanged;
	const GlyphInfo* g = NULL;
	float4 newColor = textColor;
	char32_t c;
	int i = 0;

	do {
		const bool endOfString = SkipColorCodesAndNewLines(ustr, &i, &newColor, &colorChanged, &skippedLines, &baseTextColor);

		if (endOfString)
			return;

		c = Utf8GetNextChar(str,i);

		if (colorChanged) {
			if (autoOutlineColor) {
				SetColors(&newColor,NULL);
			} else {
				SetTextColor(&newColor);
			}
		}

		const GlyphInfo* c_g = &GetGlyph(c);
		if (skippedLines>0) {
			x  = startx;
			y -= skippedLines * lineHeight_;
		} else if (g) {
			x += scaleX * GetKerning(*g, *c_g);
		}

		g = c_g;

		const auto&  tc = g->texCord;
		const auto& stc = g->shadowTexCord;
		const float dx0 = (scaleX * g->size.x0()) + x, dy0 = (scaleY * g->size.y0()) + y;
		const float dx1 = (scaleX * g->size.x1()) + x, dy1 = (scaleY * g->size.y1()) + y;

		// draw outline
		va2.AddVertexQ2dT(dx0-shiftX, dy1-shiftY, stc.x0(), stc.y1());
		va2.AddVertexQ2dT(dx0-shiftX, dy0+shiftY, stc.x0(), stc.y0());
		va2.AddVertexQ2dT(dx1+shiftX, dy0+shiftY, stc.x1(), stc.y0());
		va2.AddVertexQ2dT(dx1+shiftX, dy1-shiftY, stc.x1(), stc.y1());

		// draw the actual character
		va.AddVertexQ2dT(dx0, dy1, tc.x0(), tc.y1());
		va.AddVertexQ2dT(dx0, dy0, tc.x0(), tc.y0());
		va.AddVertexQ2dT(dx1, dy0, tc.x1(), tc.y0());
		va.AddVertexQ2dT(dx1, dy1, tc.x1(), tc.y1());
	} while(true);
}
예제 #24
0
int Text::WrapString(const char* string, bool draw) {
	lineBreaksL = 0;

	int from = 0;
	int to = strlen(string);
	int lineOffset = 0;
	int visibleLines = -1;

	const int maxWidth = bufferW - marginLeft - marginRight - 1;
    const int spaceW = cache->GetAdvance(' ');
    const int lineHeight = GetLineHeight();

    if (maxWidth < spaceW) {
    	return lineBreaksL = 1;
    }

	bool panic = false;
	int line = 0;
    int lineWidth = penX - marginLeft;
    int wordCount = 0;
    int charCount = 0;
    int lineDrawEnd = 0;

	int lastPenX = penX;
    int lastPenY = penY;
	int index = from;

    char tempString[to - from + 1];
    int tempIndex = 0;
    int lastFittingChar = 0; //Last char that fits on the current line
    bool allCharsDrawn = true;

	while (index < to) {
		//Find next word start
        while (index < to && INVISIBLE_CHAR(string[index])) { //Skip whitespace
            index++;
            if (line >= lineOffset && (visibleLines < 0 || line - lineOffset < visibleLines)) {
            	charCount++;
            }
        }

        int oldIndex = index;
        int oldCharCount = charCount;

        int ww = 0; //Word Width (includes optional prefixed space)
        bool wordFits = true;
        bool newlineEncountered = false;

        if (index < to) {
	        if (wordCount > 0) {
	            ww = spaceW;
	            tempString[tempIndex] = ' ';
	            tempIndex++;
	        }

	        lastFittingChar = tempIndex; //Last char that fits on the current line

	        //Add letters to word
	        while (index < to && !INVISIBLE_CHAR(string[index])) {
	        	if (string[index] == '\n' || string[index] == '|') {
	        		index++;
	        		lastFittingChar = index;
	        		newlineEncountered = true;
	        		wordFits = false;
	        		panic = false; //Word fits
	        		break;
	        	}

                u32 c = string[index];
                int bytes = FontCache::GetCodePoint(string + index, &c);
                if (bytes == 0) bytes = 1;
                int advance = cache->GetAdvance(c);

	            if (lineWidth + ww + advance <= maxWidth) {
	                //Char still fits on this line
	                lastFittingChar += bytes;
	            } else if (ww + advance > maxWidth) {
	                //This single word is wider than an entire line. It needs to be
	                //cut on an unnatural position to be displayed.

	                wordFits = false; //Word will never fit in this state
	                break;
	            } else {
	            	ww = 9999;
	            	break;
	            }

	            for (int n = 0; n < bytes; n++) {
	            	tempString[tempIndex] = string[index];
	            	tempIndex++;
	            	index++;
	            }

                if (line >= lineOffset && (visibleLines < 0 || line - lineOffset < visibleLines)) {
                	charCount++;
                }
                if (visibleChars < 0 || charCount <= visibleChars) {
                	lineDrawEnd = tempIndex;
                } else {
            		allCharsDrawn = (visibleChars < 0);
                }

                ww += advance;
	        }
        }

        if (!wordFits || (index >= to && lineWidth + ww <= maxWidth)) {
            //if !wordFits :: Word longer than a full line, cut up word
        	//if index >= to :: Add final word to line
            tempIndex = lastFittingChar + 1;

            lineWidth += ww;
        } else if (lineWidth + ww > maxWidth) {
            tempIndex -= (index - oldIndex);
            lineDrawEnd = MIN(lineDrawEnd, tempIndex);
            charCount = oldCharCount;
            index = oldIndex;
            wordFits = false;
        }

        if (!wordFits || index >= to) {
            //Word doesn't fit on the current line or the end of the string
            //has been reached

        	if (lineDrawEnd <= 0 && !newlineEncountered) {
        		break;
        	}
        	lineBreaks[line] = index;

            //Draw Line
            if (line >= lineOffset && (visibleLines < 0 || line - lineOffset < visibleLines)) {
            	tempString[lineDrawEnd] = '\0';
                if (draw) {
                	PrintLine(tempString);
                }
		else {
			CalcLine(tempString);
		}

            	lastPenX = penX;
            	lastPenY = penY;

				penX = marginLeft;
				penY += lineHeight;

				//Cursor shouldn't go back after a hard newline
				if (newlineEncountered) {
					lastPenX = penX;
					lastPenY = penY;
				}
            }

            int oldLineDrawEnd = lineDrawEnd;

            //New Line
           	line++;
            lineWidth = penX - marginLeft;
            lineDrawEnd = 0;
            wordCount = 0;
            tempIndex = 0;

            if (oldLineDrawEnd == 0) { //Can't even fit a single char two times in a row, time to quit
    			if (panic) {
    				break;
    			} else {
    				panic = true;
    			}
    		} else {
    			panic = false;
    		}
        } else {
            //Add word to line
            wordCount++;
            lineWidth += ww;
        }
    }

	penX = lastPenX;
	penY = lastPenY;

	lineBreaksL = MAX(1, line);
	return lineBreaksL;
}
예제 #25
0
void CShaderEdit::OnUpdate()
{
	if(m_nIDEvent == -1)
	{
		m_nIDEvent = SetTimer(1, 100, NULL); 
	}

	CString text;
	int nStartChar = 0, nEndChar = -1;
	GetSel(nStartChar, nEndChar);

	if(nStartChar == nEndChar)
	{
		GetWindowText(text);
		while(nStartChar > 0 && _istalnum(text.GetAt(nStartChar-1)))
			nStartChar--;
	}

	if(nStartChar < nEndChar)
	{
		text = text.Mid(nStartChar, nEndChar - nStartChar);
		text.TrimRight('(');
		text.MakeLower();

		m_acdlg.m_list.ResetContent();

		CString key, value;
		POSITION pos = m_acdlg.m_inst.GetStartPosition();
		while(pos)
		{
			POSITION cur = pos;
			m_acdlg.m_inst.GetNextAssoc(pos, key, value);

			if(key.Find(text) == 0)
			{
				CAtlList<CString> sl;
				Explode(value, sl, '|', 2);
				if(sl.GetCount() != 2) continue;
				CString name = sl.RemoveHead();
				CString description = sl.RemoveHead();
				int i = m_acdlg.m_list.AddString(name);
				m_acdlg.m_list.SetItemDataPtr(i, cur);
			}
		}

		if(m_acdlg.m_list.GetCount() > 0)
		{
			int lineheight = GetLineHeight();

			CPoint p = PosFromChar(nStartChar);
			p.y += lineheight;
			ClientToScreen(&p);
			CRect r(p, CSize(100, 100));

			m_acdlg.MoveWindow(r);
			m_acdlg.SetWindowPos(&wndTopMost, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
			m_acdlg.ShowWindow(SW_SHOWNOACTIVATE);

			m_nEndChar = nEndChar;

			return;
		}
	}

	m_acdlg.ShowWindow(SW_HIDE);
}
예제 #26
0
void Text::PrintNewline() {
    penX = marginLeft;
    penY += GetLineHeight();
}
예제 #27
0
파일: kguifont.cpp 프로젝트: CarlHuff/kgui
int kGUIText::CalcLineList(int w)
{
	unsigned int line;
	unsigned int sindex;
	unsigned int totalchars;
	unsigned int numfit;
	unsigned int pixwidth;
	unsigned int maxw;

	const unsigned char *t;
	const unsigned char *cc;
	const unsigned char *ce;
	kGUIInputLineInfo *lbptr;

	if(m_linelist.GetNumEntries()==0)
	{
		m_linelist.Init(1,-1);
		m_linelist.SetEntry(0,new kGUIInputLineInfo);
	}

	maxw=0;
	line=0;
	sindex=0;
	t=(const unsigned char *)GetString();
	totalchars=GetLen();
	if((!t) || (!totalchars))
	{
		lbptr=m_linelist.GetEntry(0);
		lbptr->startindex=sindex;
		lbptr->endindex=sindex;
		lbptr->pixwidth=0;
		lbptr->hardbreak=true;
		lbptr->pixheight=GetLineHeight();
		m_lltotalheight=lbptr->pixheight+2;
		lbptr->ty=0;
		lbptr->by=m_lltotalheight-1;
		m_llnum=1;
		return(0);
	}

	m_lltotalheight=0;
	do{
		numfit=CalcFitWidth(sindex,totalchars-sindex,w,&pixwidth);
		if(pixwidth>maxw)
			maxw=pixwidth;

		/* go back and break on a space, unless there are no spaces */
		if(!numfit)
		{
			if(t[sindex]!=10)				/* supposed to be a blank line? */
				numfit=totalchars-sindex;	/* rest of line */
		}
		else
		{
			cc=t+sindex;
			ce=cc+numfit;
			if(ce[0]!=10 && ce[0])
			{
				while((ce[-1]!=' ') && (ce>cc))
					--ce;

				if(ce!=cc)			/* only if a space was found */
					numfit=(int)(ce-cc);
			}
		}

		/* alloc more space? */
		if(line>=m_linelist.GetNumEntries())
			m_linelist.Alloc(line<<3);

		lbptr=m_linelist.GetEntry(line);
		if(!lbptr)
		{
			lbptr=new kGUIInputLineInfo;
			m_linelist.SetEntry(line,lbptr);
		}
		lbptr->startindex=sindex;		/* line starts at this character */
		lbptr->endindex=sindex+numfit;	/* line stops at this character */

		/* calc size of Substring */
		lbptr->ty=m_lltotalheight;
		GetSubSize(sindex,numfit,&lbptr->pixwidth,&lbptr->pixheight);
		if(!numfit)
		{
			/* how tall is a blank line, use height of last character in previous line */
			if(!sindex)
				lbptr->pixheight=GetLineHeight();
			else
				GetSubSize(sindex-1,1,0,&lbptr->pixheight);
		}
		m_lltotalheight+=lbptr->pixheight+2;
		lbptr->by=m_lltotalheight-1;

		if(t[sindex+numfit]==0 || t[sindex+numfit]==10)
			lbptr->hardbreak=true;
		else
			lbptr->hardbreak=false;

		++line;
		sindex+=numfit;
		if(t[sindex]==10)
			++sindex;
		else if(!numfit)
			break;
	}while(sindex<totalchars);
	m_llnum=line;
	return(maxw);
}
예제 #28
0
파일: kguifont.cpp 프로젝트: CarlHuff/kgui
void kGUIText::Draw(int x,int y,int w,int h,kGUIColor color)
{
	/* this is the only draw call that looks at the valign and halign */
	kGUIInputLineInfo *lbptr;
	int i;
	FT_HALIGN halign=GetHAlign();
	int cx=0;
	int cy;
	int lineheight=GetLineHeight()+2;
	int numl;

	if(m_llnum<2)
		numl=1;
	else
		numl=m_llnum;

	cy=y;
	switch(GetVAlign())
	{
	case FT_TOP:
	break;
	case FT_MIDDLE:
		cy+=(h-((lineheight*numl)-2))/2;
	break;
	case FT_BOTTOM:
		cy+=h-((lineheight*numl)-2);
	break;
	}

	if(m_llnum<2)
	{
		switch(halign)
		{
		case FT_LEFT:
			cx=x;
		break;
		case FT_CENTER:
			cx=x+((w-(int)GetWidth())/2);
		break;
		case FT_RIGHT:
			cx=x+(w-(int)GetWidth());
		break;
		}

		DrawSection(0,GetLen(),x,cx,cy,GetLineHeight(),color);
	}
	else
	{
		for(i=0;i<m_llnum;++i)
		{
			lbptr=m_linelist.GetEntry(i);
			switch(halign)
			{
			case FT_LEFT:
				cx=x;
			break;
			case FT_CENTER:
				cx=x+((w-lbptr->pixwidth)/2);
			break;
			case FT_RIGHT:
				cx=x+(w-lbptr->pixwidth);
			break;
			}
			DrawSection(lbptr->startindex,lbptr->endindex-lbptr->startindex,x,cx,cy,lbptr->pixheight,color);
			cy+=lineheight;
		}
	}
}