~ubuntu-branches/ubuntu/trusty/aegisub/trusty

« back to all changes in this revision

Viewing changes to automation/include/unicode.lua

  • Committer: Package Import Robot
  • Author(s): Sebastian Reichel
  • Date: 2012-03-16 22:58:00 UTC
  • Revision ID: package-import@ubuntu.com-20120316225800-yfb8h9e5n04rk46a
Tags: upstream-2.1.9
ImportĀ upstreamĀ versionĀ 2.1.9

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
--[[
 
2
 Copyright (c) 2007, Niels Martin Hansen, Rodrigo Braz Monteiro
 
3
 All rights reserved.
 
4
 
 
5
 Redistribution and use in source and binary forms, with or without
 
6
 modification, are permitted provided that the following conditions are met:
 
7
 
 
8
   * Redistributions of source code must retain the above copyright notice,
 
9
     this list of conditions and the following disclaimer.
 
10
   * Redistributions in binary form must reproduce the above copyright notice,
 
11
     this list of conditions and the following disclaimer in the documentation
 
12
     and/or other materials provided with the distribution.
 
13
   * Neither the name of the Aegisub Group nor the names of its contributors
 
14
     may be used to endorse or promote products derived from this software
 
15
     without specific prior written permission.
 
16
 
 
17
 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 
18
 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 
19
 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 
20
 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 
21
 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 
22
 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 
23
 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 
24
 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 
25
 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 
26
 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 
27
 POSSIBILITY OF SUCH DAMAGE.
 
28
]]
 
29
 
 
30
-- Unicode (UTF-8) support functions for Aegisub Automation 4 Lua
 
31
-- http://www.ietf.org/rfc/rfc2279.txt
 
32
 
 
33
module("unicode")
 
34
 
 
35
-- Return the number of bytes occupied by the character starting at the i'th byte in s
 
36
function charwidth(s, i)
 
37
        local b = s:byte(i or 1)
 
38
        if not b then
 
39
                --aegisub.debug.out(3, "unicode.charwidth of '%s' @ %d, nil byte\n", s, i)
 
40
                -- FIXME, something in karaskel results in this case, shouldn't happen
 
41
                -- What would "proper" behaviour be? Zero? Or just explode?
 
42
                return 1
 
43
        elseif b < 128 then
 
44
                return 1
 
45
        elseif b < 224 then
 
46
                return 2
 
47
        elseif b < 240 then
 
48
                return 3
 
49
        elseif b < 248 then
 
50
                return 4
 
51
        elseif b < 252 then
 
52
                return 5
 
53
        else
 
54
                return 6
 
55
        end
 
56
        -- Actually there are more possibilities, but those aren't really legal
 
57
end
 
58
 
 
59
-- Returns an iterator function for iterating over the characters in s
 
60
function chars(s)
 
61
        local curchar, i = 0, 1
 
62
        
 
63
        local function itor()
 
64
                if i > s:len() then
 
65
                        return nil
 
66
                end
 
67
                
 
68
                local width = charwidth(s, i)
 
69
                local j = i
 
70
                curchar = curchar + 1
 
71
                i = i + width
 
72
                return s:sub(j, i-1), curchar
 
73
        end
 
74
        
 
75
        return itor
 
76
end
 
77
 
 
78
-- Returns the number of characters in s
 
79
-- Runs in O(s:len()) time!
 
80
function len(s)
 
81
        local n = 0
 
82
        for c in chars(s) do
 
83
                n = n + 1
 
84
        end
 
85
        return n
 
86
end
 
87
 
 
88
-- Get codepoint of first char in s
 
89
function codepoint(s)
 
90
        -- Basic case, ASCII
 
91
        local b = s:byte(1)
 
92
        if s:byte(1) < 128 then
 
93
                return s:byte(1)
 
94
        end
 
95
        
 
96
        -- Use a naive decoding algorithm, and assume input is valid
 
97
        local res, w = 0
 
98
        
 
99
        if b < 224 then
 
100
                -- prefix byte is 110xxxxx
 
101
                res = b - 192
 
102
                w = 2
 
103
        elseif b < 240 then
 
104
                -- prefix byte is 11100000
 
105
                res = b - 224
 
106
                w = 3
 
107
        elseif b < 248 then
 
108
                -- prefix byte is 11110000
 
109
                res = b - 240
 
110
                w = 4
 
111
        elseif b < 252 then
 
112
                -- prefix byte is 11111000
 
113
                res = b - 248
 
114
                w = 5
 
115
        else
 
116
                -- prefix byte is 11111100
 
117
                res = b - 252
 
118
                w = 6
 
119
        end
 
120
        
 
121
        for i = 2, w do
 
122
                res = res*64 + s:byte(i) - 128
 
123
        end
 
124
        
 
125
        return res
 
126
end