Jump to content

[HELP] Whole text height calculating


Spc

Recommended Posts

Hey, I have problem with calculating the whole text height.

local sw, sh = guiGetScreenSize()
local newsFont = dxCreateFont("fonts/Lato.ttf", 8)
local NEWS = {} -- example texts here

function renderNews()
    local height = 0
    for _, v in ipairs(NEWS) do
        local h = math.ceil((string.len(v) / 65)) * 25
        dxDrawRectangle(sw-385, 95+height, 370, h, tocolor(0,0,0,155))
        dxDrawText(v, sw-380, 100+height, sw-15, 100+h+height, tocolor(255,255,255,255), 1, newsFont, "left", "top", true, true)
        height = height + h + 10
    end
end

1ypZD0t.png

I don't have any idea how to do that. I want the height to match every text.

Link to comment
  • Moderators

Idea:

If you have a string, like this: "This is a test string, what more than 1 row."

If this string's lenght is 100px and the dxDrawRectangle's lenght is 50px, you can calculate how many rows need to the string.

rows = 100 / 50

So, now you know how many rows need. This is 2.

After it, you can get your font height, with dxGetFontHeight. Example: this is 30px.

So the full height is:

height = rows * 30

 

Edited by Patrick2562
Link to comment
  • Moderators

I made an algorithm for you.
It looks working good.

(I'm sure there is a better solution. But this is also a viable solution.)

 

 

function calculateRows(text, font, fontSize, rectangeWidth)
	local line_text = ""
	local line_count = 1
	
	for word in text:gmatch("%S+") do
		local temp_line_text = line_text .. " " .. word
		
		local temp_line_width = dxGetTextWidth(temp_line_text, fontSize, font)
		if temp_line_width >= rectangeWidth then
			line_text = word
			line_count = line_count + 1
		else
			line_text = temp_line_text
		end
	end
	
	return line_count
end



local font = "default"
local size = 1
local rectangeWidth = 200
local text = "akosdk sadpdfksdfw eporksdopf sdkopfks dopfkopewkop fksdopmgfdio opfgsdopfk sdopfks dopkfowerop mkopdfmdopgmop mwropfmsdopfmsdop gmiterogmopsefm, opsdmfop meoprgm sdfopgm"
local fontHeight = dxGetFontHeight(size, font)
local height = calculateRows(text, font, size, rectangeWidth) * fontHeight

addEventHandler("onClientRender", root, function()
	dxDrawText(text, 500,200,500+rectangeWidth,200+height, tocolor(255,255,255,255), size, font, "left", "top", false, true)
	dxDrawRectangle(500,200,rectangeWidth,height,tocolor(0,0,0,150))
end)
Edited by Patrick2562
  • Thanks 1
Link to comment
  • Discord Moderators

You may want to use functions from the utf8 lib instead, because Lua doesn't handle utf8 chars that well, for example Hungarian letters: é, á, ő, and so on
I mean, it should actually work with gmatch as well, but for example :gsub with Hungarian letters isn't a working thing ?

Edited by Pirulax
Link to comment
  • Moderators
33 minutes ago, Pirulax said:

You may want to use functions from the utf8 lib instead, because Lua doesn't handle utf8 chars that well, for example Hungarian letters: é, á, ő, and so on
I mean, it should actually work with gmatch as well, but for example :gsub with Hungarian letters isn't a working thing ?<span>

UTF8 does not matter now.

Link to comment

Here you go, I think this should work

local sw, sh = guiGetScreenSize()
fontSize = 8
local newsFont = dxCreateFont("lato.ttf", fontSize) --  default = 9
local sizeScale = 1 -- text size in scales
local NEWS = {
	"This is overlord test1",
	"Ayowapodkjawp awpojkdpawdpow   awpojkdpawdpow  awpojkdpawdpow  wapo jdawpodj apwowoap dowap wap[ojd wapdojawp oa jspodj opapoajs opsdj asd lkjawbd wpiaugd  uipwadwapiug dpwaiug dp iudwapi udgpwad udgapiw d ipugea fuea[udh fw[ad iuoha[foiuh a aw[uoihauoi hdw[fdiuo ahw[ aw wa[ uohawf[  fuhiwa[  h oaiudhAyowapodkjawp awpojkdpawdpow  wapo jdawpodj apwowoap dowap wap[ojd wapdojawp oa jspodj opapoajs opsdj asd lkjawbd wpiaugd  uipwadwapiug dpwaiug dp iudwapi udgpwad udgapiw d ipugea fuea[udh fw[ad iuoha[foiuh a aw[uoihauoi hdw[fdiuo ahw[ aw wa[ uohawf[  fuhiwa[  h oaiudh",
	"Awesome"
}


function renderNews()
	addEventHandler("onClientRender", root, function()
		local height = 0
		for _, v in ipairs(NEWS) do
			local sizeOfRect = (2*(dxGetFontHeight(sizeScale, newsFont)/1.75)) -- converts logical units to actual pixels height
			local lines = math.ceil(string.len(v)/(65/(sizeScale*(fontSize/9))))
			if lines < 1 then lines = 1 end --Just to make sure, idk if it's necessary
			if lines > (dxGetFontHeight(sizeScale, newsFont)/1.75) then lines = lines + 1 end --Just to make sure, but i think it's necessary
			local h = lines * sizeOfRect
			dxDrawRectangle(sw-385, 95+height, 370, h+(5*sizeScale*(fontSize/9)), tocolor(0,0,0,155))
			dxDrawText(v, sw-380, 90+height+(5*sizeScale*(fontSize/9)), sw-15, 100+h+height, tocolor(255,255,255,255), sizeScale, newsFont, "left", "center", true, true) -- align Y set to 'center' to be more flexible
			height = height + h + 10*sizeScale*(fontSize/9)
		end
	end)
end
addEventHandler("onClientResourceStart", resourceRoot, renderNews)

 

Edited by savour
Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...