mirror of
https://github.com/ByteWelder/Tactility.git
synced 2026-10-19 20:05:06 +00:00
Compare commits
2 Commits
21b100b789
...
4279a8ed72
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4279a8ed72 | ||
|
|
bdb50505e7 |
Binary file not shown.
@ -119,7 +119,7 @@ def main():
|
||||
shared.generate_tactility_sdk_top_cmakelists(target_path)
|
||||
|
||||
# Output ESP-IDF SDK version to file
|
||||
with open(os.path.join(target_path, "idf-version.txt"), "a") as f:
|
||||
with open(os.path.join(target_path, "idf-version.txt"), "w") as f:
|
||||
f.write(esp_idf_version)
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
app-module
|
||||
audio-decoder-module
|
||||
cjson-module
|
||||
crypt-module
|
||||
gps-module
|
||||
http-module
|
||||
|
||||
@ -84,3 +84,27 @@ CONFIG_ESP_WIFI_AMPDU_TX_ENABLED=y
|
||||
CONFIG_ESP_WIFI_TX_BA_WIN=5
|
||||
CONFIG_ESP_WIFI_AMPDU_RX_ENABLED=y
|
||||
CONFIG_ESP_WIFI_RX_BA_WIN=5
|
||||
# Audio codec: audio-stream only decodes (never encodes), and AudiobookPlayer (the only current
|
||||
# consumer) is MP3-only. Disabling the rest saves several hundred KB of flash across every device;
|
||||
# re-enable a specific decoder here if a future app needs it.
|
||||
CONFIG_AUDIO_DECODER_AAC_SUPPORT=n
|
||||
CONFIG_AUDIO_DECODER_G711_SUPPORT=n
|
||||
CONFIG_AUDIO_DECODER_AMRNB_SUPPORT=n
|
||||
CONFIG_AUDIO_DECODER_AMRWB_SUPPORT=n
|
||||
CONFIG_AUDIO_DECODER_FLAC_SUPPORT=n
|
||||
CONFIG_AUDIO_DECODER_OPUS_SUPPORT=n
|
||||
CONFIG_AUDIO_DECODER_VORBIS_SUPPORT=n
|
||||
CONFIG_AUDIO_DECODER_ADPCM_SUPPORT=n
|
||||
CONFIG_AUDIO_DECODER_ALAC_SUPPORT=n
|
||||
CONFIG_AUDIO_DECODER_SBC_SUPPORT=n
|
||||
CONFIG_AUDIO_DECODER_LC3_SUPPORT=n
|
||||
CONFIG_AUDIO_ENCODER_AAC_SUPPORT=n
|
||||
CONFIG_AUDIO_ENCODER_G711_SUPPORT=n
|
||||
CONFIG_AUDIO_ENCODER_AMRNB_SUPPORT=n
|
||||
CONFIG_AUDIO_ENCODER_AMRWB_SUPPORT=n
|
||||
CONFIG_AUDIO_ENCODER_OPUS_SUPPORT=n
|
||||
CONFIG_AUDIO_ENCODER_ADPCM_SUPPORT=n
|
||||
CONFIG_AUDIO_ENCODER_ALAC_SUPPORT=n
|
||||
CONFIG_AUDIO_ENCODER_SBC_SUPPORT=n
|
||||
CONFIG_AUDIO_ENCODER_LC3_SUPPORT=n
|
||||
CONFIG_AUDIO_ENCODER_PCM_SUPPORT=n
|
||||
|
||||
@ -124,9 +124,12 @@ if (NOT DEFINED ENV{ESP_IDF_VERSION})
|
||||
add_subdirectory(Libraries/minitar)
|
||||
add_subdirectory(Libraries/minmea)
|
||||
add_subdirectory(Modules/lvgl-module)
|
||||
add_subdirectory(Modules/audio-decoder-module)
|
||||
add_subdirectory(Modules/c-symbols-module)
|
||||
add_subdirectory(Modules/cjson-module)
|
||||
add_subdirectory(Modules/cpp-symbols-module)
|
||||
add_subdirectory(Modules/crypt-module)
|
||||
add_subdirectory(Modules/font-module)
|
||||
add_subdirectory(Modules/freertos-module)
|
||||
add_subdirectory(Modules/gps-module)
|
||||
add_subdirectory(Modules/http-module)
|
||||
@ -139,6 +142,9 @@ if (NOT DEFINED ENV{ESP_IDF_VERSION})
|
||||
add_subdirectory(Modules/lvgl-window-manager-module)
|
||||
add_subdirectory(Drivers/gps-generic-module)
|
||||
add_subdirectory(Drivers/gps-meshtastic-module)
|
||||
# Kernel-only software aggregate; built on sim so its device-lifecycle behavior
|
||||
# is covered by Drivers/audio-stream-module/tests.
|
||||
add_subdirectory(Drivers/audio-stream-module)
|
||||
|
||||
# FreeRTOS
|
||||
set(FREERTOS_CONFIG_FILE_DIRECTORY ${PROJECT_SOURCE_DIR}/Devices/simulator/Source CACHE STRING "")
|
||||
|
||||
@ -152,5 +152,5 @@ void cl32_power_detect_start() {
|
||||
}
|
||||
|
||||
void cl32_power_detect_stop() {
|
||||
device_listener_remove(on_i2c0_started);
|
||||
device_listener_remove(on_i2c0_started, nullptr);
|
||||
}
|
||||
|
||||
@ -49,7 +49,7 @@ static error_t start() {
|
||||
}
|
||||
|
||||
static error_t stop() {
|
||||
device_listener_remove(on_device_event);
|
||||
device_listener_remove(on_device_event, nullptr);
|
||||
return ERROR_NONE;
|
||||
}
|
||||
|
||||
|
||||
@ -141,5 +141,5 @@ void tab5_detect_start() {
|
||||
}
|
||||
|
||||
void tab5_detect_stop() {
|
||||
device_listener_remove(on_display_detect_event);
|
||||
device_listener_remove(on_display_detect_event, nullptr);
|
||||
}
|
||||
|
||||
@ -6,12 +6,24 @@
|
||||
#include <lvgl/lvgl.h>
|
||||
#include <lvgl.h>
|
||||
|
||||
#include <atomic>
|
||||
|
||||
static lv_display_rotation_t saved_rotation = LV_DISPLAY_ROTATION_0;
|
||||
static bool rotation_override_active = false;
|
||||
// device_listener_remove() doesn't wait for an in-flight on_device_event() callback to finish -
|
||||
// a DEVICE_EVENT_STARTED already snapshotted by device_listener_notify() can still fire after
|
||||
// stop() has run. This flag makes such a late callback a no-op instead of re-applying the
|
||||
// override after shutdown.
|
||||
static std::atomic<bool> listener_active { false };
|
||||
|
||||
static void apply_rotation(bool attached) {
|
||||
lvgl_lock();
|
||||
|
||||
if (attached && !listener_active.load(std::memory_order_acquire)) {
|
||||
lvgl_unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
auto* display = lv_display_get_default();
|
||||
if (display == nullptr) {
|
||||
lvgl_unlock();
|
||||
@ -37,7 +49,7 @@ static void apply_rotation(bool attached) {
|
||||
}
|
||||
|
||||
static void on_device_event(Device* device, DeviceEvent event, void*) {
|
||||
if (!device_is_compatible(device, "m5stack,tab5-keyboard")) {
|
||||
if (!listener_active.load(std::memory_order_acquire) || !device_is_compatible(device, "m5stack,tab5-keyboard")) {
|
||||
return;
|
||||
}
|
||||
if (event == DEVICE_EVENT_STARTED) {
|
||||
@ -49,10 +61,13 @@ static void on_device_event(Device* device, DeviceEvent event, void*) {
|
||||
|
||||
void tab5_keyboard_lvgl_rotation_start() {
|
||||
rotation_override_active = false;
|
||||
listener_active.store(true, std::memory_order_release);
|
||||
device_listener_add(on_device_event, nullptr);
|
||||
}
|
||||
|
||||
void tab5_keyboard_lvgl_rotation_stop() {
|
||||
// Set before apply_rotation()/device_listener_remove(): a late in-flight callback must no-op.
|
||||
listener_active.store(false, std::memory_order_release);
|
||||
apply_rotation(false);
|
||||
device_listener_remove(on_device_event);
|
||||
device_listener_remove(on_device_event, nullptr);
|
||||
}
|
||||
|
||||
@ -77,7 +77,7 @@ static error_t start() {
|
||||
static error_t stop() {
|
||||
tab5_keyboard_lvgl_rotation_stop();
|
||||
tab5_headphone_detect_stop();
|
||||
device_listener_remove(on_io_expander0_started);
|
||||
device_listener_remove(on_io_expander0_started, nullptr);
|
||||
tab5_detect_stop();
|
||||
return ERROR_NONE;
|
||||
}
|
||||
|
||||
@ -55,4 +55,10 @@ sdkconfig.CONFIG_LV_DEF_REFR_PERIOD=15
|
||||
# SC202CS (SC2356) MIPI CSI camera sensor + ISP pipeline (AE/AWB/demosaicing)
|
||||
sdkconfig.CONFIG_CAMERA_SC202CS=y
|
||||
sdkconfig.CONFIG_CAMERA_SC202CS_AUTO_DETECT_MIPI_INTERFACE_SENSOR=y
|
||||
sdkconfig.CONFIG_ESP_VIDEO_ENABLE_ISP_PIPELINE_CONTROLLER=y
|
||||
# Pipeline disabled until espressif fixes their damn bugs, camera still works but looks bad.
|
||||
# Pipeline enabled with idf 6.1 currently spams the log with errors and also breaks the camera functioning.
|
||||
sdkconfig.CONFIG_ESP_VIDEO_ENABLE_ISP_PIPELINE_CONTROLLER=n
|
||||
# USB audio: 16 ms of isochronous transfers tolerates short display/decoder
|
||||
# scheduling bursts better than the component's 9 ms default.
|
||||
sdkconfig.CONFIG_UAC_NUM_ISOC_URBS=4
|
||||
sdkconfig.CONFIG_UAC_NUM_PACKETS_PER_URB=4
|
||||
@ -209,6 +209,14 @@
|
||||
usbhostmsc0 {
|
||||
compatible = "espressif,esp32-usbhost-msc";
|
||||
};
|
||||
|
||||
// USB headphones/headsets (UAC 1.0, 48 kHz / 16-bit / stereo PCM output).
|
||||
// The manager installs the class client; a dynamic "usb_uac0" codec device
|
||||
// appears per connected headset and the audio-stream aggregate re-binds
|
||||
// output to it.
|
||||
usbhostaudio0 {
|
||||
compatible = "espressif,esp32-usbhost-uac";
|
||||
};
|
||||
};
|
||||
|
||||
usbdevice0 {
|
||||
|
||||
@ -32,7 +32,8 @@ extern void vAssertCalled(unsigned long line, const char* const file);
|
||||
/* Memory allocation related definitions. */
|
||||
#define configSUPPORT_STATIC_ALLOCATION 0
|
||||
#define configSUPPORT_DYNAMIC_ALLOCATION 1
|
||||
#define configTOTAL_HEAP_SIZE (1024 * 1024)
|
||||
// 1MB was insufficient for terminal app
|
||||
#define configTOTAL_HEAP_SIZE (8 * 1024 * 1024)
|
||||
#define configAPPLICATION_ALLOCATED_HEAP 0
|
||||
#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 // TODO: Compare with ESP defaults
|
||||
|
||||
|
||||
@ -94,7 +94,7 @@ static error_t start() {
|
||||
}
|
||||
|
||||
static error_t stop() {
|
||||
device_listener_remove(on_root_started);
|
||||
device_listener_remove(on_root_started, nullptr);
|
||||
return ERROR_NONE;
|
||||
}
|
||||
|
||||
|
||||
@ -43,7 +43,7 @@ static error_t start() {
|
||||
}
|
||||
|
||||
static error_t stop() {
|
||||
device_listener_remove(&on_device_event);
|
||||
device_listener_remove(&on_device_event, nullptr);
|
||||
return ERROR_NONE;
|
||||
}
|
||||
|
||||
|
||||
@ -2,11 +2,16 @@
|
||||
|
||||
## Before release
|
||||
|
||||
- Tactility/Source/service/autorotate/AutoRotate.cpp
|
||||
TODO: Display settings app might be saving DisplaySettings at the same time. This might corrupt the settings file.
|
||||
- Try out speed optimizations: https://docs.espressif.com/projects/esp-faq/en/latest/software-framework/peripherals/lcd.html
|
||||
(relates to CONFIG_ESP32S3_DATA_CACHE_LINE_64B that is in use for RGB displays via the `device.properties` fix/workaround)
|
||||
|
||||
## Higher Priority
|
||||
|
||||
- App List: Close when app was started
|
||||
- App List: Support marking apps as favourite
|
||||
- Shell interpreter works recursive-descent algorithm, which requires a big stack size. Can we optimize this?
|
||||
- CrashDiagnostics shouldn't show a QR when there's no callstack
|
||||
- stopAppFromToolbar() in Tactility.cpp stops the top-most app. Change it so the toolbar knows for which app id it is created, so it can rely on that.
|
||||
- Warn if file operations are done from prohibited tasks (e.g. lvgl task)
|
||||
|
||||
@ -4,8 +4,14 @@ include("${CMAKE_CURRENT_LIST_DIR}/../../Buildscripts/module.cmake")
|
||||
|
||||
file(GLOB_RECURSE SOURCE_FILES "source/*.c*")
|
||||
|
||||
set(REQUIRES_LIST TactilityKernel)
|
||||
if (DEFINED ENV{ESP_IDF_VERSION})
|
||||
# Decoder symbol exports (source/symbols.c) compile against the ESP-only audio codec component.
|
||||
list(APPEND REQUIRES_LIST espressif__esp_audio_codec)
|
||||
endif ()
|
||||
|
||||
tactility_add_module(audio-stream-module
|
||||
SRCS ${SOURCE_FILES}
|
||||
INCLUDE_DIRS include/
|
||||
REQUIRES TactilityKernel
|
||||
REQUIRES ${REQUIRES_LIST}
|
||||
)
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
#include <tactility/device.h>
|
||||
#include <tactility/driver.h>
|
||||
#include <tactility/device_listener.h>
|
||||
#include <tactility/log.h>
|
||||
#include <tactility/drivers/audio_codec.h>
|
||||
#include <tactility/drivers/audio_stream.h>
|
||||
@ -98,19 +99,25 @@ struct AudioStreamHandleImpl : AudioStreamHandleData {
|
||||
uint8_t codec_channels = 0;
|
||||
uint8_t bytes_per_frame = 0; // app-side frame size (config.channels)
|
||||
uint8_t codec_bytes_per_frame = 0; // codec-side frame size (codec_channels)
|
||||
// Bound at open time; the AudioStreamData slot can be re-bound mid-handle by
|
||||
// on_codec_device_event, but I/O must keep targeting this codec. Nulled when this codec's
|
||||
// device is being removed, so close_stream() skips audio_codec_close() on soon-freed memory.
|
||||
Device* codec = nullptr;
|
||||
float input_gain = 1.0f; // fixed digital gain multiplier, input direction only (see audio_codec_get_input_gain_multiplier)
|
||||
std::vector<uint8_t> codec_buffer; // raw codec-rate/codec-channel PCM, scratch
|
||||
std::vector<uint8_t> convert_buffer; // intermediate scratch for the second conversion stage
|
||||
|
||||
// Lifetime guard: close_stream() can be triggered from a different task than the one
|
||||
// doing read()/write() (e.g. the Settings UI disabling output while SfxEngine's audio
|
||||
// task is mid-write). `closing` keeps new I/O calls out, `busy_count` tracks I/O calls
|
||||
// currently in flight, and `drain_semaphore` lets close_stream() block until they finish
|
||||
// before freeing the handle. All three are only touched while `AudioStreamData::mutex`
|
||||
// is held, except for the give/take on drain_semaphore itself.
|
||||
// Lets close_stream() and on_codec_device_event() independently wait for this handle's
|
||||
// in-flight I/O to drain without racing each other or double-freeing it: each waits on its
|
||||
// own semaphore (a shared one would only wake one of them), and lifetime_refs ensures
|
||||
// whichever finishes last is the one that deletes `handle`. All fields here are only
|
||||
// touched while `AudioStreamData::mutex` is held, except the semaphore give/take themselves.
|
||||
bool listener_closed = false;
|
||||
bool closing = false;
|
||||
int busy_count = 0;
|
||||
int lifetime_refs = 1; // the implicit reference held by the open handle itself
|
||||
SemaphoreHandle_t drain_semaphore = nullptr;
|
||||
SemaphoreHandle_t listener_drain_semaphore = nullptr;
|
||||
};
|
||||
|
||||
struct AudioStreamData {
|
||||
@ -134,6 +141,17 @@ struct AudioStreamData {
|
||||
// through them, so close (possibly forced by set_enabled) can't race with read/write.
|
||||
SemaphoreHandle_t mutex = nullptr;
|
||||
|
||||
// Set to the codec being opened while open_stream() holds the reservation placeholder in
|
||||
// open_input/open_output; there's no handle yet to mark listener_closed, so a STOPPED event
|
||||
// during that window instead polls this field until the open resolves.
|
||||
Device* input_reservation_codec = nullptr;
|
||||
Device* output_reservation_codec = nullptr;
|
||||
|
||||
// The audio-stream device this state belongs to; used by on_codec_device_event (which
|
||||
// only receives the state as context) for notify_change(). Nulled during stop_device so
|
||||
// a late listener invocation becomes a no-op.
|
||||
Device* self = nullptr;
|
||||
|
||||
AudioStreamChangeCallback change_callback = nullptr;
|
||||
void* change_callback_user_data = nullptr;
|
||||
};
|
||||
@ -226,31 +244,163 @@ Device* codec_for_direction(AudioStreamData* data, AudioCodecDirection direction
|
||||
return result;
|
||||
}
|
||||
|
||||
// Marks an I/O operation as in-flight on `handle`, preventing close_stream() from freeing it
|
||||
// underneath us. Returns false (and does nothing further) if the handle is closing/closed --
|
||||
// callers must bail out with an error in that case. Must be paired with io_end().
|
||||
bool io_begin(AudioStreamData* data, AudioStreamHandleImpl* handle) {
|
||||
// Marks I/O as in-flight on `handle` and hands back the codec to use, preventing close_stream()
|
||||
// from freeing it underneath us. Returns false if the handle is closing/closed (caller must
|
||||
// bail with an error). Reads handle->codec under the same lock as the validity check so it can't
|
||||
// race on_codec_device_event's mutex-protected null-out. Must be paired with io_end().
|
||||
bool io_begin(AudioStreamData* data, AudioStreamHandleImpl* handle, Device** out_codec) {
|
||||
xSemaphoreTake(data->mutex, portMAX_DELAY);
|
||||
bool is_input = (handle->direction == AUDIO_CODEC_DIR_INPUT);
|
||||
AudioStreamHandleImpl* slot_value = is_input ? data->open_input : data->open_output;
|
||||
if (slot_value != handle || handle->closing) {
|
||||
if (slot_value != handle || handle->closing || handle->listener_closed || handle->codec == nullptr) {
|
||||
xSemaphoreGive(data->mutex);
|
||||
return false;
|
||||
}
|
||||
*out_codec = handle->codec;
|
||||
handle->busy_count++;
|
||||
xSemaphoreGive(data->mutex);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Drops one lifetime reference; on the last one, deletes handle's semaphores (nulled out first
|
||||
// so nothing else can observe a dangling pointer) and returns true so the caller frees `handle`
|
||||
// itself. Never touches handle->codec: that stays close_stream()'s own responsibility.
|
||||
bool release_lifetime_ref(AudioStreamData* data, AudioStreamHandleImpl* handle) {
|
||||
xSemaphoreTake(data->mutex, portMAX_DELAY);
|
||||
handle->lifetime_refs--;
|
||||
bool last_ref = (handle->lifetime_refs == 0);
|
||||
SemaphoreHandle_t drain_to_delete = nullptr;
|
||||
SemaphoreHandle_t listener_drain_to_delete = nullptr;
|
||||
if (last_ref) {
|
||||
drain_to_delete = handle->drain_semaphore;
|
||||
listener_drain_to_delete = handle->listener_drain_semaphore;
|
||||
handle->drain_semaphore = nullptr;
|
||||
handle->listener_drain_semaphore = nullptr;
|
||||
}
|
||||
xSemaphoreGive(data->mutex);
|
||||
|
||||
if (drain_to_delete != nullptr) {
|
||||
vSemaphoreDelete(drain_to_delete);
|
||||
}
|
||||
if (listener_drain_to_delete != nullptr) {
|
||||
vSemaphoreDelete(listener_drain_to_delete);
|
||||
}
|
||||
return last_ref;
|
||||
}
|
||||
|
||||
void io_end(AudioStreamData* data, AudioStreamHandleImpl* handle) {
|
||||
xSemaphoreTake(data->mutex, portMAX_DELAY);
|
||||
handle->busy_count--;
|
||||
if (handle->closing && handle->busy_count == 0) {
|
||||
xSemaphoreGive(handle->drain_semaphore);
|
||||
// Give under data->mutex: semaphore fields are only nulled under this same mutex before
|
||||
// deletion, so this can't target an already-freed semaphore.
|
||||
if (handle->busy_count == 0) {
|
||||
if (handle->closing && handle->drain_semaphore != nullptr) {
|
||||
xSemaphoreGive(handle->drain_semaphore);
|
||||
}
|
||||
if (handle->listener_closed && handle->listener_drain_semaphore != nullptr) {
|
||||
xSemaphoreGive(handle->listener_drain_semaphore);
|
||||
}
|
||||
}
|
||||
xSemaphoreGive(data->mutex);
|
||||
}
|
||||
|
||||
// Re-binds each direction's codec on hotplug. A stream open on the old codec is marked
|
||||
// listener_closed so it drains and closes safely; for STOPPED, the codec pointer is nulled
|
||||
// first too, since the Device memory is freed right after this callback returns and an
|
||||
// in-flight read/write may still be using it (io_begin captured the pointer before the null-out).
|
||||
// The wait below is bounded because read/write's own timeout guarantees it finishes on its own;
|
||||
// an unbounded wait here could deadlock hotplug teardown. DEVICE_EVENT_STOPPED (not STOPPING) is
|
||||
// used because the device only drops out of find_first_codec_supporting's candidates once
|
||||
// STOPPING has already been notified.
|
||||
void on_codec_device_event(Device* dev, DeviceEvent event, void* context) {
|
||||
auto* data = static_cast<AudioStreamData*>(context);
|
||||
if (data == nullptr || data->self == nullptr) {
|
||||
return;
|
||||
}
|
||||
if (device_get_type(dev) != &AUDIO_CODEC_TYPE) {
|
||||
return;
|
||||
}
|
||||
if (event != DEVICE_EVENT_STARTED && event != DEVICE_EVENT_STOPPED) {
|
||||
return;
|
||||
}
|
||||
|
||||
const AudioCodecDirection directions[] = { AUDIO_CODEC_DIR_INPUT, AUDIO_CODEC_DIR_OUTPUT };
|
||||
for (AudioCodecDirection direction : directions) {
|
||||
Device* preferred = find_first_codec_supporting(direction);
|
||||
|
||||
xSemaphoreTake(data->mutex, portMAX_DELAY);
|
||||
Device** codec_slot = (direction == AUDIO_CODEC_DIR_INPUT) ? &data->input_codec : &data->output_codec;
|
||||
Device* current = *codec_slot;
|
||||
if (preferred == current) {
|
||||
xSemaphoreGive(data->mutex);
|
||||
continue;
|
||||
}
|
||||
|
||||
AudioStreamHandleImpl** open_slot = (direction == AUDIO_CODEC_DIR_INPUT) ? &data->open_input : &data->open_output;
|
||||
AudioStreamHandleImpl* open_handle = *open_slot;
|
||||
auto* reservation = reinterpret_cast<AudioStreamHandleImpl*>(1);
|
||||
AudioStreamHandleImpl* drained_handle = nullptr;
|
||||
bool must_drain = false;
|
||||
Device** reservation_codec = (direction == AUDIO_CODEC_DIR_INPUT) ? &data->input_reservation_codec : &data->output_reservation_codec;
|
||||
bool must_wait_for_open = (event == DEVICE_EVENT_STOPPED && open_handle == reservation && *reservation_codec == current);
|
||||
if (open_handle != nullptr && open_handle != reservation) {
|
||||
if (event == DEVICE_EVENT_STOPPED && open_handle->codec == current) {
|
||||
open_handle->codec = nullptr;
|
||||
// read/write_stream capture `codec` into a local before this callback's mutex
|
||||
// window can run, so I/O already past that point is still using the pointer
|
||||
// we just nulled out -- wait for it before returning, since our caller (the
|
||||
// STOPPED event's source) frees that Device's memory right after we return.
|
||||
must_drain = (open_handle->busy_count > 0);
|
||||
if (must_drain) {
|
||||
// Own semaphore, since close_stream() can be waiting on drain_semaphore
|
||||
// concurrently for this same handle. Take a lifetime ref too so a concurrent
|
||||
// close_stream() can't free `handle` out from under this wait.
|
||||
open_handle->listener_drain_semaphore = xSemaphoreCreateBinary();
|
||||
open_handle->lifetime_refs++;
|
||||
}
|
||||
drained_handle = open_handle;
|
||||
}
|
||||
open_handle->listener_closed = true;
|
||||
*open_slot = nullptr;
|
||||
}
|
||||
*codec_slot = preferred;
|
||||
xSemaphoreGive(data->mutex);
|
||||
|
||||
if (must_drain && drained_handle->listener_drain_semaphore != nullptr) {
|
||||
// Bounded to 2s (comfortably covers every timeout this codebase's callers use), since
|
||||
// there's no way to cancel an in-flight audio_codec_read/write call.
|
||||
xSemaphoreTake(drained_handle->listener_drain_semaphore, pdMS_TO_TICKS(2000));
|
||||
if (release_lifetime_ref(data, drained_handle)) {
|
||||
delete drained_handle;
|
||||
}
|
||||
}
|
||||
|
||||
if (must_wait_for_open) {
|
||||
// open_stream() is between reserving the slot and audio_codec_open() returning, so
|
||||
// there's no handle yet to mark listener_closed/drain: poll for the reservation to
|
||||
// resolve instead. Bounded for the same reason as the drain wait above.
|
||||
for (int waited_ms = 0; waited_ms < 2000; waited_ms += 20) {
|
||||
xSemaphoreTake(data->mutex, portMAX_DELAY);
|
||||
bool resolved = (*reservation_codec != current);
|
||||
xSemaphoreGive(data->mutex);
|
||||
if (resolved) {
|
||||
break;
|
||||
}
|
||||
vTaskDelay(pdMS_TO_TICKS(20));
|
||||
}
|
||||
}
|
||||
|
||||
LOG_I(
|
||||
TAG,
|
||||
"Re-bound %s codec: %s -> %s",
|
||||
(direction == AUDIO_CODEC_DIR_INPUT) ? "input" : "output",
|
||||
(current != nullptr) ? current->name : "(none)",
|
||||
(preferred != nullptr) ? preferred->name : "(none)"
|
||||
);
|
||||
notify_change(data, data->self, direction, AUDIO_STREAM_CHANGE_CODEC);
|
||||
}
|
||||
}
|
||||
|
||||
// region AudioStreamApi
|
||||
|
||||
error_t open_stream(Device* device, const struct AudioStreamConfig* config, AudioCodecDirection direction, AudioStreamHandle* out_handle) {
|
||||
@ -293,20 +443,24 @@ error_t open_stream(Device* device, const struct AudioStreamConfig* config, Audi
|
||||
// above while we do the (potentially slow) codec open below outside the lock.
|
||||
auto* reservation = reinterpret_cast<AudioStreamHandleImpl*>(1);
|
||||
*slot = reservation;
|
||||
// See input_reservation_codec's comment: no handle exists yet for a concurrent STOPPED
|
||||
// event to mark listener_closed on, so it polls this instead.
|
||||
Device** reservation_codec = is_input ? &data->input_reservation_codec : &data->output_reservation_codec;
|
||||
*reservation_codec = codec;
|
||||
xSemaphoreGive(data->mutex);
|
||||
|
||||
uint32_t codec_rate = 0;
|
||||
if (audio_codec_get_native_sample_rate(codec, direction, &codec_rate) != ERROR_NONE || codec_rate == 0) {
|
||||
xSemaphoreTake(data->mutex, portMAX_DELAY);
|
||||
if (*slot == reservation) { *slot = nullptr; }
|
||||
*reservation_codec = nullptr;
|
||||
xSemaphoreGive(data->mutex);
|
||||
return ERROR_RESOURCE;
|
||||
}
|
||||
|
||||
// The codec must be opened with its native channel layout (e.g. 4 for a 4-slot TDM mic
|
||||
// ADC) -- opening it with the app's requested channel count can silently corrupt the
|
||||
// stream (ES7210 in TDM mode halves its configured bit depth for <= 2 channels). We
|
||||
// convert between the codec's layout and the app's requested channel count ourselves.
|
||||
// Must open with the codec's native channel layout (e.g. 4 for a 4-slot TDM mic ADC):
|
||||
// opening with the app's count can silently corrupt the stream (ES7210 TDM halves its bit
|
||||
// depth for <= 2 channels). We convert to the app's requested layout ourselves.
|
||||
uint8_t codec_channels = config->channels;
|
||||
if (audio_codec_get_native_channels(codec, direction, &codec_channels) != ERROR_NONE || codec_channels == 0) {
|
||||
codec_channels = config->channels;
|
||||
@ -323,6 +477,7 @@ error_t open_stream(Device* device, const struct AudioStreamConfig* config, Audi
|
||||
LOG_E(TAG, "Failed to open codec for %s", is_input ? "input" : "output");
|
||||
xSemaphoreTake(data->mutex, portMAX_DELAY);
|
||||
if (*slot == reservation) { *slot = nullptr; }
|
||||
*reservation_codec = nullptr;
|
||||
xSemaphoreGive(data->mutex);
|
||||
return ERROR_RESOURCE;
|
||||
}
|
||||
@ -342,6 +497,7 @@ error_t open_stream(Device* device, const struct AudioStreamConfig* config, Audi
|
||||
handle->device = device;
|
||||
handle->direction = direction;
|
||||
handle->config = *config;
|
||||
handle->codec = codec;
|
||||
handle->codec_rate = codec_rate;
|
||||
handle->codec_channels = codec_channels;
|
||||
handle->bytes_per_frame = (uint8_t) ((config->bits_per_sample / 8) * config->channels);
|
||||
@ -356,12 +512,30 @@ error_t open_stream(Device* device, const struct AudioStreamConfig* config, Audi
|
||||
audio_codec_close(codec);
|
||||
xSemaphoreTake(data->mutex, portMAX_DELAY);
|
||||
if (*slot == reservation) { *slot = nullptr; }
|
||||
*reservation_codec = nullptr;
|
||||
xSemaphoreGive(data->mutex);
|
||||
return ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
xSemaphoreTake(data->mutex, portMAX_DELAY);
|
||||
Device* bound_codec = is_input ? data->input_codec : data->output_codec;
|
||||
if (bound_codec != codec) {
|
||||
// A codec device event re-bound this direction to another codec while we were
|
||||
// opening this one (e.g. USB headphones attached mid-open). Undo the open instead
|
||||
// of committing a handle whose codec no longer matches the slot: the app's retry
|
||||
// picks up the new codec.
|
||||
if (*slot == reservation) {
|
||||
*slot = nullptr;
|
||||
}
|
||||
*reservation_codec = nullptr;
|
||||
xSemaphoreGive(data->mutex);
|
||||
audio_codec_close(codec);
|
||||
vSemaphoreDelete(handle->drain_semaphore);
|
||||
delete handle;
|
||||
return ERROR_RESOURCE;
|
||||
}
|
||||
*slot = handle;
|
||||
*reservation_codec = nullptr;
|
||||
xSemaphoreGive(data->mutex);
|
||||
|
||||
*out_handle = handle;
|
||||
@ -383,7 +557,7 @@ error_t read_stream(AudioStreamHandle handle_base, void* out_data, size_t data_s
|
||||
}
|
||||
|
||||
auto* data = GET_DATA(handle->device);
|
||||
if (data == nullptr || data->input_codec == nullptr) {
|
||||
if (data == nullptr) {
|
||||
return ERROR_RESOURCE;
|
||||
}
|
||||
|
||||
@ -395,7 +569,8 @@ error_t read_stream(AudioStreamHandle handle_base, void* out_data, size_t data_s
|
||||
return ERROR_NONE;
|
||||
}
|
||||
|
||||
if (!io_begin(data, handle)) {
|
||||
Device* codec = nullptr;
|
||||
if (!io_begin(data, handle, &codec)) {
|
||||
return ERROR_INVALID_STATE;
|
||||
}
|
||||
|
||||
@ -405,7 +580,7 @@ error_t read_stream(AudioStreamHandle handle_base, void* out_data, size_t data_s
|
||||
error_t result;
|
||||
if (same_rate && same_channels) {
|
||||
size_t codec_bytes_read = 0;
|
||||
result = audio_codec_read(data->input_codec, out_data, data_size, &codec_bytes_read, timeout);
|
||||
result = audio_codec_read(codec, out_data, data_size, &codec_bytes_read, timeout);
|
||||
if (bytes_read != nullptr) {
|
||||
*bytes_read = codec_bytes_read;
|
||||
}
|
||||
@ -418,7 +593,7 @@ error_t read_stream(AudioStreamHandle handle_base, void* out_data, size_t data_s
|
||||
}
|
||||
|
||||
size_t codec_bytes_read = 0;
|
||||
result = audio_codec_read(data->input_codec, handle->codec_buffer.data(), codec_bytes_needed, &codec_bytes_read, timeout);
|
||||
result = audio_codec_read(codec, handle->codec_buffer.data(), codec_bytes_needed, &codec_bytes_read, timeout);
|
||||
if (result == ERROR_NONE) {
|
||||
size_t codec_frames_read = codec_bytes_read / handle->codec_bytes_per_frame;
|
||||
const int16_t* rate_input = reinterpret_cast<const int16_t*>(handle->codec_buffer.data());
|
||||
@ -468,7 +643,7 @@ error_t write_stream(AudioStreamHandle handle_base, const void* in_data, size_t
|
||||
}
|
||||
|
||||
auto* data = GET_DATA(handle->device);
|
||||
if (data == nullptr || data->output_codec == nullptr) {
|
||||
if (data == nullptr) {
|
||||
return ERROR_RESOURCE;
|
||||
}
|
||||
|
||||
@ -480,7 +655,8 @@ error_t write_stream(AudioStreamHandle handle_base, const void* in_data, size_t
|
||||
return ERROR_NONE;
|
||||
}
|
||||
|
||||
if (!io_begin(data, handle)) {
|
||||
Device* codec = nullptr;
|
||||
if (!io_begin(data, handle, &codec)) {
|
||||
return ERROR_INVALID_STATE;
|
||||
}
|
||||
|
||||
@ -490,7 +666,7 @@ error_t write_stream(AudioStreamHandle handle_base, const void* in_data, size_t
|
||||
error_t result;
|
||||
if (same_rate && same_channels) {
|
||||
size_t codec_bytes_written = 0;
|
||||
result = audio_codec_write(data->output_codec, in_data, data_size, &codec_bytes_written, timeout);
|
||||
result = audio_codec_write(codec, in_data, data_size, &codec_bytes_written, timeout);
|
||||
if (bytes_written != nullptr) {
|
||||
// Report in terms of input bytes consumed, matching codec_bytes_written 1:1 here.
|
||||
*bytes_written = codec_bytes_written;
|
||||
@ -531,7 +707,7 @@ error_t write_stream(AudioStreamHandle handle_base, const void* in_data, size_t
|
||||
|
||||
size_t codec_bytes_to_write = codec_frames * handle->codec_bytes_per_frame;
|
||||
size_t codec_bytes_written = 0;
|
||||
result = audio_codec_write(data->output_codec, handle->codec_buffer.data(), codec_bytes_to_write, &codec_bytes_written, timeout);
|
||||
result = audio_codec_write(codec, handle->codec_buffer.data(), codec_bytes_to_write, &codec_bytes_written, timeout);
|
||||
if (result == ERROR_NONE && bytes_written != nullptr) {
|
||||
// The caller provided `data_size` worth of input; we consumed all of it (resampled/converted).
|
||||
*bytes_written = data_size;
|
||||
@ -550,7 +726,6 @@ error_t close_stream(AudioStreamHandle handle_base) {
|
||||
}
|
||||
|
||||
bool is_input = (handle->direction == AUDIO_CODEC_DIR_INPUT);
|
||||
Device* codec = is_input ? data->input_codec : data->output_codec;
|
||||
AudioStreamHandleImpl** slot = is_input ? &data->open_input : &data->open_output;
|
||||
|
||||
xSemaphoreTake(data->mutex, portMAX_DELAY);
|
||||
@ -564,6 +739,12 @@ error_t close_stream(AudioStreamHandle handle_base) {
|
||||
*slot = nullptr;
|
||||
}
|
||||
bool must_drain = (handle->busy_count > 0);
|
||||
// Close the codec this handle was opened against - NOT the current slot value, which may
|
||||
// since have been re-bound to a different codec by a device event. Read under the mutex:
|
||||
// on_codec_device_event() nulls this same field (also under the mutex) right before the
|
||||
// codec Device's memory is freed, so reading it unlocked could race and capture a pointer
|
||||
// that's about to dangle.
|
||||
Device* codec = handle->codec;
|
||||
xSemaphoreGive(data->mutex);
|
||||
|
||||
if (must_drain && handle->drain_semaphore != nullptr) {
|
||||
@ -574,11 +755,13 @@ error_t close_stream(AudioStreamHandle handle_base) {
|
||||
audio_codec_close(codec);
|
||||
}
|
||||
|
||||
if (handle->drain_semaphore != nullptr) {
|
||||
vSemaphoreDelete(handle->drain_semaphore);
|
||||
// Releases this call's (the app's) lifetime reference. If a codec-hotplug listener is
|
||||
// concurrently waiting to drain this same handle (see AudioStreamHandleImpl's comment), its
|
||||
// own reference keeps `handle` alive until it finishes too - only the last release actually
|
||||
// deletes it.
|
||||
if (release_lifetime_ref(data, handle)) {
|
||||
delete handle;
|
||||
}
|
||||
|
||||
delete handle;
|
||||
return ERROR_NONE;
|
||||
}
|
||||
|
||||
@ -768,7 +951,9 @@ error_t start_device(Device* device) {
|
||||
delete data;
|
||||
return ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
data->self = device;
|
||||
device_set_driver_data(device, data);
|
||||
device_listener_add(on_codec_device_event, data);
|
||||
return ERROR_NONE;
|
||||
}
|
||||
|
||||
@ -778,6 +963,10 @@ error_t stop_device(Device* device) {
|
||||
return ERROR_NONE;
|
||||
}
|
||||
|
||||
// Stop reacting to codec device events before tearing anything down.
|
||||
data->self = nullptr;
|
||||
device_listener_remove(on_codec_device_event, data);
|
||||
|
||||
if (data->open_input != nullptr) {
|
||||
close_stream(data->open_input);
|
||||
}
|
||||
|
||||
@ -5,12 +5,28 @@
|
||||
#include <tactility/log.h>
|
||||
#include <tactility/module.h>
|
||||
|
||||
#ifdef ESP_PLATFORM
|
||||
#include <esp_audio_dec_default.h>
|
||||
#include <esp_audio_simple_dec_default.h>
|
||||
#endif
|
||||
|
||||
extern "C" {
|
||||
|
||||
extern Driver audio_stream_driver;
|
||||
extern Device audio_stream_device;
|
||||
|
||||
static error_t start() {
|
||||
#ifdef ESP_PLATFORM
|
||||
/* Firmware-owned decoder registration, before any app can open a decode stream.
|
||||
* External ELF apps reach the decoders through this module's symbol table. */
|
||||
esp_audio_err_t dec_result = esp_audio_dec_register_default();
|
||||
esp_audio_err_t simple_result = esp_audio_simple_dec_register_default();
|
||||
if (dec_result != ESP_AUDIO_ERR_OK || simple_result != ESP_AUDIO_ERR_OK) {
|
||||
LOG_E("AudioStream", "Decoder registration failed: dec=%d simple=%d",
|
||||
(int) dec_result, (int) simple_result);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* We crash when construct fails, because if a single driver fails to construct,
|
||||
* there is no guarantee that the previously constructed drivers can be destroyed */
|
||||
check(driver_construct_add(&audio_stream_driver) == ERROR_NONE);
|
||||
|
||||
@ -1,6 +1,23 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
#include <tactility/module.h>
|
||||
|
||||
#ifdef ESP_PLATFORM
|
||||
|
||||
#include <esp_audio_simple_dec.h>
|
||||
|
||||
// The software decoders live in the esp_audio_codec component and are registered once at
|
||||
// module start (source/module.cpp), so apps never register decoders themselves.
|
||||
const struct ModuleSymbol audio_stream_module_symbols[] = {
|
||||
DEFINE_MODULE_SYMBOL(esp_audio_simple_dec_open),
|
||||
DEFINE_MODULE_SYMBOL(esp_audio_simple_dec_close),
|
||||
DEFINE_MODULE_SYMBOL(esp_audio_simple_dec_process),
|
||||
DEFINE_MODULE_SYMBOL(esp_audio_simple_dec_get_info),
|
||||
MODULE_SYMBOL_TERMINATOR
|
||||
};
|
||||
|
||||
#else // !ESP_PLATFORM: no decoder exports outside the ESP build
|
||||
|
||||
const struct ModuleSymbol audio_stream_module_symbols[] = {
|
||||
MODULE_SYMBOL_TERMINATOR
|
||||
};
|
||||
#endif
|
||||
18
Drivers/audio-stream-module/tests/CMakeLists.txt
Normal file
18
Drivers/audio-stream-module/tests/CMakeLists.txt
Normal file
@ -0,0 +1,18 @@
|
||||
project(AudioStreamModuleTests)
|
||||
|
||||
enable_language(C CXX ASM)
|
||||
|
||||
|
||||
file(GLOB_RECURSE TEST_SOURCES CONFIGURE_DEPENDS ${PROJECT_SOURCE_DIR}/source/*.cpp)
|
||||
add_executable(AudioStreamModuleTests EXCLUDE_FROM_ALL ${TEST_SOURCES})
|
||||
|
||||
target_include_directories(AudioStreamModuleTests PRIVATE ${DOCTESTINC})
|
||||
|
||||
add_test(NAME AudioStreamModuleTests COMMAND AudioStreamModuleTests)
|
||||
|
||||
target_link_libraries(AudioStreamModuleTests PUBLIC
|
||||
TactilityKernel
|
||||
audio-stream-module
|
||||
platform-posix
|
||||
freertos_kernel
|
||||
)
|
||||
@ -0,0 +1,277 @@
|
||||
// Regression tests for the audio-stream open/hotplug race in open_stream():
|
||||
// while a codec is being opened (slot reserved), a codec device event can re-bind
|
||||
// the direction to another codec. The abort path must release the reservation --
|
||||
// before the fix it checked `*slot == handle` (never true at that point, the handle
|
||||
// is only committed afterwards), stranding the reservation sentinel in the slot so
|
||||
// every later open of that direction failed with ERROR_INVALID_STATE.
|
||||
//
|
||||
// The race is reproduced deterministically: a mock codec's open() blocks on a gate
|
||||
// semaphore, holding open_stream() mid-window, while the test starts a second codec
|
||||
// device (its DEVICE_EVENT_STARTED re-binds the direction through the module's own
|
||||
// device listener).
|
||||
|
||||
#include "doctest.h"
|
||||
|
||||
#include <atomic>
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "semphr.h"
|
||||
|
||||
#include <tactility/device.h>
|
||||
#include <tactility/driver.h>
|
||||
#include <tactility/drivers/audio_codec.h>
|
||||
#include <tactility/drivers/audio_stream.h>
|
||||
#include <tactility/concurrent/thread.h>
|
||||
|
||||
extern "C" {
|
||||
// Exported by the audio-stream module (see source/audio_stream.cpp bottom).
|
||||
extern Driver audio_stream_driver;
|
||||
extern Device audio_stream_device;
|
||||
}
|
||||
|
||||
// region Mock codec
|
||||
|
||||
struct MockCodecState {
|
||||
AudioCodecDirection capabilities = AUDIO_CODEC_DIR_OUTPUT;
|
||||
bool fail_open = false;
|
||||
// When set, open() blocks until the gate is given, letting the test hold
|
||||
// open_stream() in its mid-open window (slot reserved, codec not yet opened).
|
||||
SemaphoreHandle_t open_gate = nullptr;
|
||||
std::atomic<int> open_count{0};
|
||||
int close_count = 0;
|
||||
};
|
||||
|
||||
static MockCodecState state_a;
|
||||
static MockCodecState state_b;
|
||||
|
||||
#define MOCK_STATE(device) (static_cast<MockCodecState*>(const_cast<void*>((device)->config)))
|
||||
|
||||
static error_t mock_start(Device* device) {
|
||||
return ERROR_NONE;
|
||||
}
|
||||
|
||||
static error_t mock_stop(Device* device) {
|
||||
return ERROR_NONE;
|
||||
}
|
||||
|
||||
static error_t mock_open(Device* device, const AudioCodecStreamConfig* config) {
|
||||
auto* state = MOCK_STATE(device);
|
||||
state->open_count++;
|
||||
if (state->open_gate != nullptr) {
|
||||
xSemaphoreTake(state->open_gate, portMAX_DELAY);
|
||||
}
|
||||
return state->fail_open ? ERROR_RESOURCE : ERROR_NONE;
|
||||
}
|
||||
|
||||
static error_t mock_close(Device* device) {
|
||||
MOCK_STATE(device)->close_count++;
|
||||
return ERROR_NONE;
|
||||
}
|
||||
|
||||
static error_t mock_read(Device* device, void* data, size_t data_size, size_t* bytes_read, TickType_t timeout) {
|
||||
return ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
static error_t mock_write(Device* device, const void* data, size_t data_size, size_t* bytes_written, TickType_t timeout) {
|
||||
return ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
static error_t mock_set_volume(Device* device, AudioCodecDirection direction, float volume_percent) {
|
||||
return ERROR_NONE;
|
||||
}
|
||||
|
||||
static error_t mock_get_volume(Device* device, AudioCodecDirection direction, float* volume_percent) {
|
||||
*volume_percent = 100.0f;
|
||||
return ERROR_NONE;
|
||||
}
|
||||
|
||||
static error_t mock_set_mute(Device* device, AudioCodecDirection direction, bool muted) {
|
||||
return ERROR_NONE;
|
||||
}
|
||||
|
||||
static error_t mock_get_mute(Device* device, AudioCodecDirection direction, bool* muted) {
|
||||
*muted = false;
|
||||
return ERROR_NONE;
|
||||
}
|
||||
|
||||
static error_t mock_get_native_sample_rate(Device* device, AudioCodecDirection direction, uint32_t* rate_hz) {
|
||||
*rate_hz = 48000;
|
||||
return ERROR_NONE;
|
||||
}
|
||||
|
||||
static error_t mock_get_native_channels(Device* device, AudioCodecDirection direction, uint8_t* channels) {
|
||||
*channels = 2;
|
||||
return ERROR_NONE;
|
||||
}
|
||||
|
||||
static error_t mock_get_capabilities(Device* device, AudioCodecDirection* supported_directions) {
|
||||
*supported_directions = MOCK_STATE(device)->capabilities;
|
||||
return ERROR_NONE;
|
||||
}
|
||||
|
||||
static error_t mock_get_input_gain_multiplier(Device* device, float* gain) {
|
||||
*gain = 1.0f;
|
||||
return ERROR_NONE;
|
||||
}
|
||||
|
||||
static const AudioCodecApi MOCK_API = {
|
||||
.open = mock_open,
|
||||
.close = mock_close,
|
||||
.read = mock_read,
|
||||
.write = mock_write,
|
||||
.set_volume = mock_set_volume,
|
||||
.get_volume = mock_get_volume,
|
||||
.set_mute = mock_set_mute,
|
||||
.get_mute = mock_get_mute,
|
||||
.get_native_sample_rate = mock_get_native_sample_rate,
|
||||
.get_native_channels = mock_get_native_channels,
|
||||
.get_capabilities = mock_get_capabilities,
|
||||
.get_input_gain_multiplier = mock_get_input_gain_multiplier,
|
||||
};
|
||||
|
||||
static Driver mock_codec_driver = {
|
||||
.name = "audio_stream_test_codec",
|
||||
.compatible = (const char*[]) { "audio-stream-test-codec", nullptr },
|
||||
.start_device = mock_start,
|
||||
.stop_device = mock_stop,
|
||||
.api = &MOCK_API,
|
||||
.device_type = &AUDIO_CODEC_TYPE,
|
||||
.owner = nullptr,
|
||||
.internal = nullptr,
|
||||
};
|
||||
|
||||
static Device codec_a = {
|
||||
.address = 0,
|
||||
.name = "test_codec_a",
|
||||
.config = &state_a,
|
||||
.parent = nullptr,
|
||||
.internal = nullptr,
|
||||
};
|
||||
|
||||
static Device codec_b = {
|
||||
.address = 0,
|
||||
.name = "test_codec_b",
|
||||
.config = &state_b,
|
||||
.parent = nullptr,
|
||||
.internal = nullptr,
|
||||
};
|
||||
|
||||
// endregion
|
||||
|
||||
static void reset_mock_state(MockCodecState& state, AudioCodecDirection capabilities) {
|
||||
if (state.open_gate != nullptr) {
|
||||
vSemaphoreDelete(state.open_gate);
|
||||
state.open_gate = nullptr;
|
||||
}
|
||||
state.capabilities = capabilities;
|
||||
state.fail_open = false;
|
||||
state.open_count = 0;
|
||||
state.close_count = 0;
|
||||
}
|
||||
|
||||
struct OpenRequest {
|
||||
Device* stream;
|
||||
AudioStreamConfig config;
|
||||
AudioStreamHandle handle = nullptr;
|
||||
error_t result = ERROR_UNDEFINED;
|
||||
};
|
||||
|
||||
static int32_t open_output_thread(void* context) {
|
||||
auto* request = static_cast<OpenRequest*>(context);
|
||||
request->result = audio_stream_open_output(request->stream, &request->config, &request->handle);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void teardown_devices_and_drivers() {
|
||||
// Only tear down devices this test case actually started (each case starts a
|
||||
// different subset; device_stop on a never-constructed device faults).
|
||||
if (device_is_added(&codec_a)) {
|
||||
device_stop(&codec_a);
|
||||
device_remove(&codec_a);
|
||||
device_destruct(&codec_a);
|
||||
}
|
||||
if (device_is_added(&codec_b)) {
|
||||
device_stop(&codec_b);
|
||||
device_remove(&codec_b);
|
||||
device_destruct(&codec_b);
|
||||
}
|
||||
if (device_is_added(&audio_stream_device)) {
|
||||
device_stop(&audio_stream_device);
|
||||
device_remove(&audio_stream_device);
|
||||
device_destruct(&audio_stream_device);
|
||||
}
|
||||
driver_remove_destruct(&mock_codec_driver);
|
||||
driver_remove_destruct(&audio_stream_driver);
|
||||
}
|
||||
|
||||
TEST_CASE("open_stream reservations are released on codec re-bind and failed codec open") {
|
||||
// Codec A is both-capable (binds output and input); codec B is output-only, so
|
||||
// starting it re-binds the output direction away from A.
|
||||
reset_mock_state(state_a, AUDIO_CODEC_DIR_BOTH);
|
||||
reset_mock_state(state_b, AUDIO_CODEC_DIR_OUTPUT);
|
||||
|
||||
REQUIRE_EQ(driver_construct_add(&audio_stream_driver), ERROR_NONE);
|
||||
REQUIRE_EQ(driver_construct_add(&mock_codec_driver), ERROR_NONE);
|
||||
REQUIRE_EQ(device_construct_add_start(&audio_stream_device, "audio-stream"), ERROR_NONE);
|
||||
REQUIRE_EQ(device_construct_add_start(&codec_a, "audio-stream-test-codec"), ERROR_NONE);
|
||||
|
||||
// Hold open_stream() mid-open: the slot is reserved and the codec open blocks.
|
||||
state_a.open_gate = xSemaphoreCreateBinary();
|
||||
REQUIRE(state_a.open_gate != nullptr);
|
||||
|
||||
OpenRequest request = {
|
||||
.stream = &audio_stream_device,
|
||||
.config = { .sample_rate = 44100, .bits_per_sample = 16, .channels = 2 },
|
||||
};
|
||||
Thread* thread = thread_alloc_full("open_race", 4096, open_output_thread, &request, -1);
|
||||
REQUIRE(thread != nullptr);
|
||||
REQUIRE_EQ(thread_start(thread), ERROR_NONE);
|
||||
|
||||
// Wait until the open is inside the codec (reservation is set by then).
|
||||
for (int i = 0; i < 500 && state_a.open_count == 0; ++i) {
|
||||
vTaskDelay(pdMS_TO_TICKS(2));
|
||||
}
|
||||
REQUIRE_EQ(state_a.open_count, 1);
|
||||
|
||||
// Re-bind the output direction mid-open: codec B's DEVICE_EVENT_STARTED makes it
|
||||
// the preferred output codec. The module's listener leaves the reserved slot alone.
|
||||
REQUIRE_EQ(device_construct_add_start(&codec_b, "audio-stream-test-codec"), ERROR_NONE);
|
||||
|
||||
// Release the gate; the open aborts because its codec no longer matches the slot.
|
||||
xSemaphoreGive(state_a.open_gate);
|
||||
REQUIRE_EQ(thread_join(thread, pdMS_TO_TICKS(10000), pdMS_TO_TICKS(5)), ERROR_NONE);
|
||||
thread_free(thread);
|
||||
|
||||
REQUIRE_EQ(request.result, ERROR_RESOURCE);
|
||||
REQUIRE_EQ(request.handle, nullptr);
|
||||
REQUIRE_EQ(state_a.close_count, 1); // the aborted open undid its codec open
|
||||
|
||||
// The regression: the reservation must be released, so the retry open succeeds
|
||||
// (before the fix this failed permanently with ERROR_INVALID_STATE).
|
||||
AudioStreamConfig config = { .sample_rate = 44100, .bits_per_sample = 16, .channels = 2 };
|
||||
AudioStreamHandle handle = nullptr;
|
||||
REQUIRE_EQ(audio_stream_open_output(&audio_stream_device, &config, &handle), ERROR_NONE);
|
||||
REQUIRE(handle != nullptr);
|
||||
REQUIRE_EQ(state_b.open_count, 1);
|
||||
|
||||
// Normal close still succeeds, and another open/close cycle works afterwards.
|
||||
REQUIRE_EQ(audio_stream_close(handle), ERROR_NONE);
|
||||
REQUIRE_EQ(state_b.close_count, 1);
|
||||
handle = nullptr;
|
||||
REQUIRE_EQ(audio_stream_open_output(&audio_stream_device, &config, &handle), ERROR_NONE);
|
||||
REQUIRE_EQ(audio_stream_close(handle), ERROR_NONE);
|
||||
|
||||
// A failed codec open must also release the reservation: the retry reaches the
|
||||
// codec again (a stranded reservation would return ERROR_INVALID_STATE instead),
|
||||
// and once the codec succeeds the stream opens and closes normally.
|
||||
state_b.fail_open = true;
|
||||
REQUIRE_EQ(audio_stream_open_output(&audio_stream_device, &config, &handle), ERROR_RESOURCE);
|
||||
REQUIRE_EQ(audio_stream_open_output(&audio_stream_device, &config, &handle), ERROR_RESOURCE);
|
||||
REQUIRE_EQ(state_b.open_count, 4); // 1 + 1 + 2 failed attempts
|
||||
state_b.fail_open = false;
|
||||
REQUIRE_EQ(audio_stream_open_output(&audio_stream_device, &config, &handle), ERROR_NONE);
|
||||
REQUIRE_EQ(audio_stream_close(handle), ERROR_NONE);
|
||||
|
||||
teardown_devices_and_drivers();
|
||||
}
|
||||
53
Drivers/audio-stream-module/tests/source/main.cpp
Normal file
53
Drivers/audio-stream-module/tests/source/main.cpp
Normal file
@ -0,0 +1,53 @@
|
||||
#define DOCTEST_CONFIG_IMPLEMENT
|
||||
#include "doctest.h"
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
typedef struct {
|
||||
int argc;
|
||||
char** argv;
|
||||
int result;
|
||||
} TestTaskData;
|
||||
|
||||
void test_task(void* parameter) {
|
||||
auto* data = (TestTaskData*)parameter;
|
||||
|
||||
doctest::Context context;
|
||||
|
||||
context.applyCommandLine(data->argc, data->argv);
|
||||
|
||||
// overrides
|
||||
context.setOption("no-breaks", true); // don't break in the debugger when assertions fail
|
||||
|
||||
data->result = context.run();
|
||||
|
||||
vTaskEndScheduler();
|
||||
|
||||
vTaskDelete(nullptr);
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
TestTaskData data = {
|
||||
.argc = argc,
|
||||
.argv = argv,
|
||||
.result = 0
|
||||
};
|
||||
|
||||
BaseType_t task_result = xTaskCreate(
|
||||
test_task,
|
||||
"test_task",
|
||||
8192,
|
||||
&data,
|
||||
1,
|
||||
nullptr
|
||||
);
|
||||
|
||||
if (task_result != pdPASS) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
vTaskStartScheduler();
|
||||
|
||||
return data.result;
|
||||
}
|
||||
@ -15,26 +15,12 @@ tactility_add_module(app-module
|
||||
|
||||
# Tells source/io.cpp its real-syscall fallback must go through __real_read/write/close() rather
|
||||
# than calling ::read/::write/::close() directly, on every platform where those are wrapped: via
|
||||
# -Wl,--wrap= on ESP-IDF (see the top-level CMakeLists.txt) and non-Apple POSIX (below), or via
|
||||
# source/stdio_wrap.cpp's dyld interpose on Apple (whose linker lacks --wrap).
|
||||
# -Wl,--wrap= on ESP-IDF (see the top-level CMakeLists.txt), or via source/stdio_wrap.cpp's own
|
||||
# read/write/close and printf-family definitions on POSIX (dyld interpose on Apple, plain
|
||||
# symbol overrides elsewhere - see that file for why POSIX doesn't use --wrap).
|
||||
tactility_get_module_name(app-module MODULE_NAME)
|
||||
target_compile_definitions(${MODULE_NAME} PRIVATE TT_APP_IO_WRAPS_STDIO)
|
||||
|
||||
# Routes every read()/write()/close() and printf-family call to source/stdio_wrap.cpp's __wrap_*
|
||||
# functions; see that file for what they do and why. ESP-IDF wraps the same symbols itself (see
|
||||
# the top-level CMakeLists.txt); Apple gets the same routing via dyld interpose instead, self-
|
||||
# registered in that file. PUBLIC so every consumer of this module (Tactility, and any test target
|
||||
# that links app-module directly) gets the flags too.
|
||||
if (NOT ESP_PLATFORM AND NOT APPLE)
|
||||
tactility_get_module_name(app-module MODULE_NAME)
|
||||
target_link_options(${MODULE_NAME} PUBLIC
|
||||
"-Wl,--wrap=read" "-Wl,--wrap=write" "-Wl,--wrap=close"
|
||||
"-Wl,--wrap=printf" "-Wl,--wrap=fprintf" "-Wl,--wrap=vprintf" "-Wl,--wrap=vfprintf"
|
||||
"-Wl,--wrap=puts" "-Wl,--wrap=fputs" "-Wl,--wrap=putchar" "-Wl,--wrap=fputc"
|
||||
"-Wl,--wrap=getchar" "-Wl,--wrap=fgetc" "-Wl,--wrap=fgets"
|
||||
)
|
||||
endif ()
|
||||
|
||||
# install.cpp resolves an installed binary's fixed bin/<platform>/<binary>.so path itself, so it
|
||||
# needs the same platform-arch string app-posix-module's own CMakeLists.txt defines for its
|
||||
# loader (the ESP32 equivalent, CONFIG_IDF_TARGET, comes for free from sdkconfig.h there).
|
||||
|
||||
@ -94,6 +94,8 @@ error_t app_execute_for_result_with_streams(
|
||||
*/
|
||||
bool app_is_executable(struct AppLocation location);
|
||||
|
||||
bool app_is_executable_path(const char* path);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -12,39 +12,28 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** Which readiness condition to block for in AppFileOps::await(). */
|
||||
typedef enum {
|
||||
APP_FILE_WAIT_READABLE,
|
||||
APP_FILE_WAIT_WRITABLE,
|
||||
} AppFileWait;
|
||||
|
||||
/** Bits returned by AppFileOps::poll(). */
|
||||
#define APP_FILE_READABLE (1u << 0)
|
||||
#define APP_FILE_WRITABLE (1u << 1)
|
||||
|
||||
/**
|
||||
* Operations table for one kind of file-like object (stream, file, device, ...). Every function
|
||||
* takes the type-erased `object` a concrete AppFile instance was constructed with.
|
||||
*/
|
||||
struct AppFileOps {
|
||||
ssize_t (*read)(void* object, void* buffer, size_t size);
|
||||
ssize_t (*write)(void* object, const void* buffer, size_t size);
|
||||
error_t (*close)(void* object);
|
||||
error_t (*await)(void* object, AppFileWait wait, TickType_t timeout);
|
||||
/** @return bitmask of APP_FILE_READABLE / APP_FILE_WRITABLE. */
|
||||
uint32_t (*poll)(void* object);
|
||||
/** Optional (may be NULL). Called by app_fd_table_get_and_retain() atomically with the fd
|
||||
* lookup, before handing `object` to a caller about to dispatch into it, so a concurrent
|
||||
* teardown of `object` can wait for that dispatch to finish instead of racing it. The caller
|
||||
* calls release() once done, regardless of what the dispatched call returned. */
|
||||
void (*retain)(void* object);
|
||||
void (*release)(void* object);
|
||||
};
|
||||
|
||||
/** A file-descriptor-table entry: an operations table paired with the object it operates on. */
|
||||
struct AppFile {
|
||||
const struct AppFileOps* ops;
|
||||
void* object;
|
||||
bool suppress_console_tee;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@ -1,9 +1,13 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
#pragma once
|
||||
|
||||
#include <app/file.h>
|
||||
|
||||
#include <stddef.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <tactility/error.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@ -16,20 +20,31 @@ extern "C" {
|
||||
#define APP_MAX_FDS 16
|
||||
|
||||
/**
|
||||
* FD-table dispatch for read()/write()/close(). When the calling task belongs to a running app
|
||||
* instance and @a fd is one that instance bound/allocated itself, it's looked up in that
|
||||
* instance's own fd table. Otherwise (no app instance, e.g. a kernel service task; or an app
|
||||
* instance's own fd that was never bound through app-module, e.g. a real file from fopen()/
|
||||
* open(), which this layer never intercepts) @a fd is a real underlying fd and the call falls
|
||||
* through to the real syscall unchanged.
|
||||
* @return number of bytes transferred, 0 on EOF (read) or a closed peer (write), or -1 with
|
||||
* errno set on failure. This is the fd-layer translation of AppFileOps::read()/write()'s ssize_t
|
||||
* and AppFileOps::close()'s error_t.
|
||||
* FD-table dispatch for read()/write()/close(). Falls through to the real syscall for a fd not
|
||||
* bound by the calling task's own app instance.
|
||||
*/
|
||||
ssize_t app_io_read(int fd, void* buffer, size_t size);
|
||||
ssize_t app_io_write(int fd, const void* buffer, size_t size);
|
||||
int app_io_close(int fd);
|
||||
|
||||
/**
|
||||
* FD-table dispatch for AppFileOps::await(): blocks until @a fd is ready or @a timeout elapses.
|
||||
* @retval ERROR_NOT_FOUND @a fd isn't bound in the calling task's own app instance fd table
|
||||
* @retval ERROR_TIMEOUT @a timeout elapsed
|
||||
* @retval ERROR_NONE the condition is true
|
||||
*/
|
||||
error_t app_io_await(int fd, AppFileWait wait, TickType_t timeout);
|
||||
|
||||
/**
|
||||
* Installs a custom AppFileOps at @a fd in the calling task's own app instance fd table.
|
||||
* Unlike AppStreamBinding, writes are never teed to the real underlying fd.
|
||||
* @warning Must be called from the app instance's own task.
|
||||
* @retval ERROR_NOT_FOUND the calling task isn't a running app instance
|
||||
* @retval ERROR_OUT_OF_RANGE @a fd is outside [0, APP_MAX_FDS)
|
||||
* @retval ERROR_NONE on success
|
||||
*/
|
||||
error_t app_io_bind_self(int fd, const struct AppFileOps* ops, void* object);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -32,9 +32,10 @@ enum AppManifestFlags {
|
||||
};
|
||||
|
||||
/** Largest stack depth (in words) an app may request. Keeps `depth * sizeof(StackType_t)` safely
|
||||
* bounded and stops one app from claiming an unreasonable share of available RAM. A depth beyond
|
||||
* this must be rejected outright, not silently truncated or clamped. */
|
||||
#define APP_STACK_SIZE_MAX 16384
|
||||
* bounded and stops one app from claiming an unreasonable share of available RAM.
|
||||
* A depth beyond must be rejected outright.
|
||||
* Was last increased because of recursive-descent shell interpreter. */
|
||||
#define APP_STACK_SIZE_MAX 65535
|
||||
|
||||
struct AppStackConfig {
|
||||
/** Stack depth (in words, matching FreeRTOS's configSTACK_DEPTH_TYPE) for this app's task.
|
||||
|
||||
@ -17,7 +17,7 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** @warning This is internal data. Do not read/write to it directly. */
|
||||
/** @warning Internal data. */
|
||||
struct AppStreamBuffer {
|
||||
uint8_t* data;
|
||||
size_t capacity;
|
||||
@ -29,45 +29,29 @@ struct AppStreamBuffer {
|
||||
/**
|
||||
* Buffered byte-oriented communication between one producer task and one consumer task. The
|
||||
* consumer owns the AppStream object and its lifetime. See app_stream_subscribe().
|
||||
*
|
||||
* @warning This is internal data. Do not read/write to it directly.
|
||||
* @warning Internal data.
|
||||
*/
|
||||
struct AppStream {
|
||||
struct AppStreamBuffer buffer;
|
||||
AppInstanceId producer_id;
|
||||
TaskHandle_t producer_task;
|
||||
/** fd this stream is installed at in producer_id's fd table; set by
|
||||
* app_stream_subscribe()/app_start_with_streams(), used by
|
||||
* app_stream_unsubscribe() to find it again. */
|
||||
int producer_fd;
|
||||
|
||||
struct Mutex mutex;
|
||||
/** Caller-owned group readiness is signalled on; see app_stream_subscribe(). */
|
||||
struct TaskEventGroup* event_group;
|
||||
uint32_t readable_bit;
|
||||
uint32_t writable_bit;
|
||||
bool closed;
|
||||
/** Count of AppFileOps calls currently executing against this stream; app_stream_unsubscribe()
|
||||
* waits for this to reach 0 before destructing `mutex`, since a call already blocked in
|
||||
* app_stream_await() when unsubscribe starts only wakes (it doesn't vanish) when closed. */
|
||||
int active_operations;
|
||||
};
|
||||
|
||||
/**
|
||||
* Registers @a stream as the file-like object bound to @a producer_id's fd table at
|
||||
* @a producer_fd, claiming two bits from @a event_group for its readable/writable readiness.
|
||||
* There is at most one subscriber for a given app fd. Subscribing over an existing one
|
||||
* atomically closes it first (any task blocked on it wakes; already-buffered bytes remain
|
||||
* readable until drained) and installs @a stream in its place.
|
||||
* @param[in,out] stream caller-owned. Storage must remain valid until app_stream_unsubscribe()
|
||||
* returns. That is the only operation guaranteeing both that the fd-table binding is gone and
|
||||
* that no AppFileOps call is still executing against @a stream; app_stream_close() alone does
|
||||
* neither.
|
||||
* @param[in] buffer ring buffer storage; caller-owned, same validity requirement as @a stream.
|
||||
* @param[in] buffer_capacity size of @a buffer in bytes.
|
||||
* @param[in] event_group caller-owned; must outlive @a stream (i.e. be destructed only after
|
||||
* app_stream_unsubscribe()). Lets a task wait on this stream's readiness together with other
|
||||
* event sources sharing the same group via task_event_group_wait()/task_event_group_wait_any().
|
||||
* @a producer_fd, claiming two bits from @a event_group for readiness. At most one subscriber
|
||||
* per fd; subscribing over an existing one closes it first.
|
||||
* @param[in,out] stream caller-owned; must stay valid until app_stream_unsubscribe() returns.
|
||||
* @param[in] buffer ring buffer storage; caller-owned, same validity as @a stream.
|
||||
* @param[in] event_group caller-owned; must outlive @a stream.
|
||||
* @retval ERROR_NOT_FOUND no instance with this id is running
|
||||
* @retval ERROR_OUT_OF_RANGE @a producer_fd is out of range
|
||||
* @retval ERROR_RESOURCE @a event_group has no free bits left to claim
|
||||
@ -76,19 +60,22 @@ struct AppStream {
|
||||
error_t app_stream_subscribe(struct AppStream* stream, void* buffer, size_t buffer_capacity, struct TaskEventGroup* event_group, AppInstanceId producer_id, int producer_fd);
|
||||
|
||||
/**
|
||||
* Removes @a stream's binding from whichever fd table it was installed in (further use of that
|
||||
* fd then fails), wakes and waits for every AppFileOps call currently in flight against
|
||||
* @a stream to finish, then releases its two bits back to the event_group given to
|
||||
* app_stream_subscribe() and destructs its internal mutex. Only after this returns is
|
||||
* @a stream's storage safe to free or reuse.
|
||||
* Binds an already-subscribed @a stream at a second fd too, so writes to either fd land in the
|
||||
* same buffer in true write-time order (e.g. aliasing stderr onto a stdout stream).
|
||||
* @retval ERROR_NOT_FOUND no instance with @a stream's producer_id is running
|
||||
* @retval ERROR_OUT_OF_RANGE @a alias_fd is out of range
|
||||
*/
|
||||
error_t app_stream_bind_alias_fd(struct AppStream* stream, int alias_fd);
|
||||
|
||||
/**
|
||||
* Removes @a stream's fd-table binding, waits for in-flight AppFileOps calls to finish, then
|
||||
* releases its event bits and destructs its mutex. Only after this returns is @a stream safe to
|
||||
* free or reuse.
|
||||
*/
|
||||
error_t app_stream_unsubscribe(struct AppStream* stream);
|
||||
|
||||
/**
|
||||
* Blocks until @a stream becomes readable/writable (per @a wait) or @a timeout elapses. Checks
|
||||
* the current state directly before blocking, so a permanently-true condition (e.g. closed)
|
||||
* keeps returning immediately on every call, even though the underlying event bit itself is
|
||||
* one-shot (task_event_group_wait() clears a matched bit on exit).
|
||||
* Blocks until @a stream becomes readable/writable (per @a wait) or @a timeout elapses.
|
||||
* @retval ERROR_NONE the condition is true
|
||||
* @retval ERROR_TIMEOUT @a timeout elapsed
|
||||
* @retval ERROR_ISR_STATUS called from an ISR
|
||||
@ -98,16 +85,10 @@ error_t app_stream_await(struct AppStream* stream, AppFileWait wait, TickType_t
|
||||
/** Non-blocking: copies up to @a buffer_size currently-available bytes out of @a stream. */
|
||||
size_t app_stream_read(struct AppStream* stream, void* buffer, size_t buffer_size);
|
||||
|
||||
/** Non-blocking: copies up to @a buffer_size bytes into @a stream, as much as currently fits.
|
||||
* Copies nothing and returns 0 once @a stream is closed. */
|
||||
/** Non-blocking: copies up to @a buffer_size bytes into @a stream. Returns 0 once closed. */
|
||||
size_t app_stream_write(struct AppStream* stream, const void* buffer, size_t buffer_size);
|
||||
|
||||
/**
|
||||
* Marks @a stream closed: wakes any task blocked in app_stream_await(), and causes the other side
|
||||
* to observe EOF (reader, once drained) or a write error (writer). Safe to call while another
|
||||
* task may be blocked on @a stream, unlike app_stream_unsubscribe() (see its own doc); does not
|
||||
* by itself make @a stream's storage safe to free.
|
||||
*/
|
||||
/** Marks @a stream closed: readers see EOF, writers fail. Does not free @a stream's storage. */
|
||||
error_t app_stream_close(struct AppStream* stream);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@ -58,9 +58,10 @@ void app_fd_table_teardown(struct AppFdTable* table);
|
||||
/**
|
||||
* Installs {ops, object} at @a fd, closing whatever was previously there first (the null device
|
||||
* counts as "previously there" for fds 0-2, so this doubles as their initial stdio binding).
|
||||
* @param[in] suppress_console_tee see AppFile::suppress_console_tee
|
||||
* @retval ERROR_OUT_OF_RANGE @a fd is outside [0, APP_MAX_FDS)
|
||||
*/
|
||||
error_t app_fd_table_bind(struct AppFdTable* table, int fd, const struct AppFileOps* ops, void* object);
|
||||
error_t app_fd_table_bind(struct AppFdTable* table, int fd, const struct AppFileOps* ops, void* object, bool suppress_console_tee);
|
||||
|
||||
/**
|
||||
* Installs {ops, object} at the lowest unused fd >= 3.
|
||||
|
||||
@ -44,6 +44,18 @@ error_t app_execute_for_result_with_streams(AppLocation location, AppStackConfig
|
||||
return app_manager_start_internal(nullptr, location, stack, parent_instance_id, argc, argv, bindings, binding_count, out_app_instance_id);
|
||||
}
|
||||
|
||||
bool app_is_executable_path(const char* path) {
|
||||
const AppLoaderApi* loader = find_loader_api(APP_LOCATION_PATH);
|
||||
if (loader == nullptr || loader->is_executable == nullptr) {
|
||||
return false;
|
||||
}
|
||||
AppLocation location = {
|
||||
.type = APP_LOCATION_PATH,
|
||||
.location = (void*)path,
|
||||
};
|
||||
return loader->is_executable(location);
|
||||
}
|
||||
|
||||
bool app_is_executable(AppLocation location) {
|
||||
const AppLoaderApi* loader = find_loader_api(location.type);
|
||||
if (loader == nullptr || loader->is_executable == nullptr) {
|
||||
|
||||
@ -71,7 +71,7 @@ void app_fd_table_teardown(AppFdTable* table) {
|
||||
mutex_destruct(&table->mutex);
|
||||
}
|
||||
|
||||
error_t app_fd_table_bind(AppFdTable* table, int fd, const AppFileOps* ops, void* object) {
|
||||
error_t app_fd_table_bind(AppFdTable* table, int fd, const AppFileOps* ops, void* object, bool suppress_console_tee) {
|
||||
if (!fd_in_range(fd)) {
|
||||
return ERROR_OUT_OF_RANGE;
|
||||
}
|
||||
@ -81,7 +81,7 @@ error_t app_fd_table_bind(AppFdTable* table, int fd, const AppFileOps* ops, void
|
||||
AppFdSlot& slot = table->slots[fd];
|
||||
AppFile old = slot.file;
|
||||
bool had_old = slot.in_use;
|
||||
slot.file = { .ops = ops, .object = object };
|
||||
slot.file = { .ops = ops, .object = object, .suppress_console_tee = suppress_console_tee };
|
||||
slot.in_use = true;
|
||||
slot.ever_used = true;
|
||||
mutex_unlock(&table->mutex);
|
||||
|
||||
@ -92,7 +92,7 @@ bool delete_recursively(const std::string& path) {
|
||||
}
|
||||
|
||||
bool get_app_install_directory(std::string& out_path) {
|
||||
char root[192];
|
||||
char root[FILE_MAX_PATH_STRING_LENGTH];
|
||||
if (paths_get_data_path(root, sizeof(root)) != ERROR_NONE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -96,14 +96,17 @@ ssize_t app_io_write(int fd, const void* buffer, size_t size) {
|
||||
if (file.ops->release != nullptr) {
|
||||
file.ops->release(file.object);
|
||||
}
|
||||
// Tee to the real fd too: a bound stream only exists because a parent explicitly asked
|
||||
// to capture this app instance's own output (see AppStreamBinding), but generic code
|
||||
// running on that same instance's thread - most commonly the platform's own logging
|
||||
// Tee to the real fd too: a bound stream normally exists because a parent explicitly
|
||||
// asked to capture this app instance's own output (see AppStreamBinding), but generic
|
||||
// code running on that same instance's thread - most commonly the platform's own logging
|
||||
// (LOG_I/etc, which calls write() the same as anything else) - has no way to know its
|
||||
// output is currently being intercepted. Without this, a log line emitted while any app
|
||||
// instance has its stdout captured would vanish from the console entirely instead of
|
||||
// just also being visible to the capturing parent.
|
||||
real_write(fd, buffer, size);
|
||||
// just also being visible to the capturing parent. An instance that bound its own fd
|
||||
// (see app_io_bind_self()) opts out - it wants exclusive ownership, not a silent tap.
|
||||
if (!file.suppress_console_tee) {
|
||||
real_write(fd, buffer, size);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
if (table != nullptr && app_fd_table_is_app_owned(table, fd)) {
|
||||
@ -128,4 +131,28 @@ int app_io_close(int fd) {
|
||||
return real_close(fd);
|
||||
}
|
||||
|
||||
error_t app_io_await(int fd, AppFileWait wait, TickType_t timeout) {
|
||||
AppFdTable* table = current_app_fd_table();
|
||||
if (table == nullptr) {
|
||||
return ERROR_NOT_FOUND;
|
||||
}
|
||||
AppFile file {};
|
||||
if (!app_fd_table_get_and_retain(table, fd, &file)) {
|
||||
return ERROR_NOT_FOUND;
|
||||
}
|
||||
error_t result = file.ops->await(file.object, wait, timeout);
|
||||
if (file.ops->release != nullptr) {
|
||||
file.ops->release(file.object);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
error_t app_io_bind_self(int fd, const AppFileOps* ops, void* object) {
|
||||
AppFdTable* table = current_app_fd_table();
|
||||
if (table == nullptr) {
|
||||
return ERROR_NOT_FOUND;
|
||||
}
|
||||
return app_fd_table_bind(table, fd, ops, object, /*suppress_console_tee=*/true);
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
|
||||
@ -33,6 +33,7 @@ static const ModuleSymbol SYMBOLS[] = {
|
||||
DEFINE_MODULE_SYMBOL(app_execute_with_streams),
|
||||
DEFINE_MODULE_SYMBOL(app_execute_for_result_with_streams),
|
||||
DEFINE_MODULE_SYMBOL(app_is_executable),
|
||||
DEFINE_MODULE_SYMBOL(app_is_executable_path),
|
||||
// app/install
|
||||
DEFINE_MODULE_SYMBOL(app_get_install_path),
|
||||
DEFINE_MODULE_SYMBOL(app_install),
|
||||
@ -41,6 +42,8 @@ static const ModuleSymbol SYMBOLS[] = {
|
||||
DEFINE_MODULE_SYMBOL(app_io_read),
|
||||
DEFINE_MODULE_SYMBOL(app_io_write),
|
||||
DEFINE_MODULE_SYMBOL(app_io_close),
|
||||
DEFINE_MODULE_SYMBOL(app_io_await),
|
||||
DEFINE_MODULE_SYMBOL(app_io_bind_self),
|
||||
// app/manager
|
||||
DEFINE_MODULE_SYMBOL(app_manager_stop),
|
||||
DEFINE_MODULE_SYMBOL(app_manager_get_state),
|
||||
@ -76,6 +79,7 @@ static const ModuleSymbol SYMBOLS[] = {
|
||||
DEFINE_MODULE_SYMBOL(app_start_with_streams),
|
||||
DEFINE_MODULE_SYMBOL(app_start_for_result_with_streams),
|
||||
// app/stream
|
||||
DEFINE_MODULE_SYMBOL(app_stream_bind_alias_fd),
|
||||
DEFINE_MODULE_SYMBOL(app_stream_subscribe),
|
||||
DEFINE_MODULE_SYMBOL(app_stream_unsubscribe),
|
||||
DEFINE_MODULE_SYMBOL(app_stream_await),
|
||||
|
||||
@ -31,7 +31,7 @@ bool app_get_install_dir_from_binary_path(const char* binary_path, std::string&
|
||||
extern "C" {
|
||||
|
||||
error_t app_paths_get_user_data_directory(const char* app_id, char* out_path, size_t out_path_size) {
|
||||
char root[192];
|
||||
char root[FILE_MAX_PATH_STRING_LENGTH];
|
||||
error_t error = paths_get_data_path(root, sizeof(root));
|
||||
if (error != ERROR_NONE) {
|
||||
return error;
|
||||
@ -44,7 +44,7 @@ error_t app_paths_get_user_data_directory(const char* app_id, char* out_path, si
|
||||
}
|
||||
|
||||
error_t app_paths_get_user_data_path(const char* app_id, const char* child_path, char* out_path, size_t out_path_size) {
|
||||
char directory[224];
|
||||
char directory[FILE_MAX_PATH_STRING_LENGTH];
|
||||
error_t error = app_paths_get_user_data_directory(app_id, directory, sizeof(directory));
|
||||
if (error != ERROR_NONE) {
|
||||
return error;
|
||||
@ -80,7 +80,7 @@ error_t app_paths_get_assets_directory(const char* app_id, char* out_path, size_
|
||||
}
|
||||
|
||||
error_t app_paths_get_assets_path(const char* app_id, const char* child_path, char* out_path, size_t out_path_size) {
|
||||
char directory[224];
|
||||
char directory[FILE_MAX_PATH_STRING_LENGTH];
|
||||
error_t error = app_paths_get_assets_directory(app_id, directory, sizeof(directory));
|
||||
if (error != ERROR_NONE) {
|
||||
return error;
|
||||
|
||||
@ -412,7 +412,7 @@ error_t app_scheduler_start(AppInstanceId app_instance_id, AppLocation location,
|
||||
vTaskPrioritySet(task_handle, APP_TASK_PRIORITY);
|
||||
vTaskResume(task_handle);
|
||||
|
||||
memory_print_stats();
|
||||
memory_log_stats();
|
||||
|
||||
return ERROR_NONE;
|
||||
}
|
||||
|
||||
@ -1,20 +1,16 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Paired with -Wl,--wrap= on POSIX (this module's own CMakeLists.txt) and ESP32 (top-level
|
||||
// CMakeLists.txt); self-registered via dyld interpose below on Apple, whose linker doesn't
|
||||
// support --wrap.
|
||||
// ESP32 uses -Wl,--wrap=. POSIX can't: --wrap doesn't reach a dlopen()ed app's own printf/write
|
||||
// calls, so these are defined under their real names instead - dyld interpose on Apple, plain
|
||||
// strong definitions elsewhere (ELF gives the main executable's symbols priority process-wide).
|
||||
#include <app/io.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifdef ESP_PLATFORM
|
||||
|
||||
// Newlib's own stdio (fflush()'s buffer-flush path, in particular) calls the reentrant
|
||||
// _read_r/_write_r/_close_r syscall stubs directly, not the plain read()/write()/close() newlib
|
||||
// itself provides as thin wrappers around them (see e.g. esp-idf's components/newlib/src/
|
||||
// syscalls.c: `write(fd, dst, size) { return _write_r(__getreent(), fd, dst, size); }`)
|
||||
// Wrapping the plain names only catches direct write()-style callers, not newlib's own internal
|
||||
// stdio calls, so the _r stubs are wrapped here instead.
|
||||
// Newlib's own stdio calls the reentrant _read_r/_write_r/_close_r stubs directly, not the plain
|
||||
// read/write/close wrappers, so those stubs are wrapped instead of the plain names.
|
||||
#include <reent.h>
|
||||
|
||||
extern "C" {
|
||||
@ -54,15 +50,7 @@ int __wrap_close(int fd) {
|
||||
|
||||
}
|
||||
|
||||
#endif // ESP_PLATFORM
|
||||
|
||||
#ifdef __APPLE__
|
||||
|
||||
// --wrap also synthesizes __real_read/write/close automatically; dyld interpose doesn't, so
|
||||
// io.cpp's TT_APP_IO_WRAPS_STDIO fallback needs them defined here. dlsym(RTLD_NEXT, ...) is the
|
||||
// standard way to reach the true libSystem implementation despite the interpose below: a direct
|
||||
// call to read/write/close from this file would just recurse into __wrap_read/write/close, since
|
||||
// interpose rewrites every reference to those symbols in the process, this file included.
|
||||
// dlsym(RTLD_NEXT, ...) avoids recursing into our own override below.
|
||||
#include <dlfcn.h>
|
||||
#include <unistd.h>
|
||||
|
||||
@ -85,9 +73,9 @@ int __real_close(int fd) {
|
||||
|
||||
}
|
||||
|
||||
// <mach-o/dyld-interposing.h> isn't a public SDK header (it ships with dyld's own source, not
|
||||
// Xcode/Command Line Tools), so this reimplements its DYLD_INTERPOSE macro locally; reused below
|
||||
// for the printf-family interposes too.
|
||||
#ifdef __APPLE__
|
||||
|
||||
// <mach-o/dyld-interposing.h> isn't a public SDK header, so reimplemented locally.
|
||||
#define TT_DYLD_INTERPOSE(replacement, replacee) \
|
||||
__attribute__((used)) static struct { const void* replacement; const void* replacee; } \
|
||||
tt_interpose_##replacee __attribute__((section("__DATA,__interpose"))) = { \
|
||||
@ -98,21 +86,37 @@ TT_DYLD_INTERPOSE(__wrap_read, read)
|
||||
TT_DYLD_INTERPOSE(__wrap_write, write)
|
||||
TT_DYLD_INTERPOSE(__wrap_close, close)
|
||||
|
||||
#else
|
||||
|
||||
extern "C" {
|
||||
|
||||
ssize_t read(int fd, void* buffer, size_t size) {
|
||||
return __wrap_read(fd, buffer, size);
|
||||
}
|
||||
|
||||
ssize_t write(int fd, const void* buffer, size_t size) {
|
||||
return __wrap_write(fd, buffer, size);
|
||||
}
|
||||
|
||||
int close(int fd) {
|
||||
return __wrap_close(fd);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // __APPLE__
|
||||
|
||||
#endif // ESP_PLATFORM
|
||||
|
||||
// region glibc stdio wraps
|
||||
//
|
||||
// libc's printf/fprintf/etc are compiled into the C library and call an internal, non-exported
|
||||
// write() alias, which --wrap=write/the read/write/close interpose above can't reach: only calls
|
||||
// WE make to the public symbol. These wraps instead redirect calls WE make to printf/fprintf/etc,
|
||||
// the same trick as read/write/close above. Newlib (ESP-IDF) doesn't have this gap: its stdio does
|
||||
// call the wrappable syscall stubs, so this block is POSIX-only.
|
||||
// libc's printf/fprintf/etc call an internal, non-exported write() alias that the read/write/close
|
||||
// wraps above can't reach, so these redirect calls to printf/fprintf/etc directly. POSIX-only:
|
||||
// newlib's stdio already goes through the wrappable syscall stubs.
|
||||
//
|
||||
// Scoped to the printf/getc families only: fread/fwrite take an arbitrary FILE* and are already
|
||||
// used sitewide for real file I/O (e.g. File.cpp's readBinaryInternal), so wrapping them would
|
||||
// route every such call through this file's stdin/stdout check, a correctness risk for unrelated
|
||||
// code that isn't worth taking here. putc/getc are excluded too since libc defines them as
|
||||
// macros, not real calls, so wrapping those symbols wouldn't reliably intercept them.
|
||||
// Scoped to printf/getc: fread/fwrite are used sitewide for real file I/O, so wrapping them would
|
||||
// be a correctness risk for unrelated code. putc/getc are macros, not real calls, so wrapping
|
||||
// those symbols wouldn't reliably intercept them.
|
||||
|
||||
#if !defined(ESP_PLATFORM)
|
||||
|
||||
@ -130,10 +134,6 @@ int __real_fgetc(FILE* stream);
|
||||
char* __real_fgets(char* buffer, int size, FILE* stream);
|
||||
}
|
||||
|
||||
#ifdef __APPLE__
|
||||
|
||||
// --wrap synthesizes these automatically elsewhere; on Apple they're defined here via
|
||||
// dlsym(RTLD_NEXT, ...) instead. See the read/write/close __real_* block above for why.
|
||||
#include <dlfcn.h>
|
||||
|
||||
extern "C" {
|
||||
@ -165,15 +165,13 @@ char* __real_fgets(char* buffer, int size, FILE* stream) {
|
||||
|
||||
}
|
||||
|
||||
#endif // __APPLE__
|
||||
|
||||
namespace {
|
||||
|
||||
void writeAllToStdout(const void* data, size_t size) {
|
||||
void writeAllTo(int fd, const void* data, size_t size) {
|
||||
const auto* bytes = static_cast<const char*>(data);
|
||||
size_t remaining = size;
|
||||
while (remaining > 0) {
|
||||
ssize_t written = app_io_write(STDOUT_FILENO, bytes, remaining);
|
||||
ssize_t written = app_io_write(fd, bytes, remaining);
|
||||
if (written <= 0) {
|
||||
break;
|
||||
}
|
||||
@ -182,9 +180,7 @@ void writeAllToStdout(const void* data, size_t size) {
|
||||
}
|
||||
}
|
||||
|
||||
// Formats into stdout via app_io_write() rather than through a FILE*'s own buffering, since that
|
||||
// buffering is exactly what glibc's internal write() call sidesteps --wrap for in the first place.
|
||||
int formatToStdout(const char* format, va_list args) {
|
||||
int formatTo(int fd, const char* format, va_list args) {
|
||||
char stackBuffer[256];
|
||||
va_list argsForStack;
|
||||
va_copy(argsForStack, args);
|
||||
@ -194,7 +190,7 @@ int formatToStdout(const char* format, va_list args) {
|
||||
return needed;
|
||||
}
|
||||
if (static_cast<size_t>(needed) < sizeof(stackBuffer)) {
|
||||
writeAllToStdout(stackBuffer, static_cast<size_t>(needed));
|
||||
writeAllTo(fd, stackBuffer, static_cast<size_t>(needed));
|
||||
return needed;
|
||||
}
|
||||
auto heapBuffer = std::make_unique<char[]>(static_cast<size_t>(needed) + 1);
|
||||
@ -202,7 +198,7 @@ int formatToStdout(const char* format, va_list args) {
|
||||
va_copy(argsForHeap, args);
|
||||
vsnprintf(heapBuffer.get(), static_cast<size_t>(needed) + 1, format, argsForHeap);
|
||||
va_end(argsForHeap);
|
||||
writeAllToStdout(heapBuffer.get(), static_cast<size_t>(needed));
|
||||
writeAllTo(fd, heapBuffer.get(), static_cast<size_t>(needed));
|
||||
return needed;
|
||||
}
|
||||
|
||||
@ -210,25 +206,32 @@ int readOneFromStdin(char& out) {
|
||||
return static_cast<int>(app_io_read(STDIN_FILENO, &out, 1));
|
||||
}
|
||||
|
||||
int targetFdOf(FILE* stream) {
|
||||
if (stream == stdout) return STDOUT_FILENO;
|
||||
if (stream == stderr) return STDERR_FILENO;
|
||||
return -1;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
extern "C" {
|
||||
|
||||
int __wrap_vprintf(const char* format, va_list args) {
|
||||
return formatToStdout(format, args);
|
||||
return formatTo(STDOUT_FILENO, format, args);
|
||||
}
|
||||
|
||||
int __wrap_printf(const char* format, ...) {
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
int result = formatToStdout(format, args);
|
||||
int result = formatTo(STDOUT_FILENO, format, args);
|
||||
va_end(args);
|
||||
return result;
|
||||
}
|
||||
|
||||
int __wrap_vfprintf(FILE* stream, const char* format, va_list args) {
|
||||
if (stream == stdout) {
|
||||
return formatToStdout(format, args);
|
||||
int fd = targetFdOf(stream);
|
||||
if (fd >= 0) {
|
||||
return formatTo(fd, format, args);
|
||||
}
|
||||
return __real_vfprintf(stream, format, args);
|
||||
}
|
||||
@ -236,20 +239,22 @@ int __wrap_vfprintf(FILE* stream, const char* format, va_list args) {
|
||||
int __wrap_fprintf(FILE* stream, const char* format, ...) {
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
int result = (stream == stdout) ? formatToStdout(format, args) : __real_vfprintf(stream, format, args);
|
||||
int fd = targetFdOf(stream);
|
||||
int result = (fd >= 0) ? formatTo(fd, format, args) : __real_vfprintf(stream, format, args);
|
||||
va_end(args);
|
||||
return result;
|
||||
}
|
||||
|
||||
int __wrap_puts(const char* s) {
|
||||
writeAllToStdout(s, strlen(s));
|
||||
writeAllToStdout("\n", 1);
|
||||
writeAllTo(STDOUT_FILENO, s, strlen(s));
|
||||
writeAllTo(STDOUT_FILENO, "\n", 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __wrap_fputs(const char* s, FILE* stream) {
|
||||
if (stream == stdout) {
|
||||
writeAllToStdout(s, strlen(s));
|
||||
int fd = targetFdOf(stream);
|
||||
if (fd >= 0) {
|
||||
writeAllTo(fd, s, strlen(s));
|
||||
return 0;
|
||||
}
|
||||
return __real_fputs(s, stream);
|
||||
@ -257,13 +262,16 @@ int __wrap_fputs(const char* s, FILE* stream) {
|
||||
|
||||
int __wrap_putchar(int c) {
|
||||
auto ch = static_cast<char>(c);
|
||||
writeAllToStdout(&ch, 1);
|
||||
writeAllTo(STDOUT_FILENO, &ch, 1);
|
||||
return c;
|
||||
}
|
||||
|
||||
int __wrap_fputc(int c, FILE* stream) {
|
||||
if (stream == stdout) {
|
||||
return __wrap_putchar(c);
|
||||
int fd = targetFdOf(stream);
|
||||
if (fd >= 0) {
|
||||
auto ch = static_cast<char>(c);
|
||||
writeAllTo(fd, &ch, 1);
|
||||
return c;
|
||||
}
|
||||
return __real_fputc(c, stream);
|
||||
}
|
||||
@ -320,6 +328,64 @@ TT_DYLD_INTERPOSE(__wrap_fputc, fputc)
|
||||
TT_DYLD_INTERPOSE(__wrap_getchar, getchar)
|
||||
TT_DYLD_INTERPOSE(__wrap_fgetc, fgetc)
|
||||
TT_DYLD_INTERPOSE(__wrap_fgets, fgets)
|
||||
#else
|
||||
|
||||
extern "C" {
|
||||
|
||||
int vprintf(const char* format, va_list args) {
|
||||
return __wrap_vprintf(format, args);
|
||||
}
|
||||
|
||||
int printf(const char* format, ...) {
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
int result = __wrap_vprintf(format, args);
|
||||
va_end(args);
|
||||
return result;
|
||||
}
|
||||
|
||||
int vfprintf(FILE* stream, const char* format, va_list args) {
|
||||
return __wrap_vfprintf(stream, format, args);
|
||||
}
|
||||
|
||||
int fprintf(FILE* stream, const char* format, ...) {
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
int result = __wrap_vfprintf(stream, format, args);
|
||||
va_end(args);
|
||||
return result;
|
||||
}
|
||||
|
||||
int puts(const char* s) {
|
||||
return __wrap_puts(s);
|
||||
}
|
||||
|
||||
int fputs(const char* s, FILE* stream) {
|
||||
return __wrap_fputs(s, stream);
|
||||
}
|
||||
|
||||
int putchar(int c) {
|
||||
return __wrap_putchar(c);
|
||||
}
|
||||
|
||||
int fputc(int c, FILE* stream) {
|
||||
return __wrap_fputc(c, stream);
|
||||
}
|
||||
|
||||
int getchar() {
|
||||
return __wrap_getchar();
|
||||
}
|
||||
|
||||
int fgetc(FILE* stream) {
|
||||
return __wrap_fgetc(stream);
|
||||
}
|
||||
|
||||
char* fgets(char* buffer, int size, FILE* stream) {
|
||||
return __wrap_fgets(buffer, size, stream);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // __APPLE__
|
||||
|
||||
#endif // !ESP_PLATFORM
|
||||
|
||||
@ -194,7 +194,7 @@ error_t app_stream_subscribe(AppStream* stream, void* buffer, size_t buffer_capa
|
||||
return ERROR_NOT_FOUND;
|
||||
}
|
||||
stream->producer_task = iterator->second.task;
|
||||
error_t bind_result = app_fd_table_bind(&iterator->second.fd_table, producer_fd, &STREAM_OPS, stream);
|
||||
error_t bind_result = app_fd_table_bind(&iterator->second.fd_table, producer_fd, &STREAM_OPS, stream, /*suppress_console_tee=*/false);
|
||||
mutex_unlock(&ledger.mutex);
|
||||
|
||||
if (bind_result != ERROR_NONE) {
|
||||
@ -205,6 +205,25 @@ error_t app_stream_subscribe(AppStream* stream, void* buffer, size_t buffer_capa
|
||||
return bind_result;
|
||||
}
|
||||
|
||||
error_t app_stream_bind_alias_fd(AppStream* stream, int alias_fd) {
|
||||
if (alias_fd < 0 || alias_fd >= APP_MAX_FDS) {
|
||||
return ERROR_OUT_OF_RANGE;
|
||||
}
|
||||
|
||||
// Same locking rationale as app_stream_subscribe(): held across the fd-table lookup and bind
|
||||
// so this can't race app_fd_table_teardown().
|
||||
auto& ledger = app_ledger();
|
||||
mutex_lock(&ledger.mutex);
|
||||
auto iterator = ledger.instances.find(stream->producer_id);
|
||||
if (iterator == ledger.instances.end()) {
|
||||
mutex_unlock(&ledger.mutex);
|
||||
return ERROR_NOT_FOUND;
|
||||
}
|
||||
error_t result = app_fd_table_bind(&iterator->second.fd_table, alias_fd, &STREAM_OPS, stream, /*suppress_console_tee=*/false);
|
||||
mutex_unlock(&ledger.mutex);
|
||||
return result;
|
||||
}
|
||||
|
||||
error_t app_stream_unsubscribe(AppStream* stream) {
|
||||
// Held across the fd-table lookup, get, and close. See app_stream_subscribe()'s own
|
||||
// comment on why this must stay exclusive with app_fd_table_teardown().
|
||||
@ -213,9 +232,14 @@ error_t app_stream_unsubscribe(AppStream* stream) {
|
||||
auto iterator = ledger.instances.find(stream->producer_id);
|
||||
if (iterator != ledger.instances.end()) {
|
||||
AppFdTable* table = &iterator->second.fd_table;
|
||||
AppFile current {};
|
||||
if (app_fd_table_get(table, stream->producer_fd, ¤t) && current.object == stream) {
|
||||
app_fd_table_close(table, stream->producer_fd); // -> stream_file_close() -> app_stream_close()
|
||||
// Closes producer_fd and any fd bound via app_stream_bind_alias_fd(): all share this same
|
||||
// stream object, and app_fd_table_teardown() finding one afterwards would dispatch into
|
||||
// a destructed mutex otherwise.
|
||||
for (int fd = 0; fd < APP_MAX_FDS; fd++) {
|
||||
AppFile current {};
|
||||
if (app_fd_table_get(table, fd, ¤t) && current.object == stream) {
|
||||
app_fd_table_close(table, fd); // -> stream_file_close() -> app_stream_close()
|
||||
}
|
||||
}
|
||||
}
|
||||
mutex_unlock(&ledger.mutex);
|
||||
|
||||
@ -44,6 +44,18 @@ bool wait_for_state(AppInstanceId id, AppInstanceState target, uint32_t timeout_
|
||||
return app_manager_get_state(id) == target;
|
||||
}
|
||||
|
||||
bool wait_for_flag(std::atomic<bool>& flag, uint32_t timeout_ms) {
|
||||
uint32_t waited = 0;
|
||||
while (waited < timeout_ms) {
|
||||
if (flag.load(std::memory_order_acquire)) {
|
||||
return true;
|
||||
}
|
||||
delay_millis(10);
|
||||
waited += 10;
|
||||
}
|
||||
return flag.load(std::memory_order_acquire);
|
||||
}
|
||||
|
||||
std::atomic<ssize_t> g_stdio_write_result { -2 };
|
||||
std::atomic<ssize_t> g_stdio_read_result { -2 };
|
||||
|
||||
@ -90,6 +102,19 @@ int32_t blocked_writer_app_main(int, char*[]) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::atomic<error_t> g_await_before_write { ERROR_NONE };
|
||||
std::atomic<error_t> g_await_after_write { ERROR_TIMEOUT };
|
||||
std::atomic<bool> g_await_first_done { false };
|
||||
std::atomic<bool> g_await_done { false };
|
||||
|
||||
int32_t await_reader_app_main(int, char*[]) {
|
||||
g_await_before_write.store(app_io_await(STDIN_FILENO, APP_FILE_WAIT_READABLE, pdMS_TO_TICKS(50)), std::memory_order_release);
|
||||
g_await_first_done.store(true, std::memory_order_release);
|
||||
g_await_after_write.store(app_io_await(STDIN_FILENO, APP_FILE_WAIT_READABLE, pdMS_TO_TICKS(1000)), std::memory_order_release);
|
||||
g_await_done.store(true, std::memory_order_release);
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::atomic<ssize_t> g_real_file_write_result { -2 };
|
||||
std::atomic<ssize_t> g_real_file_read_result { -2 };
|
||||
std::atomic<bool> g_real_file_read_matches { false };
|
||||
@ -117,6 +142,53 @@ int32_t real_file_io_app_main(int, char*[]) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct SelfBoundObject {
|
||||
char written[16] = {};
|
||||
size_t written_len = 0;
|
||||
};
|
||||
|
||||
ssize_t self_bound_write(void* object, const void* buffer, size_t size) {
|
||||
auto* obj = static_cast<SelfBoundObject*>(object);
|
||||
size_t n = size < sizeof(obj->written) ? size : sizeof(obj->written);
|
||||
memcpy(obj->written, buffer, n);
|
||||
obj->written_len = n;
|
||||
return static_cast<ssize_t>(n);
|
||||
}
|
||||
|
||||
ssize_t self_bound_read(void*, void* buffer, size_t size) {
|
||||
const char reply[] = "yo";
|
||||
size_t n = size < sizeof(reply) - 1 ? size : sizeof(reply) - 1;
|
||||
memcpy(buffer, reply, n);
|
||||
return static_cast<ssize_t>(n);
|
||||
}
|
||||
|
||||
error_t self_bound_close(void*) { return ERROR_NONE; }
|
||||
error_t self_bound_await(void*, AppFileWait, TickType_t) { return ERROR_NONE; }
|
||||
uint32_t self_bound_poll(void*) { return APP_FILE_READABLE | APP_FILE_WRITABLE; }
|
||||
|
||||
const AppFileOps SELF_BOUND_OPS = {
|
||||
.read = self_bound_read,
|
||||
.write = self_bound_write,
|
||||
.close = self_bound_close,
|
||||
.await = self_bound_await,
|
||||
.poll = self_bound_poll,
|
||||
.retain = nullptr,
|
||||
.release = nullptr,
|
||||
};
|
||||
|
||||
SelfBoundObject g_self_bound_object;
|
||||
std::atomic<error_t> g_self_bind_result { ERROR_UNDEFINED };
|
||||
std::atomic<ssize_t> g_self_bound_write_result { -2 };
|
||||
std::atomic<ssize_t> g_self_bound_read_result { -2 };
|
||||
char g_self_bound_read_buffer[16] = {};
|
||||
|
||||
int32_t self_bind_app_main(int, char*[]) {
|
||||
g_self_bind_result.store(app_io_bind_self(STDOUT_FILENO, &SELF_BOUND_OPS, &g_self_bound_object), std::memory_order_release);
|
||||
g_self_bound_write_result.store(app_io_write(STDOUT_FILENO, "hi", 2), std::memory_order_release);
|
||||
g_self_bound_read_result.store(app_io_read(STDOUT_FILENO, g_self_bound_read_buffer, sizeof(g_self_bound_read_buffer) - 1), std::memory_order_release);
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::atomic<int> g_double_close_first_result { -2 };
|
||||
std::atomic<int> g_double_close_second_result { -2 };
|
||||
std::atomic<ssize_t> g_write_after_close_result { -2 };
|
||||
@ -186,39 +258,40 @@ TEST_CASE("app_start_with_streams pipes a child's app_io_write() calls into a pa
|
||||
app_manager_remove("test.io.writer");
|
||||
}
|
||||
|
||||
TEST_CASE("app_start_with_streams pipes a child's plain printf() calls into a parent-owned AppStream") {
|
||||
TEST_CASE("app_io_await blocks until the bound stream becomes readable or times out") {
|
||||
ensure_memory_loader_registered();
|
||||
g_await_before_write.store(ERROR_NONE, std::memory_order_relaxed);
|
||||
g_await_after_write.store(ERROR_TIMEOUT, std::memory_order_relaxed);
|
||||
g_await_first_done.store(false, std::memory_order_relaxed);
|
||||
g_await_done.store(false, std::memory_order_relaxed);
|
||||
|
||||
AppManifest manifest { "test.io.printf_writer", "PrintfWriter", APP_CATEGORY_USER, { APP_LOCATION_MEMORY, reinterpret_cast<void*>(stdout_printf_app_main) } };
|
||||
AppManifest manifest { "test.io.await", "Await", APP_CATEGORY_USER, { APP_LOCATION_MEMORY, reinterpret_cast<void*>(await_reader_app_main) } };
|
||||
REQUIRE_EQ(app_manager_add(&manifest), ERROR_NONE);
|
||||
|
||||
TaskEventGroup event_group {};
|
||||
task_event_group_construct(&event_group);
|
||||
|
||||
uint8_t storage[64];
|
||||
AppStream child_stdout {};
|
||||
|
||||
AppStreamBinding binding { STDOUT_FILENO, &child_stdout, storage, sizeof(storage), &event_group };
|
||||
uint8_t storage[16];
|
||||
AppStream child_stdin {};
|
||||
AppStreamBinding binding { STDIN_FILENO, &child_stdin, storage, sizeof(storage), &event_group };
|
||||
AppInstanceId child_id = 0;
|
||||
REQUIRE_EQ(app_start_with_streams("test.io.printf_writer", &binding, 1, &child_id), ERROR_NONE);
|
||||
REQUIRE_EQ(app_start_with_streams("test.io.await", &binding, 1, &child_id), ERROR_NONE);
|
||||
|
||||
std::vector<uint8_t> received;
|
||||
while (app_stream_await(&child_stdout, APP_FILE_WAIT_READABLE, pdMS_TO_TICKS(1000)) == ERROR_NONE) {
|
||||
uint8_t chunk[16];
|
||||
size_t n = app_stream_read(&child_stdout, chunk, sizeof(chunk));
|
||||
if (n == 0) {
|
||||
break; // EOF
|
||||
}
|
||||
received.insert(received.end(), chunk, chunk + n);
|
||||
}
|
||||
// Wait for the child's first await (50ms, on an empty stream) to actually return before
|
||||
// writing: a fixed delay doesn't prove that, and under slow scheduling the write could land
|
||||
// first, making the first await succeed and the second one time out instead.
|
||||
REQUIRE(wait_for_flag(g_await_first_done, 1000));
|
||||
CHECK_FALSE(g_await_done.load(std::memory_order_acquire));
|
||||
|
||||
REQUIRE_EQ(received.size(), 5u);
|
||||
CHECK_EQ(std::memcmp(received.data(), "hello", 5), 0);
|
||||
app_stream_write(&child_stdin, "x", 1);
|
||||
|
||||
REQUIRE(wait_for_state(child_id, APP_INSTANCE_STATE_STOPPED, 1000));
|
||||
app_stream_unsubscribe(&child_stdout);
|
||||
CHECK_EQ(g_await_before_write.load(std::memory_order_acquire), ERROR_TIMEOUT);
|
||||
CHECK_EQ(g_await_after_write.load(std::memory_order_acquire), ERROR_NONE);
|
||||
|
||||
app_stream_unsubscribe(&child_stdin);
|
||||
task_event_group_destruct(&event_group);
|
||||
app_manager_remove("test.io.printf_writer");
|
||||
app_manager_remove("test.io.await");
|
||||
}
|
||||
|
||||
TEST_CASE("a write blocked on a full stream wakes with an error once the consumer closes it") {
|
||||
@ -315,6 +388,36 @@ TEST_CASE("app_io_read/write/close pass through a real file fd app-module never
|
||||
app_manager_remove("test.io.real_file");
|
||||
}
|
||||
|
||||
TEST_CASE("app_io_bind_self installs a custom AppFileOps used by subsequent app_io_read/write") {
|
||||
ensure_memory_loader_registered();
|
||||
g_self_bind_result.store(ERROR_UNDEFINED, std::memory_order_relaxed);
|
||||
g_self_bound_write_result.store(-2, std::memory_order_relaxed);
|
||||
g_self_bound_read_result.store(-2, std::memory_order_relaxed);
|
||||
g_self_bound_object = SelfBoundObject {};
|
||||
memset(g_self_bound_read_buffer, 0, sizeof(g_self_bound_read_buffer));
|
||||
|
||||
AppManifest manifest { "test.io.self_bind", "SelfBind", APP_CATEGORY_USER, { APP_LOCATION_MEMORY, reinterpret_cast<void*>(self_bind_app_main) } };
|
||||
REQUIRE_EQ(app_manager_add(&manifest), ERROR_NONE);
|
||||
|
||||
AppInstanceId instance_id = 0;
|
||||
REQUIRE_EQ(app_start("test.io.self_bind", 0, nullptr, &instance_id), ERROR_NONE);
|
||||
REQUIRE(wait_for_state(instance_id, APP_INSTANCE_STATE_STOPPED, 1000));
|
||||
|
||||
CHECK_EQ(g_self_bind_result.load(std::memory_order_acquire), ERROR_NONE);
|
||||
CHECK_EQ(g_self_bound_write_result.load(std::memory_order_acquire), 2);
|
||||
CHECK_EQ(g_self_bound_object.written_len, 2u);
|
||||
CHECK_EQ(std::memcmp(g_self_bound_object.written, "hi", 2), 0);
|
||||
CHECK_EQ(g_self_bound_read_result.load(std::memory_order_acquire), 2);
|
||||
CHECK_EQ(std::memcmp(g_self_bound_read_buffer, "yo", 2), 0);
|
||||
|
||||
app_manager_remove("test.io.self_bind");
|
||||
}
|
||||
|
||||
TEST_CASE("app_io_bind_self returns ERROR_NOT_FOUND when called outside a running app instance") {
|
||||
SelfBoundObject object;
|
||||
CHECK_EQ(app_io_bind_self(STDOUT_FILENO, &SELF_BOUND_OPS, &object), ERROR_NOT_FOUND);
|
||||
}
|
||||
|
||||
TEST_CASE("closing an already-closed app fd reports EBADF instead of falling through to the platform") {
|
||||
ensure_memory_loader_registered();
|
||||
g_double_close_first_result.store(-2, std::memory_order_relaxed);
|
||||
|
||||
@ -11,6 +11,13 @@ add_library(app_posix_module_test_fixture SHARED EXCLUDE_FROM_ALL ${CMAKE_CURREN
|
||||
target_include_directories(app_posix_module_test_fixture PRIVATE ${CMAKE_SOURCE_DIR}/Modules/app-module/include)
|
||||
set_target_properties(app_posix_module_test_fixture PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
# Fixture: calls printf() with no app-module linkage of its own, so its call must resolve against
|
||||
# the host process's own printf - proves a dlopen()ed app's stdio actually reaches app_io_write()
|
||||
# rather than bypassing straight to libc (see stdio_wrap.cpp's own comment for why that's not a
|
||||
# given on POSIX).
|
||||
add_library(printf_fixture SHARED EXCLUDE_FROM_ALL ${CMAKE_CURRENT_LIST_DIR}/fixtures/printf_fixture.cpp)
|
||||
set_target_properties(printf_fixture PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
# A file with a ".so" extension but no ELF header, for is_executable() rejection tests.
|
||||
set(NON_ELF_FIXTURE_PATH "${CMAKE_CURRENT_BINARY_DIR}/not-elf.so")
|
||||
file(WRITE "${NON_ELF_FIXTURE_PATH}" "not an elf file")
|
||||
@ -29,11 +36,12 @@ add_custom_target(install_dir_fixture DEPENDS "${INSTALL_DIR_FIXTURE_BIN_DIR}/ap
|
||||
|
||||
file(GLOB_RECURSE TEST_SOURCES CONFIGURE_DEPENDS ${PROJECT_SOURCE_DIR}/source/*.cpp)
|
||||
add_executable(AppPosixModuleTests EXCLUDE_FROM_ALL ${TEST_SOURCES})
|
||||
add_dependencies(AppPosixModuleTests app_posix_module_test_fixture install_dir_fixture)
|
||||
add_dependencies(AppPosixModuleTests app_posix_module_test_fixture printf_fixture install_dir_fixture)
|
||||
|
||||
target_include_directories(AppPosixModuleTests PRIVATE ${DOCTESTINC})
|
||||
target_compile_definitions(AppPosixModuleTests PRIVATE
|
||||
FIXTURE_APP_PATH="$<TARGET_FILE:app_posix_module_test_fixture>"
|
||||
PRINTF_FIXTURE_APP_PATH="$<TARGET_FILE:printf_fixture>"
|
||||
FIXTURE_NON_ELF_PATH="${NON_ELF_FIXTURE_PATH}"
|
||||
FIXTURE_INSTALL_DIR_PATH="${INSTALL_DIR_FIXTURE_PATH}"
|
||||
)
|
||||
|
||||
12
Modules/app-posix-module/tests/fixtures/printf_fixture.cpp
vendored
Normal file
12
Modules/app-posix-module/tests/fixtures/printf_fixture.cpp
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
#include <cstdint>
|
||||
#include <cstdio>
|
||||
|
||||
// Deliberately not linked against app-module: printf()'s dynamic symbol resolution must reach
|
||||
// Tactility's own override in the loading process, exactly like a real loaded app's would.
|
||||
extern "C" int32_t main(int, char*[]) {
|
||||
printf("hello from dlopen'd app\n");
|
||||
// %s, not a literal: a literal fprintf compiles to fwrite(), which bypasses the wrap.
|
||||
fprintf(stderr, "%s\n", "oops from dlopen'd app");
|
||||
return 0;
|
||||
}
|
||||
@ -7,13 +7,16 @@
|
||||
#include <app/manager.h>
|
||||
#include <app/start.h>
|
||||
#include <app/scheduler.h>
|
||||
#include <app/stream.h>
|
||||
|
||||
#include <service/manager.h>
|
||||
|
||||
#include <tactility/delay.h>
|
||||
|
||||
#include <atomic>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include <unistd.h>
|
||||
|
||||
extern ServiceManifest loader_service_manifest; // app-posix-module's own
|
||||
extern ServiceManifest app_internal_loader_service_manifest; // app-module's real memory loader
|
||||
@ -103,8 +106,91 @@ int32_t parent_app_main(int, char*[]) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string g_printf_fixture_output;
|
||||
std::string g_printf_fixture_stderr;
|
||||
|
||||
// Starts the printf fixture with its stdout/stderr each piped through an AppStream, proving
|
||||
// printf()/fprintf(stderr, ...) reach app_io_write() rather than bypassing straight to libc.
|
||||
int32_t printf_parent_app_main(int, char*[]) {
|
||||
static uint8_t stdoutBuffer[256];
|
||||
static uint8_t stderrBuffer[256];
|
||||
AppStream stdoutStream {};
|
||||
AppStream stderrStream {};
|
||||
|
||||
TaskEventGroup event_group {};
|
||||
task_event_group_construct(&event_group);
|
||||
|
||||
AppEventSubscription sub {};
|
||||
app_event_subscribe(&sub, &event_group);
|
||||
|
||||
AppInstanceId self_id = app_scheduler_current_app_id();
|
||||
|
||||
AppStreamBinding bindings[] = {
|
||||
{ STDOUT_FILENO, &stdoutStream, stdoutBuffer, sizeof(stdoutBuffer), &event_group },
|
||||
{ STDERR_FILENO, &stderrStream, stderrBuffer, sizeof(stderrBuffer), &event_group },
|
||||
};
|
||||
|
||||
AppLocation location { APP_LOCATION_PATH, const_cast<char*>(PRINTF_FIXTURE_APP_PATH) };
|
||||
AppInstanceId childId = 0;
|
||||
app_execute_for_result_with_streams(location, AppStackConfig {}, 0, nullptr, bindings, 2, self_id, &childId);
|
||||
|
||||
uint8_t drain[256];
|
||||
bool childDone = false;
|
||||
while (!childDone) {
|
||||
if (task_event_group_wait_any(&event_group, nullptr, pdMS_TO_TICKS(5000)) != ERROR_NONE) {
|
||||
break; // safety net so a bug here can't hang the test suite
|
||||
}
|
||||
size_t n;
|
||||
while ((n = app_stream_read(&stdoutStream, drain, sizeof(drain))) > 0) {
|
||||
g_printf_fixture_output.append(reinterpret_cast<const char*>(drain), n);
|
||||
}
|
||||
while ((n = app_stream_read(&stderrStream, drain, sizeof(drain))) > 0) {
|
||||
g_printf_fixture_stderr.append(reinterpret_cast<const char*>(drain), n);
|
||||
}
|
||||
AppEvent event {};
|
||||
while (app_event_poll(&sub, &event) == ERROR_NONE) {
|
||||
if (event.type == APP_EVENT_RESULT && event.result.launch_id == childId) {
|
||||
childDone = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
size_t n;
|
||||
while ((n = app_stream_read(&stdoutStream, drain, sizeof(drain))) > 0) {
|
||||
g_printf_fixture_output.append(reinterpret_cast<const char*>(drain), n);
|
||||
}
|
||||
while ((n = app_stream_read(&stderrStream, drain, sizeof(drain))) > 0) {
|
||||
g_printf_fixture_stderr.append(reinterpret_cast<const char*>(drain), n);
|
||||
}
|
||||
|
||||
app_stream_unsubscribe(&stdoutStream);
|
||||
app_stream_unsubscribe(&stderrStream);
|
||||
app_event_unsubscribe(&sub);
|
||||
task_event_group_destruct(&event_group);
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
TEST_CASE("app-posix-module's loader-path service dlopen()s a .so whose printf()/fprintf(stderr, ...) output reaches the parent's streams") {
|
||||
ensure_path_loader_registered();
|
||||
ensure_memory_loader_registered();
|
||||
g_printf_fixture_output.clear();
|
||||
g_printf_fixture_stderr.clear();
|
||||
|
||||
AppManifest parent_manifest { "test.posix.printf_parent", "PrintfParent", APP_CATEGORY_USER, { APP_LOCATION_MEMORY, reinterpret_cast<void*>(printf_parent_app_main) } };
|
||||
REQUIRE_EQ(app_manager_add(&parent_manifest), ERROR_NONE);
|
||||
|
||||
AppInstanceId parent_id = 0;
|
||||
REQUIRE_EQ(app_start("test.posix.printf_parent", 0, nullptr, &parent_id), ERROR_NONE);
|
||||
REQUIRE(wait_for_state(parent_id, APP_INSTANCE_STATE_STOPPED, 3000));
|
||||
|
||||
CHECK_EQ(g_printf_fixture_output, "hello from dlopen'd app\n");
|
||||
// Not exact: the child's own scheduler bookkeeping may also log to stderr while running.
|
||||
CHECK(g_printf_fixture_stderr.find("oops from dlopen'd app\n") != std::string::npos);
|
||||
|
||||
app_manager_remove("test.posix.printf_parent");
|
||||
}
|
||||
|
||||
TEST_CASE("app-posix-module's loader-path service dlopen()s a .so and calls its main(), which resolves a real Tactility symbol against the host") {
|
||||
ensure_path_loader_registered();
|
||||
ensure_memory_loader_registered();
|
||||
|
||||
20
Modules/audio-decoder-module/CMakeLists.txt
Normal file
20
Modules/audio-decoder-module/CMakeLists.txt
Normal file
@ -0,0 +1,20 @@
|
||||
cmake_minimum_required(VERSION 3.20)
|
||||
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/../../Buildscripts/module.cmake")
|
||||
|
||||
file(GLOB_RECURSE SOURCE_FILES "source/*.c*")
|
||||
|
||||
# include/tactility/esp_audio_simple_dec.h and esp_audio_types.h are vendored verbatim from
|
||||
# espressif__esp_audio_codec so apps can include this module's header alone; symbols resolve
|
||||
# from the firmware's module table at load, like any other kernel/platform export.
|
||||
# ESP-only: there is no POSIX audio-decoder backend.
|
||||
set(REQUIRES_LIST TactilityKernel)
|
||||
if (DEFINED ENV{ESP_IDF_VERSION})
|
||||
list(APPEND REQUIRES_LIST espressif__esp_audio_codec)
|
||||
endif ()
|
||||
|
||||
tactility_add_module(audio-decoder-module
|
||||
SRCS ${SOURCE_FILES}
|
||||
INCLUDE_DIRS include/
|
||||
REQUIRES ${REQUIRES_LIST}
|
||||
)
|
||||
14
Modules/audio-decoder-module/include/audio_decoder/module.h
Normal file
14
Modules/audio-decoder-module/include/audio_decoder/module.h
Normal file
@ -0,0 +1,14 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
#pragma once
|
||||
|
||||
#include <tactility/module.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern struct Module audio_decoder_module;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@ -0,0 +1,232 @@
|
||||
/*
|
||||
* Espressif Modified MIT License
|
||||
*
|
||||
* Copyright (c) 2025 Espressif Systems (Shanghai) CO., LTD
|
||||
*
|
||||
* Permission is hereby granted for use EXCLUSIVELY with Espressif Systems products.
|
||||
* This includes the right to use, copy, modify, merge, publish, distribute, and sublicense
|
||||
* the Software, subject to the following conditions:
|
||||
*
|
||||
* 1. This Software MUST BE USED IN CONJUNCTION WITH ESPRESSIF SYSTEMS PRODUCTS.
|
||||
* 2. The above copyright notice and this permission notice shall be included in all copies
|
||||
* or substantial portions of the Software.
|
||||
* 3. Redistribution of the Software in source or binary form FOR USE WITH NON-ESPRESSIF PRODUCTS
|
||||
* is strictly prohibited.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
* PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||
* FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* SPDX-License-Identifier: LicenseRef-Espressif-Modified-MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "esp_audio_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Audio simple decoder handle
|
||||
*
|
||||
* @note Most audio decoder can only process frame data.
|
||||
* To support playback simply, simple decoder is imported.
|
||||
* In simple playback scenario, like play MP3, AAC, WAV etc.
|
||||
* User need only provide the original audio data, simple decoder will filter out frame data,
|
||||
* send frame data to decoder, then return decoded data to user directly.
|
||||
*/
|
||||
typedef void *esp_audio_simple_dec_handle_t;
|
||||
|
||||
/**
|
||||
* @brief Recovery strategy for tht current frame
|
||||
*/
|
||||
typedef enum {
|
||||
ESP_AUDIO_SIMPLE_DEC_RECOVERY_NONE = 0, /*!< The current frame is a normal decoded frame */
|
||||
ESP_AUDIO_SIMPLE_DEC_RECOVERY_PLC = 1, /*!< The current frame is recovered through the packet loss concealment (PLC) mechanism */
|
||||
} esp_audio_simple_dec_recovery_t;
|
||||
|
||||
/**
|
||||
* @brief Audio simple decoder type
|
||||
*/
|
||||
typedef enum {
|
||||
ESP_AUDIO_SIMPLE_DEC_TYPE_NONE = 0, /*!< Invalid simple decoder type */
|
||||
ESP_AUDIO_SIMPLE_DEC_TYPE_AAC = ESP_AUDIO_TYPE_AAC, /*!< Simple decoder for AAC, support input data of any size */
|
||||
ESP_AUDIO_SIMPLE_DEC_TYPE_MP3 = ESP_AUDIO_TYPE_MP3, /*!< Simple decoder for MP3, support input data of any size */
|
||||
ESP_AUDIO_SIMPLE_DEC_TYPE_AMRNB = ESP_AUDIO_TYPE_AMRNB, /*!< Simple decoder for AMR-NB, support input data of any size */
|
||||
ESP_AUDIO_SIMPLE_DEC_TYPE_AMRWB = ESP_AUDIO_TYPE_AMRWB, /*!< Simple decoder for AMR-WB, support input data of any size */
|
||||
ESP_AUDIO_SIMPLE_DEC_TYPE_FLAC = ESP_AUDIO_TYPE_FLAC, /*!< Simple decoder for FLAC, support input data of any size */
|
||||
ESP_AUDIO_SIMPLE_DEC_TYPE_WAV = ESP_AUDIO_FOURCC_TO_INT('W', 'A', 'V', ' '), /*!< Simple decoder for WAV, support input data of any size */
|
||||
ESP_AUDIO_SIMPLE_DEC_TYPE_M4A = ESP_AUDIO_FOURCC_TO_INT('M', '4', 'A', 'A'), /*!< Simple decoder for M4A, support input data of any size */
|
||||
ESP_AUDIO_SIMPLE_DEC_TYPE_TS = ESP_AUDIO_FOURCC_TO_INT('M', '2', 'T', 'S'), /*!< Simple decoder for TS, support input data of any size */
|
||||
ESP_AUDIO_SIMPLE_DEC_TYPE_RAW_OPUS = ESP_AUDIO_TYPE_OPUS, /*!< Simple decoder for OPUS (raw data with no extra header),
|
||||
only supports input data with a size of one encoded frame */
|
||||
ESP_AUDIO_SIMPLE_DEC_TYPE_G711A = ESP_AUDIO_TYPE_G711A, /*!< Simple decoder for G711A, support input data of any size */
|
||||
ESP_AUDIO_SIMPLE_DEC_TYPE_G711U = ESP_AUDIO_TYPE_G711U, /*!< Simple decoder for G711U, support input data of any size */
|
||||
ESP_AUDIO_SIMPLE_DEC_TYPE_PCM = ESP_AUDIO_TYPE_PCM, /*!< Simple decoder for PCM, support input data of any size */
|
||||
ESP_AUDIO_SIMPLE_DEC_TYPE_ADPCM = ESP_AUDIO_TYPE_ADPCM, /*!< Simple decoder for IMA-ADPCM,
|
||||
only supports input data with a size of one encoded frame */
|
||||
ESP_AUDIO_SIMPLE_DEC_TYPE_SBC = ESP_AUDIO_TYPE_SBC, /*!< Simple decoder for SBC,
|
||||
only supports input data with a size of one or multi encoded frame */
|
||||
ESP_AUDIO_SIMPLE_DEC_TYPE_LC3 = ESP_AUDIO_TYPE_LC3, /*!< Simple decoder for LC3,
|
||||
in vbr and no len_prefixed case, only supports input data with a size of one encoded frame,
|
||||
other cases, support input data with a size of one or multi encoded frame */
|
||||
ESP_AUDIO_SIMPLE_DEC_TYPE_ALAC = ESP_AUDIO_TYPE_ALAC, /*!< Simple decoder for ALAC,
|
||||
only supports input data with a size of one encoded frame */
|
||||
ESP_AUDIO_SIMPLE_DEC_TYPE_VORBIS = ESP_AUDIO_TYPE_VORBIS, /*!< Simple decoder for Vorbis (raw data with no extra header),
|
||||
only supports input data with a size of one encoded frame */
|
||||
ESP_AUDIO_SIMPLE_DEC_TYPE_CUSTOM = 0x1, /*!< Customized simple decoder type start */
|
||||
ESP_AUDIO_SIMPLE_DEC_TYPE_CUSTOM_MAX = 0x10, /*!< Customized simple decoder type end */
|
||||
} esp_audio_simple_dec_type_t;
|
||||
|
||||
/**
|
||||
* @brief Audio simple decoder configuration
|
||||
*/
|
||||
typedef struct {
|
||||
esp_audio_simple_dec_type_t dec_type; /*!< Simple decoder type */
|
||||
void *dec_cfg; /*!< Decoder specified configuration data (check decoder header file for details)
|
||||
Ex: When use internal aac decoder can refer `esp_aac_dec.h`
|
||||
If user want to enable AAC_PLUS can set it to pointer to
|
||||
`esp_aac_dec_cfg_t` */
|
||||
int cfg_size; /*!< Decoder specified configuration size */
|
||||
bool use_frame_dec; /*!< The flag of whether use frame decoder without parse
|
||||
If set to true, means that the input data is a complete frame and can be decoded directly
|
||||
If set to false, for decoders with parser, will parse to obtain the complete frame and then decode it */
|
||||
} esp_audio_simple_dec_cfg_t;
|
||||
|
||||
/**
|
||||
* @brief Input data information to be decoded
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t *buffer; /*!< Raw data to be decoded */
|
||||
uint32_t len; /*!< Raw data length */
|
||||
bool eos; /*!< Whether end of stream (some parser like FLAC need eos flag to flush cached data) */
|
||||
uint32_t consumed; /*!< Consumed size of input raw data */
|
||||
esp_audio_simple_dec_recovery_t frame_recover; /*!< Recovery strategy for current frame */
|
||||
} esp_audio_simple_dec_raw_t;
|
||||
|
||||
/**
|
||||
* @brief Audio simple decoder output frame
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t *buffer; /*!< Output buffer to hold decoded PCM data */
|
||||
uint32_t len; /*!< Output buffer size */
|
||||
uint32_t needed_size; /*!< Set when output buffer size not enough (output) */
|
||||
uint32_t decoded_size; /*!< Decoded PCM data size (output) */
|
||||
} esp_audio_simple_dec_out_t;
|
||||
|
||||
/**
|
||||
* @brief Audio simple decoder information
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t sample_rate; /*!< Audio sample rate */
|
||||
uint8_t bits_per_sample; /*!< Bits per sample */
|
||||
uint8_t channel; /*!< Audio channel*/
|
||||
uint32_t bitrate; /*!< Audio bitrate (bits per second) */
|
||||
uint32_t frame_size; /*!< Audio frame size */
|
||||
} esp_audio_simple_dec_info_t;
|
||||
|
||||
/**
|
||||
* @brief Query whether the simple decoder type is supported
|
||||
*
|
||||
* @param[in] dec_type Simple decoder type
|
||||
*
|
||||
* @return
|
||||
* - ESP_AUDIO_ERR_OK On success
|
||||
* - ESP_AUDIO_ERR_NOT_SUPPORT Not support the audio type
|
||||
*/
|
||||
esp_audio_err_t esp_audio_simple_check_audio_type(esp_audio_simple_dec_type_t dec_type);
|
||||
|
||||
/**
|
||||
* @brief Open audio simple decoder
|
||||
*
|
||||
* @param[in] cfg Decoder configuration
|
||||
* @param[out] dec_handle Pointer to output simple decoder handle
|
||||
*
|
||||
* @return
|
||||
* - ESP_AUDIO_ERR_OK Open decoder success
|
||||
* - ESP_AUDIO_ERR_INVALID_PARAMETER Invalid input argument
|
||||
* - ESP_AUDIO_ERR_MEM_LACK No memory for decoder instance
|
||||
* - ESP_AUDIO_ERR_NOT_SUPPORT Not supported parse type
|
||||
*/
|
||||
esp_audio_err_t esp_audio_simple_dec_open(esp_audio_simple_dec_cfg_t *cfg, esp_audio_simple_dec_handle_t *dec_handle);
|
||||
|
||||
/**
|
||||
* @brief Decode input raw data to PCM data
|
||||
*
|
||||
* @param[in] dec_handle Simple decoder handle
|
||||
* @param[in,out] raw Raw data to be decoded
|
||||
* @param[in,out] frame Decoded PCM frame
|
||||
*
|
||||
* @return
|
||||
* - ESP_AUDIO_ERR_OK Decode success or data feed into cached buffer
|
||||
* - ESP_AUDIO_ERR_INVALID_PARAMETER Invalid input argument
|
||||
* - ESP_AUDIO_ERR_BUFF_NOT_ENOUGH Output frame buffer not enough need reallocated and try again
|
||||
* - ESP_AUDIO_ERR_NOT_SUPPORT Decoder not supported
|
||||
*/
|
||||
esp_audio_err_t esp_audio_simple_dec_process(esp_audio_simple_dec_handle_t dec_handle, esp_audio_simple_dec_raw_t *raw,
|
||||
esp_audio_simple_dec_out_t *frame);
|
||||
|
||||
/**
|
||||
* @brief Get audio simple decoder information
|
||||
*
|
||||
* @note Audio decoder information contain 2 parts:
|
||||
* 1. Basic information which can be used for play (`sample_rate`, `channel`, `bits`)
|
||||
* This information is ready when decoder decode output PCM data
|
||||
* When `esp_audio_simple_dec_process` return `decoded_size` have value
|
||||
* User no need frequently call this API to get it for it almost unchanged
|
||||
* 2. Frame related information such as (`frame_size`) which may differ for each frame
|
||||
* User can use it to estimate duration and play position.
|
||||
*
|
||||
* @param[in] dec_handle Simple decoder handle
|
||||
* @param[out] info Decoder information
|
||||
*
|
||||
* @return
|
||||
* - ESP_AUDIO_ERR_OK Open decoder success
|
||||
* - ESP_AUDIO_ERR_INVALID_PARAMETER Invalid input argument
|
||||
* - ESP_AUDIO_ERR_NOT_FOUND Decode information not ready yet
|
||||
*/
|
||||
esp_audio_err_t esp_audio_simple_dec_get_info(esp_audio_simple_dec_handle_t dec_handle, esp_audio_simple_dec_info_t *info);
|
||||
|
||||
/**
|
||||
* @brief Reset audio simple decoder
|
||||
* Reset action will reset both of the internal parser and decoder to initial state
|
||||
* It allows the handle to be reused efficiently, avoiding the overhead of closing and recreating the handle
|
||||
* Typical use cases include:
|
||||
* - Replay the same audio stream
|
||||
* - Seek when use frame decoder
|
||||
*
|
||||
* @note 1. This function is not thread-safe. The user must ensure proper call sequencing
|
||||
* and avoid invoking this function while the process is running
|
||||
* 2. Work as a frame decoder: After calling the `esp_audio_simple_dec_reset`, playback can
|
||||
* start from any frame of the audio stream. The audio file can be the same or different but keeping
|
||||
* 3. Work as a non-frame decoder: After calling the `esp_audio_simple_dec_reset`,
|
||||
* playback must starts from the beginning of the audio stream.
|
||||
* The audio file can be the same or different from the previous one but keeping format unchanged
|
||||
*
|
||||
* @param[in] dec_handle Simple decoder handle
|
||||
*
|
||||
* @return
|
||||
* - ESP_AUDIO_ERR_OK On success
|
||||
* - ESP_AUDIO_ERR_FAIL Fail to reset
|
||||
* - ESP_AUDIO_ERR_INVALID_PARAMETER Invalid parameter
|
||||
*/
|
||||
esp_audio_err_t esp_audio_simple_dec_reset(esp_audio_simple_dec_handle_t dec_handle);
|
||||
|
||||
/**
|
||||
* @brief Close audio simple decoder
|
||||
*
|
||||
* @param[in] dec_handle Decoder handle
|
||||
*
|
||||
*/
|
||||
void esp_audio_simple_dec_close(esp_audio_simple_dec_handle_t dec_handle);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
113
Modules/audio-decoder-module/include/tactility/esp_audio_types.h
Normal file
113
Modules/audio-decoder-module/include/tactility/esp_audio_types.h
Normal file
@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Espressif Modified MIT License
|
||||
*
|
||||
* Copyright (c) 2025 Espressif Systems (Shanghai) CO., LTD
|
||||
*
|
||||
* Permission is hereby granted for use EXCLUSIVELY with Espressif Systems products.
|
||||
* This includes the right to use, copy, modify, merge, publish, distribute, and sublicense
|
||||
* the Software, subject to the following conditions:
|
||||
*
|
||||
* 1. This Software MUST BE USED IN CONJUNCTION WITH ESPRESSIF SYSTEMS PRODUCTS.
|
||||
* 2. The above copyright notice and this permission notice shall be included in all copies
|
||||
* or substantial portions of the Software.
|
||||
* 3. Redistribution of the Software in source or binary form FOR USE WITH NON-ESPRESSIF PRODUCTS
|
||||
* is strictly prohibited.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
* PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||
* FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* SPDX-License-Identifier: LicenseRef-Espressif-Modified-MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define ESP_AUDIO_SAMPLE_RATE_8K (8000)
|
||||
#define ESP_AUDIO_SAMPLE_RATE_11K (11025)
|
||||
#define ESP_AUDIO_SAMPLE_RATE_12K (12000)
|
||||
#define ESP_AUDIO_SAMPLE_RATE_16K (16000)
|
||||
#define ESP_AUDIO_SAMPLE_RATE_22K (22050)
|
||||
#define ESP_AUDIO_SAMPLE_RATE_24K (24000)
|
||||
#define ESP_AUDIO_SAMPLE_RATE_32K (32000)
|
||||
#define ESP_AUDIO_SAMPLE_RATE_44K (44100)
|
||||
#define ESP_AUDIO_SAMPLE_RATE_48K (48000)
|
||||
#define ESP_AUDIO_SAMPLE_RATE_64K (64000)
|
||||
#define ESP_AUDIO_SAMPLE_RATE_88K (88200)
|
||||
#define ESP_AUDIO_SAMPLE_RATE_96K (96000)
|
||||
|
||||
#define ESP_AUDIO_BIT8 (8)
|
||||
#define ESP_AUDIO_BIT16 (16)
|
||||
#define ESP_AUDIO_BIT24 (24)
|
||||
#define ESP_AUDIO_BIT32 (32)
|
||||
|
||||
#define ESP_AUDIO_MONO (1)
|
||||
#define ESP_AUDIO_DUAL (2)
|
||||
|
||||
#define ESP_AUDIO_FOURCC_TO_INT(a, b, c, d) ((uint32_t)(a) | ((uint32_t)(b << 8)) | ((uint32_t)(c) << 16) | ((uint32_t)(d) << 24))
|
||||
|
||||
/**
|
||||
* @brief Audio codec type
|
||||
*
|
||||
* @note 1. The type enum value is reference to `esp_fourcc.h`(http://github.com/espressif/esp-gmf/blob/main/gmf_core/helpers/include/esp_fourcc.h)
|
||||
* 2. The range of customized type is [0x20, 0x40]
|
||||
*/
|
||||
typedef enum {
|
||||
ESP_AUDIO_TYPE_UNSUPPORT = 0,
|
||||
ESP_AUDIO_TYPE_AMRNB = ESP_AUDIO_FOURCC_TO_INT('A', 'M', 'R', 'N'),
|
||||
ESP_AUDIO_TYPE_AMRWB = ESP_AUDIO_FOURCC_TO_INT('A', 'M', 'R', 'W'),
|
||||
ESP_AUDIO_TYPE_AAC = ESP_AUDIO_FOURCC_TO_INT('A', 'A', 'C', ' '),
|
||||
ESP_AUDIO_TYPE_G711A = ESP_AUDIO_FOURCC_TO_INT('A', 'L', 'A', 'W'),
|
||||
ESP_AUDIO_TYPE_G711U = ESP_AUDIO_FOURCC_TO_INT('U', 'L', 'A', 'W'),
|
||||
ESP_AUDIO_TYPE_OPUS = ESP_AUDIO_FOURCC_TO_INT('O', 'P', 'U', 'S'),
|
||||
ESP_AUDIO_TYPE_ADPCM = ESP_AUDIO_FOURCC_TO_INT('A', 'D', 'P', 'C'),
|
||||
ESP_AUDIO_TYPE_PCM = ESP_AUDIO_FOURCC_TO_INT('P', 'C', 'M', ' '),
|
||||
ESP_AUDIO_TYPE_FLAC = ESP_AUDIO_FOURCC_TO_INT('F', 'L', 'A', 'C'),
|
||||
ESP_AUDIO_TYPE_VORBIS = ESP_AUDIO_FOURCC_TO_INT('V', 'O', 'B', 'S'),
|
||||
ESP_AUDIO_TYPE_MP3 = ESP_AUDIO_FOURCC_TO_INT('M', 'P', '3', ' '),
|
||||
ESP_AUDIO_TYPE_ALAC = ESP_AUDIO_FOURCC_TO_INT('A', 'L', 'A', 'C'),
|
||||
ESP_AUDIO_TYPE_SBC = ESP_AUDIO_FOURCC_TO_INT('S', 'B', 'C', ' '),
|
||||
ESP_AUDIO_TYPE_LC3 = ESP_AUDIO_FOURCC_TO_INT('L', 'C', '3', '0'),
|
||||
ESP_AUDIO_TYPE_CUSTOMIZED = 0x20,
|
||||
ESP_AUDIO_TYPE_CUSTOMIZED_MAX = 0x40,
|
||||
} esp_audio_type_t;
|
||||
|
||||
/**
|
||||
* @brief Audio codec error type definition
|
||||
*/
|
||||
typedef enum {
|
||||
ESP_AUDIO_ERR_CONTINUE = 1, /*!< Continue */
|
||||
ESP_AUDIO_ERR_OK = 0, /*!< Success */
|
||||
ESP_AUDIO_ERR_FAIL = -1, /*!< Fail */
|
||||
ESP_AUDIO_ERR_MEM_LACK = -2, /*!< Fail to malloc memory */
|
||||
ESP_AUDIO_ERR_DATA_LACK = -3, /*!< Data is not enough */
|
||||
ESP_AUDIO_ERR_HEADER_PARSE = -4, /*!< Parse header happened error */
|
||||
ESP_AUDIO_ERR_INVALID_PARAMETER = -5, /*!< Input invalid parameter */
|
||||
ESP_AUDIO_ERR_ALREADY_EXIST = -6, /*!< Audio library is already exist */
|
||||
ESP_AUDIO_ERR_NOT_SUPPORT = -7, /*!< Not support type */
|
||||
ESP_AUDIO_ERR_BUFF_NOT_ENOUGH = -8, /*!< Buffer not enough */
|
||||
ESP_AUDIO_ERR_NOT_FOUND = -9, /*!< Not found */
|
||||
} esp_audio_err_t;
|
||||
|
||||
/**
|
||||
* @brief Get audio codec type stringify name
|
||||
*
|
||||
* @param[in] type Audio codec type
|
||||
*
|
||||
* @return
|
||||
* - "NONE" Invalid codec type
|
||||
* - Others Codec stringify name
|
||||
*/
|
||||
const char *esp_audio_codec_get_name(esp_audio_type_t type);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
61
Modules/audio-decoder-module/source/module.cpp
Normal file
61
Modules/audio-decoder-module/source/module.cpp
Normal file
@ -0,0 +1,61 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
#include <audio_decoder/module.h>
|
||||
|
||||
#ifdef ESP_PLATFORM
|
||||
|
||||
#include <simple_dec/esp_audio_simple_dec.h>
|
||||
#include <esp_audio_dec_default.h>
|
||||
|
||||
#include <esp_log.h>
|
||||
|
||||
// Registers Kconfig-selected decoders once so any app can use esp_audio_simple_dec_open()
|
||||
// without registering itself.
|
||||
static error_t audio_decoder_module_start(void) {
|
||||
esp_audio_err_t dec_register_result = esp_audio_dec_register_default();
|
||||
if (dec_register_result != ESP_AUDIO_ERR_OK) {
|
||||
// Not a boot failure: apps can still use everything else. But without this, a later
|
||||
// esp_audio_simple_dec_open() failure has no explanation in the log.
|
||||
ESP_LOGE("audio-decoder", "esp_audio_dec_register_default failed: %d", (int) dec_register_result);
|
||||
}
|
||||
return ERROR_NONE;
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
|
||||
static const ModuleSymbol SYMBOLS[] = {
|
||||
DEFINE_MODULE_SYMBOL(esp_audio_simple_check_audio_type),
|
||||
DEFINE_MODULE_SYMBOL(esp_audio_simple_dec_open),
|
||||
DEFINE_MODULE_SYMBOL(esp_audio_simple_dec_process),
|
||||
DEFINE_MODULE_SYMBOL(esp_audio_simple_dec_get_info),
|
||||
DEFINE_MODULE_SYMBOL(esp_audio_simple_dec_reset),
|
||||
DEFINE_MODULE_SYMBOL(esp_audio_simple_dec_close),
|
||||
MODULE_SYMBOL_TERMINATOR
|
||||
};
|
||||
|
||||
Module audio_decoder_module = {
|
||||
.name = "audio-decoder",
|
||||
.start = audio_decoder_module_start,
|
||||
.stop = nullptr,
|
||||
.drivers = nullptr,
|
||||
.symbols = SYMBOLS,
|
||||
.internal = nullptr,
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#else // !ESP_PLATFORM
|
||||
|
||||
extern "C" {
|
||||
|
||||
Module audio_decoder_module = {
|
||||
.name = "audio-decoder",
|
||||
.start = nullptr,
|
||||
.stop = nullptr,
|
||||
.drivers = nullptr,
|
||||
.symbols = nullptr,
|
||||
.internal = nullptr,
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // ESP_PLATFORM
|
||||
@ -100,6 +100,7 @@ static const ModuleSymbol SYMBOLS[] = {
|
||||
DEFINE_MODULE_SYMBOL_SIGNATURE(round, double (*)(double)),
|
||||
// cassert / cstdio
|
||||
DEFINE_MODULE_SYMBOL(abort),
|
||||
DEFINE_MODULE_SYMBOL(clearerr),
|
||||
DEFINE_MODULE_SYMBOL(fclose),
|
||||
DEFINE_MODULE_SYMBOL(feof),
|
||||
DEFINE_MODULE_SYMBOL(ferror),
|
||||
|
||||
25
Modules/cjson-module/CMakeLists.txt
Normal file
25
Modules/cjson-module/CMakeLists.txt
Normal file
@ -0,0 +1,25 @@
|
||||
cmake_minimum_required(VERSION 3.20)
|
||||
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/../../Buildscripts/module.cmake")
|
||||
|
||||
file(GLOB_RECURSE SOURCE_FILES "source/*.c*")
|
||||
|
||||
# include/cJSON.h is vendored verbatim from espressif__cjson so apps can `#include <cJSON.h>`
|
||||
# against this module alone (no idf_component.yml entry of their own needed) - the app ELF keeps
|
||||
# cJSON_* calls undefined and the firmware resolves them from this module's symbol table at load,
|
||||
# same mechanism as any other kernel/platform export.
|
||||
#
|
||||
# cJSON symbol exports (source/module.cpp) are used on every platform, but the managed-component
|
||||
# target name only resolves in an ESP-IDF build; POSIX links the repo's own cJSON library instead.
|
||||
set(REQUIRES_LIST TactilityKernel)
|
||||
if (ESP_PLATFORM)
|
||||
list(APPEND REQUIRES_LIST espressif__cjson)
|
||||
else ()
|
||||
list(APPEND REQUIRES_LIST cJSON)
|
||||
endif ()
|
||||
|
||||
tactility_add_module(cjson-module
|
||||
SRCS ${SOURCE_FILES}
|
||||
INCLUDE_DIRS include/
|
||||
REQUIRES ${REQUIRES_LIST}
|
||||
)
|
||||
195
Modules/cjson-module/LICENSE-Apache-2.0.md
Normal file
195
Modules/cjson-module/LICENSE-Apache-2.0.md
Normal file
@ -0,0 +1,195 @@
|
||||
Apache License
|
||||
==============
|
||||
|
||||
_Version 2.0, January 2004_
|
||||
_<<http://www.apache.org/licenses/>>_
|
||||
|
||||
### Terms and Conditions for use, reproduction, and distribution
|
||||
|
||||
#### 1. Definitions
|
||||
|
||||
“License” shall mean the terms and conditions for use, reproduction, and
|
||||
distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
“Licensor” shall mean the copyright owner or entity authorized by the copyright
|
||||
owner that is granting the License.
|
||||
|
||||
“Legal Entity” shall mean the union of the acting entity and all other entities
|
||||
that control, are controlled by, or are under common control with that entity.
|
||||
For the purposes of this definition, “control” means **(i)** the power, direct or
|
||||
indirect, to cause the direction or management of such entity, whether by
|
||||
contract or otherwise, or **(ii)** ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or **(iii)** beneficial ownership of such entity.
|
||||
|
||||
“You” (or “Your”) shall mean an individual or Legal Entity exercising
|
||||
permissions granted by this License.
|
||||
|
||||
“Source” form shall mean the preferred form for making modifications, including
|
||||
but not limited to software source code, documentation source, and configuration
|
||||
files.
|
||||
|
||||
“Object” form shall mean any form resulting from mechanical transformation or
|
||||
translation of a Source form, including but not limited to compiled object code,
|
||||
generated documentation, and conversions to other media types.
|
||||
|
||||
“Work” shall mean the work of authorship, whether in Source or Object form, made
|
||||
available under the License, as indicated by a copyright notice that is included
|
||||
in or attached to the work (an example is provided in the Appendix below).
|
||||
|
||||
“Derivative Works” shall mean any work, whether in Source or Object form, that
|
||||
is based on (or derived from) the Work and for which the editorial revisions,
|
||||
annotations, elaborations, or other modifications represent, as a whole, an
|
||||
original work of authorship. For the purposes of this License, Derivative Works
|
||||
shall not include works that remain separable from, or merely link (or bind by
|
||||
name) to the interfaces of, the Work and Derivative Works thereof.
|
||||
|
||||
“Contribution” shall mean any work of authorship, including the original version
|
||||
of the Work and any modifications or additions to that Work or Derivative Works
|
||||
thereof, that is intentionally submitted to Licensor for inclusion in the Work
|
||||
by the copyright owner or by an individual or Legal Entity authorized to submit
|
||||
on behalf of the copyright owner. For the purposes of this definition,
|
||||
“submitted” means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems, and
|
||||
issue tracking systems that are managed by, or on behalf of, the Licensor for
|
||||
the purpose of discussing and improving the Work, but excluding communication
|
||||
that is conspicuously marked or otherwise designated in writing by the copyright
|
||||
owner as “Not a Contribution.”
|
||||
|
||||
“Contributor” shall mean Licensor and any individual or Legal Entity on behalf
|
||||
of whom a Contribution has been received by Licensor and subsequently
|
||||
incorporated within the Work.
|
||||
|
||||
#### 2. Grant of Copyright License
|
||||
|
||||
Subject to the terms and conditions of this License, each Contributor hereby
|
||||
grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
|
||||
irrevocable copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the Work and such
|
||||
Derivative Works in Source or Object form.
|
||||
|
||||
#### 3. Grant of Patent License
|
||||
|
||||
Subject to the terms and conditions of this License, each Contributor hereby
|
||||
grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
|
||||
irrevocable (except as stated in this section) patent license to make, have
|
||||
made, use, offer to sell, sell, import, and otherwise transfer the Work, where
|
||||
such license applies only to those patent claims licensable by such Contributor
|
||||
that are necessarily infringed by their Contribution(s) alone or by combination
|
||||
of their Contribution(s) with the Work to which such Contribution(s) was
|
||||
submitted. If You institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work or a
|
||||
Contribution incorporated within the Work constitutes direct or contributory
|
||||
patent infringement, then any patent licenses granted to You under this License
|
||||
for that Work shall terminate as of the date such litigation is filed.
|
||||
|
||||
#### 4. Redistribution
|
||||
|
||||
You may reproduce and distribute copies of the Work or Derivative Works thereof
|
||||
in any medium, with or without modifications, and in Source or Object form,
|
||||
provided that You meet the following conditions:
|
||||
|
||||
* **(a)** You must give any other recipients of the Work or Derivative Works a copy of
|
||||
this License; and
|
||||
* **(b)** You must cause any modified files to carry prominent notices stating that You
|
||||
changed the files; and
|
||||
* **(c)** You must retain, in the Source form of any Derivative Works that You distribute,
|
||||
all copyright, patent, trademark, and attribution notices from the Source form
|
||||
of the Work, excluding those notices that do not pertain to any part of the
|
||||
Derivative Works; and
|
||||
* **(d)** If the Work includes a “NOTICE” text file as part of its distribution, then any
|
||||
Derivative Works that You distribute must include a readable copy of the
|
||||
attribution notices contained within such NOTICE file, excluding those notices
|
||||
that do not pertain to any part of the Derivative Works, in at least one of the
|
||||
following places: within a NOTICE text file distributed as part of the
|
||||
Derivative Works; within the Source form or documentation, if provided along
|
||||
with the Derivative Works; or, within a display generated by the Derivative
|
||||
Works, if and wherever such third-party notices normally appear. The contents of
|
||||
the NOTICE file are for informational purposes only and do not modify the
|
||||
License. You may add Your own attribution notices within Derivative Works that
|
||||
You distribute, alongside or as an addendum to the NOTICE text from the Work,
|
||||
provided that such additional attribution notices cannot be construed as
|
||||
modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and may provide
|
||||
additional or different license terms and conditions for use, reproduction, or
|
||||
distribution of Your modifications, or for any such Derivative Works as a whole,
|
||||
provided Your use, reproduction, and distribution of the Work otherwise complies
|
||||
with the conditions stated in this License.
|
||||
|
||||
#### 5. Submission of Contributions
|
||||
|
||||
Unless You explicitly state otherwise, any Contribution intentionally submitted
|
||||
for inclusion in the Work by You to the Licensor shall be under the terms and
|
||||
conditions of this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify the terms of
|
||||
any separate license agreement you may have executed with Licensor regarding
|
||||
such Contributions.
|
||||
|
||||
#### 6. Trademarks
|
||||
|
||||
This License does not grant permission to use the trade names, trademarks,
|
||||
service marks, or product names of the Licensor, except as required for
|
||||
reasonable and customary use in describing the origin of the Work and
|
||||
reproducing the content of the NOTICE file.
|
||||
|
||||
#### 7. Disclaimer of Warranty
|
||||
|
||||
Unless required by applicable law or agreed to in writing, Licensor provides the
|
||||
Work (and each Contributor provides its Contributions) on an “AS IS” BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
|
||||
including, without limitation, any warranties or conditions of TITLE,
|
||||
NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are
|
||||
solely responsible for determining the appropriateness of using or
|
||||
redistributing the Work and assume any risks associated with Your exercise of
|
||||
permissions under this License.
|
||||
|
||||
#### 8. Limitation of Liability
|
||||
|
||||
In no event and under no legal theory, whether in tort (including negligence),
|
||||
contract, or otherwise, unless required by applicable law (such as deliberate
|
||||
and grossly negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special, incidental,
|
||||
or consequential damages of any character arising as a result of this License or
|
||||
out of the use or inability to use the Work (including but not limited to
|
||||
damages for loss of goodwill, work stoppage, computer failure or malfunction, or
|
||||
any and all other commercial damages or losses), even if such Contributor has
|
||||
been advised of the possibility of such damages.
|
||||
|
||||
#### 9. Accepting Warranty or Additional Liability
|
||||
|
||||
While redistributing the Work or Derivative Works thereof, You may choose to
|
||||
offer, and charge a fee for, acceptance of support, warranty, indemnity, or
|
||||
other liability obligations and/or rights consistent with this License. However,
|
||||
in accepting such obligations, You may act only on Your own behalf and on Your
|
||||
sole responsibility, not on behalf of any other Contributor, and only if You
|
||||
agree to indemnify, defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason of your
|
||||
accepting any such warranty or additional liability.
|
||||
|
||||
_END OF TERMS AND CONDITIONS_
|
||||
|
||||
### APPENDIX: How to apply the Apache License to your work
|
||||
|
||||
To apply the Apache License to your work, attach the following boilerplate
|
||||
notice, with the fields enclosed by brackets `[]` replaced with your own
|
||||
identifying information. (Don't include the brackets!) The text should be
|
||||
enclosed in the appropriate comment syntax for the file format. We also
|
||||
recommend that a file or class name and description of purpose be included on
|
||||
the same “printed page” as the copyright notice for easier identification within
|
||||
third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
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.
|
||||
|
||||
306
Modules/cjson-module/include/cJSON.h
Normal file
306
Modules/cjson-module/include/cJSON.h
Normal file
@ -0,0 +1,306 @@
|
||||
/*
|
||||
Copyright (c) 2009-2017 Dave Gamble and cJSON contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef cJSON__h
|
||||
#define cJSON__h
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#if !defined(__WINDOWS__) && (defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32))
|
||||
#define __WINDOWS__
|
||||
#endif
|
||||
|
||||
#ifdef __WINDOWS__
|
||||
|
||||
/* When compiling for windows, we specify a specific calling convention to avoid issues where we are being called from a project with a different default calling convention. For windows you have 3 define options:
|
||||
|
||||
CJSON_HIDE_SYMBOLS - Define this in the case where you don't want to ever dllexport symbols
|
||||
CJSON_EXPORT_SYMBOLS - Define this on library build when you want to dllexport symbols (default)
|
||||
CJSON_IMPORT_SYMBOLS - Define this if you want to dllimport symbol
|
||||
|
||||
For *nix builds that support visibility attribute, you can define similar behavior by
|
||||
|
||||
setting default visibility to hidden by adding
|
||||
-fvisibility=hidden (for gcc)
|
||||
or
|
||||
-xldscope=hidden (for sun cc)
|
||||
to CFLAGS
|
||||
|
||||
then using the CJSON_API_VISIBILITY flag to "export" the same symbols the way CJSON_EXPORT_SYMBOLS does
|
||||
|
||||
*/
|
||||
|
||||
#define CJSON_CDECL __cdecl
|
||||
#define CJSON_STDCALL __stdcall
|
||||
|
||||
/* export symbols by default, this is necessary for copy pasting the C and header file */
|
||||
#if !defined(CJSON_HIDE_SYMBOLS) && !defined(CJSON_IMPORT_SYMBOLS) && !defined(CJSON_EXPORT_SYMBOLS)
|
||||
#define CJSON_EXPORT_SYMBOLS
|
||||
#endif
|
||||
|
||||
#if defined(CJSON_HIDE_SYMBOLS)
|
||||
#define CJSON_PUBLIC(type) type CJSON_STDCALL
|
||||
#elif defined(CJSON_EXPORT_SYMBOLS)
|
||||
#define CJSON_PUBLIC(type) __declspec(dllexport) type CJSON_STDCALL
|
||||
#elif defined(CJSON_IMPORT_SYMBOLS)
|
||||
#define CJSON_PUBLIC(type) __declspec(dllimport) type CJSON_STDCALL
|
||||
#endif
|
||||
#else /* !__WINDOWS__ */
|
||||
#define CJSON_CDECL
|
||||
#define CJSON_STDCALL
|
||||
|
||||
#if (defined(__GNUC__) || defined(__SUNPRO_CC) || defined (__SUNPRO_C)) && defined(CJSON_API_VISIBILITY)
|
||||
#define CJSON_PUBLIC(type) __attribute__((visibility("default"))) type
|
||||
#else
|
||||
#define CJSON_PUBLIC(type) type
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* project version */
|
||||
#define CJSON_VERSION_MAJOR 1
|
||||
#define CJSON_VERSION_MINOR 7
|
||||
#define CJSON_VERSION_PATCH 19
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
/* cJSON Types: */
|
||||
#define cJSON_Invalid (0)
|
||||
#define cJSON_False (1 << 0)
|
||||
#define cJSON_True (1 << 1)
|
||||
#define cJSON_NULL (1 << 2)
|
||||
#define cJSON_Number (1 << 3)
|
||||
#define cJSON_String (1 << 4)
|
||||
#define cJSON_Array (1 << 5)
|
||||
#define cJSON_Object (1 << 6)
|
||||
#define cJSON_Raw (1 << 7) /* raw json */
|
||||
|
||||
#define cJSON_IsReference 256
|
||||
#define cJSON_StringIsConst 512
|
||||
|
||||
/* The cJSON structure: */
|
||||
typedef struct cJSON
|
||||
{
|
||||
/* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
|
||||
struct cJSON *next;
|
||||
struct cJSON *prev;
|
||||
/* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
|
||||
struct cJSON *child;
|
||||
|
||||
/* The type of the item, as above. */
|
||||
int type;
|
||||
|
||||
/* The item's string, if type==cJSON_String and type == cJSON_Raw */
|
||||
char *valuestring;
|
||||
/* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */
|
||||
int valueint;
|
||||
/* The item's number, if type==cJSON_Number */
|
||||
double valuedouble;
|
||||
|
||||
/* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
|
||||
char *string;
|
||||
} cJSON;
|
||||
|
||||
typedef struct cJSON_Hooks
|
||||
{
|
||||
/* malloc/free are CDECL on Windows regardless of the default calling convention of the compiler, so ensure the hooks allow passing those functions directly. */
|
||||
void *(CJSON_CDECL *malloc_fn)(size_t sz);
|
||||
void (CJSON_CDECL *free_fn)(void *ptr);
|
||||
} cJSON_Hooks;
|
||||
|
||||
typedef int cJSON_bool;
|
||||
|
||||
/* Limits how deeply nested arrays/objects can be before cJSON rejects to parse them.
|
||||
* This is to prevent stack overflows. */
|
||||
#ifndef CJSON_NESTING_LIMIT
|
||||
#define CJSON_NESTING_LIMIT 1000
|
||||
#endif
|
||||
|
||||
/* Limits the length of circular references can be before cJSON rejects to parse them.
|
||||
* This is to prevent stack overflows. */
|
||||
#ifndef CJSON_CIRCULAR_LIMIT
|
||||
#define CJSON_CIRCULAR_LIMIT 10000
|
||||
#endif
|
||||
|
||||
/* returns the version of cJSON as a string */
|
||||
CJSON_PUBLIC(const char*) cJSON_Version(void);
|
||||
|
||||
/* Supply malloc, realloc and free functions to cJSON */
|
||||
CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks);
|
||||
|
||||
/* Memory Management: the caller is always responsible to free the results from all variants of cJSON_Parse (with cJSON_Delete) and cJSON_Print (with stdlib free, cJSON_Hooks.free_fn, or cJSON_free as appropriate). The exception is cJSON_PrintPreallocated, where the caller has full responsibility of the buffer. */
|
||||
/* Supply a block of JSON, and this returns a cJSON object you can interrogate. */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_ParseWithLength(const char *value, size_t buffer_length);
|
||||
/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */
|
||||
/* If you supply a ptr in return_parse_end and parsing fails, then return_parse_end will contain a pointer to the error so will match cJSON_GetErrorPtr(). */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_ParseWithLengthOpts(const char *value, size_t buffer_length, const char **return_parse_end, cJSON_bool require_null_terminated);
|
||||
|
||||
/* Render a cJSON entity to text for transfer/storage. */
|
||||
CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item);
|
||||
/* Render a cJSON entity to text for transfer/storage without any formatting. */
|
||||
CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item);
|
||||
/* Render a cJSON entity to text using a buffered strategy. prebuffer is a guess at the final size. guessing well reduces reallocation. fmt=0 gives unformatted, =1 gives formatted */
|
||||
CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt);
|
||||
/* Render a cJSON entity to text using a buffer already allocated in memory with given length. Returns 1 on success and 0 on failure. */
|
||||
/* NOTE: cJSON is not always 100% accurate in estimating how much memory it will use, so to be safe allocate 5 bytes more than you actually need */
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format);
|
||||
/* Delete a cJSON entity and all subentities. */
|
||||
CJSON_PUBLIC(void) cJSON_Delete(cJSON *item);
|
||||
|
||||
/* Returns the number of items in an array (or object). */
|
||||
CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array);
|
||||
/* Retrieve item number "index" from array "array". Returns NULL if unsuccessful. */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index);
|
||||
/* Get item "string" from object. Case insensitive. */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON *object, const char *string);
|
||||
/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
|
||||
CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void);
|
||||
|
||||
/* Check item type and return its value */
|
||||
CJSON_PUBLIC(char *) cJSON_GetStringValue(const cJSON * const item);
|
||||
CJSON_PUBLIC(double) cJSON_GetNumberValue(const cJSON * const item);
|
||||
|
||||
/* These functions check the type of an item */
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item);
|
||||
|
||||
/* These calls create a cJSON item of the appropriate type. */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool boolean);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string);
|
||||
/* raw json */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void);
|
||||
|
||||
/* Create a string where valuestring references a string so
|
||||
* it will not be freed by cJSON_Delete */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateStringReference(const char *string);
|
||||
/* Create an object/array that only references it's elements so
|
||||
* they will not be freed by cJSON_Delete */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child);
|
||||
|
||||
/* These utilities create an Array of count items.
|
||||
* The parameter count cannot be greater than the number of elements in the number array, otherwise array access will be out of bounds.*/
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char *const *strings, int count);
|
||||
|
||||
/* Append item to the specified array/object. */
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToArray(cJSON *array, cJSON *item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item);
|
||||
/* Use this when string is definitely const (i.e. a literal, or as good as), and will definitely survive the cJSON object.
|
||||
* WARNING: When this function was used, make sure to always check that (item->type & cJSON_StringIsConst) is zero before
|
||||
* writing to `item->string` */
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item);
|
||||
/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item);
|
||||
|
||||
/* Remove/Detach items from Arrays/Objects. */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which);
|
||||
CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string);
|
||||
CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string);
|
||||
CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string);
|
||||
|
||||
/* Update array items. */
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem); /* Shifts pre-existing items to the right. */
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object,const char *string,cJSON *newitem);
|
||||
|
||||
/* Duplicate a cJSON item */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse);
|
||||
/* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will
|
||||
* need to be released. With recurse!=0, it will duplicate any children connected to the item.
|
||||
* The item->next and ->prev pointers are always zero on return from Duplicate. */
|
||||
/* Recursively compare two cJSON items for equality. If either a or b is NULL or invalid, they will be considered unequal.
|
||||
* case_sensitive determines if object keys are treated case sensitive (1) or case insensitive (0) */
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive);
|
||||
|
||||
/* Minify a strings, remove blank characters(such as ' ', '\t', '\r', '\n') from strings.
|
||||
* The input pointer json cannot point to a read-only address area, such as a string constant,
|
||||
* but should point to a readable and writable address area. */
|
||||
CJSON_PUBLIC(void) cJSON_Minify(char *json);
|
||||
|
||||
/* Helper functions for creating and adding items to an object at the same time.
|
||||
* They return the added item or NULL on failure. */
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_bool boolean);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddRawToObject(cJSON * const object, const char * const name, const char * const raw);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON * const object, const char * const name);
|
||||
CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name);
|
||||
|
||||
/* When assigning an integer value, it needs to be propagated to valuedouble too. */
|
||||
#define cJSON_SetIntValue(object, number) ((object) ? (object)->valueint = (object)->valuedouble = (number) : (number))
|
||||
/* helper for the cJSON_SetNumberValue macro */
|
||||
CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number);
|
||||
#define cJSON_SetNumberValue(object, number) ((object != NULL) ? cJSON_SetNumberHelper(object, (double)number) : (number))
|
||||
/* Change the valuestring of a cJSON_String object, only takes effect when type of object is cJSON_String */
|
||||
CJSON_PUBLIC(char*) cJSON_SetValuestring(cJSON *object, const char *valuestring);
|
||||
|
||||
/* If the object is not a boolean type this does nothing and returns cJSON_Invalid else it returns the new type*/
|
||||
#define cJSON_SetBoolValue(object, boolValue) ( \
|
||||
(object != NULL && ((object)->type & (cJSON_False|cJSON_True))) ? \
|
||||
(object)->type=((object)->type &(~(cJSON_False|cJSON_True)))|((boolValue)?cJSON_True:cJSON_False) : \
|
||||
cJSON_Invalid\
|
||||
)
|
||||
|
||||
/* Macro for iterating over an array or object */
|
||||
#define cJSON_ArrayForEach(element, array) for(element = (array != NULL) ? (array)->child : NULL; element != NULL; element = element->next)
|
||||
|
||||
/* malloc/free objects using the malloc/free functions that have been set with cJSON_InitHooks */
|
||||
CJSON_PUBLIC(void *) cJSON_malloc(size_t size);
|
||||
CJSON_PUBLIC(void) cJSON_free(void *object);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
14
Modules/cjson-module/include/cjson_symbols/module.h
Normal file
14
Modules/cjson-module/include/cjson_symbols/module.h
Normal file
@ -0,0 +1,14 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
#pragma once
|
||||
|
||||
#include <tactility/module.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern struct Module cjson_module;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
104
Modules/cjson-module/source/module.cpp
Normal file
104
Modules/cjson-module/source/module.cpp
Normal file
@ -0,0 +1,104 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
#include <cjson_symbols/module.h>
|
||||
|
||||
#include <cJSON.h>
|
||||
|
||||
extern "C" {
|
||||
|
||||
static const ModuleSymbol SYMBOLS[] = {
|
||||
// cJSON.h - every real exported function (not the header's inline SetIntValue/
|
||||
// SetNumberValue/SetBoolValue/ArrayForEach macros, which expand at the app's own compile
|
||||
// time and need no export).
|
||||
DEFINE_MODULE_SYMBOL(cJSON_Version),
|
||||
// cJSON_InitHooks intentionally not exported: it overrides cJSON's process-global
|
||||
// malloc/free hooks, which every app and the firmware itself share - one app could break
|
||||
// allocation for everyone.
|
||||
DEFINE_MODULE_SYMBOL(cJSON_Parse),
|
||||
DEFINE_MODULE_SYMBOL(cJSON_ParseWithLength),
|
||||
DEFINE_MODULE_SYMBOL(cJSON_ParseWithOpts),
|
||||
DEFINE_MODULE_SYMBOL(cJSON_ParseWithLengthOpts),
|
||||
DEFINE_MODULE_SYMBOL(cJSON_Print),
|
||||
DEFINE_MODULE_SYMBOL(cJSON_PrintUnformatted),
|
||||
DEFINE_MODULE_SYMBOL(cJSON_PrintBuffered),
|
||||
DEFINE_MODULE_SYMBOL(cJSON_PrintPreallocated),
|
||||
DEFINE_MODULE_SYMBOL(cJSON_Delete),
|
||||
DEFINE_MODULE_SYMBOL(cJSON_GetArraySize),
|
||||
DEFINE_MODULE_SYMBOL(cJSON_GetArrayItem),
|
||||
DEFINE_MODULE_SYMBOL(cJSON_GetObjectItem),
|
||||
DEFINE_MODULE_SYMBOL(cJSON_GetObjectItemCaseSensitive),
|
||||
DEFINE_MODULE_SYMBOL(cJSON_HasObjectItem),
|
||||
DEFINE_MODULE_SYMBOL(cJSON_GetErrorPtr),
|
||||
DEFINE_MODULE_SYMBOL(cJSON_GetStringValue),
|
||||
DEFINE_MODULE_SYMBOL(cJSON_GetNumberValue),
|
||||
DEFINE_MODULE_SYMBOL(cJSON_IsInvalid),
|
||||
DEFINE_MODULE_SYMBOL(cJSON_IsFalse),
|
||||
DEFINE_MODULE_SYMBOL(cJSON_IsTrue),
|
||||
DEFINE_MODULE_SYMBOL(cJSON_IsBool),
|
||||
DEFINE_MODULE_SYMBOL(cJSON_IsNull),
|
||||
DEFINE_MODULE_SYMBOL(cJSON_IsNumber),
|
||||
DEFINE_MODULE_SYMBOL(cJSON_IsString),
|
||||
DEFINE_MODULE_SYMBOL(cJSON_IsArray),
|
||||
DEFINE_MODULE_SYMBOL(cJSON_IsObject),
|
||||
DEFINE_MODULE_SYMBOL(cJSON_IsRaw),
|
||||
DEFINE_MODULE_SYMBOL(cJSON_CreateNull),
|
||||
DEFINE_MODULE_SYMBOL(cJSON_CreateTrue),
|
||||
DEFINE_MODULE_SYMBOL(cJSON_CreateFalse),
|
||||
DEFINE_MODULE_SYMBOL(cJSON_CreateBool),
|
||||
DEFINE_MODULE_SYMBOL(cJSON_CreateNumber),
|
||||
DEFINE_MODULE_SYMBOL(cJSON_CreateString),
|
||||
DEFINE_MODULE_SYMBOL(cJSON_CreateRaw),
|
||||
DEFINE_MODULE_SYMBOL(cJSON_CreateArray),
|
||||
DEFINE_MODULE_SYMBOL(cJSON_CreateObject),
|
||||
DEFINE_MODULE_SYMBOL(cJSON_CreateStringReference),
|
||||
DEFINE_MODULE_SYMBOL(cJSON_CreateObjectReference),
|
||||
DEFINE_MODULE_SYMBOL(cJSON_CreateArrayReference),
|
||||
DEFINE_MODULE_SYMBOL(cJSON_CreateIntArray),
|
||||
DEFINE_MODULE_SYMBOL(cJSON_CreateFloatArray),
|
||||
DEFINE_MODULE_SYMBOL(cJSON_CreateDoubleArray),
|
||||
DEFINE_MODULE_SYMBOL(cJSON_CreateStringArray),
|
||||
DEFINE_MODULE_SYMBOL(cJSON_AddItemToArray),
|
||||
DEFINE_MODULE_SYMBOL(cJSON_AddItemToObject),
|
||||
DEFINE_MODULE_SYMBOL(cJSON_AddItemToObjectCS),
|
||||
DEFINE_MODULE_SYMBOL(cJSON_AddItemReferenceToArray),
|
||||
DEFINE_MODULE_SYMBOL(cJSON_AddItemReferenceToObject),
|
||||
DEFINE_MODULE_SYMBOL(cJSON_DetachItemViaPointer),
|
||||
DEFINE_MODULE_SYMBOL(cJSON_DetachItemFromArray),
|
||||
DEFINE_MODULE_SYMBOL(cJSON_DeleteItemFromArray),
|
||||
DEFINE_MODULE_SYMBOL(cJSON_DetachItemFromObject),
|
||||
DEFINE_MODULE_SYMBOL(cJSON_DetachItemFromObjectCaseSensitive),
|
||||
DEFINE_MODULE_SYMBOL(cJSON_DeleteItemFromObject),
|
||||
DEFINE_MODULE_SYMBOL(cJSON_DeleteItemFromObjectCaseSensitive),
|
||||
DEFINE_MODULE_SYMBOL(cJSON_InsertItemInArray),
|
||||
DEFINE_MODULE_SYMBOL(cJSON_ReplaceItemViaPointer),
|
||||
DEFINE_MODULE_SYMBOL(cJSON_ReplaceItemInArray),
|
||||
DEFINE_MODULE_SYMBOL(cJSON_ReplaceItemInObject),
|
||||
DEFINE_MODULE_SYMBOL(cJSON_ReplaceItemInObjectCaseSensitive),
|
||||
DEFINE_MODULE_SYMBOL(cJSON_Duplicate),
|
||||
DEFINE_MODULE_SYMBOL(cJSON_Compare),
|
||||
DEFINE_MODULE_SYMBOL(cJSON_Minify),
|
||||
DEFINE_MODULE_SYMBOL(cJSON_AddNullToObject),
|
||||
DEFINE_MODULE_SYMBOL(cJSON_AddTrueToObject),
|
||||
DEFINE_MODULE_SYMBOL(cJSON_AddFalseToObject),
|
||||
DEFINE_MODULE_SYMBOL(cJSON_AddBoolToObject),
|
||||
DEFINE_MODULE_SYMBOL(cJSON_AddNumberToObject),
|
||||
DEFINE_MODULE_SYMBOL(cJSON_AddStringToObject),
|
||||
DEFINE_MODULE_SYMBOL(cJSON_AddRawToObject),
|
||||
DEFINE_MODULE_SYMBOL(cJSON_AddObjectToObject),
|
||||
DEFINE_MODULE_SYMBOL(cJSON_AddArrayToObject),
|
||||
DEFINE_MODULE_SYMBOL(cJSON_SetNumberHelper),
|
||||
DEFINE_MODULE_SYMBOL(cJSON_SetValuestring),
|
||||
DEFINE_MODULE_SYMBOL(cJSON_malloc),
|
||||
DEFINE_MODULE_SYMBOL(cJSON_free),
|
||||
MODULE_SYMBOL_TERMINATOR
|
||||
};
|
||||
|
||||
Module cjson_module = {
|
||||
.name = "cjson",
|
||||
.start = nullptr,
|
||||
.stop = nullptr,
|
||||
.drivers = nullptr,
|
||||
.symbols = SYMBOLS,
|
||||
.internal = nullptr,
|
||||
};
|
||||
|
||||
}
|
||||
@ -7,9 +7,11 @@ instantiation, not a plain function call. Apps still `#include <new>`/`<map>`/`<
|
||||
directly; this module only makes sure the actual out-of-line definitions resolve when their ELF
|
||||
is loaded into the firmware.
|
||||
|
||||
ESP32-only: several of these symbols are mangled for a 32-bit ABI (`j` = `unsigned int`, used
|
||||
here to represent `size_t`). On a 64-bit host those would mangle differently (e.g. `_Znwm`
|
||||
instead of `_Znwj`), so this module doesn't build for the POSIX simulator.
|
||||
Most of this module is ESP32-only: several of these symbols are mangled for a 32-bit ABI (`j` =
|
||||
`unsigned int`, used here to represent `size_t`) that only applies there - a 64-bit host mangles
|
||||
them differently (e.g. `_Znwm` instead of `_Znwj`). Those sections are gated behind `#ifdef
|
||||
ESP_PLATFORM` in `source/module.cpp`; symbols outside that gate (e.g. `__cxa_pure_virtual`,
|
||||
`__cxa_guard_*`) build and export on the POSIX simulator too.
|
||||
|
||||
## Supported symbols
|
||||
|
||||
@ -74,15 +76,73 @@ symbol - the same trick used for `_M_replace_cold` and friends, except *we* supp
|
||||
instead of pointing at one the library already provides). An app whose loaded ELF needs it will
|
||||
still fail with `Can't find common ...C1.../...C2.../...C5...`.
|
||||
|
||||
### `std::deque<char>` / `<double>` / `<basic_string<char>>`, `std::stack`
|
||||
|
||||
Non-template `_Deque_base`/`_Deque_iterator` internals plus each element type's own out-of-line
|
||||
member set (push_back/pop_back/emplace_back, map reallocation, iterator arithmetic). Needed by any
|
||||
app using `std::stack` (whose default underlying container is `std::deque`). None of this has an
|
||||
`extern template` instantiation in libstdc++.a, so every member here is forced into existence by
|
||||
a wrapper that calls the real public deque/stack API on a real object (see `source/module.cpp`).
|
||||
|
||||
### `std::_Rb_tree<std::string, ...>`, `std::map<std::string, std::string>`
|
||||
|
||||
The `std::map<string, string>` instantiation's own non-template-shared internals (on top of the
|
||||
generic `_Rb_tree_increment`/`_Rb_tree_insert_and_rebalance` helpers above), plus
|
||||
`operator[]`/piecewise-construct support for in-place node construction.
|
||||
|
||||
### `std::vector<const char*>`, `std::vector<std::pair<std::string, bool>>`
|
||||
|
||||
Same `_M_check_len`/`_Guard_alloc`/`emplace_back`/`_M_realloc_append` pattern as `vector<string>`
|
||||
and `vector<unsigned char>` above, for two more element types apps instantiate over.
|
||||
|
||||
### `std::shared_ptr<T>` control block
|
||||
|
||||
`__shared_count::operator=`, `_Sp_counted_base`'s virtual dispatch, and its vtable, for both lock
|
||||
policies (atomic and mutex-based - which one an app's build selects isn't controlled by this
|
||||
firmware, so both are exported). Forced via `std::shared_ptr<int>` rather than any real app type,
|
||||
since none of these three carry a pointee type in their mangled name.
|
||||
|
||||
**Not exported: the raw-pointer constructor** (`__shared_count<Lp>::__shared_count<T*>(T*)`),
|
||||
because its mangled name does embed the pointee type `T` - no single firmware-side entry can serve
|
||||
every app's `shared_ptr<AppDefinedType>`. This isn't a gap in practice: the app's own compiler
|
||||
already emits a local, weak-linkage definition of that exact constructor in the app's own ELF
|
||||
(standard behavior for an implicitly-instantiated template), and the ELF loader falls back to an
|
||||
app-local definition whenever firmware doesn't provide one, so it resolves without any firmware
|
||||
export at all. Confirmed by loading an app holding a `shared_ptr` to one of its own types with
|
||||
nothing shared_ptr-specific exported here beyond the generic pieces above.
|
||||
|
||||
### `std::function<int(char*, unsigned int)>`
|
||||
|
||||
`operator()`, `swap`, copy constructor, and `operator=(nullptr)` for this one call signature.
|
||||
|
||||
### Misc algorithm/iterator template instantiations
|
||||
|
||||
`__copy_move_a2`, `__copy_move_backward_a2`, `__relocate_a_1`, `__advance`, `iter_swap`,
|
||||
`transform`, `std::min`/`std::max<short>` - pulled in by `std::stack`/`vector<pair<...>>` usage
|
||||
above rather than needed standalone.
|
||||
|
||||
## Adding a new symbol
|
||||
|
||||
1. Find the mangled name (`nm`/`c++filt`, or the linker's "undefined reference" error from an
|
||||
app build).
|
||||
1. Find the mangled name. `TactilityApps/Tools/check-app-symbols.py <path/to/App.app.elf>` reports
|
||||
every symbol an app's ELF actually needs firmware to resolve - it already excludes symbols the
|
||||
app's own ELF defines locally (e.g. an implicitly-instantiated template like a `shared_ptr<T>`
|
||||
constructor over an app-defined `T`), so if it doesn't list something, it doesn't need adding
|
||||
here even if the mangled name shows up in the ELF's relocations.
|
||||
2. Add an `extern "C"` declaration for it in `source/module.cpp` if the name isn't already a
|
||||
valid identifier you can reference directly (mangled names usually are, e.g. `_ZSt19...`).
|
||||
valid identifier you can reference directly (mangled names usually are, e.g. `_ZSt19...`). If a
|
||||
plain `extern` declaration compiles but fails to *link*, the symbol likely has no `extern
|
||||
template` instantiation anywhere in libstdc++.a (true for `deque`, `vector<pair<...>>`,
|
||||
`shared_ptr`'s control block, `std::function`, and most algorithm templates) - write a small
|
||||
wrapper that calls the real public API on a real object instead (see any of the existing
|
||||
`construct_*`/`destroy_*` functions in this file for the pattern), and register the wrapper's
|
||||
address rather than the mangled name directly.
|
||||
3. Add a `DEFINE_MODULE_SYMBOL(...)` entry (or a manual `{ "mangled_name", (void*)&expr }` pair
|
||||
when the address isn't reachable through the mangled identifier itself, e.g. `std::nothrow`
|
||||
or the `__throw_*` functions).
|
||||
4. Rebuild the firmware and confirm with `nm`/`check-app-symbols.py` that the symbol resolves to
|
||||
a real, non-null defined address - a reference that merely compiles and links without error can
|
||||
still silently resolve to the wrong (e.g. an unrelated weak-undefined stub) or a null definition
|
||||
if something else in the link graph shifts which archive member satisfies it first.
|
||||
|
||||
## License
|
||||
|
||||
|
||||
@ -3,9 +3,17 @@
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <deque>
|
||||
#include <exception>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <new>
|
||||
#include <stack>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#if defined(__GLIBCXX__) || defined(ESP_PLATFORM)
|
||||
#define TT_CPP_SYMBOLS_AVAILABLE 1
|
||||
@ -29,11 +37,12 @@ extern "C" {
|
||||
extern void _ZdlPv(void* p); // operator delete(void*)
|
||||
extern void _ZdaPv(void* p); // operator delete[](void*)
|
||||
#endif
|
||||
extern void __cxa_pure_virtual();
|
||||
// cxx_guards.cpp
|
||||
extern int __cxa_guard_acquire(void* pg);
|
||||
extern void __cxa_guard_release(void* pg) throw();
|
||||
extern void __cxa_guard_abort(void* pg) throw();
|
||||
// bits/atomic_wait.h (pulled in via <memory>) declares these as long long*; must match
|
||||
// exactly or GCC treats them as conflicting redeclarations.
|
||||
extern int __cxa_guard_acquire(long long* pg);
|
||||
extern void __cxa_guard_release(long long* pg) throw();
|
||||
extern void __cxa_guard_abort(long long* pg) throw();
|
||||
#ifdef ESP_PLATFORM
|
||||
// Not part of the Itanium C++ ABI that desktop libstdc++ implements; ESP-IDF's toolchain only.
|
||||
extern void __cxa_guard_dummy(void);
|
||||
@ -72,9 +81,164 @@ extern "C" {
|
||||
// return-value pointer (Itanium ABI), same convention as substr() above.
|
||||
void* _ZSt12__str_concatINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEET_PKNS6_10value_typeENS6_9size_typeES9_SA_RKNS6_14allocator_typeE(void*, const char*, unsigned int, const char*, unsigned int, const void*);
|
||||
void* _ZStplIcSt11char_traitsIcESaIcEENSt7__cxx1112basic_stringIT_T0_T1_EERKS8_PKS5_(void*, const void*, const char*);
|
||||
unsigned int _ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE4findEPKcj(const void*, const char*, unsigned int);
|
||||
unsigned int _ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE4findEPKcjj(const void*, const char*, unsigned int, unsigned int);
|
||||
unsigned int _ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE5rfindEPKcjj(const void*, const char*, unsigned int, unsigned int);
|
||||
unsigned int _ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE5rfindEcj(const void*, char, unsigned int);
|
||||
int _ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7compareERKS4_(const void*, const void*);
|
||||
void _ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE4swapERS4_(void*, void*);
|
||||
void* _ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6insertEjPKc(void*, unsigned int, const char*);
|
||||
void* _ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7replaceEjjPKcj(void*, unsigned int, unsigned int, const char*, unsigned int);
|
||||
unsigned int _ZNSt8__detail14__to_chars_lenIjEEjT_i(unsigned int, int);
|
||||
void _ZNSt8__detail18__to_chars_10_implIjEEvPcjT_(char*, unsigned int, unsigned int);
|
||||
// `unsigned long` overloads of the same two helpers - to_string(long)'s internal path,
|
||||
// distinct mangled names from the `unsigned int` ones above (to_string(unsigned)'s path).
|
||||
unsigned int _ZNSt8__detail14__to_chars_lenImEEjT_i(unsigned long, int);
|
||||
void _ZNSt8__detail18__to_chars_10_implImEEvPcjT_(char*, unsigned int, unsigned long);
|
||||
bool _ZSteqIcSt11char_traitsIcESaIcEEbRKNSt7__cxx1112basic_stringIT_T0_T1_EEPKS5_(const void*, const char*); // operator==(string const&, const char*)
|
||||
bool _ZSteqIcSt11char_traitsIcESaIcEEbRKNSt7__cxx1112basic_stringIT_T0_T1_EESA_(const void*, const void*); // operator==(string const&, string const&)
|
||||
// operator+ overloads: hidden return-value pointer (return basic_string by value).
|
||||
void* _ZStplIcSt11char_traitsIcESaIcEENSt7__cxx1112basic_stringIT_T0_T1_EEOS8_S9_(void*, void*, void*);
|
||||
void* _ZStplIcSt11char_traitsIcESaIcEENSt7__cxx1112basic_stringIT_T0_T1_EEPKS5_RKS8_(void*, const char*, const void*);
|
||||
void* _ZStplIcSt11char_traitsIcESaIcEENSt7__cxx1112basic_stringIT_T0_T1_EERKS8_SA_(void*, const void*, const void*);
|
||||
// vector<unsigned char> and vector<std::string> internals - Note: mangled names required.
|
||||
void _ZNKSt6vectorIhSaIhEE12_M_check_lenEjPKc(const void*, unsigned int, const char*);
|
||||
void _ZNKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS5_EE12_M_check_lenEjPKc(const void*, unsigned int, const char*);
|
||||
bool _ZNKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS5_EE5emptyEv(const void*);
|
||||
void* _ZNSt12_Vector_baseIhSaIhEE11_M_allocateEj(void*, unsigned int);
|
||||
void* _ZNSt12_Vector_baseIhSaIhEE17_M_create_storageEj(void*, unsigned int);
|
||||
void _ZNSt6vectorIhSaIhEE17_M_default_appendEj(void*, unsigned int);
|
||||
void _ZNSt6vectorIhSaIhEE6resizeEj(void*, unsigned int);
|
||||
unsigned char* _ZNSt27__uninitialized_default_n_1ILb1EE18__uninit_default_nIPhjEET_S3_T0_(unsigned char*, unsigned int);
|
||||
void* _ZSt9__fill_a1IhhEN9__gnu_cxx11__enable_ifIXaasrSt9__is_byteIT_E7__valueoosrSt10__are_sameIS3_T0_E7__valuesrSt20__memcpyable_integerIS6_E7__widthEvE6__typeEPS3_SC_RKS6_(unsigned char*, unsigned char*, const unsigned char*);
|
||||
// std::mutex
|
||||
void _ZNSt5mutex4lockEv(void*);
|
||||
// Remaining basic_string/vector template instantiations, raw-extern like _M_construct's
|
||||
// forward-iterator overload above - these are genuinely out-of-line template
|
||||
// instantiations (not compiler-inlined ctors/dtors), so no forcing wrapper is needed.
|
||||
void _ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructILb1EEEvPKcj(void*, const char*, unsigned int);
|
||||
// resize_and_overwrite's instantiation is scoped to to_string(unsigned)'s own private lambda
|
||||
// type - unnameable directly, but calling std::to_string(unsigned) below (construct_
|
||||
// to_string_result) instantiates it in this TU under this exact mangled name, addressable
|
||||
// by name even though its C++ type can't be spelled outside to_string's own body.
|
||||
void _ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE20resize_and_overwriteIRZNS_9to_stringEjEUlPcjE_EEvjT_(void*, unsigned int, void*);
|
||||
void* _ZSt14__relocate_a_1IPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES6_SaIS5_EET0_T_S9_S8_RT1_(void*, void*, void*, void*);
|
||||
int _ZStssIcSt11char_traitsIcESaIcEEDTcl21__char_traits_cmp_catIT0_ELi0EEERKNSt7__cxx1112basic_stringIT_S3_T1_EESB_(const void*, const void*); // operator<=>(string const&, string const&)
|
||||
|
||||
long _ZNKSt8functionIFlvEEclEv(const void*); // std::function<long()>::operator()() const
|
||||
void _ZNSt14_Function_baseD2Ev(void*); // std::_Function_base::~_Function_base()
|
||||
void _ZNSt8functionIFlvEEC1ERKS1_(void*, const void*); // std::function<long()>::function(function const&)
|
||||
|
||||
unsigned int _ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE13find_first_ofEPKcj(const void*, const char*, unsigned int);
|
||||
unsigned int _ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE13find_first_ofEPKcjj(const void*, const char*, unsigned int, unsigned int);
|
||||
unsigned int _ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE4copyEPcjj(const void*, char*, unsigned int, unsigned int);
|
||||
int _ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7compareEjjPKc(const void*, unsigned int, unsigned int, const char*);
|
||||
void _ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE8_M_checkEjPKc(const void*, unsigned int, const char*);
|
||||
void* _ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructEjc(void*, unsigned int, char);
|
||||
void* _ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE14_M_replace_auxEjjjc(void*, unsigned int, unsigned int, unsigned int, char);
|
||||
void* _ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE5eraseEjj(void*, unsigned int, unsigned int);
|
||||
void* _ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6appendEjc(void*, unsigned int, char);
|
||||
void* _ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6assignEPKcj(void*, const char*, unsigned int);
|
||||
void* _ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6resizeEjc(void*, unsigned int, char);
|
||||
void _ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE9_S_assignEPcjc(char*, unsigned int, char);
|
||||
void _ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1EPKcjRKS3_(void*, const char*, unsigned int, const void*);
|
||||
// resize_and_overwrite/to_string's `long` overloads - distinct mangled names from the
|
||||
// `unsigned int` ones already handled above (construct_to_string_result et al.).
|
||||
void _ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE20resize_and_overwriteIRZNS_9to_stringElEUlPcjE_EEvjT_(void*, unsigned int, void*);
|
||||
|
||||
// std::_Rb_tree<std::string, std::pair<const std::string, std::string>, ...> - std::map<string,
|
||||
// string>'s internals.
|
||||
void* _ZNKSt8_Rb_treeINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt4pairIKS5_S5_ESt10_Select1stIS8_ESt4lessIS5_ESaIS8_EE14_M_lower_boundEPSt18_Rb_tree_node_baseSG_RS7_(const void*, void*, void*, const void*);
|
||||
void* _ZNSt8_Rb_treeINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt4pairIKS5_S5_ESt10_Select1stIS8_ESt4lessIS5_ESaIS8_EE10_Auto_node9_M_insertES6_IPSt18_Rb_tree_node_baseSH_E(void*, void*, void*);
|
||||
void _ZNSt8_Rb_treeINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt4pairIKS5_S5_ESt10_Select1stIS8_ESt4lessIS5_ESaIS8_EE10_Auto_nodeD1Ev(void*);
|
||||
void* _ZNSt8_Rb_treeINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt4pairIKS5_S5_ESt10_Select1stIS8_ESt4lessIS5_ESaIS8_EE11lower_boundERS7_(void*, const void*);
|
||||
void _ZNSt8_Rb_treeINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt4pairIKS5_S5_ESt10_Select1stIS8_ESt4lessIS5_ESaIS8_EE12_M_drop_nodeEPSt13_Rb_tree_nodeIS8_E(void*, void*);
|
||||
void* _ZNSt8_Rb_treeINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt4pairIKS5_S5_ESt10_Select1stIS8_ESt4lessIS5_ESaIS8_EE14_M_create_nodeIJRKSt21piecewise_construct_tSt5tupleIJOS5_EESJ_IJEEEEEPSt13_Rb_tree_nodeIS8_EDpOT_(void*, const void*, void*, void*);
|
||||
void* _ZNSt8_Rb_treeINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt4pairIKS5_S5_ESt10_Select1stIS8_ESt4lessIS5_ESaIS8_EE14_M_create_nodeIJRKSt21piecewise_construct_tSt5tupleIJRS7_EESJ_IJEEEEEPSt13_Rb_tree_nodeIS8_EDpOT_(void*, const void*, void*, void*);
|
||||
void* _ZNSt8_Rb_treeINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt4pairIKS5_S5_ESt10_Select1stIS8_ESt4lessIS5_ESaIS8_EE14_M_insert_nodeEPSt18_Rb_tree_node_baseSG_PSt13_Rb_tree_nodeIS8_E(void*, void*, void*, void*);
|
||||
void* _ZNSt8_Rb_treeINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt4pairIKS5_S5_ESt10_Select1stIS8_ESt4lessIS5_ESaIS8_EE22_M_emplace_hint_uniqueIJRKSt21piecewise_construct_tSt5tupleIJOS5_EESJ_IJEEEEESt17_Rb_tree_iteratorIS8_ESt23_Rb_tree_const_iteratorIS8_EDpOT_(void*, void*, const void*, void*, void*);
|
||||
void* _ZNSt8_Rb_treeINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt4pairIKS5_S5_ESt10_Select1stIS8_ESt4lessIS5_ESaIS8_EE22_M_emplace_hint_uniqueIJRKSt21piecewise_construct_tSt5tupleIJRS7_EESJ_IJEEEEESt17_Rb_tree_iteratorIS8_ESt23_Rb_tree_const_iteratorIS8_EDpOT_(void*, void*, const void*, void*, void*);
|
||||
void* _ZNSt8_Rb_treeINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt4pairIKS5_S5_ESt10_Select1stIS8_ESt4lessIS5_ESaIS8_EE24_M_get_insert_unique_posERS7_(void*, const void*);
|
||||
void* _ZNSt8_Rb_treeINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt4pairIKS5_S5_ESt10_Select1stIS8_ESt4lessIS5_ESaIS8_EE29_M_get_insert_hint_unique_posESt23_Rb_tree_const_iteratorIS8_ERS7_(void*, void*, const void*);
|
||||
void* _ZNSt8_Rb_treeINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt4pairIKS5_S5_ESt10_Select1stIS8_ESt4lessIS5_ESaIS8_EE4findERS7_(void*, const void*);
|
||||
void _ZNSt8_Rb_treeINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt4pairIKS5_S5_ESt10_Select1stIS8_ESt4lessIS5_ESaIS8_EE8_M_eraseEPSt13_Rb_tree_nodeIS8_E(void*, void*);
|
||||
|
||||
// std::map<std::string, std::string>::operator[] (two overloads: rvalue key and const& key).
|
||||
void* _ZNSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES5_St4lessIS5_ESaISt4pairIKS5_S5_EEEixEOS5_(void*, void*);
|
||||
void* _ZNSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES5_St4lessIS5_ESaISt4pairIKS5_S5_EEEixERS9_(void*, const void*);
|
||||
// pair<const string, string>(piecewise_construct_t, tuple<string&>, tuple<>) - the map-node
|
||||
// in-place construction path std::map<string,string>::operator[] uses internally.
|
||||
void _ZNSt4pairIKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES5_EC1IJRS6_EJEEESt21piecewise_construct_tSt5tupleIJDpT_EESB_IJDpT0_EE(void*, const void*, void*, void*);
|
||||
|
||||
// No addressable name of their own (private members / SFINAE overloads); the forcing
|
||||
// wrappers above make GCC emit real definitions, resolved here by mangled name.
|
||||
void _ZNSt11_Deque_baseIcSaIcEEC2Ev(void*);
|
||||
void _ZNSt11_Deque_baseIcSaIcEED2Ev(void*);
|
||||
void _ZNSt11_Deque_baseIcSaIcEE15_M_create_nodesEPPcS3_(void*, char**, char**);
|
||||
void _ZNSt11_Deque_baseIcSaIcEE16_M_destroy_nodesEPPcS3_(void*, char**, char**);
|
||||
void _ZNSt11_Deque_baseIcSaIcEE17_M_initialize_mapEj(void*, unsigned int);
|
||||
void _ZNSt11_Deque_baseIdSaIdEEC2Ev(void*);
|
||||
void _ZNSt11_Deque_baseIdSaIdEED2Ev(void*);
|
||||
void _ZNSt11_Deque_baseIdSaIdEE15_M_create_nodesEPPdS3_(void*, double**, double**);
|
||||
void _ZNSt11_Deque_baseIdSaIdEE16_M_destroy_nodesEPPdS3_(void*, double**, double**);
|
||||
void _ZNSt11_Deque_baseIdSaIdEE17_M_initialize_mapEj(void*, unsigned int);
|
||||
void _ZNSt11_Deque_baseINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS5_EEC2Ev(void*);
|
||||
void _ZNSt11_Deque_baseINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS5_EEC2EOS7_(void*, void*);
|
||||
void _ZNSt11_Deque_baseINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS5_EED2Ev(void*);
|
||||
void _ZNSt11_Deque_baseINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS5_EE15_M_create_nodesEPPS5_S9_(void*, void*, void*);
|
||||
void _ZNSt11_Deque_baseINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS5_EE16_M_destroy_nodesEPPS5_S9_(void*, void*, void*);
|
||||
void _ZNSt11_Deque_baseINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS5_EE17_M_initialize_mapEj(void*, unsigned int);
|
||||
void _ZNSt11_Deque_baseINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS5_EE16_Deque_impl_dataC1EOS8_(void*, void*);
|
||||
void _ZNSt11_Deque_baseINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS5_EE16_Deque_impl_dataC1ERKS8_(void*, const void*);
|
||||
void* _ZSt4swapINSt11_Deque_baseINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS6_EE16_Deque_impl_dataEENSt9enable_ifIXsrSt6__and_IJSt6__not_ISt15__is_tuple_likeIT_EESt21is_move_constructibleISE_ESt18is_move_assignableISE_EEE5valueEvE4typeERSE_SO_(void*, void*);
|
||||
void _ZNSt5dequeIcSaIcEE15_M_pop_back_auxEv(void*);
|
||||
void _ZNSt5dequeIcSaIcEE16_M_push_back_auxIJRKcEEEvDpOT_(void*, const char*);
|
||||
void _ZNSt5dequeIcSaIcEE16_M_push_back_auxIJcEEEvDpOT_(void*, char*);
|
||||
void _ZNSt5dequeIcSaIcEE17_M_reallocate_mapEjb(void*, unsigned int, bool);
|
||||
void _ZNSt5dequeIcSaIcEE22_M_reserve_map_at_backEj(void*, unsigned int);
|
||||
void _ZNSt5dequeIdSaIdEE15_M_pop_back_auxEv(void*);
|
||||
void _ZNSt5dequeIdSaIdEE16_M_push_back_auxIJRKdEEEvDpOT_(void*, const double*);
|
||||
void _ZNSt5dequeIdSaIdEE16_M_push_back_auxIJdEEEvDpOT_(void*, double*);
|
||||
void _ZNSt5dequeIdSaIdEE17_M_reallocate_mapEjb(void*, unsigned int, bool);
|
||||
void _ZNSt5dequeIdSaIdEE22_M_reserve_map_at_backEj(void*, unsigned int);
|
||||
void _ZNSt5dequeINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS5_EE16_M_pop_front_auxEv(void*);
|
||||
void _ZNSt5dequeINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS5_EE16_M_push_back_auxIJRKS5_EEEvDpOT_(void*, const void*);
|
||||
void _ZNSt5dequeINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS5_EE16_M_push_back_auxIJS5_EEEvDpOT_(void*, void*);
|
||||
void _ZNSt5dequeINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS5_EE17_M_reallocate_mapEjb(void*, unsigned int, bool);
|
||||
void _ZNSt5dequeINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS5_EE22_M_reserve_map_at_backEj(void*, unsigned int);
|
||||
void _ZNSt5dequeINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS5_EE15_M_destroy_dataESt15_Deque_iteratorIS5_RS5_PS5_ESB_RKS6_(void*, void*, void*, const void*);
|
||||
void _ZNSt5dequeINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS5_EE15_M_erase_at_endESt15_Deque_iteratorIS5_RS5_PS5_E(void*, void*);
|
||||
void _ZNSt5dequeINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS5_EE19_M_destroy_data_auxESt15_Deque_iteratorIS5_RS5_PS5_ESB_(void*, void*, void*);
|
||||
void _ZNKSt6vectorIPKcSaIS1_EE12_M_check_lenEjS1_(const void*, unsigned int, const char*);
|
||||
void _ZNKSt6vectorISt4pairINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbESaIS7_EE12_M_check_lenEjPKc(const void*, unsigned int, const char*);
|
||||
void _ZNSt6vectorISt4pairINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbESaIS7_EE15_M_erase_at_endEPS7_(void*, void*);
|
||||
void* _ZNSt6vectorISt4pairINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbESaIS7_EE4backEv(void*);
|
||||
void _ZNSt16_Sp_counted_baseILN9__gnu_cxx12_Lock_policyE1EE10_M_destroyEv(void*);
|
||||
void _ZNSt16_Sp_counted_baseILN9__gnu_cxx12_Lock_policyE1EE10_M_releaseEv(void*);
|
||||
void _ZNSt16_Sp_counted_baseILN9__gnu_cxx12_Lock_policyE1EE19_M_release_last_useEv(void*);
|
||||
void _ZNSt16_Sp_counted_baseILN9__gnu_cxx12_Lock_policyE2EE10_M_destroyEv(void*);
|
||||
void _ZNSt16_Sp_counted_baseILN9__gnu_cxx12_Lock_policyE2EE10_M_releaseEv(void*);
|
||||
void _ZNSt16_Sp_counted_baseILN9__gnu_cxx12_Lock_policyE2EE19_M_release_last_useEv(void*);
|
||||
// Base _Sp_counted_base<Lock_policy> vtable (not a derived _Sp_counted_ptr<T,...>'s, which
|
||||
// varies per pointee type); exported as a weak symbol once the shared_count wrappers below
|
||||
// force its emission.
|
||||
extern void* _ZTVSt16_Sp_counted_baseILN9__gnu_cxx12_Lock_policyE1EE;
|
||||
extern void* _ZTVSt16_Sp_counted_baseILN9__gnu_cxx12_Lock_policyE2EE;
|
||||
#endif
|
||||
}
|
||||
|
||||
namespace {
|
||||
// Reimplements __cxa_pure_virtual's terminate() call directly rather than linking against
|
||||
// libstdc++.a(pure.o): once this file's locale/codecvt-pulling surface area (deque/vector<pair>/
|
||||
// shared_ptr/function below) grows large enough, some archive members carry their own
|
||||
// weak-undefined __cxa_pure_virtual reference that ld can resolve against instead of pure.o,
|
||||
// silently leaving the exported symbol null. Unconditional (not gated behind #ifdef
|
||||
// ESP_PLATFORM): also needed on the POSIX/simulator build.
|
||||
[[noreturn]] void pure_virtual_called() {
|
||||
std::terminate();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ESP_PLATFORM
|
||||
namespace {
|
||||
// basic_string(basic_string const&, pos, len) has no out-of-line definition anywhere to take the
|
||||
@ -95,6 +259,308 @@ void construct_basic_string_from_cstr(void* self, const char* s, const void* all
|
||||
void construct_basic_string_move(void* self, void* other) {
|
||||
new (self) std::string(std::move(*static_cast<std::string*>(other)));
|
||||
}
|
||||
|
||||
// vector<std::string>: same story as basic_string's ctors above - the destructor for a
|
||||
// non-trivial element type has no out-of-line definition anywhere to take the address of, so a
|
||||
// wrapper that actually destroys one forces the compiler to emit a genuine, addressable
|
||||
// definition here, registered below under the mangled name the ELF loader looks up.
|
||||
void destroy_vector_of_strings(void* self) {
|
||||
static_cast<std::vector<std::string>*>(self)->~vector();
|
||||
}
|
||||
// Same story for __new_allocator<std::string>::allocate() (used internally by vector<string>'s
|
||||
// growth/reserve path).
|
||||
void* allocate_string_storage(void* self, unsigned int n, const void* hint) {
|
||||
return static_cast<std::__new_allocator<std::string>*>(self)->allocate(n, hint);
|
||||
}
|
||||
|
||||
// Same story for vector<unsigned char>'s destructor.
|
||||
void destroy_vector_of_bytes(void* self) {
|
||||
static_cast<std::vector<unsigned char>*>(self)->~vector();
|
||||
}
|
||||
|
||||
// _Vector_base<T>::~_Vector_base only deallocates the raw buffer (element destruction is
|
||||
// vector<T>::~vector()'s job, called before this) - a distinct entry point with no accessible
|
||||
// out-of-line definition of its own (it's a protected base of vector<T>, and its destructor body
|
||||
// is a one-line inline in the header). A shim that publicly re-derives from it regains access to
|
||||
// call the real destructor at the right address, without duplicating its (private) cleanup logic.
|
||||
struct StringVectorBaseShim : std::_Vector_base<std::string, std::allocator<std::string>> {};
|
||||
void destroy_vector_base_of_strings(void* self) {
|
||||
static_cast<StringVectorBaseShim*>(self)->~StringVectorBaseShim();
|
||||
}
|
||||
|
||||
// std::to_string(unsigned) is `inline` in the header (no prebuilt out-of-line definition in
|
||||
// libstdc++'s archive) - the app calls it directly as an opaque function in at least one call
|
||||
// site (rather than always inlining it), so it needs a real out-of-line definition under its own
|
||||
// mangled name, not just a forcing side effect. Hidden return-value pointer convention, matching
|
||||
// the other string-returning functions (operator+, __str_concat) elsewhere in this file. This
|
||||
// same call also instantiates resize_and_overwrite()'s to_string-private lambda, registered
|
||||
// separately below under its own mangled name.
|
||||
void construct_to_string_result(void* out, unsigned int value) {
|
||||
new (out) std::string(std::to_string(value));
|
||||
}
|
||||
// Same story for std::to_string(long) - a distinct overload/mangled name from the unsigned one
|
||||
// above. Also instantiates its own private resize_and_overwrite lambda, registered separately
|
||||
// under its own mangled name (see the extern declarations above).
|
||||
void construct_to_string_result_long(void* out, long value) {
|
||||
new (out) std::string(std::to_string(value));
|
||||
}
|
||||
|
||||
// basic_string::rfind<string_view>(string_view const&, pos) is a small header-inline SFINAE
|
||||
// forwarder around the already-exported rfind(const char*, pos, n) overload - no prebuilt
|
||||
// out-of-line definition either, same story as to_string above.
|
||||
[[gnu::used]] unsigned int rfind_string_view(const std::string& self, const std::string_view& sv, unsigned int pos) {
|
||||
return self.rfind(sv, pos);
|
||||
}
|
||||
|
||||
// _Vector_base<T>::_Vector_impl_data::_M_swap_data - a plain one-line inline swap of three
|
||||
// pointers, normally never emitted out-of-line, but the app references it directly anyway
|
||||
// (matches _M_replace_cold's "kept out of line" pattern elsewhere in this file). Its type and
|
||||
// method are public members of the (struct, so default-public) _Vector_base.
|
||||
using StringVectorImplData = std::_Vector_base<std::string, std::allocator<std::string>>::_Vector_impl_data;
|
||||
void swap_string_vector_impl_data(void* self, void* other) {
|
||||
static_cast<StringVectorImplData*>(self)->_M_swap_data(*static_cast<StringVectorImplData*>(other));
|
||||
}
|
||||
// Same story for vector<unsigned char>(size_type, allocator const&).
|
||||
void construct_vector_of_bytes_sized(void* self, unsigned int count, const void* alloc) {
|
||||
new (self) std::vector<unsigned char>(count, *static_cast<const std::allocator<unsigned char>*>(alloc));
|
||||
}
|
||||
|
||||
// Same _Vector_base<T>::~_Vector_base distinction as the string version above, for
|
||||
// vector<unsigned char>.
|
||||
struct ByteVectorBaseShim : std::_Vector_base<unsigned char, std::allocator<unsigned char>> {};
|
||||
void destroy_vector_base_of_bytes(void* self) {
|
||||
static_cast<ByteVectorBaseShim*>(self)->~ByteVectorBaseShim();
|
||||
}
|
||||
|
||||
// push_back/emplace_back/back on vector<string> are ordinary public member functions with
|
||||
// out-of-line definitions, registered below under their real mangled names - the app's own
|
||||
// push_back/emplace_back calls resolve directly here, so each must insert exactly once.
|
||||
void push_back_string(void* self, const std::string& value) {
|
||||
static_cast<std::vector<std::string>*>(self)->push_back(value);
|
||||
}
|
||||
std::string& emplace_back_string(void* self, std::string&& value) {
|
||||
return static_cast<std::vector<std::string>*>(self)->emplace_back(std::move(value));
|
||||
}
|
||||
|
||||
// _M_realloc_append(T&&) is what push_back/emplace_back call internally when the vector needs
|
||||
// to grow - the app can also call it directly (its own compiled code inlined the fast/slow-path
|
||||
// split from push_back's body, keeping only the growth call out-of-line). These do exactly what
|
||||
// _M_realloc_append itself does (append one element, growing the vector), so redirecting the
|
||||
// app's call here is behavior-preserving - unlike push_back_string/emplace_back_string above,
|
||||
// which append TWO elements and must not be reused for this.
|
||||
void realloc_append_string_const_ref(void* self, const std::string& value) {
|
||||
static_cast<std::vector<std::string>*>(self)->push_back(value);
|
||||
}
|
||||
void realloc_append_string_rvalue(void* self, std::string&& value) {
|
||||
static_cast<std::vector<std::string>*>(self)->push_back(std::move(value));
|
||||
}
|
||||
|
||||
// std::deque<char>/<double>/<basic_string<char>> - unlike basic_string, libstdc++ does NOT
|
||||
// `extern template` instantiate std::deque anywhere, so NONE of its members (public or private)
|
||||
// exist as prebuilt symbols in libstdc++.a - a plain extern declaration link-fails even though it
|
||||
// compiles. Every wrapper below calls only the PUBLIC deque API on a real object; that forces the
|
||||
// compiler to instantiate and emit genuine out-of-line definitions for both the public entry point
|
||||
// and whichever private _M_*/_Deque_base helpers it needs internally, each addressable under its
|
||||
// own real mangled name (registered directly in SYMBOLS[] below, same as _M_realloc_append above).
|
||||
void destroy_deque_char(void* self) { static_cast<std::deque<char>*>(self)->~deque(); }
|
||||
char& back_of_deque_char(void* self) { return static_cast<std::deque<char>*>(self)->back(); }
|
||||
void pop_back_deque_char(void* self) { static_cast<std::deque<char>*>(self)->pop_back(); }
|
||||
void push_back_deque_char(void* self, const char& v) { static_cast<std::deque<char>*>(self)->push_back(v); }
|
||||
char& emplace_back_deque_char(void* self, char&& v) { return static_cast<std::deque<char>*>(self)->emplace_back(std::move(v)); }
|
||||
|
||||
void destroy_deque_double(void* self) { static_cast<std::deque<double>*>(self)->~deque(); }
|
||||
double& back_of_deque_double(void* self) { return static_cast<std::deque<double>*>(self)->back(); }
|
||||
void pop_back_deque_double(void* self) { static_cast<std::deque<double>*>(self)->pop_back(); }
|
||||
void push_back_deque_double(void* self, const double& v) { static_cast<std::deque<double>*>(self)->push_back(v); }
|
||||
double& emplace_back_deque_double(void* self, double&& v) { return static_cast<std::deque<double>*>(self)->emplace_back(std::move(v)); }
|
||||
|
||||
using StringDeque = std::deque<std::string>;
|
||||
void construct_deque_string(void* self) { new (self) StringDeque(); }
|
||||
void move_construct_deque_string(void* self, void* other) { new (self) StringDeque(std::move(*static_cast<StringDeque*>(other))); }
|
||||
void destroy_deque_string(void* self) { static_cast<StringDeque*>(self)->~deque(); }
|
||||
std::string& back_of_deque_string(void* self) { return static_cast<StringDeque*>(self)->back(); }
|
||||
void clear_deque_string(void* self) { static_cast<StringDeque*>(self)->clear(); }
|
||||
void pop_front_deque_string(void* self) { static_cast<StringDeque*>(self)->pop_front(); }
|
||||
void push_back_deque_string(void* self, const std::string& v) { static_cast<StringDeque*>(self)->push_back(v); }
|
||||
std::string& emplace_back_deque_string(void* self, std::string&& v) { return static_cast<StringDeque*>(self)->emplace_back(std::move(v)); }
|
||||
|
||||
// std::stack<T, deque<T>>'s default constructor - trivial, but (like everything else deque-related
|
||||
// here) has no prebuilt out-of-line definition anywhere; a value-initializing placement-new forces
|
||||
// the compiler to emit one.
|
||||
void construct_stack_char(void* self) { new (self) std::stack<char, std::deque<char>>(); }
|
||||
void construct_stack_double(void* self) { new (self) std::stack<double, std::deque<double>>(); }
|
||||
|
||||
// std::_Deque_iterator<T,...>::operator--() and operator-(iterator, iterator) - reached through
|
||||
// std::stack<T>::pop()/size() internals when T's deque grows past a single node. Forced the same
|
||||
// way: call the real operators on real iterators (obtained via begin()/end(), which are cheap and
|
||||
// always valid even on an empty deque).
|
||||
void decrement_deque_iterator_char(void* self) { --*static_cast<std::deque<char>::iterator*>(self); }
|
||||
void decrement_deque_iterator_double(void* self) { --*static_cast<std::deque<double>::iterator*>(self); }
|
||||
void decrement_deque_iterator_string(void* self) { --*static_cast<StringDeque::iterator*>(self); }
|
||||
int subtract_deque_iterators_char(const void* a, const void* b) {
|
||||
return static_cast<int>(*static_cast<const std::deque<char>::iterator*>(a) - *static_cast<const std::deque<char>::iterator*>(b));
|
||||
}
|
||||
int subtract_deque_iterators_double(const void* a, const void* b) {
|
||||
return static_cast<int>(*static_cast<const std::deque<double>::iterator*>(a) - *static_cast<const std::deque<double>::iterator*>(b));
|
||||
}
|
||||
int subtract_deque_iterators_string(const void* a, const void* b) {
|
||||
return static_cast<int>(*static_cast<const StringDeque::iterator*>(a) - *static_cast<const StringDeque::iterator*>(b));
|
||||
}
|
||||
|
||||
// std::vector<const char*> and std::vector<std::pair<std::string, bool>> - same "no extern
|
||||
// template anywhere" story as deque above (nothing else in the firmware happens to instantiate
|
||||
// these two particular element types, unlike vector<string>/vector<unsigned char> which do get
|
||||
// pulled in elsewhere and so link fine as plain externs). Forced via the public API, same pattern.
|
||||
using CStrVector = std::vector<const char*>;
|
||||
void destroy_vector_base_of_cstrs(void* self) { static_cast<std::_Vector_base<const char*, std::allocator<const char*>>*>(self)->~_Vector_base(); }
|
||||
const char*& back_of_cstr_vector(void* self) { return static_cast<CStrVector*>(self)->back(); }
|
||||
const char*& emplace_back_cstr_vector(void* self, const char*&& v) { return static_cast<CStrVector*>(self)->emplace_back(std::move(v)); }
|
||||
void realloc_append_cstr_vector(void* self, const char*&& v) { static_cast<CStrVector*>(self)->push_back(std::move(v)); }
|
||||
void reserve_cstr_vector(void* self, unsigned int n) { static_cast<CStrVector*>(self)->reserve(n); }
|
||||
void* allocate_cstr_storage(void* self, unsigned int n, const void* hint) {
|
||||
return static_cast<std::__new_allocator<const char*>*>(self)->allocate(n, hint);
|
||||
}
|
||||
|
||||
using StringBoolPair = std::pair<std::string, bool>;
|
||||
using StringBoolPairVector = std::vector<StringBoolPair>;
|
||||
bool empty_string_bool_pair_vector(const void* self) { return static_cast<const StringBoolPairVector*>(self)->empty(); }
|
||||
// erase(begin(), end()) calls _M_erase_at_end(pointer) internally, forcing its instantiation
|
||||
// under the mangled name registered directly via DEFINE_MODULE_SYMBOL below - this function
|
||||
// itself is never called or registered, it exists purely so that call happens somewhere in this
|
||||
// TU. [[gnu::used]] keeps the compiler from dead-stripping it as an uncalled anonymous-namespace
|
||||
// function, which would silently drop the instantiation it exists to force.
|
||||
[[gnu::used]] void clear_string_bool_pair_vector(void* self) {
|
||||
auto* v = static_cast<StringBoolPairVector*>(self);
|
||||
v->erase(v->begin(), v->end());
|
||||
}
|
||||
void destroy_vector_base_of_string_bool_pairs(void* self) { static_cast<std::_Vector_base<StringBoolPair, std::allocator<StringBoolPair>>*>(self)->~_Vector_base(); }
|
||||
void destroy_vector_of_string_bool_pairs(void* self) { static_cast<StringBoolPairVector*>(self)->~vector(); }
|
||||
StringBoolPair& emplace_back_string_bool_pair_vector(void* self, StringBoolPair&& v) { return static_cast<StringBoolPairVector*>(self)->emplace_back(std::move(v)); }
|
||||
void realloc_append_string_bool_pair_vector(void* self, StringBoolPair&& v) { static_cast<StringBoolPairVector*>(self)->push_back(std::move(v)); }
|
||||
void* allocate_string_bool_pair_storage(void* self, unsigned int n, const void* hint) {
|
||||
return static_cast<std::__new_allocator<StringBoolPair>*>(self)->allocate(n, hint);
|
||||
}
|
||||
void* allocate_string_ptr_storage(void* self, unsigned int n, const void* hint) {
|
||||
return static_cast<std::__new_allocator<std::string*>*>(self)->allocate(n, hint);
|
||||
}
|
||||
void* allocate_char_ptr_storage(void* self, unsigned int n, const void* hint) {
|
||||
return static_cast<std::__new_allocator<char*>*>(self)->allocate(n, hint);
|
||||
}
|
||||
void* allocate_double_ptr_storage(void* self, unsigned int n, const void* hint) {
|
||||
return static_cast<std::__new_allocator<double*>*>(self)->allocate(n, hint);
|
||||
}
|
||||
|
||||
// std::__shared_count<Lp>/_Sp_counted_base<Lp> - no extern-template instantiation anywhere, same
|
||||
// story as deque/vector<pair<...>> above. Forced via std::shared_ptr<int> rather than a real app
|
||||
// type: the raw-pointer constructor's mangled name embeds the pointee type, but operator= and
|
||||
// _Sp_counted_base's virtual dispatch (forced as a side effect of constructing one) don't - their
|
||||
// mangled names carry only the Lock_policy, so those two are genuinely reusable across every app's
|
||||
// shared_ptr<AnyType> regardless of what int has to do with any of them.
|
||||
using GenericSharedCountAtomic = std::__shared_count<__gnu_cxx::_Lock_policy::_S_atomic>;
|
||||
using GenericSharedCountMutex = std::__shared_count<__gnu_cxx::_Lock_policy::_S_mutex>;
|
||||
// [[gnu::used]]: neither of these is registered in SYMBOLS[] under its own name (nothing looks
|
||||
// up "construct a shared_ptr<int>" by that description) - they exist purely so the compiler
|
||||
// instantiates _Sp_counted_base<Lock_policy>'s virtual table and out-of-line thunks as a side
|
||||
// effect, which -ffunction-sections/--gc-sections would otherwise strip as dead code since no
|
||||
// other code in this TU calls them and nothing takes their address.
|
||||
[[gnu::used]] void construct_shared_count_atomic_int(void* self, int* p) { new (self) GenericSharedCountAtomic(p); }
|
||||
void assign_shared_count_atomic(void* self, const void* other) {
|
||||
*static_cast<GenericSharedCountAtomic*>(self) = *static_cast<const GenericSharedCountAtomic*>(other);
|
||||
}
|
||||
[[gnu::used]] void construct_shared_count_mutex_int(void* self, int* p) { new (self) GenericSharedCountMutex(p); }
|
||||
void assign_shared_count_mutex(void* self, const void* other) {
|
||||
*static_cast<GenericSharedCountMutex*>(self) = *static_cast<const GenericSharedCountMutex*>(other);
|
||||
}
|
||||
// _Sp_counted_base<Lock_policy> is an abstract base (_M_destroy/_M_release/_M_release_last_use
|
||||
// are virtual, overridden by the concrete _Sp_counted_ptr<T*,...> that __shared_count's
|
||||
// constructor above actually allocates) - can't instantiate it standalone, but constructing a real
|
||||
// GenericSharedCount*(ptr) above already forces the compiler to emit its base class's virtual
|
||||
// table and out-of-line virtual function thunks, addressable under _Sp_counted_base's own mangled
|
||||
// names because that's the base subobject type the virtual calls are dispatched through, and
|
||||
// those names carry only the Lock_policy (not the pointee type T), so this generic forcing works
|
||||
// for every app's shared_ptr<AnyType> without needing to know AnyType.
|
||||
//
|
||||
// The raw-pointer __shared_count<Lp>::__shared_count<T*>(T*) constructor is deliberately NOT
|
||||
// exported here: the app's own compiler already emits a local weak-linkage definition of it, and
|
||||
// esp_elf.c's relocate loop falls back to that when the firmware doesn't provide one.
|
||||
|
||||
// std::function<int(char*, unsigned int)> - no extern-template instantiation anywhere, so forced
|
||||
// via the public API on a real object, same pattern as everything else above.
|
||||
using CharBufferFn = std::function<int(char*, unsigned int)>;
|
||||
int call_char_buffer_fn(const void* self, char* buf, unsigned int len) { return (*static_cast<const CharBufferFn*>(self))(buf, len); }
|
||||
void swap_char_buffer_fn(void* self, void* other) { static_cast<CharBufferFn*>(self)->swap(*static_cast<CharBufferFn*>(other)); }
|
||||
void construct_char_buffer_fn_copy(void* self, const void* other) { new (self) CharBufferFn(*static_cast<const CharBufferFn*>(other)); }
|
||||
void* assign_char_buffer_fn_nullptr(void* self) { return &(*static_cast<CharBufferFn*>(self) = nullptr); }
|
||||
|
||||
// _Guard_alloc's dtor is private to vector<T> itself (unlike _Vector_base above), so this
|
||||
// replicates its fixed layout/dtor logic directly instead of calling the inaccessible real one.
|
||||
template <typename T>
|
||||
struct GuardAllocLayout {
|
||||
T* storage;
|
||||
std::size_t len;
|
||||
void* vect;
|
||||
};
|
||||
template <typename T>
|
||||
void destroy_guard_alloc(void* self) {
|
||||
auto* guard = static_cast<GuardAllocLayout<T>*>(self);
|
||||
if (guard->storage) {
|
||||
std::allocator<T>().deallocate(guard->storage, guard->len);
|
||||
}
|
||||
}
|
||||
std::string& back_of_string_vector(void* self) {
|
||||
return static_cast<std::vector<std::string>*>(self)->back();
|
||||
}
|
||||
// vector<string>'s move-assignment operator (self = std::move(other)) - forces the private
|
||||
// _M_move_assign/_M_swap_data helpers it needs to be emitted as addressable definitions too.
|
||||
void move_assign_string_vector(void* self, void* other) {
|
||||
*static_cast<std::vector<std::string>*>(self) = std::move(*static_cast<std::vector<std::string>*>(other));
|
||||
}
|
||||
|
||||
// Misc algorithm/iterator template instantiations pulled in by std::stack<char/double> and
|
||||
// vector<pair<string,bool>> usage - none prebuilt anywhere, forced by calling the public std::
|
||||
// algorithm entry point on real pointers/iterators of the exact instantiated type.
|
||||
std::string** copy_move_a2_string_ptr(std::string** first, std::string** last, std::string** out) {
|
||||
return std::copy(first, last, out);
|
||||
}
|
||||
char** copy_move_a2_char_ptr(char** first, char** last, char** out) { return std::copy(first, last, out); }
|
||||
double** copy_move_a2_double_ptr(double** first, double** last, double** out) { return std::copy(first, last, out); }
|
||||
StringBoolPair* relocate_string_bool_pairs(StringBoolPair* first, StringBoolPair* last, StringBoolPair* out, std::allocator<StringBoolPair>& alloc) {
|
||||
return std::__relocate_a(first, last, out, alloc);
|
||||
}
|
||||
std::string** copy_move_backward_a2_string_ptr(std::string** first, std::string** last, std::string** out) {
|
||||
return std::copy_backward(first, last, out);
|
||||
}
|
||||
char** copy_move_backward_a2_char_ptr(char** first, char** last, char** out) { return std::copy_backward(first, last, out); }
|
||||
double** copy_move_backward_a2_double_ptr(double** first, double** last, double** out) { return std::copy_backward(first, last, out); }
|
||||
StringBoolPair* move_backward_string_bool_pairs(StringBoolPair* first, StringBoolPair* last, StringBoolPair* out) {
|
||||
return std::move_backward(first, last, out);
|
||||
}
|
||||
short max_short_init_list(std::initializer_list<short> values) {
|
||||
return std::max(values);
|
||||
}
|
||||
short min_short_init_list(std::initializer_list<short> values) {
|
||||
return std::min(values);
|
||||
}
|
||||
void advance_string_ptr_ptr(std::string*** it, int n) { std::advance(*it, n); }
|
||||
void advance_char_ptr_ptr(char*** it, int n) { std::advance(*it, n); }
|
||||
void advance_double_ptr_ptr(double*** it, int n) { std::advance(*it, n); }
|
||||
void iter_swap_string_bool_pair_vector(StringBoolPairVector::iterator a, StringBoolPairVector::iterator b) {
|
||||
std::iter_swap(a, b);
|
||||
}
|
||||
__gnu_cxx::__normal_iterator<char*, std::string> transform_char_to_upper(
|
||||
__gnu_cxx::__normal_iterator<char*, std::string> first,
|
||||
__gnu_cxx::__normal_iterator<char*, std::string> last,
|
||||
__gnu_cxx::__normal_iterator<char*, std::string> out,
|
||||
int (*fn)(int)
|
||||
) {
|
||||
return std::transform(first, last, out, fn);
|
||||
}
|
||||
// std::_Any_data (std::function's internal storage union) - swap<T> is SFINAE-enabled only for
|
||||
// move-constructible/assignable, non-tuple-like T; _Any_data qualifies, so calling std::swap on
|
||||
// two real ones forces this exact overload's instantiation.
|
||||
void swap_any_data(void* a, void* b) {
|
||||
std::swap(*static_cast<std::_Any_data*>(a), *static_cast<std::_Any_data*>(b));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@ -111,7 +577,7 @@ static const ModuleSymbol SYMBOLS[] = {
|
||||
DEFINE_MODULE_SYMBOL(_ZdaPv), // operator delete[](void*)
|
||||
#endif
|
||||
{ "_ZSt7nothrow", (void*)&std::nothrow },
|
||||
DEFINE_MODULE_SYMBOL(__cxa_pure_virtual), // class-related, see https://arobenko.github.io/bare_metal_cpp/
|
||||
{ "__cxa_pure_virtual", (void*)&pure_virtual_called }, // see comment above pure_virtual_called
|
||||
DEFINE_MODULE_SYMBOL(__cxa_guard_acquire),
|
||||
DEFINE_MODULE_SYMBOL(__cxa_guard_release),
|
||||
DEFINE_MODULE_SYMBOL(__cxa_guard_abort),
|
||||
@ -164,6 +630,225 @@ static const ModuleSymbol SYMBOLS[] = {
|
||||
{ "_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC5EOS4_", (void*)&construct_basic_string_move },
|
||||
DEFINE_MODULE_SYMBOL(_ZSt12__str_concatINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEET_PKNS6_10value_typeENS6_9size_typeES9_SA_RKNS6_14allocator_typeE),
|
||||
DEFINE_MODULE_SYMBOL(_ZStplIcSt11char_traitsIcESaIcEENSt7__cxx1112basic_stringIT_T0_T1_EERKS8_PKS5_),
|
||||
DEFINE_MODULE_SYMBOL(_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE4findEPKcj),
|
||||
DEFINE_MODULE_SYMBOL(_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE4findEPKcjj),
|
||||
DEFINE_MODULE_SYMBOL(_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE5rfindEPKcjj),
|
||||
DEFINE_MODULE_SYMBOL(_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE5rfindEcj),
|
||||
DEFINE_MODULE_SYMBOL(_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7compareERKS4_),
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE4swapERS4_),
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6insertEjPKc),
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7replaceEjjPKcj),
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt8__detail14__to_chars_lenIjEEjT_i),
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt8__detail18__to_chars_10_implIjEEvPcjT_),
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt8__detail14__to_chars_lenImEEjT_i),
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt8__detail18__to_chars_10_implImEEvPcjT_),
|
||||
DEFINE_MODULE_SYMBOL(_ZSteqIcSt11char_traitsIcESaIcEEbRKNSt7__cxx1112basic_stringIT_T0_T1_EEPKS5_),
|
||||
DEFINE_MODULE_SYMBOL(_ZSteqIcSt11char_traitsIcESaIcEEbRKNSt7__cxx1112basic_stringIT_T0_T1_EESA_),
|
||||
DEFINE_MODULE_SYMBOL(_ZStplIcSt11char_traitsIcESaIcEENSt7__cxx1112basic_stringIT_T0_T1_EEOS8_S9_),
|
||||
DEFINE_MODULE_SYMBOL(_ZStplIcSt11char_traitsIcESaIcEENSt7__cxx1112basic_stringIT_T0_T1_EEPKS5_RKS8_),
|
||||
DEFINE_MODULE_SYMBOL(_ZStplIcSt11char_traitsIcESaIcEENSt7__cxx1112basic_stringIT_T0_T1_EERKS8_SA_),
|
||||
DEFINE_MODULE_SYMBOL(_ZNKSt6vectorIhSaIhEE12_M_check_lenEjPKc),
|
||||
DEFINE_MODULE_SYMBOL(_ZNKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS5_EE12_M_check_lenEjPKc),
|
||||
DEFINE_MODULE_SYMBOL(_ZNKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS5_EE5emptyEv),
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt12_Vector_baseIhSaIhEE11_M_allocateEj),
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt12_Vector_baseIhSaIhEE17_M_create_storageEj),
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt6vectorIhSaIhEE17_M_default_appendEj),
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt6vectorIhSaIhEE6resizeEj),
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt27__uninitialized_default_n_1ILb1EE18__uninit_default_nIPhjEET_S3_T0_),
|
||||
DEFINE_MODULE_SYMBOL(_ZSt9__fill_a1IhhEN9__gnu_cxx11__enable_ifIXaasrSt9__is_byteIT_E7__valueoosrSt10__are_sameIS3_T0_E7__valuesrSt20__memcpyable_integerIS6_E7__widthEvE6__typeEPS3_SC_RKS6_),
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt5mutex4lockEv),
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructILb1EEEvPKcj),
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE20resize_and_overwriteIRZNS_9to_stringEjEUlPcjE_EEvjT_),
|
||||
{ "_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE5rfindISt17basic_string_viewIcS2_EEENSt9enable_ifIXsrSt6__and_IJSt14is_convertibleIRKT_S7_ESt6__not_ISA_IPSC_PKS4_EESF_ISA_ISD_PKcEEEE5valueEjE4typeESD_j", (void*)&rfind_string_view },
|
||||
DEFINE_MODULE_SYMBOL(_ZSt14__relocate_a_1IPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES6_SaIS5_EET0_T_S9_S8_RT1_),
|
||||
DEFINE_MODULE_SYMBOL(_ZStssIcSt11char_traitsIcESaIcEEDTcl21__char_traits_cmp_catIT0_ELi0EEERKNSt7__cxx1112basic_stringIT_S3_T1_EESB_),
|
||||
// vector<std::string> - Note: You have to use the mangled names here
|
||||
{ "_ZNSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS5_EED1Ev", (void*)&destroy_vector_of_strings },
|
||||
{ "_ZNSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS5_EED2Ev", (void*)&destroy_vector_of_strings },
|
||||
{ "_ZNSt15__new_allocatorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE8allocateEjPKv", (void*)&allocate_string_storage },
|
||||
{ "_ZNSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS5_EE9push_backERKS5_", (void*)&push_back_string },
|
||||
{ "_ZNSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS5_EE12emplace_backIJS5_EEERS5_DpOT_", (void*)&emplace_back_string },
|
||||
{ "_ZNSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS5_EE4backEv", (void*)&back_of_string_vector },
|
||||
{ "_ZNSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS5_EE14_M_move_assignEOS7_St17integral_constantIbLb1EE", (void*)&move_assign_string_vector },
|
||||
// vector<unsigned char> - Note: You have to use the mangled names here
|
||||
{ "_ZNSt6vectorIhSaIhEED1Ev", (void*)&destroy_vector_of_bytes },
|
||||
{ "_ZNSt6vectorIhSaIhEED2Ev", (void*)&destroy_vector_of_bytes },
|
||||
{ "_ZNSt6vectorIhSaIhEEC1EjRKS0_", (void*)&construct_vector_of_bytes_sized },
|
||||
{ "_ZNSt12_Vector_baseIhSaIhEED2Ev", (void*)&destroy_vector_base_of_bytes },
|
||||
// _Vector_base<T>::~_Vector_base only deallocates the raw buffer (elements are destroyed by
|
||||
// vector<T>'s own destructor before this runs) - a distinct entry point from ~vector(), so
|
||||
// it needs its own wrapper rather than reusing destroy_vector_of_strings/_of_bytes above.
|
||||
{ "_ZNSt12_Vector_baseINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS5_EED2Ev", (void*)&destroy_vector_base_of_strings },
|
||||
{ "_ZNSt7__cxx119to_stringEj", (void*)&construct_to_string_result },
|
||||
{ "_ZNSt12_Vector_baseINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS5_EE17_Vector_impl_data12_M_swap_dataERS8_", (void*)&swap_string_vector_impl_data },
|
||||
{ "_ZNSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS5_EE17_M_realloc_appendIJRKS5_EEEvDpOT_", (void*)&realloc_append_string_const_ref },
|
||||
{ "_ZNSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS5_EE17_M_realloc_appendIJS5_EEEvDpOT_", (void*)&realloc_append_string_rvalue },
|
||||
{ "_ZNSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS5_EE12_Guard_allocD1Ev", (void*)&destroy_guard_alloc<std::string> },
|
||||
{ "_ZNSt6vectorIhSaIhEE12_Guard_allocD1Ev", (void*)&destroy_guard_alloc<unsigned char> },
|
||||
DEFINE_MODULE_SYMBOL(_ZNKSt8functionIFlvEEclEv),
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt14_Function_baseD2Ev),
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt8functionIFlvEEC1ERKS1_),
|
||||
|
||||
DEFINE_MODULE_SYMBOL(_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE13find_first_ofEPKcj),
|
||||
DEFINE_MODULE_SYMBOL(_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE13find_first_ofEPKcjj),
|
||||
DEFINE_MODULE_SYMBOL(_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE4copyEPcjj),
|
||||
DEFINE_MODULE_SYMBOL(_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE7compareEjjPKc),
|
||||
DEFINE_MODULE_SYMBOL(_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE8_M_checkEjPKc),
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructEjc),
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE14_M_replace_auxEjjjc),
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE5eraseEjj),
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6appendEjc),
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6assignEPKcj),
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6resizeEjc),
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE9_S_assignEPcjc),
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1EPKcjRKS3_),
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE20resize_and_overwriteIRZNS_9to_stringElEUlPcjE_EEvjT_),
|
||||
{ "_ZNSt7__cxx119to_stringEl", (void*)&construct_to_string_result_long },
|
||||
|
||||
// std::deque<char>/<double>/<basic_string<char>> and std::stack<T, deque<T>>
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt11_Deque_baseIcSaIcEEC2Ev),
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt11_Deque_baseIcSaIcEED2Ev),
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt11_Deque_baseIcSaIcEE15_M_create_nodesEPPcS3_),
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt11_Deque_baseIcSaIcEE16_M_destroy_nodesEPPcS3_),
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt11_Deque_baseIcSaIcEE17_M_initialize_mapEj),
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt11_Deque_baseIdSaIdEEC2Ev),
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt11_Deque_baseIdSaIdEED2Ev),
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt11_Deque_baseIdSaIdEE15_M_create_nodesEPPdS3_),
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt11_Deque_baseIdSaIdEE16_M_destroy_nodesEPPdS3_),
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt11_Deque_baseIdSaIdEE17_M_initialize_mapEj),
|
||||
{ "_ZNSt11_Deque_baseINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS5_EEC2Ev", (void*)&construct_deque_string },
|
||||
{ "_ZNSt11_Deque_baseINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS5_EEC2EOS7_", (void*)&move_construct_deque_string },
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt11_Deque_baseINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS5_EED2Ev),
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt11_Deque_baseINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS5_EE15_M_create_nodesEPPS5_S9_),
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt11_Deque_baseINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS5_EE16_M_destroy_nodesEPPS5_S9_),
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt11_Deque_baseINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS5_EE17_M_initialize_mapEj),
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt11_Deque_baseINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS5_EE16_Deque_impl_dataC1EOS8_),
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt11_Deque_baseINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS5_EE16_Deque_impl_dataC1ERKS8_),
|
||||
DEFINE_MODULE_SYMBOL(_ZSt4swapINSt11_Deque_baseINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS6_EE16_Deque_impl_dataEENSt9enable_ifIXsrSt6__and_IJSt6__not_ISt15__is_tuple_likeIT_EESt21is_move_constructibleISE_ESt18is_move_assignableISE_EEE5valueEvE4typeERSE_SO_),
|
||||
{ "_ZNSt15_Deque_iteratorIcRcPcEmmEv", (void*)&decrement_deque_iterator_char },
|
||||
{ "_ZNSt15_Deque_iteratorIdRdPdEmmEv", (void*)&decrement_deque_iterator_double },
|
||||
{ "_ZNSt15_Deque_iteratorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS5_PS5_EmmEv", (void*)&decrement_deque_iterator_string },
|
||||
{ "_ZStmiRKSt15_Deque_iteratorIcRcPcES4_", (void*)&subtract_deque_iterators_char },
|
||||
{ "_ZStmiRKSt15_Deque_iteratorIdRdPdES4_", (void*)&subtract_deque_iterators_double },
|
||||
{ "_ZStmiRKSt15_Deque_iteratorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS5_PS5_ESA_", (void*)&subtract_deque_iterators_string },
|
||||
{ "_ZNSt5dequeIcSaIcEED1Ev", (void*)&destroy_deque_char },
|
||||
{ "_ZNSt5dequeIcSaIcEE4backEv", (void*)&back_of_deque_char },
|
||||
{ "_ZNSt5dequeIcSaIcEE8pop_backEv", (void*)&pop_back_deque_char },
|
||||
{ "_ZNSt5dequeIcSaIcEE9push_backERKc", (void*)&push_back_deque_char },
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt5dequeIcSaIcEE15_M_pop_back_auxEv),
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt5dequeIcSaIcEE16_M_push_back_auxIJRKcEEEvDpOT_),
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt5dequeIcSaIcEE16_M_push_back_auxIJcEEEvDpOT_),
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt5dequeIcSaIcEE17_M_reallocate_mapEjb),
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt5dequeIcSaIcEE22_M_reserve_map_at_backEj),
|
||||
{ "_ZNSt5dequeIcSaIcEE12emplace_backIJcEEERcDpOT_", (void*)&emplace_back_deque_char },
|
||||
{ "_ZNSt5dequeIdSaIdEED1Ev", (void*)&destroy_deque_double },
|
||||
{ "_ZNSt5dequeIdSaIdEE4backEv", (void*)&back_of_deque_double },
|
||||
{ "_ZNSt5dequeIdSaIdEE8pop_backEv", (void*)&pop_back_deque_double },
|
||||
{ "_ZNSt5dequeIdSaIdEE9push_backERKd", (void*)&push_back_deque_double },
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt5dequeIdSaIdEE15_M_pop_back_auxEv),
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt5dequeIdSaIdEE16_M_push_back_auxIJRKdEEEvDpOT_),
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt5dequeIdSaIdEE16_M_push_back_auxIJdEEEvDpOT_),
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt5dequeIdSaIdEE17_M_reallocate_mapEjb),
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt5dequeIdSaIdEE22_M_reserve_map_at_backEj),
|
||||
{ "_ZNSt5dequeIdSaIdEE12emplace_backIJdEEERdDpOT_", (void*)&emplace_back_deque_double },
|
||||
{ "_ZNSt5dequeINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS5_EED1Ev", (void*)&destroy_deque_string },
|
||||
{ "_ZNSt5dequeINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS5_EE4backEv", (void*)&back_of_deque_string },
|
||||
{ "_ZNSt5dequeINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS5_EE5clearEv", (void*)&clear_deque_string },
|
||||
{ "_ZNSt5dequeINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS5_EE9pop_frontEv", (void*)&pop_front_deque_string },
|
||||
{ "_ZNSt5dequeINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS5_EE9push_backERKS5_", (void*)&push_back_deque_string },
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt5dequeINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS5_EE16_M_pop_front_auxEv),
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt5dequeINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS5_EE16_M_push_back_auxIJRKS5_EEEvDpOT_),
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt5dequeINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS5_EE16_M_push_back_auxIJS5_EEEvDpOT_),
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt5dequeINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS5_EE17_M_reallocate_mapEjb),
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt5dequeINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS5_EE22_M_reserve_map_at_backEj),
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt5dequeINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS5_EE15_M_destroy_dataESt15_Deque_iteratorIS5_RS5_PS5_ESB_RKS6_),
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt5dequeINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS5_EE15_M_erase_at_endESt15_Deque_iteratorIS5_RS5_PS5_E),
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt5dequeINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS5_EE19_M_destroy_data_auxESt15_Deque_iteratorIS5_RS5_PS5_ESB_),
|
||||
{ "_ZNSt5dequeINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS5_EE12emplace_backIJS5_EEERS5_DpOT_", (void*)&emplace_back_deque_string },
|
||||
{ "_ZNSt5stackIcSt5dequeIcSaIcEEEC1IS2_vEEv", (void*)&construct_stack_char },
|
||||
{ "_ZNSt5stackIdSt5dequeIdSaIdEEEC1IS2_vEEv", (void*)&construct_stack_double },
|
||||
|
||||
// std::vector<const char*> / vector<pair<string,bool>> internals
|
||||
DEFINE_MODULE_SYMBOL(_ZNKSt6vectorIPKcSaIS1_EE12_M_check_lenEjS1_),
|
||||
{ "_ZNSt12_Vector_baseIPKcSaIS1_EED2Ev", (void*)&destroy_vector_base_of_cstrs },
|
||||
{ "_ZNSt6vectorIPKcSaIS1_EE12_Guard_allocD1Ev", (void*)&(destroy_guard_alloc<const char*>) },
|
||||
{ "_ZNSt6vectorIPKcSaIS1_EE12emplace_backIJS1_EEERS1_DpOT_", (void*)&emplace_back_cstr_vector },
|
||||
{ "_ZNSt6vectorIPKcSaIS1_EE17_M_realloc_appendIJS1_EEEvDpOT_", (void*)&realloc_append_cstr_vector },
|
||||
{ "_ZNSt6vectorIPKcSaIS1_EE4backEv", (void*)&back_of_cstr_vector },
|
||||
{ "_ZNSt6vectorIPKcSaIS1_EE7reserveEj", (void*)&reserve_cstr_vector },
|
||||
{ "_ZNSt15__new_allocatorIPKcE8allocateEjPKv", (void*)&allocate_cstr_storage },
|
||||
DEFINE_MODULE_SYMBOL(_ZNKSt6vectorISt4pairINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbESaIS7_EE12_M_check_lenEjPKc),
|
||||
{ "_ZNKSt6vectorISt4pairINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbESaIS7_EE5emptyEv", (void*)&empty_string_bool_pair_vector },
|
||||
{ "_ZNSt12_Vector_baseISt4pairINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbESaIS7_EED2Ev", (void*)&destroy_vector_base_of_string_bool_pairs },
|
||||
{ "_ZNSt6vectorISt4pairINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbESaIS7_EE12_Guard_allocD1Ev", (void*)&(destroy_guard_alloc<StringBoolPair>) },
|
||||
{ "_ZNSt6vectorISt4pairINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbESaIS7_EE12emplace_backIJS7_EEERS7_DpOT_", (void*)&emplace_back_string_bool_pair_vector },
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt6vectorISt4pairINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbESaIS7_EE15_M_erase_at_endEPS7_),
|
||||
{ "_ZNSt6vectorISt4pairINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbESaIS7_EE17_M_realloc_appendIJS7_EEEvDpOT_", (void*)&realloc_append_string_bool_pair_vector },
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt6vectorISt4pairINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbESaIS7_EE4backEv),
|
||||
{ "_ZNSt6vectorISt4pairINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbESaIS7_EED1Ev", (void*)&destroy_vector_of_string_bool_pairs },
|
||||
{ "_ZNSt15__new_allocatorISt4pairINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbEE8allocateEjPKv", (void*)&allocate_string_bool_pair_storage },
|
||||
{ "_ZNSt15__new_allocatorIPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE8allocateEjPKv", (void*)&allocate_string_ptr_storage },
|
||||
{ "_ZNSt15__new_allocatorIPcE8allocateEjPKv", (void*)&allocate_char_ptr_storage },
|
||||
{ "_ZNSt15__new_allocatorIPdE8allocateEjPKv", (void*)&allocate_double_ptr_storage },
|
||||
|
||||
// std::_Rb_tree<string, pair<const string,string>, ...> - std::map<string,string> internals
|
||||
DEFINE_MODULE_SYMBOL(_ZNKSt8_Rb_treeINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt4pairIKS5_S5_ESt10_Select1stIS8_ESt4lessIS5_ESaIS8_EE14_M_lower_boundEPSt18_Rb_tree_node_baseSG_RS7_),
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt8_Rb_treeINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt4pairIKS5_S5_ESt10_Select1stIS8_ESt4lessIS5_ESaIS8_EE10_Auto_node9_M_insertES6_IPSt18_Rb_tree_node_baseSH_E),
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt8_Rb_treeINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt4pairIKS5_S5_ESt10_Select1stIS8_ESt4lessIS5_ESaIS8_EE10_Auto_nodeD1Ev),
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt8_Rb_treeINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt4pairIKS5_S5_ESt10_Select1stIS8_ESt4lessIS5_ESaIS8_EE11lower_boundERS7_),
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt8_Rb_treeINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt4pairIKS5_S5_ESt10_Select1stIS8_ESt4lessIS5_ESaIS8_EE12_M_drop_nodeEPSt13_Rb_tree_nodeIS8_E),
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt8_Rb_treeINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt4pairIKS5_S5_ESt10_Select1stIS8_ESt4lessIS5_ESaIS8_EE14_M_create_nodeIJRKSt21piecewise_construct_tSt5tupleIJOS5_EESJ_IJEEEEEPSt13_Rb_tree_nodeIS8_EDpOT_),
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt8_Rb_treeINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt4pairIKS5_S5_ESt10_Select1stIS8_ESt4lessIS5_ESaIS8_EE14_M_create_nodeIJRKSt21piecewise_construct_tSt5tupleIJRS7_EESJ_IJEEEEEPSt13_Rb_tree_nodeIS8_EDpOT_),
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt8_Rb_treeINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt4pairIKS5_S5_ESt10_Select1stIS8_ESt4lessIS5_ESaIS8_EE14_M_insert_nodeEPSt18_Rb_tree_node_baseSG_PSt13_Rb_tree_nodeIS8_E),
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt8_Rb_treeINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt4pairIKS5_S5_ESt10_Select1stIS8_ESt4lessIS5_ESaIS8_EE22_M_emplace_hint_uniqueIJRKSt21piecewise_construct_tSt5tupleIJOS5_EESJ_IJEEEEESt17_Rb_tree_iteratorIS8_ESt23_Rb_tree_const_iteratorIS8_EDpOT_),
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt8_Rb_treeINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt4pairIKS5_S5_ESt10_Select1stIS8_ESt4lessIS5_ESaIS8_EE22_M_emplace_hint_uniqueIJRKSt21piecewise_construct_tSt5tupleIJRS7_EESJ_IJEEEEESt17_Rb_tree_iteratorIS8_ESt23_Rb_tree_const_iteratorIS8_EDpOT_),
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt8_Rb_treeINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt4pairIKS5_S5_ESt10_Select1stIS8_ESt4lessIS5_ESaIS8_EE24_M_get_insert_unique_posERS7_),
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt8_Rb_treeINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt4pairIKS5_S5_ESt10_Select1stIS8_ESt4lessIS5_ESaIS8_EE29_M_get_insert_hint_unique_posESt23_Rb_tree_const_iteratorIS8_ERS7_),
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt8_Rb_treeINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt4pairIKS5_S5_ESt10_Select1stIS8_ESt4lessIS5_ESaIS8_EE4findERS7_),
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt8_Rb_treeINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt4pairIKS5_S5_ESt10_Select1stIS8_ESt4lessIS5_ESaIS8_EE8_M_eraseEPSt13_Rb_tree_nodeIS8_E),
|
||||
|
||||
// std::map<string,string>::operator[] + its map-node piecewise-construct path
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES5_St4lessIS5_ESaISt4pairIKS5_S5_EEEixEOS5_),
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES5_St4lessIS5_ESaISt4pairIKS5_S5_EEEixERS9_),
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt4pairIKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES5_EC1IJRS6_EJEEESt21piecewise_construct_tSt5tupleIJDpT_EESB_IJDpT0_EE),
|
||||
{ "_ZSt19piecewise_construct", (void*)&std::piecewise_construct },
|
||||
|
||||
// std::shared_ptr<T> control block - generic; see the comment above assign_shared_count_atomic
|
||||
// for why the raw-pointer constructor itself is deliberately not registered here.
|
||||
{ "_ZNSt14__shared_countILN9__gnu_cxx12_Lock_policyE1EEaSERKS2_", (void*)&assign_shared_count_atomic },
|
||||
{ "_ZNSt14__shared_countILN9__gnu_cxx12_Lock_policyE2EEaSERKS2_", (void*)&assign_shared_count_mutex },
|
||||
DEFINE_MODULE_SYMBOL(_ZTVSt16_Sp_counted_baseILN9__gnu_cxx12_Lock_policyE1EE),
|
||||
DEFINE_MODULE_SYMBOL(_ZTVSt16_Sp_counted_baseILN9__gnu_cxx12_Lock_policyE2EE),
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt16_Sp_counted_baseILN9__gnu_cxx12_Lock_policyE1EE10_M_destroyEv),
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt16_Sp_counted_baseILN9__gnu_cxx12_Lock_policyE1EE10_M_releaseEv),
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt16_Sp_counted_baseILN9__gnu_cxx12_Lock_policyE1EE19_M_release_last_useEv),
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt16_Sp_counted_baseILN9__gnu_cxx12_Lock_policyE2EE10_M_destroyEv),
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt16_Sp_counted_baseILN9__gnu_cxx12_Lock_policyE2EE10_M_releaseEv),
|
||||
DEFINE_MODULE_SYMBOL(_ZNSt16_Sp_counted_baseILN9__gnu_cxx12_Lock_policyE2EE19_M_release_last_useEv),
|
||||
|
||||
// std::function<int(char*, unsigned int)>
|
||||
{ "_ZNKSt8functionIFiPcjEEclES0_j", (void*)&call_char_buffer_fn },
|
||||
{ "_ZNSt8functionIFiPcjEE4swapERS2_", (void*)&swap_char_buffer_fn },
|
||||
{ "_ZNSt8functionIFiPcjEEC1ERKS2_", (void*)&construct_char_buffer_fn_copy },
|
||||
{ "_ZNSt8functionIFiPcjEEaSEDn", (void*)&assign_char_buffer_fn_nullptr },
|
||||
|
||||
// Misc algorithm/iterator template instantiations
|
||||
{ "_ZSt14__copy_move_a2ILb0EPPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES7_S7_ET2_T0_T1_S8_", (void*)©_move_a2_string_ptr },
|
||||
{ "_ZSt14__copy_move_a2ILb0EPPcS1_S1_ET2_T0_T1_S2_", (void*)©_move_a2_char_ptr },
|
||||
{ "_ZSt14__copy_move_a2ILb0EPPdS1_S1_ET2_T0_T1_S2_", (void*)©_move_a2_double_ptr },
|
||||
{ "_ZSt14__relocate_a_1IPSt4pairINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbES8_SaIS7_EET0_T_SB_SA_RT1_", (void*)&relocate_string_bool_pairs },
|
||||
{ "_ZSt23__copy_move_backward_a2ILb0EPPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES7_ET1_T0_S9_S8_", (void*)©_move_backward_a2_string_ptr },
|
||||
{ "_ZSt23__copy_move_backward_a2ILb0EPPcS1_ET1_T0_S3_S2_", (void*)©_move_backward_a2_char_ptr },
|
||||
{ "_ZSt23__copy_move_backward_a2ILb0EPPdS1_ET1_T0_S3_S2_", (void*)©_move_backward_a2_double_ptr },
|
||||
{ "_ZSt23__copy_move_backward_a2ILb1EPSt4pairINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbES8_ET1_T0_SA_S9_", (void*)&move_backward_string_bool_pairs },
|
||||
{ "_ZSt3maxIsET_St16initializer_listIS0_E", (void*)&max_short_init_list },
|
||||
{ "_ZSt3minIsET_St16initializer_listIS0_E", (void*)&min_short_init_list },
|
||||
{ "_ZSt9__advanceIPPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiEvRT_T0_St26random_access_iterator_tag", (void*)&advance_string_ptr_ptr },
|
||||
{ "_ZSt9__advanceIPPciEvRT_T0_St26random_access_iterator_tag", (void*)&advance_char_ptr_ptr },
|
||||
{ "_ZSt9__advanceIPPdiEvRT_T0_St26random_access_iterator_tag", (void*)&advance_double_ptr_ptr },
|
||||
{ "_ZSt9iter_swapIN9__gnu_cxx17__normal_iteratorIPSt4pairINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbESt6vectorIS9_SaIS9_EEEESE_EvT_T0_", (void*)&iter_swap_string_bool_pair_vector },
|
||||
{ "_ZSt9transformIN9__gnu_cxx17__normal_iteratorIPcNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEES9_PFiiEET0_T_SD_SC_T1_", (void*)&transform_char_to_upper },
|
||||
{ "_ZSt4swapISt9_Any_dataENSt9enable_ifIXsrSt6__and_IJSt6__not_ISt15__is_tuple_likeIT_EESt21is_move_constructibleIS5_ESt18is_move_assignableIS5_EEE5valueEvE4typeERS5_SF_", (void*)&swap_any_data },
|
||||
#endif
|
||||
#endif // TT_CPP_SYMBOLS_AVAILABLE
|
||||
MODULE_SYMBOL_TERMINATOR
|
||||
|
||||
11
Modules/font-module/CMakeLists.txt
Normal file
11
Modules/font-module/CMakeLists.txt
Normal file
@ -0,0 +1,11 @@
|
||||
cmake_minimum_required(VERSION 3.20)
|
||||
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/../../Buildscripts/module.cmake")
|
||||
|
||||
file(GLOB_RECURSE SOURCE_FILES "source/*.c*")
|
||||
|
||||
tactility_add_module(font-module
|
||||
SRCS ${SOURCE_FILES}
|
||||
INCLUDE_DIRS include/
|
||||
REQUIRES TactilityKernel
|
||||
)
|
||||
32
Modules/font-module/Kconfig
Normal file
32
Modules/font-module/Kconfig
Normal file
@ -0,0 +1,32 @@
|
||||
menu "Fonts"
|
||||
config TT_FONT_IBMPLEXMONO_12
|
||||
bool "IBM Plex Mono 12 (7x12)"
|
||||
default n
|
||||
help
|
||||
Include the ibmplexmono12 bitmap font.
|
||||
config TT_FONT_IBMPLEXMONO_14
|
||||
bool "IBM Plex Mono 14 (8x14)"
|
||||
default n
|
||||
help
|
||||
Include the ibmplexmono14 bitmap font.
|
||||
config TT_FONT_IBMPLEXMONO_16
|
||||
bool "IBM Plex Mono 16 (10x16)"
|
||||
default n
|
||||
help
|
||||
Include the ibmplexmono16 bitmap font.
|
||||
config TT_FONT_IBMPLEXMONO_18
|
||||
bool "IBM Plex Mono 18 (11x18)"
|
||||
default n
|
||||
help
|
||||
Include the ibmplexmono18 bitmap font.
|
||||
config TT_FONT_IBMPLEXMONO_24
|
||||
bool "IBM Plex Mono 24 (14x24)"
|
||||
default n
|
||||
help
|
||||
Include the ibmplexmono24 bitmap font.
|
||||
config TT_FONT_IBMPLEXMONO_28
|
||||
bool "IBM Plex Mono 28 (17x28)"
|
||||
default n
|
||||
help
|
||||
Include the ibmplexmono28 bitmap font.
|
||||
endmenu
|
||||
195
Modules/font-module/LICENSE-Apache-2.0.md
Normal file
195
Modules/font-module/LICENSE-Apache-2.0.md
Normal file
@ -0,0 +1,195 @@
|
||||
Apache License
|
||||
==============
|
||||
|
||||
_Version 2.0, January 2004_
|
||||
_<<http://www.apache.org/licenses/>>_
|
||||
|
||||
### Terms and Conditions for use, reproduction, and distribution
|
||||
|
||||
#### 1. Definitions
|
||||
|
||||
“License” shall mean the terms and conditions for use, reproduction, and
|
||||
distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
“Licensor” shall mean the copyright owner or entity authorized by the copyright
|
||||
owner that is granting the License.
|
||||
|
||||
“Legal Entity” shall mean the union of the acting entity and all other entities
|
||||
that control, are controlled by, or are under common control with that entity.
|
||||
For the purposes of this definition, “control” means **(i)** the power, direct or
|
||||
indirect, to cause the direction or management of such entity, whether by
|
||||
contract or otherwise, or **(ii)** ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or **(iii)** beneficial ownership of such entity.
|
||||
|
||||
“You” (or “Your”) shall mean an individual or Legal Entity exercising
|
||||
permissions granted by this License.
|
||||
|
||||
“Source” form shall mean the preferred form for making modifications, including
|
||||
but not limited to software source code, documentation source, and configuration
|
||||
files.
|
||||
|
||||
“Object” form shall mean any form resulting from mechanical transformation or
|
||||
translation of a Source form, including but not limited to compiled object code,
|
||||
generated documentation, and conversions to other media types.
|
||||
|
||||
“Work” shall mean the work of authorship, whether in Source or Object form, made
|
||||
available under the License, as indicated by a copyright notice that is included
|
||||
in or attached to the work (an example is provided in the Appendix below).
|
||||
|
||||
“Derivative Works” shall mean any work, whether in Source or Object form, that
|
||||
is based on (or derived from) the Work and for which the editorial revisions,
|
||||
annotations, elaborations, or other modifications represent, as a whole, an
|
||||
original work of authorship. For the purposes of this License, Derivative Works
|
||||
shall not include works that remain separable from, or merely link (or bind by
|
||||
name) to the interfaces of, the Work and Derivative Works thereof.
|
||||
|
||||
“Contribution” shall mean any work of authorship, including the original version
|
||||
of the Work and any modifications or additions to that Work or Derivative Works
|
||||
thereof, that is intentionally submitted to Licensor for inclusion in the Work
|
||||
by the copyright owner or by an individual or Legal Entity authorized to submit
|
||||
on behalf of the copyright owner. For the purposes of this definition,
|
||||
“submitted” means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems, and
|
||||
issue tracking systems that are managed by, or on behalf of, the Licensor for
|
||||
the purpose of discussing and improving the Work, but excluding communication
|
||||
that is conspicuously marked or otherwise designated in writing by the copyright
|
||||
owner as “Not a Contribution.”
|
||||
|
||||
“Contributor” shall mean Licensor and any individual or Legal Entity on behalf
|
||||
of whom a Contribution has been received by Licensor and subsequently
|
||||
incorporated within the Work.
|
||||
|
||||
#### 2. Grant of Copyright License
|
||||
|
||||
Subject to the terms and conditions of this License, each Contributor hereby
|
||||
grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
|
||||
irrevocable copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the Work and such
|
||||
Derivative Works in Source or Object form.
|
||||
|
||||
#### 3. Grant of Patent License
|
||||
|
||||
Subject to the terms and conditions of this License, each Contributor hereby
|
||||
grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
|
||||
irrevocable (except as stated in this section) patent license to make, have
|
||||
made, use, offer to sell, sell, import, and otherwise transfer the Work, where
|
||||
such license applies only to those patent claims licensable by such Contributor
|
||||
that are necessarily infringed by their Contribution(s) alone or by combination
|
||||
of their Contribution(s) with the Work to which such Contribution(s) was
|
||||
submitted. If You institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work or a
|
||||
Contribution incorporated within the Work constitutes direct or contributory
|
||||
patent infringement, then any patent licenses granted to You under this License
|
||||
for that Work shall terminate as of the date such litigation is filed.
|
||||
|
||||
#### 4. Redistribution
|
||||
|
||||
You may reproduce and distribute copies of the Work or Derivative Works thereof
|
||||
in any medium, with or without modifications, and in Source or Object form,
|
||||
provided that You meet the following conditions:
|
||||
|
||||
* **(a)** You must give any other recipients of the Work or Derivative Works a copy of
|
||||
this License; and
|
||||
* **(b)** You must cause any modified files to carry prominent notices stating that You
|
||||
changed the files; and
|
||||
* **(c)** You must retain, in the Source form of any Derivative Works that You distribute,
|
||||
all copyright, patent, trademark, and attribution notices from the Source form
|
||||
of the Work, excluding those notices that do not pertain to any part of the
|
||||
Derivative Works; and
|
||||
* **(d)** If the Work includes a “NOTICE” text file as part of its distribution, then any
|
||||
Derivative Works that You distribute must include a readable copy of the
|
||||
attribution notices contained within such NOTICE file, excluding those notices
|
||||
that do not pertain to any part of the Derivative Works, in at least one of the
|
||||
following places: within a NOTICE text file distributed as part of the
|
||||
Derivative Works; within the Source form or documentation, if provided along
|
||||
with the Derivative Works; or, within a display generated by the Derivative
|
||||
Works, if and wherever such third-party notices normally appear. The contents of
|
||||
the NOTICE file are for informational purposes only and do not modify the
|
||||
License. You may add Your own attribution notices within Derivative Works that
|
||||
You distribute, alongside or as an addendum to the NOTICE text from the Work,
|
||||
provided that such additional attribution notices cannot be construed as
|
||||
modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and may provide
|
||||
additional or different license terms and conditions for use, reproduction, or
|
||||
distribution of Your modifications, or for any such Derivative Works as a whole,
|
||||
provided Your use, reproduction, and distribution of the Work otherwise complies
|
||||
with the conditions stated in this License.
|
||||
|
||||
#### 5. Submission of Contributions
|
||||
|
||||
Unless You explicitly state otherwise, any Contribution intentionally submitted
|
||||
for inclusion in the Work by You to the Licensor shall be under the terms and
|
||||
conditions of this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify the terms of
|
||||
any separate license agreement you may have executed with Licensor regarding
|
||||
such Contributions.
|
||||
|
||||
#### 6. Trademarks
|
||||
|
||||
This License does not grant permission to use the trade names, trademarks,
|
||||
service marks, or product names of the Licensor, except as required for
|
||||
reasonable and customary use in describing the origin of the Work and
|
||||
reproducing the content of the NOTICE file.
|
||||
|
||||
#### 7. Disclaimer of Warranty
|
||||
|
||||
Unless required by applicable law or agreed to in writing, Licensor provides the
|
||||
Work (and each Contributor provides its Contributions) on an “AS IS” BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
|
||||
including, without limitation, any warranties or conditions of TITLE,
|
||||
NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are
|
||||
solely responsible for determining the appropriateness of using or
|
||||
redistributing the Work and assume any risks associated with Your exercise of
|
||||
permissions under this License.
|
||||
|
||||
#### 8. Limitation of Liability
|
||||
|
||||
In no event and under no legal theory, whether in tort (including negligence),
|
||||
contract, or otherwise, unless required by applicable law (such as deliberate
|
||||
and grossly negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special, incidental,
|
||||
or consequential damages of any character arising as a result of this License or
|
||||
out of the use or inability to use the Work (including but not limited to
|
||||
damages for loss of goodwill, work stoppage, computer failure or malfunction, or
|
||||
any and all other commercial damages or losses), even if such Contributor has
|
||||
been advised of the possibility of such damages.
|
||||
|
||||
#### 9. Accepting Warranty or Additional Liability
|
||||
|
||||
While redistributing the Work or Derivative Works thereof, You may choose to
|
||||
offer, and charge a fee for, acceptance of support, warranty, indemnity, or
|
||||
other liability obligations and/or rights consistent with this License. However,
|
||||
in accepting such obligations, You may act only on Your own behalf and on Your
|
||||
sole responsibility, not on behalf of any other Contributor, and only if You
|
||||
agree to indemnify, defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason of your
|
||||
accepting any such warranty or additional liability.
|
||||
|
||||
_END OF TERMS AND CONDITIONS_
|
||||
|
||||
### APPENDIX: How to apply the Apache License to your work
|
||||
|
||||
To apply the Apache License to your work, attach the following boilerplate
|
||||
notice, with the fields enclosed by brackets `[]` replaced with your own
|
||||
identifying information. (Don't include the brackets!) The text should be
|
||||
enclosed in the appropriate comment syntax for the file format. We also
|
||||
recommend that a file or class name and description of purpose be included on
|
||||
the same “printed page” as the copyright notice for easier identification within
|
||||
third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
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.
|
||||
|
||||
29
Modules/font-module/include/font/font.h
Normal file
29
Modules/font-module/include/font/font.h
Normal file
@ -0,0 +1,29 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* A fixed-width bitmap font: monospaced glyphs covering a contiguous codepoint range, one row of
|
||||
* glyph_bytes_per_row bytes per pixel row (bit 7 of the first byte is the leftmost pixel).
|
||||
*
|
||||
* glyph_bitmap is indexed as glyph_bitmap[(ch - first_codepoint) * glyph_height *
|
||||
* glyph_bytes_per_row + row * glyph_bytes_per_row + byte]; a codepoint outside
|
||||
* [first_codepoint, last_codepoint] has no entry.
|
||||
*/
|
||||
typedef struct FixedWidthFont {
|
||||
uint8_t glyph_width;
|
||||
uint8_t glyph_height;
|
||||
uint8_t glyph_bytes_per_row;
|
||||
uint8_t first_codepoint;
|
||||
uint8_t last_codepoint;
|
||||
const uint8_t* glyph_bitmap;
|
||||
} FixedWidthFont;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
10
Modules/font-module/include/font/fonts.h
Normal file
10
Modules/font-module/include/font/fonts.h
Normal file
@ -0,0 +1,10 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
#pragma once
|
||||
|
||||
// Every font generate-all.py produces, so a caller can pull them all in with one include.
|
||||
#include <font/ibmplexmono12.h>
|
||||
#include <font/ibmplexmono14.h>
|
||||
#include <font/ibmplexmono16.h>
|
||||
#include <font/ibmplexmono18.h>
|
||||
#include <font/ibmplexmono24.h>
|
||||
#include <font/ibmplexmono28.h>
|
||||
14
Modules/font-module/include/font/ibmplexmono12.h
Normal file
14
Modules/font-module/include/font/ibmplexmono12.h
Normal file
@ -0,0 +1,14 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
#pragma once
|
||||
|
||||
#include <font/font.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern const FixedWidthFont ibmplexmono_12_font;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
14
Modules/font-module/include/font/ibmplexmono14.h
Normal file
14
Modules/font-module/include/font/ibmplexmono14.h
Normal file
@ -0,0 +1,14 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
#pragma once
|
||||
|
||||
#include <font/font.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern const FixedWidthFont ibmplexmono_14_font;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
14
Modules/font-module/include/font/ibmplexmono16.h
Normal file
14
Modules/font-module/include/font/ibmplexmono16.h
Normal file
@ -0,0 +1,14 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
#pragma once
|
||||
|
||||
#include <font/font.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern const FixedWidthFont ibmplexmono_16_font;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
14
Modules/font-module/include/font/ibmplexmono18.h
Normal file
14
Modules/font-module/include/font/ibmplexmono18.h
Normal file
@ -0,0 +1,14 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
#pragma once
|
||||
|
||||
#include <font/font.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern const FixedWidthFont ibmplexmono_18_font;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
14
Modules/font-module/include/font/ibmplexmono24.h
Normal file
14
Modules/font-module/include/font/ibmplexmono24.h
Normal file
@ -0,0 +1,14 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
#pragma once
|
||||
|
||||
#include <font/font.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern const FixedWidthFont ibmplexmono_24_font;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
14
Modules/font-module/include/font/ibmplexmono28.h
Normal file
14
Modules/font-module/include/font/ibmplexmono28.h
Normal file
@ -0,0 +1,14 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
#pragma once
|
||||
|
||||
#include <font/font.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern const FixedWidthFont ibmplexmono_28_font;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
14
Modules/font-module/include/font/module.h
Normal file
14
Modules/font-module/include/font/module.h
Normal file
@ -0,0 +1,14 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
#pragma once
|
||||
|
||||
#include <tactility/module.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern struct Module font_module;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
34
Modules/font-module/include/font/render.h
Normal file
34
Modules/font-module/include/font/render.h
Normal file
@ -0,0 +1,34 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
#pragma once
|
||||
|
||||
#include <font/font.h>
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Renders one character's glyph into buffer, a caller-owned RGB565 pixel buffer laid out as
|
||||
* `stride` pixels per row. The glyph occupies a font->glyph_width x font->glyph_height box
|
||||
* starting at buffer's first pixel - buffer must already point at that box's top-left corner
|
||||
* within the larger destination image. A character outside [first_codepoint, last_codepoint]
|
||||
* renders as a space.
|
||||
*/
|
||||
void font_render_char(const FixedWidthFont* font, char ch, uint16_t fg, uint16_t bg, uint16_t* buffer, int stride);
|
||||
|
||||
/**
|
||||
* Renders a null-terminated string left to right, one font_render_char() call per character,
|
||||
* each advanced by font->glyph_width pixels from the last. buffer must point at the first
|
||||
* character's top-left corner; the string occupies strlen(str) * font->glyph_width x
|
||||
* font->glyph_height pixels in total.
|
||||
*/
|
||||
void font_render_string(const FixedWidthFont* font, const char* str, uint16_t fg, uint16_t bg, uint16_t* buffer, int stride);
|
||||
|
||||
/** Pixel width font_render_string() would occupy for str: strlen(str) * font->glyph_width. */
|
||||
int font_get_string_length(const FixedWidthFont* font, const char* str);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
1
Modules/font-module/scripts/.gitignore
vendored
Normal file
1
Modules/font-module/scripts/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
*.ttf
|
||||
38
Modules/font-module/scripts/generate-all.py
Normal file
38
Modules/font-module/scripts/generate-all.py
Normal file
@ -0,0 +1,38 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Generates bitmap font files (see generate.py) for a fixed set of glyph heights, from the same
|
||||
monospace TTF.
|
||||
|
||||
Requires the freetype-py package: pip install freetype-py
|
||||
|
||||
Usage:
|
||||
python3 generate-all.py
|
||||
"""
|
||||
|
||||
import importlib.util
|
||||
import os
|
||||
|
||||
MONO_URL = "https://github.com/google/fonts/raw/refs/heads/main/ofl/ibmplexmono/IBMPlexMono-Regular.ttf"
|
||||
SIZES = [12, 14, 16, 18, 24, 28]
|
||||
|
||||
spec = importlib.util.spec_from_file_location("generate_font", os.path.join(os.path.dirname(__file__), "generate.py"))
|
||||
generate_font = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(generate_font)
|
||||
|
||||
|
||||
def write_fonts_header(outputs: list):
|
||||
path = os.path.join(generate_font.INCLUDE_DIR, "fonts.h")
|
||||
print(f"Generating {path}")
|
||||
with open(path, "w") as f:
|
||||
f.write("// SPDX-License-Identifier: Apache-2.0\n")
|
||||
f.write("#pragma once\n\n")
|
||||
f.write("// Every font generate-all.py produces, so a caller can pull them all in with one include.\n")
|
||||
for output in outputs:
|
||||
f.write(f"#include <font/{output}.h>\n")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
outputs = [f"ibmplexmono{size}" for size in SIZES]
|
||||
for output, size in zip(outputs, SIZES):
|
||||
generate_font.generate(MONO_URL, size, output)
|
||||
write_fonts_header(outputs)
|
||||
190
Modules/font-module/scripts/generate.py
Normal file
190
Modules/font-module/scripts/generate.py
Normal file
@ -0,0 +1,190 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Downloads a monospace TTF and rasterizes it into a FixedWidthFont (see include/font/font.h) covering:
|
||||
|
||||
- U+0020-U+007E
|
||||
- Height rows per glyph
|
||||
- Each row ceil(width / 8)
|
||||
- Bytes (bit 7 of the first byte = leftmost pixel)
|
||||
Plus a header declaring the font. Glyph width is the font's own natural advance width at the given size.
|
||||
|
||||
Requires the freetype-py package: pip install freetype-py
|
||||
|
||||
Usage:
|
||||
python3 generate.py --url URL --size SIZE --output NAME
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import math
|
||||
import os
|
||||
import re
|
||||
import urllib.request
|
||||
|
||||
import freetype
|
||||
|
||||
GLYPH_FIRST = 0x20
|
||||
GLYPH_LAST = 0x7E
|
||||
|
||||
MODULE_DIR = os.path.join(os.path.dirname(__file__), "..")
|
||||
SOURCE_DIR = os.path.join(MODULE_DIR, "source")
|
||||
INCLUDE_DIR = os.path.join(MODULE_DIR, "include", "font")
|
||||
|
||||
|
||||
def download_file(url: str, filename: str):
|
||||
if not os.path.exists(filename):
|
||||
print(f"Downloading {filename} from {url}")
|
||||
urllib.request.urlretrieve(url, filename)
|
||||
else:
|
||||
print(f"{filename} already exists, skipping download.")
|
||||
|
||||
|
||||
def measure_advance_width(face: freetype.Face, size: int) -> float:
|
||||
"""Natural advance width (px) of the font at `size` px tall, isotropic DPI."""
|
||||
face.set_char_size(0, size * 64, 72, 72)
|
||||
face.load_char("M", freetype.FT_LOAD_DEFAULT)
|
||||
return face.glyph.advance.x / 64
|
||||
|
||||
|
||||
def get_bit(bitmap, x: int, y: int) -> bool:
|
||||
if x < 0 or x >= bitmap.width or y < 0 or y >= bitmap.rows:
|
||||
return False
|
||||
byte = bitmap.buffer[y * abs(bitmap.pitch) + x // 8]
|
||||
return bool((byte >> (7 - x % 8)) & 1)
|
||||
|
||||
|
||||
def measure_baseline(face: freetype.Face, cell_height: int) -> int:
|
||||
"""
|
||||
Row (from the cell top) the baseline sits on.
|
||||
|
||||
face.size.ascender/descender are line-spacing metrics, not ink extents - many fonts set them
|
||||
taller than the glyphs actually are, which pushes the baseline row below the bottom of the
|
||||
cell and clips it off entirely. Measuring the real cap-height ('A') and descender depth ('g')
|
||||
at this pixel size keeps both in view instead.
|
||||
"""
|
||||
face.load_char("A", freetype.FT_LOAD_RENDER | freetype.FT_LOAD_TARGET_MONO)
|
||||
cap_top = face.glyph.bitmap_top
|
||||
face.load_char("g", freetype.FT_LOAD_RENDER | freetype.FT_LOAD_TARGET_MONO)
|
||||
descender = face.glyph.bitmap.rows - face.glyph.bitmap_top
|
||||
|
||||
max_baseline = cell_height - 1 - descender
|
||||
if max_baseline >= cap_top:
|
||||
baseline = cap_top + (max_baseline - cap_top) // 2
|
||||
else:
|
||||
# Cap height and descender depth don't both fit in cell_height rows (common at very
|
||||
# small sizes) - keep the cap/baseline row intact and let the descender clip instead.
|
||||
baseline = cap_top
|
||||
return min(max(baseline, 0), cell_height - 1)
|
||||
|
||||
|
||||
def render_glyph(face: freetype.Face, codepoint: int, cell_width: int, cell_height: int, baseline_y: int, bytes_per_row: int) -> bytearray:
|
||||
face.load_char(chr(codepoint), freetype.FT_LOAD_RENDER | freetype.FT_LOAD_TARGET_MONO)
|
||||
glyph = face.glyph
|
||||
bitmap = glyph.bitmap
|
||||
|
||||
out = bytearray(cell_height * bytes_per_row)
|
||||
for row in range(cell_height):
|
||||
src_y = row - baseline_y + glyph.bitmap_top
|
||||
for col in range(cell_width):
|
||||
src_x = col - glyph.bitmap_left
|
||||
if get_bit(bitmap, src_x, src_y):
|
||||
out[row * bytes_per_row + col // 8] |= 1 << (7 - col % 8)
|
||||
return out
|
||||
|
||||
|
||||
def split_name(output: str) -> tuple:
|
||||
"""'ibmplexmono14' -> ('ibmplexmono', '14'), so identifiers can put an underscore between the
|
||||
font name and its size instead of running them together."""
|
||||
match = re.match(r"^([a-zA-Z]+)(\d+)$", output)
|
||||
if not match:
|
||||
raise ValueError(f"'{output}' must be a name followed by digits, e.g. 'ibmplexmono14'")
|
||||
return match.group(1), match.group(2)
|
||||
|
||||
|
||||
def escape_char(ch: str) -> str:
|
||||
if ch == "\\":
|
||||
return "\\\\"
|
||||
if ch == '"':
|
||||
return '\\"'
|
||||
return ch
|
||||
|
||||
|
||||
def write_c_file(path: str, output: str, width: int, height: int, bytes_per_row: int, glyphs: dict):
|
||||
glyph_count = GLYPH_LAST - GLYPH_FIRST + 1
|
||||
glyph_bytes = height * bytes_per_row
|
||||
total_bytes = glyph_count * glyph_bytes
|
||||
name, size_digits = split_name(output)
|
||||
bitmap_name = f"{output}_glyph_bitmap"
|
||||
struct_name = f"{name}_{size_digits}_font"
|
||||
config_macro = f"CONFIG_TT_FONT_{name.upper()}_{size_digits}"
|
||||
with open(path, "w") as f:
|
||||
f.write(f"/*\n * {os.path.basename(path)} - {output} FixedWidthFont\n")
|
||||
f.write(f" *\n * Rasterized from a TTF with Modules/font-module/scripts/generate.py.\n")
|
||||
f.write(f" * Each glyph is {width} pixels wide and {height} pixels tall, stored as {height} rows of\n")
|
||||
f.write(f" * {bytes_per_row} byte{'s' if bytes_per_row != 1 else ''} each (bit 7 of the first byte = leftmost pixel).\n */\n\n")
|
||||
f.write(f"#include <font/{output}.h>\n\n")
|
||||
f.write("#ifdef ESP_PLATFORM\n")
|
||||
f.write("#include <sdkconfig.h>\n")
|
||||
f.write("#endif\n\n")
|
||||
f.write(f"// See Modules/font-module/Kconfig: undefined (POSIX, or an ESP-IDF build predating\n")
|
||||
f.write(f"// this font's Kconfig entry) is treated the same as enabled.\n")
|
||||
f.write(f"#if !defined({config_macro}) || {config_macro}\n\n")
|
||||
f.write(f"// Glyph bitmap data: {glyph_count} characters (0x20-0x7E), {glyph_bytes} bytes each = {total_bytes} bytes\n")
|
||||
f.write(f"static const uint8_t {bitmap_name}[] = {{\n")
|
||||
for cp in range(GLYPH_FIRST, GLYPH_LAST + 1):
|
||||
f.write(f' /* U+{cp:04X} "{escape_char(chr(cp))}" */\n')
|
||||
data = glyphs[cp]
|
||||
f.write(" " + ", ".join(f"0x{b:X}" for b in data) + ",\n")
|
||||
f.write("};\n\n")
|
||||
f.write(f"const FixedWidthFont {struct_name} = {{\n")
|
||||
f.write(f" .glyph_width = {width},\n")
|
||||
f.write(f" .glyph_height = {height},\n")
|
||||
f.write(f" .glyph_bytes_per_row = {bytes_per_row},\n")
|
||||
f.write(f" .first_codepoint = 0x{GLYPH_FIRST:02X},\n")
|
||||
f.write(f" .last_codepoint = 0x{GLYPH_LAST:02X},\n")
|
||||
f.write(f" .glyph_bitmap = {bitmap_name},\n")
|
||||
f.write("};\n\n")
|
||||
f.write(f"#endif // {config_macro}\n")
|
||||
|
||||
|
||||
def write_h_file(path: str, output: str):
|
||||
name, size_digits = split_name(output)
|
||||
struct_name = f"{name}_{size_digits}_font"
|
||||
with open(path, "w") as f:
|
||||
f.write("// SPDX-License-Identifier: Apache-2.0\n")
|
||||
f.write("#pragma once\n\n")
|
||||
f.write("#include <font/font.h>\n\n")
|
||||
f.write("#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n")
|
||||
f.write(f"extern const FixedWidthFont {struct_name};\n\n")
|
||||
f.write("#ifdef __cplusplus\n}\n#endif\n")
|
||||
|
||||
|
||||
def generate(mono_url: str, size: int, output: str):
|
||||
ttf_filename = os.path.basename(mono_url)
|
||||
download_file(mono_url, ttf_filename)
|
||||
|
||||
face = freetype.Face(ttf_filename)
|
||||
natural_width = measure_advance_width(face, size)
|
||||
if natural_width <= 0:
|
||||
raise RuntimeError("Font reported a non-positive advance width")
|
||||
width = round(natural_width)
|
||||
|
||||
bytes_per_row = math.ceil(width / 8)
|
||||
baseline_y = measure_baseline(face, size)
|
||||
glyphs = {cp: render_glyph(face, cp, width, size, baseline_y, bytes_per_row) for cp in range(GLYPH_FIRST, GLYPH_LAST + 1)}
|
||||
|
||||
c_path = os.path.join(SOURCE_DIR, f"{output}.c")
|
||||
h_path = os.path.join(INCLUDE_DIR, f"{output}.h")
|
||||
print(f"Generating {h_path}")
|
||||
write_h_file(h_path, output)
|
||||
print(f"Generating {c_path}")
|
||||
write_c_file(c_path, output, width, size, bytes_per_row, glyphs)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument("--url", required=True, help="URL of the monospace TTF to download")
|
||||
parser.add_argument("--size", type=int, required=True, help="Glyph height in pixels")
|
||||
parser.add_argument("--output", required=True, help="Output file base name (no extension)")
|
||||
args = parser.parse_args()
|
||||
|
||||
generate(args.url, args.size, args.output)
|
||||
222
Modules/font-module/source/ibmplexmono12.c
Normal file
222
Modules/font-module/source/ibmplexmono12.c
Normal file
@ -0,0 +1,222 @@
|
||||
/*
|
||||
* ibmplexmono12.c - ibmplexmono12 FixedWidthFont
|
||||
*
|
||||
* Rasterized from a TTF with Modules/font-module/scripts/generate.py.
|
||||
* Each glyph is 7 pixels wide and 12 pixels tall, stored as 12 rows of
|
||||
* 1 byte each (bit 7 of the first byte = leftmost pixel).
|
||||
*/
|
||||
|
||||
#include <font/ibmplexmono12.h>
|
||||
|
||||
#ifdef ESP_PLATFORM
|
||||
#include <sdkconfig.h>
|
||||
#endif
|
||||
|
||||
// See Modules/font-module/Kconfig: undefined (POSIX, or an ESP-IDF build predating
|
||||
// this font's Kconfig entry) is treated the same as enabled.
|
||||
#if !defined(CONFIG_TT_FONT_IBMPLEXMONO_12) || CONFIG_TT_FONT_IBMPLEXMONO_12
|
||||
|
||||
// Glyph bitmap data: 95 characters (0x20-0x7E), 12 bytes each = 1140 bytes
|
||||
static const uint8_t ibmplexmono12_glyph_bitmap[] = {
|
||||
/* U+0020 " " */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0021 "!" */
|
||||
0x10, 0x10, 0x10, 0x10, 0x10, 0x0, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0022 "\"" */
|
||||
0x28, 0x28, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0023 "#" */
|
||||
0x34, 0x28, 0x6E, 0x28, 0x28, 0xEC, 0x48, 0x50, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0024 "$" */
|
||||
0x38, 0x56, 0x50, 0x70, 0x1C, 0x12, 0xD4, 0x3C, 0x10, 0x0, 0x0, 0x0,
|
||||
/* U+0025 "%" */
|
||||
0x62, 0x94, 0x94, 0x68, 0x2C, 0x52, 0x52, 0x8C, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0026 "&" */
|
||||
0x30, 0x48, 0x40, 0x26, 0x74, 0x98, 0x8C, 0x76, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0027 "'" */
|
||||
0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0028 "(" */
|
||||
0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x10, 0x10, 0xC, 0x0, 0x0,
|
||||
/* U+0029 ")" */
|
||||
0x20, 0x10, 0x10, 0x8, 0x8, 0x8, 0x10, 0x10, 0x20, 0x60, 0x0, 0x0,
|
||||
/* U+002A "*" */
|
||||
0x0, 0x10, 0x10, 0xFE, 0x10, 0x28, 0x44, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+002B "+" */
|
||||
0x0, 0x10, 0x10, 0x10, 0x7C, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+002C "," */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x10, 0x10, 0x20, 0x0, 0x0,
|
||||
/* U+002D "-" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x38, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+002E "." */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+002F "/" */
|
||||
0x4, 0x8, 0x8, 0x10, 0x10, 0x10, 0x20, 0x20, 0x40, 0x40, 0x0, 0x0,
|
||||
/* U+0030 "0" */
|
||||
0x38, 0x44, 0x44, 0x54, 0x54, 0x44, 0x44, 0x38, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0031 "1" */
|
||||
0x30, 0x70, 0x50, 0x10, 0x10, 0x10, 0x10, 0x7E, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0032 "2" */
|
||||
0x38, 0x44, 0x4, 0x4, 0x8, 0x30, 0x40, 0x7C, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0033 "3" */
|
||||
0x38, 0x44, 0x4, 0x38, 0xC, 0x4, 0xC4, 0x38, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0034 "4" */
|
||||
0x8, 0x18, 0x28, 0x48, 0x48, 0xFE, 0x8, 0x8, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0035 "5" */
|
||||
0x7C, 0x40, 0x40, 0x78, 0x44, 0x4, 0x44, 0x38, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0036 "6" */
|
||||
0x18, 0x20, 0x40, 0x78, 0x44, 0x44, 0x44, 0x38, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0037 "7" */
|
||||
0x7C, 0x44, 0x4, 0x8, 0x8, 0x10, 0x10, 0x20, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0038 "8" */
|
||||
0x3C, 0x44, 0x44, 0x38, 0x44, 0x44, 0x44, 0x38, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0039 "9" */
|
||||
0x38, 0x44, 0x44, 0x44, 0x3C, 0x4, 0x8, 0x30, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+003A ":" */
|
||||
0x0, 0x10, 0x10, 0x0, 0x0, 0x0, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+003B ";" */
|
||||
0x0, 0x10, 0x10, 0x0, 0x0, 0x0, 0x18, 0x10, 0x10, 0x20, 0x0, 0x0,
|
||||
/* U+003C "<" */
|
||||
0x0, 0x4, 0x8, 0x30, 0x40, 0x30, 0x8, 0x4, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+003D "=" */
|
||||
0x0, 0x0, 0x0, 0x7C, 0x0, 0x7C, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+003E ">" */
|
||||
0x0, 0x40, 0x20, 0x18, 0x4, 0x18, 0x20, 0x40, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+003F "?" */
|
||||
0x38, 0x44, 0x4, 0x18, 0x10, 0x0, 0x30, 0x30, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0040 "@" */
|
||||
0x38, 0x44, 0x5C, 0x54, 0x64, 0x64, 0x5C, 0x40, 0x38, 0x0, 0x0, 0x0,
|
||||
/* U+0041 "A" */
|
||||
0x10, 0x28, 0x28, 0x28, 0x44, 0x7C, 0x44, 0xC6, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0042 "B" */
|
||||
0x78, 0x44, 0x44, 0x78, 0x44, 0x44, 0x44, 0x7C, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0043 "C" */
|
||||
0x38, 0x44, 0x40, 0x40, 0x40, 0x40, 0x44, 0x38, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0044 "D" */
|
||||
0x78, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x78, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0045 "E" */
|
||||
0x7C, 0x40, 0x40, 0x7C, 0x40, 0x40, 0x40, 0x7C, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0046 "F" */
|
||||
0x7C, 0x40, 0x40, 0x7C, 0x40, 0x40, 0x40, 0x40, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0047 "G" */
|
||||
0x38, 0x44, 0x40, 0x40, 0x5C, 0x44, 0x44, 0x3C, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0048 "H" */
|
||||
0x44, 0x44, 0x44, 0x7C, 0x44, 0x44, 0x44, 0x44, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0049 "I" */
|
||||
0x7C, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x7C, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+004A "J" */
|
||||
0x3C, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4C, 0x38, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+004B "K" */
|
||||
0x46, 0x48, 0x58, 0x50, 0x78, 0x48, 0x44, 0x46, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+004C "L" */
|
||||
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x7C, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+004D "M" */
|
||||
0x44, 0x6C, 0x6C, 0x54, 0x54, 0x44, 0x44, 0x44, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+004E "N" */
|
||||
0x44, 0x64, 0x64, 0x54, 0x54, 0x4C, 0x4C, 0x4C, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+004F "O" */
|
||||
0x38, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x38, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0050 "P" */
|
||||
0x7C, 0x44, 0x44, 0x44, 0x7C, 0x40, 0x40, 0x40, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0051 "Q" */
|
||||
0x38, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x38, 0x10, 0x1C, 0x0, 0x0,
|
||||
/* U+0052 "R" */
|
||||
0x7C, 0x44, 0x44, 0x44, 0x7C, 0x48, 0x48, 0x46, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0053 "S" */
|
||||
0x38, 0x44, 0x40, 0x70, 0xC, 0x4, 0xC4, 0x38, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0054 "T" */
|
||||
0xFE, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0055 "U" */
|
||||
0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x38, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0056 "V" */
|
||||
0xC6, 0x44, 0x44, 0x44, 0x28, 0x28, 0x28, 0x10, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0057 "W" */
|
||||
0x82, 0x82, 0x94, 0xB4, 0x6C, 0x6C, 0x6C, 0x6C, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0058 "X" */
|
||||
0xC6, 0x44, 0x28, 0x10, 0x18, 0x28, 0x44, 0xC6, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0059 "Y" */
|
||||
0xC2, 0x44, 0x28, 0x28, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+005A "Z" */
|
||||
0x7C, 0x4, 0x8, 0x10, 0x30, 0x20, 0x40, 0xFC, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+005B "[" */
|
||||
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x1C, 0x0, 0x0,
|
||||
/* U+005C "\\" */
|
||||
0x40, 0x20, 0x20, 0x10, 0x10, 0x10, 0x8, 0x8, 0x8, 0x4, 0x0, 0x0,
|
||||
/* U+005D "]" */
|
||||
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x70, 0x0, 0x0,
|
||||
/* U+005E "^" */
|
||||
0x10, 0x28, 0x28, 0x44, 0x82, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+005F "_" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7C, 0x0, 0x0,
|
||||
/* U+0060 "`" */
|
||||
0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0061 "a" */
|
||||
0x0, 0x0, 0x38, 0x4C, 0x4, 0x7C, 0x44, 0x7E, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0062 "b" */
|
||||
0x40, 0x40, 0x58, 0x64, 0x44, 0x44, 0x44, 0x78, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0063 "c" */
|
||||
0x0, 0x0, 0x38, 0x44, 0x40, 0x40, 0x44, 0x38, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0064 "d" */
|
||||
0x4, 0x4, 0x34, 0x4C, 0x44, 0x44, 0x44, 0x3C, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0065 "e" */
|
||||
0x0, 0x0, 0x38, 0x44, 0x7C, 0x40, 0x44, 0x38, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0066 "f" */
|
||||
0x10, 0x10, 0x7C, 0x10, 0x10, 0x10, 0x10, 0x7C, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0067 "g" */
|
||||
0x0, 0x6, 0x38, 0x44, 0x44, 0x38, 0x40, 0x3C, 0x42, 0x7C, 0x0, 0x0,
|
||||
/* U+0068 "h" */
|
||||
0x40, 0x40, 0x58, 0x64, 0x44, 0x44, 0x44, 0x44, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0069 "i" */
|
||||
0x18, 0x0, 0x70, 0x10, 0x10, 0x10, 0x10, 0x7C, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+006A "j" */
|
||||
0x8, 0x0, 0x78, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x78, 0x0, 0x0,
|
||||
/* U+006B "k" */
|
||||
0x40, 0x40, 0x46, 0x48, 0x50, 0x68, 0x4C, 0x46, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+006C "l" */
|
||||
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x7C, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+006D "m" */
|
||||
0x0, 0x0, 0x6C, 0x54, 0x54, 0x54, 0x54, 0x54, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+006E "n" */
|
||||
0x0, 0x0, 0x58, 0x64, 0x44, 0x44, 0x44, 0x44, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+006F "o" */
|
||||
0x0, 0x0, 0x38, 0x44, 0x44, 0x44, 0x44, 0x38, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0070 "p" */
|
||||
0x0, 0x0, 0x58, 0x64, 0x44, 0x44, 0x44, 0x78, 0x40, 0x40, 0x0, 0x0,
|
||||
/* U+0071 "q" */
|
||||
0x0, 0x0, 0x34, 0x4C, 0x44, 0x44, 0x44, 0x3C, 0x4, 0x4, 0x0, 0x0,
|
||||
/* U+0072 "r" */
|
||||
0x0, 0x0, 0x7E, 0x10, 0x10, 0x10, 0x10, 0x7C, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0073 "s" */
|
||||
0x0, 0x0, 0x38, 0x44, 0x70, 0xC, 0x44, 0x38, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0074 "t" */
|
||||
0x20, 0x20, 0xFC, 0x20, 0x20, 0x20, 0x20, 0x1C, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0075 "u" */
|
||||
0x0, 0x0, 0x44, 0x44, 0x44, 0x44, 0x44, 0x3C, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0076 "v" */
|
||||
0x0, 0x0, 0x44, 0x44, 0x28, 0x28, 0x28, 0x10, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0077 "w" */
|
||||
0x0, 0x0, 0x92, 0xB2, 0xAC, 0x6C, 0x6C, 0x6C, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0078 "x" */
|
||||
0x0, 0x0, 0x44, 0x28, 0x10, 0x10, 0x28, 0x44, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0079 "y" */
|
||||
0x0, 0x0, 0x44, 0x44, 0x28, 0x28, 0x30, 0x10, 0x10, 0x60, 0x0, 0x0,
|
||||
/* U+007A "z" */
|
||||
0x0, 0x0, 0x7C, 0xC, 0x10, 0x20, 0x40, 0x7C, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+007B "{" */
|
||||
0x10, 0x10, 0x10, 0x8, 0x70, 0x18, 0x10, 0x10, 0x10, 0x1C, 0x0, 0x0,
|
||||
/* U+007C "|" */
|
||||
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0, 0x0,
|
||||
/* U+007D "}" */
|
||||
0x10, 0x10, 0x20, 0x20, 0x1C, 0x30, 0x20, 0x10, 0x10, 0x70, 0x0, 0x0,
|
||||
/* U+007E "~" */
|
||||
0x0, 0x0, 0x0, 0x64, 0x54, 0x4C, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
};
|
||||
|
||||
const FixedWidthFont ibmplexmono_12_font = {
|
||||
.glyph_width = 7,
|
||||
.glyph_height = 12,
|
||||
.glyph_bytes_per_row = 1,
|
||||
.first_codepoint = 0x20,
|
||||
.last_codepoint = 0x7E,
|
||||
.glyph_bitmap = ibmplexmono12_glyph_bitmap,
|
||||
};
|
||||
|
||||
#endif // CONFIG_TT_FONT_IBMPLEXMONO_12
|
||||
222
Modules/font-module/source/ibmplexmono14.c
Normal file
222
Modules/font-module/source/ibmplexmono14.c
Normal file
@ -0,0 +1,222 @@
|
||||
/*
|
||||
* ibmplexmono14.c - ibmplexmono14 FixedWidthFont
|
||||
*
|
||||
* Rasterized from a TTF with Modules/font-module/scripts/generate.py.
|
||||
* Each glyph is 8 pixels wide and 14 pixels tall, stored as 14 rows of
|
||||
* 1 byte each (bit 7 of the first byte = leftmost pixel).
|
||||
*/
|
||||
|
||||
#include <font/ibmplexmono14.h>
|
||||
|
||||
#ifdef ESP_PLATFORM
|
||||
#include <sdkconfig.h>
|
||||
#endif
|
||||
|
||||
// See Modules/font-module/Kconfig: undefined (POSIX, or an ESP-IDF build predating
|
||||
// this font's Kconfig entry) is treated the same as enabled.
|
||||
#if !defined(CONFIG_TT_FONT_IBMPLEXMONO_14) || CONFIG_TT_FONT_IBMPLEXMONO_14
|
||||
|
||||
// Glyph bitmap data: 95 characters (0x20-0x7E), 14 bytes each = 1330 bytes
|
||||
static const uint8_t ibmplexmono14_glyph_bitmap[] = {
|
||||
/* U+0020 " " */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0021 "!" */
|
||||
0x18, 0x18, 0x18, 0x18, 0x10, 0x10, 0x10, 0x0, 0x18, 0x18, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0022 "\"" */
|
||||
0x24, 0x24, 0x24, 0x24, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0023 "#" */
|
||||
0x12, 0x14, 0x14, 0x67, 0x24, 0x24, 0xE6, 0x28, 0x28, 0x48, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0024 "$" */
|
||||
0x3C, 0x4A, 0x49, 0x48, 0x38, 0xE, 0xA, 0xB, 0x4A, 0x3C, 0x8, 0x0, 0x0, 0x0,
|
||||
/* U+0025 "%" */
|
||||
0x71, 0x92, 0x92, 0x94, 0x70, 0xE, 0x29, 0x49, 0x49, 0x8E, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0026 "&" */
|
||||
0x38, 0x44, 0x40, 0x40, 0x23, 0x52, 0x8C, 0x8C, 0xC6, 0x7B, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0027 "'" */
|
||||
0x18, 0x18, 0x18, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0028 "(" */
|
||||
0x8, 0x8, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x8, 0x8, 0x6, 0x0, 0x0,
|
||||
/* U+0029 ")" */
|
||||
0x10, 0x10, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x10, 0x10, 0x60, 0x0, 0x0,
|
||||
/* U+002A "*" */
|
||||
0x0, 0x0, 0x18, 0x18, 0x5A, 0xBD, 0x18, 0x24, 0x66, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+002B "+" */
|
||||
0x0, 0x0, 0x18, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+002C "," */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x18, 0x10, 0x10, 0x0, 0x0,
|
||||
/* U+002D "-" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x3C, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+002E "." */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x18, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+002F "/" */
|
||||
0x4, 0x4, 0x4, 0x8, 0x8, 0x8, 0x10, 0x10, 0x20, 0x20, 0x20, 0x40, 0x0, 0x0,
|
||||
/* U+0030 "0" */
|
||||
0x3C, 0x66, 0x42, 0x42, 0x5A, 0x5A, 0x42, 0x42, 0x66, 0x3C, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0031 "1" */
|
||||
0x18, 0x28, 0x48, 0x48, 0x8, 0x8, 0x8, 0x8, 0x8, 0x7F, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0032 "2" */
|
||||
0x3C, 0x46, 0x42, 0x2, 0x6, 0xC, 0x18, 0x30, 0x60, 0x7E, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0033 "3" */
|
||||
0x3C, 0x46, 0x2, 0x4, 0x38, 0x6, 0x2, 0x2, 0xC6, 0x3C, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0034 "4" */
|
||||
0xC, 0xC, 0x14, 0x24, 0x24, 0x44, 0x44, 0xFF, 0x4, 0x4, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0035 "5" */
|
||||
0x7E, 0x40, 0x40, 0x40, 0x5C, 0x66, 0x2, 0x2, 0x46, 0x3C, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0036 "6" */
|
||||
0xC, 0x10, 0x20, 0x40, 0x5C, 0x62, 0x42, 0x42, 0x42, 0x3C, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0037 "7" */
|
||||
0x7E, 0x42, 0x46, 0x4, 0x4, 0x8, 0x8, 0x18, 0x10, 0x30, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0038 "8" */
|
||||
0x3C, 0x42, 0x42, 0x42, 0x3C, 0x66, 0x42, 0x42, 0x42, 0x3C, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0039 "9" */
|
||||
0x3C, 0x42, 0x42, 0x42, 0x42, 0x3E, 0x2, 0x4, 0x8, 0x30, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+003A ":" */
|
||||
0x0, 0x0, 0x18, 0x18, 0x0, 0x0, 0x0, 0x0, 0x18, 0x18, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+003B ";" */
|
||||
0x0, 0x0, 0x18, 0x18, 0x0, 0x0, 0x0, 0x0, 0x18, 0x18, 0x10, 0x10, 0x0, 0x0,
|
||||
/* U+003C "<" */
|
||||
0x0, 0x0, 0x2, 0xC, 0x18, 0x60, 0x60, 0x18, 0xE, 0x2, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+003D "=" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x7E, 0x0, 0x0, 0x7E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+003E ">" */
|
||||
0x0, 0x0, 0x40, 0x70, 0x18, 0x6, 0x6, 0x18, 0x30, 0x40, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+003F "?" */
|
||||
0x3C, 0x66, 0x42, 0x2, 0x4, 0x18, 0x10, 0x0, 0x18, 0x18, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0040 "@" */
|
||||
0x3C, 0x66, 0x42, 0x4E, 0x52, 0x52, 0x52, 0x52, 0x5E, 0x40, 0x60, 0x3C, 0x0, 0x0,
|
||||
/* U+0041 "A" */
|
||||
0x18, 0x18, 0x3C, 0x24, 0x24, 0x24, 0x7E, 0x42, 0x42, 0xC3, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0042 "B" */
|
||||
0x7C, 0x42, 0x42, 0x42, 0x7C, 0x42, 0x42, 0x42, 0x42, 0x7C, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0043 "C" */
|
||||
0x3C, 0x22, 0x42, 0x40, 0x40, 0x40, 0x40, 0x44, 0x22, 0x3C, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0044 "D" */
|
||||
0x7C, 0x46, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x46, 0x7C, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0045 "E" */
|
||||
0x7E, 0x40, 0x40, 0x40, 0x7E, 0x40, 0x40, 0x40, 0x40, 0x7E, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0046 "F" */
|
||||
0x7E, 0x40, 0x40, 0x40, 0x7E, 0x40, 0x40, 0x40, 0x40, 0x40, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0047 "G" */
|
||||
0x3C, 0x66, 0x44, 0x40, 0x40, 0x4E, 0x42, 0x42, 0x66, 0x3A, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0048 "H" */
|
||||
0x42, 0x42, 0x42, 0x42, 0x7E, 0x42, 0x42, 0x42, 0x42, 0x42, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0049 "I" */
|
||||
0x7E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7E, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+004A "J" */
|
||||
0x3E, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x44, 0x38, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+004B "K" */
|
||||
0x43, 0x46, 0x4C, 0x48, 0x58, 0x68, 0x4C, 0x44, 0x42, 0x43, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+004C "L" */
|
||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3E, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+004D "M" */
|
||||
0x42, 0x66, 0x66, 0x5A, 0x5A, 0x5A, 0x52, 0x42, 0x42, 0x42, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+004E "N" */
|
||||
0x62, 0x62, 0x72, 0x52, 0x52, 0x4A, 0x4A, 0x4A, 0x46, 0x46, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+004F "O" */
|
||||
0x3C, 0x66, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x66, 0x3C, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0050 "P" */
|
||||
0x7C, 0x42, 0x42, 0x42, 0x42, 0x7C, 0x40, 0x40, 0x40, 0x40, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0051 "Q" */
|
||||
0x3C, 0x66, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x66, 0x3C, 0x18, 0xE, 0x0, 0x0,
|
||||
/* U+0052 "R" */
|
||||
0x7C, 0x42, 0x42, 0x42, 0x42, 0x7C, 0x48, 0x44, 0x46, 0x43, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0053 "S" */
|
||||
0x3C, 0x42, 0x40, 0x40, 0x78, 0xE, 0x2, 0x2, 0xC2, 0x3C, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0054 "T" */
|
||||
0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0055 "U" */
|
||||
0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x66, 0x3C, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0056 "V" */
|
||||
0xC3, 0x42, 0x42, 0x62, 0x24, 0x24, 0x24, 0x3C, 0x18, 0x18, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0057 "W" */
|
||||
0x81, 0x81, 0xC1, 0x5A, 0x5A, 0x5A, 0x5A, 0x66, 0x66, 0x66, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0058 "X" */
|
||||
0xC3, 0x62, 0x24, 0x1C, 0x18, 0x18, 0x3C, 0x24, 0x42, 0xC3, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0059 "Y" */
|
||||
0xC3, 0x42, 0x66, 0x24, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+005A "Z" */
|
||||
0x7E, 0x2, 0x4, 0x8, 0x18, 0x10, 0x20, 0x60, 0x40, 0xFE, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+005B "[" */
|
||||
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x1E, 0x0, 0x0,
|
||||
/* U+005C "\\" */
|
||||
0x20, 0x20, 0x20, 0x10, 0x10, 0x10, 0x8, 0x8, 0x4, 0x4, 0x4, 0x2, 0x0, 0x0,
|
||||
/* U+005D "]" */
|
||||
0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x78, 0x0, 0x0,
|
||||
/* U+005E "^" */
|
||||
0x18, 0x18, 0x24, 0x66, 0x42, 0x83, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+005F "_" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7F, 0x0, 0x0,
|
||||
/* U+0060 "`" */
|
||||
0x30, 0x8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0061 "a" */
|
||||
0x0, 0x0, 0x0, 0x3C, 0x44, 0x6, 0x7E, 0x46, 0x4A, 0x7B, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0062 "b" */
|
||||
0x40, 0x40, 0x40, 0x5C, 0x62, 0x42, 0x42, 0x42, 0x62, 0x5C, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0063 "c" */
|
||||
0x0, 0x0, 0x0, 0x3C, 0x62, 0x40, 0x40, 0x40, 0x62, 0x3C, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0064 "d" */
|
||||
0x2, 0x2, 0x2, 0x3A, 0x46, 0x42, 0x42, 0x42, 0x46, 0x3A, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0065 "e" */
|
||||
0x0, 0x0, 0x0, 0x3C, 0x66, 0x42, 0x7E, 0x40, 0x42, 0x3C, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0066 "f" */
|
||||
0xE, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7E, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0067 "g" */
|
||||
0x0, 0x0, 0x3, 0x3C, 0x66, 0x42, 0x66, 0x3C, 0x40, 0x3E, 0x43, 0x43, 0x7E, 0x0,
|
||||
/* U+0068 "h" */
|
||||
0x40, 0x40, 0x40, 0x5C, 0x66, 0x42, 0x42, 0x42, 0x42, 0x42, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0069 "i" */
|
||||
0x8, 0x8, 0x0, 0x78, 0x8, 0x8, 0x8, 0x8, 0x8, 0x7E, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+006A "j" */
|
||||
0xC, 0xC, 0x0, 0x7C, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x78, 0x0,
|
||||
/* U+006B "k" */
|
||||
0x40, 0x40, 0x40, 0x43, 0x4C, 0x58, 0x78, 0x44, 0x46, 0x43, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+006C "l" */
|
||||
0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7E, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+006D "m" */
|
||||
0x0, 0x0, 0x0, 0x76, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+006E "n" */
|
||||
0x0, 0x0, 0x0, 0x5C, 0x66, 0x42, 0x42, 0x42, 0x42, 0x42, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+006F "o" */
|
||||
0x0, 0x0, 0x0, 0x3C, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3C, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0070 "p" */
|
||||
0x0, 0x0, 0x0, 0x5C, 0x62, 0x42, 0x42, 0x42, 0x62, 0x5C, 0x40, 0x40, 0x40, 0x0,
|
||||
/* U+0071 "q" */
|
||||
0x0, 0x0, 0x0, 0x3A, 0x46, 0x42, 0x42, 0x42, 0x46, 0x3A, 0x2, 0x2, 0x2, 0x0,
|
||||
/* U+0072 "r" */
|
||||
0x0, 0x0, 0x0, 0x77, 0x18, 0x10, 0x10, 0x10, 0x10, 0x7E, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0073 "s" */
|
||||
0x0, 0x0, 0x0, 0x3C, 0x42, 0x40, 0x3C, 0x2, 0x42, 0x3C, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0074 "t" */
|
||||
0x10, 0x10, 0x10, 0xFE, 0x10, 0x10, 0x10, 0x10, 0x10, 0x1E, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0075 "u" */
|
||||
0x0, 0x0, 0x0, 0x42, 0x42, 0x42, 0x42, 0x42, 0x66, 0x3A, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0076 "v" */
|
||||
0x0, 0x0, 0x0, 0x42, 0x42, 0x24, 0x24, 0x24, 0x18, 0x18, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0077 "w" */
|
||||
0x0, 0x0, 0x0, 0x99, 0x99, 0x5A, 0x6A, 0x66, 0x66, 0x66, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0078 "x" */
|
||||
0x0, 0x0, 0x0, 0x42, 0x24, 0x18, 0x18, 0x18, 0x24, 0x42, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0079 "y" */
|
||||
0x0, 0x0, 0x0, 0x42, 0x42, 0x24, 0x24, 0x24, 0x18, 0x18, 0x10, 0x10, 0x60, 0x0,
|
||||
/* U+007A "z" */
|
||||
0x0, 0x0, 0x0, 0x7E, 0x4, 0x8, 0x18, 0x30, 0x60, 0x7E, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+007B "{" */
|
||||
0x10, 0x10, 0x18, 0x8, 0x8, 0x70, 0x8, 0x8, 0x18, 0x10, 0x10, 0x1E, 0x0, 0x0,
|
||||
/* U+007C "|" */
|
||||
0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x0, 0x0,
|
||||
/* U+007D "}" */
|
||||
0x8, 0x8, 0x18, 0x10, 0x10, 0xE, 0x10, 0x10, 0x18, 0x8, 0x8, 0x78, 0x0, 0x0,
|
||||
/* U+007E "~" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x72, 0x5A, 0x4E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
};
|
||||
|
||||
const FixedWidthFont ibmplexmono_14_font = {
|
||||
.glyph_width = 8,
|
||||
.glyph_height = 14,
|
||||
.glyph_bytes_per_row = 1,
|
||||
.first_codepoint = 0x20,
|
||||
.last_codepoint = 0x7E,
|
||||
.glyph_bitmap = ibmplexmono14_glyph_bitmap,
|
||||
};
|
||||
|
||||
#endif // CONFIG_TT_FONT_IBMPLEXMONO_14
|
||||
222
Modules/font-module/source/ibmplexmono16.c
Normal file
222
Modules/font-module/source/ibmplexmono16.c
Normal file
@ -0,0 +1,222 @@
|
||||
/*
|
||||
* ibmplexmono16.c - ibmplexmono16 FixedWidthFont
|
||||
*
|
||||
* Rasterized from a TTF with Modules/font-module/scripts/generate.py.
|
||||
* Each glyph is 10 pixels wide and 16 pixels tall, stored as 16 rows of
|
||||
* 2 bytes each (bit 7 of the first byte = leftmost pixel).
|
||||
*/
|
||||
|
||||
#include <font/ibmplexmono16.h>
|
||||
|
||||
#ifdef ESP_PLATFORM
|
||||
#include <sdkconfig.h>
|
||||
#endif
|
||||
|
||||
// See Modules/font-module/Kconfig: undefined (POSIX, or an ESP-IDF build predating
|
||||
// this font's Kconfig entry) is treated the same as enabled.
|
||||
#if !defined(CONFIG_TT_FONT_IBMPLEXMONO_16) || CONFIG_TT_FONT_IBMPLEXMONO_16
|
||||
|
||||
// Glyph bitmap data: 95 characters (0x20-0x7E), 32 bytes each = 3040 bytes
|
||||
static const uint8_t ibmplexmono16_glyph_bitmap[] = {
|
||||
/* U+0020 " " */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0021 "!" */
|
||||
0xC, 0x0, 0xC, 0x0, 0xC, 0x0, 0xC, 0x0, 0xC, 0x0, 0x8, 0x0, 0x8, 0x0, 0x0, 0x0, 0x0, 0x0, 0xC, 0x0, 0xC, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0022 "\"" */
|
||||
0x12, 0x0, 0x12, 0x0, 0x12, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0023 "#" */
|
||||
0x9, 0x0, 0x9, 0x0, 0x1B, 0x0, 0x73, 0xC0, 0x12, 0x0, 0x12, 0x0, 0x12, 0x0, 0xF3, 0x80, 0x36, 0x0, 0x24, 0x0, 0x24, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0024 "$" */
|
||||
0x1F, 0x0, 0x25, 0x80, 0x64, 0x0, 0x64, 0x0, 0x34, 0x0, 0x1F, 0x0, 0x5, 0x80, 0x4, 0x80, 0x44, 0x80, 0x65, 0x80, 0x1F, 0x0, 0x4, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0025 "%" */
|
||||
0x70, 0xC0, 0x48, 0x80, 0xC9, 0x0, 0x4B, 0x0, 0x72, 0x0, 0x0, 0x0, 0x13, 0x80, 0x24, 0x80, 0x24, 0x80, 0x44, 0x80, 0xC3, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0026 "&" */
|
||||
0x1C, 0x0, 0x22, 0x0, 0x20, 0x0, 0x20, 0x0, 0x30, 0x0, 0x39, 0x80, 0x49, 0x0, 0x45, 0x0, 0x42, 0x0, 0x65, 0x0, 0x39, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0027 "'" */
|
||||
0xC, 0x0, 0xC, 0x0, 0xC, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0028 "(" */
|
||||
0x6, 0x0, 0x4, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x18, 0x0, 0x18, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x4, 0x0, 0x6, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0029 ")" */
|
||||
0x18, 0x0, 0x8, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x6, 0x0, 0x6, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x8, 0x0, 0x18, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+002A "*" */
|
||||
0x0, 0x0, 0x0, 0x0, 0xC, 0x0, 0xC, 0x0, 0x4C, 0x80, 0x7F, 0x80, 0xC, 0x0, 0x1E, 0x0, 0x12, 0x0, 0x21, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+002B "+" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xC, 0x0, 0xC, 0x0, 0xC, 0x0, 0x7F, 0x80, 0xC, 0x0, 0xC, 0x0, 0xC, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+002C "," */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xC, 0x0, 0xC, 0x0, 0x8, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+002D "-" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+002E "." */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xC, 0x0, 0xC, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+002F "/" */
|
||||
0x1, 0x0, 0x2, 0x0, 0x2, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x8, 0x0, 0x8, 0x0, 0x10, 0x0, 0x10, 0x0, 0x10, 0x0, 0x20, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0030 "0" */
|
||||
0x1E, 0x0, 0x21, 0x0, 0x21, 0x0, 0x61, 0x80, 0x4C, 0x80, 0x4C, 0x80, 0x40, 0x80, 0x61, 0x80, 0x21, 0x0, 0x21, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0031 "1" */
|
||||
0x1C, 0x0, 0x34, 0x0, 0x64, 0x0, 0x44, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x3F, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0032 "2" */
|
||||
0x1E, 0x0, 0x23, 0x0, 0x61, 0x0, 0x1, 0x0, 0x1, 0x0, 0x3, 0x0, 0x6, 0x0, 0x8, 0x0, 0x10, 0x0, 0x20, 0x0, 0x7F, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0033 "3" */
|
||||
0x1E, 0x0, 0x23, 0x0, 0x41, 0x0, 0x1, 0x0, 0x3, 0x0, 0x1C, 0x0, 0x3, 0x0, 0x1, 0x0, 0x41, 0x0, 0x63, 0x0, 0x3E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0034 "4" */
|
||||
0x7, 0x0, 0x7, 0x0, 0xB, 0x0, 0x1B, 0x0, 0x13, 0x0, 0x23, 0x0, 0x23, 0x0, 0x43, 0x0, 0x7F, 0x80, 0x3, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0035 "5" */
|
||||
0x3F, 0x0, 0x20, 0x0, 0x20, 0x0, 0x20, 0x0, 0x2E, 0x0, 0x31, 0x0, 0x1, 0x80, 0x1, 0x80, 0x41, 0x80, 0x21, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0036 "6" */
|
||||
0x6, 0x0, 0x18, 0x0, 0x10, 0x0, 0x20, 0x0, 0x3E, 0x0, 0x61, 0x0, 0x61, 0x80, 0x61, 0x80, 0x61, 0x80, 0x21, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0037 "7" */
|
||||
0x7F, 0x80, 0x41, 0x80, 0x41, 0x0, 0x3, 0x0, 0x2, 0x0, 0x6, 0x0, 0x4, 0x0, 0xC, 0x0, 0x8, 0x0, 0x8, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0038 "8" */
|
||||
0x1E, 0x0, 0x21, 0x0, 0x61, 0x80, 0x61, 0x80, 0x21, 0x0, 0x1E, 0x0, 0x21, 0x0, 0x40, 0x80, 0x40, 0x80, 0x61, 0x80, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0039 "9" */
|
||||
0x1E, 0x0, 0x21, 0x0, 0x61, 0x80, 0x61, 0x80, 0x61, 0x80, 0x21, 0x80, 0x1F, 0x0, 0x3, 0x0, 0x2, 0x0, 0x6, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+003A ":" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xC, 0x0, 0xC, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xC, 0x0, 0xC, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+003B ";" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xC, 0x0, 0xC, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xC, 0x0, 0xC, 0x0, 0x8, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+003C "<" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x3, 0x0, 0xC, 0x0, 0x30, 0x0, 0x60, 0x0, 0x30, 0x0, 0xC, 0x0, 0x3, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+003D "=" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7F, 0x80, 0x0, 0x0, 0x0, 0x0, 0x7F, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+003E ">" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x30, 0x0, 0xC, 0x0, 0x3, 0x0, 0x1, 0x80, 0x3, 0x0, 0xC, 0x0, 0x30, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+003F "?" */
|
||||
0x1E, 0x0, 0x21, 0x0, 0x61, 0x0, 0x1, 0x0, 0x3, 0x0, 0xC, 0x0, 0x8, 0x0, 0x0, 0x0, 0x0, 0x0, 0xC, 0x0, 0xC, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0040 "@" */
|
||||
0x1E, 0x0, 0x21, 0x0, 0x21, 0x0, 0x67, 0x80, 0x49, 0x80, 0x49, 0x80, 0x49, 0x80, 0x49, 0x80, 0x49, 0x80, 0x6F, 0x80, 0x20, 0x0, 0x30, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0041 "A" */
|
||||
0xC, 0x0, 0xC, 0x0, 0x1E, 0x0, 0x12, 0x0, 0x12, 0x0, 0x33, 0x0, 0x23, 0x0, 0x3F, 0x0, 0x61, 0x80, 0x61, 0x80, 0x40, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0042 "B" */
|
||||
0x3E, 0x0, 0x21, 0x0, 0x21, 0x0, 0x21, 0x0, 0x21, 0x0, 0x3E, 0x0, 0x21, 0x80, 0x21, 0x80, 0x21, 0x80, 0x21, 0x0, 0x3F, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0043 "C" */
|
||||
0x1E, 0x0, 0x31, 0x0, 0x21, 0x80, 0x20, 0x0, 0x60, 0x0, 0x60, 0x0, 0x60, 0x0, 0x20, 0x0, 0x21, 0x0, 0x31, 0x80, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0044 "D" */
|
||||
0x3E, 0x0, 0x23, 0x0, 0x21, 0x0, 0x21, 0x80, 0x21, 0x80, 0x21, 0x80, 0x21, 0x80, 0x21, 0x80, 0x21, 0x0, 0x23, 0x0, 0x3E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0045 "E" */
|
||||
0x3F, 0x0, 0x20, 0x0, 0x20, 0x0, 0x20, 0x0, 0x20, 0x0, 0x3F, 0x0, 0x20, 0x0, 0x20, 0x0, 0x20, 0x0, 0x20, 0x0, 0x3F, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0046 "F" */
|
||||
0x3F, 0x80, 0x20, 0x0, 0x20, 0x0, 0x20, 0x0, 0x20, 0x0, 0x3F, 0x0, 0x20, 0x0, 0x20, 0x0, 0x20, 0x0, 0x20, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0047 "G" */
|
||||
0x1E, 0x0, 0x31, 0x0, 0x21, 0x80, 0x60, 0x0, 0x60, 0x0, 0x60, 0x0, 0x67, 0x80, 0x61, 0x80, 0x61, 0x80, 0x31, 0x80, 0x1F, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0048 "H" */
|
||||
0x61, 0x0, 0x61, 0x0, 0x61, 0x0, 0x61, 0x0, 0x61, 0x0, 0x7F, 0x0, 0x61, 0x0, 0x61, 0x0, 0x61, 0x0, 0x61, 0x0, 0x61, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0049 "I" */
|
||||
0x3F, 0x0, 0xC, 0x0, 0xC, 0x0, 0xC, 0x0, 0xC, 0x0, 0xC, 0x0, 0xC, 0x0, 0xC, 0x0, 0xC, 0x0, 0xC, 0x0, 0x3F, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+004A "J" */
|
||||
0x3F, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x23, 0x0, 0x62, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+004B "K" */
|
||||
0x21, 0x80, 0x23, 0x0, 0x22, 0x0, 0x24, 0x0, 0x2C, 0x0, 0x3C, 0x0, 0x36, 0x0, 0x22, 0x0, 0x23, 0x0, 0x21, 0x80, 0x20, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+004C "L" */
|
||||
0x20, 0x0, 0x20, 0x0, 0x20, 0x0, 0x20, 0x0, 0x20, 0x0, 0x20, 0x0, 0x20, 0x0, 0x20, 0x0, 0x20, 0x0, 0x20, 0x0, 0x3F, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+004D "M" */
|
||||
0x61, 0x80, 0x73, 0x80, 0x73, 0x80, 0x73, 0x80, 0x6D, 0x80, 0x6D, 0x80, 0x6D, 0x80, 0x69, 0x80, 0x61, 0x80, 0x61, 0x80, 0x61, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+004E "N" */
|
||||
0x31, 0x80, 0x31, 0x80, 0x31, 0x80, 0x29, 0x80, 0x29, 0x80, 0x2D, 0x80, 0x25, 0x80, 0x27, 0x80, 0x23, 0x80, 0x23, 0x80, 0x23, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+004F "O" */
|
||||
0x1E, 0x0, 0x33, 0x0, 0x21, 0x0, 0x61, 0x80, 0x61, 0x80, 0x61, 0x80, 0x61, 0x80, 0x61, 0x80, 0x21, 0x0, 0x33, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0050 "P" */
|
||||
0x3F, 0x0, 0x21, 0x80, 0x21, 0x80, 0x21, 0x80, 0x21, 0x80, 0x3F, 0x0, 0x20, 0x0, 0x20, 0x0, 0x20, 0x0, 0x20, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0051 "Q" */
|
||||
0x1E, 0x0, 0x33, 0x0, 0x21, 0x0, 0x61, 0x80, 0x61, 0x80, 0x61, 0x80, 0x61, 0x80, 0x61, 0x80, 0x21, 0x0, 0x33, 0x0, 0x1E, 0x0, 0xC, 0x0, 0x7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0052 "R" */
|
||||
0x3F, 0x0, 0x21, 0x80, 0x21, 0x80, 0x21, 0x80, 0x21, 0x80, 0x3F, 0x0, 0x24, 0x0, 0x22, 0x0, 0x23, 0x0, 0x21, 0x0, 0x21, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0053 "S" */
|
||||
0x1F, 0x0, 0x21, 0x80, 0x60, 0x0, 0x60, 0x0, 0x30, 0x0, 0x1F, 0x0, 0x1, 0x80, 0x1, 0x80, 0x41, 0x80, 0x61, 0x0, 0x3E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0054 "T" */
|
||||
0x7F, 0x80, 0xC, 0x0, 0xC, 0x0, 0xC, 0x0, 0xC, 0x0, 0xC, 0x0, 0xC, 0x0, 0xC, 0x0, 0xC, 0x0, 0xC, 0x0, 0xC, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0055 "U" */
|
||||
0x61, 0x80, 0x61, 0x80, 0x61, 0x80, 0x61, 0x80, 0x61, 0x80, 0x61, 0x80, 0x61, 0x80, 0x21, 0x0, 0x21, 0x0, 0x21, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0056 "V" */
|
||||
0x40, 0x80, 0x61, 0x80, 0x21, 0x0, 0x21, 0x0, 0x21, 0x0, 0x33, 0x0, 0x12, 0x0, 0x12, 0x0, 0x1E, 0x0, 0xC, 0x0, 0xC, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0057 "W" */
|
||||
0x40, 0x80, 0x40, 0x80, 0x40, 0x80, 0x4C, 0x80, 0x4C, 0x80, 0x4C, 0x80, 0x5E, 0x80, 0x72, 0x80, 0x73, 0x80, 0x33, 0x0, 0x33, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0058 "X" */
|
||||
0x61, 0x80, 0x21, 0x0, 0x33, 0x0, 0x1A, 0x0, 0xC, 0x0, 0xC, 0x0, 0xE, 0x0, 0x12, 0x0, 0x33, 0x0, 0x21, 0x0, 0x40, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0059 "Y" */
|
||||
0xC0, 0xC0, 0x61, 0x80, 0x31, 0x0, 0x12, 0x0, 0x1E, 0x0, 0xC, 0x0, 0xC, 0x0, 0xC, 0x0, 0xC, 0x0, 0xC, 0x0, 0xC, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+005A "Z" */
|
||||
0x7F, 0x80, 0x1, 0x80, 0x3, 0x0, 0x2, 0x0, 0x4, 0x0, 0xC, 0x0, 0x8, 0x0, 0x10, 0x0, 0x30, 0x0, 0x60, 0x0, 0x7F, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+005B "[" */
|
||||
0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0xF, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+005C "\\" */
|
||||
0x20, 0x0, 0x10, 0x0, 0x10, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x4, 0x0, 0x4, 0x0, 0x2, 0x0, 0x2, 0x0, 0x2, 0x0, 0x1, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+005D "]" */
|
||||
0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x3C, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+005E "^" */
|
||||
0xC, 0x0, 0x1E, 0x0, 0x12, 0x0, 0x33, 0x0, 0x21, 0x0, 0x61, 0x80, 0x41, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+005F "_" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7F, 0x80, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0060 "`" */
|
||||
0x8, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0061 "a" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1E, 0x0, 0x23, 0x0, 0x1, 0x0, 0x3F, 0x0, 0x61, 0x0, 0x61, 0x0, 0x67, 0x0, 0x3D, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0062 "b" */
|
||||
0x20, 0x0, 0x20, 0x0, 0x20, 0x0, 0x2E, 0x0, 0x31, 0x0, 0x21, 0x80, 0x21, 0x80, 0x21, 0x80, 0x21, 0x80, 0x31, 0x0, 0x2E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0063 "c" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1E, 0x0, 0x31, 0x0, 0x20, 0x0, 0x20, 0x0, 0x20, 0x0, 0x20, 0x0, 0x31, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0064 "d" */
|
||||
0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1D, 0x0, 0x23, 0x0, 0x61, 0x0, 0x61, 0x0, 0x61, 0x0, 0x61, 0x0, 0x23, 0x0, 0x1D, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0065 "e" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1E, 0x0, 0x21, 0x0, 0x21, 0x80, 0x7F, 0x80, 0x60, 0x0, 0x61, 0x0, 0x31, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0066 "f" */
|
||||
0xC, 0x0, 0xC, 0x0, 0xC, 0x0, 0x7F, 0x80, 0xC, 0x0, 0xC, 0x0, 0xC, 0x0, 0xC, 0x0, 0xC, 0x0, 0xC, 0x0, 0x3F, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0067 "g" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x1, 0x80, 0x1E, 0x0, 0x33, 0x0, 0x21, 0x0, 0x21, 0x0, 0x13, 0x0, 0x3E, 0x0, 0x20, 0x0, 0x1F, 0x0, 0x60, 0x80, 0x60, 0x80, 0x3F, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0068 "h" */
|
||||
0x20, 0x0, 0x20, 0x0, 0x20, 0x0, 0x2E, 0x0, 0x31, 0x0, 0x21, 0x0, 0x21, 0x0, 0x21, 0x0, 0x21, 0x0, 0x21, 0x0, 0x21, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0069 "i" */
|
||||
0xE, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3C, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x3F, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+006A "j" */
|
||||
0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3E, 0x0, 0x2, 0x0, 0x2, 0x0, 0x2, 0x0, 0x2, 0x0, 0x2, 0x0, 0x2, 0x0, 0x2, 0x0, 0x2, 0x0, 0x2, 0x0, 0x3E, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+006B "k" */
|
||||
0x20, 0x0, 0x20, 0x0, 0x20, 0x0, 0x21, 0x80, 0x22, 0x0, 0x24, 0x0, 0x2C, 0x0, 0x36, 0x0, 0x22, 0x0, 0x21, 0x0, 0x21, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+006C "l" */
|
||||
0xC, 0x0, 0xC, 0x0, 0xC, 0x0, 0xC, 0x0, 0xC, 0x0, 0xC, 0x0, 0xC, 0x0, 0xC, 0x0, 0xC, 0x0, 0xC, 0x0, 0x7F, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+006D "m" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5B, 0x80, 0x6C, 0x80, 0x4C, 0x80, 0x4C, 0x80, 0x4C, 0x80, 0x4C, 0x80, 0x4C, 0x80, 0x4C, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+006E "n" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2E, 0x0, 0x31, 0x0, 0x21, 0x0, 0x21, 0x0, 0x21, 0x0, 0x21, 0x0, 0x21, 0x0, 0x21, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+006F "o" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1E, 0x0, 0x21, 0x0, 0x61, 0x80, 0x61, 0x80, 0x61, 0x80, 0x61, 0x80, 0x21, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0070 "p" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2E, 0x0, 0x31, 0x0, 0x21, 0x80, 0x21, 0x80, 0x21, 0x80, 0x21, 0x80, 0x31, 0x0, 0x2E, 0x0, 0x20, 0x0, 0x20, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0071 "q" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1D, 0x0, 0x23, 0x0, 0x61, 0x0, 0x61, 0x0, 0x61, 0x0, 0x61, 0x0, 0x23, 0x0, 0x1D, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0072 "r" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7B, 0x80, 0xC, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x7F, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0073 "s" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1E, 0x0, 0x21, 0x0, 0x20, 0x0, 0x3C, 0x0, 0x7, 0x0, 0x1, 0x80, 0x61, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0074 "t" */
|
||||
0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x7F, 0x80, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0xF, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0075 "u" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x21, 0x0, 0x21, 0x0, 0x21, 0x0, 0x21, 0x0, 0x21, 0x0, 0x21, 0x0, 0x23, 0x0, 0x1D, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0076 "v" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x61, 0x80, 0x21, 0x0, 0x21, 0x0, 0x12, 0x0, 0x12, 0x0, 0x12, 0x0, 0xC, 0x0, 0xC, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0077 "w" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4C, 0x80, 0x4C, 0x80, 0x4C, 0x80, 0x4C, 0x80, 0x52, 0x80, 0x33, 0x0, 0x33, 0x0, 0x33, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0078 "x" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x61, 0x80, 0x33, 0x0, 0x1E, 0x0, 0xC, 0x0, 0xC, 0x0, 0x16, 0x0, 0x33, 0x0, 0x61, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0079 "y" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x61, 0x80, 0x21, 0x0, 0x21, 0x0, 0x12, 0x0, 0x12, 0x0, 0x1E, 0x0, 0xC, 0x0, 0xC, 0x0, 0x8, 0x0, 0x8, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+007A "z" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3F, 0x0, 0x1, 0x0, 0x2, 0x0, 0x4, 0x0, 0x8, 0x0, 0x10, 0x0, 0x20, 0x0, 0x3F, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+007B "{" */
|
||||
0x8, 0x0, 0x8, 0x0, 0xC, 0x0, 0x4, 0x0, 0x4, 0x0, 0x38, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0xF, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+007C "|" */
|
||||
0xC, 0x0, 0xC, 0x0, 0xC, 0x0, 0xC, 0x0, 0xC, 0x0, 0xC, 0x0, 0xC, 0x0, 0xC, 0x0, 0xC, 0x0, 0xC, 0x0, 0xC, 0x0, 0xC, 0x0, 0xC, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+007D "}" */
|
||||
0x4, 0x0, 0x4, 0x0, 0xC, 0x0, 0x8, 0x0, 0x8, 0x0, 0x7, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x3C, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+007E "~" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x38, 0x80, 0x6D, 0x80, 0x47, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
};
|
||||
|
||||
const FixedWidthFont ibmplexmono_16_font = {
|
||||
.glyph_width = 10,
|
||||
.glyph_height = 16,
|
||||
.glyph_bytes_per_row = 2,
|
||||
.first_codepoint = 0x20,
|
||||
.last_codepoint = 0x7E,
|
||||
.glyph_bitmap = ibmplexmono16_glyph_bitmap,
|
||||
};
|
||||
|
||||
#endif // CONFIG_TT_FONT_IBMPLEXMONO_16
|
||||
222
Modules/font-module/source/ibmplexmono18.c
Normal file
222
Modules/font-module/source/ibmplexmono18.c
Normal file
@ -0,0 +1,222 @@
|
||||
/*
|
||||
* ibmplexmono18.c - ibmplexmono18 FixedWidthFont
|
||||
*
|
||||
* Rasterized from a TTF with Modules/font-module/scripts/generate.py.
|
||||
* Each glyph is 11 pixels wide and 18 pixels tall, stored as 18 rows of
|
||||
* 2 bytes each (bit 7 of the first byte = leftmost pixel).
|
||||
*/
|
||||
|
||||
#include <font/ibmplexmono18.h>
|
||||
|
||||
#ifdef ESP_PLATFORM
|
||||
#include <sdkconfig.h>
|
||||
#endif
|
||||
|
||||
// See Modules/font-module/Kconfig: undefined (POSIX, or an ESP-IDF build predating
|
||||
// this font's Kconfig entry) is treated the same as enabled.
|
||||
#if !defined(CONFIG_TT_FONT_IBMPLEXMONO_18) || CONFIG_TT_FONT_IBMPLEXMONO_18
|
||||
|
||||
// Glyph bitmap data: 95 characters (0x20-0x7E), 36 bytes each = 3420 bytes
|
||||
static const uint8_t ibmplexmono18_glyph_bitmap[] = {
|
||||
/* U+0020 " " */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0021 "!" */
|
||||
0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0xE, 0x0, 0xE, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0022 "\"" */
|
||||
0x1B, 0x0, 0x1B, 0x0, 0x1B, 0x0, 0x1B, 0x0, 0x1B, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0023 "#" */
|
||||
0xC, 0x80, 0x9, 0x80, 0x9, 0x0, 0x9, 0x0, 0x79, 0xE0, 0x19, 0x0, 0x1B, 0x0, 0x13, 0x0, 0xF3, 0xC0, 0x12, 0x0, 0x32, 0x0, 0x32, 0x0, 0x26, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0024 "$" */
|
||||
0x1F, 0x0, 0x34, 0xC0, 0x24, 0x80, 0x64, 0x0, 0x24, 0x0, 0x34, 0x0, 0xF, 0x0, 0x4, 0xC0, 0x4, 0xC0, 0x4, 0x40, 0x44, 0xC0, 0x74, 0x80, 0x1F, 0x0, 0x4, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0025 "%" */
|
||||
0x38, 0x60, 0x4C, 0xC0, 0xC4, 0x80, 0xC5, 0x80, 0x4D, 0x0, 0x7A, 0x0, 0x0, 0x0, 0x3, 0x80, 0x1E, 0x40, 0x34, 0x60, 0x24, 0x60, 0x66, 0x40, 0xC3, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0026 "&" */
|
||||
0x1E, 0x0, 0x33, 0x0, 0x20, 0x0, 0x20, 0x0, 0x30, 0x0, 0x10, 0x0, 0x38, 0xC0, 0x6C, 0x80, 0x46, 0x80, 0x43, 0x0, 0x41, 0x0, 0x62, 0x80, 0x3C, 0xC0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0027 "'" */
|
||||
0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0028 "(" */
|
||||
0x2, 0x0, 0x6, 0x0, 0x4, 0x0, 0xC, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0xC, 0x0, 0x4, 0x0, 0x6, 0x0, 0x2, 0x0, 0x1, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0029 ")" */
|
||||
0x8, 0x0, 0xC, 0x0, 0x4, 0x0, 0x6, 0x0, 0x2, 0x0, 0x2, 0x0, 0x2, 0x0, 0x2, 0x0, 0x2, 0x0, 0x2, 0x0, 0x6, 0x0, 0x4, 0x0, 0xC, 0x0, 0x8, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+002A "*" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x75, 0xC0, 0x1F, 0x0, 0xE, 0x0, 0x1B, 0x0, 0x11, 0x0, 0x31, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+002B "+" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x7F, 0xC0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+002C "," */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, 0x0, 0xC, 0x0, 0xC, 0x0, 0xC, 0x0, 0x8, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+002D "-" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1F, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+002E "." */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xE, 0x0, 0xE, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+002F "/" */
|
||||
0x1, 0x80, 0x1, 0x0, 0x1, 0x0, 0x2, 0x0, 0x2, 0x0, 0x6, 0x0, 0x4, 0x0, 0x4, 0x0, 0xC, 0x0, 0x8, 0x0, 0x18, 0x0, 0x10, 0x0, 0x10, 0x0, 0x30, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0030 "0" */
|
||||
0x1F, 0x0, 0x31, 0x80, 0x20, 0x80, 0x60, 0xC0, 0x60, 0xC0, 0x6E, 0xC0, 0x6E, 0xC0, 0x60, 0xC0, 0x60, 0xC0, 0x60, 0xC0, 0x20, 0x80, 0x31, 0x80, 0x1F, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0031 "1" */
|
||||
0xE, 0x0, 0x1E, 0x0, 0x36, 0x0, 0x66, 0x0, 0x6, 0x0, 0x6, 0x0, 0x6, 0x0, 0x6, 0x0, 0x6, 0x0, 0x6, 0x0, 0x6, 0x0, 0x6, 0x0, 0x3F, 0xC0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0032 "2" */
|
||||
0x1F, 0x0, 0x31, 0x80, 0x60, 0x80, 0x0, 0x80, 0x0, 0x80, 0x1, 0x80, 0x1, 0x0, 0x2, 0x0, 0x4, 0x0, 0x8, 0x0, 0x10, 0x0, 0x60, 0x0, 0x7F, 0xC0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0033 "3" */
|
||||
0x1F, 0x0, 0x31, 0x80, 0x61, 0x80, 0x0, 0x80, 0x1, 0x80, 0x1, 0x0, 0xE, 0x0, 0x1, 0x80, 0x0, 0x80, 0x0, 0x80, 0x40, 0x80, 0x61, 0x80, 0x3E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0034 "4" */
|
||||
0x3, 0x0, 0x7, 0x0, 0x5, 0x0, 0x9, 0x0, 0x19, 0x0, 0x11, 0x0, 0x31, 0x0, 0x61, 0x0, 0x41, 0x0, 0x7F, 0xC0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0035 "5" */
|
||||
0x3F, 0x80, 0x20, 0x0, 0x20, 0x0, 0x20, 0x0, 0x20, 0x0, 0x2F, 0x0, 0x31, 0x80, 0x0, 0x80, 0x0, 0xC0, 0x0, 0xC0, 0x20, 0x80, 0x71, 0x80, 0x1F, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0036 "6" */
|
||||
0x7, 0x0, 0xC, 0x0, 0x18, 0x0, 0x10, 0x0, 0x30, 0x0, 0x2F, 0x0, 0x71, 0x80, 0x60, 0xC0, 0x60, 0xC0, 0x60, 0xC0, 0x20, 0x80, 0x31, 0x80, 0x1F, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0037 "7" */
|
||||
0x7F, 0xC0, 0x60, 0xC0, 0x60, 0x80, 0x1, 0x80, 0x1, 0x0, 0x3, 0x0, 0x3, 0x0, 0x6, 0x0, 0x6, 0x0, 0x4, 0x0, 0xC, 0x0, 0x8, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0038 "8" */
|
||||
0x1F, 0x0, 0x31, 0x80, 0x20, 0x80, 0x60, 0xC0, 0x20, 0x80, 0x31, 0x80, 0xE, 0x0, 0x31, 0x80, 0x60, 0xC0, 0x60, 0xC0, 0x60, 0xC0, 0x31, 0x80, 0x1F, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0039 "9" */
|
||||
0x1F, 0x0, 0x31, 0x80, 0x20, 0x80, 0x60, 0xC0, 0x60, 0xC0, 0x60, 0xC0, 0x31, 0xC0, 0x1E, 0x80, 0x1, 0x80, 0x1, 0x0, 0x3, 0x0, 0x6, 0x0, 0x1C, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+003A ":" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xE, 0x0, 0xE, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xE, 0x0, 0xE, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+003B ";" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xE, 0x0, 0xE, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6, 0x0, 0xC, 0x0, 0xC, 0x0, 0xC, 0x0, 0x8, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+003C "<" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80, 0x1, 0x80, 0x6, 0x0, 0x1C, 0x0, 0x30, 0x0, 0x30, 0x0, 0x1C, 0x0, 0x6, 0x0, 0x1, 0x80, 0x0, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+003D "=" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7F, 0xC0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7F, 0xC0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+003E ">" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x30, 0x0, 0xC, 0x0, 0x7, 0x0, 0x1, 0x80, 0x1, 0x80, 0x7, 0x0, 0xC, 0x0, 0x30, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+003F "?" */
|
||||
0x1F, 0x0, 0x31, 0x80, 0x20, 0x80, 0x40, 0x80, 0x1, 0x80, 0x1, 0x80, 0xF, 0x0, 0xC, 0x0, 0xC, 0x0, 0x0, 0x0, 0x0, 0x0, 0xC, 0x0, 0xE, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0040 "@" */
|
||||
0x1F, 0x0, 0x31, 0x80, 0x20, 0x80, 0x20, 0x80, 0x67, 0xC0, 0x6C, 0xC0, 0x68, 0xC0, 0x68, 0xC0, 0x68, 0xC0, 0x6C, 0xC0, 0x67, 0xC0, 0x20, 0x0, 0x20, 0x0, 0x10, 0x0, 0xF, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0041 "A" */
|
||||
0xE, 0x0, 0xE, 0x0, 0xA, 0x0, 0x1B, 0x0, 0x1B, 0x0, 0x11, 0x0, 0x11, 0x0, 0x31, 0x80, 0x3F, 0x80, 0x20, 0x80, 0x60, 0xC0, 0x60, 0xC0, 0x40, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0042 "B" */
|
||||
0x3F, 0x0, 0x21, 0x80, 0x20, 0x80, 0x20, 0x80, 0x20, 0x80, 0x21, 0x80, 0x3F, 0x0, 0x20, 0x80, 0x20, 0xC0, 0x20, 0xC0, 0x20, 0xC0, 0x20, 0x80, 0x3F, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0043 "C" */
|
||||
0xF, 0x0, 0x11, 0x80, 0x30, 0xC0, 0x20, 0x0, 0x20, 0x0, 0x60, 0x0, 0x60, 0x0, 0x60, 0x0, 0x20, 0x0, 0x20, 0x0, 0x30, 0xC0, 0x11, 0x80, 0xF, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0044 "D" */
|
||||
0x3F, 0x0, 0x21, 0x80, 0x20, 0x80, 0x20, 0xC0, 0x20, 0xC0, 0x20, 0xC0, 0x20, 0xC0, 0x20, 0xC0, 0x20, 0xC0, 0x20, 0xC0, 0x20, 0x80, 0x21, 0x80, 0x3F, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0045 "E" */
|
||||
0x3F, 0x80, 0x20, 0x0, 0x20, 0x0, 0x20, 0x0, 0x20, 0x0, 0x20, 0x0, 0x3F, 0x80, 0x20, 0x0, 0x20, 0x0, 0x20, 0x0, 0x20, 0x0, 0x20, 0x0, 0x3F, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0046 "F" */
|
||||
0x3F, 0xC0, 0x20, 0x0, 0x20, 0x0, 0x20, 0x0, 0x20, 0x0, 0x20, 0x0, 0x3F, 0x80, 0x20, 0x0, 0x20, 0x0, 0x20, 0x0, 0x20, 0x0, 0x20, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0047 "G" */
|
||||
0x1F, 0x0, 0x31, 0x80, 0x20, 0x80, 0x60, 0x0, 0x60, 0x0, 0x60, 0x0, 0x60, 0x0, 0x67, 0x80, 0x60, 0x80, 0x60, 0x80, 0x20, 0x80, 0x31, 0x80, 0x1E, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0048 "H" */
|
||||
0x60, 0x80, 0x60, 0x80, 0x60, 0x80, 0x60, 0x80, 0x60, 0x80, 0x60, 0x80, 0x7F, 0x80, 0x60, 0x80, 0x60, 0x80, 0x60, 0x80, 0x60, 0x80, 0x60, 0x80, 0x60, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0049 "I" */
|
||||
0x3F, 0x80, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x3F, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+004A "J" */
|
||||
0x1F, 0x80, 0x1, 0x80, 0x1, 0x80, 0x1, 0x80, 0x1, 0x80, 0x1, 0x80, 0x1, 0x80, 0x1, 0x80, 0x1, 0x80, 0x1, 0x80, 0x61, 0x80, 0x31, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+004B "K" */
|
||||
0x20, 0xC0, 0x21, 0x80, 0x21, 0x0, 0x23, 0x0, 0x26, 0x0, 0x2C, 0x0, 0x3E, 0x0, 0x36, 0x0, 0x23, 0x0, 0x21, 0x0, 0x21, 0x80, 0x20, 0xC0, 0x20, 0xE0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+004C "L" */
|
||||
0x30, 0x0, 0x30, 0x0, 0x30, 0x0, 0x30, 0x0, 0x30, 0x0, 0x30, 0x0, 0x30, 0x0, 0x30, 0x0, 0x30, 0x0, 0x30, 0x0, 0x30, 0x0, 0x30, 0x0, 0x3F, 0xC0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+004D "M" */
|
||||
0x60, 0xC0, 0x71, 0xC0, 0x71, 0xC0, 0x7B, 0xC0, 0x6A, 0xC0, 0x6A, 0xC0, 0x64, 0xC0, 0x64, 0xC0, 0x64, 0xC0, 0x60, 0xC0, 0x60, 0xC0, 0x60, 0xC0, 0x60, 0xC0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+004E "N" */
|
||||
0x30, 0xC0, 0x30, 0xC0, 0x38, 0xC0, 0x28, 0xC0, 0x28, 0xC0, 0x2C, 0xC0, 0x24, 0xC0, 0x26, 0xC0, 0x22, 0xC0, 0x22, 0xC0, 0x23, 0xC0, 0x21, 0xC0, 0x21, 0xC0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+004F "O" */
|
||||
0x1F, 0x0, 0x31, 0x80, 0x20, 0x80, 0x60, 0xC0, 0x60, 0xC0, 0x60, 0xC0, 0x60, 0xC0, 0x60, 0xC0, 0x60, 0xC0, 0x60, 0xC0, 0x20, 0x80, 0x31, 0x80, 0x1F, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0050 "P" */
|
||||
0x3F, 0x0, 0x20, 0x80, 0x20, 0xC0, 0x20, 0xC0, 0x20, 0xC0, 0x20, 0x80, 0x3F, 0x0, 0x20, 0x0, 0x20, 0x0, 0x20, 0x0, 0x20, 0x0, 0x20, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0051 "Q" */
|
||||
0x1F, 0x0, 0x31, 0x80, 0x20, 0x80, 0x60, 0xC0, 0x60, 0xC0, 0x60, 0xC0, 0x60, 0xC0, 0x60, 0xC0, 0x60, 0xC0, 0x60, 0xC0, 0x20, 0x80, 0x31, 0x80, 0x1F, 0x0, 0x4, 0x0, 0x4, 0x0, 0x7, 0x80, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0052 "R" */
|
||||
0x3F, 0x0, 0x20, 0x80, 0x20, 0xC0, 0x20, 0xC0, 0x20, 0xC0, 0x20, 0x80, 0x3F, 0x0, 0x26, 0x0, 0x23, 0x0, 0x23, 0x0, 0x21, 0x80, 0x20, 0x80, 0x20, 0xC0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0053 "S" */
|
||||
0x1F, 0x0, 0x30, 0xC0, 0x60, 0x80, 0x60, 0x0, 0x60, 0x0, 0x30, 0x0, 0xF, 0x0, 0x1, 0x80, 0x0, 0xC0, 0x0, 0xC0, 0x40, 0xC0, 0x61, 0x80, 0x1F, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0054 "T" */
|
||||
0x7F, 0xC0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0055 "U" */
|
||||
0x20, 0x80, 0x20, 0x80, 0x20, 0x80, 0x20, 0x80, 0x20, 0x80, 0x20, 0x80, 0x20, 0x80, 0x20, 0x80, 0x20, 0x80, 0x20, 0x80, 0x20, 0x80, 0x31, 0x80, 0x1F, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0056 "V" */
|
||||
0x40, 0x40, 0x60, 0xC0, 0x60, 0xC0, 0x20, 0x80, 0x31, 0x80, 0x31, 0x80, 0x11, 0x0, 0x11, 0x0, 0x1B, 0x0, 0x1B, 0x0, 0xA, 0x0, 0xE, 0x0, 0xE, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0057 "W" */
|
||||
0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x44, 0x40, 0x4E, 0x40, 0x4A, 0x40, 0x6A, 0xC0, 0x6A, 0xC0, 0x6A, 0xC0, 0x7B, 0xC0, 0x31, 0x80, 0x31, 0x80, 0x31, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0058 "X" */
|
||||
0x60, 0xC0, 0x20, 0x80, 0x31, 0x80, 0x19, 0x0, 0xB, 0x0, 0xE, 0x0, 0x6, 0x0, 0xE, 0x0, 0x1B, 0x0, 0x11, 0x0, 0x31, 0x80, 0x60, 0xC0, 0x60, 0xC0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0059 "Y" */
|
||||
0xC0, 0x60, 0x60, 0xC0, 0x30, 0x80, 0x31, 0x80, 0x1B, 0x0, 0xA, 0x0, 0xE, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+005A "Z" */
|
||||
0x7F, 0xC0, 0x0, 0x80, 0x1, 0x80, 0x1, 0x0, 0x3, 0x0, 0x6, 0x0, 0x4, 0x0, 0xC, 0x0, 0x18, 0x0, 0x10, 0x0, 0x30, 0x0, 0x60, 0x0, 0x7F, 0xC0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+005B "[" */
|
||||
0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0xF, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+005C "\\" */
|
||||
0x30, 0x0, 0x10, 0x0, 0x10, 0x0, 0x8, 0x0, 0x8, 0x0, 0xC, 0x0, 0x4, 0x0, 0x4, 0x0, 0x6, 0x0, 0x2, 0x0, 0x3, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x80, 0x0, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+005D "]" */
|
||||
0x2, 0x0, 0x2, 0x0, 0x2, 0x0, 0x2, 0x0, 0x2, 0x0, 0x2, 0x0, 0x2, 0x0, 0x2, 0x0, 0x2, 0x0, 0x2, 0x0, 0x2, 0x0, 0x2, 0x0, 0x2, 0x0, 0x2, 0x0, 0x3E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+005E "^" */
|
||||
0xE, 0x0, 0xA, 0x0, 0x1B, 0x0, 0x11, 0x0, 0x31, 0x80, 0x20, 0x80, 0x60, 0xC0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+005F "_" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7F, 0xC0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0060 "`" */
|
||||
0xC, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0061 "a" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1E, 0x0, 0x21, 0x0, 0x1, 0x80, 0x1, 0x80, 0x3F, 0x80, 0x61, 0x80, 0x61, 0x80, 0x61, 0x80, 0x3E, 0xC0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0062 "b" */
|
||||
0x20, 0x0, 0x20, 0x0, 0x20, 0x0, 0x20, 0x0, 0x2F, 0x0, 0x31, 0x80, 0x20, 0xC0, 0x20, 0xC0, 0x20, 0xC0, 0x20, 0xC0, 0x20, 0xC0, 0x31, 0x80, 0x2F, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0063 "c" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xF, 0x0, 0x11, 0x80, 0x21, 0x0, 0x20, 0x0, 0x20, 0x0, 0x20, 0x0, 0x20, 0x80, 0x31, 0x80, 0xF, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0064 "d" */
|
||||
0x0, 0x80, 0x0, 0x80, 0x0, 0x80, 0x0, 0x80, 0x1E, 0x80, 0x31, 0x80, 0x60, 0x80, 0x60, 0x80, 0x60, 0x80, 0x60, 0x80, 0x60, 0x80, 0x31, 0x80, 0x1E, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0065 "e" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1F, 0x0, 0x31, 0x80, 0x20, 0x80, 0x60, 0xC0, 0x7F, 0xC0, 0x60, 0x0, 0x20, 0x0, 0x30, 0x80, 0x1F, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0066 "f" */
|
||||
0x7, 0xC0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x7F, 0xC0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x3F, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0067 "g" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xC0, 0x1F, 0x0, 0x31, 0x80, 0x20, 0x80, 0x20, 0x80, 0x31, 0x80, 0x1F, 0x0, 0x20, 0x0, 0x20, 0x0, 0x3F, 0x80, 0x20, 0x40, 0x60, 0x40, 0x60, 0xC0, 0x3F, 0x80, 0x0, 0x0,
|
||||
/* U+0068 "h" */
|
||||
0x20, 0x0, 0x20, 0x0, 0x20, 0x0, 0x20, 0x0, 0x2F, 0x0, 0x31, 0x80, 0x20, 0x80, 0x20, 0x80, 0x20, 0x80, 0x20, 0x80, 0x20, 0x80, 0x20, 0x80, 0x20, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0069 "i" */
|
||||
0x6, 0x0, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3E, 0x0, 0x6, 0x0, 0x6, 0x0, 0x6, 0x0, 0x6, 0x0, 0x6, 0x0, 0x6, 0x0, 0x6, 0x0, 0x3F, 0xC0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+006A "j" */
|
||||
0x3, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3F, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3E, 0x0, 0x0, 0x0,
|
||||
/* U+006B "k" */
|
||||
0x20, 0x0, 0x20, 0x0, 0x20, 0x0, 0x20, 0x0, 0x20, 0xC0, 0x21, 0x0, 0x26, 0x0, 0x2C, 0x0, 0x3E, 0x0, 0x33, 0x0, 0x21, 0x0, 0x21, 0x80, 0x20, 0xC0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+006C "l" */
|
||||
0x3C, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x3F, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+006D "m" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x59, 0x80, 0x66, 0xC0, 0x44, 0x40, 0x44, 0x40, 0x44, 0x40, 0x44, 0x40, 0x44, 0x40, 0x44, 0x40, 0x44, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+006E "n" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2F, 0x0, 0x31, 0x80, 0x20, 0x80, 0x20, 0x80, 0x20, 0x80, 0x20, 0x80, 0x20, 0x80, 0x20, 0x80, 0x20, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+006F "o" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1F, 0x0, 0x31, 0x80, 0x20, 0x80, 0x60, 0xC0, 0x60, 0xC0, 0x60, 0xC0, 0x20, 0x80, 0x31, 0x80, 0x1F, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0070 "p" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2F, 0x0, 0x31, 0x80, 0x20, 0xC0, 0x20, 0xC0, 0x20, 0xC0, 0x20, 0xC0, 0x20, 0xC0, 0x31, 0x80, 0x2F, 0x0, 0x20, 0x0, 0x20, 0x0, 0x20, 0x0, 0x20, 0x0, 0x0, 0x0,
|
||||
/* U+0071 "q" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1E, 0x80, 0x31, 0x80, 0x60, 0x80, 0x60, 0x80, 0x60, 0x80, 0x60, 0x80, 0x60, 0x80, 0x31, 0x80, 0x1E, 0x80, 0x0, 0x80, 0x0, 0x80, 0x0, 0x80, 0x0, 0x80, 0x0, 0x0,
|
||||
/* U+0072 "r" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7D, 0xC0, 0xE, 0x0, 0xC, 0x0, 0xC, 0x0, 0xC, 0x0, 0xC, 0x0, 0xC, 0x0, 0xC, 0x0, 0x7F, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0073 "s" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1F, 0x0, 0x30, 0x80, 0x20, 0x0, 0x30, 0x0, 0x1F, 0x0, 0x0, 0x80, 0x0, 0xC0, 0x60, 0x80, 0x1F, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0074 "t" */
|
||||
0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x7F, 0xC0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0x8, 0x0, 0xF, 0xC0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0075 "u" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x80, 0x20, 0x80, 0x20, 0x80, 0x20, 0x80, 0x20, 0x80, 0x20, 0x80, 0x20, 0x80, 0x31, 0x80, 0x1E, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0076 "v" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x60, 0xC0, 0x20, 0x80, 0x31, 0x80, 0x11, 0x0, 0x11, 0x0, 0x1B, 0x0, 0xA, 0x0, 0xA, 0x0, 0xE, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0077 "w" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x44, 0x40, 0x4E, 0x40, 0x4A, 0x40, 0x4A, 0x40, 0x6A, 0x40, 0x2A, 0x80, 0x31, 0x80, 0x31, 0x80, 0x31, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0078 "x" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x60, 0xC0, 0x31, 0x80, 0x1B, 0x0, 0xE, 0x0, 0x4, 0x0, 0xA, 0x0, 0x1B, 0x0, 0x31, 0x80, 0x60, 0xC0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0079 "y" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x60, 0xC0, 0x20, 0x80, 0x30, 0x80, 0x31, 0x80, 0x11, 0x0, 0x1B, 0x0, 0xA, 0x0, 0xE, 0x0, 0x6, 0x0, 0x4, 0x0, 0xC, 0x0, 0x8, 0x0, 0x38, 0x0, 0x0, 0x0,
|
||||
/* U+007A "z" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3F, 0x80, 0x1, 0x80, 0x3, 0x0, 0x6, 0x0, 0x4, 0x0, 0x8, 0x0, 0x18, 0x0, 0x30, 0x0, 0x3F, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+007B "{" */
|
||||
0xC, 0x0, 0xC, 0x0, 0x4, 0x0, 0x6, 0x0, 0x2, 0x0, 0x2, 0x0, 0x3C, 0x0, 0x6, 0x0, 0x2, 0x0, 0x6, 0x0, 0x4, 0x0, 0xC, 0x0, 0xC, 0x0, 0xC, 0x0, 0x7, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+007C "|" */
|
||||
0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+007D "}" */
|
||||
0x6, 0x0, 0x6, 0x0, 0x4, 0x0, 0xC, 0x0, 0x8, 0x0, 0x8, 0x0, 0x7, 0x80, 0xC, 0x0, 0x8, 0x0, 0xC, 0x0, 0x4, 0x0, 0x6, 0x0, 0x6, 0x0, 0x6, 0x0, 0x3C, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+007E "~" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x38, 0x40, 0x2C, 0x40, 0x46, 0x80, 0x43, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
};
|
||||
|
||||
const FixedWidthFont ibmplexmono_18_font = {
|
||||
.glyph_width = 11,
|
||||
.glyph_height = 18,
|
||||
.glyph_bytes_per_row = 2,
|
||||
.first_codepoint = 0x20,
|
||||
.last_codepoint = 0x7E,
|
||||
.glyph_bitmap = ibmplexmono18_glyph_bitmap,
|
||||
};
|
||||
|
||||
#endif // CONFIG_TT_FONT_IBMPLEXMONO_18
|
||||
222
Modules/font-module/source/ibmplexmono24.c
Normal file
222
Modules/font-module/source/ibmplexmono24.c
Normal file
@ -0,0 +1,222 @@
|
||||
/*
|
||||
* ibmplexmono24.c - ibmplexmono24 FixedWidthFont
|
||||
*
|
||||
* Rasterized from a TTF with Modules/font-module/scripts/generate.py.
|
||||
* Each glyph is 14 pixels wide and 24 pixels tall, stored as 24 rows of
|
||||
* 2 bytes each (bit 7 of the first byte = leftmost pixel).
|
||||
*/
|
||||
|
||||
#include <font/ibmplexmono24.h>
|
||||
|
||||
#ifdef ESP_PLATFORM
|
||||
#include <sdkconfig.h>
|
||||
#endif
|
||||
|
||||
// See Modules/font-module/Kconfig: undefined (POSIX, or an ESP-IDF build predating
|
||||
// this font's Kconfig entry) is treated the same as enabled.
|
||||
#if !defined(CONFIG_TT_FONT_IBMPLEXMONO_24) || CONFIG_TT_FONT_IBMPLEXMONO_24
|
||||
|
||||
// Glyph bitmap data: 95 characters (0x20-0x7E), 48 bytes each = 4560 bytes
|
||||
static const uint8_t ibmplexmono24_glyph_bitmap[] = {
|
||||
/* U+0020 " " */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0021 "!" */
|
||||
0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x7, 0x80, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0022 "\"" */
|
||||
0xC, 0xC0, 0xC, 0xC0, 0xC, 0xC0, 0xC, 0xC0, 0xC, 0xC0, 0xC, 0xC0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0023 "#" */
|
||||
0x6, 0x30, 0x6, 0x20, 0x6, 0x60, 0x6, 0x60, 0x4, 0x60, 0x7C, 0x7C, 0x7C, 0x7C, 0xC, 0x40, 0xC, 0xC0, 0x8, 0xC0, 0xF8, 0xF8, 0xF8, 0xF8, 0x18, 0x80, 0x19, 0x80, 0x19, 0x80, 0x11, 0x80, 0x31, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0024 "$" */
|
||||
0xF, 0xC0, 0x1F, 0xF0, 0x39, 0x38, 0x31, 0x10, 0x31, 0x0, 0x31, 0x0, 0x39, 0x0, 0x1F, 0x80, 0xF, 0xE0, 0x1, 0xF0, 0x1, 0x38, 0x1, 0x18, 0x1, 0x18, 0x61, 0x18, 0x39, 0x38, 0x1F, 0xF0, 0xF, 0xC0, 0x1, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0025 "%" */
|
||||
0x3C, 0xC, 0x7E, 0x18, 0xC6, 0x10, 0xC2, 0x30, 0xC2, 0x20, 0xC6, 0x60, 0x7E, 0x40, 0x3C, 0x80, 0x0, 0x0, 0x0, 0xF0, 0xD, 0xF8, 0x19, 0x8C, 0x11, 0xC, 0x31, 0xC, 0x21, 0x8C, 0x61, 0xF8, 0xC0, 0xF0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0026 "&" */
|
||||
0xF, 0x0, 0x1F, 0x80, 0x38, 0xC0, 0x30, 0x80, 0x30, 0x0, 0x30, 0x0, 0x18, 0x0, 0x1C, 0x38, 0x3E, 0x38, 0x76, 0x20, 0x63, 0x20, 0xC1, 0xA0, 0xC1, 0xE0, 0xE0, 0xE0, 0x70, 0xF0, 0x7F, 0x30, 0x1E, 0x1C, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0027 "'" */
|
||||
0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0028 "(" */
|
||||
0x0, 0xC0, 0x1, 0x80, 0x1, 0x0, 0x3, 0x0, 0x2, 0x0, 0x6, 0x0, 0x6, 0x0, 0x6, 0x0, 0x6, 0x0, 0x6, 0x0, 0x6, 0x0, 0x6, 0x0, 0x6, 0x0, 0x6, 0x0, 0x2, 0x0, 0x3, 0x0, 0x1, 0x0, 0x1, 0x80, 0x0, 0xC0, 0x0, 0x70, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0029 ")" */
|
||||
0xC, 0x0, 0x6, 0x0, 0x2, 0x0, 0x3, 0x0, 0x1, 0x0, 0x1, 0x80, 0x1, 0x80, 0x1, 0x80, 0x1, 0x80, 0x1, 0x80, 0x1, 0x80, 0x1, 0x80, 0x1, 0x80, 0x1, 0x80, 0x1, 0x0, 0x3, 0x0, 0x2, 0x0, 0x6, 0x0, 0xC, 0x0, 0x38, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+002A "*" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x73, 0x38, 0x3F, 0xF0, 0x7, 0x80, 0x7, 0x80, 0xC, 0xC0, 0xC, 0xC0, 0x18, 0x60, 0x10, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+002B "+" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x7F, 0xF8, 0x7F, 0xF8, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+002C "," */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x80, 0x3, 0x0, 0x7, 0x0, 0x6, 0x0, 0x6, 0x0, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+002D "-" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xF, 0xE0, 0xF, 0xE0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+002E "." */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x7, 0x80, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+002F "/" */
|
||||
0x0, 0x30, 0x0, 0x60, 0x0, 0x60, 0x0, 0x40, 0x0, 0xC0, 0x0, 0xC0, 0x1, 0x80, 0x1, 0x80, 0x1, 0x0, 0x3, 0x0, 0x3, 0x0, 0x6, 0x0, 0x6, 0x0, 0x4, 0x0, 0xC, 0x0, 0xC, 0x0, 0x18, 0x0, 0x18, 0x0, 0x10, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0030 "0" */
|
||||
0x7, 0x80, 0x1F, 0xE0, 0x38, 0x70, 0x30, 0x30, 0x30, 0x30, 0x60, 0x18, 0x60, 0x18, 0x63, 0x18, 0x63, 0x18, 0x63, 0x18, 0x60, 0x18, 0x60, 0x18, 0x30, 0x30, 0x30, 0x30, 0x38, 0x70, 0x1F, 0xE0, 0x7, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0031 "1" */
|
||||
0x7, 0x80, 0xF, 0x80, 0x1D, 0x80, 0x39, 0x80, 0x71, 0x80, 0x21, 0x80, 0x41, 0x80, 0x1, 0x80, 0x1, 0x80, 0x1, 0x80, 0x1, 0x80, 0x1, 0x80, 0x1, 0x80, 0x1, 0x80, 0x1, 0x80, 0x3F, 0xF8, 0x3F, 0xF8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0032 "2" */
|
||||
0xF, 0x80, 0x1F, 0xE0, 0x38, 0x60, 0x30, 0x30, 0x60, 0x30, 0x0, 0x30, 0x0, 0x30, 0x0, 0x60, 0x0, 0xE0, 0x1, 0xC0, 0x3, 0x80, 0x7, 0x0, 0xE, 0x0, 0x18, 0x0, 0x30, 0x0, 0x7F, 0xF8, 0x7F, 0xF8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0033 "3" */
|
||||
0xF, 0x80, 0x1F, 0xE0, 0x38, 0x70, 0x30, 0x30, 0x0, 0x30, 0x0, 0x30, 0x0, 0x60, 0xF, 0xC0, 0xF, 0xC0, 0x0, 0x60, 0x0, 0x30, 0x0, 0x30, 0x0, 0x30, 0x60, 0x30, 0x70, 0x70, 0x3F, 0xE0, 0xF, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0034 "4" */
|
||||
0x0, 0xE0, 0x1, 0xE0, 0x3, 0x60, 0x3, 0x60, 0x6, 0x60, 0x4, 0x60, 0xC, 0x60, 0x18, 0x60, 0x18, 0x60, 0x30, 0x60, 0x20, 0x60, 0x60, 0x60, 0x7F, 0xF8, 0x7F, 0xF8, 0x0, 0x60, 0x0, 0x60, 0x0, 0x60, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0035 "5" */
|
||||
0x1F, 0xF0, 0x1F, 0xF0, 0x10, 0x0, 0x30, 0x0, 0x30, 0x0, 0x30, 0x0, 0x37, 0xC0, 0x3F, 0xE0, 0x38, 0x70, 0x0, 0x30, 0x0, 0x38, 0x0, 0x18, 0x0, 0x38, 0x30, 0x30, 0x38, 0x70, 0x1F, 0xE0, 0xF, 0xC0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0036 "6" */
|
||||
0x1, 0xC0, 0x3, 0x0, 0x6, 0x0, 0xC, 0x0, 0x18, 0x0, 0x18, 0x0, 0x33, 0xC0, 0x3F, 0xE0, 0x38, 0x70, 0x70, 0x30, 0x60, 0x18, 0x60, 0x18, 0x20, 0x18, 0x30, 0x30, 0x38, 0x70, 0x1F, 0xE0, 0x7, 0xC0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0037 "7" */
|
||||
0x7F, 0xF8, 0x7F, 0xF8, 0x60, 0x30, 0x60, 0x30, 0x60, 0x60, 0x0, 0x60, 0x0, 0x60, 0x0, 0xC0, 0x0, 0xC0, 0x1, 0x80, 0x1, 0x80, 0x3, 0x0, 0x3, 0x0, 0x7, 0x0, 0x6, 0x0, 0x6, 0x0, 0xC, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0038 "8" */
|
||||
0xF, 0xC0, 0x1F, 0xE0, 0x38, 0x70, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x38, 0x70, 0xF, 0xC0, 0xF, 0xC0, 0x38, 0x70, 0x70, 0x38, 0x60, 0x18, 0x60, 0x18, 0x70, 0x38, 0x38, 0x70, 0x3F, 0xF0, 0xF, 0xC0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0039 "9" */
|
||||
0xF, 0x80, 0x1F, 0xE0, 0x38, 0x70, 0x30, 0x30, 0x60, 0x10, 0x60, 0x18, 0x60, 0x18, 0x30, 0x38, 0x38, 0x70, 0x1F, 0xF0, 0xF, 0x30, 0x0, 0x60, 0x0, 0x60, 0x0, 0xC0, 0x1, 0x80, 0x3, 0x80, 0xE, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+003A ":" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x7, 0x80, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x7, 0x80, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+003B ";" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x0, 0x7, 0x80, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0x80, 0x3, 0x0, 0x7, 0x0, 0x6, 0x0, 0x6, 0x0, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+003C "<" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x30, 0x0, 0xE0, 0x3, 0xC0, 0x7, 0x0, 0x1C, 0x0, 0x30, 0x0, 0x30, 0x0, 0x1C, 0x0, 0x7, 0x0, 0x3, 0xC0, 0x0, 0xF0, 0x0, 0x30, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+003D "=" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7F, 0xF8, 0x7F, 0xF8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7F, 0xF8, 0x7F, 0xF8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+003E ">" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x0, 0x30, 0x0, 0x3C, 0x0, 0xF, 0x0, 0x3, 0x80, 0x0, 0xE0, 0x0, 0x30, 0x0, 0x30, 0x0, 0xE0, 0x3, 0x80, 0xF, 0x0, 0x1C, 0x0, 0x30, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+003F "?" */
|
||||
0x7, 0xC0, 0x1F, 0xE0, 0x38, 0x70, 0x30, 0x30, 0x10, 0x30, 0x0, 0x30, 0x0, 0x60, 0x1, 0xC0, 0x3, 0x80, 0x2, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0x0, 0x7, 0x0, 0x7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0040 "@" */
|
||||
0x7, 0xC0, 0x1F, 0xE0, 0x18, 0x70, 0x30, 0x30, 0x30, 0x30, 0x21, 0xD0, 0x63, 0xD0, 0x66, 0x30, 0x66, 0x10, 0x66, 0x10, 0x66, 0x10, 0x66, 0x10, 0x66, 0x30, 0x63, 0xD0, 0x23, 0xD0, 0x30, 0x0, 0x30, 0x0, 0x18, 0x0, 0x1F, 0xE0, 0x7, 0xE0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0041 "A" */
|
||||
0x3, 0x80, 0x7, 0x80, 0x7, 0x80, 0x5, 0x80, 0xC, 0xC0, 0xC, 0xC0, 0xC, 0xC0, 0x18, 0x60, 0x18, 0x60, 0x18, 0x60, 0x3F, 0xF0, 0x3F, 0xF0, 0x30, 0x30, 0x30, 0x30, 0x60, 0x18, 0x60, 0x18, 0x60, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0042 "B" */
|
||||
0x3F, 0xC0, 0x3F, 0xE0, 0x30, 0x70, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x70, 0x3F, 0xC0, 0x3F, 0xE0, 0x30, 0x30, 0x30, 0x18, 0x30, 0x18, 0x30, 0x18, 0x30, 0x18, 0x30, 0x30, 0x3F, 0xF0, 0x3F, 0xC0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0043 "C" */
|
||||
0x7, 0xC0, 0xF, 0xE0, 0x1C, 0x70, 0x38, 0x30, 0x30, 0x28, 0x30, 0x0, 0x30, 0x0, 0x70, 0x0, 0x70, 0x0, 0x70, 0x0, 0x30, 0x0, 0x30, 0x0, 0x30, 0x20, 0x38, 0x38, 0x1C, 0x70, 0xF, 0xE0, 0x7, 0xC0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0044 "D" */
|
||||
0x3F, 0x80, 0x3F, 0xE0, 0x30, 0x70, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x30, 0x18, 0x30, 0x18, 0x30, 0x18, 0x30, 0x18, 0x30, 0x18, 0x30, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x70, 0x3F, 0xE0, 0x3F, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0045 "E" */
|
||||
0x3F, 0xF0, 0x3F, 0xF0, 0x30, 0x0, 0x30, 0x0, 0x30, 0x0, 0x30, 0x0, 0x30, 0x0, 0x3F, 0xF0, 0x3F, 0xF0, 0x30, 0x0, 0x30, 0x0, 0x30, 0x0, 0x30, 0x0, 0x30, 0x0, 0x30, 0x0, 0x3F, 0xF0, 0x3F, 0xF0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0046 "F" */
|
||||
0x3F, 0xF8, 0x3F, 0xF8, 0x30, 0x0, 0x30, 0x0, 0x30, 0x0, 0x30, 0x0, 0x30, 0x0, 0x3F, 0xF0, 0x3F, 0xF0, 0x30, 0x0, 0x30, 0x0, 0x30, 0x0, 0x30, 0x0, 0x30, 0x0, 0x30, 0x0, 0x30, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0047 "G" */
|
||||
0x7, 0x80, 0x1F, 0xE0, 0x38, 0x70, 0x30, 0x30, 0x30, 0x20, 0x60, 0x0, 0x60, 0x0, 0x60, 0x0, 0x61, 0xF0, 0x61, 0xF0, 0x60, 0x30, 0x60, 0x30, 0x30, 0x30, 0x30, 0x30, 0x38, 0x70, 0x1F, 0xF0, 0xF, 0xB0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0048 "H" */
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3F, 0xF0, 0x3F, 0xF0, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0049 "I" */
|
||||
0x3F, 0xF0, 0x3F, 0xF0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3F, 0xF0, 0x3F, 0xF0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+004A "J" */
|
||||
0x1F, 0xE0, 0x1F, 0xE0, 0x0, 0x60, 0x0, 0x60, 0x0, 0x60, 0x0, 0x60, 0x0, 0x60, 0x0, 0x60, 0x0, 0x60, 0x0, 0x60, 0x0, 0x60, 0x0, 0x60, 0x0, 0x60, 0x30, 0x60, 0x38, 0xE0, 0x1F, 0xC0, 0xF, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+004B "K" */
|
||||
0x30, 0x18, 0x30, 0x30, 0x30, 0x60, 0x30, 0xE0, 0x31, 0xC0, 0x31, 0x80, 0x33, 0x0, 0x37, 0x0, 0x3F, 0x0, 0x3D, 0x80, 0x39, 0xC0, 0x30, 0xC0, 0x30, 0x60, 0x30, 0x70, 0x30, 0x30, 0x30, 0x38, 0x30, 0x1C, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+004C "L" */
|
||||
0x18, 0x0, 0x18, 0x0, 0x18, 0x0, 0x18, 0x0, 0x18, 0x0, 0x18, 0x0, 0x18, 0x0, 0x18, 0x0, 0x18, 0x0, 0x18, 0x0, 0x18, 0x0, 0x18, 0x0, 0x18, 0x0, 0x18, 0x0, 0x18, 0x0, 0x1F, 0xF8, 0x1F, 0xF8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+004D "M" */
|
||||
0x70, 0x38, 0x78, 0x78, 0x78, 0x78, 0x68, 0x58, 0x6C, 0xD8, 0x6C, 0xD8, 0x66, 0x98, 0x67, 0x98, 0x63, 0x18, 0x63, 0x18, 0x63, 0x18, 0x62, 0x18, 0x60, 0x18, 0x60, 0x18, 0x60, 0x18, 0x60, 0x18, 0x60, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+004E "N" */
|
||||
0x38, 0x30, 0x38, 0x30, 0x3C, 0x30, 0x2C, 0x30, 0x2C, 0x30, 0x26, 0x30, 0x26, 0x30, 0x22, 0x30, 0x23, 0x30, 0x23, 0x30, 0x21, 0xB0, 0x21, 0xB0, 0x20, 0xB0, 0x20, 0xF0, 0x20, 0xF0, 0x20, 0x70, 0x20, 0x70, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+004F "O" */
|
||||
0x7, 0x80, 0x1F, 0xE0, 0x38, 0x70, 0x30, 0x30, 0x30, 0x30, 0x60, 0x18, 0x60, 0x18, 0x60, 0x18, 0x60, 0x18, 0x60, 0x18, 0x60, 0x18, 0x60, 0x18, 0x30, 0x30, 0x30, 0x30, 0x38, 0x70, 0x1F, 0xE0, 0x7, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0050 "P" */
|
||||
0x3F, 0xC0, 0x3F, 0xF0, 0x30, 0x30, 0x30, 0x18, 0x30, 0x18, 0x30, 0x18, 0x30, 0x18, 0x30, 0x30, 0x3F, 0xF0, 0x3F, 0xE0, 0x30, 0x0, 0x30, 0x0, 0x30, 0x0, 0x30, 0x0, 0x30, 0x0, 0x30, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0051 "Q" */
|
||||
0x7, 0x80, 0x1F, 0xE0, 0x38, 0x70, 0x30, 0x30, 0x30, 0x30, 0x60, 0x18, 0x60, 0x18, 0x60, 0x18, 0x60, 0x18, 0x60, 0x18, 0x60, 0x18, 0x60, 0x18, 0x30, 0x30, 0x30, 0x30, 0x38, 0x70, 0x1F, 0xE0, 0xF, 0xC0, 0x3, 0x0, 0x3, 0x0, 0x3, 0xF0, 0x1, 0xF0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0052 "R" */
|
||||
0x3F, 0xC0, 0x3F, 0xF0, 0x30, 0x30, 0x30, 0x18, 0x30, 0x18, 0x30, 0x18, 0x30, 0x18, 0x30, 0x30, 0x3F, 0xF0, 0x3F, 0xC0, 0x31, 0x80, 0x30, 0xC0, 0x30, 0xC0, 0x30, 0x60, 0x30, 0x60, 0x30, 0x30, 0x30, 0x38, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0053 "S" */
|
||||
0xF, 0xC0, 0x1F, 0xE0, 0x38, 0x70, 0x30, 0x18, 0x70, 0x0, 0x30, 0x0, 0x38, 0x0, 0x3F, 0x80, 0xF, 0xE0, 0x0, 0xF0, 0x0, 0x38, 0x0, 0x18, 0x0, 0x18, 0x60, 0x38, 0x78, 0x70, 0x3F, 0xE0, 0xF, 0xC0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0054 "T" */
|
||||
0xFF, 0xFC, 0xFF, 0xFC, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0055 "U" */
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x38, 0x70, 0x1F, 0xE0, 0xF, 0xC0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0056 "V" */
|
||||
0x60, 0x18, 0x60, 0x18, 0x70, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x60, 0x18, 0x60, 0x18, 0x60, 0x18, 0x60, 0xC, 0xC0, 0xC, 0xC0, 0xC, 0xC0, 0x7, 0x80, 0x7, 0x80, 0x7, 0x80, 0x7, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0057 "W" */
|
||||
0x40, 0x8, 0x60, 0x18, 0x60, 0x18, 0x60, 0x18, 0x63, 0x18, 0x63, 0x18, 0x67, 0x98, 0x67, 0x98, 0x66, 0x98, 0x64, 0x98, 0x64, 0x98, 0x2C, 0xD0, 0x2C, 0xD0, 0x2C, 0xD0, 0x28, 0x50, 0x38, 0x70, 0x38, 0x70, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0058 "X" */
|
||||
0x60, 0x18, 0x30, 0x38, 0x30, 0x30, 0x18, 0x60, 0xC, 0xE0, 0xC, 0xC0, 0x7, 0x80, 0x7, 0x80, 0x3, 0x0, 0x7, 0x80, 0x7, 0xC0, 0xC, 0xC0, 0x18, 0x60, 0x18, 0x60, 0x30, 0x30, 0x70, 0x38, 0xE0, 0x1C, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0059 "Y" */
|
||||
0xE0, 0x1C, 0x60, 0x18, 0x30, 0x30, 0x30, 0x30, 0x18, 0x60, 0x1C, 0xE0, 0xC, 0xC0, 0x7, 0x80, 0x7, 0x80, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+005A "Z" */
|
||||
0x7F, 0xF8, 0x7F, 0xF8, 0x0, 0x30, 0x0, 0x70, 0x0, 0xE0, 0x0, 0xC0, 0x1, 0x80, 0x3, 0x80, 0x3, 0x0, 0x6, 0x0, 0xC, 0x0, 0x1C, 0x0, 0x18, 0x0, 0x30, 0x0, 0x60, 0x0, 0x7F, 0xF8, 0x7F, 0xF8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+005B "[" */
|
||||
0x7, 0xF0, 0x6, 0x0, 0x6, 0x0, 0x6, 0x0, 0x6, 0x0, 0x6, 0x0, 0x6, 0x0, 0x6, 0x0, 0x6, 0x0, 0x6, 0x0, 0x6, 0x0, 0x6, 0x0, 0x6, 0x0, 0x6, 0x0, 0x6, 0x0, 0x6, 0x0, 0x6, 0x0, 0x6, 0x0, 0x7, 0xF0, 0x7, 0xF0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+005C "\\" */
|
||||
0x30, 0x0, 0x18, 0x0, 0x18, 0x0, 0x8, 0x0, 0xC, 0x0, 0xC, 0x0, 0x6, 0x0, 0x6, 0x0, 0x2, 0x0, 0x3, 0x0, 0x3, 0x0, 0x1, 0x80, 0x1, 0x80, 0x0, 0x80, 0x0, 0xC0, 0x0, 0xC0, 0x0, 0x60, 0x0, 0x60, 0x0, 0x20, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+005D "]" */
|
||||
0x3F, 0x80, 0x1, 0x80, 0x1, 0x80, 0x1, 0x80, 0x1, 0x80, 0x1, 0x80, 0x1, 0x80, 0x1, 0x80, 0x1, 0x80, 0x1, 0x80, 0x1, 0x80, 0x1, 0x80, 0x1, 0x80, 0x1, 0x80, 0x1, 0x80, 0x1, 0x80, 0x1, 0x80, 0x1, 0x80, 0x3F, 0x80, 0x3F, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+005E "^" */
|
||||
0x3, 0x0, 0x7, 0x80, 0x5, 0x80, 0xC, 0xC0, 0x18, 0x60, 0x18, 0x60, 0x30, 0x30, 0x30, 0x30, 0x60, 0x18, 0x20, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+005F "_" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7F, 0xF8, 0x7F, 0xF8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0060 "`" */
|
||||
0x6, 0x0, 0x3, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0061 "a" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xF, 0x80, 0x1F, 0xC0, 0x30, 0x60, 0x20, 0x60, 0x0, 0x60, 0x1F, 0xE0, 0x3F, 0xE0, 0x70, 0x60, 0x60, 0x60, 0x30, 0xA0, 0x3F, 0xB8, 0x1F, 0x38, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0062 "b" */
|
||||
0x30, 0x0, 0x30, 0x0, 0x30, 0x0, 0x30, 0x0, 0x30, 0x0, 0x33, 0xC0, 0x37, 0xE0, 0x38, 0x70, 0x30, 0x30, 0x30, 0x18, 0x30, 0x18, 0x30, 0x18, 0x30, 0x18, 0x30, 0x30, 0x38, 0x70, 0x37, 0xE0, 0x33, 0xC0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0063 "c" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0xC0, 0x1F, 0xE0, 0x18, 0x70, 0x30, 0x20, 0x30, 0x0, 0x30, 0x0, 0x30, 0x0, 0x30, 0x0, 0x30, 0x30, 0x18, 0x70, 0x1F, 0xE0, 0x7, 0xC0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0064 "d" */
|
||||
0x0, 0x30, 0x0, 0x30, 0x0, 0x30, 0x0, 0x30, 0x0, 0x30, 0xF, 0x30, 0x1F, 0xB0, 0x38, 0x70, 0x30, 0x30, 0x60, 0x30, 0x60, 0x30, 0x60, 0x30, 0x60, 0x30, 0x30, 0x30, 0x38, 0x70, 0x1F, 0xB0, 0xF, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0065 "e" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0xC0, 0x1F, 0xE0, 0x38, 0x30, 0x30, 0x30, 0x3F, 0xF8, 0x7F, 0xF8, 0x60, 0x0, 0x30, 0x0, 0x30, 0x20, 0x38, 0x70, 0x1F, 0xE0, 0x7, 0xC0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0066 "f" */
|
||||
0x3, 0xF8, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3F, 0xF8, 0x3F, 0xF8, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3F, 0xF0, 0x3F, 0xF0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0067 "g" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x38, 0x0, 0x78, 0xF, 0xC0, 0x1F, 0xE0, 0x38, 0x70, 0x30, 0x30, 0x30, 0x30, 0x38, 0x60, 0x1F, 0xE0, 0xF, 0x80, 0x10, 0x0, 0x30, 0x0, 0x3F, 0xF0, 0x1F, 0xF8, 0x30, 0x18, 0x60, 0x18, 0x70, 0x18, 0x3F, 0xF0, 0x1F, 0xE0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0068 "h" */
|
||||
0x30, 0x0, 0x30, 0x0, 0x30, 0x0, 0x30, 0x0, 0x30, 0x0, 0x33, 0xC0, 0x37, 0xE0, 0x38, 0x70, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0069 "i" */
|
||||
0x3, 0x80, 0x1, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3F, 0x80, 0x3F, 0x80, 0x1, 0x80, 0x1, 0x80, 0x1, 0x80, 0x1, 0x80, 0x1, 0x80, 0x1, 0x80, 0x1, 0x80, 0x1, 0x80, 0x3F, 0xF8, 0x3F, 0xF8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+006A "j" */
|
||||
0x0, 0xE0, 0x0, 0xC0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3F, 0xC0, 0x3F, 0xC0, 0x0, 0xC0, 0x0, 0xC0, 0x0, 0xC0, 0x0, 0xC0, 0x0, 0xC0, 0x0, 0xC0, 0x0, 0xC0, 0x0, 0xC0, 0x0, 0xC0, 0x0, 0xC0, 0x0, 0xC0, 0x0, 0xC0, 0x0, 0xC0, 0x3F, 0xC0, 0x3F, 0x80, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+006B "k" */
|
||||
0x30, 0x0, 0x30, 0x0, 0x30, 0x0, 0x30, 0x0, 0x30, 0x0, 0x30, 0x38, 0x30, 0x60, 0x30, 0xC0, 0x31, 0x80, 0x33, 0x0, 0x37, 0x0, 0x3D, 0x80, 0x30, 0xC0, 0x30, 0xE0, 0x30, 0x70, 0x30, 0x30, 0x30, 0x1C, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+006C "l" */
|
||||
0x3F, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3F, 0xF0, 0x3F, 0xF0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+006D "m" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6E, 0x70, 0x7E, 0xF8, 0x63, 0x18, 0x63, 0x18, 0x63, 0x18, 0x63, 0x18, 0x63, 0x18, 0x63, 0x18, 0x63, 0x18, 0x63, 0x18, 0x63, 0x18, 0x63, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+006E "n" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x33, 0xC0, 0x37, 0xE0, 0x38, 0x70, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+006F "o" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xF, 0xC0, 0x1F, 0xE0, 0x38, 0x70, 0x30, 0x30, 0x60, 0x10, 0x60, 0x18, 0x60, 0x18, 0x60, 0x10, 0x30, 0x30, 0x38, 0x70, 0x1F, 0xE0, 0xF, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0070 "p" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x33, 0xC0, 0x37, 0xE0, 0x38, 0x70, 0x30, 0x30, 0x30, 0x18, 0x30, 0x18, 0x30, 0x18, 0x30, 0x18, 0x30, 0x30, 0x38, 0x70, 0x37, 0xE0, 0x33, 0xC0, 0x30, 0x0, 0x30, 0x0, 0x30, 0x0, 0x30, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0071 "q" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xF, 0x30, 0x1F, 0xB0, 0x38, 0x70, 0x30, 0x30, 0x60, 0x30, 0x60, 0x30, 0x60, 0x30, 0x60, 0x30, 0x30, 0x30, 0x38, 0x70, 0x1F, 0xB0, 0xF, 0x30, 0x0, 0x30, 0x0, 0x30, 0x0, 0x30, 0x0, 0x30, 0x0, 0x30, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0072 "r" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3E, 0x78, 0x3E, 0xF8, 0x6, 0x80, 0x7, 0x0, 0x6, 0x0, 0x6, 0x0, 0x6, 0x0, 0x6, 0x0, 0x6, 0x0, 0x6, 0x0, 0x3F, 0xF0, 0x3F, 0xF0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0073 "s" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xF, 0xC0, 0x1F, 0xF0, 0x38, 0x30, 0x30, 0x0, 0x38, 0x0, 0x1F, 0xC0, 0x7, 0xF0, 0x0, 0x30, 0x0, 0x30, 0x30, 0x30, 0x7F, 0xF0, 0xF, 0xC0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0074 "t" */
|
||||
0x6, 0x0, 0x6, 0x0, 0x6, 0x0, 0x6, 0x0, 0x6, 0x0, 0x7F, 0xF0, 0x7F, 0xF0, 0x6, 0x0, 0x6, 0x0, 0x6, 0x0, 0x6, 0x0, 0x6, 0x0, 0x6, 0x0, 0x6, 0x0, 0x6, 0x0, 0x7, 0xF0, 0x3, 0xF0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0075 "u" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x38, 0x70, 0x1F, 0xB0, 0xF, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0076 "v" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x60, 0x18, 0x30, 0x30, 0x30, 0x30, 0x18, 0x20, 0x18, 0x60, 0x18, 0x60, 0xC, 0xC0, 0xC, 0xC0, 0xC, 0xC0, 0x7, 0x80, 0x7, 0x80, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0077 "w" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x43, 0xC, 0x43, 0x8, 0x67, 0x98, 0x67, 0x98, 0x64, 0x98, 0x64, 0x98, 0x24, 0x90, 0x2C, 0xD0, 0x2C, 0xD0, 0x38, 0x70, 0x38, 0x70, 0x38, 0x70, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0078 "x" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x70, 0x38, 0x18, 0x60, 0x1C, 0x60, 0xC, 0xC0, 0x7, 0x80, 0x3, 0x0, 0x7, 0x80, 0x7, 0x80, 0xC, 0xC0, 0x18, 0x60, 0x38, 0x70, 0x70, 0x38, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0079 "y" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x60, 0x18, 0x30, 0x30, 0x30, 0x30, 0x10, 0x30, 0x18, 0x60, 0x18, 0x60, 0xC, 0xC0, 0xC, 0xC0, 0x4, 0x80, 0x7, 0x80, 0x7, 0x80, 0x3, 0x0, 0x3, 0x0, 0x6, 0x0, 0x6, 0x0, 0x3E, 0x0, 0x3C, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+007A "z" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3F, 0xF0, 0x3F, 0xF0, 0x0, 0x70, 0x0, 0xE0, 0x1, 0x80, 0x3, 0x0, 0x6, 0x0, 0xC, 0x0, 0x18, 0x0, 0x30, 0x0, 0x3F, 0xF0, 0x3F, 0xF0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+007B "{" */
|
||||
0x7, 0xF0, 0x6, 0x0, 0x6, 0x0, 0x2, 0x0, 0x3, 0x0, 0x1, 0x80, 0x1, 0x80, 0x1, 0x80, 0x3F, 0x0, 0x3F, 0x0, 0x1, 0x80, 0x1, 0x80, 0x1, 0x80, 0x1, 0x0, 0x3, 0x0, 0x2, 0x0, 0x6, 0x0, 0x6, 0x0, 0x7, 0xF0, 0x3, 0xF0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+007C "|" */
|
||||
0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+007D "}" */
|
||||
0x3F, 0x80, 0x1, 0x80, 0x1, 0x80, 0x1, 0x0, 0x3, 0x0, 0x6, 0x0, 0x6, 0x0, 0x6, 0x0, 0x3, 0xF0, 0x3, 0xF0, 0x6, 0x0, 0x6, 0x0, 0x6, 0x0, 0x2, 0x0, 0x3, 0x0, 0x1, 0x0, 0x1, 0x80, 0x1, 0x80, 0x3F, 0x80, 0x3F, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+007E "~" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1C, 0x18, 0x3E, 0x18, 0x37, 0x18, 0x63, 0xB0, 0x61, 0xF0, 0x60, 0xE0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
};
|
||||
|
||||
const FixedWidthFont ibmplexmono_24_font = {
|
||||
.glyph_width = 14,
|
||||
.glyph_height = 24,
|
||||
.glyph_bytes_per_row = 2,
|
||||
.first_codepoint = 0x20,
|
||||
.last_codepoint = 0x7E,
|
||||
.glyph_bitmap = ibmplexmono24_glyph_bitmap,
|
||||
};
|
||||
|
||||
#endif // CONFIG_TT_FONT_IBMPLEXMONO_24
|
||||
222
Modules/font-module/source/ibmplexmono28.c
Normal file
222
Modules/font-module/source/ibmplexmono28.c
Normal file
@ -0,0 +1,222 @@
|
||||
/*
|
||||
* ibmplexmono28.c - ibmplexmono28 FixedWidthFont
|
||||
*
|
||||
* Rasterized from a TTF with Modules/font-module/scripts/generate.py.
|
||||
* Each glyph is 17 pixels wide and 28 pixels tall, stored as 28 rows of
|
||||
* 3 bytes each (bit 7 of the first byte = leftmost pixel).
|
||||
*/
|
||||
|
||||
#include <font/ibmplexmono28.h>
|
||||
|
||||
#ifdef ESP_PLATFORM
|
||||
#include <sdkconfig.h>
|
||||
#endif
|
||||
|
||||
// See Modules/font-module/Kconfig: undefined (POSIX, or an ESP-IDF build predating
|
||||
// this font's Kconfig entry) is treated the same as enabled.
|
||||
#if !defined(CONFIG_TT_FONT_IBMPLEXMONO_28) || CONFIG_TT_FONT_IBMPLEXMONO_28
|
||||
|
||||
// Glyph bitmap data: 95 characters (0x20-0x7E), 84 bytes each = 7980 bytes
|
||||
static const uint8_t ibmplexmono28_glyph_bitmap[] = {
|
||||
/* U+0020 " " */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0021 "!" */
|
||||
0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x0, 0x80, 0x0, 0x0, 0x80, 0x0, 0x0, 0x80, 0x0, 0x0, 0x80, 0x0, 0x0, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xC0, 0x0, 0x3, 0xE0, 0x0, 0x3, 0xE0, 0x0, 0x1, 0xC0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0022 "\"" */
|
||||
0x6, 0x30, 0x0, 0x6, 0x30, 0x0, 0x6, 0x30, 0x0, 0x6, 0x30, 0x0, 0x6, 0x30, 0x0, 0x6, 0x30, 0x0, 0x6, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0023 "#" */
|
||||
0x1, 0x8C, 0x0, 0x3, 0xC, 0x0, 0x3, 0x18, 0x0, 0x3, 0x18, 0x0, 0x3, 0x18, 0x0, 0x3, 0x18, 0x0, 0x3F, 0x1F, 0x0, 0x3E, 0x3F, 0x0, 0x6, 0x30, 0x0, 0x6, 0x30, 0x0, 0x6, 0x30, 0x0, 0x6, 0x30, 0x0, 0x7E, 0x3E, 0x0, 0x7C, 0x7E, 0x0, 0xC, 0x60, 0x0, 0xC, 0x60, 0x0, 0xC, 0x60, 0x0, 0xC, 0x60, 0x0, 0x18, 0x60, 0x0, 0x18, 0xC0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0024 "$" */
|
||||
0x7, 0xF0, 0x0, 0xF, 0xFC, 0x0, 0x1C, 0xDE, 0x0, 0x38, 0xC6, 0x0, 0x38, 0xC0, 0x0, 0x30, 0xC0, 0x0, 0x38, 0xC0, 0x0, 0x18, 0xC0, 0x0, 0x1F, 0xC0, 0x0, 0xF, 0xF0, 0x0, 0x1, 0xFC, 0x0, 0x0, 0xDE, 0x0, 0x0, 0xC6, 0x0, 0x0, 0xC6, 0x0, 0x0, 0xC7, 0x0, 0x20, 0xC6, 0x0, 0x30, 0xC6, 0x0, 0x7C, 0xDE, 0x0, 0x1F, 0xFC, 0x0, 0x7, 0xF0, 0x0, 0x0, 0xC0, 0x0, 0x0, 0xC0, 0x0, 0x0, 0xC0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0025 "%" */
|
||||
0x1E, 0x3, 0x0, 0x3F, 0x3, 0x0, 0x63, 0x86, 0x0, 0x61, 0x8E, 0x0, 0x61, 0x8C, 0x0, 0x61, 0x98, 0x0, 0x61, 0x98, 0x0, 0x63, 0xB0, 0x0, 0x3F, 0x0, 0x0, 0x1E, 0x0, 0x0, 0x0, 0x3C, 0x0, 0x0, 0x7E, 0x0, 0x6, 0xE3, 0x0, 0xC, 0xC3, 0x0, 0xC, 0xC3, 0x0, 0x18, 0xC3, 0x0, 0x30, 0xC3, 0x0, 0x30, 0xE3, 0x0, 0x60, 0x7E, 0x0, 0x60, 0x3C, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0026 "&" */
|
||||
0x7, 0xC0, 0x0, 0xF, 0xE0, 0x0, 0x1C, 0x70, 0x0, 0x18, 0x20, 0x0, 0x18, 0x0, 0x0, 0x18, 0x0, 0x0, 0x18, 0x0, 0x0, 0x1C, 0x0, 0x0, 0xE, 0x0, 0x0, 0xE, 0xF, 0x0, 0x3B, 0xF, 0x0, 0x33, 0x8C, 0x0, 0x71, 0xCC, 0x0, 0x60, 0xE8, 0x0, 0x60, 0x78, 0x0, 0x60, 0x38, 0x0, 0x70, 0x38, 0x0, 0x38, 0x6C, 0x0, 0x3F, 0xCE, 0x0, 0xF, 0x87, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0027 "'" */
|
||||
0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0028 "(" */
|
||||
0x0, 0x30, 0x0, 0x0, 0x60, 0x0, 0x0, 0xE0, 0x0, 0x0, 0xC0, 0x0, 0x1, 0x80, 0x0, 0x1, 0x80, 0x0, 0x1, 0x80, 0x0, 0x3, 0x0, 0x0, 0x3, 0x0, 0x0, 0x3, 0x0, 0x0, 0x3, 0x0, 0x0, 0x3, 0x0, 0x0, 0x3, 0x0, 0x0, 0x3, 0x0, 0x0, 0x3, 0x0, 0x0, 0x3, 0x0, 0x0, 0x1, 0x80, 0x0, 0x1, 0x80, 0x0, 0x1, 0x80, 0x0, 0x0, 0xC0, 0x0, 0x0, 0xE0, 0x0, 0x0, 0x60, 0x0, 0x0, 0x30, 0x0, 0x0, 0x1C, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0029 ")" */
|
||||
0x6, 0x0, 0x0, 0x3, 0x0, 0x0, 0x3, 0x80, 0x0, 0x1, 0x80, 0x0, 0x0, 0xC0, 0x0, 0x0, 0xC0, 0x0, 0x0, 0xC0, 0x0, 0x0, 0x60, 0x0, 0x0, 0x60, 0x0, 0x0, 0x60, 0x0, 0x0, 0x60, 0x0, 0x0, 0x60, 0x0, 0x0, 0x60, 0x0, 0x0, 0x60, 0x0, 0x0, 0x60, 0x0, 0x0, 0x60, 0x0, 0x0, 0xC0, 0x0, 0x0, 0xC0, 0x0, 0x0, 0xC0, 0x0, 0x1, 0x80, 0x0, 0x3, 0x80, 0x0, 0x3, 0x0, 0x0, 0x6, 0x0, 0x0, 0x1C, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+002A "*" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x21, 0xC2, 0x0, 0x7D, 0xDF, 0x0, 0x3F, 0xFE, 0x0, 0x7, 0xF0, 0x0, 0x3, 0xE0, 0x0, 0x3, 0x60, 0x0, 0x6, 0x30, 0x0, 0xE, 0x38, 0x0, 0xC, 0x18, 0x0, 0x18, 0xC, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+002B "+" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x3F, 0xFE, 0x0, 0x3F, 0xFE, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+002C "," */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xE0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0x80, 0x0, 0x3, 0x80, 0x0, 0x3, 0x80, 0x0, 0x3, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+002D "-" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xF, 0xF8, 0x0, 0xF, 0xF8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+002E "." */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xC0, 0x0, 0x3, 0xE0, 0x0, 0x3, 0xE0, 0x0, 0x1, 0xC0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+002F "/" */
|
||||
0x0, 0xC, 0x0, 0x0, 0x18, 0x0, 0x0, 0x18, 0x0, 0x0, 0x18, 0x0, 0x0, 0x30, 0x0, 0x0, 0x30, 0x0, 0x0, 0x60, 0x0, 0x0, 0x60, 0x0, 0x0, 0x60, 0x0, 0x0, 0xC0, 0x0, 0x0, 0xC0, 0x0, 0x1, 0x80, 0x0, 0x1, 0x80, 0x0, 0x1, 0x80, 0x0, 0x3, 0x0, 0x0, 0x3, 0x0, 0x0, 0x7, 0x0, 0x0, 0x6, 0x0, 0x0, 0x6, 0x0, 0x0, 0xC, 0x0, 0x0, 0xC, 0x0, 0x0, 0xC, 0x0, 0x0, 0x18, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0030 "0" */
|
||||
0x3, 0xE0, 0x0, 0xF, 0xF8, 0x0, 0x1C, 0x1C, 0x0, 0x18, 0xC, 0x0, 0x38, 0xE, 0x0, 0x30, 0x6, 0x0, 0x30, 0x6, 0x0, 0x30, 0x6, 0x0, 0x30, 0x6, 0x0, 0x31, 0xC6, 0x0, 0x31, 0xC6, 0x0, 0x31, 0xC6, 0x0, 0x30, 0x6, 0x0, 0x30, 0x6, 0x0, 0x30, 0x6, 0x0, 0x38, 0xE, 0x0, 0x18, 0xC, 0x0, 0x1C, 0x1C, 0x0, 0xF, 0xF8, 0x0, 0x3, 0xE0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0031 "1" */
|
||||
0x3, 0xC0, 0x0, 0x7, 0xC0, 0x0, 0xE, 0xC0, 0x0, 0x1C, 0xC0, 0x0, 0x38, 0xC0, 0x0, 0x38, 0xC0, 0x0, 0x30, 0xC0, 0x0, 0x0, 0xC0, 0x0, 0x0, 0xC0, 0x0, 0x0, 0xC0, 0x0, 0x0, 0xC0, 0x0, 0x0, 0xC0, 0x0, 0x0, 0xC0, 0x0, 0x0, 0xC0, 0x0, 0x0, 0xC0, 0x0, 0x0, 0xC0, 0x0, 0x0, 0xC0, 0x0, 0x0, 0xC0, 0x0, 0x3F, 0xFF, 0x0, 0x3F, 0xFF, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0032 "2" */
|
||||
0x7, 0xE0, 0x0, 0xF, 0xF8, 0x0, 0x1C, 0x38, 0x0, 0x38, 0x1C, 0x0, 0x30, 0xC, 0x0, 0x0, 0xC, 0x0, 0x0, 0xC, 0x0, 0x0, 0xC, 0x0, 0x0, 0x1C, 0x0, 0x0, 0x18, 0x0, 0x0, 0x38, 0x0, 0x0, 0x70, 0x0, 0x0, 0xE0, 0x0, 0x1, 0xC0, 0x0, 0x7, 0x0, 0x0, 0xE, 0x0, 0x0, 0x1C, 0x0, 0x0, 0x38, 0x0, 0x0, 0x3F, 0xFE, 0x0, 0x3F, 0xFE, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0033 "3" */
|
||||
0x7, 0xE0, 0x0, 0xF, 0xF8, 0x0, 0x1C, 0x38, 0x0, 0x38, 0x1C, 0x0, 0x10, 0xC, 0x0, 0x0, 0xC, 0x0, 0x0, 0xC, 0x0, 0x0, 0x1C, 0x0, 0x0, 0x38, 0x0, 0x7, 0xE0, 0x0, 0x7, 0xF0, 0x0, 0x0, 0x38, 0x0, 0x0, 0xC, 0x0, 0x0, 0xC, 0x0, 0x0, 0xE, 0x0, 0x20, 0xE, 0x0, 0x30, 0xC, 0x0, 0x78, 0x3C, 0x0, 0x1F, 0xF8, 0x0, 0x7, 0xE0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0034 "4" */
|
||||
0x0, 0x78, 0x0, 0x0, 0x78, 0x0, 0x0, 0xD8, 0x0, 0x1, 0xD8, 0x0, 0x1, 0x98, 0x0, 0x3, 0x18, 0x0, 0x3, 0x18, 0x0, 0x6, 0x18, 0x0, 0xE, 0x18, 0x0, 0xC, 0x18, 0x0, 0x18, 0x18, 0x0, 0x38, 0x18, 0x0, 0x30, 0x18, 0x0, 0x60, 0x18, 0x0, 0x7F, 0xFF, 0x0, 0x7F, 0xFF, 0x0, 0x0, 0x18, 0x0, 0x0, 0x18, 0x0, 0x0, 0x18, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0035 "5" */
|
||||
0x1F, 0xFC, 0x0, 0x1F, 0xFC, 0x0, 0x18, 0x0, 0x0, 0x18, 0x0, 0x0, 0x18, 0x0, 0x0, 0x18, 0x0, 0x0, 0x18, 0x0, 0x0, 0x19, 0xF0, 0x0, 0x1B, 0xF8, 0x0, 0x1C, 0x1C, 0x0, 0x8, 0xE, 0x0, 0x0, 0xE, 0x0, 0x0, 0x6, 0x0, 0x0, 0x6, 0x0, 0x0, 0x6, 0x0, 0x10, 0xE, 0x0, 0x38, 0xC, 0x0, 0x1C, 0x1C, 0x0, 0xF, 0xF8, 0x0, 0x7, 0xE0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0036 "6" */
|
||||
0x0, 0xF0, 0x0, 0x1, 0xC0, 0x0, 0x3, 0x80, 0x0, 0x7, 0x0, 0x0, 0xE, 0x0, 0x0, 0xC, 0x0, 0x0, 0x1C, 0x0, 0x0, 0x19, 0xF0, 0x0, 0x3B, 0xF8, 0x0, 0x34, 0x1C, 0x0, 0x38, 0xE, 0x0, 0x38, 0xE, 0x0, 0x30, 0x6, 0x0, 0x30, 0x6, 0x0, 0x30, 0x6, 0x0, 0x38, 0xE, 0x0, 0x18, 0xC, 0x0, 0x1C, 0x1C, 0x0, 0xF, 0xF8, 0x0, 0x3, 0xE0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0037 "7" */
|
||||
0x3F, 0xFE, 0x0, 0x3F, 0xFE, 0x0, 0x30, 0xE, 0x0, 0x30, 0xC, 0x0, 0x30, 0xC, 0x0, 0x30, 0x1C, 0x0, 0x0, 0x18, 0x0, 0x0, 0x38, 0x0, 0x0, 0x30, 0x0, 0x0, 0x70, 0x0, 0x0, 0x60, 0x0, 0x0, 0x60, 0x0, 0x0, 0xE0, 0x0, 0x0, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0x80, 0x0, 0x3, 0x80, 0x0, 0x3, 0x80, 0x0, 0x3, 0x0, 0x0, 0x7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0038 "8" */
|
||||
0x7, 0xF0, 0x0, 0xF, 0xF8, 0x0, 0x1C, 0x1C, 0x0, 0x38, 0xE, 0x0, 0x38, 0xE, 0x0, 0x38, 0xE, 0x0, 0x18, 0xC, 0x0, 0x1C, 0x1C, 0x0, 0x7, 0xF0, 0x0, 0x7, 0xF0, 0x0, 0x1C, 0x1C, 0x0, 0x38, 0xE, 0x0, 0x30, 0x6, 0x0, 0x30, 0x6, 0x0, 0x30, 0x6, 0x0, 0x30, 0x6, 0x0, 0x38, 0xE, 0x0, 0x1C, 0x1C, 0x0, 0xF, 0xF8, 0x0, 0x7, 0xF0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0039 "9" */
|
||||
0x3, 0xE0, 0x0, 0xF, 0xF8, 0x0, 0x1C, 0x1C, 0x0, 0x18, 0xC, 0x0, 0x38, 0xE, 0x0, 0x30, 0x6, 0x0, 0x30, 0x6, 0x0, 0x30, 0x6, 0x0, 0x38, 0xE, 0x0, 0x38, 0xE, 0x0, 0x1C, 0x16, 0x0, 0xF, 0xEC, 0x0, 0x7, 0xCC, 0x0, 0x0, 0x1C, 0x0, 0x0, 0x18, 0x0, 0x0, 0x38, 0x0, 0x0, 0x70, 0x0, 0x0, 0xE0, 0x0, 0x1, 0xC0, 0x0, 0x7, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+003A ":" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xC0, 0x0, 0x3, 0xE0, 0x0, 0x3, 0xE0, 0x0, 0x1, 0xC0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xC0, 0x0, 0x3, 0xE0, 0x0, 0x3, 0xE0, 0x0, 0x1, 0xC0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+003B ";" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xC0, 0x0, 0x3, 0xE0, 0x0, 0x3, 0xE0, 0x0, 0x1, 0xC0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xE0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0x80, 0x0, 0x3, 0x80, 0x0, 0x3, 0x80, 0x0, 0x3, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+003C "<" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0xC, 0x0, 0x0, 0x3C, 0x0, 0x0, 0xF0, 0x0, 0x1, 0xE0, 0x0, 0x7, 0x80, 0x0, 0x1E, 0x0, 0x0, 0x38, 0x0, 0x0, 0x38, 0x0, 0x0, 0x1E, 0x0, 0x0, 0x7, 0x80, 0x0, 0x1, 0xE0, 0x0, 0x0, 0xF0, 0x0, 0x0, 0x3C, 0x0, 0x0, 0xC, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+003D "=" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3F, 0xFE, 0x0, 0x3F, 0xFE, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3F, 0xFE, 0x0, 0x3F, 0xFE, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+003E ">" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x18, 0x0, 0x0, 0x1E, 0x0, 0x0, 0x7, 0x80, 0x0, 0x3, 0xC0, 0x0, 0x0, 0xF0, 0x0, 0x0, 0x3C, 0x0, 0x0, 0xE, 0x0, 0x0, 0xE, 0x0, 0x0, 0x3C, 0x0, 0x0, 0xF0, 0x0, 0x3, 0xC0, 0x0, 0x7, 0x80, 0x0, 0x1E, 0x0, 0x0, 0x18, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+003F "?" */
|
||||
0x3, 0xE0, 0x0, 0xF, 0xF8, 0x0, 0x1C, 0x1C, 0x0, 0x18, 0xC, 0x0, 0x38, 0xC, 0x0, 0x0, 0xC, 0x0, 0x0, 0xC, 0x0, 0x0, 0x1C, 0x0, 0x0, 0x78, 0x0, 0x1, 0xF0, 0x0, 0x1, 0x80, 0x0, 0x1, 0x80, 0x0, 0x1, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0xC0, 0x0, 0x3, 0xC0, 0x0, 0x3, 0xC0, 0x0, 0x3, 0xC0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0040 "@" */
|
||||
0x3, 0xE0, 0x0, 0xF, 0xF8, 0x0, 0xC, 0x1C, 0x0, 0x18, 0xC, 0x0, 0x18, 0xE, 0x0, 0x30, 0x6, 0x0, 0x30, 0xE6, 0x0, 0x31, 0xF6, 0x0, 0x31, 0x8E, 0x0, 0x33, 0x6, 0x0, 0x33, 0x6, 0x0, 0x33, 0x6, 0x0, 0x33, 0x6, 0x0, 0x33, 0x6, 0x0, 0x33, 0x8E, 0x0, 0x31, 0xFE, 0x0, 0x30, 0xF6, 0x0, 0x30, 0x0, 0x0, 0x18, 0x0, 0x0, 0x1C, 0x0, 0x0, 0xE, 0x0, 0x0, 0x7, 0xF8, 0x0, 0x3, 0xF8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0041 "A" */
|
||||
0x1, 0xC0, 0x0, 0x3, 0xE0, 0x0, 0x3, 0x60, 0x0, 0x3, 0x60, 0x0, 0x3, 0x60, 0x0, 0x7, 0x70, 0x0, 0x6, 0x30, 0x0, 0x6, 0x30, 0x0, 0xE, 0x38, 0x0, 0xC, 0x18, 0x0, 0xC, 0x18, 0x0, 0xC, 0x1C, 0x0, 0x1F, 0xFC, 0x0, 0x1F, 0xFC, 0x0, 0x18, 0xC, 0x0, 0x38, 0xE, 0x0, 0x30, 0x6, 0x0, 0x30, 0x6, 0x0, 0x70, 0x7, 0x0, 0x70, 0x7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0042 "B" */
|
||||
0x1F, 0xF0, 0x0, 0x1F, 0xF8, 0x0, 0x18, 0x1C, 0x0, 0x18, 0xC, 0x0, 0x18, 0xE, 0x0, 0x18, 0xE, 0x0, 0x18, 0xC, 0x0, 0x18, 0xC, 0x0, 0x18, 0x1C, 0x0, 0x1F, 0xF0, 0x0, 0x1F, 0xF8, 0x0, 0x18, 0x1C, 0x0, 0x18, 0xE, 0x0, 0x18, 0x6, 0x0, 0x18, 0x6, 0x0, 0x18, 0x6, 0x0, 0x18, 0x6, 0x0, 0x18, 0xC, 0x0, 0x1F, 0xFC, 0x0, 0x1F, 0xF0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0043 "C" */
|
||||
0x3, 0xF0, 0x0, 0x7, 0xF8, 0x0, 0xE, 0x1C, 0x0, 0x1C, 0xE, 0x0, 0x18, 0x6, 0x0, 0x18, 0x0, 0x0, 0x38, 0x0, 0x0, 0x38, 0x0, 0x0, 0x38, 0x0, 0x0, 0x38, 0x0, 0x0, 0x38, 0x0, 0x0, 0x38, 0x0, 0x0, 0x38, 0x0, 0x0, 0x38, 0x0, 0x0, 0x18, 0x0, 0x0, 0x18, 0x6, 0x0, 0x1C, 0xE, 0x0, 0xE, 0x1C, 0x0, 0x7, 0xF8, 0x0, 0x3, 0xF0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0044 "D" */
|
||||
0x1F, 0xE0, 0x0, 0x1F, 0xF8, 0x0, 0x18, 0x3C, 0x0, 0x18, 0x1C, 0x0, 0x18, 0xE, 0x0, 0x18, 0xE, 0x0, 0x18, 0x6, 0x0, 0x18, 0x6, 0x0, 0x18, 0x6, 0x0, 0x18, 0x6, 0x0, 0x18, 0x6, 0x0, 0x18, 0x6, 0x0, 0x18, 0x6, 0x0, 0x18, 0x6, 0x0, 0x18, 0xE, 0x0, 0x18, 0xE, 0x0, 0x18, 0x1C, 0x0, 0x18, 0x3C, 0x0, 0x1F, 0xF8, 0x0, 0x1F, 0xE0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0045 "E" */
|
||||
0x1F, 0xFE, 0x0, 0x1F, 0xFE, 0x0, 0x18, 0x0, 0x0, 0x18, 0x0, 0x0, 0x18, 0x0, 0x0, 0x18, 0x0, 0x0, 0x18, 0x0, 0x0, 0x18, 0x0, 0x0, 0x18, 0x0, 0x0, 0x1F, 0xFC, 0x0, 0x1F, 0xFC, 0x0, 0x18, 0x0, 0x0, 0x18, 0x0, 0x0, 0x18, 0x0, 0x0, 0x18, 0x0, 0x0, 0x18, 0x0, 0x0, 0x18, 0x0, 0x0, 0x18, 0x0, 0x0, 0x1F, 0xFE, 0x0, 0x1F, 0xFE, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0046 "F" */
|
||||
0x1F, 0xFE, 0x0, 0x1F, 0xFE, 0x0, 0x18, 0x0, 0x0, 0x18, 0x0, 0x0, 0x18, 0x0, 0x0, 0x18, 0x0, 0x0, 0x18, 0x0, 0x0, 0x18, 0x0, 0x0, 0x18, 0x0, 0x0, 0x1F, 0xFC, 0x0, 0x1F, 0xFC, 0x0, 0x18, 0x0, 0x0, 0x18, 0x0, 0x0, 0x18, 0x0, 0x0, 0x18, 0x0, 0x0, 0x18, 0x0, 0x0, 0x18, 0x0, 0x0, 0x18, 0x0, 0x0, 0x18, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0047 "G" */
|
||||
0x3, 0xE0, 0x0, 0xF, 0xF8, 0x0, 0x1E, 0x1C, 0x0, 0x18, 0xC, 0x0, 0x38, 0xE, 0x0, 0x30, 0x0, 0x0, 0x30, 0x0, 0x0, 0x30, 0x0, 0x0, 0x30, 0x0, 0x0, 0x30, 0x0, 0x0, 0x30, 0xFE, 0x0, 0x30, 0xFE, 0x0, 0x30, 0x6, 0x0, 0x30, 0x6, 0x0, 0x30, 0xE, 0x0, 0x38, 0xE, 0x0, 0x18, 0xE, 0x0, 0x1C, 0x16, 0x0, 0xF, 0xF6, 0x0, 0x3, 0xC6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0048 "H" */
|
||||
0x38, 0xE, 0x0, 0x38, 0xE, 0x0, 0x38, 0xE, 0x0, 0x38, 0xE, 0x0, 0x38, 0xE, 0x0, 0x38, 0xE, 0x0, 0x38, 0xE, 0x0, 0x38, 0xE, 0x0, 0x38, 0xE, 0x0, 0x3F, 0xFE, 0x0, 0x3F, 0xFE, 0x0, 0x38, 0xE, 0x0, 0x38, 0xE, 0x0, 0x38, 0xE, 0x0, 0x38, 0xE, 0x0, 0x38, 0xE, 0x0, 0x38, 0xE, 0x0, 0x38, 0xE, 0x0, 0x38, 0xE, 0x0, 0x38, 0xE, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0049 "I" */
|
||||
0x3F, 0xFE, 0x0, 0x3F, 0xFE, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x3F, 0xFE, 0x0, 0x3F, 0xFE, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+004A "J" */
|
||||
0xF, 0xFC, 0x0, 0xF, 0xFC, 0x0, 0x0, 0x1C, 0x0, 0x0, 0x1C, 0x0, 0x0, 0x1C, 0x0, 0x0, 0x1C, 0x0, 0x0, 0x1C, 0x0, 0x0, 0x1C, 0x0, 0x0, 0x1C, 0x0, 0x0, 0x1C, 0x0, 0x0, 0x1C, 0x0, 0x0, 0x1C, 0x0, 0x0, 0x1C, 0x0, 0x0, 0x1C, 0x0, 0x0, 0x1C, 0x0, 0x10, 0x18, 0x0, 0x38, 0x18, 0x0, 0x1C, 0x38, 0x0, 0xF, 0xF0, 0x0, 0x7, 0xC0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+004B "K" */
|
||||
0x38, 0x7, 0x0, 0x38, 0xE, 0x0, 0x38, 0x1C, 0x0, 0x38, 0x38, 0x0, 0x38, 0x30, 0x0, 0x38, 0x70, 0x0, 0x38, 0xE0, 0x0, 0x39, 0xC0, 0x0, 0x3B, 0x80, 0x0, 0x3B, 0xC0, 0x0, 0x3E, 0xE0, 0x0, 0x3E, 0xE0, 0x0, 0x3C, 0x70, 0x0, 0x38, 0x30, 0x0, 0x38, 0x38, 0x0, 0x38, 0x1C, 0x0, 0x38, 0x1C, 0x0, 0x38, 0xE, 0x0, 0x38, 0x6, 0x0, 0x38, 0x7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+004C "L" */
|
||||
0x1C, 0x0, 0x0, 0x1C, 0x0, 0x0, 0x1C, 0x0, 0x0, 0x1C, 0x0, 0x0, 0x1C, 0x0, 0x0, 0x1C, 0x0, 0x0, 0x1C, 0x0, 0x0, 0x1C, 0x0, 0x0, 0x1C, 0x0, 0x0, 0x1C, 0x0, 0x0, 0x1C, 0x0, 0x0, 0x1C, 0x0, 0x0, 0x1C, 0x0, 0x0, 0x1C, 0x0, 0x0, 0x1C, 0x0, 0x0, 0x1C, 0x0, 0x0, 0x1C, 0x0, 0x0, 0x1C, 0x0, 0x0, 0x1F, 0xFE, 0x0, 0x1F, 0xFE, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+004D "M" */
|
||||
0x38, 0xE, 0x0, 0x3C, 0x1E, 0x0, 0x3C, 0x1E, 0x0, 0x3C, 0x1E, 0x0, 0x36, 0x36, 0x0, 0x36, 0x36, 0x0, 0x33, 0x26, 0x0, 0x33, 0x66, 0x0, 0x33, 0x66, 0x0, 0x31, 0xC6, 0x0, 0x31, 0xC6, 0x0, 0x30, 0x86, 0x0, 0x30, 0x86, 0x0, 0x30, 0x86, 0x0, 0x30, 0x6, 0x0, 0x30, 0x6, 0x0, 0x30, 0x6, 0x0, 0x30, 0x6, 0x0, 0x30, 0x6, 0x0, 0x30, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+004E "N" */
|
||||
0x3C, 0x6, 0x0, 0x3C, 0x6, 0x0, 0x3E, 0x6, 0x0, 0x3E, 0x6, 0x0, 0x3E, 0x6, 0x0, 0x3B, 0x6, 0x0, 0x3B, 0x6, 0x0, 0x3B, 0x86, 0x0, 0x39, 0x86, 0x0, 0x39, 0x86, 0x0, 0x38, 0xC6, 0x0, 0x38, 0xC6, 0x0, 0x38, 0xE6, 0x0, 0x38, 0x66, 0x0, 0x38, 0x66, 0x0, 0x38, 0x36, 0x0, 0x38, 0x36, 0x0, 0x38, 0x3E, 0x0, 0x38, 0x1E, 0x0, 0x38, 0x1E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+004F "O" */
|
||||
0x3, 0xE0, 0x0, 0xF, 0xF8, 0x0, 0x1C, 0x1C, 0x0, 0x18, 0xC, 0x0, 0x38, 0xE, 0x0, 0x30, 0x6, 0x0, 0x30, 0x6, 0x0, 0x30, 0x6, 0x0, 0x30, 0x6, 0x0, 0x30, 0x6, 0x0, 0x30, 0x6, 0x0, 0x30, 0x6, 0x0, 0x30, 0x6, 0x0, 0x30, 0x6, 0x0, 0x30, 0x6, 0x0, 0x38, 0xE, 0x0, 0x18, 0xC, 0x0, 0x1C, 0x1C, 0x0, 0xF, 0xF8, 0x0, 0x3, 0xE0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0050 "P" */
|
||||
0x1F, 0xF0, 0x0, 0x1F, 0xFC, 0x0, 0x18, 0xE, 0x0, 0x18, 0x6, 0x0, 0x18, 0x6, 0x0, 0x18, 0x6, 0x0, 0x18, 0x6, 0x0, 0x18, 0x6, 0x0, 0x18, 0xE, 0x0, 0x1F, 0xFC, 0x0, 0x1F, 0xF0, 0x0, 0x18, 0x0, 0x0, 0x18, 0x0, 0x0, 0x18, 0x0, 0x0, 0x18, 0x0, 0x0, 0x18, 0x0, 0x0, 0x18, 0x0, 0x0, 0x18, 0x0, 0x0, 0x18, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0051 "Q" */
|
||||
0x3, 0xE0, 0x0, 0xF, 0xF8, 0x0, 0x1C, 0x1C, 0x0, 0x18, 0xC, 0x0, 0x38, 0xE, 0x0, 0x30, 0x6, 0x0, 0x30, 0x6, 0x0, 0x30, 0x6, 0x0, 0x30, 0x6, 0x0, 0x30, 0x6, 0x0, 0x30, 0x6, 0x0, 0x30, 0x6, 0x0, 0x30, 0x6, 0x0, 0x30, 0x6, 0x0, 0x30, 0x6, 0x0, 0x38, 0xE, 0x0, 0x18, 0xC, 0x0, 0x1C, 0x1C, 0x0, 0xF, 0xF8, 0x0, 0x3, 0xE0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x0, 0xFC, 0x0, 0x0, 0x7C, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0052 "R" */
|
||||
0x1F, 0xF0, 0x0, 0x1F, 0xFC, 0x0, 0x18, 0xE, 0x0, 0x18, 0x6, 0x0, 0x18, 0x6, 0x0, 0x18, 0x6, 0x0, 0x18, 0x6, 0x0, 0x18, 0x6, 0x0, 0x18, 0xE, 0x0, 0x1F, 0xFC, 0x0, 0x1F, 0xF0, 0x0, 0x18, 0xE0, 0x0, 0x18, 0x60, 0x0, 0x18, 0x70, 0x0, 0x18, 0x30, 0x0, 0x18, 0x38, 0x0, 0x18, 0x1C, 0x0, 0x18, 0xC, 0x0, 0x18, 0xE, 0x0, 0x18, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0053 "S" */
|
||||
0x7, 0xF0, 0x0, 0xF, 0xFC, 0x0, 0x1C, 0x1E, 0x0, 0x38, 0x6, 0x0, 0x38, 0x0, 0x0, 0x30, 0x0, 0x0, 0x38, 0x0, 0x0, 0x38, 0x0, 0x0, 0x1F, 0x0, 0x0, 0xF, 0xF0, 0x0, 0x3, 0xFC, 0x0, 0x0, 0x1E, 0x0, 0x0, 0xE, 0x0, 0x0, 0x6, 0x0, 0x0, 0x6, 0x0, 0x20, 0x6, 0x0, 0x70, 0xE, 0x0, 0x3C, 0x1C, 0x0, 0x1F, 0xF8, 0x0, 0x7, 0xF0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0054 "T" */
|
||||
0x7F, 0xFF, 0x0, 0x7F, 0xFF, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0055 "U" */
|
||||
0x38, 0xE, 0x0, 0x38, 0xE, 0x0, 0x38, 0xE, 0x0, 0x38, 0xE, 0x0, 0x38, 0xE, 0x0, 0x38, 0xE, 0x0, 0x38, 0xE, 0x0, 0x38, 0xE, 0x0, 0x38, 0xE, 0x0, 0x38, 0xE, 0x0, 0x38, 0xE, 0x0, 0x38, 0xE, 0x0, 0x38, 0xE, 0x0, 0x38, 0xE, 0x0, 0x38, 0xE, 0x0, 0x18, 0xC, 0x0, 0x18, 0xC, 0x0, 0x1C, 0x1C, 0x0, 0xF, 0xF8, 0x0, 0x7, 0xF0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0056 "V" */
|
||||
0x70, 0x7, 0x0, 0x30, 0x6, 0x0, 0x30, 0x6, 0x0, 0x38, 0xE, 0x0, 0x38, 0xE, 0x0, 0x18, 0xC, 0x0, 0x18, 0xC, 0x0, 0x1C, 0x1C, 0x0, 0xC, 0x18, 0x0, 0xC, 0x18, 0x0, 0xC, 0x18, 0x0, 0xE, 0x38, 0x0, 0x6, 0x30, 0x0, 0x6, 0x30, 0x0, 0x7, 0x70, 0x0, 0x3, 0x60, 0x0, 0x3, 0x60, 0x0, 0x3, 0x60, 0x0, 0x3, 0xE0, 0x0, 0x1, 0xC0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0057 "W" */
|
||||
0x60, 0x3, 0x0, 0x60, 0x3, 0x0, 0x60, 0x3, 0x0, 0x60, 0x3, 0x0, 0x70, 0x3, 0x0, 0x31, 0xC7, 0x0, 0x31, 0xC6, 0x0, 0x31, 0xC6, 0x0, 0x33, 0x66, 0x0, 0x33, 0x66, 0x0, 0x33, 0x66, 0x0, 0x33, 0x66, 0x0, 0x32, 0x26, 0x0, 0x36, 0x36, 0x0, 0x36, 0x36, 0x0, 0x36, 0x36, 0x0, 0x36, 0x36, 0x0, 0x36, 0x16, 0x0, 0x1C, 0x1E, 0x0, 0x1C, 0x1C, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0058 "X" */
|
||||
0x70, 0x7, 0x0, 0x38, 0x6, 0x0, 0x18, 0xC, 0x0, 0x1C, 0x1C, 0x0, 0xE, 0x18, 0x0, 0x6, 0x38, 0x0, 0x7, 0x30, 0x0, 0x3, 0x60, 0x0, 0x3, 0xE0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x3, 0xE0, 0x0, 0x3, 0x70, 0x0, 0x6, 0x30, 0x0, 0xE, 0x38, 0x0, 0xC, 0x18, 0x0, 0x1C, 0x1C, 0x0, 0x38, 0xE, 0x0, 0x30, 0x6, 0x0, 0x70, 0x7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0059 "Y" */
|
||||
0x70, 0x7, 0x0, 0x70, 0x7, 0x0, 0x38, 0xE, 0x0, 0x38, 0xE, 0x0, 0x1C, 0x1C, 0x0, 0xC, 0x18, 0x0, 0xE, 0x38, 0x0, 0x6, 0x30, 0x0, 0x7, 0x70, 0x0, 0x3, 0x60, 0x0, 0x3, 0xE0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+005A "Z" */
|
||||
0x3F, 0xFE, 0x0, 0x3F, 0xFE, 0x0, 0x0, 0xE, 0x0, 0x0, 0x1C, 0x0, 0x0, 0x18, 0x0, 0x0, 0x38, 0x0, 0x0, 0x70, 0x0, 0x0, 0x60, 0x0, 0x0, 0xE0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0x80, 0x0, 0x3, 0x80, 0x0, 0x7, 0x0, 0x0, 0x6, 0x0, 0x0, 0xC, 0x0, 0x0, 0x1C, 0x0, 0x0, 0x38, 0x0, 0x0, 0x30, 0x0, 0x0, 0x7F, 0xFF, 0x0, 0x7F, 0xFF, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+005B "[" */
|
||||
0x3, 0xFC, 0x0, 0x3, 0x0, 0x0, 0x3, 0x0, 0x0, 0x3, 0x0, 0x0, 0x3, 0x0, 0x0, 0x3, 0x0, 0x0, 0x3, 0x0, 0x0, 0x3, 0x0, 0x0, 0x3, 0x0, 0x0, 0x3, 0x0, 0x0, 0x3, 0x0, 0x0, 0x3, 0x0, 0x0, 0x3, 0x0, 0x0, 0x3, 0x0, 0x0, 0x3, 0x0, 0x0, 0x3, 0x0, 0x0, 0x3, 0x0, 0x0, 0x3, 0x0, 0x0, 0x3, 0x0, 0x0, 0x3, 0x0, 0x0, 0x3, 0x0, 0x0, 0x3, 0x0, 0x0, 0x3, 0xFC, 0x0, 0x3, 0xFC, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+005C "\\" */
|
||||
0x18, 0x0, 0x0, 0xC, 0x0, 0x0, 0xC, 0x0, 0x0, 0xC, 0x0, 0x0, 0x6, 0x0, 0x0, 0x6, 0x0, 0x0, 0x3, 0x0, 0x0, 0x3, 0x0, 0x0, 0x3, 0x0, 0x0, 0x1, 0x80, 0x0, 0x1, 0x80, 0x0, 0x0, 0xC0, 0x0, 0x0, 0xC0, 0x0, 0x0, 0xC0, 0x0, 0x0, 0x60, 0x0, 0x0, 0x60, 0x0, 0x0, 0x70, 0x0, 0x0, 0x30, 0x0, 0x0, 0x30, 0x0, 0x0, 0x18, 0x0, 0x0, 0x18, 0x0, 0x0, 0x18, 0x0, 0x0, 0xC, 0x0, 0x0, 0xC, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+005D "]" */
|
||||
0x1F, 0xE0, 0x0, 0x0, 0x60, 0x0, 0x0, 0x60, 0x0, 0x0, 0x60, 0x0, 0x0, 0x60, 0x0, 0x0, 0x60, 0x0, 0x0, 0x60, 0x0, 0x0, 0x60, 0x0, 0x0, 0x60, 0x0, 0x0, 0x60, 0x0, 0x0, 0x60, 0x0, 0x0, 0x60, 0x0, 0x0, 0x60, 0x0, 0x0, 0x60, 0x0, 0x0, 0x60, 0x0, 0x0, 0x60, 0x0, 0x0, 0x60, 0x0, 0x0, 0x60, 0x0, 0x0, 0x60, 0x0, 0x0, 0x60, 0x0, 0x0, 0x60, 0x0, 0x0, 0x60, 0x0, 0x1F, 0xE0, 0x0, 0x1F, 0xE0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+005E "^" */
|
||||
0x1, 0xC0, 0x0, 0x3, 0xE0, 0x0, 0x3, 0x60, 0x0, 0x7, 0x70, 0x0, 0x6, 0x30, 0x0, 0xC, 0x38, 0x0, 0xC, 0x18, 0x0, 0x18, 0xC, 0x0, 0x18, 0xC, 0x0, 0x30, 0x6, 0x0, 0x70, 0x7, 0x0, 0x20, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+005F "_" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3F, 0xFE, 0x0, 0x3F, 0xFE, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0060 "`" */
|
||||
0x3, 0x0, 0x0, 0x1, 0x80, 0x0, 0x1, 0x80, 0x0, 0x0, 0xC0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0061 "a" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0xE0, 0x0, 0xF, 0xF0, 0x0, 0x1C, 0x38, 0x0, 0x30, 0x18, 0x0, 0x0, 0x18, 0x0, 0x0, 0x18, 0x0, 0xF, 0xF8, 0x0, 0x1F, 0xF8, 0x0, 0x38, 0x18, 0x0, 0x30, 0x18, 0x0, 0x30, 0x18, 0x0, 0x38, 0x38, 0x0, 0x1F, 0xCF, 0x0, 0xF, 0x8F, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0062 "b" */
|
||||
0x18, 0x0, 0x0, 0x18, 0x0, 0x0, 0x18, 0x0, 0x0, 0x18, 0x0, 0x0, 0x18, 0x0, 0x0, 0x18, 0x0, 0x0, 0x19, 0xF0, 0x0, 0x1B, 0xF8, 0x0, 0x1C, 0x1C, 0x0, 0x18, 0xE, 0x0, 0x18, 0x6, 0x0, 0x18, 0x6, 0x0, 0x18, 0x6, 0x0, 0x18, 0x6, 0x0, 0x18, 0x6, 0x0, 0x18, 0x6, 0x0, 0x18, 0xE, 0x0, 0x1C, 0x1C, 0x0, 0x1B, 0xF8, 0x0, 0x19, 0xF0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0063 "c" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0xF0, 0x0, 0x7, 0xF8, 0x0, 0xE, 0x1C, 0x0, 0x1C, 0xC, 0x0, 0x18, 0x0, 0x0, 0x18, 0x0, 0x0, 0x38, 0x0, 0x0, 0x38, 0x0, 0x0, 0x18, 0x0, 0x0, 0x18, 0x8, 0x0, 0x1C, 0xC, 0x0, 0xE, 0x1E, 0x0, 0x7, 0xF8, 0x0, 0x3, 0xF0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0064 "d" */
|
||||
0x0, 0xC, 0x0, 0x0, 0xC, 0x0, 0x0, 0xC, 0x0, 0x0, 0xC, 0x0, 0x0, 0xC, 0x0, 0x0, 0xC, 0x0, 0x7, 0xCC, 0x0, 0xF, 0xEC, 0x0, 0x1C, 0x1C, 0x0, 0x38, 0xC, 0x0, 0x30, 0xC, 0x0, 0x30, 0xC, 0x0, 0x30, 0xC, 0x0, 0x30, 0xC, 0x0, 0x30, 0xC, 0x0, 0x30, 0xC, 0x0, 0x38, 0xC, 0x0, 0x1C, 0x1C, 0x0, 0xF, 0xEC, 0x0, 0x7, 0xCC, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0065 "e" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0xE0, 0x0, 0xF, 0xF8, 0x0, 0x1C, 0x1C, 0x0, 0x18, 0xC, 0x0, 0x38, 0xE, 0x0, 0x30, 0x6, 0x0, 0x3F, 0xFE, 0x0, 0x3F, 0xFE, 0x0, 0x30, 0x0, 0x0, 0x30, 0x0, 0x0, 0x18, 0x0, 0x0, 0x1C, 0xC, 0x0, 0xF, 0xFE, 0x0, 0x3, 0xF0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0066 "f" */
|
||||
0x0, 0xFE, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x3F, 0xFE, 0x0, 0x3F, 0xFE, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x3F, 0xFE, 0x0, 0x3F, 0xFE, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0067 "g" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xF, 0x0, 0x0, 0x1F, 0x0, 0x3, 0xF0, 0x0, 0xF, 0xF8, 0x0, 0x1C, 0x1C, 0x0, 0x18, 0x1C, 0x0, 0x18, 0xC, 0x0, 0x18, 0xC, 0x0, 0x18, 0x1C, 0x0, 0xC, 0x18, 0x0, 0x7, 0xF8, 0x0, 0x7, 0xE0, 0x0, 0x18, 0x0, 0x0, 0x18, 0x0, 0x0, 0x1F, 0xFC, 0x0, 0xF, 0xFE, 0x0, 0x18, 0x7, 0x0, 0x30, 0x3, 0x0, 0x30, 0x3, 0x0, 0x38, 0xE, 0x0, 0x1F, 0xFE, 0x0, 0xF, 0xF8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0068 "h" */
|
||||
0x18, 0x0, 0x0, 0x18, 0x0, 0x0, 0x18, 0x0, 0x0, 0x18, 0x0, 0x0, 0x18, 0x0, 0x0, 0x18, 0x0, 0x0, 0x19, 0xF0, 0x0, 0x1B, 0xF8, 0x0, 0x1E, 0x1C, 0x0, 0x18, 0xC, 0x0, 0x18, 0xC, 0x0, 0x18, 0xC, 0x0, 0x18, 0xC, 0x0, 0x18, 0xC, 0x0, 0x18, 0xC, 0x0, 0x18, 0xC, 0x0, 0x18, 0xC, 0x0, 0x18, 0xC, 0x0, 0x18, 0xC, 0x0, 0x18, 0xC, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0069 "i" */
|
||||
0x0, 0xE0, 0x0, 0x0, 0xE0, 0x0, 0x0, 0xE0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1F, 0xE0, 0x0, 0x1F, 0xE0, 0x0, 0x0, 0xE0, 0x0, 0x0, 0xE0, 0x0, 0x0, 0xE0, 0x0, 0x0, 0xE0, 0x0, 0x0, 0xE0, 0x0, 0x0, 0xE0, 0x0, 0x0, 0xE0, 0x0, 0x0, 0xE0, 0x0, 0x0, 0xE0, 0x0, 0x0, 0xE0, 0x0, 0x1F, 0xFE, 0x0, 0x1F, 0xFE, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+006A "j" */
|
||||
0x0, 0x38, 0x0, 0x0, 0x78, 0x0, 0x0, 0x38, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1F, 0xF0, 0x0, 0x1F, 0xF0, 0x0, 0x0, 0x30, 0x0, 0x0, 0x30, 0x0, 0x0, 0x30, 0x0, 0x0, 0x30, 0x0, 0x0, 0x30, 0x0, 0x0, 0x30, 0x0, 0x0, 0x30, 0x0, 0x0, 0x30, 0x0, 0x0, 0x30, 0x0, 0x0, 0x30, 0x0, 0x0, 0x30, 0x0, 0x0, 0x30, 0x0, 0x0, 0x30, 0x0, 0x0, 0x30, 0x0, 0x0, 0x30, 0x0, 0x0, 0x30, 0x0, 0x1F, 0xF0, 0x0, 0x1F, 0xE0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+006B "k" */
|
||||
0x18, 0x0, 0x0, 0x18, 0x0, 0x0, 0x18, 0x0, 0x0, 0x18, 0x0, 0x0, 0x18, 0x0, 0x0, 0x18, 0x0, 0x0, 0x18, 0xE, 0x0, 0x18, 0x1C, 0x0, 0x18, 0x38, 0x0, 0x18, 0x70, 0x0, 0x18, 0xE0, 0x0, 0x19, 0x80, 0x0, 0x1F, 0xC0, 0x0, 0x1E, 0xE0, 0x0, 0x1C, 0x70, 0x0, 0x18, 0x38, 0x0, 0x18, 0x18, 0x0, 0x18, 0x1C, 0x0, 0x18, 0xE, 0x0, 0x18, 0x7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+006C "l" */
|
||||
0x3F, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x3F, 0xFE, 0x0, 0x3F, 0xFE, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+006D "m" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x37, 0x1C, 0x0, 0x3F, 0xBE, 0x0, 0x31, 0xC6, 0x0, 0x31, 0xC6, 0x0, 0x31, 0xC6, 0x0, 0x31, 0xC6, 0x0, 0x31, 0xC6, 0x0, 0x31, 0xC6, 0x0, 0x31, 0xC6, 0x0, 0x31, 0xC6, 0x0, 0x31, 0xC6, 0x0, 0x31, 0xC6, 0x0, 0x31, 0xC6, 0x0, 0x31, 0xC6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+006E "n" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x19, 0xF0, 0x0, 0x1B, 0xF8, 0x0, 0x1E, 0x1C, 0x0, 0x18, 0xC, 0x0, 0x18, 0xC, 0x0, 0x18, 0xC, 0x0, 0x18, 0xC, 0x0, 0x18, 0xC, 0x0, 0x18, 0xC, 0x0, 0x18, 0xC, 0x0, 0x18, 0xC, 0x0, 0x18, 0xC, 0x0, 0x18, 0xC, 0x0, 0x18, 0xC, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+006F "o" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0xE0, 0x0, 0xF, 0xF8, 0x0, 0x1C, 0x1C, 0x0, 0x18, 0xC, 0x0, 0x38, 0xE, 0x0, 0x30, 0x6, 0x0, 0x30, 0x6, 0x0, 0x30, 0x6, 0x0, 0x30, 0x6, 0x0, 0x38, 0xE, 0x0, 0x18, 0xC, 0x0, 0x1C, 0x1C, 0x0, 0xF, 0xF8, 0x0, 0x3, 0xE0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0070 "p" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x19, 0xF0, 0x0, 0x1B, 0xF8, 0x0, 0x1C, 0x1C, 0x0, 0x18, 0xE, 0x0, 0x18, 0x6, 0x0, 0x18, 0x6, 0x0, 0x18, 0x6, 0x0, 0x18, 0x6, 0x0, 0x18, 0x6, 0x0, 0x18, 0x6, 0x0, 0x18, 0xE, 0x0, 0x1C, 0x1C, 0x0, 0x1B, 0xF8, 0x0, 0x19, 0xF0, 0x0, 0x18, 0x0, 0x0, 0x18, 0x0, 0x0, 0x18, 0x0, 0x0, 0x18, 0x0, 0x0, 0x18, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0071 "q" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0xCC, 0x0, 0xF, 0xEC, 0x0, 0x1C, 0x1C, 0x0, 0x38, 0xC, 0x0, 0x30, 0xC, 0x0, 0x30, 0xC, 0x0, 0x30, 0xC, 0x0, 0x30, 0xC, 0x0, 0x30, 0xC, 0x0, 0x30, 0xC, 0x0, 0x38, 0xC, 0x0, 0x1C, 0x1C, 0x0, 0xF, 0xEC, 0x0, 0x7, 0xCC, 0x0, 0x0, 0xC, 0x0, 0x0, 0xC, 0x0, 0x0, 0xC, 0x0, 0x0, 0xC, 0x0, 0x0, 0xC, 0x0, 0x0, 0xC, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0072 "r" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3F, 0x9F, 0x0, 0x3F, 0xBF, 0x0, 0x3, 0xE0, 0x0, 0x3, 0xC0, 0x0, 0x3, 0x80, 0x0, 0x3, 0x80, 0x0, 0x3, 0x80, 0x0, 0x3, 0x80, 0x0, 0x3, 0x80, 0x0, 0x3, 0x80, 0x0, 0x3, 0x80, 0x0, 0x3, 0x80, 0x0, 0x3F, 0xFC, 0x0, 0x3F, 0xFC, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0073 "s" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0xF0, 0x0, 0xF, 0xFC, 0x0, 0x1C, 0x1E, 0x0, 0x18, 0x8, 0x0, 0x18, 0x0, 0x0, 0x1E, 0x0, 0x0, 0xF, 0xF0, 0x0, 0x3, 0xFC, 0x0, 0x0, 0xE, 0x0, 0x0, 0x6, 0x0, 0x10, 0xE, 0x0, 0x3C, 0x1C, 0x0, 0x1F, 0xFC, 0x0, 0x7, 0xF0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0074 "t" */
|
||||
0x3, 0x0, 0x0, 0x3, 0x0, 0x0, 0x3, 0x0, 0x0, 0x3, 0x0, 0x0, 0x3, 0x0, 0x0, 0x3, 0x0, 0x0, 0x7F, 0xFE, 0x0, 0x7F, 0xFE, 0x0, 0x3, 0x0, 0x0, 0x3, 0x0, 0x0, 0x3, 0x0, 0x0, 0x3, 0x0, 0x0, 0x3, 0x0, 0x0, 0x3, 0x0, 0x0, 0x3, 0x0, 0x0, 0x3, 0x0, 0x0, 0x3, 0x0, 0x0, 0x3, 0x0, 0x0, 0x3, 0xFE, 0x0, 0x1, 0xFE, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0075 "u" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0xC, 0x0, 0x18, 0xC, 0x0, 0x18, 0xC, 0x0, 0x18, 0xC, 0x0, 0x18, 0xC, 0x0, 0x18, 0xC, 0x0, 0x18, 0xC, 0x0, 0x18, 0xC, 0x0, 0x18, 0xC, 0x0, 0x18, 0xC, 0x0, 0x18, 0xC, 0x0, 0x1C, 0x3C, 0x0, 0xF, 0xEC, 0x0, 0x7, 0xCC, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0076 "v" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x30, 0x6, 0x0, 0x38, 0xE, 0x0, 0x18, 0xC, 0x0, 0x18, 0xC, 0x0, 0xC, 0x18, 0x0, 0xC, 0x18, 0x0, 0xC, 0x18, 0x0, 0x6, 0x30, 0x0, 0x6, 0x30, 0x0, 0x7, 0x70, 0x0, 0x3, 0x60, 0x0, 0x3, 0x60, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0077 "w" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x61, 0xC3, 0x0, 0x61, 0xC3, 0x0, 0x61, 0x43, 0x0, 0x21, 0x43, 0x0, 0x33, 0x66, 0x0, 0x33, 0x66, 0x0, 0x33, 0x66, 0x0, 0x32, 0x26, 0x0, 0x32, 0x36, 0x0, 0x36, 0x36, 0x0, 0x16, 0x34, 0x0, 0x1E, 0x34, 0x0, 0x1C, 0x1C, 0x0, 0x1C, 0x1C, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0078 "x" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x38, 0xE, 0x0, 0x1C, 0x1C, 0x0, 0xC, 0x18, 0x0, 0x6, 0x30, 0x0, 0x7, 0x70, 0x0, 0x3, 0xE0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x3, 0xE0, 0x0, 0x7, 0x70, 0x0, 0xE, 0x38, 0x0, 0xC, 0x18, 0x0, 0x18, 0x1C, 0x0, 0x38, 0xE, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+0079 "y" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x30, 0x6, 0x0, 0x30, 0x6, 0x0, 0x18, 0xC, 0x0, 0x18, 0xC, 0x0, 0x1C, 0x1C, 0x0, 0xC, 0x18, 0x0, 0xE, 0x18, 0x0, 0x6, 0x30, 0x0, 0x6, 0x30, 0x0, 0x7, 0x70, 0x0, 0x3, 0x60, 0x0, 0x3, 0x60, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0xC0, 0x0, 0x1, 0x80, 0x0, 0x3, 0x80, 0x0, 0x3, 0x0, 0x0, 0x3F, 0x0, 0x0, 0x3E, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+007A "z" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1F, 0xFC, 0x0, 0x1F, 0xFC, 0x0, 0x0, 0x1C, 0x0, 0x0, 0x38, 0x0, 0x0, 0x70, 0x0, 0x0, 0xE0, 0x0, 0x0, 0xC0, 0x0, 0x1, 0x80, 0x0, 0x3, 0x0, 0x0, 0x6, 0x0, 0x0, 0xC, 0x0, 0x0, 0x18, 0x0, 0x0, 0x1F, 0xFE, 0x0, 0x1F, 0xFE, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+007B "{" */
|
||||
0x1, 0xFC, 0x0, 0x1, 0x80, 0x0, 0x1, 0x80, 0x0, 0x1, 0x80, 0x0, 0x1, 0x80, 0x0, 0x0, 0xC0, 0x0, 0x0, 0xC0, 0x0, 0x0, 0x60, 0x0, 0x0, 0x60, 0x0, 0x0, 0xE0, 0x0, 0x1F, 0xC0, 0x0, 0x1F, 0x80, 0x0, 0x0, 0xE0, 0x0, 0x0, 0x60, 0x0, 0x0, 0x60, 0x0, 0x0, 0x60, 0x0, 0x0, 0xC0, 0x0, 0x1, 0x80, 0x0, 0x1, 0x80, 0x0, 0x1, 0x80, 0x0, 0x1, 0x80, 0x0, 0x1, 0x80, 0x0, 0x1, 0xFC, 0x0, 0x1, 0xFC, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+007C "|" */
|
||||
0x0, 0x80, 0x0, 0x0, 0x80, 0x0, 0x0, 0x80, 0x0, 0x0, 0x80, 0x0, 0x0, 0x80, 0x0, 0x0, 0x80, 0x0, 0x0, 0x80, 0x0, 0x0, 0x80, 0x0, 0x0, 0x80, 0x0, 0x0, 0x80, 0x0, 0x0, 0x80, 0x0, 0x0, 0x80, 0x0, 0x0, 0x80, 0x0, 0x0, 0x80, 0x0, 0x0, 0x80, 0x0, 0x0, 0x80, 0x0, 0x0, 0x80, 0x0, 0x0, 0x80, 0x0, 0x0, 0x80, 0x0, 0x0, 0x80, 0x0, 0x0, 0x80, 0x0, 0x0, 0x80, 0x0, 0x0, 0x80, 0x0, 0x0, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+007D "}" */
|
||||
0x1F, 0xC0, 0x0, 0x0, 0xC0, 0x0, 0x0, 0xC0, 0x0, 0x0, 0xC0, 0x0, 0x0, 0xC0, 0x0, 0x1, 0x80, 0x0, 0x1, 0x80, 0x0, 0x3, 0x0, 0x0, 0x3, 0x0, 0x0, 0x3, 0x80, 0x0, 0x1, 0xFC, 0x0, 0x0, 0xFC, 0x0, 0x3, 0x80, 0x0, 0x3, 0x0, 0x0, 0x3, 0x0, 0x0, 0x3, 0x0, 0x0, 0x1, 0x80, 0x0, 0x0, 0xC0, 0x0, 0x0, 0xC0, 0x0, 0x0, 0xC0, 0x0, 0x0, 0xC0, 0x0, 0x0, 0xC0, 0x0, 0x1F, 0xC0, 0x0, 0x1F, 0xC0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
/* U+007E "~" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xE, 0x2, 0x0, 0x1F, 0x6, 0x0, 0x39, 0x86, 0x0, 0x30, 0xCE, 0x0, 0x30, 0xFC, 0x0, 0x20, 0x38, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
};
|
||||
|
||||
const FixedWidthFont ibmplexmono_28_font = {
|
||||
.glyph_width = 17,
|
||||
.glyph_height = 28,
|
||||
.glyph_bytes_per_row = 3,
|
||||
.first_codepoint = 0x20,
|
||||
.last_codepoint = 0x7E,
|
||||
.glyph_bitmap = ibmplexmono28_glyph_bitmap,
|
||||
};
|
||||
|
||||
#endif // CONFIG_TT_FONT_IBMPLEXMONO_28
|
||||
19
Modules/font-module/source/module.c
Normal file
19
Modules/font-module/source/module.c
Normal file
@ -0,0 +1,19 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
#include <font/module.h>
|
||||
#include <font/render.h>
|
||||
|
||||
static const struct ModuleSymbol SYMBOLS[] = {
|
||||
DEFINE_MODULE_SYMBOL(font_render_char),
|
||||
DEFINE_MODULE_SYMBOL(font_render_string),
|
||||
DEFINE_MODULE_SYMBOL(font_get_string_length),
|
||||
MODULE_SYMBOL_TERMINATOR
|
||||
};
|
||||
|
||||
struct Module font_module = {
|
||||
.name = "font",
|
||||
.start = NULL,
|
||||
.stop = NULL,
|
||||
.drivers = NULL,
|
||||
.symbols = SYMBOLS,
|
||||
.internal = NULL,
|
||||
};
|
||||
34
Modules/font-module/source/render.cpp
Normal file
34
Modules/font-module/source/render.cpp
Normal file
@ -0,0 +1,34 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
#include <font/render.h>
|
||||
|
||||
#include <cstring>
|
||||
|
||||
void font_render_char(const FixedWidthFont* font, char ch, uint16_t fg, uint16_t bg, uint16_t* buffer, int stride) {
|
||||
// Anything outside the font's range renders as blank rather than as garbage. The comparison
|
||||
// uses an unsigned value so that a byte above 0x7F cannot come out negative and pass the
|
||||
// lower-bound test.
|
||||
const auto raw = static_cast<unsigned char>(ch);
|
||||
const unsigned char glyphChar = (raw >= font->first_codepoint && raw <= font->last_codepoint) ? raw : ' ';
|
||||
const uint8_t* glyph = &font->glyph_bitmap[(glyphChar - font->first_codepoint) * font->glyph_height * font->glyph_bytes_per_row];
|
||||
|
||||
for (int y = 0; y < font->glyph_height; y++) {
|
||||
const uint8_t* bits = &glyph[y * font->glyph_bytes_per_row];
|
||||
uint16_t* out = &buffer[y * stride];
|
||||
|
||||
for (int x = 0; x < font->glyph_width; x++) {
|
||||
// The font stores the leftmost pixel of each row byte in the most significant bit.
|
||||
out[x] = (bits[x / 8] & (0x80U >> (x % 8))) ? fg : bg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void font_render_string(const FixedWidthFont* font, const char* str, uint16_t fg, uint16_t bg, uint16_t* buffer, int stride) {
|
||||
for (const char* p = str; *p != '\0'; p++) {
|
||||
font_render_char(font, *p, fg, bg, buffer, stride);
|
||||
buffer += font->glyph_width;
|
||||
}
|
||||
}
|
||||
|
||||
int font_get_string_length(const FixedWidthFont* font, const char* str) {
|
||||
return static_cast<int>(strlen(str)) * font->glyph_width;
|
||||
}
|
||||
@ -1,5 +1,8 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
#include <gps/gps_settings.h>
|
||||
|
||||
#include "tactility/paths.h"
|
||||
|
||||
#include <gps/private/gps_ledger.h>
|
||||
|
||||
#include <service/paths.h>
|
||||
@ -76,7 +79,7 @@ static error_t write_configurations(const std::vector<GpsConfiguration>& configu
|
||||
return ERROR_RESOURCE;
|
||||
}
|
||||
|
||||
char path[256];
|
||||
char path[FILE_MAX_PATH_STRING_LENGTH];
|
||||
if (!get_configuration_path(path, sizeof(path))) {
|
||||
return ERROR_RESOURCE;
|
||||
}
|
||||
|
||||
@ -44,10 +44,11 @@ def generate_icon_fonts(font_file, font_sizes, symbols, output):
|
||||
generate(2, size, font_file, symbols, output)
|
||||
|
||||
def generate_icon_names(codepoint_map: dict, codepoint_names: list, variable_name: str):
|
||||
filename = f"lvgl_icon_{variable_name}.h"
|
||||
filename = f"{variable_name}.h"
|
||||
print(f"Generating {filename}")
|
||||
output_path = os.path.join("..", "include", "tactility", filename)
|
||||
output_path = os.path.join("..", "include", "lvgl", "icons", filename)
|
||||
with open(output_path, 'w') as f:
|
||||
f.write("// SPDX-License-Identifier: Apache-2.0\n\n")
|
||||
f.write("#pragma once\n\n")
|
||||
for name in codepoint_names:
|
||||
safe_name = name.lower()
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#define LVGL_ICON_LAUNCHER_APPS "\xEE\x97\x83"
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#define LVGL_ICON_SHARED_ADD "\xEE\x85\x85"
|
||||
@ -10,7 +11,7 @@
|
||||
#define LVGL_ICON_SHARED_CIRCLE "\xEE\xBD\x8A"
|
||||
#define LVGL_ICON_SHARED_CLOSE "\xEE\x97\x8D"
|
||||
#define LVGL_ICON_SHARED_CLOUD "\xEF\x85\x9C"
|
||||
#define LVGL_ICON_SHARED_CHECK "\xEE\x97\x8A"
|
||||
#define LVGL_ICON_SHARED_CHECK "\xEE\x99\xA8"
|
||||
#define LVGL_ICON_SHARED_DELETE "\xEE\xA4\xAE"
|
||||
#define LVGL_ICON_SHARED_DEVICES "\xEE\x8C\xA6"
|
||||
#define LVGL_ICON_SHARED_DISPLAY_SETTINGS "\xEE\xAE\x97"
|
||||
@ -26,7 +27,7 @@
|
||||
#define LVGL_ICON_SHARED_IMAGE "\xEE\x8F\xB4"
|
||||
#define LVGL_ICON_SHARED_KEYBOARD_ARROW_UP "\xEE\x8C\x96"
|
||||
#define LVGL_ICON_SHARED_LIGHTBULB "\xEE\xA4\x8F"
|
||||
#define LVGL_ICON_SHARED_LANGUAGE "\xEE\xA2\x94"
|
||||
#define LVGL_ICON_SHARED_LANGUAGE "\xEE\xA8\x87"
|
||||
#define LVGL_ICON_SHARED_LISTS "\xEE\xA6\xB9"
|
||||
#define LVGL_ICON_SHARED_MAIL "\xEE\x85\x99"
|
||||
#define LVGL_ICON_SHARED_MENU "\xEE\x97\x92"
|
||||
@ -36,7 +37,7 @@
|
||||
#define LVGL_ICON_SHARED_NOTE_ADD "\xEE\xA2\x9C"
|
||||
#define LVGL_ICON_SHARED_POWER_SETTINGS_NEW "\xEF\xA3\x87"
|
||||
#define LVGL_ICON_SHARED_REFRESH "\xEE\x97\x95"
|
||||
#define LVGL_ICON_SHARED_SEARCH "\xEE\xA2\xB6"
|
||||
#define LVGL_ICON_SHARED_SEARCH "\xEE\xBD\xBA"
|
||||
#define LVGL_ICON_SHARED_SETTINGS "\xEE\xA2\xB8"
|
||||
#define LVGL_ICON_SHARED_TOOLBAR "\xEE\xA7\xB7"
|
||||
#define LVGL_ICON_SHARED_NAVIGATION "\xEE\x95\x9D"
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#define LVGL_ICON_STATUSBAR_LOCATION_ON "\xEF\x87\x9B"
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
/*******************************************************************************
|
||||
* Size: 12 px
|
||||
* Bpp: 2
|
||||
* Opts: --no-compress --no-prefilter --bpp 2 --size 12 --font MaterialSymbolsRounded.ttf -r 0xE145,0xE5C3,0xE770,0xEF40,0xEBCC,0xEFE6,0xEF4A,0xE5CD,0xF15C,0xE5CA,0xE92E,0xE326,0xEB97,0xE745,0xEC1C,0xE2C7,0xF720,0xF090,0xE8AF,0xE30F,0xE8FD,0xE9F4,0xE3F4,0xE316,0xE90F,0xE894,0xE9B9,0xE159,0xE5D2,0xE28D,0xE5D4,0xE405,0xE89C,0xF8C7,0xE5D5,0xE8B6,0xE8B8,0xE9F7,0xE55D,0xF028,0xE1E0,0xE63E,0xE1A7 --format lvgl -o ../source-fonts/material_symbols_shared_12.c --force-fast-kern-format
|
||||
* Opts: --no-compress --no-prefilter --bpp 2 --size 12 --font MaterialSymbolsRounded.ttf -r 0xE145,0xE5C3,0xE770,0xEF40,0xEBCC,0xEFE6,0xEF4A,0xE5CD,0xF15C,0xE668,0xE92E,0xE326,0xEB97,0xE745,0xEC1C,0xE2C7,0xF720,0xF090,0xE8AF,0xE30F,0xE8FD,0xE9F4,0xE3F4,0xE316,0xE90F,0xEA07,0xE9B9,0xE159,0xE5D2,0xE28D,0xE5D4,0xE405,0xE89C,0xF8C7,0xE5D5,0xEF7A,0xE8B8,0xE9F7,0xE55D,0xF028,0xE1E0,0xE63E,0xE1A7 --format lvgl -o ../source-fonts/material_symbols_shared_12.c --force-fast-kern-format
|
||||
******************************************************************************/
|
||||
|
||||
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
|
||||
@ -86,10 +86,6 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = {
|
||||
0xf3, 0xcf, 0xf3, 0xcf, 0x0, 0x0, 0xf3, 0xcf,
|
||||
0xf3, 0xcf, 0x0, 0x0, 0xf3, 0xcf, 0xf3, 0xcf,
|
||||
|
||||
/* U+E5CA "" */
|
||||
0x0, 0x2, 0x0, 0xd, 0x0, 0x34, 0xa0, 0xd0,
|
||||
0x2b, 0x40, 0x9, 0x0,
|
||||
|
||||
/* U+E5CD "" */
|
||||
0x10, 0x0, 0x34, 0x1c, 0xd, 0x70, 0x3, 0xc0,
|
||||
0x7, 0xd0, 0x1c, 0x34, 0x30, 0xc, 0x0, 0x0,
|
||||
@ -111,6 +107,10 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = {
|
||||
0x0, 0x40, 0x0, 0x3c, 0x0, 0x0, 0x7c, 0x0,
|
||||
0x0, 0x14, 0x0,
|
||||
|
||||
/* U+E668 "" */
|
||||
0x0, 0x2, 0x0, 0xd, 0x0, 0x34, 0xa0, 0xd0,
|
||||
0x2b, 0x40, 0x9, 0x0,
|
||||
|
||||
/* U+E745 "" */
|
||||
0xff, 0xc0, 0x0, 0x0, 0xf, 0xfc, 0x0, 0x0,
|
||||
0x4, 0xfd, 0xb, 0xc0, 0xa, 0xd0, 0x9, 0x90,
|
||||
@ -121,12 +121,6 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = {
|
||||
0xd0, 0xc, 0x94, 0x90, 0xc9, 0x1f, 0x8c, 0xbb,
|
||||
0xff, 0xcb, 0xff, 0xfc, 0x0, 0x0, 0x0,
|
||||
|
||||
/* U+E894 "" */
|
||||
0x6, 0xf9, 0x2, 0xea, 0xb8, 0x73, 0x1c, 0xdb,
|
||||
0xff, 0xfe, 0xc3, 0xc, 0x3c, 0x30, 0xc3, 0xbf,
|
||||
0xff, 0xe7, 0x31, 0xcd, 0x2e, 0xab, 0x80, 0x6f,
|
||||
0x90,
|
||||
|
||||
/* U+E89C "" */
|
||||
0xff, 0xd0, 0xc0, 0xb8, 0xc0, 0xbd, 0xc0, 0x2b,
|
||||
0xc1, 0x43, 0xc6, 0x93, 0xc6, 0x93, 0xc1, 0x43,
|
||||
@ -138,12 +132,6 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = {
|
||||
0xaa, 0xf0, 0xff, 0xff, 0x0, 0x0, 0xb0, 0x0,
|
||||
0x0,
|
||||
|
||||
/* U+E8B6 "" */
|
||||
0x0, 0x0, 0x2, 0xfe, 0x0, 0x70, 0x34, 0x9,
|
||||
0x1, 0x80, 0x90, 0x18, 0x3, 0x47, 0x40, 0x1f,
|
||||
0xec, 0x0, 0x0, 0x70, 0x0, 0x1, 0xc0, 0x0,
|
||||
0x0,
|
||||
|
||||
/* U+E8B8 "" */
|
||||
0x1, 0xf4, 0x1, 0x25, 0x84, 0x7e, 0xb, 0xda,
|
||||
0xa, 0xa, 0x36, 0xf9, 0xc3, 0x2f, 0x9c, 0xa0,
|
||||
@ -184,6 +172,12 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = {
|
||||
0x0, 0x9a, 0x0, 0x9, 0x65, 0x55, 0xd2, 0xaa,
|
||||
0xa8,
|
||||
|
||||
/* U+EA07 "" */
|
||||
0x6, 0xf9, 0x2, 0xea, 0xb8, 0x73, 0x1c, 0xdb,
|
||||
0xff, 0xfe, 0xc3, 0xc, 0x3c, 0x30, 0xc3, 0xbf,
|
||||
0xff, 0xe7, 0x31, 0xcd, 0x2e, 0xab, 0x80, 0x6f,
|
||||
0x90,
|
||||
|
||||
/* U+EB97 "" */
|
||||
0x15, 0x55, 0x4e, 0xaa, 0xab, 0xc0, 0x0, 0x3c,
|
||||
0xaa, 0x63, 0xc1, 0x0, 0x3c, 0xdf, 0xf3, 0xc1,
|
||||
@ -212,6 +206,12 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = {
|
||||
0x0, 0x67, 0x0, 0xd, 0x2d, 0x7, 0x80, 0x6f,
|
||||
0x90,
|
||||
|
||||
/* U+EF7A "" */
|
||||
0x0, 0x0, 0x2, 0xfe, 0x0, 0x70, 0x34, 0x9,
|
||||
0x1, 0x80, 0x90, 0x18, 0x3, 0x47, 0x40, 0x1f,
|
||||
0xec, 0x0, 0x0, 0x70, 0x0, 0x1, 0xc0, 0x0,
|
||||
0x0,
|
||||
|
||||
/* U+EFE6 "" */
|
||||
0x0, 0x1, 0x1, 0xf8, 0x78, 0x24, 0xcf, 0xc2,
|
||||
0x4c, 0xfc, 0x24, 0xc3, 0x2, 0x4c, 0x30, 0x7c,
|
||||
@ -264,29 +264,29 @@ static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = {
|
||||
{.bitmap_index = 203, .adv_w = 192, .box_w = 6, .box_h = 10, .ofs_x = 3, .ofs_y = 1},
|
||||
{.bitmap_index = 218, .adv_w = 192, .box_w = 8, .box_h = 10, .ofs_x = 2, .ofs_y = 1},
|
||||
{.bitmap_index = 238, .adv_w = 192, .box_w = 8, .box_h = 8, .ofs_x = 2, .ofs_y = 2},
|
||||
{.bitmap_index = 254, .adv_w = 192, .box_w = 8, .box_h = 6, .ofs_x = 2, .ofs_y = 3},
|
||||
{.bitmap_index = 266, .adv_w = 192, .box_w = 8, .box_h = 8, .ofs_x = 2, .ofs_y = 2},
|
||||
{.bitmap_index = 282, .adv_w = 192, .box_w = 10, .box_h = 6, .ofs_x = 1, .ofs_y = 3},
|
||||
{.bitmap_index = 297, .adv_w = 192, .box_w = 2, .box_h = 8, .ofs_x = 5, .ofs_y = 2},
|
||||
{.bitmap_index = 301, .adv_w = 192, .box_w = 8, .box_h = 8, .ofs_x = 2, .ofs_y = 2},
|
||||
{.bitmap_index = 317, .adv_w = 192, .box_w = 12, .box_h = 9, .ofs_x = 0, .ofs_y = 1},
|
||||
{.bitmap_index = 254, .adv_w = 192, .box_w = 8, .box_h = 8, .ofs_x = 2, .ofs_y = 2},
|
||||
{.bitmap_index = 270, .adv_w = 192, .box_w = 10, .box_h = 6, .ofs_x = 1, .ofs_y = 3},
|
||||
{.bitmap_index = 285, .adv_w = 192, .box_w = 2, .box_h = 8, .ofs_x = 5, .ofs_y = 2},
|
||||
{.bitmap_index = 289, .adv_w = 192, .box_w = 8, .box_h = 8, .ofs_x = 2, .ofs_y = 2},
|
||||
{.bitmap_index = 305, .adv_w = 192, .box_w = 12, .box_h = 9, .ofs_x = 0, .ofs_y = 1},
|
||||
{.bitmap_index = 332, .adv_w = 192, .box_w = 8, .box_h = 6, .ofs_x = 2, .ofs_y = 3},
|
||||
{.bitmap_index = 344, .adv_w = 192, .box_w = 9, .box_h = 8, .ofs_x = 2, .ofs_y = 2},
|
||||
{.bitmap_index = 362, .adv_w = 192, .box_w = 10, .box_h = 9, .ofs_x = 1, .ofs_y = 1},
|
||||
{.bitmap_index = 385, .adv_w = 192, .box_w = 10, .box_h = 10, .ofs_x = 1, .ofs_y = 1},
|
||||
{.bitmap_index = 410, .adv_w = 192, .box_w = 8, .box_h = 10, .ofs_x = 2, .ofs_y = 1},
|
||||
{.bitmap_index = 385, .adv_w = 192, .box_w = 8, .box_h = 10, .ofs_x = 2, .ofs_y = 1},
|
||||
{.bitmap_index = 405, .adv_w = 192, .box_w = 10, .box_h = 10, .ofs_x = 1, .ofs_y = 1},
|
||||
{.bitmap_index = 430, .adv_w = 192, .box_w = 10, .box_h = 10, .ofs_x = 1, .ofs_y = 1},
|
||||
{.bitmap_index = 455, .adv_w = 192, .box_w = 10, .box_h = 10, .ofs_x = 1, .ofs_y = 1},
|
||||
{.bitmap_index = 480, .adv_w = 192, .box_w = 10, .box_h = 10, .ofs_x = 1, .ofs_y = 1},
|
||||
{.bitmap_index = 505, .adv_w = 192, .box_w = 10, .box_h = 10, .ofs_x = 1, .ofs_y = 1},
|
||||
{.bitmap_index = 530, .adv_w = 192, .box_w = 8, .box_h = 10, .ofs_x = 2, .ofs_y = 1},
|
||||
{.bitmap_index = 550, .adv_w = 192, .box_w = 8, .box_h = 10, .ofs_x = 2, .ofs_y = 1},
|
||||
{.bitmap_index = 570, .adv_w = 192, .box_w = 10, .box_h = 8, .ofs_x = 1, .ofs_y = 2},
|
||||
{.bitmap_index = 590, .adv_w = 192, .box_w = 12, .box_h = 12, .ofs_x = 0, .ofs_y = 0},
|
||||
{.bitmap_index = 480, .adv_w = 192, .box_w = 8, .box_h = 10, .ofs_x = 2, .ofs_y = 1},
|
||||
{.bitmap_index = 500, .adv_w = 192, .box_w = 8, .box_h = 10, .ofs_x = 2, .ofs_y = 1},
|
||||
{.bitmap_index = 520, .adv_w = 192, .box_w = 10, .box_h = 8, .ofs_x = 1, .ofs_y = 2},
|
||||
{.bitmap_index = 540, .adv_w = 192, .box_w = 12, .box_h = 12, .ofs_x = 0, .ofs_y = 0},
|
||||
{.bitmap_index = 576, .adv_w = 192, .box_w = 10, .box_h = 10, .ofs_x = 1, .ofs_y = 1},
|
||||
{.bitmap_index = 601, .adv_w = 192, .box_w = 10, .box_h = 10, .ofs_x = 1, .ofs_y = 1},
|
||||
{.bitmap_index = 626, .adv_w = 192, .box_w = 10, .box_h = 10, .ofs_x = 1, .ofs_y = 1},
|
||||
{.bitmap_index = 651, .adv_w = 192, .box_w = 10, .box_h = 10, .ofs_x = 1, .ofs_y = 1},
|
||||
{.bitmap_index = 676, .adv_w = 192, .box_w = 10, .box_h = 10, .ofs_x = 1, .ofs_y = 1},
|
||||
{.bitmap_index = 701, .adv_w = 192, .box_w = 8, .box_h = 10, .ofs_x = 2, .ofs_y = 1},
|
||||
{.bitmap_index = 721, .adv_w = 192, .box_w = 9, .box_h = 8, .ofs_x = 2, .ofs_y = 2},
|
||||
{.bitmap_index = 676, .adv_w = 192, .box_w = 8, .box_h = 10, .ofs_x = 2, .ofs_y = 1},
|
||||
{.bitmap_index = 696, .adv_w = 192, .box_w = 9, .box_h = 8, .ofs_x = 2, .ofs_y = 2},
|
||||
{.bitmap_index = 714, .adv_w = 192, .box_w = 10, .box_h = 10, .ofs_x = 1, .ofs_y = 1},
|
||||
{.bitmap_index = 739, .adv_w = 192, .box_w = 10, .box_h = 10, .ofs_x = 1, .ofs_y = 1},
|
||||
{.bitmap_index = 764, .adv_w = 192, .box_w = 10, .box_h = 10, .ofs_x = 1, .ofs_y = 1},
|
||||
{.bitmap_index = 789, .adv_w = 192, .box_w = 12, .box_h = 8, .ofs_x = 0, .ofs_y = 2},
|
||||
@ -302,10 +302,10 @@ static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = {
|
||||
|
||||
static const uint16_t unicode_list_0[] = {
|
||||
0x0, 0x14, 0x62, 0x9b, 0x148, 0x182, 0x1ca, 0x1d1,
|
||||
0x1e1, 0x2af, 0x2c0, 0x418, 0x47e, 0x485, 0x488, 0x48d,
|
||||
0x48f, 0x490, 0x4f9, 0x600, 0x62b, 0x74f, 0x757, 0x76a,
|
||||
0x771, 0x773, 0x7b8, 0x7ca, 0x7e9, 0x874, 0x8af, 0x8b2,
|
||||
0xa52, 0xa87, 0xad7, 0xdfb, 0xe05, 0xea1, 0xee3, 0xf4b,
|
||||
0x1e1, 0x2af, 0x2c0, 0x418, 0x47e, 0x488, 0x48d, 0x48f,
|
||||
0x490, 0x4f9, 0x523, 0x600, 0x62b, 0x757, 0x76a, 0x773,
|
||||
0x7b8, 0x7ca, 0x7e9, 0x874, 0x8af, 0x8b2, 0x8c2, 0xa52,
|
||||
0xa87, 0xad7, 0xdfb, 0xe05, 0xe35, 0xea1, 0xee3, 0xf4b,
|
||||
0x1017, 0x15db, 0x1782
|
||||
};
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
/*******************************************************************************
|
||||
* Size: 16 px
|
||||
* Bpp: 2
|
||||
* Opts: --no-compress --no-prefilter --bpp 2 --size 16 --font MaterialSymbolsRounded.ttf -r 0xE145,0xE5C3,0xE770,0xEF40,0xEBCC,0xEFE6,0xEF4A,0xE5CD,0xF15C,0xE5CA,0xE92E,0xE326,0xEB97,0xE745,0xEC1C,0xE2C7,0xF720,0xF090,0xE8AF,0xE30F,0xE8FD,0xE9F4,0xE3F4,0xE316,0xE90F,0xE894,0xE9B9,0xE159,0xE5D2,0xE28D,0xE5D4,0xE405,0xE89C,0xF8C7,0xE5D5,0xE8B6,0xE8B8,0xE9F7,0xE55D,0xF028,0xE1E0,0xE63E,0xE1A7 --format lvgl -o ../source-fonts/material_symbols_shared_16.c --force-fast-kern-format
|
||||
* Opts: --no-compress --no-prefilter --bpp 2 --size 16 --font MaterialSymbolsRounded.ttf -r 0xE145,0xE5C3,0xE770,0xEF40,0xEBCC,0xEFE6,0xEF4A,0xE5CD,0xF15C,0xE668,0xE92E,0xE326,0xEB97,0xE745,0xEC1C,0xE2C7,0xF720,0xF090,0xE8AF,0xE30F,0xE8FD,0xE9F4,0xE3F4,0xE316,0xE90F,0xEA07,0xE9B9,0xE159,0xE5D2,0xE28D,0xE5D4,0xE405,0xE89C,0xF8C7,0xE5D5,0xEF7A,0xE8B8,0xE9F7,0xE55D,0xF028,0xE1E0,0xE63E,0xE1A7 --format lvgl -o ../source-fonts/material_symbols_shared_16.c --force-fast-kern-format
|
||||
******************************************************************************/
|
||||
|
||||
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
|
||||
@ -114,11 +114,6 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = {
|
||||
0x14, 0x14, 0x14, 0x3d, 0x3d, 0x3d, 0x3c, 0x3c,
|
||||
0x3c, 0x0, 0x0, 0x0,
|
||||
|
||||
/* U+E5CA "" */
|
||||
0x0, 0x0, 0x8, 0x0, 0x0, 0x3c, 0x0, 0x0,
|
||||
0xf0, 0x10, 0x3, 0xc0, 0x38, 0xf, 0x0, 0xe,
|
||||
0x3c, 0x0, 0x3, 0xf0, 0x0, 0x0, 0x80, 0x0,
|
||||
|
||||
/* U+E5CD "" */
|
||||
0x20, 0x0, 0x43, 0xc0, 0x1d, 0xf, 0x7, 0x40,
|
||||
0x3e, 0xd0, 0x0, 0xf4, 0x0, 0x1f, 0xc0, 0x7,
|
||||
@ -149,6 +144,11 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = {
|
||||
0x0, 0x1, 0x0, 0x0, 0x0, 0xb, 0xc0, 0x0,
|
||||
0x0, 0xf, 0xd0, 0x0, 0x0, 0x7, 0xc0, 0x0,
|
||||
|
||||
/* U+E668 "" */
|
||||
0x0, 0x0, 0x8, 0x0, 0x0, 0x3c, 0x0, 0x0,
|
||||
0xf0, 0x10, 0x3, 0xc0, 0x38, 0xf, 0x0, 0xe,
|
||||
0x3c, 0x0, 0x3, 0xf0, 0x0, 0x0, 0x80, 0x0,
|
||||
|
||||
/* U+E745 "" */
|
||||
0x15, 0x55, 0x0, 0xf, 0xff, 0xc0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x55, 0x54, 0x0, 0x3f, 0xff, 0x0,
|
||||
@ -163,15 +163,6 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = {
|
||||
0xf4, 0xff, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0x55, 0x55, 0x55,
|
||||
|
||||
/* U+E894 "" */
|
||||
0x0, 0x15, 0x0, 0x0, 0x1f, 0xff, 0x40, 0xb,
|
||||
0xba, 0xee, 0x2, 0xc7, 0xc, 0x74, 0x39, 0xf5,
|
||||
0xe7, 0xcb, 0xff, 0xff, 0xfd, 0xa0, 0xd0, 0x70,
|
||||
0xea, 0xc, 0x7, 0xe, 0xb5, 0xe5, 0xb5, 0xd7,
|
||||
0xff, 0xff, 0xfc, 0x3c, 0xb0, 0xd3, 0x80, 0xe7,
|
||||
0x5c, 0xf0, 0x3, 0xff, 0xfc, 0x0, 0x6, 0xf9,
|
||||
0x0,
|
||||
|
||||
/* U+E89C "" */
|
||||
0x15, 0x54, 0x0, 0x3f, 0xff, 0x40, 0x70, 0x7,
|
||||
0xd0, 0x70, 0x7, 0xf4, 0x70, 0x7, 0xfc, 0x70,
|
||||
@ -188,13 +179,6 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = {
|
||||
0x7f, 0xff, 0xfc, 0x3, 0xff, 0xff, 0xc0, 0x0,
|
||||
0x0, 0x3c, 0x0, 0x0, 0x0, 0x80,
|
||||
|
||||
/* U+E8B6 "" */
|
||||
0xb, 0xf4, 0x0, 0x3d, 0x6d, 0x0, 0xb0, 0x7,
|
||||
0x0, 0xe0, 0x3, 0x40, 0xd0, 0x3, 0x80, 0xe0,
|
||||
0x3, 0x40, 0xb0, 0xb, 0x0, 0x3e, 0xbf, 0x0,
|
||||
0x7, 0xe2, 0xc0, 0x0, 0x0, 0xb0, 0x0, 0x0,
|
||||
0x2c, 0x0, 0x0, 0x9,
|
||||
|
||||
/* U+E8B8 "" */
|
||||
0x0, 0x5, 0x0, 0x0, 0x3, 0xfc, 0x0, 0x4,
|
||||
0x35, 0xc1, 0x2, 0xff, 0xf, 0xf8, 0x35, 0x40,
|
||||
@ -252,6 +236,15 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = {
|
||||
0xd0, 0x0, 0x7, 0xd0, 0x0, 0x7, 0xe5, 0x55,
|
||||
0x5b, 0xbf, 0xff, 0xfe,
|
||||
|
||||
/* U+EA07 "" */
|
||||
0x0, 0x15, 0x0, 0x0, 0x1f, 0xff, 0x40, 0xb,
|
||||
0xba, 0xee, 0x2, 0xc7, 0xc, 0x74, 0x39, 0xf5,
|
||||
0xe7, 0xcb, 0xff, 0xff, 0xfd, 0xa0, 0xd0, 0x70,
|
||||
0xea, 0xc, 0x7, 0xe, 0xb5, 0xe5, 0xb5, 0xd7,
|
||||
0xff, 0xff, 0xfc, 0x3c, 0xb0, 0xd3, 0x80, 0xe7,
|
||||
0x5c, 0xf0, 0x3, 0xff, 0xfc, 0x0, 0x6, 0xf9,
|
||||
0x0,
|
||||
|
||||
/* U+EB97 "" */
|
||||
0x7f, 0xff, 0xff, 0xce, 0x55, 0x55, 0x5d, 0xd0,
|
||||
0x0, 0x0, 0xdd, 0x15, 0x53, 0x4d, 0xd1, 0x55,
|
||||
@ -292,6 +285,13 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = {
|
||||
0x0, 0xf0, 0x3, 0xea, 0xbc, 0x0, 0x6, 0xf9,
|
||||
0x0,
|
||||
|
||||
/* U+EF7A "" */
|
||||
0xb, 0xf4, 0x0, 0x3d, 0x6d, 0x0, 0xb0, 0x7,
|
||||
0x0, 0xe0, 0x3, 0x40, 0xd0, 0x3, 0x80, 0xe0,
|
||||
0x3, 0x40, 0xb0, 0xb, 0x0, 0x3e, 0xbf, 0x0,
|
||||
0x7, 0xe2, 0xc0, 0x0, 0x0, 0xb0, 0x0, 0x0,
|
||||
0x2c, 0x0, 0x0, 0x9,
|
||||
|
||||
/* U+EFE6 "" */
|
||||
0xb, 0xd0, 0x3c, 0x1d, 0xb0, 0xbe, 0x28, 0x34,
|
||||
0xff, 0x28, 0x34, 0xff, 0x28, 0x34, 0xbe, 0x28,
|
||||
@ -360,30 +360,30 @@ static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = {
|
||||
{.bitmap_index = 377, .adv_w = 256, .box_w = 8, .box_h = 12, .ofs_x = 4, .ofs_y = 2},
|
||||
{.bitmap_index = 401, .adv_w = 256, .box_w = 12, .box_h = 12, .ofs_x = 2, .ofs_y = 2},
|
||||
{.bitmap_index = 437, .adv_w = 256, .box_w = 12, .box_h = 12, .ofs_x = 2, .ofs_y = 2},
|
||||
{.bitmap_index = 473, .adv_w = 256, .box_w = 12, .box_h = 8, .ofs_x = 2, .ofs_y = 4},
|
||||
{.bitmap_index = 497, .adv_w = 256, .box_w = 10, .box_h = 10, .ofs_x = 3, .ofs_y = 3},
|
||||
{.bitmap_index = 522, .adv_w = 256, .box_w = 12, .box_h = 8, .ofs_x = 2, .ofs_y = 4},
|
||||
{.bitmap_index = 546, .adv_w = 256, .box_w = 4, .box_h = 12, .ofs_x = 6, .ofs_y = 2},
|
||||
{.bitmap_index = 558, .adv_w = 256, .box_w = 12, .box_h = 12, .ofs_x = 2, .ofs_y = 2},
|
||||
{.bitmap_index = 594, .adv_w = 256, .box_w = 16, .box_h = 12, .ofs_x = 0, .ofs_y = 2},
|
||||
{.bitmap_index = 473, .adv_w = 256, .box_w = 10, .box_h = 10, .ofs_x = 3, .ofs_y = 3},
|
||||
{.bitmap_index = 498, .adv_w = 256, .box_w = 12, .box_h = 8, .ofs_x = 2, .ofs_y = 4},
|
||||
{.bitmap_index = 522, .adv_w = 256, .box_w = 4, .box_h = 12, .ofs_x = 6, .ofs_y = 2},
|
||||
{.bitmap_index = 534, .adv_w = 256, .box_w = 12, .box_h = 12, .ofs_x = 2, .ofs_y = 2},
|
||||
{.bitmap_index = 570, .adv_w = 256, .box_w = 16, .box_h = 12, .ofs_x = 0, .ofs_y = 2},
|
||||
{.bitmap_index = 618, .adv_w = 256, .box_w = 12, .box_h = 8, .ofs_x = 2, .ofs_y = 4},
|
||||
{.bitmap_index = 642, .adv_w = 256, .box_w = 13, .box_h = 12, .ofs_x = 2, .ofs_y = 2},
|
||||
{.bitmap_index = 681, .adv_w = 256, .box_w = 12, .box_h = 12, .ofs_x = 2, .ofs_y = 2},
|
||||
{.bitmap_index = 717, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = 1},
|
||||
{.bitmap_index = 766, .adv_w = 256, .box_w = 12, .box_h = 14, .ofs_x = 2, .ofs_y = 1},
|
||||
{.bitmap_index = 808, .adv_w = 256, .box_w = 14, .box_h = 13, .ofs_x = 1, .ofs_y = 2},
|
||||
{.bitmap_index = 854, .adv_w = 256, .box_w = 12, .box_h = 12, .ofs_x = 2, .ofs_y = 2},
|
||||
{.bitmap_index = 890, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = 1},
|
||||
{.bitmap_index = 939, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = 1},
|
||||
{.bitmap_index = 988, .adv_w = 256, .box_w = 10, .box_h = 14, .ofs_x = 3, .ofs_y = 1},
|
||||
{.bitmap_index = 1023, .adv_w = 256, .box_w = 12, .box_h = 12, .ofs_x = 2, .ofs_y = 2},
|
||||
{.bitmap_index = 1059, .adv_w = 256, .box_w = 14, .box_h = 12, .ofs_x = 1, .ofs_y = 2},
|
||||
{.bitmap_index = 1101, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = 0},
|
||||
{.bitmap_index = 1165, .adv_w = 256, .box_w = 12, .box_h = 12, .ofs_x = 2, .ofs_y = 2},
|
||||
{.bitmap_index = 1201, .adv_w = 256, .box_w = 14, .box_h = 13, .ofs_x = 1, .ofs_y = 1},
|
||||
{.bitmap_index = 1247, .adv_w = 256, .box_w = 12, .box_h = 14, .ofs_x = 2, .ofs_y = 1},
|
||||
{.bitmap_index = 1289, .adv_w = 256, .box_w = 12, .box_h = 14, .ofs_x = 2, .ofs_y = 1},
|
||||
{.bitmap_index = 1331, .adv_w = 256, .box_w = 13, .box_h = 12, .ofs_x = 2, .ofs_y = 2},
|
||||
{.bitmap_index = 1370, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = 1},
|
||||
{.bitmap_index = 717, .adv_w = 256, .box_w = 12, .box_h = 14, .ofs_x = 2, .ofs_y = 1},
|
||||
{.bitmap_index = 759, .adv_w = 256, .box_w = 14, .box_h = 13, .ofs_x = 1, .ofs_y = 2},
|
||||
{.bitmap_index = 805, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = 1},
|
||||
{.bitmap_index = 854, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = 1},
|
||||
{.bitmap_index = 903, .adv_w = 256, .box_w = 10, .box_h = 14, .ofs_x = 3, .ofs_y = 1},
|
||||
{.bitmap_index = 938, .adv_w = 256, .box_w = 12, .box_h = 12, .ofs_x = 2, .ofs_y = 2},
|
||||
{.bitmap_index = 974, .adv_w = 256, .box_w = 14, .box_h = 12, .ofs_x = 1, .ofs_y = 2},
|
||||
{.bitmap_index = 1016, .adv_w = 256, .box_w = 16, .box_h = 16, .ofs_x = 0, .ofs_y = 0},
|
||||
{.bitmap_index = 1080, .adv_w = 256, .box_w = 12, .box_h = 12, .ofs_x = 2, .ofs_y = 2},
|
||||
{.bitmap_index = 1116, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = 1},
|
||||
{.bitmap_index = 1165, .adv_w = 256, .box_w = 14, .box_h = 13, .ofs_x = 1, .ofs_y = 1},
|
||||
{.bitmap_index = 1211, .adv_w = 256, .box_w = 12, .box_h = 14, .ofs_x = 2, .ofs_y = 1},
|
||||
{.bitmap_index = 1253, .adv_w = 256, .box_w = 12, .box_h = 14, .ofs_x = 2, .ofs_y = 1},
|
||||
{.bitmap_index = 1295, .adv_w = 256, .box_w = 13, .box_h = 12, .ofs_x = 2, .ofs_y = 2},
|
||||
{.bitmap_index = 1334, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = 1},
|
||||
{.bitmap_index = 1383, .adv_w = 256, .box_w = 12, .box_h = 12, .ofs_x = 2, .ofs_y = 2},
|
||||
{.bitmap_index = 1419, .adv_w = 256, .box_w = 12, .box_h = 12, .ofs_x = 2, .ofs_y = 2},
|
||||
{.bitmap_index = 1455, .adv_w = 256, .box_w = 16, .box_h = 12, .ofs_x = 0, .ofs_y = 2},
|
||||
{.bitmap_index = 1503, .adv_w = 256, .box_w = 12, .box_h = 12, .ofs_x = 2, .ofs_y = 2},
|
||||
@ -398,10 +398,10 @@ static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = {
|
||||
|
||||
static const uint16_t unicode_list_0[] = {
|
||||
0x0, 0x14, 0x62, 0x9b, 0x148, 0x182, 0x1ca, 0x1d1,
|
||||
0x1e1, 0x2af, 0x2c0, 0x418, 0x47e, 0x485, 0x488, 0x48d,
|
||||
0x48f, 0x490, 0x4f9, 0x600, 0x62b, 0x74f, 0x757, 0x76a,
|
||||
0x771, 0x773, 0x7b8, 0x7ca, 0x7e9, 0x874, 0x8af, 0x8b2,
|
||||
0xa52, 0xa87, 0xad7, 0xdfb, 0xe05, 0xea1, 0xee3, 0xf4b,
|
||||
0x1e1, 0x2af, 0x2c0, 0x418, 0x47e, 0x488, 0x48d, 0x48f,
|
||||
0x490, 0x4f9, 0x523, 0x600, 0x62b, 0x757, 0x76a, 0x773,
|
||||
0x7b8, 0x7ca, 0x7e9, 0x874, 0x8af, 0x8b2, 0x8c2, 0xa52,
|
||||
0xa87, 0xad7, 0xdfb, 0xe05, 0xe35, 0xea1, 0xee3, 0xf4b,
|
||||
0x1017, 0x15db, 0x1782
|
||||
};
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
/*******************************************************************************
|
||||
* Size: 20 px
|
||||
* Bpp: 2
|
||||
* Opts: --no-compress --no-prefilter --bpp 2 --size 20 --font MaterialSymbolsRounded.ttf -r 0xE145,0xE5C3,0xE770,0xEF40,0xEBCC,0xEFE6,0xEF4A,0xE5CD,0xF15C,0xE5CA,0xE92E,0xE326,0xEB97,0xE745,0xEC1C,0xE2C7,0xF720,0xF090,0xE8AF,0xE30F,0xE8FD,0xE9F4,0xE3F4,0xE316,0xE90F,0xE894,0xE9B9,0xE159,0xE5D2,0xE28D,0xE5D4,0xE405,0xE89C,0xF8C7,0xE5D5,0xE8B6,0xE8B8,0xE9F7,0xE55D,0xF028,0xE1E0,0xE63E,0xE1A7 --format lvgl -o ../source-fonts/material_symbols_shared_20.c --force-fast-kern-format
|
||||
* Opts: --no-compress --no-prefilter --bpp 2 --size 20 --font MaterialSymbolsRounded.ttf -r 0xE145,0xE5C3,0xE770,0xEF40,0xEBCC,0xEFE6,0xEF4A,0xE5CD,0xF15C,0xE668,0xE92E,0xE326,0xEB97,0xE745,0xEC1C,0xE2C7,0xF720,0xF090,0xE8AF,0xE30F,0xE8FD,0xE9F4,0xE3F4,0xE316,0xE90F,0xEA07,0xE9B9,0xE159,0xE5D2,0xE28D,0xE5D4,0xE405,0xE89C,0xF8C7,0xE5D5,0xEF7A,0xE8B8,0xE9F7,0xE55D,0xF028,0xE1E0,0xE63E,0xE1A7 --format lvgl -o ../source-fonts/material_symbols_shared_20.c --force-fast-kern-format
|
||||
******************************************************************************/
|
||||
|
||||
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
|
||||
@ -142,13 +142,6 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = {
|
||||
0xf4, 0xbd, 0xbe, 0x2f, 0x8b, 0xe3, 0x80, 0xe0,
|
||||
0x38,
|
||||
|
||||
/* U+E5CA "" */
|
||||
0x0, 0x0, 0x0, 0x80, 0x0, 0x0, 0x3d, 0x0,
|
||||
0x0, 0xf, 0x40, 0x0, 0x3, 0xd0, 0x10, 0x0,
|
||||
0xf4, 0x7, 0xc0, 0x3d, 0x0, 0x2f, 0xf, 0x40,
|
||||
0x0, 0xbf, 0xd0, 0x0, 0x2, 0xf4, 0x0, 0x0,
|
||||
0x5, 0x0, 0x0,
|
||||
|
||||
/* U+E5CD "" */
|
||||
0x20, 0x0, 0x9, 0x3c, 0x0, 0x2e, 0x1f, 0x0,
|
||||
0xb8, 0x7, 0xc2, 0xe0, 0x1, 0xfb, 0x80, 0x0,
|
||||
@ -188,6 +181,13 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = {
|
||||
0x0, 0x0, 0x0, 0x7f, 0x0, 0x0, 0x0, 0x0,
|
||||
0x4, 0x0, 0x0,
|
||||
|
||||
/* U+E668 "" */
|
||||
0x0, 0x0, 0x0, 0x80, 0x0, 0x0, 0x3d, 0x0,
|
||||
0x0, 0xf, 0x40, 0x0, 0x3, 0xd0, 0x10, 0x0,
|
||||
0xf4, 0x7, 0xc0, 0x3d, 0x0, 0x2f, 0xf, 0x40,
|
||||
0x0, 0xbf, 0xd0, 0x0, 0x2, 0xf4, 0x0, 0x0,
|
||||
0x5, 0x0, 0x0,
|
||||
|
||||
/* U+E745 "" */
|
||||
0x6a, 0xaa, 0x80, 0x0, 0x7f, 0xff, 0xd0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x2a, 0xaa, 0x80, 0x0,
|
||||
@ -206,19 +206,6 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = {
|
||||
0xbe, 0x3f, 0xff, 0xce, 0xbf, 0xff, 0xff, 0xfe,
|
||||
0xbf, 0xff, 0xff, 0xfe, 0x7f, 0xff, 0xff, 0xfd,
|
||||
|
||||
/* U+E894 "" */
|
||||
0x0, 0x1, 0x64, 0x0, 0x0, 0x2, 0xff, 0xfc,
|
||||
0x0, 0x1, 0xff, 0xef, 0xf4, 0x0, 0x7c, 0xb4,
|
||||
0xe3, 0xd0, 0xf, 0xf, 0xb, 0xf, 0x2, 0xfa,
|
||||
0xfa, 0xba, 0xb8, 0x3f, 0xff, 0xff, 0xff, 0xc3,
|
||||
0x82, 0xc0, 0x3c, 0x1d, 0x34, 0x2c, 0x3, 0xc1,
|
||||
0xd3, 0x42, 0xc0, 0x3c, 0x1d, 0x3e, 0xbe, 0xab,
|
||||
0xea, 0xc2, 0xff, 0xff, 0xff, 0xfc, 0x1e, 0xe,
|
||||
0xb, 0x4b, 0x80, 0xb4, 0xf0, 0xf1, 0xf0, 0x3,
|
||||
0xe7, 0x9e, 0xbc, 0x0, 0xb, 0xff, 0xff, 0x0,
|
||||
0x0, 0x1b, 0xfe, 0x40, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0,
|
||||
|
||||
/* U+E89C "" */
|
||||
0x1a, 0xaa, 0x40, 0xb, 0xff, 0xfe, 0x0, 0xb0,
|
||||
0x1, 0xf8, 0xb, 0x0, 0xf, 0xe0, 0xb0, 0x0,
|
||||
@ -241,16 +228,6 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = {
|
||||
0x0, 0x0, 0x3, 0xe0, 0x0, 0x0, 0x0, 0x1d,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
|
||||
/* U+E8B6 "" */
|
||||
0x0, 0x55, 0x0, 0x0, 0x7, 0xff, 0xd0, 0x0,
|
||||
0x1f, 0x41, 0xf4, 0x0, 0x3c, 0x0, 0x3c, 0x0,
|
||||
0x74, 0x0, 0x2c, 0x0, 0x70, 0x0, 0x1d, 0x0,
|
||||
0x74, 0x0, 0x1d, 0x0, 0x38, 0x0, 0x2c, 0x0,
|
||||
0x3d, 0x0, 0x78, 0x0, 0xf, 0xeb, 0xfc, 0x0,
|
||||
0x2, 0xff, 0x5f, 0x0, 0x0, 0x0, 0x7, 0xc0,
|
||||
0x0, 0x0, 0x1, 0xf0, 0x0, 0x0, 0x0, 0x7c,
|
||||
0x0, 0x0, 0x0, 0x1c,
|
||||
|
||||
/* U+E8B8 "" */
|
||||
0x0, 0x6, 0x90, 0x0, 0x0, 0x7, 0xfd, 0x0,
|
||||
0x0, 0x2, 0xc3, 0x80, 0x0, 0x79, 0xf0, 0xf6,
|
||||
@ -330,6 +307,19 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = {
|
||||
0xb0, 0x0, 0x0, 0xe, 0x70, 0x0, 0x0, 0xe,
|
||||
0x7f, 0xff, 0xff, 0xfd, 0x1a, 0xaa, 0xaa, 0xa4,
|
||||
|
||||
/* U+EA07 "" */
|
||||
0x0, 0x1, 0x64, 0x0, 0x0, 0x2, 0xff, 0xfc,
|
||||
0x0, 0x1, 0xff, 0xef, 0xf4, 0x0, 0x7c, 0xb4,
|
||||
0xe3, 0xd0, 0xf, 0xf, 0xb, 0xf, 0x2, 0xfa,
|
||||
0xfa, 0xba, 0xb8, 0x3f, 0xff, 0xff, 0xff, 0xc3,
|
||||
0x82, 0xc0, 0x3c, 0x1d, 0x34, 0x2c, 0x3, 0xc1,
|
||||
0xd3, 0x42, 0xc0, 0x3c, 0x1d, 0x3e, 0xbe, 0xab,
|
||||
0xea, 0xc2, 0xff, 0xff, 0xff, 0xfc, 0x1e, 0xe,
|
||||
0xb, 0x4b, 0x80, 0xb4, 0xf0, 0xf1, 0xf0, 0x3,
|
||||
0xe7, 0x9e, 0xbc, 0x0, 0xb, 0xff, 0xff, 0x0,
|
||||
0x0, 0x1b, 0xfe, 0x40, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0,
|
||||
|
||||
/* U+EB97 "" */
|
||||
0xa, 0xaa, 0xaa, 0xaa, 0x43, 0xff, 0xff, 0xff,
|
||||
0xfd, 0x38, 0x0, 0x0, 0x0, 0xe3, 0x80, 0x0,
|
||||
@ -384,6 +374,16 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = {
|
||||
0x0, 0x1b, 0xff, 0x40, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0,
|
||||
|
||||
/* U+EF7A "" */
|
||||
0x0, 0x55, 0x0, 0x0, 0x7, 0xff, 0xd0, 0x0,
|
||||
0x1f, 0x41, 0xf4, 0x0, 0x3c, 0x0, 0x3c, 0x0,
|
||||
0x74, 0x0, 0x2c, 0x0, 0x70, 0x0, 0x1d, 0x0,
|
||||
0x74, 0x0, 0x1d, 0x0, 0x38, 0x0, 0x2c, 0x0,
|
||||
0x3d, 0x0, 0x78, 0x0, 0xf, 0xeb, 0xfc, 0x0,
|
||||
0x2, 0xff, 0x5f, 0x0, 0x0, 0x0, 0x7, 0xc0,
|
||||
0x0, 0x0, 0x1, 0xf0, 0x0, 0x0, 0x0, 0x7c,
|
||||
0x0, 0x0, 0x0, 0x1c,
|
||||
|
||||
/* U+EFE6 "" */
|
||||
0x0, 0x54, 0x1, 0x90, 0x3, 0xfe, 0x3, 0xf0,
|
||||
0xb, 0x8b, 0x4b, 0xf8, 0xf, 0x3, 0x8f, 0xfc,
|
||||
@ -470,30 +470,30 @@ static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = {
|
||||
{.bitmap_index = 578, .adv_w = 320, .box_w = 10, .box_h = 16, .ofs_x = 5, .ofs_y = 2},
|
||||
{.bitmap_index = 618, .adv_w = 320, .box_w = 14, .box_h = 16, .ofs_x = 3, .ofs_y = 2},
|
||||
{.bitmap_index = 674, .adv_w = 320, .box_w = 14, .box_h = 14, .ofs_x = 3, .ofs_y = 3},
|
||||
{.bitmap_index = 723, .adv_w = 320, .box_w = 14, .box_h = 10, .ofs_x = 3, .ofs_y = 5},
|
||||
{.bitmap_index = 758, .adv_w = 320, .box_w = 12, .box_h = 12, .ofs_x = 4, .ofs_y = 4},
|
||||
{.bitmap_index = 794, .adv_w = 320, .box_w = 16, .box_h = 10, .ofs_x = 2, .ofs_y = 5},
|
||||
{.bitmap_index = 834, .adv_w = 320, .box_w = 4, .box_h = 14, .ofs_x = 8, .ofs_y = 3},
|
||||
{.bitmap_index = 848, .adv_w = 320, .box_w = 14, .box_h = 14, .ofs_x = 3, .ofs_y = 3},
|
||||
{.bitmap_index = 897, .adv_w = 320, .box_w = 20, .box_h = 15, .ofs_x = 0, .ofs_y = 2},
|
||||
{.bitmap_index = 723, .adv_w = 320, .box_w = 12, .box_h = 12, .ofs_x = 4, .ofs_y = 4},
|
||||
{.bitmap_index = 759, .adv_w = 320, .box_w = 16, .box_h = 10, .ofs_x = 2, .ofs_y = 5},
|
||||
{.bitmap_index = 799, .adv_w = 320, .box_w = 4, .box_h = 14, .ofs_x = 8, .ofs_y = 3},
|
||||
{.bitmap_index = 813, .adv_w = 320, .box_w = 14, .box_h = 14, .ofs_x = 3, .ofs_y = 3},
|
||||
{.bitmap_index = 862, .adv_w = 320, .box_w = 20, .box_h = 15, .ofs_x = 0, .ofs_y = 2},
|
||||
{.bitmap_index = 937, .adv_w = 320, .box_w = 14, .box_h = 10, .ofs_x = 3, .ofs_y = 5},
|
||||
{.bitmap_index = 972, .adv_w = 320, .box_w = 16, .box_h = 14, .ofs_x = 3, .ofs_y = 3},
|
||||
{.bitmap_index = 1028, .adv_w = 320, .box_w = 16, .box_h = 14, .ofs_x = 2, .ofs_y = 3},
|
||||
{.bitmap_index = 1084, .adv_w = 320, .box_w = 18, .box_h = 18, .ofs_x = 1, .ofs_y = 1},
|
||||
{.bitmap_index = 1165, .adv_w = 320, .box_w = 14, .box_h = 18, .ofs_x = 3, .ofs_y = 1},
|
||||
{.bitmap_index = 1228, .adv_w = 320, .box_w = 18, .box_h = 17, .ofs_x = 1, .ofs_y = 2},
|
||||
{.bitmap_index = 1305, .adv_w = 320, .box_w = 16, .box_h = 15, .ofs_x = 2, .ofs_y = 3},
|
||||
{.bitmap_index = 1365, .adv_w = 320, .box_w = 17, .box_h = 18, .ofs_x = 2, .ofs_y = 1},
|
||||
{.bitmap_index = 1442, .adv_w = 320, .box_w = 18, .box_h = 18, .ofs_x = 1, .ofs_y = 1},
|
||||
{.bitmap_index = 1523, .adv_w = 320, .box_w = 14, .box_h = 18, .ofs_x = 3, .ofs_y = 1},
|
||||
{.bitmap_index = 1586, .adv_w = 320, .box_w = 14, .box_h = 16, .ofs_x = 3, .ofs_y = 2},
|
||||
{.bitmap_index = 1642, .adv_w = 320, .box_w = 18, .box_h = 14, .ofs_x = 1, .ofs_y = 3},
|
||||
{.bitmap_index = 1705, .adv_w = 320, .box_w = 20, .box_h = 20, .ofs_x = 0, .ofs_y = 0},
|
||||
{.bitmap_index = 1805, .adv_w = 320, .box_w = 16, .box_h = 16, .ofs_x = 2, .ofs_y = 2},
|
||||
{.bitmap_index = 1869, .adv_w = 320, .box_w = 18, .box_h = 16, .ofs_x = 1, .ofs_y = 2},
|
||||
{.bitmap_index = 1941, .adv_w = 320, .box_w = 16, .box_h = 18, .ofs_x = 2, .ofs_y = 1},
|
||||
{.bitmap_index = 2013, .adv_w = 320, .box_w = 14, .box_h = 18, .ofs_x = 3, .ofs_y = 1},
|
||||
{.bitmap_index = 2076, .adv_w = 320, .box_w = 16, .box_h = 14, .ofs_x = 3, .ofs_y = 3},
|
||||
{.bitmap_index = 2132, .adv_w = 320, .box_w = 18, .box_h = 18, .ofs_x = 1, .ofs_y = 1},
|
||||
{.bitmap_index = 1084, .adv_w = 320, .box_w = 14, .box_h = 18, .ofs_x = 3, .ofs_y = 1},
|
||||
{.bitmap_index = 1147, .adv_w = 320, .box_w = 18, .box_h = 17, .ofs_x = 1, .ofs_y = 2},
|
||||
{.bitmap_index = 1224, .adv_w = 320, .box_w = 17, .box_h = 18, .ofs_x = 2, .ofs_y = 1},
|
||||
{.bitmap_index = 1301, .adv_w = 320, .box_w = 18, .box_h = 18, .ofs_x = 1, .ofs_y = 1},
|
||||
{.bitmap_index = 1382, .adv_w = 320, .box_w = 14, .box_h = 18, .ofs_x = 3, .ofs_y = 1},
|
||||
{.bitmap_index = 1445, .adv_w = 320, .box_w = 14, .box_h = 16, .ofs_x = 3, .ofs_y = 2},
|
||||
{.bitmap_index = 1501, .adv_w = 320, .box_w = 18, .box_h = 14, .ofs_x = 1, .ofs_y = 3},
|
||||
{.bitmap_index = 1564, .adv_w = 320, .box_w = 20, .box_h = 20, .ofs_x = 0, .ofs_y = 0},
|
||||
{.bitmap_index = 1664, .adv_w = 320, .box_w = 16, .box_h = 16, .ofs_x = 2, .ofs_y = 2},
|
||||
{.bitmap_index = 1728, .adv_w = 320, .box_w = 18, .box_h = 18, .ofs_x = 1, .ofs_y = 1},
|
||||
{.bitmap_index = 1809, .adv_w = 320, .box_w = 18, .box_h = 16, .ofs_x = 1, .ofs_y = 2},
|
||||
{.bitmap_index = 1881, .adv_w = 320, .box_w = 16, .box_h = 18, .ofs_x = 2, .ofs_y = 1},
|
||||
{.bitmap_index = 1953, .adv_w = 320, .box_w = 14, .box_h = 18, .ofs_x = 3, .ofs_y = 1},
|
||||
{.bitmap_index = 2016, .adv_w = 320, .box_w = 16, .box_h = 14, .ofs_x = 3, .ofs_y = 3},
|
||||
{.bitmap_index = 2072, .adv_w = 320, .box_w = 18, .box_h = 18, .ofs_x = 1, .ofs_y = 1},
|
||||
{.bitmap_index = 2153, .adv_w = 320, .box_w = 16, .box_h = 15, .ofs_x = 2, .ofs_y = 3},
|
||||
{.bitmap_index = 2213, .adv_w = 320, .box_w = 16, .box_h = 16, .ofs_x = 2, .ofs_y = 2},
|
||||
{.bitmap_index = 2277, .adv_w = 320, .box_w = 20, .box_h = 14, .ofs_x = 0, .ofs_y = 3},
|
||||
{.bitmap_index = 2347, .adv_w = 320, .box_w = 14, .box_h = 14, .ofs_x = 3, .ofs_y = 3},
|
||||
@ -508,10 +508,10 @@ static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = {
|
||||
|
||||
static const uint16_t unicode_list_0[] = {
|
||||
0x0, 0x14, 0x62, 0x9b, 0x148, 0x182, 0x1ca, 0x1d1,
|
||||
0x1e1, 0x2af, 0x2c0, 0x418, 0x47e, 0x485, 0x488, 0x48d,
|
||||
0x48f, 0x490, 0x4f9, 0x600, 0x62b, 0x74f, 0x757, 0x76a,
|
||||
0x771, 0x773, 0x7b8, 0x7ca, 0x7e9, 0x874, 0x8af, 0x8b2,
|
||||
0xa52, 0xa87, 0xad7, 0xdfb, 0xe05, 0xea1, 0xee3, 0xf4b,
|
||||
0x1e1, 0x2af, 0x2c0, 0x418, 0x47e, 0x488, 0x48d, 0x48f,
|
||||
0x490, 0x4f9, 0x523, 0x600, 0x62b, 0x757, 0x76a, 0x773,
|
||||
0x7b8, 0x7ca, 0x7e9, 0x874, 0x8af, 0x8b2, 0x8c2, 0xa52,
|
||||
0xa87, 0xad7, 0xdfb, 0xe05, 0xe35, 0xea1, 0xee3, 0xf4b,
|
||||
0x1017, 0x15db, 0x1782
|
||||
};
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
/*******************************************************************************
|
||||
* Size: 24 px
|
||||
* Bpp: 2
|
||||
* Opts: --no-compress --no-prefilter --bpp 2 --size 24 --font MaterialSymbolsRounded.ttf -r 0xE145,0xE5C3,0xE770,0xEF40,0xEBCC,0xEFE6,0xEF4A,0xE5CD,0xF15C,0xE5CA,0xE92E,0xE326,0xEB97,0xE745,0xEC1C,0xE2C7,0xF720,0xF090,0xE8AF,0xE30F,0xE8FD,0xE9F4,0xE3F4,0xE316,0xE90F,0xE894,0xE9B9,0xE159,0xE5D2,0xE28D,0xE5D4,0xE405,0xE89C,0xF8C7,0xE5D5,0xE8B6,0xE8B8,0xE9F7,0xE55D,0xF028,0xE1E0,0xE63E,0xE1A7 --format lvgl -o ../source-fonts/material_symbols_shared_24.c --force-fast-kern-format
|
||||
* Opts: --no-compress --no-prefilter --bpp 2 --size 24 --font MaterialSymbolsRounded.ttf -r 0xE145,0xE5C3,0xE770,0xEF40,0xEBCC,0xEFE6,0xEF4A,0xE5CD,0xF15C,0xE668,0xE92E,0xE326,0xEB97,0xE745,0xEC1C,0xE2C7,0xF720,0xF090,0xE8AF,0xE30F,0xE8FD,0xE9F4,0xE3F4,0xE316,0xE90F,0xEA07,0xE9B9,0xE159,0xE5D2,0xE28D,0xE5D4,0xE405,0xE89C,0xF8C7,0xE5D5,0xEF7A,0xE8B8,0xE9F7,0xE55D,0xF028,0xE1E0,0xE63E,0xE1A7 --format lvgl -o ../source-fonts/material_symbols_shared_24.c --force-fast-kern-format
|
||||
******************************************************************************/
|
||||
|
||||
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
|
||||
@ -170,14 +170,6 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = {
|
||||
0x7d, 0x7, 0xd0, 0x7d, 0xff, 0xf, 0xf0, 0xff,
|
||||
0xff, 0xf, 0xf0, 0xff, 0x7d, 0x7, 0xd0, 0x7d,
|
||||
|
||||
/* U+E5CA "" */
|
||||
0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x3e,
|
||||
0x0, 0x0, 0x0, 0xfc, 0x0, 0x0, 0x3, 0xf0,
|
||||
0x0, 0x0, 0xf, 0xc0, 0x60, 0x0, 0x3f, 0x0,
|
||||
0xbc, 0x0, 0xfc, 0x0, 0x3f, 0x3, 0xf0, 0x0,
|
||||
0xf, 0xcf, 0xc0, 0x0, 0x3, 0xff, 0x0, 0x0,
|
||||
0x0, 0xfc, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0,
|
||||
|
||||
/* U+E5CD "" */
|
||||
0x10, 0x0, 0x0, 0x4b, 0x40, 0x0, 0x3d, 0x7d,
|
||||
0x0, 0xf, 0xc1, 0xf4, 0x3, 0xf0, 0x7, 0xd0,
|
||||
@ -225,6 +217,14 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = {
|
||||
0x0, 0x0, 0x0, 0x0, 0xf, 0xf4, 0x0, 0x0,
|
||||
0x0, 0x0, 0x7, 0xe0, 0x0, 0x0,
|
||||
|
||||
/* U+E668 "" */
|
||||
0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x3e,
|
||||
0x0, 0x0, 0x0, 0xfc, 0x0, 0x0, 0x3, 0xf0,
|
||||
0x0, 0x0, 0xf, 0xc0, 0x60, 0x0, 0x3f, 0x0,
|
||||
0xbc, 0x0, 0xfc, 0x0, 0x3f, 0x3, 0xf0, 0x0,
|
||||
0xf, 0xcf, 0xc0, 0x0, 0x3, 0xff, 0x0, 0x0,
|
||||
0x0, 0xfc, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0,
|
||||
|
||||
/* U+E745 "" */
|
||||
0xff, 0xff, 0xfc, 0x0, 0xf, 0xff, 0xff, 0xc0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
@ -248,21 +248,6 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = {
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xf0,
|
||||
|
||||
/* U+E894 "" */
|
||||
0x0, 0x6, 0xff, 0x90, 0x0, 0x0, 0x7f, 0xff,
|
||||
0xfd, 0x0, 0x2, 0xff, 0xef, 0xff, 0x80, 0xb,
|
||||
0xd7, 0xc7, 0xcb, 0xe0, 0x1f, 0xb, 0x43, 0xd1,
|
||||
0xf4, 0x3d, 0xf, 0x2, 0xe0, 0xbc, 0x7f, 0xff,
|
||||
0xff, 0xff, 0xfd, 0xbf, 0xff, 0xff, 0xff, 0xfe,
|
||||
0xf0, 0x2d, 0x0, 0xf0, 0xf, 0xf0, 0x2d, 0x0,
|
||||
0xb4, 0xf, 0xf0, 0x2d, 0x0, 0xb4, 0xf, 0xf0,
|
||||
0x2d, 0x0, 0xf0, 0xf, 0xbf, 0xff, 0xff, 0xff,
|
||||
0xfe, 0x7f, 0xff, 0xff, 0xff, 0xfd, 0x3d, 0xf,
|
||||
0x2, 0xe0, 0xbc, 0x1f, 0xb, 0x43, 0xd1, 0xf4,
|
||||
0xb, 0xd7, 0xc7, 0xcb, 0xe0, 0x2, 0xff, 0xef,
|
||||
0xff, 0x80, 0x0, 0x7f, 0xff, 0xfd, 0x0, 0x0,
|
||||
0x6, 0xff, 0x90, 0x0,
|
||||
|
||||
/* U+E89C "" */
|
||||
0x7f, 0xff, 0xf4, 0x0, 0xff, 0xff, 0xfe, 0x0,
|
||||
0xf0, 0x0, 0x3f, 0x80, 0xf0, 0x0, 0x3f, 0xe0,
|
||||
@ -289,19 +274,6 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = {
|
||||
0x0, 0x0, 0x0, 0x0, 0xbf, 0x0, 0x0, 0x0,
|
||||
0x0, 0x2f, 0x0, 0x0, 0x0, 0x0, 0x5,
|
||||
|
||||
/* U+E8B6 "" */
|
||||
0x1, 0xbf, 0x90, 0x0, 0x0, 0xbf, 0xff, 0x80,
|
||||
0x0, 0x2f, 0x40, 0x7e, 0x0, 0x7, 0xc0, 0x0,
|
||||
0xf4, 0x0, 0xb4, 0x0, 0x7, 0x80, 0xf, 0x0,
|
||||
0x0, 0x3c, 0x0, 0xf0, 0x0, 0x3, 0xc0, 0xf,
|
||||
0x0, 0x0, 0x3c, 0x0, 0xb4, 0x0, 0x7, 0x80,
|
||||
0x7, 0xc0, 0x0, 0xf0, 0x0, 0x2f, 0x40, 0x7f,
|
||||
0x0, 0x0, 0xbf, 0xff, 0xfc, 0x0, 0x1, 0xbf,
|
||||
0x83, 0xf0, 0x0, 0x0, 0x0, 0xf, 0xc0, 0x0,
|
||||
0x0, 0x0, 0x3f, 0x0, 0x0, 0x0, 0x0, 0xfc,
|
||||
0x0, 0x0, 0x0, 0x3, 0xe0, 0x0, 0x0, 0x0,
|
||||
0x8,
|
||||
|
||||
/* U+E8B8 "" */
|
||||
0x0, 0x2, 0xff, 0x0, 0x0, 0x0, 0x3, 0xff,
|
||||
0x80, 0x0, 0x0, 0x7, 0x83, 0xc0, 0x0, 0xb,
|
||||
@ -400,6 +372,21 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = {
|
||||
0xff, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff,
|
||||
0xfd,
|
||||
|
||||
/* U+EA07 "" */
|
||||
0x0, 0x6, 0xff, 0x90, 0x0, 0x0, 0x7f, 0xff,
|
||||
0xfd, 0x0, 0x2, 0xff, 0xef, 0xff, 0x80, 0xb,
|
||||
0xd7, 0xc7, 0xcb, 0xe0, 0x1f, 0xb, 0x43, 0xd1,
|
||||
0xf4, 0x3d, 0xf, 0x2, 0xe0, 0xbc, 0x7f, 0xff,
|
||||
0xff, 0xff, 0xfd, 0xbf, 0xff, 0xff, 0xff, 0xfe,
|
||||
0xf0, 0x2d, 0x0, 0xf0, 0xf, 0xf0, 0x2d, 0x0,
|
||||
0xb4, 0xf, 0xf0, 0x2d, 0x0, 0xb4, 0xf, 0xf0,
|
||||
0x2d, 0x0, 0xf0, 0xf, 0xbf, 0xff, 0xff, 0xff,
|
||||
0xfe, 0x7f, 0xff, 0xff, 0xff, 0xfd, 0x3d, 0xf,
|
||||
0x2, 0xe0, 0xbc, 0x1f, 0xb, 0x43, 0xd1, 0xf4,
|
||||
0xb, 0xd7, 0xc7, 0xcb, 0xe0, 0x2, 0xff, 0xef,
|
||||
0xff, 0x80, 0x0, 0x7f, 0xff, 0xfd, 0x0, 0x0,
|
||||
0x6, 0xff, 0x90, 0x0,
|
||||
|
||||
/* U+EB97 "" */
|
||||
0x7f, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xf0, 0x0, 0x0, 0x0, 0xf, 0xf0,
|
||||
@ -466,6 +453,19 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = {
|
||||
0x7f, 0x80, 0x0, 0x7f, 0xff, 0xfd, 0x0, 0x0,
|
||||
0x6, 0xff, 0x90, 0x0,
|
||||
|
||||
/* U+EF7A "" */
|
||||
0x1, 0xbf, 0x90, 0x0, 0x0, 0xbf, 0xff, 0x80,
|
||||
0x0, 0x2f, 0x40, 0x7e, 0x0, 0x7, 0xc0, 0x0,
|
||||
0xf4, 0x0, 0xb4, 0x0, 0x7, 0x80, 0xf, 0x0,
|
||||
0x0, 0x3c, 0x0, 0xf0, 0x0, 0x3, 0xc0, 0xf,
|
||||
0x0, 0x0, 0x3c, 0x0, 0xb4, 0x0, 0x7, 0x80,
|
||||
0x7, 0xc0, 0x0, 0xf0, 0x0, 0x2f, 0x40, 0x7f,
|
||||
0x0, 0x0, 0xbf, 0xff, 0xfc, 0x0, 0x1, 0xbf,
|
||||
0x83, 0xf0, 0x0, 0x0, 0x0, 0xf, 0xc0, 0x0,
|
||||
0x0, 0x0, 0x3f, 0x0, 0x0, 0x0, 0x0, 0xfc,
|
||||
0x0, 0x0, 0x0, 0x3, 0xe0, 0x0, 0x0, 0x0,
|
||||
0x8,
|
||||
|
||||
/* U+EFE6 "" */
|
||||
0x0, 0xbe, 0x0, 0x3f, 0xc0, 0x3f, 0xfc, 0x3,
|
||||
0xfc, 0xb, 0x82, 0xe0, 0xbf, 0xe0, 0xf0, 0xf,
|
||||
@ -565,30 +565,30 @@ static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = {
|
||||
{.bitmap_index = 747, .adv_w = 384, .box_w = 12, .box_h = 18, .ofs_x = 6, .ofs_y = 3},
|
||||
{.bitmap_index = 801, .adv_w = 384, .box_w = 16, .box_h = 18, .ofs_x = 4, .ofs_y = 3},
|
||||
{.bitmap_index = 873, .adv_w = 384, .box_w = 16, .box_h = 16, .ofs_x = 4, .ofs_y = 4},
|
||||
{.bitmap_index = 937, .adv_w = 384, .box_w = 16, .box_h = 12, .ofs_x = 4, .ofs_y = 6},
|
||||
{.bitmap_index = 985, .adv_w = 384, .box_w = 14, .box_h = 14, .ofs_x = 5, .ofs_y = 5},
|
||||
{.bitmap_index = 1034, .adv_w = 384, .box_w = 18, .box_h = 12, .ofs_x = 3, .ofs_y = 6},
|
||||
{.bitmap_index = 1088, .adv_w = 384, .box_w = 4, .box_h = 16, .ofs_x = 10, .ofs_y = 4},
|
||||
{.bitmap_index = 1104, .adv_w = 384, .box_w = 16, .box_h = 16, .ofs_x = 4, .ofs_y = 4},
|
||||
{.bitmap_index = 1168, .adv_w = 384, .box_w = 24, .box_h = 17, .ofs_x = 0, .ofs_y = 3},
|
||||
{.bitmap_index = 937, .adv_w = 384, .box_w = 14, .box_h = 14, .ofs_x = 5, .ofs_y = 5},
|
||||
{.bitmap_index = 986, .adv_w = 384, .box_w = 18, .box_h = 12, .ofs_x = 3, .ofs_y = 6},
|
||||
{.bitmap_index = 1040, .adv_w = 384, .box_w = 4, .box_h = 16, .ofs_x = 10, .ofs_y = 4},
|
||||
{.bitmap_index = 1056, .adv_w = 384, .box_w = 16, .box_h = 16, .ofs_x = 4, .ofs_y = 4},
|
||||
{.bitmap_index = 1120, .adv_w = 384, .box_w = 24, .box_h = 17, .ofs_x = 0, .ofs_y = 3},
|
||||
{.bitmap_index = 1222, .adv_w = 384, .box_w = 16, .box_h = 12, .ofs_x = 4, .ofs_y = 6},
|
||||
{.bitmap_index = 1270, .adv_w = 384, .box_w = 18, .box_h = 16, .ofs_x = 4, .ofs_y = 4},
|
||||
{.bitmap_index = 1342, .adv_w = 384, .box_w = 18, .box_h = 17, .ofs_x = 3, .ofs_y = 4},
|
||||
{.bitmap_index = 1419, .adv_w = 384, .box_w = 20, .box_h = 20, .ofs_x = 2, .ofs_y = 2},
|
||||
{.bitmap_index = 1519, .adv_w = 384, .box_w = 16, .box_h = 20, .ofs_x = 4, .ofs_y = 2},
|
||||
{.bitmap_index = 1599, .adv_w = 384, .box_w = 20, .box_h = 19, .ofs_x = 2, .ofs_y = 3},
|
||||
{.bitmap_index = 1694, .adv_w = 384, .box_w = 18, .box_h = 18, .ofs_x = 3, .ofs_y = 3},
|
||||
{.bitmap_index = 1775, .adv_w = 384, .box_w = 20, .box_h = 20, .ofs_x = 2, .ofs_y = 2},
|
||||
{.bitmap_index = 1875, .adv_w = 384, .box_w = 20, .box_h = 20, .ofs_x = 2, .ofs_y = 2},
|
||||
{.bitmap_index = 1975, .adv_w = 384, .box_w = 16, .box_h = 20, .ofs_x = 4, .ofs_y = 2},
|
||||
{.bitmap_index = 2055, .adv_w = 384, .box_w = 16, .box_h = 18, .ofs_x = 4, .ofs_y = 3},
|
||||
{.bitmap_index = 2127, .adv_w = 384, .box_w = 20, .box_h = 16, .ofs_x = 2, .ofs_y = 4},
|
||||
{.bitmap_index = 2207, .adv_w = 384, .box_w = 24, .box_h = 23, .ofs_x = 0, .ofs_y = 1},
|
||||
{.bitmap_index = 2345, .adv_w = 384, .box_w = 18, .box_h = 18, .ofs_x = 3, .ofs_y = 3},
|
||||
{.bitmap_index = 2426, .adv_w = 384, .box_w = 20, .box_h = 18, .ofs_x = 2, .ofs_y = 3},
|
||||
{.bitmap_index = 2516, .adv_w = 384, .box_w = 18, .box_h = 20, .ofs_x = 3, .ofs_y = 2},
|
||||
{.bitmap_index = 2606, .adv_w = 384, .box_w = 16, .box_h = 20, .ofs_x = 4, .ofs_y = 2},
|
||||
{.bitmap_index = 2686, .adv_w = 384, .box_w = 18, .box_h = 16, .ofs_x = 4, .ofs_y = 4},
|
||||
{.bitmap_index = 2758, .adv_w = 384, .box_w = 20, .box_h = 20, .ofs_x = 2, .ofs_y = 2},
|
||||
{.bitmap_index = 1419, .adv_w = 384, .box_w = 16, .box_h = 20, .ofs_x = 4, .ofs_y = 2},
|
||||
{.bitmap_index = 1499, .adv_w = 384, .box_w = 20, .box_h = 19, .ofs_x = 2, .ofs_y = 3},
|
||||
{.bitmap_index = 1594, .adv_w = 384, .box_w = 20, .box_h = 20, .ofs_x = 2, .ofs_y = 2},
|
||||
{.bitmap_index = 1694, .adv_w = 384, .box_w = 20, .box_h = 20, .ofs_x = 2, .ofs_y = 2},
|
||||
{.bitmap_index = 1794, .adv_w = 384, .box_w = 16, .box_h = 20, .ofs_x = 4, .ofs_y = 2},
|
||||
{.bitmap_index = 1874, .adv_w = 384, .box_w = 16, .box_h = 18, .ofs_x = 4, .ofs_y = 3},
|
||||
{.bitmap_index = 1946, .adv_w = 384, .box_w = 20, .box_h = 16, .ofs_x = 2, .ofs_y = 4},
|
||||
{.bitmap_index = 2026, .adv_w = 384, .box_w = 24, .box_h = 23, .ofs_x = 0, .ofs_y = 1},
|
||||
{.bitmap_index = 2164, .adv_w = 384, .box_w = 18, .box_h = 18, .ofs_x = 3, .ofs_y = 3},
|
||||
{.bitmap_index = 2245, .adv_w = 384, .box_w = 20, .box_h = 20, .ofs_x = 2, .ofs_y = 2},
|
||||
{.bitmap_index = 2345, .adv_w = 384, .box_w = 20, .box_h = 18, .ofs_x = 2, .ofs_y = 3},
|
||||
{.bitmap_index = 2435, .adv_w = 384, .box_w = 18, .box_h = 20, .ofs_x = 3, .ofs_y = 2},
|
||||
{.bitmap_index = 2525, .adv_w = 384, .box_w = 16, .box_h = 20, .ofs_x = 4, .ofs_y = 2},
|
||||
{.bitmap_index = 2605, .adv_w = 384, .box_w = 18, .box_h = 16, .ofs_x = 4, .ofs_y = 4},
|
||||
{.bitmap_index = 2677, .adv_w = 384, .box_w = 20, .box_h = 20, .ofs_x = 2, .ofs_y = 2},
|
||||
{.bitmap_index = 2777, .adv_w = 384, .box_w = 18, .box_h = 18, .ofs_x = 3, .ofs_y = 3},
|
||||
{.bitmap_index = 2858, .adv_w = 384, .box_w = 18, .box_h = 18, .ofs_x = 3, .ofs_y = 3},
|
||||
{.bitmap_index = 2939, .adv_w = 384, .box_w = 22, .box_h = 16, .ofs_x = 1, .ofs_y = 4},
|
||||
{.bitmap_index = 3027, .adv_w = 384, .box_w = 16, .box_h = 16, .ofs_x = 4, .ofs_y = 4},
|
||||
@ -603,10 +603,10 @@ static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = {
|
||||
|
||||
static const uint16_t unicode_list_0[] = {
|
||||
0x0, 0x14, 0x62, 0x9b, 0x148, 0x182, 0x1ca, 0x1d1,
|
||||
0x1e1, 0x2af, 0x2c0, 0x418, 0x47e, 0x485, 0x488, 0x48d,
|
||||
0x48f, 0x490, 0x4f9, 0x600, 0x62b, 0x74f, 0x757, 0x76a,
|
||||
0x771, 0x773, 0x7b8, 0x7ca, 0x7e9, 0x874, 0x8af, 0x8b2,
|
||||
0xa52, 0xa87, 0xad7, 0xdfb, 0xe05, 0xea1, 0xee3, 0xf4b,
|
||||
0x1e1, 0x2af, 0x2c0, 0x418, 0x47e, 0x488, 0x48d, 0x48f,
|
||||
0x490, 0x4f9, 0x523, 0x600, 0x62b, 0x757, 0x76a, 0x773,
|
||||
0x7b8, 0x7ca, 0x7e9, 0x874, 0x8af, 0x8b2, 0x8c2, 0xa52,
|
||||
0xa87, 0xad7, 0xdfb, 0xe05, 0xe35, 0xea1, 0xee3, 0xf4b,
|
||||
0x1017, 0x15db, 0x1782
|
||||
};
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
/*******************************************************************************
|
||||
* Size: 32 px
|
||||
* Bpp: 2
|
||||
* Opts: --no-compress --no-prefilter --bpp 2 --size 32 --font MaterialSymbolsRounded.ttf -r 0xE145,0xE5C3,0xE770,0xEF40,0xEBCC,0xEFE6,0xEF4A,0xE5CD,0xF15C,0xE5CA,0xE92E,0xE326,0xEB97,0xE745,0xEC1C,0xE2C7,0xF720,0xF090,0xE8AF,0xE30F,0xE8FD,0xE9F4,0xE3F4,0xE316,0xE90F,0xE894,0xE9B9,0xE159,0xE5D2,0xE28D,0xE5D4,0xE405,0xE89C,0xF8C7,0xE5D5,0xE8B6,0xE8B8,0xE9F7,0xE55D,0xF028,0xE1E0,0xE63E,0xE1A7 --format lvgl -o ../source-fonts/material_symbols_shared_32.c --force-fast-kern-format
|
||||
* Opts: --no-compress --no-prefilter --bpp 2 --size 32 --font MaterialSymbolsRounded.ttf -r 0xE145,0xE5C3,0xE770,0xEF40,0xEBCC,0xEFE6,0xEF4A,0xE5CD,0xF15C,0xE668,0xE92E,0xE326,0xEB97,0xE745,0xEC1C,0xE2C7,0xF720,0xF090,0xE8AF,0xE30F,0xE8FD,0xE9F4,0xE3F4,0xE316,0xE90F,0xEA07,0xE9B9,0xE159,0xE5D2,0xE28D,0xE5D4,0xE405,0xE89C,0xF8C7,0xE5D5,0xEF7A,0xE8B8,0xE9F7,0xE55D,0xF028,0xE1E0,0xE63E,0xE1A7 --format lvgl -o ../source-fonts/material_symbols_shared_32.c --force-fast-kern-format
|
||||
******************************************************************************/
|
||||
|
||||
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
|
||||
@ -274,19 +274,6 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = {
|
||||
0x7f, 0xc0, 0x7f, 0xc1, 0xe4, 0x1, 0xe4, 0x1,
|
||||
0xe4,
|
||||
|
||||
/* U+E5CA "" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x1, 0x40, 0x0, 0x0,
|
||||
0x0, 0x0, 0xbc, 0x0, 0x0, 0x0, 0x0, 0x2f,
|
||||
0xc0, 0x0, 0x0, 0x0, 0xb, 0xf0, 0x0, 0x0,
|
||||
0x0, 0x2, 0xfc, 0x0, 0x0, 0x0, 0x0, 0xbf,
|
||||
0x40, 0x0, 0x0, 0x0, 0x2f, 0xd0, 0x3, 0xc0,
|
||||
0x0, 0xb, 0xf4, 0x0, 0x7f, 0x0, 0x2, 0xfd,
|
||||
0x0, 0x2, 0xfc, 0x0, 0xbf, 0x40, 0x0, 0xb,
|
||||
0xf0, 0x2f, 0xd0, 0x0, 0x0, 0x2f, 0xcb, 0xf4,
|
||||
0x0, 0x0, 0x0, 0xbf, 0xfd, 0x0, 0x0, 0x0,
|
||||
0x2, 0xff, 0x40, 0x0, 0x0, 0x0, 0xb, 0xd0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0,
|
||||
|
||||
/* U+E5CD "" */
|
||||
0x24, 0x0, 0x0, 0x1, 0x8b, 0xd0, 0x0, 0x0,
|
||||
0x7e, 0x7f, 0x40, 0x0, 0x1f, 0xd1, 0xfd, 0x0,
|
||||
@ -364,6 +351,19 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = {
|
||||
0x0, 0x0, 0x0, 0x2f, 0xf8, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0xb, 0xe0, 0x0, 0x0, 0x0,
|
||||
|
||||
/* U+E668 "" */
|
||||
0x0, 0x0, 0x0, 0x0, 0x1, 0x40, 0x0, 0x0,
|
||||
0x0, 0x0, 0xbc, 0x0, 0x0, 0x0, 0x0, 0x2f,
|
||||
0xc0, 0x0, 0x0, 0x0, 0xb, 0xf0, 0x0, 0x0,
|
||||
0x0, 0x2, 0xfc, 0x0, 0x0, 0x0, 0x0, 0xbf,
|
||||
0x40, 0x0, 0x0, 0x0, 0x2f, 0xd0, 0x3, 0xc0,
|
||||
0x0, 0xb, 0xf4, 0x0, 0x7f, 0x0, 0x2, 0xfd,
|
||||
0x0, 0x2, 0xfc, 0x0, 0xbf, 0x40, 0x0, 0xb,
|
||||
0xf0, 0x2f, 0xd0, 0x0, 0x0, 0x2f, 0xcb, 0xf4,
|
||||
0x0, 0x0, 0x0, 0xbf, 0xfd, 0x0, 0x0, 0x0,
|
||||
0x2, 0xff, 0x40, 0x0, 0x0, 0x0, 0xb, 0xd0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0,
|
||||
|
||||
/* U+E745 "" */
|
||||
0x2a, 0xaa, 0xaa, 0xa0, 0x0, 0x0, 0x2f, 0xff,
|
||||
0xff, 0xfe, 0x0, 0x0, 0x7, 0xff, 0xff, 0xff,
|
||||
@ -403,33 +403,6 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = {
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa,
|
||||
|
||||
/* U+E894 "" */
|
||||
0x0, 0x0, 0x1, 0x69, 0x40, 0x0, 0x0, 0x0,
|
||||
0x0, 0x6f, 0xff, 0xfd, 0x0, 0x0, 0x0, 0x2,
|
||||
0xff, 0xff, 0xff, 0xd0, 0x0, 0x0, 0x1f, 0xff,
|
||||
0xfb, 0xff, 0xf4, 0x0, 0x0, 0x7f, 0x8b, 0xd3,
|
||||
0xf2, 0xfe, 0x0, 0x1, 0xfd, 0xf, 0x82, 0xf4,
|
||||
0x7f, 0x40, 0x3, 0xf4, 0x2f, 0x40, 0xfc, 0xf,
|
||||
0xc0, 0xb, 0xe0, 0x3f, 0x0, 0xbc, 0x7, 0xf0,
|
||||
0xf, 0xea, 0xbf, 0xaa, 0xfe, 0xab, 0xf4, 0x2f,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x3f, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xfc, 0x3e, 0x0, 0xfc,
|
||||
0x0, 0x3f, 0x0, 0xbc, 0x3e, 0x0, 0xfc, 0x0,
|
||||
0x2f, 0x0, 0x7d, 0x3d, 0x0, 0xfc, 0x0, 0x2f,
|
||||
0x0, 0x7d, 0x3d, 0x0, 0xfc, 0x0, 0x2f, 0x0,
|
||||
0x7d, 0x3e, 0x0, 0xfc, 0x0, 0x2f, 0x0, 0x7d,
|
||||
0x3f, 0xaa, 0xfe, 0xaa, 0xbf, 0xaa, 0xfc, 0x2f,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x1f, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xf8, 0xf, 0xd0, 0x3f,
|
||||
0x0, 0xbd, 0x3, 0xf0, 0x7, 0xf0, 0x3f, 0x0,
|
||||
0xfc, 0xb, 0xe0, 0x2, 0xfc, 0x1f, 0x41, 0xf8,
|
||||
0x2f, 0xc0, 0x0, 0xff, 0xf, 0xc3, 0xf0, 0xbf,
|
||||
0x0, 0x0, 0x3f, 0xeb, 0xe7, 0xfb, 0xfc, 0x0,
|
||||
0x0, 0xb, 0xff, 0xff, 0xff, 0xf0, 0x0, 0x0,
|
||||
0x1, 0xff, 0xff, 0xff, 0x40, 0x0, 0x0, 0x0,
|
||||
0x1b, 0xff, 0xe4, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0,
|
||||
|
||||
/* U+E89C "" */
|
||||
0x6, 0xaa, 0xaa, 0x90, 0x0, 0x3, 0xff, 0xff,
|
||||
0xff, 0x80, 0x0, 0xbf, 0xff, 0xff, 0xfe, 0x0,
|
||||
@ -477,26 +450,6 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = {
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3e, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x4,
|
||||
|
||||
/* U+E8B6 "" */
|
||||
0x0, 0x1b, 0xfe, 0x0, 0x0, 0x0, 0x1, 0xff,
|
||||
0xff, 0xe0, 0x0, 0x0, 0x7, 0xff, 0xaf, 0xfc,
|
||||
0x0, 0x0, 0x1f, 0xe0, 0x1, 0xfe, 0x0, 0x0,
|
||||
0x3f, 0x40, 0x0, 0x3f, 0x40, 0x0, 0x7e, 0x0,
|
||||
0x0, 0xf, 0xc0, 0x0, 0xbc, 0x0, 0x0, 0xb,
|
||||
0xc0, 0x0, 0xfc, 0x0, 0x0, 0x7, 0xd0, 0x0,
|
||||
0xf8, 0x0, 0x0, 0x7, 0xd0, 0x0, 0xfc, 0x0,
|
||||
0x0, 0x7, 0xd0, 0x0, 0xfc, 0x0, 0x0, 0xb,
|
||||
0xc0, 0x0, 0x7d, 0x0, 0x0, 0xf, 0xc0, 0x0,
|
||||
0x3f, 0x0, 0x0, 0x3f, 0x40, 0x0, 0x1f, 0xd0,
|
||||
0x0, 0xff, 0x0, 0x0, 0xb, 0xfe, 0xaf, 0xff,
|
||||
0x80, 0x0, 0x1, 0xff, 0xff, 0xef, 0xe0, 0x0,
|
||||
0x0, 0x2f, 0xfe, 0x3, 0xf8, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0xfe, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x3f, 0x80, 0x0, 0x0, 0x0, 0x0, 0xf, 0xe0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x3, 0xf8, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0xfd, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x3d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
|
||||
/* U+E8B8 "" */
|
||||
0x0, 0x0, 0x6, 0xa9, 0x0, 0x0, 0x0, 0x0,
|
||||
0x1, 0xff, 0xf4, 0x0, 0x0, 0x0, 0x0, 0x3f,
|
||||
@ -663,6 +616,33 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = {
|
||||
0xaa, 0xaa, 0xaa, 0xbf, 0xbf, 0xff, 0xff, 0xff,
|
||||
0xff, 0xfe, 0x2f, 0xff, 0xff, 0xff, 0xff, 0xf8,
|
||||
|
||||
/* U+EA07 "" */
|
||||
0x0, 0x0, 0x1, 0x69, 0x40, 0x0, 0x0, 0x0,
|
||||
0x0, 0x6f, 0xff, 0xfd, 0x0, 0x0, 0x0, 0x2,
|
||||
0xff, 0xff, 0xff, 0xd0, 0x0, 0x0, 0x1f, 0xff,
|
||||
0xfb, 0xff, 0xf4, 0x0, 0x0, 0x7f, 0x8b, 0xd3,
|
||||
0xf2, 0xfe, 0x0, 0x1, 0xfd, 0xf, 0x82, 0xf4,
|
||||
0x7f, 0x40, 0x3, 0xf4, 0x2f, 0x40, 0xfc, 0xf,
|
||||
0xc0, 0xb, 0xe0, 0x3f, 0x0, 0xbc, 0x7, 0xf0,
|
||||
0xf, 0xea, 0xbf, 0xaa, 0xfe, 0xab, 0xf4, 0x2f,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x3f, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xfc, 0x3e, 0x0, 0xfc,
|
||||
0x0, 0x3f, 0x0, 0xbc, 0x3e, 0x0, 0xfc, 0x0,
|
||||
0x2f, 0x0, 0x7d, 0x3d, 0x0, 0xfc, 0x0, 0x2f,
|
||||
0x0, 0x7d, 0x3d, 0x0, 0xfc, 0x0, 0x2f, 0x0,
|
||||
0x7d, 0x3e, 0x0, 0xfc, 0x0, 0x2f, 0x0, 0x7d,
|
||||
0x3f, 0xaa, 0xfe, 0xaa, 0xbf, 0xaa, 0xfc, 0x2f,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x1f, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xf8, 0xf, 0xd0, 0x3f,
|
||||
0x0, 0xbd, 0x3, 0xf0, 0x7, 0xf0, 0x3f, 0x0,
|
||||
0xfc, 0xb, 0xe0, 0x2, 0xfc, 0x1f, 0x41, 0xf8,
|
||||
0x2f, 0xc0, 0x0, 0xff, 0xf, 0xc3, 0xf0, 0xbf,
|
||||
0x0, 0x0, 0x3f, 0xeb, 0xe7, 0xfb, 0xfc, 0x0,
|
||||
0x0, 0xb, 0xff, 0xff, 0xff, 0xf0, 0x0, 0x0,
|
||||
0x1, 0xff, 0xff, 0xff, 0x40, 0x0, 0x0, 0x0,
|
||||
0x1b, 0xff, 0xe4, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0,
|
||||
|
||||
/* U+EB97 "" */
|
||||
0xb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf4, 0x3f,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0x3f, 0xaa,
|
||||
@ -778,6 +758,26 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = {
|
||||
0x1b, 0xff, 0xe4, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0,
|
||||
|
||||
/* U+EF7A "" */
|
||||
0x0, 0x1b, 0xfe, 0x0, 0x0, 0x0, 0x1, 0xff,
|
||||
0xff, 0xe0, 0x0, 0x0, 0x7, 0xff, 0xaf, 0xfc,
|
||||
0x0, 0x0, 0x1f, 0xe0, 0x1, 0xfe, 0x0, 0x0,
|
||||
0x3f, 0x40, 0x0, 0x3f, 0x40, 0x0, 0x7e, 0x0,
|
||||
0x0, 0xf, 0xc0, 0x0, 0xbc, 0x0, 0x0, 0xb,
|
||||
0xc0, 0x0, 0xfc, 0x0, 0x0, 0x7, 0xd0, 0x0,
|
||||
0xf8, 0x0, 0x0, 0x7, 0xd0, 0x0, 0xfc, 0x0,
|
||||
0x0, 0x7, 0xd0, 0x0, 0xfc, 0x0, 0x0, 0xb,
|
||||
0xc0, 0x0, 0x7d, 0x0, 0x0, 0xf, 0xc0, 0x0,
|
||||
0x3f, 0x0, 0x0, 0x3f, 0x40, 0x0, 0x1f, 0xd0,
|
||||
0x0, 0xff, 0x0, 0x0, 0xb, 0xfe, 0xaf, 0xff,
|
||||
0x80, 0x0, 0x1, 0xff, 0xff, 0xef, 0xe0, 0x0,
|
||||
0x0, 0x2f, 0xfe, 0x3, 0xf8, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0xfe, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x3f, 0x80, 0x0, 0x0, 0x0, 0x0, 0xf, 0xe0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x3, 0xf8, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0xfd, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x3d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
|
||||
/* U+EFE6 "" */
|
||||
0x0, 0x1b, 0xf4, 0x0, 0x1f, 0xf4, 0x0, 0xbf,
|
||||
0xff, 0x0, 0x2f, 0xf8, 0x1, 0xff, 0xbf, 0x80,
|
||||
@ -934,30 +934,30 @@ static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = {
|
||||
{.bitmap_index = 1409, .adv_w = 512, .box_w = 16, .box_h = 24, .ofs_x = 8, .ofs_y = 4},
|
||||
{.bitmap_index = 1505, .adv_w = 512, .box_w = 22, .box_h = 24, .ofs_x = 5, .ofs_y = 4},
|
||||
{.bitmap_index = 1637, .adv_w = 512, .box_w = 22, .box_h = 22, .ofs_x = 5, .ofs_y = 5},
|
||||
{.bitmap_index = 1758, .adv_w = 512, .box_w = 22, .box_h = 16, .ofs_x = 5, .ofs_y = 8},
|
||||
{.bitmap_index = 1846, .adv_w = 512, .box_w = 18, .box_h = 18, .ofs_x = 7, .ofs_y = 7},
|
||||
{.bitmap_index = 1927, .adv_w = 512, .box_w = 24, .box_h = 16, .ofs_x = 4, .ofs_y = 8},
|
||||
{.bitmap_index = 2023, .adv_w = 512, .box_w = 6, .box_h = 22, .ofs_x = 13, .ofs_y = 5},
|
||||
{.bitmap_index = 2056, .adv_w = 512, .box_w = 22, .box_h = 22, .ofs_x = 5, .ofs_y = 5},
|
||||
{.bitmap_index = 2177, .adv_w = 512, .box_w = 32, .box_h = 23, .ofs_x = 0, .ofs_y = 4},
|
||||
{.bitmap_index = 1758, .adv_w = 512, .box_w = 18, .box_h = 18, .ofs_x = 7, .ofs_y = 7},
|
||||
{.bitmap_index = 1839, .adv_w = 512, .box_w = 24, .box_h = 16, .ofs_x = 4, .ofs_y = 8},
|
||||
{.bitmap_index = 1935, .adv_w = 512, .box_w = 6, .box_h = 22, .ofs_x = 13, .ofs_y = 5},
|
||||
{.bitmap_index = 1968, .adv_w = 512, .box_w = 22, .box_h = 22, .ofs_x = 5, .ofs_y = 5},
|
||||
{.bitmap_index = 2089, .adv_w = 512, .box_w = 32, .box_h = 23, .ofs_x = 0, .ofs_y = 4},
|
||||
{.bitmap_index = 2273, .adv_w = 512, .box_w = 22, .box_h = 16, .ofs_x = 5, .ofs_y = 8},
|
||||
{.bitmap_index = 2361, .adv_w = 512, .box_w = 25, .box_h = 22, .ofs_x = 5, .ofs_y = 5},
|
||||
{.bitmap_index = 2499, .adv_w = 512, .box_w = 24, .box_h = 22, .ofs_x = 4, .ofs_y = 5},
|
||||
{.bitmap_index = 2631, .adv_w = 512, .box_w = 28, .box_h = 28, .ofs_x = 2, .ofs_y = 2},
|
||||
{.bitmap_index = 2827, .adv_w = 512, .box_w = 22, .box_h = 28, .ofs_x = 5, .ofs_y = 2},
|
||||
{.bitmap_index = 2981, .adv_w = 512, .box_w = 28, .box_h = 26, .ofs_x = 2, .ofs_y = 4},
|
||||
{.bitmap_index = 3163, .adv_w = 512, .box_w = 24, .box_h = 24, .ofs_x = 4, .ofs_y = 4},
|
||||
{.bitmap_index = 3307, .adv_w = 512, .box_w = 26, .box_h = 28, .ofs_x = 3, .ofs_y = 2},
|
||||
{.bitmap_index = 3489, .adv_w = 512, .box_w = 28, .box_h = 28, .ofs_x = 2, .ofs_y = 2},
|
||||
{.bitmap_index = 3685, .adv_w = 512, .box_w = 20, .box_h = 28, .ofs_x = 6, .ofs_y = 2},
|
||||
{.bitmap_index = 3825, .adv_w = 512, .box_w = 22, .box_h = 24, .ofs_x = 5, .ofs_y = 4},
|
||||
{.bitmap_index = 3957, .adv_w = 512, .box_w = 28, .box_h = 22, .ofs_x = 2, .ofs_y = 5},
|
||||
{.bitmap_index = 4111, .adv_w = 512, .box_w = 32, .box_h = 31, .ofs_x = 0, .ofs_y = 1},
|
||||
{.bitmap_index = 4359, .adv_w = 512, .box_w = 24, .box_h = 24, .ofs_x = 4, .ofs_y = 4},
|
||||
{.bitmap_index = 4503, .adv_w = 512, .box_w = 28, .box_h = 24, .ofs_x = 2, .ofs_y = 4},
|
||||
{.bitmap_index = 4671, .adv_w = 512, .box_w = 24, .box_h = 28, .ofs_x = 4, .ofs_y = 2},
|
||||
{.bitmap_index = 4839, .adv_w = 512, .box_w = 22, .box_h = 28, .ofs_x = 5, .ofs_y = 2},
|
||||
{.bitmap_index = 4993, .adv_w = 512, .box_w = 25, .box_h = 22, .ofs_x = 5, .ofs_y = 5},
|
||||
{.bitmap_index = 5131, .adv_w = 512, .box_w = 28, .box_h = 28, .ofs_x = 2, .ofs_y = 2},
|
||||
{.bitmap_index = 2631, .adv_w = 512, .box_w = 22, .box_h = 28, .ofs_x = 5, .ofs_y = 2},
|
||||
{.bitmap_index = 2785, .adv_w = 512, .box_w = 28, .box_h = 26, .ofs_x = 2, .ofs_y = 4},
|
||||
{.bitmap_index = 2967, .adv_w = 512, .box_w = 26, .box_h = 28, .ofs_x = 3, .ofs_y = 2},
|
||||
{.bitmap_index = 3149, .adv_w = 512, .box_w = 28, .box_h = 28, .ofs_x = 2, .ofs_y = 2},
|
||||
{.bitmap_index = 3345, .adv_w = 512, .box_w = 20, .box_h = 28, .ofs_x = 6, .ofs_y = 2},
|
||||
{.bitmap_index = 3485, .adv_w = 512, .box_w = 22, .box_h = 24, .ofs_x = 5, .ofs_y = 4},
|
||||
{.bitmap_index = 3617, .adv_w = 512, .box_w = 28, .box_h = 22, .ofs_x = 2, .ofs_y = 5},
|
||||
{.bitmap_index = 3771, .adv_w = 512, .box_w = 32, .box_h = 31, .ofs_x = 0, .ofs_y = 1},
|
||||
{.bitmap_index = 4019, .adv_w = 512, .box_w = 24, .box_h = 24, .ofs_x = 4, .ofs_y = 4},
|
||||
{.bitmap_index = 4163, .adv_w = 512, .box_w = 28, .box_h = 28, .ofs_x = 2, .ofs_y = 2},
|
||||
{.bitmap_index = 4359, .adv_w = 512, .box_w = 28, .box_h = 24, .ofs_x = 2, .ofs_y = 4},
|
||||
{.bitmap_index = 4527, .adv_w = 512, .box_w = 24, .box_h = 28, .ofs_x = 4, .ofs_y = 2},
|
||||
{.bitmap_index = 4695, .adv_w = 512, .box_w = 22, .box_h = 28, .ofs_x = 5, .ofs_y = 2},
|
||||
{.bitmap_index = 4849, .adv_w = 512, .box_w = 25, .box_h = 22, .ofs_x = 5, .ofs_y = 5},
|
||||
{.bitmap_index = 4987, .adv_w = 512, .box_w = 28, .box_h = 28, .ofs_x = 2, .ofs_y = 2},
|
||||
{.bitmap_index = 5183, .adv_w = 512, .box_w = 24, .box_h = 24, .ofs_x = 4, .ofs_y = 4},
|
||||
{.bitmap_index = 5327, .adv_w = 512, .box_w = 24, .box_h = 24, .ofs_x = 4, .ofs_y = 4},
|
||||
{.bitmap_index = 5471, .adv_w = 512, .box_w = 30, .box_h = 22, .ofs_x = 1, .ofs_y = 5},
|
||||
{.bitmap_index = 5636, .adv_w = 512, .box_w = 22, .box_h = 22, .ofs_x = 5, .ofs_y = 5},
|
||||
@ -972,10 +972,10 @@ static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = {
|
||||
|
||||
static const uint16_t unicode_list_0[] = {
|
||||
0x0, 0x14, 0x62, 0x9b, 0x148, 0x182, 0x1ca, 0x1d1,
|
||||
0x1e1, 0x2af, 0x2c0, 0x418, 0x47e, 0x485, 0x488, 0x48d,
|
||||
0x48f, 0x490, 0x4f9, 0x600, 0x62b, 0x74f, 0x757, 0x76a,
|
||||
0x771, 0x773, 0x7b8, 0x7ca, 0x7e9, 0x874, 0x8af, 0x8b2,
|
||||
0xa52, 0xa87, 0xad7, 0xdfb, 0xe05, 0xea1, 0xee3, 0xf4b,
|
||||
0x1e1, 0x2af, 0x2c0, 0x418, 0x47e, 0x488, 0x48d, 0x48f,
|
||||
0x490, 0x4f9, 0x523, 0x600, 0x62b, 0x757, 0x76a, 0x773,
|
||||
0x7b8, 0x7ca, 0x7e9, 0x874, 0x8af, 0x8b2, 0x8c2, 0xa52,
|
||||
0xa87, 0xad7, 0xdfb, 0xe05, 0xe35, 0xea1, 0xee3, 0xf4b,
|
||||
0x1017, 0x15db, 0x1782
|
||||
};
|
||||
|
||||
|
||||
@ -92,6 +92,7 @@ const struct ModuleSymbol lvgl_module_symbols[] = {
|
||||
DEFINE_MODULE_SYMBOL(lv_obj_clean),
|
||||
DEFINE_MODULE_SYMBOL(lv_obj_create),
|
||||
DEFINE_MODULE_SYMBOL(lv_obj_delete),
|
||||
DEFINE_MODULE_SYMBOL(lv_obj_delete_async),
|
||||
DEFINE_MODULE_SYMBOL(lv_obj_add_event_cb),
|
||||
DEFINE_MODULE_SYMBOL(lv_obj_add_flag),
|
||||
DEFINE_MODULE_SYMBOL(lv_obj_add_state),
|
||||
@ -155,6 +156,7 @@ const struct ModuleSymbol lvgl_module_symbols[] = {
|
||||
DEFINE_MODULE_SYMBOL(lv_obj_set_style_margin_left),
|
||||
DEFINE_MODULE_SYMBOL(lv_obj_set_style_margin_right),
|
||||
DEFINE_MODULE_SYMBOL(lv_obj_set_style_margin_all),
|
||||
DEFINE_MODULE_SYMBOL(lv_obj_set_style_min_width),
|
||||
DEFINE_MODULE_SYMBOL(lv_obj_set_style_pad_all),
|
||||
DEFINE_MODULE_SYMBOL(lv_obj_set_style_pad_hor),
|
||||
DEFINE_MODULE_SYMBOL(lv_obj_set_style_pad_ver),
|
||||
@ -216,6 +218,8 @@ const struct ModuleSymbol lvgl_module_symbols[] = {
|
||||
DEFINE_MODULE_SYMBOL(lv_obj_set_style_max_height),
|
||||
DEFINE_MODULE_SYMBOL(lv_obj_set_style_width),
|
||||
DEFINE_MODULE_SYMBOL(lv_obj_set_style_height),
|
||||
DEFINE_MODULE_SYMBOL(lv_obj_set_style_clip_corner),
|
||||
DEFINE_MODULE_SYMBOL(lv_obj_set_style_shadow_color),
|
||||
// lv_font
|
||||
DEFINE_MODULE_SYMBOL(lv_font_get_bitmap_fmt_txt),
|
||||
DEFINE_MODULE_SYMBOL(lv_font_get_default),
|
||||
|
||||
@ -8,7 +8,7 @@
|
||||
extern "C" {
|
||||
|
||||
error_t service_paths_get_user_data_directory(const char* service_id, char* out_path, size_t out_path_size) {
|
||||
char root[192];
|
||||
char root[FILE_MAX_PATH_STRING_LENGTH];
|
||||
error_t error = paths_get_data_path(root, sizeof(root));
|
||||
if (error != ERROR_NONE) {
|
||||
return error;
|
||||
@ -21,7 +21,7 @@ error_t service_paths_get_user_data_directory(const char* service_id, char* out_
|
||||
}
|
||||
|
||||
error_t service_paths_get_user_data_path(const char* service_id, const char* child_path, char* out_path, size_t out_path_size) {
|
||||
char directory[224];
|
||||
char directory[FILE_MAX_PATH_STRING_LENGTH];
|
||||
error_t error = service_paths_get_user_data_directory(service_id, directory, sizeof(directory));
|
||||
if (error != ERROR_NONE) {
|
||||
return error;
|
||||
@ -34,7 +34,7 @@ error_t service_paths_get_user_data_path(const char* service_id, const char* chi
|
||||
}
|
||||
|
||||
error_t service_paths_get_assets_directory(const char* service_id, char* out_path, size_t out_path_size) {
|
||||
char directory[224];
|
||||
char directory[FILE_MAX_PATH_STRING_LENGTH];
|
||||
error_t error = service_paths_get_user_data_directory(service_id, directory, sizeof(directory));
|
||||
if (error != ERROR_NONE) {
|
||||
return error;
|
||||
@ -47,7 +47,7 @@ error_t service_paths_get_assets_directory(const char* service_id, char* out_pat
|
||||
}
|
||||
|
||||
error_t service_paths_get_assets_path(const char* service_id, const char* child_path, char* out_path, size_t out_path_size) {
|
||||
char directory[224];
|
||||
char directory[FILE_MAX_PATH_STRING_LENGTH];
|
||||
error_t error = service_paths_get_assets_directory(service_id, directory, sizeof(directory));
|
||||
if (error != ERROR_NONE) {
|
||||
return error;
|
||||
|
||||
@ -8,7 +8,7 @@
|
||||
#include <string>
|
||||
|
||||
TEST_CASE("paths_get_data_path returns a non-empty path") {
|
||||
char buffer[192];
|
||||
char buffer[FILE_MAX_PATH_STRING_LENGTH];
|
||||
REQUIRE_EQ(paths_get_data_path(buffer, sizeof(buffer)), ERROR_NONE);
|
||||
CHECK_GT(std::strlen(buffer), 0);
|
||||
}
|
||||
@ -19,10 +19,10 @@ TEST_CASE("paths_get_data_path reports overflow for a too-small buffer") {
|
||||
}
|
||||
|
||||
TEST_CASE("service_paths_get_user_data_directory includes the service id") {
|
||||
char root[192];
|
||||
char root[FILE_MAX_PATH_STRING_LENGTH];
|
||||
REQUIRE_EQ(paths_get_data_path(root, sizeof(root)), ERROR_NONE);
|
||||
|
||||
char buffer[224];
|
||||
char buffer[FILE_MAX_PATH_STRING_LENGTH];
|
||||
CHECK_EQ(service_paths_get_user_data_directory("my-service", buffer, sizeof(buffer)), ERROR_NONE);
|
||||
|
||||
std::string expected = std::string(root) + "/service/my-service";
|
||||
@ -30,7 +30,7 @@ TEST_CASE("service_paths_get_user_data_directory includes the service id") {
|
||||
}
|
||||
|
||||
TEST_CASE("service_paths_get_user_data_path appends the child path") {
|
||||
char directory[224];
|
||||
char directory[FILE_MAX_PATH_STRING_LENGTH];
|
||||
REQUIRE_EQ(service_paths_get_user_data_directory("my-service", directory, sizeof(directory)), ERROR_NONE);
|
||||
|
||||
char buffer[256];
|
||||
@ -41,10 +41,10 @@ TEST_CASE("service_paths_get_user_data_path appends the child path") {
|
||||
}
|
||||
|
||||
TEST_CASE("service_paths_get_assets_directory is nested under the user data directory") {
|
||||
char directory[224];
|
||||
char directory[FILE_MAX_PATH_STRING_LENGTH];
|
||||
REQUIRE_EQ(service_paths_get_user_data_directory("my-service", directory, sizeof(directory)), ERROR_NONE);
|
||||
|
||||
char buffer[256];
|
||||
char buffer[FILE_MAX_PATH_STRING_LENGTH];
|
||||
CHECK_EQ(service_paths_get_assets_directory("my-service", buffer, sizeof(buffer)), ERROR_NONE);
|
||||
|
||||
std::string expected = std::string(directory) + "/assets";
|
||||
@ -52,10 +52,10 @@ TEST_CASE("service_paths_get_assets_directory is nested under the user data dire
|
||||
}
|
||||
|
||||
TEST_CASE("service_paths_get_assets_path appends the child path") {
|
||||
char directory[224];
|
||||
char directory[FILE_MAX_PATH_STRING_LENGTH];
|
||||
REQUIRE_EQ(service_paths_get_assets_directory("my-service", directory, sizeof(directory)), ERROR_NONE);
|
||||
|
||||
char buffer[256];
|
||||
char buffer[FILE_MAX_PATH_STRING_LENGTH];
|
||||
CHECK_EQ(service_paths_get_assets_path("my-service", "icon.png", buffer, sizeof(buffer)), ERROR_NONE);
|
||||
|
||||
std::string expected = std::string(directory) + "/icon.png";
|
||||
|
||||
@ -28,7 +28,10 @@ if (DEFINED ENV{ESP_IDF_VERSION})
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
idf_component_optional_requires(PRIVATE bt usb espressif__usb_host_hid espressif__usb_host_msc)
|
||||
idf_component_optional_requires(PRIVATE bt usb espressif__usb_host_hid espressif__usb_host_msc espressif__esp_audio_codec)
|
||||
if ("${IDF_TARGET}" STREQUAL "esp32s3" OR "${IDF_TARGET}" STREQUAL "esp32p4")
|
||||
idf_component_optional_requires(PRIVATE espressif__usb_host_uac)
|
||||
endif ()
|
||||
|
||||
if ("${IDF_TARGET}" STREQUAL "esp32p4")
|
||||
# Force-links esp32p4_libc_compat.c's __issignalingf() shim - nothing references it until
|
||||
|
||||
@ -0,0 +1,9 @@
|
||||
description: ESP32 USB Host UAC manager (installs the USB Audio Class client)
|
||||
|
||||
compatible: "espressif,esp32-usbhost-uac"
|
||||
|
||||
properties:
|
||||
_unused:
|
||||
type: int
|
||||
default: 0
|
||||
description: Placeholder required by the binding schema; this driver has no device-tree configuration.
|
||||
@ -12,6 +12,7 @@ DEFINE_DEVICETREE(esp32_usbhost, struct Esp32UsbHostConfig)
|
||||
DEFINE_DEVICETREE(esp32_usbhost_hid, struct Esp32UsbHostChildConfig)
|
||||
DEFINE_DEVICETREE(esp32_usbhost_midi, struct Esp32UsbHostChildConfig)
|
||||
DEFINE_DEVICETREE(esp32_usbhost_msc, struct Esp32UsbHostChildConfig)
|
||||
DEFINE_DEVICETREE(esp32_usbhost_uac, struct Esp32UsbHostChildConfig)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@ -15,7 +15,7 @@ void release_pin(GpioDescriptor** gpio_descriptor);
|
||||
* If the pin spec is invalid, the pointer is set to null.
|
||||
* @return true if the pin was acquired successfully
|
||||
*/
|
||||
bool acquire_pin_or_set_null(const GpioPinSpec& pin_spec, gpio_flags_t direction_flags, GpioDescriptor** gpio_descriptor);
|
||||
bool acquire_pin_or_set_null(const GpioPinSpec& pin_spec, gpio_flags_t direction_flags, GpioDescriptor** gpio_descriptor, GpioOwnerType owner = GPIO_OWNER_GPIO);
|
||||
|
||||
/**
|
||||
* Safely acquire the native pin value.
|
||||
|
||||
@ -9,13 +9,13 @@ void release_pin(GpioDescriptor** gpio_descriptor) {
|
||||
*gpio_descriptor = nullptr;
|
||||
}
|
||||
|
||||
bool acquire_pin_or_set_null(const GpioPinSpec& pin_spec, gpio_flags_t direction_flags, GpioDescriptor** gpio_descriptor) {
|
||||
bool acquire_pin_or_set_null(const GpioPinSpec& pin_spec, gpio_flags_t direction_flags, GpioDescriptor** gpio_descriptor, GpioOwnerType owner) {
|
||||
if (pin_spec.gpio_controller == nullptr) {
|
||||
*gpio_descriptor = nullptr;
|
||||
return true;
|
||||
}
|
||||
|
||||
*gpio_descriptor = gpio_descriptor_acquire(pin_spec.gpio_controller, pin_spec.pin, pin_spec.flags | direction_flags, GPIO_OWNER_GPIO);
|
||||
*gpio_descriptor = gpio_descriptor_acquire(pin_spec.gpio_controller, pin_spec.pin, pin_spec.flags | direction_flags, owner);
|
||||
if (*gpio_descriptor == nullptr) {
|
||||
LOG_E(TAG, "Failed to acquire pin %u from %s", pin_spec.pin, pin_spec.gpio_controller->name);
|
||||
}
|
||||
|
||||
@ -153,14 +153,14 @@ static error_t start(Device* device) {
|
||||
auto dts_config = GET_CONFIG(device);
|
||||
|
||||
auto& sda_spec = dts_config->pinSda;
|
||||
auto* sda_descriptor = gpio_descriptor_acquire(sda_spec.gpio_controller, sda_spec.pin, sda_spec.flags | GPIO_FLAG_DIRECTION_INPUT_OUTPUT, GPIO_OWNER_GPIO);
|
||||
auto* sda_descriptor = gpio_descriptor_acquire(sda_spec.gpio_controller, sda_spec.pin, sda_spec.flags | GPIO_FLAG_DIRECTION_INPUT_OUTPUT, GPIO_OWNER_PERIPHERAL);
|
||||
if (!sda_descriptor) {
|
||||
LOG_E(TAG, "Failed to acquire pin %u", sda_spec.pin);
|
||||
return ERROR_RESOURCE;
|
||||
}
|
||||
|
||||
auto& scl_spec = dts_config->pinScl;
|
||||
auto* scl_descriptor = gpio_descriptor_acquire(scl_spec.gpio_controller, scl_spec.pin, scl_spec.flags | GPIO_FLAG_DIRECTION_OUTPUT, GPIO_OWNER_GPIO);
|
||||
auto* scl_descriptor = gpio_descriptor_acquire(scl_spec.gpio_controller, scl_spec.pin, scl_spec.flags | GPIO_FLAG_DIRECTION_OUTPUT, GPIO_OWNER_PERIPHERAL);
|
||||
if (!scl_descriptor) {
|
||||
LOG_E(TAG, "Failed to acquire pin %u", scl_spec.pin);
|
||||
gpio_descriptor_release(sda_descriptor);
|
||||
|
||||
@ -65,11 +65,11 @@ struct Esp32I2sInternal {
|
||||
auto& data_out_spec = dts_config->pin_data_out;
|
||||
auto& mclk_spec = dts_config->pin_mclk;
|
||||
|
||||
bool success = acquire_pin_or_set_null(ws_spec, GPIO_FLAG_DIRECTION_OUTPUT, &ws_descriptor) &&
|
||||
acquire_pin_or_set_null(bclk_spec, GPIO_FLAG_DIRECTION_OUTPUT, &bclk_descriptor) &&
|
||||
acquire_pin_or_set_null(data_in_spec, GPIO_FLAG_DIRECTION_INPUT, &data_in_descriptor) &&
|
||||
acquire_pin_or_set_null(data_out_spec, GPIO_FLAG_DIRECTION_OUTPUT, &data_out_descriptor) &&
|
||||
acquire_pin_or_set_null(mclk_spec, GPIO_FLAG_DIRECTION_OUTPUT, &mclk_descriptor);
|
||||
bool success = acquire_pin_or_set_null(ws_spec, GPIO_FLAG_DIRECTION_OUTPUT, &ws_descriptor, GPIO_OWNER_PERIPHERAL) &&
|
||||
acquire_pin_or_set_null(bclk_spec, GPIO_FLAG_DIRECTION_OUTPUT, &bclk_descriptor, GPIO_OWNER_PERIPHERAL) &&
|
||||
acquire_pin_or_set_null(data_in_spec, GPIO_FLAG_DIRECTION_INPUT, &data_in_descriptor, GPIO_OWNER_PERIPHERAL) &&
|
||||
acquire_pin_or_set_null(data_out_spec, GPIO_FLAG_DIRECTION_OUTPUT, &data_out_descriptor, GPIO_OWNER_PERIPHERAL) &&
|
||||
acquire_pin_or_set_null(mclk_spec, GPIO_FLAG_DIRECTION_OUTPUT, &mclk_descriptor, GPIO_OWNER_PERIPHERAL);
|
||||
|
||||
if (!success) {
|
||||
cleanup_pins();
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user