Build liblouis_nacl using gyp.

Tries to reland 237638 after fixing compiler warnings from a more recent compiler used on arm.

This cl ports the nacl wrapper to the chromium build system and adds local modifications from Chromevox to liblouis. The native library and braille tables are copied to the location in the resources output directory where chromevox can pick them up.

BUG=316353

Committed: https://src.chromium.org/viewvc/chrome?view=rev&revision=237638

Review URL: https://codereview.chromium.org/67283007

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@238548 0039d316-1c4b-4281-b951-d872f2087c98
parent deb2998a
...@@ -32,6 +32,7 @@ sys.path.insert(1, os.path.join(chrome_src, 'native_client', 'build')) ...@@ -32,6 +32,7 @@ sys.path.insert(1, os.path.join(chrome_src, 'native_client', 'build'))
sys.path.insert(1, os.path.join(chrome_src, 'native_client_sdk', 'src', sys.path.insert(1, os.path.join(chrome_src, 'native_client_sdk', 'src',
'build_tools')) 'build_tools'))
sys.path.insert(1, os.path.join(chrome_src, 'remoting', 'tools', 'build')) sys.path.insert(1, os.path.join(chrome_src, 'remoting', 'tools', 'build'))
sys.path.insert(1, os.path.join(chrome_src, 'third_party', 'liblouis'))
sys.path.insert(1, os.path.join(chrome_src, 'third_party', 'WebKit', sys.path.insert(1, os.path.join(chrome_src, 'third_party', 'WebKit',
'Source', 'build', 'scripts')) 'Source', 'build', 'scripts'))
......
...@@ -23,6 +23,9 @@ ...@@ -23,6 +23,9 @@
'<(PRODUCT_DIR)/nacl_helper_bootstrap<(EXECUTABLE_SUFFIX)', '<(PRODUCT_DIR)/nacl_helper_bootstrap<(EXECUTABLE_SUFFIX)',
'<(PRODUCT_DIR)/xdisplaycheck<(EXECUTABLE_SUFFIX)', '<(PRODUCT_DIR)/xdisplaycheck<(EXECUTABLE_SUFFIX)',
], ],
'isolate_dependency_untracked': [
'<(PRODUCT_DIR)/chromevox_test_data/',
],
}, },
}], }],
['OS=="linux" or OS=="mac"', { ['OS=="linux" or OS=="mac"', {
......
...@@ -1668,7 +1668,17 @@ ...@@ -1668,7 +1668,17 @@
'test/data/nacl/nacl_test_data.gyp:*', 'test/data/nacl/nacl_test_data.gyp:*',
'../ppapi/native_client/native_client.gyp:nacl_irt', '../ppapi/native_client/native_client.gyp:nacl_irt',
'../ppapi/ppapi_untrusted.gyp:ppapi_nacl_tests', '../ppapi/ppapi_untrusted.gyp:ppapi_nacl_tests',
'../ppapi/tests/extensions/extensions.gyp:ppapi_tests_extensions_socket' '../ppapi/tests/extensions/extensions.gyp:ppapi_tests_extensions_socket',
],
'conditions': [
['OS=="linux"', {
'sources': [
'../third_party/liblouis/nacl_wrapper/liblouis_wrapper_browsertest.cc',
],
'dependencies': [
'../third_party/liblouis/liblouis_untrusted.gyp:liblouis_test_data',
],
}],
], ],
}], }],
['OS=="win" or OS=="linux"', { ['OS=="win" or OS=="linux"', {
......
{
"key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDJ8Hl8K6R+n/hrPsN1ienxRU3GbL00wFHLJNML45MHwT+3PstgWf4EgC3wbyyTXFtbvJC+Hn14Hyltfhsa+cSraldNHeL+rl+FL04kE4uYHq8YhOYEtzUfg380+o7XV9oESKu9oLTeG9QuQCjmlp3MUqC9wm7ICjxR9flODClOkQIDAQAB",
"name": "liblouis_nacl tests",
"version": "0.1",
"manifest_version": 2,
"description": "test",
"background": {
"scripts": [ "test.js" ]
}
}
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
var pass = chrome.test.callbackPass;
var TABLE_NAME = 'en-us-comp8.ctb';
var TEXT = 'hello';
// Translation of the above string as a hexadecimal sequence of cells.
var CELLS = '1311070715';
var pendingCallback = null;
var pendingMessageId = -1;
var nextMessageId = 0;
var naclEmbed = null;
function loadLibrary(callback) {
var embed = document.createElement('embed');
embed.src = 'liblouis_nacl.nmf';
embed.type = 'application/x-nacl';
embed.width = 0;
embed.height = 0;
embed.setAttribute('tablesdir', 'tables');
embed.addEventListener('load', function() {
console.log("liblouis loaded");
naclEmbed = embed;
callback();
}, false /* useCapture */);
embed.addEventListener('error', function() {
chrome.test.fail('liblouis load error');
}, false /* useCapture */);
embed.addEventListener('message', function(e) {
var reply = JSON.parse(e.data);
console.log('Message from liblouis: ' + e.data);
pendingCallback(reply);
}, false /* useCapture */);
document.body.appendChild(embed);
}
function rpc(command, args, callback) {
var messageId = '' + nextMessageId++;
args['command'] = command;
args['message_id'] = messageId;
var json = JSON.stringify(args)
console.log('Message to liblouis: ' + json);
naclEmbed.postMessage(json);
pendingCallback = callback;
pendingMessageId = messageId;
}
function expectSuccessReply(callback) {
return function(reply) {
chrome.test.assertEq(pendingMessageId, reply['in_reply_to']);
chrome.test.assertTrue(reply['error'] === undefined);
chrome.test.assertTrue(reply['success']);
if (callback) {
callback(reply);
}
};
}
loadLibrary(function() {
chrome.test.runTests([
function testGetTranslator() {
rpc('CheckTable', { 'table_name': TABLE_NAME},
pass(expectSuccessReply()));
},
function testTranslateString() {
rpc('Translate', { 'table_name': TABLE_NAME, 'text': TEXT},
pass(expectSuccessReply(function(reply) {
chrome.test.assertEq(CELLS, reply['cells']);
})));
},
function testBackTranslateString() {
rpc('BackTranslate', { 'table_name': TABLE_NAME, 'cells': CELLS},
pass(expectSuccessReply(function(reply) {
chrome.test.assertEq(TEXT, reply['text']);
})));
},
])});
...@@ -15,4 +15,13 @@ libloius is used in a native client binary in ChromeVox and not linked into ...@@ -15,4 +15,13 @@ libloius is used in a native client binary in ChromeVox and not linked into
Chrome itself. Chrome itself.
Local Modifications: Local Modifications:
...
* Add manually created liblouis.h.
* On Android: log to logcat.
* Fix backtranslation to not output unicode braille patterns
(svn r838)
* Fix 3 letters in Danish 8 dot braille table, reverting part of svn r238.
* Fix out-of-bounds array access (code removed by upstream).
* Fix compiler warnings (part of svn r856).
* Add tables.json a list of tables with metadata.
* Add a wrapper to expose the library in native client.
#!/usr/bin/env python
# Copyright 2013 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import os
import re
import sys
import json
import optparse
# Matches the include statement in the braille table files.
INCLUDE_RE = re.compile(r"^\s*include\s+([^#\s]+)")
def Error(msg):
print >> sys.stderr, 'liblouis_list_tables: %s' % msg
sys.exit(1)
def ToNativePath(pathname):
return os.path.sep.join(pathname.split('/'))
def LoadTablesFile(filename):
with open(ToNativePath(filename), 'r') as fh:
return json.load(fh)
def FindFile(filename, directories):
for d in directories:
fullname = '/'.join([d, filename])
if os.path.isfile(ToNativePath(fullname)):
return fullname
Error('File not found: %s' % filename)
def GetIncludeFiles(filename):
result = []
with open(ToNativePath(filename), 'r') as fh:
for line in fh.xreadlines():
match = INCLUDE_RE.match(line)
if match:
result.append(match.group(1))
return result
def ProcessFile(output_set, filename, directories):
fullname = FindFile(filename, directories)
if fullname in output_set:
return
output_set.add(fullname)
for include_file in GetIncludeFiles(fullname):
ProcessFile(output_set, include_file, directories)
def DoMain(argv):
"Entry point for gyp's pymod_do_main command."
parser = optparse.OptionParser()
# Give a clearer error message when this is used as a module.
parser.prog = 'liblouis_list_tables'
parser.set_usage('usage: %prog [options] listfile')
parser.add_option('-D', '--directory', dest='directories',
action='append', help='Where to search for table files')
(options, args) = parser.parse_args(argv)
if len(args) != 1:
parser.error('Expecting exactly one argument')
if not options.directories:
parser.error('At least one --directory option must be specified')
tables = LoadTablesFile(args[0])
output_set = set()
for table in tables:
ProcessFile(output_set, table['fileName'], options.directories)
return '\n'.join(output_set)
def main(argv):
print DoMain(argv[1:])
if __name__ == '__main__':
try:
sys.exit(main(sys.argv))
except KeyboardInterrupt:
Error('interrupted')
# Copyright 2013 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
{
'variables': {
'braille_test_data_dir': '<(PRODUCT_DIR)/chromevox_test_data/braille',
'braille_chromevox_dir': '<(PRODUCT_DIR)/resources/chromeos/chromevox/chromevox/background/braille',
'table_files': [
'>!@pymod_do_main(liblouis_list_tables -D overrides/tables -D src/tables tables.json)',
],
},
# x86 targets build both 32 and 64 bit binaries by default. We only need
# the one that matches our target architecture.
'target_defaults': {
'conditions': [
['target_arch=="ia32"', {
'variables': {
'enable_x86_64': 0,
},
}],
['target_arch=="x64"', {
'variables': {
'enable_x86_32': 0,
},
}],
],
},
'includes': [
'../../build/common_untrusted.gypi',
],
'conditions': [
['disable_nacl==0 and disable_nacl_untrusted==0', {
'targets': [
{
'target_name': 'liblouis_untrusted',
'type': 'none',
'variables': {
'nacl_untrusted_build': 1,
'nlib_target': 'liblouis_untrusted.a',
'build_newlib': 1,
},
'compile_flags': [
'-Wno-switch',
'-Wno-unused-but-set-variable',
],
'include_dirs': [
'overrides/liblouis',
'src/liblouis',
'.',
],
'direct_dependent_settings': {
'include_dirs': [
'overrides',
],
},
'sources': [
'overrides/liblouis/config.h',
'overrides/liblouis/liblouis.h',
'overrides/liblouis/compileTranslationTable.c',
'src/liblouis/lou_backTranslateString.c',
'src/liblouis/lou_translateString.c',
'src/liblouis/transcommon.ci',
'src/liblouis/wrappers.c',
],
'dependencies': [
'../../native_client/tools.gyp:prep_toolchain',
],
},
{
'target_name': 'liblouis_nacl_wrapper_untrusted',
'type': 'none',
'variables': {
'nacl_untrusted_build': 1,
'nexe_target': 'liblouis_nacl',
'out_newlib64': '<(braille_test_data_dir)/>(nexe_target)_x86_64.nexe',
'out_newlib32': '<(braille_test_data_dir)/>(nexe_target)_x86_32.nexe',
'out_newlib_arm': '<(braille_test_data_dir)/>(nexe_target)_arm.nexe',
'build_newlib': 1,
'extra_args': [
'--strip-debug',
],
'nmf': '<(braille_test_data_dir)/>(nexe_target).nmf',
'target_conditions': [
['enable_x86_64==1', {
'nexe_files': ['>(out_newlib64)'],
}],
['enable_x86_32==1', {
'nexe_files': ['>(out_newlib32)'],
}],
['enable_arm==1', {
'nexe_files': ['>(out_newlib_arm)'],
}],
],
},
'sources': [
'nacl_wrapper/liblouis_instance.h',
'nacl_wrapper/liblouis_instance.cc',
'nacl_wrapper/liblouis_module.h',
'nacl_wrapper/liblouis_module.cc',
'nacl_wrapper/liblouis_wrapper.h',
'nacl_wrapper/liblouis_wrapper.cc',
'nacl_wrapper/translation_params.h',
'nacl_wrapper/translation_result.h',
],
'link_flags': [
'-lppapi',
'-lppapi_cpp',
'-llouis_untrusted',
'-ljsoncpp_untrusted',
'-lpthread',
'-lnacl_io',
],
'dependencies': [
'../../native_client/src/untrusted/nacl/nacl.gyp:nacl_lib',
'../../native_client/tools.gyp:prep_toolchain',
'../../native_client_sdk/native_client_sdk_untrusted.gyp:nacl_io_untrusted',
'../../ppapi/native_client/native_client.gyp:ppapi_lib',
'../../ppapi/ppapi_untrusted.gyp:ppapi_cpp_lib',
'../jsoncpp/jsoncpp_untrusted.gyp:jsoncpp_untrusted',
'liblouis_untrusted',
],
'actions': [
{
'action_name': 'Generate NEWLIB NMF',
'inputs': [
'>@(nexe_files)',
],
'outputs': ['>(nmf)'],
'action': [
'python',
'<(DEPTH)/native_client_sdk/src/tools/create_nmf.py',
'>@(_inputs)',
'--output=>(nmf)',
],
},
],
# Copy specific files into the product directory to avoid
# copying over the unstripped binary file.
# TODO(plundblad): Temporarily disabled while the rest of chromevox
# lands.
# 'copies': [
# {
# 'destination': '<(braille_chromevox_dir)',
# 'files': [
# '<(nmf)',
# '>@(nexe_files)',
# 'tables.json',
# ],
# },
# {
# 'destination': '<(braille_chromevox_dir)/tables',
# 'files': [
# '<@(table_files)',
# ],
# },
# ],
},
{
'target_name': 'liblouis_test_data',
'type': 'none',
'variables': {
'test_extension_dir': '<(DEPTH)/chrome/test/data/chromeos/liblouis_nacl',
},
'dependencies': [
'liblouis_nacl_wrapper_untrusted',
],
'copies': [
{
'destination': '<(braille_test_data_dir)',
'files': [
'tables.json',
'<(test_extension_dir)/manifest.json',
'<(test_extension_dir)/test.js',
],
},
{
'destination': '<(braille_test_data_dir)/tables',
'files': [
'<@(table_files)',
],
},
],
},
],
}],
],
}
This diff is collapsed.
// Copyright 2013 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.
#ifndef LIBLOUIS_NACL_LIBLOUIS_INSTANCE_H_
#define LIBLOUIS_NACL_LIBLOUIS_INSTANCE_H_
#include <string>
#include "base/basictypes.h"
#include "json/json.h"
#include "liblouis_wrapper.h"
#include "ppapi/c/pp_instance.h"
#include "ppapi/cpp/completion_callback.h"
#include "ppapi/cpp/instance.h"
#include "ppapi/cpp/message_loop.h"
#include "ppapi/cpp/var.h"
#include "ppapi/utility/completion_callback_factory.h"
#include "ppapi/utility/threading/simple_thread.h"
#include "translation_params.h"
namespace liblouis_nacl {
class LibLouisInstance : public pp::Instance {
public:
explicit LibLouisInstance(PP_Instance instance);
virtual ~LibLouisInstance();
virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]);
virtual void HandleMessage(const pp::Var& var_message);
private:
// Post work to the background (liblouis) thread.
int32_t PostWorkToBackground(const pp::CompletionCallback& callback) {
return liblouis_thread_.message_loop().PostWork(callback);
}
// Encodes a message as JSON and sends it over to JavaScript.
void PostReply(Json::Value reply, const std::string& in_reply_to);
// Posts an error response to JavaScript.
void PostError(const std::string& error);
// Posts an error response to JavaScript, with the message ID of the call
// which caused it.
void PostError(const std::string& error, const std::string& in_reply_to);
// Parses and executes a table check command.
void HandleCheckTable(const Json::Value& message,
const std::string& message_id);
// Called to check a table on a background thread.
void CheckTableInBackground(int32_t result, const std::string& table_name,
const std::string& message_id);
// Parses and executes a translation command.
void HandleTranslate(const Json::Value& message,
const std::string& message_id);
// Called to translate text on a background thread.
void TranslateInBackground(int32_t result, const TranslationParams& params,
const std::string& message_id);
// Parses and executes a back translation command.
void HandleBackTranslate(const Json::Value& message,
const std::string& message_id);
// Called to back-translate text on a background thread.
void BackTranslateInBackground(int32_t result,
const std::string& table_name, const std::vector<unsigned char>& cells,
const std::string& message_id);
LibLouisWrapper liblouis_;
pp::SimpleThread liblouis_thread_;
pp::CompletionCallbackFactory<LibLouisInstance> cc_factory_;
DISALLOW_COPY_AND_ASSIGN(LibLouisInstance);
};
} // namespace liblouis_nacl
#endif // LIBLOUIS_NACL_LIBLOUIS_INSTANCE_H_
// Copyright 2013 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.
#include "liblouis_module.h"
#include <cstddef>
#include "liblouis_instance.h"
namespace liblouis_nacl {
LibLouisModule::LibLouisModule() : pp::Module() {}
LibLouisModule::~LibLouisModule() {}
pp::Instance* LibLouisModule::CreateInstance(PP_Instance instance) {
static bool created = false;
if (!created) {
created = true;
return new LibLouisInstance(instance);
}
return NULL;
}
} // namespace liblouis_nacl
namespace pp {
Module* CreateModule() {
static bool created = false;
if (!created) {
created = true;
return new liblouis_nacl::LibLouisModule();
}
return NULL;
}
} // namespace pp
// Copyright 2013 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.
#ifndef LIBLOUIS_NACL_LIBLOUIS_MODULE_H_
#define LIBLOUIS_NACL_LIBLOUIS_MODULE_H_
#include "base/basictypes.h"
#include "ppapi/c/pp_instance.h"
#include "ppapi/cpp/instance.h"
#include "ppapi/cpp/module.h"
namespace liblouis_nacl {
// Native Client module which contains liblouis.
class LibLouisModule : public pp::Module {
public:
LibLouisModule();
virtual ~LibLouisModule();
virtual pp::Instance* CreateInstance(PP_Instance instance);
private:
DISALLOW_COPY_AND_ASSIGN(LibLouisModule);
};
} // namespace liblouis_nacl
#endif // LIBLOUIS_NACL_LIBLOUIS_MODULE_H_
// Copyright 2013 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.
#include "liblouis_wrapper.h"
#include <cstddef>
#include "liblouis/liblouis.h"
namespace {
// Decodes UTF-8 into 16-bit wide characters.
// This implementation is very permissive and may miss encoding errors.
// It ignores charaters which are not in the Unicode Basic Multilingual Plane.
// TODO(jbroman): Handle more than BMP if liblouis changes to accept UTF-16.
static bool DecodeUtf8(const std::string& in, std::vector<widechar>* out) {
int len = in.length();
std::vector<widechar> result;
result.reserve(len);
int i = 0;
while (i < len) {
int ch = static_cast<unsigned char>(in[i++]);
widechar cp;
if ((ch & 0x80) == 0x00) { // U+0000 - U+007F
cp = ch;
} else if ((ch & 0xe0) == 0xc0 && i < len) { // U+0080 - U+07FF
cp = (ch & 0x1f) << 6;
ch = static_cast<unsigned char>(in[i++]);
cp |= (ch & 0x3f);
} else if ((ch & 0xf0) == 0xe0 && i+1 < len) { // U+0800 - U+FFFF
cp = (ch & 0x0f) << 12;
ch = static_cast<unsigned char>(in[i++]);
cp |= (ch & 0x3f) << 6;
ch = static_cast<unsigned char>(in[i++]);
cp |= (ch & 0x3f);
} else if ((ch & 0xf8) == 0xf0 && i+2 < len) { // U+10000 - U+1FFFFF
i += 3;
continue;
} else if ((ch & 0xfc) == 0xf8 && i+3 < len) { // U+200000 - U+3FFFFFF
i += 4;
continue;
} else if ((ch & 0xfe) == 0xfc && i+4 < len) { // U+4000000 - U+7FFFFFFF
i += 5;
continue;
} else {
// Invalid first code point.
return false;
}
result.push_back(cp);
}
out->swap(result);
return true;
}
// Encodes 16-bit wide characters into UTF-8.
// This implementation is very permissive and may miss invalid code points in
// its input.
// TODO(jbroman): Handle more than BMP if widechar ever becomes larger.
static bool EncodeUtf8(const std::vector<widechar>& in, std::string* out) {
std::string result;
result.reserve(in.size() * 2);
for (std::vector<widechar>::const_iterator it = in.begin(); it != in.end();
++it) {
unsigned int cp = *it;
if (cp <= 0x007f) { // U+0000 - U+007F
result.push_back(static_cast<char>(cp));
} else if (cp <= 0x07ff) { // U+0080 - U+07FF
result.push_back(static_cast<char>(0xc0 | ((cp >> 6) & 0x1f)));
result.push_back(static_cast<char>(0x80 | (cp & 0x3f)));
} else if (cp <= 0xffff) { // U+0800 - U+FFFF
result.push_back(static_cast<char>(0xe0 | ((cp >> 12) & 0x0f)));
result.push_back(static_cast<char>(0x80 | ((cp >> 6) & 0x3f)));
result.push_back(static_cast<char>(0x80 | (cp & 0x3f)));
} else {
// This can't happen if widechar is 16 bits wide.
// TODO(jbroman): assert this
}
}
out->swap(result);
return true;
}
} // namespace
namespace liblouis_nacl {
LibLouisWrapper::LibLouisWrapper() {
char data_path[] = "/"; // Needed because lou_setDataPath takes a char*.
lou_setDataPath(data_path);
}
LibLouisWrapper::~LibLouisWrapper() {
lou_free();
}
const char* LibLouisWrapper::tables_dir() const {
return "/liblouis/tables";
}
bool LibLouisWrapper::CheckTable(const std::string& table_name) {
return lou_getTable(table_name.c_str()) != NULL;
}
bool LibLouisWrapper::Translate(const TranslationParams& params,
TranslationResult* out) {
// Convert the character set of the input text.
std::vector<widechar> inbuf;
if (!DecodeUtf8(params.text, &inbuf)) {
// TODO(jbroman): log this
return false;
}
int inlen = inbuf.size();
int outlen = inlen * 2; // TODO(jbroman): choose this size more accurately.
std::vector<widechar> outbuf(outlen);
std::vector<int> text_to_braille(inlen);
std::vector<int> braille_to_text(outlen);
// Compute the cursor position pointer to pass to liblouis.
int out_cursor_position;
int* out_cursor_position_ptr;
if (params.cursor_position < 0) {
out_cursor_position = -1;
out_cursor_position_ptr = NULL;
} else {
out_cursor_position = params.cursor_position;
out_cursor_position_ptr = &out_cursor_position;
}
// Invoke liblouis.
int result = lou_translate(params.table_name.c_str(),
&inbuf[0], &inlen, &outbuf[0], &outlen,
NULL /* typeform */, NULL /* spacing */,
&text_to_braille[0], &braille_to_text[0],
out_cursor_position_ptr, dotsIO /* mode */);
if (result == 0) {
// TODO(jbroman): log this
return false;
}
// Massage the result.
std::vector<unsigned char> cells;
cells.reserve(outlen);
for (int i = 0; i < outlen; i++) {
cells.push_back(outbuf[i]);
}
braille_to_text.resize(outlen);
// Return the translation result.
out->cells.swap(cells);
out->text_to_braille.swap(text_to_braille);
out->braille_to_text.swap(braille_to_text);
out->cursor_position = out_cursor_position;
return true;
}
bool LibLouisWrapper::BackTranslate(const std::string& table_name,
const std::vector<unsigned char>& cells, std::string* out) {
std::vector<widechar> inbuf;
inbuf.reserve(cells.size());
for (std::vector<unsigned char>::const_iterator it = cells.begin();
it != cells.end(); ++it) {
// Set the high-order bit to prevent liblouis from dropping empty cells.
inbuf.push_back(*it | 0x8000);
}
int inlen = inbuf.size();
int outlen = inlen * 2; // TODO(jbroman): choose this size more accurately.
std::vector<widechar> outbuf(outlen);
// Invoke liblouis.
int result = lou_backTranslateString(table_name.c_str(),
&inbuf[0], &inlen, &outbuf[0], &outlen,
NULL /* typeform */, NULL /* spacing */, dotsIO /* mode */);
if (result == 0) {
// TODO(njbroman): log this
return false;
}
// Massage the result.
outbuf.resize(outlen);
std::string text;
if (!EncodeUtf8(outbuf, &text)) {
// TODO(jbroman): log this
return false;
}
// Return the back translation result.
out->swap(text);
return true;
}
} // namespace liblouis_nacl
// Copyright 2013 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.
#ifndef LIBLOUIS_NACL_LIBLOUIS_WRAPPER_H_
#define LIBLOUIS_NACL_LIBLOUIS_WRAPPER_H_
#include <string>
#include "base/basictypes.h"
#include "translation_params.h"
#include "translation_result.h"
namespace liblouis_nacl {
// Encapsulates logic for interacting (synchronously) with liblouis.
//
// This class is *not* thread-safe; it should be used only from one thread.
// Since the underlying library is not reentrant, only one instance should be
// in use at a time.
//
// All input strings should be represented in UTF-8.
class LibLouisWrapper {
public:
LibLouisWrapper();
~LibLouisWrapper();
// Returns one of the paths where tables may be searched for.
const char* tables_dir() const;
// Loads, checks, and compiles the requested table.
// Returns true on success.
bool CheckTable(const std::string& table_name);
// Translates the given text and cursor position into braille.
bool Translate(const TranslationParams& params, TranslationResult* out);
// Translates the given braille cells into text.
bool BackTranslate(const std::string& table_name,
const std::vector<unsigned char>& cells, std::string* out);
private:
DISALLOW_COPY_AND_ASSIGN(LibLouisWrapper);
};
} // namespace liblouis_nacl
#endif // LIBLOUIS_NACL_LIBLOUIS_WRAPPER_H_
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/base_paths.h"
#include "base/files/file_path.h"
#include "base/path_service.h"
#include "chrome/browser/extensions/extension_apitest.h"
class LibLouisWrapperTest : public ExtensionApiTest {
};
IN_PROC_BROWSER_TEST_F(LibLouisWrapperTest, LibLouisLoad) {
ASSERT_TRUE(PathService::Get(base::DIR_EXE, &test_data_dir_));
test_data_dir_ = test_data_dir_.AppendASCII("chromevox_test_data");
LOG(ERROR) << "Test data dir: " << test_data_dir_.MaybeAsASCII();
ASSERT_TRUE(RunExtensionTest("braille")) << message_;
}
// Copyright 2013 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.
#ifndef LIBLOUIS_NACL_TRANSLATION_PARAMS_H_
#define LIBLOUIS_NACL_TRANSLATION_PARAMS_H_
#include <string>
namespace liblouis_nacl {
// Struct containing the parameters of translation.
struct TranslationParams {
public:
std::string table_name;
std::string text;
int cursor_position;
};
}
#endif // LIBLOUIS_NACL_TRANSLATION_PARAMS_H_
// Copyright 2013 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.
#ifndef LIBLOUIS_NACL_TRANSLATION_RESULT_H_
#define LIBLOUIS_NACL_TRANSLATION_RESULT_H_
#include <vector>
namespace liblouis_nacl {
// Struct containing the result of translation.
struct TranslationResult {
public:
std::vector<unsigned char> cells;
std::vector<int> text_to_braille;
std::vector<int> braille_to_text;
int cursor_position;
};
}
#endif // LIBLOUIS_NACL_TRANSLATION_RESULT_H_
/*
* Copyright 2013 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
#define TABLESDIR ""
#define PACKAGE_VERSION "2.5.1-google"
/* liblouis Braille Translation and Back-Translation Library
Based on the Linux screenreader BRLTTY, copyright (C) 1999-2006 by
The BRLTTY Team
Copyright (C) 2004, 2005, 2006, 2009 ViewPlus Technologies, Inc.
www.viewplus.com and JJB Software, Inc. www.jjb-software.com
liblouis is free software: you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
liblouis is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this program. If not, see
<http://www.gnu.org/licenses/>.
Maintained by John J. Boyer john.boyer@abilitiessoft.com
*/
#ifndef __LIBLOUIS_H_
#define __LIBLOUIS_H_
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
#define widechar unsigned short int
#ifdef _WIN32
#define EXPORT_CALL __stdcall
char * EXPORT_CALL lou_getProgramPath ();
#else
#define EXPORT_CALL
#endif
typedef enum
{
plain_text = 0,
italic = 1,
underline = 2,
bold = 4,
computer_braille = 8
} typeforms;
#define comp_emph_1 italic
#define comp_emph_2 underline
#define comp_emph_3 bold
typedef enum
{
noContractions = 1,
compbrlAtCursor = 2,
dotsIO = 4,
comp8Dots = 8,
pass1Only = 16,
compbrlLeftCursor = 32,
otherTrans = 64,
ucBrl = 128
} translationModes;
char * EXPORT_CALL lou_version ();
int EXPORT_CALL lou_charSize ();
/* Return the size of widechar */
int EXPORT_CALL lou_translateString
(const char *tableList,
const widechar *inbuf,
int *inlen,
widechar * outbuf,
int *outlen, char *typeform, char *spacing, int mode);
int EXPORT_CALL lou_translate (const char *tableList, const widechar
*inbuf,
int *inlen, widechar * outbuf, int *outlen,
char *typeform, char *spacing, int *outputPos, int
*inputPos, int *cursorPos, int mode);
int EXPORT_CALL lou_hyphenate (const char *tableList, const widechar
*inbuf,
int inlen, char *hyphens, int mode);
int EXPORT_CALL lou_dotsToChar (const char *tableList, widechar *inbuf,
widechar *outbuf, int length, int mode);
int EXPORT_CALL lou_charToDots (const char *tableList, const widechar
*inbuf,
widechar *outbuf, int length, int mode);
int EXPORT_CALL lou_backTranslateString (const char *tableList,
const widechar *inbuf,
int *inlen,
widechar * outbuf,
int *outlen, char *typeform, char
*spacing, int mode);
int EXPORT_CALL lou_backTranslate (const char *tableList, const widechar
*inbuf,
int *inlen, widechar * outbuf, int *outlen,
char *typeform, char *spacing, int
*outputPos, int *inputPos, int *cursorPos, int
mode);
void EXPORT_CALL lou_logPrint (char *format, ...);
/* prints error messages to a file */
void EXPORT_CALL lou_logFile (const char *filename);
/* Specifies the name of the file to be used by lou_logPrint. If it is
* not used, this file is stderr*/
int EXPORT_CALL lou_readCharFromFile (const char *fileName, int *mode);
/*Read a character from a file, whether big-encian, little-endian or
* ASCII8, and return it as an integer. EOF at end of file. Mode = 1 on
* first call, any other value thereafter*/
void EXPORT_CALL lou_logEnd ();
/* Closes the log file so it can be read by other functions. */
void * EXPORT_CALL lou_getTable (const char *tableList);
/* This function checks a table for errors. If none are found it loads
* the table into memory and returns a pointer to it. if errors are found
* it returns a null pointer. It is called by lou_translateString and
* lou_backTranslateString and also by functions in liblouisxml
*/
int EXPORT_CALL lou_compileString (const char *tableList, const char
*inString);
char * EXPORT_CALL lou_setDataPath (char *path);
/* Set the path used for searching for tables and liblouisutdml files.
* Overrides the installation path. */
char * EXPORT_CALL lou_getDataPath ();
/* Get the path set in the previous function. */
// char EXPORT_CALL * lou_getTablePaths ();
/* Get a list of paths actually used in seraching for tables*/
void EXPORT_CALL lou_free ();
/* This function should be called at the end of
* the application to free all memory allocated by liblouis. */
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /*LibLOUIS_H_ */
This diff is collapsed.
This diff is collapsed.
[
{
"locale": "ar",
"dots": "6",
"id": "ar-g1",
"grade": "1",
"fileName": "ar-ar-g1.utb"
},
{
"locale": "bg",
"dots": "8",
"id": "bg-comp8",
"fileName": "bg.ctb"
},
{
"locale": "ca",
"dots": "6",
"id": "ca-g1",
"grade": "1",
"fileName": "ca-g1.ctb"
},
{
"locale": "hr",
"dots": "8",
"id": "hr-comp8",
"fileName": "hr.ctb"
},
{
"locale": "cs",
"dots": "6",
"id": "cs-g1",
"grade": "1",
"fileName": "cs-g1.ctb"
},
{
"locale": "da",
"dots": "8",
"id": "da-comp8",
"fileName": "da.ctb"
},
{
"locale": "nl",
"dots": "6",
"id": "nl-g1",
"grade": "1",
"fileName": "Nl-Nl-g1.utb"
},
{
"locale": "en_CA",
"dots": "8",
"id": "en-CA-comp8",
"fileName": "en_CA.ctb"
},
{
"locale": "en_GB",
"dots": "6",
"id": "en-GB-g1",
"grade": "1",
"fileName": "en-gb-g1.utb"
},
{
"locale": "en_GB",
"dots": "6",
"id": "en-GB-g2",
"grade": "2",
"fileName": "en-GB-g2.ctb"
},
{
"locale": "en_US",
"dots": "8",
"id": "en-US-comp8",
"fileName": "en-us-comp8.ctb"
},
{
"locale": "en_US",
"dots": "6",
"id": "en-US-g1",
"grade": "1",
"fileName": "en-us-g1.ctb"
},
{
"locale": "en_US",
"dots": "6",
"id": "en-US-g2",
"grade": "2",
"fileName": "en-us-g2.ctb"
},
{
"locale": "et",
"dots": "8",
"id": "et-comp8",
"fileName": "et-g0.utb"
},
{
"locale": "fr",
"dots": "8",
"id": "fr-comp8",
"fileName": "fr-2007.ctb"
},
{
"locale": "fr_CA",
"dots": "6",
"id": "fr-CA-g1",
"grade": "1",
"fileName": "fr-ca-g1.utb"
},
{
"locale": "fr_CA",
"dots": "6",
"id": "fr-CA-g2",
"grade": "2",
"fileName": "Fr-Ca-g2.ctb"
},
{
"locale": "fr_FR",
"dots": "6",
"id": "fr-FR-g1",
"grade": "1",
"fileName": "fr-fr-g1.utb"
},
{
"locale": "fr_FR",
"dots": "6",
"id": "fr-FR-g2",
"grade": "2",
"fileName": "Fr-Fr-g2.ctb"
},
{
"locale": "fi",
"dots": "8",
"id": "fi-comp8",
"fileName": "fi-fi-8dot.ctb"
},
{
"locale": "de",
"dots": "8",
"id": "de-comp8",
"fileName": "de-de-comp8.ctb"
},
{
"locale": "de_CH",
"dots": "6",
"id": "de-CH-g0",
"grade": "0",
"fileName": "de-ch-g0.utb"
},
{
"locale": "de_CH",
"dots": "6",
"id": "de-CH-g1",
"grade": "1",
"fileName": "de-ch-g1.ctb"
},
{
"locale": "de_CH",
"dots": "6",
"id": "de-CH-g2",
"grade": "2",
"fileName": "de-ch-g2.ctb"
},
{
"locale": "de_DE",
"dots": "6",
"id": "de-DE-g0",
"grade": "0",
"fileName": "de-de-g0.utb"
},
{
"locale": "de_DE",
"dots": "6",
"id": "de-DE-g1",
"grade": "1",
"fileName": "de-de-g1.ctb"
},
{
"locale": "de_DE",
"dots": "6",
"id": "de-DE-g2",
"grade": "2",
"fileName": "de-de-g2.ctb"
},
{
"locale": "el",
"dots": "6",
"id": "el-g1",
"grade": "1",
"fileName": "gr-gr-g1.utb"
},
{
"locale": "hi",
"dots": "8",
"id": "hi-comp8",
"fileName": "hi.ctb"
},
{
"locale": "hi",
"dots": "6",
"id": "hi-g1",
"grade": "1",
"fileName": "hi-in-g1.utb"
},
{
"locale": "hu",
"dots": "8",
"id": "hu-comp8",
"fileName": "hu-hu-comp8.ctb"
},
{
"locale": "hu",
"dots": "6",
"id": "hu-g1",
"grade": "1",
"fileName": "hu-hu-g1.ctb"
},
{
"locale": "is",
"dots": "8",
"id": "is-comp8",
"fileName": "is.ctb"
},
{
"locale": "it",
"dots": "8",
"id": "it-comp8",
"fileName": "it-it-comp8.utb"
},
{
"locale": "it",
"dots": "6",
"id": "it-g1",
"grade": "1",
"fileName": "it-it-comp6.utb"
},
{
"locale": "lv",
"dots": "6",
"id": "lv-g1",
"grade": "1",
"fileName": "Lv-Lv-g1.utb"
},
{
"locale": "lt",
"dots": "8",
"id": "lt-comp8",
"fileName": "lt.ctb"
},
{
"locale": "nb",
"dots": "8",
"id": "nb-comp8",
"fileName": "no-no.ctb"
},
{
"locale": "nb",
"dots": "6",
"id": "nb-g0",
"grade": "0",
"fileName": "no-no-g0.utb"
},
{
"locale": "nb",
"dots": "6",
"id": "nb-g1",
"grade": "1",
"fileName": "no-no-g1.ctb"
},
{
"locale": "nb",
"dots": "6",
"id": "nb-g2",
"grade": "2",
"fileName": "no-no-g2.ctb"
},
{
"locale": "nb",
"dots": "6",
"id": "nb-g3",
"grade": "3",
"fileName": "no-no-g3.ctb"
},
{
"locale": "pl",
"dots": "6",
"id": "pl-g1",
"grade": "1",
"fileName": "Pl-Pl-g1.utb"
},
{
"locale": "pt",
"dots": "8",
"id": "pt-comp8",
"fileName": "pt-pt-comp8.ctb"
},
{
"locale": "pt",
"dots": "6",
"id": "pt-g1",
"grade": "1",
"fileName": "pt-pt-g1.utb"
},
{
"locale": "pt",
"dots": "6",
"id": "pt-g2",
"grade": "2",
"fileName": "pt-pt-g2.ctb"
},
{
"locale": "ro",
"dots": "8",
"id": "ro-comp8",
"fileName": "ro.ctb"
},
{
"locale": "ru",
"dots": "8",
"id": "ru-comp8",
"fileName": "ru.ctb"
},
{
"locale": "ru",
"dots": "6",
"id": "ru-g1",
"grade": "1",
"fileName": "ru-ru-g1.utb"
},
{
"locale": "sr",
"dots": "6",
"id": "sr-g1",
"grade": "1",
"fileName": "sr-g1.ctb"
},
{
"locale": "sk",
"dots": "6",
"id": "sk-g1",
"grade": "1",
"fileName": "sk-sk-g1.utb"
},
{
"locale": "sl",
"dots": "6",
"id": "sl-g1",
"grade": "1",
"fileName": "sl-si-g1.utb"
},
{
"locale": "es",
"dots": "8",
"id": "es-comp8",
"fileName": "Es-Es-G0.utb"
},
{
"locale": "es",
"dots": "6",
"id": "es-g1",
"grade": "1",
"fileName": "es-g1.ctb"
},
{
"locale": "sv",
"dots": "8",
"id": "sv-comp8",
"fileName": "sv-1996.ctb"
},
{
"locale": "sv",
"dots": "6",
"id": "sv-g1",
"grade": "1",
"fileName": "Se-Se-g1.utb"
},
{
"locale": "tr",
"dots": "8",
"id": "tr-comp8",
"fileName": "tr.ctb"
},
{
"locale": "vi",
"dots": "8",
"id": "vi-comp8",
"fileName": "vi.ctb"
},
{
"locale": "zh",
"dots": "8",
"id": "zh-comp8",
"fileName": "zh-hk.ctb"
},
{
"locale": "zh_TW",
"dots": "8",
"id": "zh-TW-comp8",
"fileName": "zh-tw.ctb"
}
]
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment