Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- (!) основную функцию fDxGetTextHeight смотрим внизу кода
- -- ручной перенос слов в тексте.
- -- механизм идентичен переносу слов в dxDrawText
- --
- -- заменяет некоторые пробелы на символы \n, согласно указанной ширине
- -- предполагаемого контейнера для текста. Если в нужном месте для \n
- -- нет пробела, то \n будет просто вставлен.
- --
- -- возвращает новый текст, где некоторые пробелы заменены на символы \n
- function fWordWrap ( sText, nWidth, nFontScaleX, nFontScaleY, font, bReturnLinesCountToo )
- local sOutText, sCurLine, sCurWord, sSpaceBeforeWord, sSpaceAndWordGroup, sSpaceAndWordGroupEnd = "", "", "", "", "", 1
- local sSpaceAndWordGroupPattern = "(([\r\n\t -/:-?%[-`{-~]*)([^\r\n\t -/:-?%[-`{-~]+))"
- -- перенос слов
- _, sSpaceAndWordGroupEnd, sSpaceAndWordGroup, sSpaceBeforeWord, sCurWord = sText:find (
- sSpaceAndWordGroupPattern,
- 1
- )
- while sSpaceAndWordGroupEnd do
- if dxGetTextWidth( sCurLine .. sSpaceAndWordGroup, nFontScaleX, font ) > nWidth then
- -- если сама группа шире
- if dxGetTextWidth( sSpaceAndWordGroup, nFontScaleX, font ) > nWidth then
- while true do
- local sPartEnd = sSpaceAndWordGroup:len() - 1
- local sPart = sSpaceAndWordGroup:sub( 1, sPartEnd )
- -- уменьшаем слово по 1 символу пока оно не влезет вместе с текущим содержимым строки в нужный размер
- -- меньше 1 символа слово не может быть
- while sPartEnd >= 1 and dxGetTextWidth( sCurLine .. sSpaceAndWordGroup, nFontScaleX, font ) > nWidth do
- sPartEnd = sPartEnd - 1
- sPart = sSpaceAndWordGroup:sub( 1, sPartEnd )
- end
- -- новая строка = оставшаяся часть от разбитого слова
- sCurLine = sSpaceAndWordGroup:sub( sPartEnd + 2, -1 )
- -- группа = первой части слова + \n
- sSpaceAndWordGroup = sPart .. "\n" .. sCurLine
- -- если ширину будет превышать даже самый узкий символ, цикл будет бесконечным
- -- для этого тут проверка длины первой части группы
- if sPart:len() <= 1 or dxGetTextWidth( sCurLine .. sSpaceAndWordGroup, nFontScaleX, font ) <= nWidth then
- break
- end
- end
- else
- sSpaceAndWordGroup = sSpaceBeforeWord .. "\n" .. sCurWord
- sCurLine = sCurWord
- end
- else
- sCurLine = sCurLine .. sSpaceAndWordGroup
- end
- sOutText = sOutText .. sSpaceAndWordGroup
- _, sSpaceAndWordGroupEnd, sSpaceAndWordGroup, sSpaceBeforeWord, sCurWord = sText:find (
- sSpaceAndWordGroupPattern,
- sSpaceAndWordGroupEnd + 1
- )
- end
- --
- -- добавим к тексту пробелы, которые возможно были пропущены в конце текста
- sOutText = sOutText .. ( sText:match("[\r\n\t -/:-?%[-`{-~]*$") or "" )
- if bReturnLinesCountToo then
- -- подсчитаем кол-во линий в полученном тексте
- local nLines
- _, nLines = sOutText:gsub( "(\r?\n)", "%1" )
- -- вернем новый текст с переносами и кол-во линий в новом тексте
- return sOutText, (nLines + 1)
- else
- return sOutText
- end
- end
- -- подсчитывает высоту текста с учетом переноса слов и максимальной
- -- ширины контейнера под текст в пикселях
- function fDxGetTextHeight ( sText, font, nFontScaleX, nFontScaleY, nMaxWidth )
- if type(sText) ~= 'string' or sText == '' or
- type(nMaxWidth) ~= 'number' or nMaxWidth <= 0 or
- type(nFontScaleX) ~= 'number' or nFontScaleX <= 0 or
- type(nFontScaleY) ~= 'number' or nFontScaleY <= 0 or
- ( type(font) ~= 'string' and type(font) ~= 'userdata' )
- then
- return 0
- end
- local _, nStrings = fWordWrap( sText, nMaxWidth, nFontScaleX, nFontScaleY, font, true )
- return dxGetFontHeight(nFontScaleY, font) * nStrings
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement