Advertisement
MX_Master

dxGetTextHeight

Aug 8th, 2012
207
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 4.86 KB | None | 0 0
  1. -- (!) основную функцию fDxGetTextHeight смотрим внизу кода
  2.  
  3. -- ручной перенос слов в тексте.
  4. -- механизм идентичен переносу слов в dxDrawText
  5. --
  6. -- заменяет некоторые пробелы на символы \n, согласно указанной ширине
  7. -- предполагаемого контейнера для текста. Если в нужном месте для \n
  8. -- нет пробела, то \n будет просто вставлен.
  9. --
  10. -- возвращает новый текст, где некоторые пробелы заменены на символы \n
  11. function fWordWrap ( sText, nWidth, nFontScaleX, nFontScaleY, font, bReturnLinesCountToo )
  12.  
  13.     local sOutText, sCurLine, sCurWord, sSpaceBeforeWord, sSpaceAndWordGroup, sSpaceAndWordGroupEnd = "", "", "", "", "", 1
  14.     local sSpaceAndWordGroupPattern = "(([\r\n\t -/:-?%[-`{-~]*)([^\r\n\t -/:-?%[-`{-~]+))"
  15.  
  16.  
  17.     -- перенос слов
  18.     _, sSpaceAndWordGroupEnd, sSpaceAndWordGroup, sSpaceBeforeWord, sCurWord = sText:find (
  19.         sSpaceAndWordGroupPattern,
  20.         1
  21.     )
  22.  
  23.     while sSpaceAndWordGroupEnd do
  24.  
  25.         if dxGetTextWidth( sCurLine .. sSpaceAndWordGroup, nFontScaleX, font ) > nWidth then
  26.  
  27.             -- если сама группа шире
  28.             if dxGetTextWidth( sSpaceAndWordGroup, nFontScaleX, font ) > nWidth then
  29.  
  30.                 while true do
  31.                     local sPartEnd = sSpaceAndWordGroup:len() - 1
  32.                     local sPart =    sSpaceAndWordGroup:sub( 1, sPartEnd )
  33.  
  34.                     -- уменьшаем слово по 1 символу пока оно не влезет вместе с текущим содержимым строки в нужный размер
  35.                     -- меньше 1 символа слово не может быть
  36.                     while sPartEnd >= 1 and dxGetTextWidth( sCurLine .. sSpaceAndWordGroup, nFontScaleX, font ) > nWidth do
  37.                         sPartEnd =   sPartEnd - 1
  38.                         sPart =      sSpaceAndWordGroup:sub( 1, sPartEnd )
  39.                     end
  40.  
  41.                     -- новая строка = оставшаяся часть от разбитого слова
  42.                     sCurLine = sSpaceAndWordGroup:sub( sPartEnd + 2, -1 )
  43.                     -- группа = первой части слова + \n
  44.                     sSpaceAndWordGroup = sPart .. "\n" .. sCurLine
  45.  
  46.                     -- если ширину будет превышать даже самый узкий символ, цикл будет бесконечным
  47.                     -- для этого тут проверка длины первой части группы
  48.                     if sPart:len() <= 1 or dxGetTextWidth( sCurLine .. sSpaceAndWordGroup, nFontScaleX, font ) <= nWidth then
  49.                         break
  50.                     end
  51.                 end
  52.  
  53.             else
  54.  
  55.                 sSpaceAndWordGroup = sSpaceBeforeWord .. "\n" .. sCurWord
  56.                 sCurLine = sCurWord
  57.  
  58.             end
  59.  
  60.  
  61.         else
  62.             sCurLine = sCurLine .. sSpaceAndWordGroup
  63.         end
  64.  
  65.         sOutText = sOutText .. sSpaceAndWordGroup
  66.  
  67.         _, sSpaceAndWordGroupEnd, sSpaceAndWordGroup, sSpaceBeforeWord, sCurWord = sText:find (
  68.             sSpaceAndWordGroupPattern,
  69.             sSpaceAndWordGroupEnd + 1
  70.         )
  71.  
  72.     end
  73.     --
  74.  
  75.  
  76.  
  77.     -- добавим к тексту пробелы, которые возможно были пропущены в конце текста
  78.     sOutText = sOutText .. ( sText:match("[\r\n\t -/:-?%[-`{-~]*$") or "" )
  79.  
  80.  
  81.  
  82.     if bReturnLinesCountToo then
  83.         -- подсчитаем кол-во линий в полученном тексте
  84.         local nLines
  85.         _, nLines = sOutText:gsub( "(\r?\n)", "%1" )
  86.  
  87.         -- вернем новый текст с переносами и кол-во линий в новом тексте
  88.         return sOutText, (nLines + 1)
  89.     else
  90.         return sOutText
  91.     end
  92.  
  93. end
  94.  
  95.  
  96.  
  97.  
  98. -- подсчитывает высоту текста с учетом переноса слов и максимальной
  99. -- ширины контейнера под текст в пикселях
  100. function fDxGetTextHeight ( sText, font, nFontScaleX, nFontScaleY, nMaxWidth )
  101.  
  102.     if  type(sText) ~= 'string' or sText == '' or
  103.         type(nMaxWidth) ~= 'number' or nMaxWidth <= 0 or
  104.         type(nFontScaleX) ~= 'number' or nFontScaleX <= 0 or
  105.         type(nFontScaleY) ~= 'number' or nFontScaleY <= 0 or
  106.         ( type(font) ~= 'string' and type(font) ~= 'userdata' )
  107.     then
  108.         return 0
  109.     end
  110.  
  111.     local _, nStrings = fWordWrap( sText, nMaxWidth, nFontScaleX, nFontScaleY, font, true )
  112.  
  113.     return dxGetFontHeight(nFontScaleY, font) * nStrings
  114. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement