Page 1 of 1

A very simple Chinese-compatible layouter (0.8.0)

Posted: Thu Oct 06, 2011 3:18 pm
by infinte
Code:

Code: Select all

local exports = {}

local function isHan(char)
	-- Simple processing. Not precise
	return char >= 0x3000
end
local function isSpace(char)
	return char == 0x20
end
local function isBreak(char)
	return char == 0xA
end

local function forUChar(s, f)
	local i = 1
	local len = string.len(s)
	while i <= len do
		local char
		local b = string.byte(s, i)
		local d = 0
		if b < 0x80 then
			char = b
		elseif b < 0xc0 then
			char = (b - 0xc0) * 64 + (string.byte(s, i + 1) - 0x80)
			d = 1
		else
			char = (b - 0xe0) * 4096 + (string.byte(s, i + 1) - 0x80) * 64 + (string.byte(s, i + 2) - 0x80)
			d = 2
		end
		f(char, string.sub(s, i, i + d))
		i = i + d + 1
	end
end

local function layout(s, x, y, limit)
	local segments = {}
	local spaces   = {}
	local buff     = ""

	local font = love.graphics.getFont()
	local lineHeight = font:getLineHeight() * font:getHeight()

	forUChar(s, function(char, ds)
		if isHan(char) then
			if string.len(buff) > 0 then
				table.insert(segments, buff)
				table.insert(spaces, "")
				buff = ""
			end
			table.insert(segments, ds)
			table.insert(spaces, "")
		elseif isBreak(char) then
			if string.len(buff) > 0 then
				table.insert(segments, buff)
				table.insert(spaces, "")
				buff = ""
			end
			table.insert(segments, "\n")
			table.insert(spaces, "")
		elseif isSpace(char) then
			table.insert(segments, buff)
			table.insert(spaces, ds)
			buff = ""
		else
			buff = buff .. ds
		end
	end)
	if string.len(buff) > 0 then
		table.insert(segments, buff)
		table.insert(spaces, "")
		buff = ""
	end

	local position = 0
	local line = ""
	for i, segment in ipairs(segments) do
		position = position + font:getWidth(segment)
		if segment ~= "\n" and position <= limit then
			line = line .. segment
			if position + font:getWidth(spaces[i]) <= limit then
				position = position + font:getWidth(spaces[i])
				line = line .. spaces[i]
			end
		else
			love.graphics.print(line, x, y)
			y = y + lineHeight
			if segment == "\n" then
				line = ""
				position = 0
			else
				line = segment .. spaces[i]
				position = font:getWidth(segment)
			end
		end
	end
	love.graphics.print(line, x, y)
end

exports.layout = layout
return exports
Usage:

Code: Select all

layouter.layout("Wish your dream comes true\n愿你的梦想可以绽放\nあなたの夢を、咲きますように", 100, 100, 200)
Done in 3 hours. It is simple, so that special processings around punctuations is not considered.
三小时的成果,很简单,没有考虑标点周围的特殊行为。

Re: A very simple Chinese-compatible layouter (0.8.0)

Posted: Thu Oct 06, 2011 3:52 pm
by Robin
You might want to change all functions to local functions, to prevent polluting the global scope.

Re: A very simple Chinese-compatible layouter (0.8.0)

Posted: Thu Oct 06, 2011 3:59 pm
by infinte
Robin wrote:You might want to change all functions to local functions, to prevent polluting the global scope.

Sorry, It is fixed
function(){...} IS local in JavaScript, but not in lua. sigh~

Re: A very simple Chinese-compatible layouter (0.8.0)

Posted: Thu Oct 06, 2011 4:12 pm
by kikito
Another minor thing - since you are only exporting the layout function, you can skip the "exports" table altogether:

Code: Select all

local function isHan(char)
   -- Simple processing. Not precise
   return char >= 0x3000
end
...
return layout
Usage:

Code: Select all

layout = require 'layout'
...
layout("Wish your dream comes true\n愿你的梦想可以绽放\nあなたの夢を、咲きますように", 100, 100, 200)

Re: A very simple Chinese-compatible layouter (0.8.0)

Posted: Thu Oct 06, 2011 5:36 pm
by infinte
kikito wrote:Another minor thing - since you are only exporting the layout function, you can skip the "exports" table altogether:

Code: Select all

local function isHan(char)
   -- Simple processing. Not precise
   return char >= 0x3000
end
...
return layout
Usage:

Code: Select all

layout = require 'layout'
...
layout("Wish your dream comes true\n愿你的梦想可以绽放\nあなたの夢を、咲きますように", 100, 100, 200)
It is common in Node.JS development... I think this is also OK. Considering maybe I'll add more functions