fix utf-16 reading and make it work on android
This commit is contained in:
@@ -31,6 +31,7 @@ add_library(
|
|||||||
../libs/poly2tri/poly2tri/sweep/cdt.cc
|
../libs/poly2tri/poly2tri/sweep/cdt.cc
|
||||||
../libs/poly2tri/poly2tri/sweep/sweep_context.cc
|
../libs/poly2tri/poly2tri/sweep/sweep_context.cc
|
||||||
../libs/poly2tri/poly2tri/sweep/sweep.cc
|
../libs/poly2tri/poly2tri/sweep/sweep.cc
|
||||||
|
../libs/fmt/src/format.cc
|
||||||
src/main/cpp/main.cpp
|
src/main/cpp/main.cpp
|
||||||
../src/pch.cpp
|
../src/pch.cpp
|
||||||
../src/util.cpp
|
../src/util.cpp
|
||||||
@@ -91,6 +92,7 @@ add_library(
|
|||||||
../src/node_usermanual.cpp
|
../src/node_usermanual.cpp
|
||||||
../src/node_viewport.cpp
|
../src/node_viewport.cpp
|
||||||
../src/node_scroll.cpp
|
../src/node_scroll.cpp
|
||||||
|
../src/abr.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
target_include_directories(native-lib PRIVATE
|
target_include_directories(native-lib PRIVATE
|
||||||
@@ -107,6 +109,8 @@ target_include_directories(native-lib PRIVATE
|
|||||||
../libs/sqlite3
|
../libs/sqlite3
|
||||||
../libs/nanort
|
../libs/nanort
|
||||||
../libs/native_app_glue
|
../libs/native_app_glue
|
||||||
|
../libs/hash-library
|
||||||
|
../libs/fmt/include
|
||||||
)
|
)
|
||||||
|
|
||||||
# add lib dependencies
|
# add lib dependencies
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ public class MainActivity extends NativeActivity {
|
|||||||
|
|
||||||
}
|
}
|
||||||
// patterns
|
// patterns
|
||||||
File patterns = new File(pano_dir.getAbsolutePath(), "brushes");
|
File patterns = new File(pano_dir.getAbsolutePath(), "patterns");
|
||||||
if (!patterns.exists())
|
if (!patterns.exists())
|
||||||
{
|
{
|
||||||
if (patterns.mkdirs())
|
if (patterns.mkdirs())
|
||||||
|
|||||||
26
src/abr.cpp
26
src/abr.cpp
@@ -1,5 +1,6 @@
|
|||||||
#include "pch.h"
|
#include "pch.h"
|
||||||
#include "abr.h"
|
#include "abr.h"
|
||||||
|
#include "log.h"
|
||||||
|
|
||||||
bool ABR::section_desc()
|
bool ABR::section_desc()
|
||||||
{
|
{
|
||||||
@@ -20,7 +21,11 @@ bool ABR::section_desc()
|
|||||||
m_presets.push_back(desc);
|
m_presets.push_back(desc);
|
||||||
}
|
}
|
||||||
auto out = presets->str(0, "");
|
auto out = presets->str(0, "");
|
||||||
std::cout << out << '\n';
|
auto lines = split(out, '\n');
|
||||||
|
for (const auto& l : lines)
|
||||||
|
{
|
||||||
|
LOG("%s", l.c_str());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -63,7 +68,7 @@ bool ABR::section_patt()
|
|||||||
auto image_mode = ru32();
|
auto image_mode = ru32();
|
||||||
if (!(image_mode == 1 || image_mode == 3))
|
if (!(image_mode == 1 || image_mode == 3))
|
||||||
{
|
{
|
||||||
printf("PATT: skip image mode %d\n", image_mode);
|
LOG("PATT: skip image mode %d\n", image_mode);
|
||||||
skip(patt_length - 8);
|
skip(patt_length - 8);
|
||||||
snap();
|
snap();
|
||||||
continue;
|
continue;
|
||||||
@@ -83,7 +88,7 @@ bool ABR::section_patt()
|
|||||||
int nc = std::min((int)vm->channels.size(), 3);
|
int nc = std::min((int)vm->channels.size(), 3);
|
||||||
if (nc != image_mode)
|
if (nc != image_mode)
|
||||||
{
|
{
|
||||||
printf("PATT: image_mode (%d) and number of channels (%d) not matching\n",
|
LOG("PATT: image_mode (%d) and number of channels (%d) not matching\n",
|
||||||
image_mode, vm->channels.size());
|
image_mode, vm->channels.size());
|
||||||
}
|
}
|
||||||
if (auto img = vm->image(true))
|
if (auto img = vm->image(true))
|
||||||
@@ -135,12 +140,13 @@ std::vector<std::shared_ptr<Brush>> ABR::compute_brushes(const std::string& path
|
|||||||
//b->m_blend_mode = i.m_blend_mode;
|
//b->m_blend_mode = i.m_blend_mode;
|
||||||
//b->m_name.resize(i.m_name_len);
|
//b->m_name.resize(i.m_name_len);
|
||||||
//b->m_stencil_path.resize(i.m_stencil_path_len);
|
//b->m_stencil_path.resize(i.m_stencil_path_len);
|
||||||
auto& tip_uid = wstr2str(samp->value<String>("sampledData"));
|
auto tip_uid = wstr2str(samp->value<String>("sampledData"));
|
||||||
|
LOG("tip uid %d %s", tip_uid.size(), tip_uid.c_str());
|
||||||
b->m_brush_path = path + "/brushes/" + tip_uid + ".png";
|
b->m_brush_path = path + "/brushes/" + tip_uid + ".png";
|
||||||
b->m_brush_thumb_path = path + "/brushes/thumbs/" + tip_uid + ".png";
|
b->m_brush_thumb_path = path + "/brushes/thumbs/" + tip_uid + ".png";
|
||||||
if (auto patt = p->get<Descriptor>("Txtr"))
|
if (auto patt = p->get<Descriptor>("Txtr"))
|
||||||
{
|
{
|
||||||
auto& patt_uid = wstr2str(patt->value<String>("Idnt"));
|
auto patt_uid = wstr2str(patt->value<String>("Idnt"));
|
||||||
b->m_stencil_path = path + "/patterns/" + patt_uid + ".png";
|
b->m_stencil_path = path + "/patterns/" + patt_uid + ".png";
|
||||||
//b->m_brush_thumb_path = path + "/patterns/thumbs/" + patt_uid + ".png";
|
//b->m_brush_thumb_path = path + "/patterns/thumbs/" + patt_uid + ".png";
|
||||||
b->m_tip_stencil = p->value<UnitFloat>("textureDepth") * 0.01f;
|
b->m_tip_stencil = p->value<UnitFloat>("textureDepth") * 0.01f;
|
||||||
@@ -179,7 +185,7 @@ std::shared_ptr<ABR::VMArray> ABR::parse_vmem()
|
|||||||
auto compression = ru8(); // 1 = zip
|
auto compression = ru8(); // 1 = zip
|
||||||
if (depth != 8)
|
if (depth != 8)
|
||||||
{
|
{
|
||||||
printf("unsupported depth %d bits\n", depth);
|
LOG("unsupported depth %d bits\n", depth);
|
||||||
skip(length - 23);
|
skip(length - 23);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -208,7 +214,7 @@ std::shared_ptr<ABR::VMArray> ABR::parse_vmem()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
printf("unsupported compression mode %d\n", compression);
|
LOG("unsupported compression mode %d\n", compression);
|
||||||
skip(length - 23);
|
skip(length - 23);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -257,7 +263,7 @@ std::shared_ptr<ABR::Descriptor> ABR::parse_objc()
|
|||||||
if (!property)
|
if (!property)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
if (ret->props.find(key) != ret->props.end())
|
if (ret->props.find(key) != ret->props.end())
|
||||||
printf("DUPLICATE prop %d\n", key.c_str());
|
LOG("DUPLICATE prop %d\n", key.c_str());
|
||||||
ret->props[key] = property;
|
ret->props[key] = property;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
@@ -336,7 +342,7 @@ bool ABR::open(const std::string& path)
|
|||||||
init(asset.read_all(), asset.m_len, BinaryStream::ByteOrder::BigEndian);
|
init(asset.read_all(), asset.m_len, BinaryStream::ByteOrder::BigEndian);
|
||||||
auto version_major = ru16();
|
auto version_major = ru16();
|
||||||
auto version_minor = ru16();
|
auto version_minor = ru16();
|
||||||
printf("ABR %d.%d\n", version_major, version_minor);
|
LOG("ABR %d.%d\n", version_major, version_minor);
|
||||||
while (!eof())
|
while (!eof())
|
||||||
{
|
{
|
||||||
if (rstring(4) != "8BIM")
|
if (rstring(4) != "8BIM")
|
||||||
@@ -356,7 +362,7 @@ bool ABR::open(const std::string& path)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
printf("skip section %s\n", t.c_str());
|
LOG("skip section %s\n", t.c_str());
|
||||||
skip(align4(ru32()));
|
skip(align4(ru32()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
19
src/abr.h
19
src/abr.h
@@ -5,6 +5,7 @@
|
|||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "image.h"
|
#include "image.h"
|
||||||
#include "brush.h"
|
#include "brush.h"
|
||||||
|
#include "log.h"
|
||||||
|
|
||||||
class BinaryStream
|
class BinaryStream
|
||||||
{
|
{
|
||||||
@@ -19,7 +20,7 @@ public:
|
|||||||
|
|
||||||
return bint.c[0] == 1 ? ByteOrder::BigEndian : ByteOrder::LittleEndian;
|
return bint.c[0] == 1 ? ByteOrder::BigEndian : ByteOrder::LittleEndian;
|
||||||
}
|
}
|
||||||
BinaryStream(const BinaryParam&) = delete;
|
BinaryStream(const BinaryStream&) = delete;
|
||||||
BinaryStream() = default;
|
BinaryStream() = default;
|
||||||
~BinaryStream()
|
~BinaryStream()
|
||||||
{
|
{
|
||||||
@@ -66,13 +67,17 @@ public:
|
|||||||
std::wstring rwstring(size_t len)
|
std::wstring rwstring(size_t len)
|
||||||
{
|
{
|
||||||
auto ptr = advance<char>(len * 2);
|
auto ptr = advance<char>(len * 2);
|
||||||
for (int i = 0; i < len; i++)
|
//for (int i = 0; i < len; i++)
|
||||||
std::swap(ptr[i * 2], ptr[i * 2 + 1]);
|
// std::swap(ptr[i * 2], ptr[i * 2 + 1]);
|
||||||
|
|
||||||
// right trim trailing zeroes
|
// right trim trailing zeroes
|
||||||
auto wptr = (wchar_t*)ptr;
|
auto wptr = (uint16_t*)ptr;
|
||||||
for (int i = len - 1; i >= 0; i--)
|
for (int i = len - 1; i >= 0; i--)
|
||||||
if (wptr[i] == 0) len--;
|
if (wptr[i] == 0) len--;
|
||||||
return std::wstring(wptr, len);
|
|
||||||
|
// wide to UTF-16le
|
||||||
|
std::wstring_convert<std::codecvt_utf16<wchar_t, 0x10ffff>> converter;
|
||||||
|
return converter.from_bytes(ptr, ptr + len * 2);
|
||||||
}
|
}
|
||||||
std::string rpascal()
|
std::string rpascal()
|
||||||
{
|
{
|
||||||
@@ -168,7 +173,7 @@ protected:
|
|||||||
return *reinterpret_cast<T*>(&y);
|
return *reinterpret_cast<T*>(&y);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
auto p = reinterpret_cast<uint16_t*>(&x);
|
auto p = reinterpret_cast<uint8_t*>(&x);
|
||||||
if (sizeof(T) == 2)
|
if (sizeof(T) == 2)
|
||||||
{
|
{
|
||||||
std::swap(p[0], p[1]);
|
std::swap(p[0], p[1]);
|
||||||
@@ -347,7 +352,7 @@ class ABR : private BinaryStream
|
|||||||
uint8_t compression;
|
uint8_t compression;
|
||||||
std::vector<uint8_t> data;
|
std::vector<uint8_t> data;
|
||||||
Channel() = default;
|
Channel() = default;
|
||||||
Channel(uint32_t depth, const Rectangle& rect, uint8_t compression, std::vector<uint8_t>& data) :
|
Channel(uint32_t depth, Rectangle rect, uint8_t compression, std::vector<uint8_t> data) :
|
||||||
depth(depth), rect(rect), compression(compression), data(std::move(data)) { }
|
depth(depth), rect(rect), compression(compression), data(std::move(data)) { }
|
||||||
};
|
};
|
||||||
struct VMArray : public Type
|
struct VMArray : public Type
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ void App::pick_file(std::vector<std::string> types, std::function<void (std::str
|
|||||||
callback(path);
|
callback(path);
|
||||||
});
|
});
|
||||||
#elif __ANDROID__
|
#elif __ANDROID__
|
||||||
//android_pick_file(and_app, callback);
|
android_pick_file(and_app, callback);
|
||||||
#elif _WIN32
|
#elif _WIN32
|
||||||
std::string filter = "Supported Files (";
|
std::string filter = "Supported Files (";
|
||||||
bool first_type = true;
|
bool first_type = true;
|
||||||
|
|||||||
@@ -139,13 +139,25 @@ bool Asset::open(const char* path)
|
|||||||
m_current_path = path;
|
m_current_path = path;
|
||||||
std::string file_path = path;
|
std::string file_path = path;
|
||||||
#ifdef __ANDROID__
|
#ifdef __ANDROID__
|
||||||
if (!(m_asset = AAssetManager_open(m_am, path, AASSET_MODE_RANDOM)))
|
if (is_asset(path))
|
||||||
{
|
{
|
||||||
LOG("AAssetManager_open failed %s", path);
|
if (!(m_asset = AAssetManager_open(m_am, path, AASSET_MODE_RANDOM)))
|
||||||
return false;
|
{
|
||||||
|
LOG("AAssetManager_open failed %s", path);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!(m_fp = fopen(file_path.c_str(), "rb")))
|
||||||
|
{
|
||||||
|
LOG("asset open errno = %d, %s", errno, path);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
fseek(m_fp, 0, SEEK_END);
|
||||||
|
m_len = (int)ftell(m_fp);
|
||||||
|
fseek(m_fp, 0, SEEK_SET);
|
||||||
}
|
}
|
||||||
m_len = (int)AAsset_getLength(m_asset);
|
|
||||||
m_data = (uint8_t*)AAsset_getBuffer(m_asset);
|
|
||||||
#else
|
#else
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
NSString* bundle_path = [[NSBundle mainBundle] resourcePath];
|
NSString* bundle_path = [[NSBundle mainBundle] resourcePath];
|
||||||
@@ -168,6 +180,24 @@ bool Asset::open(const char* path)
|
|||||||
glm::uint8_t* Asset::read_all()
|
glm::uint8_t* Asset::read_all()
|
||||||
{
|
{
|
||||||
#ifdef __ANDROID__
|
#ifdef __ANDROID__
|
||||||
|
if (!m_data)
|
||||||
|
{
|
||||||
|
if (is_asset(m_current_path))
|
||||||
|
{
|
||||||
|
m_len = (int)AAsset_getLength(m_asset);
|
||||||
|
m_data = (uint8_t*)AAsset_getBuffer(m_asset);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_data = new uint8_t[m_len];
|
||||||
|
if (m_len != fread(m_data, 1, m_len, m_fp))
|
||||||
|
{
|
||||||
|
LOG("ASSET READ FAILED for %s", m_current_path.c_str());
|
||||||
|
delete[] m_data;
|
||||||
|
m_data = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return m_data;
|
return m_data;
|
||||||
#else
|
#else
|
||||||
if (!m_data)
|
if (!m_data)
|
||||||
|
|||||||
@@ -286,7 +286,11 @@ bool Brush::load()
|
|||||||
{
|
{
|
||||||
m_tip_texture = std::make_shared<Texture2D>();
|
m_tip_texture = std::make_shared<Texture2D>();
|
||||||
if (!m_tip_texture->load(m_brush_path))
|
if (!m_tip_texture->load(m_brush_path))
|
||||||
|
{
|
||||||
|
LOG("failed to load %s", m_brush_path.c_str());
|
||||||
|
m_tip_texture = nullptr;
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
m_tip_texture->create_mipmaps();
|
m_tip_texture->create_mipmaps();
|
||||||
m_tip_texture->auto_destroy = true;
|
m_tip_texture->auto_destroy = true;
|
||||||
}
|
}
|
||||||
@@ -294,7 +298,12 @@ bool Brush::load()
|
|||||||
{
|
{
|
||||||
m_stencil_texture = std::make_shared<Texture2D>();
|
m_stencil_texture = std::make_shared<Texture2D>();
|
||||||
if (!m_stencil_texture->load(m_stencil_path))
|
if (!m_stencil_texture->load(m_stencil_path))
|
||||||
|
{
|
||||||
|
LOG("failed to load %s", m_stencil_path.c_str());
|
||||||
|
m_tip_texture = nullptr;
|
||||||
|
m_stencil_texture = nullptr;
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
m_stencil_texture->create_mipmaps();
|
m_stencil_texture->create_mipmaps();
|
||||||
m_stencil_texture->auto_destroy = true;
|
m_stencil_texture->auto_destroy = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,7 +41,10 @@ bool Image::load_file(std::string filename)
|
|||||||
|
|
||||||
bool Image::save(const std::string& path)
|
bool Image::save(const std::string& path)
|
||||||
{
|
{
|
||||||
return stbi_write_png(path.c_str(), width, height, comp, data(), 0);
|
bool ret = stbi_write_png(path.c_str(), width, height, comp, data(), 0);
|
||||||
|
if (!ret)
|
||||||
|
LOG("failed Image::save %s", path.c_str());
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Image::flip()
|
void Image::flip()
|
||||||
|
|||||||
@@ -65,7 +65,14 @@ void NodePanelBrush::init()
|
|||||||
if (str_iequals(ext, "abr"))
|
if (str_iequals(ext, "abr"))
|
||||||
{
|
{
|
||||||
ABR abr;
|
ABR abr;
|
||||||
abr.open(path);
|
LOG("ABR detected");
|
||||||
|
|
||||||
|
if (!abr.open(path))
|
||||||
|
{
|
||||||
|
LOG("ABR read failed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (const auto& samp : abr.m_samples)
|
for (const auto& samp : abr.m_samples)
|
||||||
{
|
{
|
||||||
std::string path_high = App::I.data_path + "/brushes/" + samp.first + ".png";
|
std::string path_high = App::I.data_path + "/brushes/" + samp.first + ".png";
|
||||||
@@ -101,8 +108,13 @@ void NodePanelBrush::init()
|
|||||||
for (const auto& pr : brushes)
|
for (const auto& pr : brushes)
|
||||||
{
|
{
|
||||||
auto presets = App::I.stroke->m_presets_popup;
|
auto presets = App::I.stroke->m_presets_popup;
|
||||||
|
async_start();
|
||||||
if (pr->load())
|
if (pr->load())
|
||||||
|
{
|
||||||
|
LOG("add preset %s", pr->m_name.c_str());
|
||||||
presets->add_brush(pr);
|
presets->add_brush(pr);
|
||||||
|
}
|
||||||
|
async_end();
|
||||||
}
|
}
|
||||||
//save();
|
//save();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user