word wrap

This commit is contained in:
airstruck
2015-11-26 08:53:42 -05:00
parent bbba7e1b3d
commit 2c81c0c293
18 changed files with 409 additions and 89 deletions

View File

@@ -197,13 +197,10 @@ Font.SDL2_ttf = SDL2_ttf
local fontCache = {}
function Font:constructor (path, size, color)
function Font:constructor (path, size)
if not size then
size = 12
end
if not color then
color = { 0, 0, 0, 255 }
end
if not path then
path = REL:gsub('%.', '/') .. 'resource/DejaVuSans.ttf'
end
@@ -222,7 +219,6 @@ function Font:constructor (path, size, color)
end
self.sdlFont = fontCache[key]
self.color = color
end
function Font:setAlignment (align)

View File

@@ -14,10 +14,12 @@ end })
function Image:constructor (renderer, path)
self.sdlRenderer = renderer
self.sdlSurface = SDL2_image.IMG_Load(path)
ffi.gc(self.sdlSurface, sdl.freeSurface)
self.sdlTexture = sdl.createTextureFromSurface(renderer, self.sdlSurface)
ffi.gc(self.sdlTexture, sdl.destroyTexture)
self.sdlSurface = ffi.gc(
SDL2_image.IMG_Load(path),
sdl.freeSurface)
self.sdlTexture = ffi.gc(
sdl.createTextureFromSurface(renderer, self.sdlSurface),
sdl.destroyTexture)
self.width = self.sdlSurface.w
self.height = self.sdlSurface.h
end
@@ -30,17 +32,4 @@ function Image:getHeight ()
return self.height
end
function Image:draw (x, y, sx, sy)
local w = self.width * (sx or 1)
local h = self.height * (sy or 1)
-- HACK. Somehow drawing something first prevents renderCopy from
-- incorrectly scaling up in some cases (after rendering slices).
-- For example http://stackoverflow.com/questions/28218906
sdl.renderDrawPoint(self.sdlRenderer, -1, -1)
-- Draw the image.
sdl.renderCopy(self.sdlRenderer, self.sdlTexture, nil, sdl.Rect(x, y, w, h))
end
return Image

View File

@@ -1,7 +1,7 @@
local ROOT = (...):gsub('[^.]*$', '')
local REL = (...):gsub('[^.]*$', '')
local ffi = require 'ffi'
local sdl = require(ROOT .. 'sdl2.init')
local sdl = require(REL .. 'sdl2.init')
sdl.AudioCVT = ffi.typeof 'SDL_AudioCVT'
-- sdl.AudioDeviceEvent = ffi.typeof 'SDL_AudioDeviceEvent'

View File

@@ -0,0 +1,106 @@
local ROOT = (...):gsub('[^.]*.[^.]*.[^.]*$', '')
local REL = (...):gsub('[^.]*$', '')
local ffi = require 'ffi'
local sdl = require(REL .. 'sdl')
local Font = require(REL .. 'font')
local ttf = Font.SDL2_ttf
local Multiline = require(ROOT .. 'multiline')
local Text = setmetatable({}, { __call = function (self, ...)
local object = setmetatable({}, { __index = self })
return object, self.constructor(object, ...)
end })
local function renderSingle (self, font, text, color)
local alphaMod = color and color[4]
color = sdl.Color(color or 0)
local surface = ffi.gc(
ttf.TTF_RenderUTF8_Blended(font.sdlFont, text, color),
sdl.freeSurface)
self.sdlSurface = surface
self.sdlTexture = ffi.gc(
sdl.createTextureFromSurface(self.sdlRenderer, surface),
sdl.destroyTexture)
if alphaMod then
sdl.setTextureAlphaMod(self.sdlTexture, alphaMod)
end
self.width, self.height = surface.w, surface.h
end
local function renderMulti (self, font, text, color, align, limit)
local alphaMod = color and color[4]
local lines = Multiline.wrap(font, text, limit)
local lineHeight = font:getLineHeight()
local height = #lines * lineHeight
color = sdl.Color(color or 0)
local r, g, b, a
if sdl.BYTEORDER == sdl.BIG_ENDIAN then
r, g, b, a = 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF
else
r, g, b, a = 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000
end
local surface = ffi.gc(
sdl.createRGBSurface(0, limit, height, 32, r, g, b, a),
sdl.freeSurface)
self.sdlSurface = surface
for index, line in ipairs(lines) do
local text = table.concat(line)
local lineSurface = ffi.gc(
ttf.TTF_RenderUTF8_Blended(font.sdlFont, text, color),
sdl.freeSurface)
if lineSurface ~= nil then
local w, h = lineSurface.w, lineSurface.h
local top = (index - 1) * lineHeight
if align == 'left' then
sdl.blitSurface(lineSurface, nil, surface,
sdl.Rect(0, top, w, h))
elseif align == 'right' then
sdl.blitSurface(lineSurface, nil, surface,
sdl.Rect(limit - line.width, top, w, h))
elseif align == 'center' then
sdl.blitSurface(lineSurface, nil, surface,
sdl.Rect((limit - line.width) / 2, top, w, h))
end
end
end
self.sdlTexture = ffi.gc(
sdl.createTextureFromSurface(self.sdlRenderer, surface),
sdl.destroyTexture)
if alphaMod then
sdl.setTextureAlphaMod(self.sdlTexture, alphaMod)
end
self.width, self.height = surface.w, surface.h
end
function Text:constructor (renderer, font, text, color, align, limit)
self.width, self.height = 0, 0
if not text or text == '' then return end
self.sdlRenderer = renderer
if limit then
renderMulti(self, font, text, color, align, limit)
else
renderSingle(self, font, text, color)
end
end
function Text:getWidth ()
return self.width
end
function Text:getHeight ()
return self.height
end
return Text