mirror of
https://github.com/daveallie/crosspoint-reader.git
synced 2026-02-06 23:57:39 +03:00
Compare commits
No commits in common. "941643cf97fb1934af3e1f150081158388ba2de0" and "e43fec79bed98f214cda8c91340bb6c9b383de90" have entirely different histories.
941643cf97
...
e43fec79be
@ -2,7 +2,8 @@
|
||||
|
||||
#include <Utf8.h>
|
||||
|
||||
#include <algorithm>
|
||||
inline int min(const int a, const int b) { return a < b ? a : b; }
|
||||
inline int max(const int a, const int b) { return a < b ? b : a; }
|
||||
|
||||
void EpdFont::getTextBounds(const char* string, const int startX, const int startY, int* minX, int* minY, int* maxX,
|
||||
int* maxY) const {
|
||||
@ -31,10 +32,10 @@ void EpdFont::getTextBounds(const char* string, const int startX, const int star
|
||||
continue;
|
||||
}
|
||||
|
||||
*minX = std::min(*minX, cursorX + glyph->left);
|
||||
*maxX = std::max(*maxX, cursorX + glyph->left + glyph->width);
|
||||
*minY = std::min(*minY, cursorY + glyph->top - glyph->height);
|
||||
*maxY = std::max(*maxY, cursorY + glyph->top);
|
||||
*minX = min(*minX, cursorX + glyph->left);
|
||||
*maxX = max(*maxX, cursorX + glyph->left + glyph->width);
|
||||
*minY = min(*minY, cursorY + glyph->top - glyph->height);
|
||||
*maxY = max(*maxY, cursorY + glyph->top);
|
||||
cursorX += glyph->advanceX;
|
||||
}
|
||||
}
|
||||
|
||||
1954
lib/EpdFont/builtinFonts/aleo_12_bold.h
Normal file
1954
lib/EpdFont/builtinFonts/aleo_12_bold.h
Normal file
File diff suppressed because it is too large
Load Diff
2043
lib/EpdFont/builtinFonts/aleo_12_bolditalic.h
Normal file
2043
lib/EpdFont/builtinFonts/aleo_12_bolditalic.h
Normal file
File diff suppressed because it is too large
Load Diff
1916
lib/EpdFont/builtinFonts/aleo_12_italic.h
Normal file
1916
lib/EpdFont/builtinFonts/aleo_12_italic.h
Normal file
File diff suppressed because it is too large
Load Diff
1854
lib/EpdFont/builtinFonts/aleo_12_regular.h
Normal file
1854
lib/EpdFont/builtinFonts/aleo_12_regular.h
Normal file
File diff suppressed because it is too large
Load Diff
2481
lib/EpdFont/builtinFonts/aleo_14_bold.h
Normal file
2481
lib/EpdFont/builtinFonts/aleo_14_bold.h
Normal file
File diff suppressed because it is too large
Load Diff
2583
lib/EpdFont/builtinFonts/aleo_14_bolditalic.h
Normal file
2583
lib/EpdFont/builtinFonts/aleo_14_bolditalic.h
Normal file
File diff suppressed because it is too large
Load Diff
2424
lib/EpdFont/builtinFonts/aleo_14_italic.h
Normal file
2424
lib/EpdFont/builtinFonts/aleo_14_italic.h
Normal file
File diff suppressed because it is too large
Load Diff
2348
lib/EpdFont/builtinFonts/aleo_14_regular.h
Normal file
2348
lib/EpdFont/builtinFonts/aleo_14_regular.h
Normal file
File diff suppressed because it is too large
Load Diff
3070
lib/EpdFont/builtinFonts/aleo_16_bold.h
Normal file
3070
lib/EpdFont/builtinFonts/aleo_16_bold.h
Normal file
File diff suppressed because it is too large
Load Diff
3206
lib/EpdFont/builtinFonts/aleo_16_bolditalic.h
Normal file
3206
lib/EpdFont/builtinFonts/aleo_16_bolditalic.h
Normal file
File diff suppressed because it is too large
Load Diff
2992
lib/EpdFont/builtinFonts/aleo_16_italic.h
Normal file
2992
lib/EpdFont/builtinFonts/aleo_16_italic.h
Normal file
File diff suppressed because it is too large
Load Diff
2862
lib/EpdFont/builtinFonts/aleo_16_regular.h
Normal file
2862
lib/EpdFont/builtinFonts/aleo_16_regular.h
Normal file
File diff suppressed because it is too large
Load Diff
3721
lib/EpdFont/builtinFonts/aleo_18_bold.h
Normal file
3721
lib/EpdFont/builtinFonts/aleo_18_bold.h
Normal file
File diff suppressed because it is too large
Load Diff
3912
lib/EpdFont/builtinFonts/aleo_18_bolditalic.h
Normal file
3912
lib/EpdFont/builtinFonts/aleo_18_bolditalic.h
Normal file
File diff suppressed because it is too large
Load Diff
3647
lib/EpdFont/builtinFonts/aleo_18_italic.h
Normal file
3647
lib/EpdFont/builtinFonts/aleo_18_italic.h
Normal file
File diff suppressed because it is too large
Load Diff
3481
lib/EpdFont/builtinFonts/aleo_18_regular.h
Normal file
3481
lib/EpdFont/builtinFonts/aleo_18_regular.h
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,22 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include <builtinFonts/bookerly_12_bold.h>
|
||||
#include <builtinFonts/bookerly_12_bolditalic.h>
|
||||
#include <builtinFonts/bookerly_12_italic.h>
|
||||
#include <builtinFonts/bookerly_12_regular.h>
|
||||
#include <builtinFonts/bookerly_14_bold.h>
|
||||
#include <builtinFonts/bookerly_14_bolditalic.h>
|
||||
#include <builtinFonts/bookerly_14_italic.h>
|
||||
#include <builtinFonts/bookerly_14_regular.h>
|
||||
#include <builtinFonts/bookerly_16_bold.h>
|
||||
#include <builtinFonts/bookerly_16_bolditalic.h>
|
||||
#include <builtinFonts/bookerly_16_italic.h>
|
||||
#include <builtinFonts/bookerly_16_regular.h>
|
||||
#include <builtinFonts/bookerly_18_bold.h>
|
||||
#include <builtinFonts/bookerly_18_bolditalic.h>
|
||||
#include <builtinFonts/bookerly_18_italic.h>
|
||||
#include <builtinFonts/bookerly_18_regular.h>
|
||||
#include <builtinFonts/notosans_8_regular.h>
|
||||
#include <builtinFonts/aleo_12_bold.h>
|
||||
#include <builtinFonts/aleo_12_bolditalic.h>
|
||||
#include <builtinFonts/aleo_12_italic.h>
|
||||
#include <builtinFonts/aleo_12_regular.h>
|
||||
#include <builtinFonts/aleo_14_bold.h>
|
||||
#include <builtinFonts/aleo_14_bolditalic.h>
|
||||
#include <builtinFonts/aleo_14_italic.h>
|
||||
#include <builtinFonts/aleo_14_regular.h>
|
||||
#include <builtinFonts/aleo_16_bold.h>
|
||||
#include <builtinFonts/aleo_16_bolditalic.h>
|
||||
#include <builtinFonts/aleo_16_italic.h>
|
||||
#include <builtinFonts/aleo_16_regular.h>
|
||||
#include <builtinFonts/aleo_18_bold.h>
|
||||
#include <builtinFonts/aleo_18_bolditalic.h>
|
||||
#include <builtinFonts/aleo_18_italic.h>
|
||||
#include <builtinFonts/aleo_18_regular.h>
|
||||
#include <builtinFonts/notosans_12_bold.h>
|
||||
#include <builtinFonts/notosans_12_bolditalic.h>
|
||||
#include <builtinFonts/notosans_12_italic.h>
|
||||
@ -49,6 +48,7 @@
|
||||
#include <builtinFonts/opendyslexic_8_bolditalic.h>
|
||||
#include <builtinFonts/opendyslexic_8_italic.h>
|
||||
#include <builtinFonts/opendyslexic_8_regular.h>
|
||||
#include <builtinFonts/spacegrotesk.h>
|
||||
#include <builtinFonts/ubuntu_10_bold.h>
|
||||
#include <builtinFonts/ubuntu_10_regular.h>
|
||||
#include <builtinFonts/ubuntu_12_bold.h>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
BIN
lib/EpdFont/builtinFonts/source/Aleo/Aleo-Bold.ttf
Normal file
BIN
lib/EpdFont/builtinFonts/source/Aleo/Aleo-Bold.ttf
Normal file
Binary file not shown.
BIN
lib/EpdFont/builtinFonts/source/Aleo/Aleo-BoldItalic.ttf
Normal file
BIN
lib/EpdFont/builtinFonts/source/Aleo/Aleo-BoldItalic.ttf
Normal file
Binary file not shown.
BIN
lib/EpdFont/builtinFonts/source/Aleo/Aleo-Italic.ttf
Normal file
BIN
lib/EpdFont/builtinFonts/source/Aleo/Aleo-Italic.ttf
Normal file
Binary file not shown.
BIN
lib/EpdFont/builtinFonts/source/Aleo/Aleo-Regular.ttf
Normal file
BIN
lib/EpdFont/builtinFonts/source/Aleo/Aleo-Regular.ttf
Normal file
Binary file not shown.
93
lib/EpdFont/builtinFonts/source/Aleo/OFL.txt
Normal file
93
lib/EpdFont/builtinFonts/source/Aleo/OFL.txt
Normal file
@ -0,0 +1,93 @@
|
||||
Copyright 2018 The Aleo Project Authors (https://github.com/AlessioLaiso/aleo)
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
https://openfontlicense.org
|
||||
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
93
lib/EpdFont/builtinFonts/source/SpaceGrotesk/OFL.txt
Normal file
93
lib/EpdFont/builtinFonts/source/SpaceGrotesk/OFL.txt
Normal file
@ -0,0 +1,93 @@
|
||||
Copyright 2020 The Space Grotesk Project Authors (https://github.com/floriankarsten/space-grotesk)
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
https://openfontlicense.org
|
||||
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||
Binary file not shown.
826
lib/EpdFont/builtinFonts/spacegrotesk.h
Normal file
826
lib/EpdFont/builtinFonts/spacegrotesk.h
Normal file
@ -0,0 +1,826 @@
|
||||
/**
|
||||
* generated by fontconvert.py
|
||||
* name: spacegrotesk
|
||||
* size: 8
|
||||
* mode: 1-bit
|
||||
*/
|
||||
#pragma once
|
||||
#include "EpdFontData.h"
|
||||
|
||||
static const uint8_t spacegroteskBitmaps[5331] = {
|
||||
0x66, 0x66, 0x66, 0x66, 0x60, 0x67, 0x20, 0x00, 0xF9, 0xF1, 0xA6, 0xC0, 0x00, 0x33, 0x0C, 0xC3,
|
||||
0x31, 0xFF, 0xFF, 0xCC, 0xC3, 0x33, 0xFF, 0xFF, 0xCC, 0xC3, 0x30, 0xCC, 0x0C, 0x03, 0x03, 0xF1,
|
||||
0xFE, 0x6D, 0x9B, 0x77, 0xC8, 0xF8, 0x1F, 0x93, 0x7E, 0xCD, 0xB3, 0x7F, 0x8F, 0xE0, 0xC0, 0x30,
|
||||
0x78, 0x37, 0xE3, 0x33, 0x39, 0x9B, 0x87, 0xD8, 0x1D, 0x80, 0x19, 0x01, 0xFE, 0x1D, 0xB8, 0xCC,
|
||||
0xCC, 0x66, 0xC3, 0xE0, 0x04, 0x00, 0x3E, 0x1F, 0x86, 0x03, 0x84, 0x63, 0x1F, 0xF7, 0xFD, 0x8C,
|
||||
0xC3, 0x38, 0xC7, 0xF0, 0xFC, 0x06, 0x73, 0x60, 0x19, 0xEE, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0C,
|
||||
0x30, 0xC3, 0x0E, 0x1E, 0x3C, 0xC3, 0xC3, 0x86, 0x1C, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x61,
|
||||
0xBC, 0xE0, 0x08, 0x6A, 0x3E, 0xFF, 0x7F, 0x3E, 0x6A, 0x08, 0x18, 0x18, 0x18, 0xFF, 0xFF, 0x18,
|
||||
0x18, 0x18, 0x06, 0x73, 0x60, 0xFF, 0xE0, 0x06, 0x72, 0x0C, 0x18, 0x30, 0xE1, 0x83, 0x06, 0x18,
|
||||
0x30, 0x61, 0x83, 0x06, 0x18, 0x30, 0x40, 0x3E, 0x3F, 0xB0, 0xF8, 0x3C, 0x1E, 0x0F, 0x07, 0x83,
|
||||
0xC1, 0xE0, 0xF9, 0xCF, 0xE1, 0x80, 0x1C, 0xF7, 0xDB, 0xEF, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x3F,
|
||||
0x1F, 0xE6, 0x19, 0x87, 0x41, 0xC0, 0x60, 0xF8, 0xF8, 0x70, 0x18, 0x07, 0xF9, 0xFF, 0x7F, 0x9F,
|
||||
0xF0, 0x38, 0x3C, 0x1C, 0x07, 0xC1, 0xF8, 0x06, 0xC1, 0xD8, 0x67, 0x38, 0xFC, 0x0C, 0x00, 0x07,
|
||||
0x03, 0xC0, 0xF0, 0x6C, 0x3B, 0x0C, 0xC6, 0x33, 0x8C, 0xFF, 0xFF, 0xF0, 0x30, 0x0C, 0x7F, 0x9F,
|
||||
0xE6, 0x01, 0x80, 0x7F, 0x1F, 0xE7, 0x18, 0x07, 0x61, 0xD8, 0x67, 0x38, 0xFC, 0x0C, 0x00, 0x7E,
|
||||
0x7F, 0xB0, 0xD8, 0x3F, 0xE7, 0xFB, 0x0D, 0x83, 0xC1, 0xE1, 0xF9, 0xCF, 0xC1, 0x80, 0xFF, 0xFF,
|
||||
0xC0, 0x60, 0x60, 0x30, 0x30, 0x38, 0x18, 0x1C, 0x0C, 0x0E, 0x06, 0x00, 0x3F, 0x1F, 0xE6, 0x1D,
|
||||
0x83, 0x61, 0xCF, 0xE7, 0xF9, 0x87, 0xE0, 0xF8, 0x37, 0x3C, 0xFE, 0x0C, 0x00, 0x3F, 0x1F, 0xE6,
|
||||
0x19, 0x87, 0xE1, 0xD8, 0x77, 0xFC, 0xFF, 0x41, 0xD8, 0x67, 0x38, 0xFC, 0x0C, 0x00, 0x06, 0x72,
|
||||
0x00, 0x06, 0x72, 0x06, 0x72, 0x00, 0x06, 0x73, 0x60, 0x01, 0x0F, 0x3E, 0xF0, 0xF0, 0x7C, 0x1F,
|
||||
0x03, 0xFF, 0xFF, 0x7F, 0xFF, 0x00, 0xC0, 0xF0, 0x7E, 0x0F, 0x07, 0x3E, 0xF8, 0xC0, 0x3F, 0x3F,
|
||||
0xD8, 0x78, 0x34, 0x18, 0x3C, 0x3C, 0x18, 0x0C, 0x00, 0x07, 0x03, 0x80, 0x80, 0x0F, 0xE0, 0x3F,
|
||||
0xF0, 0xE0, 0x73, 0x18, 0x6E, 0x7F, 0x79, 0xDE, 0xF3, 0x1D, 0xEE, 0x1B, 0xDC, 0x37, 0x98, 0xEF,
|
||||
0x3B, 0xFB, 0x3F, 0xE7, 0x10, 0x07, 0x80, 0x07, 0xFC, 0x01, 0xF0, 0x0E, 0x03, 0xC0, 0x7C, 0x0D,
|
||||
0x83, 0xB0, 0x66, 0x0C, 0x63, 0xFC, 0x7F, 0x8C, 0x39, 0x83, 0x60, 0x60, 0xFF, 0x9F, 0xF8, 0xC3,
|
||||
0x18, 0x63, 0x0C, 0x7F, 0x8F, 0xE1, 0x86, 0x30, 0xC6, 0x19, 0xFF, 0x7F, 0xC0, 0x3E, 0x3F, 0xB8,
|
||||
0x78, 0x3C, 0x1E, 0x03, 0x01, 0x83, 0xC1, 0xE0, 0xFD, 0xEF, 0xE1, 0xC0, 0xFF, 0x1F, 0xF0, 0xC7,
|
||||
0x18, 0x63, 0x0E, 0x61, 0xCC, 0x39, 0x87, 0x30, 0xC6, 0x19, 0xFF, 0x7F, 0xC0, 0xFF, 0xFF, 0xC0,
|
||||
0xC0, 0xC0, 0xFE, 0xFE, 0xC0, 0xC0, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0xC0, 0xC0, 0xFE, 0xFE,
|
||||
0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x3E, 0x3F, 0xB8, 0x78, 0x3C, 0x1E, 0x03, 0x3F, 0x9F, 0xC1, 0xE0,
|
||||
0xFD, 0xEF, 0xF1, 0x80, 0xC1, 0xE0, 0xF0, 0x78, 0x3C, 0x1F, 0xFF, 0xFF, 0x83, 0xC1, 0xE0, 0xF0,
|
||||
0x78, 0x30, 0xFF, 0xFF, 0xFF, 0x0F, 0x83, 0xE0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x33, 0x0C, 0xC3,
|
||||
0x38, 0xC7, 0x71, 0xF8, 0x18, 0x00, 0xC3, 0xE3, 0xB3, 0x9B, 0x8F, 0x87, 0x83, 0xC1, 0xF0, 0xDC,
|
||||
0x67, 0x31, 0xD8, 0x70, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xFF, 0xFF,
|
||||
0xE0, 0x77, 0x83, 0xBC, 0x3D, 0xE1, 0xEF, 0x8F, 0x6C, 0x7B, 0x66, 0xDB, 0x36, 0xCD, 0xB6, 0x7D,
|
||||
0xB3, 0xCD, 0x9E, 0x60, 0xE1, 0xF8, 0xFC, 0x7F, 0x3D, 0x9E, 0xCF, 0x37, 0x9B, 0xCF, 0xE3, 0xF1,
|
||||
0xF8, 0xF0, 0x3E, 0x1F, 0xEE, 0x1B, 0x06, 0xC1, 0xF0, 0x7C, 0x1F, 0x07, 0xC1, 0xB0, 0x6F, 0x79,
|
||||
0xFC, 0x1C, 0x00, 0xFE, 0x7F, 0xB0, 0xF8, 0x3C, 0x1E, 0x1B, 0xFD, 0xF8, 0xC0, 0x60, 0x30, 0x18,
|
||||
0x00, 0x3E, 0x1F, 0xEE, 0x1B, 0x06, 0xC1, 0xF0, 0x7C, 0x1F, 0x07, 0xC1, 0xB0, 0x6F, 0x79, 0xFC,
|
||||
0x1C, 0x03, 0x80, 0xE0, 0xFE, 0x7F, 0xB0, 0x78, 0x3C, 0x1E, 0x1F, 0xFD, 0xFF, 0xC3, 0xE1, 0xF0,
|
||||
0xF8, 0x70, 0x3F, 0x1F, 0xE6, 0x19, 0x87, 0x70, 0x8F, 0x81, 0xF9, 0x07, 0xE0, 0xD8, 0x37, 0x38,
|
||||
0xFE, 0x0C, 0x00, 0xFF, 0xFF, 0xF0, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x00,
|
||||
0xC0, 0x30, 0xC1, 0xE0, 0xF0, 0x78, 0x3C, 0x1E, 0x0F, 0x07, 0x83, 0xC1, 0xE0, 0xFD, 0xEF, 0xE1,
|
||||
0xC0, 0xC0, 0xF8, 0x36, 0x1D, 0x86, 0x61, 0x8C, 0x63, 0x30, 0xCC, 0x1B, 0x07, 0xC1, 0xE0, 0x78,
|
||||
0xC3, 0x8F, 0x9E, 0x36, 0x78, 0xD9, 0xB3, 0x66, 0xCD, 0x9B, 0x76, 0xED, 0x9B, 0x36, 0x3C, 0xF8,
|
||||
0xF1, 0xE3, 0xC7, 0x8F, 0x1E, 0xE0, 0xCC, 0x38, 0xC6, 0x1D, 0x81, 0xF0, 0x3C, 0x03, 0x80, 0xF8,
|
||||
0x3B, 0x06, 0x31, 0xC7, 0x70, 0x60, 0xC0, 0xF8, 0x76, 0x18, 0xCE, 0x3B, 0x07, 0x81, 0xE0, 0x30,
|
||||
0x0C, 0x03, 0x00, 0xC0, 0x30, 0x7F, 0xBF, 0xC0, 0xE0, 0x60, 0x60, 0x70, 0x70, 0x70, 0x30, 0x30,
|
||||
0x3F, 0xFF, 0xF0, 0x77, 0xF1, 0x8C, 0x63, 0x18, 0xC6, 0x31, 0x8C, 0x63, 0x1E, 0xF8, 0x60, 0x60,
|
||||
0x60, 0x30, 0x30, 0x30, 0x18, 0x18, 0x18, 0x0C, 0x0C, 0x0C, 0x06, 0x06, 0x06, 0x02, 0xF7, 0xC6,
|
||||
0x31, 0x8C, 0x63, 0x18, 0xC6, 0x31, 0x8C, 0x7F, 0xF0, 0x1C, 0x1E, 0x1D, 0x8C, 0xEC, 0x30, 0xFF,
|
||||
0x7F, 0x80, 0x00, 0x67, 0x30, 0x1C, 0x0F, 0xC6, 0x31, 0x8C, 0x3F, 0x1F, 0xCE, 0x31, 0x9E, 0x7F,
|
||||
0xC6, 0x00, 0xC0, 0x60, 0x30, 0x1B, 0x8F, 0xF7, 0x1F, 0x07, 0x83, 0xC1, 0xE0, 0xFC, 0xFF, 0xE0,
|
||||
0xC0, 0x0E, 0x0F, 0xC7, 0x39, 0x86, 0x60, 0x18, 0x06, 0x19, 0xCE, 0x3F, 0x03, 0x00, 0x00, 0xC0,
|
||||
0x30, 0x0C, 0x73, 0x3F, 0xDC, 0x76, 0x1D, 0x83, 0x60, 0xD8, 0x77, 0x3C, 0xFF, 0x0C, 0x00, 0x0E,
|
||||
0x1F, 0x9C, 0xEC, 0x37, 0xFB, 0xFD, 0x86, 0xE7, 0x3F, 0x06, 0x00, 0x1E, 0x3C, 0x63, 0xFF, 0xE3,
|
||||
0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0x1C, 0x8F, 0xF7, 0x1D, 0x87, 0x60, 0xD8, 0x36, 0x1D, 0xEF,
|
||||
0x3F, 0xC0, 0x30, 0x0C, 0xFF, 0x3F, 0x80, 0xC0, 0xC0, 0xC0, 0xDC, 0xFE, 0xE3, 0xC3, 0xC3, 0xC3,
|
||||
0xC3, 0xC3, 0xC3, 0xDB, 0x0D, 0xB6, 0xDB, 0x60, 0x31, 0x8C, 0x03, 0x18, 0xC6, 0x31, 0x8C, 0x63,
|
||||
0x1B, 0xCC, 0xC0, 0xC0, 0xC0, 0xC2, 0xCE, 0xDC, 0xF8, 0xF0, 0xF0, 0xD8, 0xCE, 0xC7, 0xFF, 0xFF,
|
||||
0xFF, 0x18, 0xC7, 0xFF, 0xB9, 0xCD, 0x8C, 0x6C, 0x63, 0x63, 0x1B, 0x18, 0xD8, 0xC6, 0xC6, 0x30,
|
||||
0x1C, 0xFE, 0xE3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x0E, 0x0F, 0xC7, 0x39, 0x87, 0x60, 0xD8,
|
||||
0x36, 0x19, 0xCE, 0x3F, 0x03, 0x00, 0x1C, 0x7F, 0xB8, 0xF8, 0x3C, 0x1E, 0x0F, 0x07, 0xE7, 0xFF,
|
||||
0x66, 0x30, 0x18, 0x0C, 0x00, 0x1C, 0x8F, 0xF7, 0x1D, 0x87, 0x60, 0xD8, 0x36, 0x1D, 0xCF, 0x3F,
|
||||
0xC3, 0x30, 0x0C, 0x03, 0x00, 0x80, 0x1F, 0xF9, 0x8C, 0x63, 0x18, 0xC0, 0x1C, 0x7E, 0x63, 0x62,
|
||||
0x7E, 0x1F, 0x63, 0x63, 0x3F, 0x0C, 0x00, 0x30, 0x63, 0xFF, 0xE3, 0x06, 0x0C, 0x18, 0x30, 0x70,
|
||||
0xF0, 0x01, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xE7, 0x7F, 0x10, 0x41, 0x71, 0xD8, 0xCC, 0x67,
|
||||
0x71, 0xB0, 0xD8, 0x38, 0x1C, 0x00, 0x42, 0x13, 0x38, 0xD9, 0xEE, 0xCF, 0x66, 0xDB, 0x36, 0xD8,
|
||||
0xF3, 0xC7, 0x9E, 0x38, 0xE0, 0x40, 0x98, 0x63, 0x30, 0xF8, 0x1E, 0x07, 0x83, 0xF1, 0xCC, 0x61,
|
||||
0x80, 0x01, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xE7, 0x7F, 0x13, 0x03, 0x7F, 0x7E, 0xFD, 0xFC,
|
||||
0x38, 0xE3, 0x8E, 0x38, 0x7E, 0xFE, 0x1E, 0x3C, 0x60, 0xC1, 0x83, 0x06, 0x0C, 0xF1, 0xE0, 0x60,
|
||||
0xC1, 0x83, 0x06, 0x0F, 0x1E, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xF1, 0xF0, 0x60, 0xC1, 0x83, 0x06,
|
||||
0x0C, 0x1E, 0x3C, 0x60, 0xC1, 0x83, 0x06, 0x7C, 0xF0, 0x10, 0x7B, 0xFF, 0x4C, 0x67, 0x60, 0x66,
|
||||
0x66, 0x66, 0x66, 0x60, 0x08, 0x0C, 0x07, 0x0F, 0xCF, 0xF6, 0xDB, 0x61, 0xB0, 0xDB, 0x7F, 0x9F,
|
||||
0x83, 0x01, 0x80, 0x1F, 0x0F, 0xE3, 0x1C, 0xC3, 0x30, 0xDF, 0x07, 0xC0, 0xC0, 0x30, 0x0C, 0x07,
|
||||
0xF9, 0xFF, 0x00, 0x1F, 0xF7, 0xF9, 0x86, 0x60, 0xD8, 0x36, 0x19, 0xCE, 0x7F, 0xD3, 0x20, 0xC0,
|
||||
0xCC, 0x39, 0xC6, 0x19, 0xC3, 0xB0, 0x3C, 0x1F, 0xE1, 0xFC, 0x7F, 0x87, 0xF0, 0x30, 0x06, 0x00,
|
||||
0xFF, 0xFF, 0x0F, 0xFF, 0xF0, 0x3E, 0x7E, 0x63, 0x62, 0x7C, 0x7E, 0x7B, 0x3F, 0x47, 0xC3, 0x67,
|
||||
0x7E, 0x18, 0x6C, 0xD9, 0xB0, 0x3F, 0x1F, 0xEC, 0xDF, 0x7B, 0xF3, 0xFC, 0xBF, 0x0F, 0xCF, 0xFE,
|
||||
0xF7, 0xB6, 0x39, 0xFC, 0x0C, 0x00, 0x78, 0xD8, 0xF3, 0xEC, 0xCF, 0xCC, 0x00, 0x0C, 0x63, 0xBD,
|
||||
0xEE, 0x73, 0x87, 0x70, 0x77, 0x87, 0x38, 0x23, 0xFF, 0xFF, 0x03, 0x03, 0xFF, 0xE0, 0x3E, 0x7F,
|
||||
0x5D, 0x5D, 0x55, 0x77, 0x3E, 0x00, 0x7C, 0xF8, 0x7B, 0xFC, 0xF3, 0x78, 0x40, 0x08, 0x18, 0x18,
|
||||
0xFF, 0xFF, 0x18, 0x18, 0x18, 0x7F, 0xFF, 0x01, 0xEC, 0xC3, 0x7B, 0x8F, 0xC0, 0xFC, 0x73, 0x8F,
|
||||
0xCD, 0xF3, 0x00, 0x36, 0x60, 0x00, 0x61, 0xB0, 0xD8, 0x6C, 0x36, 0x1B, 0x0D, 0xCE, 0xFF, 0xE8,
|
||||
0x30, 0x18, 0x0C, 0x00, 0x3F, 0xBF, 0xF3, 0x79, 0xBC, 0xDB, 0xED, 0xF6, 0x1B, 0x0D, 0x86, 0xC3,
|
||||
0x61, 0xB0, 0x1F, 0xA0, 0x21, 0x8E, 0xF7, 0x00, 0x77, 0xF3, 0x33, 0x3C, 0xFF, 0x1E, 0x3C, 0x6F,
|
||||
0x8E, 0x00, 0xCC, 0x3B, 0xC7, 0xB8, 0x67, 0x39, 0xDD, 0xEE, 0xE2, 0x30, 0x70, 0x21, 0xC1, 0x8F,
|
||||
0x0C, 0x0C, 0x60, 0x33, 0x80, 0xCC, 0x00, 0x67, 0x03, 0x1C, 0x18, 0xD0, 0xE7, 0xE3, 0x1F, 0xD8,
|
||||
0x04, 0x00, 0x00, 0x70, 0x21, 0xC1, 0x8F, 0x0C, 0x0C, 0x60, 0x33, 0x80, 0xCC, 0x00, 0x6F, 0x83,
|
||||
0x33, 0x18, 0x18, 0xE1, 0xE3, 0x0C, 0x18, 0x3F, 0x00, 0x00, 0xFC, 0x18, 0x38, 0x60, 0xE1, 0xC1,
|
||||
0xE3, 0x0C, 0xCC, 0x0F, 0xB0, 0x0C, 0xC7, 0x03, 0x9E, 0x0E, 0x6C, 0x19, 0xFC, 0x63, 0xF9, 0x80,
|
||||
0x60, 0x00, 0x00, 0x0C, 0x06, 0x03, 0x00, 0x00, 0xC0, 0xE0, 0xE0, 0xE0, 0xE1, 0xF0, 0xD8, 0x6F,
|
||||
0xE1, 0xE0, 0x1C, 0x01, 0x80, 0x10, 0x07, 0x01, 0xE0, 0x3E, 0x06, 0xC1, 0xD8, 0x33, 0x06, 0x31,
|
||||
0xFE, 0x3F, 0xC6, 0x1C, 0xC1, 0xB0, 0x30, 0x06, 0x01, 0xC0, 0x30, 0x07, 0x01, 0xE0, 0x3E, 0x06,
|
||||
0xC1, 0xD8, 0x33, 0x06, 0x31, 0xFE, 0x3F, 0xC6, 0x1C, 0xC1, 0xB0, 0x30, 0x0E, 0x03, 0xE0, 0xCC,
|
||||
0x07, 0x01, 0xE0, 0x3E, 0x06, 0xC1, 0xD8, 0x33, 0x06, 0x31, 0xFE, 0x3F, 0xC6, 0x1C, 0xC1, 0xB0,
|
||||
0x30, 0x1D, 0x07, 0xE0, 0x18, 0x07, 0x01, 0xE0, 0x3E, 0x06, 0xC1, 0xD8, 0x33, 0x06, 0x31, 0xFE,
|
||||
0x3F, 0xC6, 0x1C, 0xC1, 0xB0, 0x30, 0x1B, 0x07, 0x60, 0x4C, 0x07, 0x01, 0xE0, 0x3E, 0x06, 0xC1,
|
||||
0xD8, 0x33, 0x06, 0x31, 0xFE, 0x3F, 0xC6, 0x1C, 0xC1, 0xB0, 0x30, 0x0E, 0x03, 0xC0, 0x78, 0x06,
|
||||
0x00, 0xE0, 0x3C, 0x07, 0xC0, 0xD8, 0x3B, 0x06, 0x60, 0xC6, 0x3F, 0xC7, 0xF8, 0xC3, 0x98, 0x36,
|
||||
0x06, 0x07, 0xF8, 0x3F, 0xE0, 0xF0, 0x07, 0xC0, 0x1B, 0x00, 0x6F, 0xE3, 0x3F, 0x8F, 0xC0, 0x7F,
|
||||
0x01, 0x8C, 0x06, 0x3F, 0xB0, 0xFE, 0x3E, 0x3F, 0xB8, 0x78, 0x3C, 0x1E, 0x03, 0x01, 0x83, 0xC1,
|
||||
0xE0, 0xFD, 0xEF, 0xE1, 0xC0, 0x70, 0x78, 0x38, 0x30, 0x18, 0x18, 0xFF, 0xFF, 0xC0, 0xC0, 0xC0,
|
||||
0xFE, 0xFE, 0xC0, 0xC0, 0xC0, 0xFF, 0xFF, 0x0C, 0x18, 0x18, 0xFF, 0xFF, 0xC0, 0xC0, 0xC0, 0xFE,
|
||||
0xFE, 0xC0, 0xC0, 0xC0, 0xFF, 0xFF, 0x18, 0x3E, 0x66, 0xFF, 0xFF, 0xC0, 0xC0, 0xC0, 0xFE, 0xFE,
|
||||
0xC0, 0xC0, 0xC0, 0xFF, 0xFF, 0x66, 0x7E, 0x24, 0xFF, 0xFF, 0xC0, 0xC0, 0xC0, 0xFE, 0xFE, 0xC0,
|
||||
0xC0, 0xC0, 0xFF, 0xFF, 0xCD, 0xB6, 0xDB, 0x6D, 0xB6, 0xD8, 0x7B, 0x6D, 0xB6, 0xDB, 0x6D, 0xB0,
|
||||
0x39, 0xFC, 0xCC, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x00, 0xCF, 0xF4, 0x8C, 0x30,
|
||||
0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x00, 0xFF, 0x1F, 0xF0, 0xC7, 0x18, 0x63, 0x0E, 0xF9,
|
||||
0xFF, 0x39, 0x87, 0x30, 0xC6, 0x19, 0xFF, 0x7F, 0xC0, 0x3A, 0x1F, 0x09, 0x1C, 0x3F, 0x1F, 0x8F,
|
||||
0xE7, 0xB3, 0xD9, 0xE6, 0xF3, 0x79, 0xFC, 0x7E, 0x3F, 0x1E, 0x18, 0x06, 0x00, 0xC0, 0xF8, 0x7F,
|
||||
0xB8, 0x6C, 0x1B, 0x07, 0xC1, 0xF0, 0x7C, 0x1F, 0x06, 0xC1, 0xBD, 0xE7, 0xF0, 0x70, 0x0C, 0x03,
|
||||
0x00, 0x80, 0xF8, 0x7F, 0xB8, 0x6C, 0x1B, 0x07, 0xC1, 0xF0, 0x7C, 0x1F, 0x06, 0xC1, 0xBD, 0xE7,
|
||||
0xF0, 0x70, 0x1C, 0x0F, 0x83, 0x20, 0xF8, 0x7F, 0xB8, 0x6C, 0x1B, 0x07, 0xC1, 0xF0, 0x7C, 0x1F,
|
||||
0x06, 0xC1, 0xBD, 0xE7, 0xF0, 0x70, 0x3A, 0x0F, 0x82, 0x40, 0xF8, 0x7F, 0xB8, 0x6C, 0x1B, 0x07,
|
||||
0xC1, 0xF0, 0x7C, 0x1F, 0x06, 0xC1, 0xBD, 0xE7, 0xF0, 0x70, 0x36, 0x0D, 0xC3, 0x20, 0xF8, 0x7F,
|
||||
0xB8, 0x6C, 0x1B, 0x07, 0xC1, 0xF0, 0x7C, 0x1F, 0x06, 0xC1, 0xBD, 0xE7, 0xF0, 0x70, 0x00, 0x67,
|
||||
0x7E, 0x3C, 0x3C, 0x7E, 0x67, 0x42, 0x03, 0x0F, 0xC7, 0xFB, 0x9E, 0xC7, 0xB3, 0x7C, 0xDF, 0x27,
|
||||
0xD9, 0xF6, 0x6F, 0x1B, 0xDE, 0x7F, 0x1F, 0x06, 0x00, 0x18, 0x0C, 0x02, 0x18, 0x3C, 0x1E, 0x0F,
|
||||
0x07, 0x83, 0xC1, 0xE0, 0xF0, 0x78, 0x3C, 0x1F, 0xBD, 0xFC, 0x38, 0x0C, 0x06, 0x02, 0x18, 0x3C,
|
||||
0x1E, 0x0F, 0x07, 0x83, 0xC1, 0xE0, 0xF0, 0x78, 0x3C, 0x1F, 0xBD, 0xFC, 0x38, 0x1C, 0x1F, 0x0C,
|
||||
0x98, 0x3C, 0x1E, 0x0F, 0x07, 0x83, 0xC1, 0xE0, 0xF0, 0x78, 0x3C, 0x1F, 0xBD, 0xFC, 0x38, 0x36,
|
||||
0x1B, 0x8C, 0x98, 0x3C, 0x1E, 0x0F, 0x07, 0x83, 0xC1, 0xE0, 0xF0, 0x78, 0x3C, 0x1F, 0xBD, 0xFC,
|
||||
0x38, 0x06, 0x03, 0x80, 0xC3, 0x03, 0xE1, 0xD8, 0x63, 0x38, 0xEC, 0x1E, 0x07, 0x80, 0xC0, 0x30,
|
||||
0x0C, 0x03, 0x00, 0xC0, 0xC0, 0x60, 0x3F, 0x9F, 0xEC, 0x3E, 0x0F, 0x07, 0x87, 0xFF, 0x7F, 0x30,
|
||||
0x18, 0x00, 0x3E, 0x3F, 0xB8, 0xD8, 0x6C, 0x66, 0x63, 0x39, 0x9E, 0xC3, 0xF8, 0xFE, 0x7B, 0xF0,
|
||||
0x60, 0x18, 0x06, 0x00, 0xC0, 0x70, 0x3F, 0x18, 0xC6, 0x30, 0xFC, 0x7F, 0x38, 0xC6, 0x79, 0xFF,
|
||||
0x18, 0x00, 0x06, 0x03, 0x00, 0xC0, 0x70, 0x3F, 0x18, 0xC6, 0x30, 0xFC, 0x7F, 0x38, 0xC6, 0x79,
|
||||
0xFF, 0x18, 0x00, 0x1C, 0x0F, 0x83, 0x70, 0x70, 0x3F, 0x18, 0xC6, 0x30, 0xFC, 0x7F, 0x38, 0xC6,
|
||||
0x79, 0xFF, 0x18, 0x00, 0x10, 0x0F, 0xC2, 0xE0, 0x70, 0x3F, 0x18, 0xC6, 0x30, 0xFC, 0x7F, 0x38,
|
||||
0xC6, 0x79, 0xFF, 0x18, 0x00, 0x36, 0x0D, 0xC3, 0x60, 0x70, 0x3F, 0x18, 0xC6, 0x30, 0xFC, 0x7F,
|
||||
0x38, 0xC6, 0x79, 0xFF, 0x18, 0x00, 0x08, 0x07, 0x81, 0x60, 0x70, 0x1C, 0x0F, 0xC6, 0x31, 0x8C,
|
||||
0x3F, 0x1F, 0xCE, 0x31, 0x9E, 0x7F, 0xC6, 0x00, 0x1C, 0x70, 0x7F, 0xF9, 0x8E, 0x33, 0x1C, 0x33,
|
||||
0xFF, 0xEF, 0xFF, 0xF8, 0xE1, 0x33, 0xE6, 0x7E, 0xFC, 0x30, 0x60, 0x0E, 0x0F, 0xC7, 0x39, 0x86,
|
||||
0x60, 0x18, 0x06, 0x19, 0xCE, 0x3F, 0x03, 0x00, 0xE0, 0x78, 0x0C, 0x00, 0x18, 0x0E, 0x03, 0x01,
|
||||
0xC3, 0xF3, 0x9D, 0x86, 0xFF, 0x7F, 0xB0, 0xDC, 0xE7, 0xE0, 0xC0, 0x06, 0x07, 0x03, 0x01, 0xC3,
|
||||
0xF3, 0x9D, 0x86, 0xFF, 0x7F, 0xB0, 0xDC, 0xE7, 0xE0, 0xC0, 0x0C, 0x0F, 0x0C, 0xC1, 0xC3, 0xF3,
|
||||
0x9D, 0x86, 0xFF, 0x7F, 0xB0, 0xDC, 0xE7, 0xE0, 0xC0, 0x12, 0x1F, 0x8C, 0xC1, 0xC3, 0xF3, 0x9D,
|
||||
0x86, 0xFF, 0x7F, 0xB0, 0xDC, 0xE7, 0xE0, 0xC0, 0xDD, 0x86, 0xDB, 0x6D, 0xB0, 0x6E, 0xC0, 0xCC,
|
||||
0xCC, 0xCC, 0xCC, 0x31, 0xEC, 0xC0, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x4B, 0xFC, 0xC0, 0x30,
|
||||
0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x02, 0x07, 0x80, 0xE0, 0x3C, 0x0D, 0x8F, 0xE7, 0x39, 0x87, 0x60,
|
||||
0xD8, 0x36, 0x19, 0xCE, 0x3F, 0x03, 0x00, 0x10, 0x3E, 0x6C, 0x1C, 0xFE, 0xE3, 0xC3, 0xC3, 0xC3,
|
||||
0xC3, 0xC3, 0xC3, 0x18, 0x03, 0x00, 0xC0, 0x38, 0x3F, 0x1C, 0xE6, 0x1D, 0x83, 0x60, 0xD8, 0x67,
|
||||
0x38, 0xFC, 0x0C, 0x00, 0x06, 0x01, 0x80, 0xC0, 0x38, 0x3F, 0x1C, 0xE6, 0x1D, 0x83, 0x60, 0xD8,
|
||||
0x67, 0x38, 0xFC, 0x0C, 0x00, 0x0C, 0x07, 0x83, 0x30, 0x38, 0x3F, 0x1C, 0xE6, 0x1D, 0x83, 0x60,
|
||||
0xD8, 0x67, 0x38, 0xFC, 0x0C, 0x00, 0x08, 0x07, 0xC3, 0x70, 0x38, 0x3F, 0x1C, 0xE6, 0x1D, 0x83,
|
||||
0x60, 0xD8, 0x67, 0x38, 0xFC, 0x0C, 0x00, 0x12, 0x0F, 0xC1, 0xB0, 0x38, 0x3F, 0x1C, 0xE6, 0x1D,
|
||||
0x83, 0x60, 0xD8, 0x67, 0x38, 0xFC, 0x0C, 0x00, 0x18, 0x1C, 0x18, 0xFF, 0xFF, 0x00, 0x1C, 0x18,
|
||||
0x00, 0x03, 0xE3, 0xF1, 0xCE, 0x67, 0xDB, 0x36, 0xCD, 0xE6, 0x7B, 0x8F, 0xC2, 0xC0, 0x00, 0x30,
|
||||
0x38, 0x18, 0x01, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xE7, 0x7F, 0x10, 0x0C, 0x1C, 0x18, 0x01,
|
||||
0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xE7, 0x7F, 0x10, 0x18, 0x3C, 0x66, 0x01, 0xC3, 0xC3, 0xC3,
|
||||
0xC3, 0xC3, 0xC3, 0xE7, 0x7F, 0x10, 0x24, 0x7E, 0x66, 0x01, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3,
|
||||
0xE7, 0x7F, 0x10, 0x0C, 0x1C, 0x18, 0x01, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xE7, 0x7F, 0x13,
|
||||
0x03, 0x7F, 0x7E, 0xC0, 0x60, 0x30, 0x1B, 0x8F, 0xF7, 0x1F, 0x07, 0x83, 0xC1, 0xE0, 0xFC, 0xDF,
|
||||
0xEC, 0xC6, 0x03, 0x01, 0x80, 0x24, 0x7E, 0x76, 0x01, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xE7,
|
||||
0x7F, 0x13, 0x03, 0x7F, 0x7E, 0x3F, 0x03, 0xC0, 0x38, 0x0F, 0x01, 0xF0, 0x36, 0x0E, 0xC1, 0x98,
|
||||
0x31, 0x8F, 0xF1, 0xFE, 0x30, 0xE6, 0x0D, 0x81, 0x80, 0x3F, 0x0F, 0x81, 0xC0, 0xFC, 0x63, 0x18,
|
||||
0xC3, 0xF1, 0xFC, 0xE3, 0x19, 0xE7, 0xFC, 0x60, 0x33, 0x03, 0xE0, 0x38, 0x07, 0x01, 0xE0, 0x3E,
|
||||
0x06, 0xC1, 0xD8, 0x33, 0x06, 0x31, 0xFE, 0x3F, 0xC6, 0x1C, 0xC1, 0xB0, 0x30, 0x32, 0x0F, 0x81,
|
||||
0xE0, 0x70, 0x3F, 0x18, 0xC6, 0x30, 0xFC, 0x7F, 0x38, 0xC6, 0x79, 0xFF, 0x18, 0x00, 0x0E, 0x03,
|
||||
0xC0, 0x7C, 0x0D, 0x83, 0xB0, 0x66, 0x0C, 0x63, 0xFC, 0x7F, 0x8C, 0x39, 0x83, 0x60, 0x60, 0x0C,
|
||||
0x01, 0xC0, 0x38, 0x1C, 0x0F, 0xC6, 0x31, 0x8C, 0x3F, 0x1F, 0xCE, 0x31, 0x9E, 0x7F, 0xC6, 0x60,
|
||||
0x18, 0x07, 0x0C, 0x06, 0x02, 0x07, 0xC7, 0xF7, 0x0F, 0x07, 0x83, 0xC0, 0x60, 0x30, 0x78, 0x3C,
|
||||
0x1F, 0xBD, 0xFC, 0x38, 0x06, 0x01, 0x80, 0xC0, 0x38, 0x3F, 0x1C, 0xE6, 0x19, 0x80, 0x60, 0x18,
|
||||
0x67, 0x38, 0xFC, 0x0C, 0x00, 0x1C, 0x1F, 0x0C, 0x87, 0xC7, 0xF7, 0x0F, 0x07, 0x83, 0xC0, 0x60,
|
||||
0x30, 0x78, 0x3C, 0x1F, 0xBD, 0xFC, 0x38, 0x0C, 0x07, 0x83, 0x30, 0x38, 0x3F, 0x1C, 0xE6, 0x19,
|
||||
0x80, 0x60, 0x18, 0x67, 0x38, 0xFC, 0x0C, 0x00, 0x1C, 0x0E, 0x02, 0x07, 0xC7, 0xF7, 0x0F, 0x07,
|
||||
0x83, 0xC0, 0x60, 0x30, 0x78, 0x3C, 0x1F, 0xBD, 0xFC, 0x38, 0x0C, 0x03, 0x00, 0xC0, 0x38, 0x3F,
|
||||
0x1C, 0xE6, 0x19, 0x80, 0x60, 0x18, 0x67, 0x38, 0xFC, 0x0C, 0x00, 0x36, 0x1F, 0x07, 0x07, 0xC7,
|
||||
0xF7, 0x0F, 0x07, 0x83, 0xC0, 0x60, 0x30, 0x78, 0x3C, 0x1F, 0xBD, 0xFC, 0x38, 0x33, 0x07, 0xC0,
|
||||
0xE0, 0x38, 0x3F, 0x1C, 0xE6, 0x19, 0x80, 0x60, 0x18, 0x67, 0x38, 0xFC, 0x0C, 0x00, 0x3B, 0x03,
|
||||
0xC0, 0x30, 0x7F, 0x8F, 0xF8, 0x63, 0x8C, 0x31, 0x87, 0x30, 0xE6, 0x1C, 0xC3, 0x98, 0x63, 0x0C,
|
||||
0xFF, 0xBF, 0xE0, 0x00, 0xF0, 0x07, 0x80, 0x3C, 0x39, 0xE3, 0xFC, 0x38, 0xE1, 0x87, 0x0C, 0x18,
|
||||
0x60, 0xC3, 0x0E, 0x1C, 0xF0, 0x7F, 0x80, 0xC0, 0x00, 0xFF, 0x1F, 0xF0, 0xC7, 0x18, 0x63, 0x0E,
|
||||
0xF9, 0xFF, 0x39, 0x87, 0x30, 0xC6, 0x19, 0xFF, 0x7F, 0xC0, 0x00, 0xC0, 0xFC, 0x1F, 0x8E, 0x63,
|
||||
0xFC, 0xE3, 0x98, 0x73, 0x06, 0x60, 0xCC, 0x39, 0xCF, 0x1F, 0xE0, 0xC0, 0x7E, 0x3C, 0xFF, 0xFF,
|
||||
0xC0, 0xC0, 0xC0, 0xFE, 0xFE, 0xC0, 0xC0, 0xC0, 0xFF, 0xFF, 0x3F, 0x1F, 0x83, 0x87, 0xE7, 0x3B,
|
||||
0x0D, 0xFE, 0xFF, 0x61, 0xB9, 0xCF, 0xC1, 0x80, 0x66, 0x7E, 0x1C, 0xFF, 0xFF, 0xC0, 0xC0, 0xC0,
|
||||
0xFE, 0xFE, 0xC0, 0xC0, 0xC0, 0xFF, 0xFF, 0x33, 0x1F, 0x87, 0x81, 0xC3, 0xF3, 0x9D, 0x86, 0xFF,
|
||||
0x7F, 0xB0, 0xDC, 0xE7, 0xE0, 0xC0, 0x18, 0x18, 0x18, 0xFF, 0xFF, 0xC0, 0xC0, 0xC0, 0xFE, 0xFE,
|
||||
0xC0, 0xC0, 0xC0, 0xFF, 0xFF, 0x0C, 0x06, 0x03, 0x01, 0xC3, 0xF3, 0x9D, 0x86, 0xFF, 0x7F, 0xB0,
|
||||
0xDC, 0xE7, 0xE0, 0xC0, 0xFF, 0xFF, 0xC0, 0xC0, 0xC0, 0xFE, 0xFE, 0xC0, 0xC0, 0xC0, 0xFF, 0xFF,
|
||||
0x06, 0x07, 0x07, 0x0E, 0x1F, 0x9C, 0xEC, 0x37, 0xFB, 0xFD, 0x86, 0xE7, 0x3F, 0x07, 0x01, 0xC0,
|
||||
0xE0, 0x66, 0x3C, 0x18, 0xFF, 0xFF, 0xC0, 0xC0, 0xC0, 0xFE, 0xFE, 0xC0, 0xC0, 0xC0, 0xFF, 0xFF,
|
||||
0x33, 0x0F, 0x03, 0x81, 0xC3, 0xF3, 0x9D, 0x86, 0xFF, 0x7F, 0xB0, 0xDC, 0xE7, 0xE0, 0xC0, 0x1C,
|
||||
0x1F, 0x0C, 0x87, 0xC7, 0xF7, 0x0F, 0x07, 0x83, 0xC0, 0x67, 0xF3, 0xF8, 0x3C, 0x1F, 0xBD, 0xFE,
|
||||
0x30, 0x0E, 0x07, 0xC1, 0xB0, 0x72, 0x3F, 0xDC, 0x76, 0x1D, 0x83, 0x60, 0xD8, 0x77, 0xBC, 0xFF,
|
||||
0x00, 0xC0, 0x33, 0xFC, 0xFE, 0x32, 0x1F, 0x07, 0x07, 0xC7, 0xF7, 0x0F, 0x07, 0x83, 0xC0, 0x67,
|
||||
0xF3, 0xF8, 0x3C, 0x1F, 0xBD, 0xFE, 0x30, 0x19, 0x07, 0xC0, 0xE0, 0x72, 0x3F, 0xDC, 0x76, 0x1D,
|
||||
0x83, 0x60, 0xD8, 0x77, 0xBC, 0xFF, 0x00, 0xC0, 0x33, 0xFC, 0xFE, 0x0C, 0x0E, 0x02, 0x07, 0xC7,
|
||||
0xF7, 0x0F, 0x07, 0x83, 0xC0, 0x67, 0xF3, 0xF8, 0x3C, 0x1F, 0xBD, 0xFE, 0x30, 0x04, 0x03, 0x80,
|
||||
0x40, 0x72, 0x3F, 0xDC, 0x76, 0x1D, 0x83, 0x60, 0xD8, 0x77, 0xBC, 0xFF, 0x00, 0xC0, 0x33, 0xFC,
|
||||
0xFE, 0x3E, 0x3F, 0xB8, 0x78, 0x3C, 0x1E, 0x03, 0x3F, 0x9F, 0xC1, 0xE0, 0xFD, 0xEF, 0xF1, 0x80,
|
||||
0xE0, 0x70, 0x18, 0x08, 0x00, 0x06, 0x03, 0x00, 0xE0, 0x38, 0x1C, 0x8F, 0xF7, 0x1D, 0x87, 0x60,
|
||||
0xD8, 0x36, 0x1D, 0xEF, 0x3F, 0xC0, 0x30, 0x0C, 0xFF, 0x3F, 0x80, 0x1C, 0x1F, 0x0D, 0x98, 0x3C,
|
||||
0x1E, 0x0F, 0x07, 0x83, 0xFF, 0xFF, 0xF0, 0x78, 0x3C, 0x1E, 0x0F, 0x06, 0x38, 0x1F, 0x0C, 0xC0,
|
||||
0xC0, 0x30, 0x0C, 0x03, 0x70, 0xFE, 0x38, 0xCC, 0x33, 0x0C, 0xC3, 0x30, 0xCC, 0x33, 0x0C, 0x60,
|
||||
0xCC, 0x1B, 0xFF, 0xFF, 0xF6, 0x0C, 0xFF, 0x9F, 0xF3, 0x06, 0x60, 0xCC, 0x19, 0x83, 0x30, 0x60,
|
||||
0x60, 0x7E, 0x3F, 0x0D, 0xC7, 0xF3, 0x8D, 0x86, 0xC3, 0x61, 0xB0, 0xD8, 0x6C, 0x30, 0x6F, 0xF1,
|
||||
0x8C, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x00, 0x23, 0xFD, 0x80, 0x30, 0xC3, 0x0C,
|
||||
0x30, 0xC3, 0x0C, 0xFD, 0xE3, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC0, 0xFF, 0xF0,
|
||||
0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x00, 0xCF, 0xF3, 0x8C, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0C,
|
||||
0x30, 0xC3, 0x00, 0xCF, 0xF7, 0x80, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0xDB, 0x6D, 0xB6, 0xDB,
|
||||
0x6D, 0xB8, 0xDB, 0x0D, 0xB6, 0xDB, 0x6D, 0xB8, 0xDB, 0x6D, 0xB6, 0xDB, 0x6D, 0xB0, 0x3F, 0xFF,
|
||||
0xC0, 0xF9, 0xFF, 0x9F, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x20, 0xC0, 0x0C, 0x30, 0xC3, 0x0C,
|
||||
0x39, 0xC1, 0xF8, 0x06, 0x00, 0xCD, 0x9F, 0x30, 0x2C, 0xD9, 0xB3, 0x66, 0xCD, 0x9B, 0x36, 0x60,
|
||||
0xC1, 0x87, 0x0C, 0x07, 0x03, 0xE0, 0xCC, 0x3E, 0x0F, 0x80, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xCC,
|
||||
0x33, 0x0C, 0xE3, 0x1D, 0xC7, 0xE0, 0x60, 0x31, 0xEC, 0xC0, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0C,
|
||||
0x30, 0xCF, 0x18, 0xC3, 0xE3, 0xB3, 0x9B, 0x8F, 0x87, 0x83, 0xC1, 0xF0, 0xDC, 0x67, 0x31, 0xD8,
|
||||
0x70, 0x00, 0xC0, 0x70, 0x30, 0x18, 0x00, 0xC0, 0xC0, 0xC0, 0xC2, 0xCE, 0xDC, 0xF8, 0xF0, 0xF0,
|
||||
0xD8, 0xCE, 0xC7, 0x00, 0x38, 0x38, 0x18, 0x10, 0x02, 0xCE, 0xDC, 0xF8, 0xF0, 0xF0, 0xD8, 0xCE,
|
||||
0xC7, 0x60, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xFF, 0xFF,
|
||||
0x7B, 0x6D, 0xB6, 0xDB, 0x6D, 0xB0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0,
|
||||
0xFF, 0xFF, 0x00, 0x18, 0x18, 0x18, 0x18, 0xFF, 0xFF, 0xFF, 0x3F, 0xC0, 0xD8, 0xD8, 0xD0, 0xD0,
|
||||
0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xFF, 0xFF, 0xDE, 0xF5, 0xAC, 0x63, 0x18, 0xC6, 0x31, 0x80,
|
||||
0xC0, 0xC0, 0xC0, 0xC0, 0xC4, 0xCE, 0xC4, 0xC0, 0xC0, 0xC0, 0xFF, 0xFF, 0xC3, 0x0C, 0x30, 0xC3,
|
||||
0x0C, 0xB7, 0xCB, 0x0C, 0x30, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x38, 0x0F, 0x07, 0x03, 0xC0, 0x30,
|
||||
0x0C, 0x03, 0xFC, 0xFF, 0x30, 0xC3, 0x0C, 0x30, 0xF3, 0xFC, 0xF0, 0xC3, 0x0C, 0x0C, 0x06, 0x02,
|
||||
0x1C, 0x3F, 0x1F, 0x8F, 0xE7, 0xB3, 0xD9, 0xE6, 0xF3, 0x79, 0xFC, 0x7E, 0x3F, 0x1E, 0x0C, 0x0C,
|
||||
0x18, 0x1C, 0xFE, 0xE3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xE1, 0xF8, 0xFC, 0x7F, 0x3D, 0x9E,
|
||||
0xCF, 0x37, 0x9B, 0xCF, 0xE3, 0xF1, 0xF8, 0xF0, 0x00, 0xE0, 0x70, 0x18, 0x08, 0x00, 0x1C, 0xFE,
|
||||
0xE3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x00, 0x18, 0x18, 0x18, 0x18, 0x36, 0x1F, 0x07, 0x1C,
|
||||
0x3F, 0x1F, 0x8F, 0xE7, 0xB3, 0xD9, 0xE6, 0xF3, 0x79, 0xFC, 0x7E, 0x3F, 0x1E, 0x66, 0x3E, 0x1C,
|
||||
0x1C, 0xFE, 0xE3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC0, 0xE0, 0x60, 0xC0, 0x1C, 0xFE, 0xE3,
|
||||
0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xE1, 0xF8, 0xFC, 0x7F, 0x3D, 0x9E, 0xCF, 0x37, 0x9B, 0xCF,
|
||||
0xE3, 0xF1, 0xF8, 0xF0, 0x18, 0x0C, 0x1E, 0x0E, 0x1C, 0xFE, 0xE3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3,
|
||||
0xC3, 0x03, 0x03, 0x0F, 0x0E, 0x3E, 0x0F, 0x83, 0xE1, 0xFE, 0xE1, 0xB0, 0x6C, 0x1F, 0x07, 0xC1,
|
||||
0xF0, 0x7C, 0x1B, 0x06, 0xF7, 0x9F, 0xC1, 0xC0, 0x3F, 0x0F, 0xC0, 0xE0, 0xFC, 0x73, 0x98, 0x76,
|
||||
0x0D, 0x83, 0x61, 0x9C, 0xE3, 0xF0, 0x30, 0x32, 0x0F, 0x81, 0xC0, 0xF8, 0x7F, 0xB8, 0x6C, 0x1B,
|
||||
0x07, 0xC1, 0xF0, 0x7C, 0x1F, 0x06, 0xC1, 0xBD, 0xE7, 0xF0, 0x70, 0x33, 0x07, 0xC1, 0xE0, 0x38,
|
||||
0x3F, 0x1C, 0xE6, 0x1D, 0x83, 0x60, 0xD8, 0x67, 0x38, 0xFC, 0x0C, 0x00, 0x1F, 0x0F, 0x83, 0x40,
|
||||
0xF8, 0x7F, 0xB8, 0x6C, 0x1B, 0x07, 0xC1, 0xF0, 0x7C, 0x1F, 0x06, 0xC1, 0xBD, 0xE7, 0xF0, 0x70,
|
||||
0x0F, 0x06, 0xC1, 0xE0, 0x38, 0x3F, 0x1C, 0xE6, 0x1D, 0x83, 0x60, 0xD8, 0x67, 0x38, 0xFC, 0x0C,
|
||||
0x00, 0x1F, 0xF3, 0xFF, 0xB9, 0x81, 0x8C, 0x0C, 0x60, 0x63, 0xFB, 0x1F, 0xD8, 0xC0, 0xC6, 0x07,
|
||||
0x30, 0x1F, 0xFC, 0x7F, 0xF0, 0x0E, 0x1C, 0x1F, 0xBF, 0x1C, 0xF8, 0xCC, 0x38, 0x66, 0x0F, 0xF3,
|
||||
0x07, 0xF9, 0x87, 0x0C, 0xE7, 0xCE, 0x3F, 0x7E, 0x06, 0x0C, 0x00, 0x0C, 0x0E, 0x06, 0x1F, 0xCF,
|
||||
0xF6, 0x0F, 0x07, 0x83, 0xC3, 0xFF, 0xBF, 0xF8, 0x7C, 0x3E, 0x1F, 0x0E, 0x19, 0x8C, 0x3F, 0xF3,
|
||||
0x18, 0xC6, 0x31, 0x80, 0xFE, 0x7F, 0xB0, 0x78, 0x3C, 0x1E, 0x1F, 0xFD, 0xFF, 0xC3, 0xE1, 0xF0,
|
||||
0xF8, 0x70, 0x00, 0xC0, 0x70, 0x38, 0x18, 0x00, 0x1F, 0xF9, 0x8C, 0x63, 0x18, 0xC0, 0x31, 0x8C,
|
||||
0x60, 0x66, 0x1E, 0x06, 0x1F, 0xCF, 0xF6, 0x0F, 0x07, 0x83, 0xC3, 0xFF, 0xBF, 0xF8, 0x7C, 0x3E,
|
||||
0x1F, 0x0E, 0x6C, 0xF8, 0xE0, 0x67, 0xCE, 0x18, 0x30, 0x60, 0xC1, 0x83, 0x00, 0x06, 0x03, 0x80,
|
||||
0xC0, 0xFC, 0x7F, 0x98, 0x66, 0x1D, 0xC2, 0x3E, 0x07, 0xE4, 0x1F, 0x83, 0x60, 0xDC, 0xE3, 0xF8,
|
||||
0x30, 0x0C, 0x0C, 0x18, 0x1C, 0x7E, 0x63, 0x62, 0x7E, 0x1F, 0x63, 0x63, 0x3F, 0x0C, 0x0E, 0x07,
|
||||
0xC3, 0x30, 0xFC, 0x7F, 0x98, 0x66, 0x1D, 0xC2, 0x3E, 0x07, 0xE4, 0x1F, 0x83, 0x60, 0xDC, 0xE3,
|
||||
0xF8, 0x30, 0x1C, 0x3E, 0x76, 0x1C, 0x7E, 0x63, 0x62, 0x7E, 0x1F, 0x63, 0x63, 0x3F, 0x0C, 0x3F,
|
||||
0x1F, 0xE6, 0x19, 0x87, 0x70, 0x8F, 0x81, 0xF9, 0x07, 0xE0, 0xD8, 0x37, 0x38, 0xFE, 0x0E, 0x01,
|
||||
0x81, 0xE0, 0x38, 0x1C, 0x7E, 0x63, 0x62, 0x7E, 0x1F, 0x63, 0x63, 0x3F, 0x0C, 0x0E, 0x1E, 0x1C,
|
||||
0x33, 0x07, 0x80, 0xC0, 0xFC, 0x7F, 0x98, 0x66, 0x1D, 0xC2, 0x3E, 0x07, 0xE4, 0x1F, 0x83, 0x60,
|
||||
0xDC, 0xE3, 0xF8, 0x30, 0x66, 0x3E, 0x1C, 0x1C, 0x7E, 0x63, 0x62, 0x7E, 0x1F, 0x63, 0x63, 0x3F,
|
||||
0x0C, 0xFF, 0xFF, 0xF0, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x30,
|
||||
0x0C, 0x03, 0x81, 0xE0, 0x30, 0x00, 0x30, 0x63, 0xFF, 0xE3, 0x06, 0x0C, 0x18, 0x30, 0x70, 0xF1,
|
||||
0x83, 0x8F, 0x0C, 0x33, 0x07, 0x80, 0xC3, 0xFF, 0xFF, 0xC3, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x00,
|
||||
0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x06, 0x06, 0x1E, 0x1E, 0x7E, 0xFE, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x1C, 0x1E, 0xFF, 0xFF, 0xF0, 0xC0, 0x30, 0x0C, 0x0F, 0xC3, 0xF0, 0x30, 0x0C, 0x03, 0x00,
|
||||
0xC0, 0x30, 0x00, 0x30, 0x63, 0xFF, 0xE3, 0x06, 0x7F, 0xFE, 0x30, 0x70, 0xF0, 0x3A, 0x1F, 0x09,
|
||||
0x18, 0x3C, 0x1E, 0x0F, 0x07, 0x83, 0xC1, 0xE0, 0xF0, 0x78, 0x3C, 0x1F, 0xBD, 0xFC, 0x38, 0x10,
|
||||
0x7E, 0x6C, 0x01, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xE7, 0x7F, 0x10, 0x3E, 0x1F, 0x30, 0x78,
|
||||
0x3C, 0x1E, 0x0F, 0x07, 0x83, 0xC1, 0xE0, 0xF0, 0x78, 0x3F, 0x7B, 0xF8, 0x70, 0x7E, 0x7E, 0x01,
|
||||
0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xE7, 0x7F, 0x10, 0x32, 0x1F, 0x07, 0x18, 0x3C, 0x1E, 0x0F,
|
||||
0x07, 0x83, 0xC1, 0xE0, 0xF0, 0x78, 0x3C, 0x1F, 0xBD, 0xFC, 0x38, 0x66, 0x7E, 0x3C, 0x01, 0xC3,
|
||||
0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xE7, 0x7F, 0x10, 0x1C, 0x0F, 0x07, 0x03, 0x8C, 0x1E, 0x0F, 0x07,
|
||||
0x83, 0xC1, 0xE0, 0xF0, 0x78, 0x3C, 0x1E, 0x0F, 0xDE, 0xFE, 0x1C, 0x00, 0x08, 0x3C, 0x3C, 0x3C,
|
||||
0x01, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xE7, 0x7F, 0x10, 0x1F, 0x1B, 0x0D, 0x18, 0x3C, 0x1E,
|
||||
0x0F, 0x07, 0x83, 0xC1, 0xE0, 0xF0, 0x78, 0x3C, 0x1F, 0xBD, 0xFC, 0x38, 0x16, 0x36, 0x3C, 0x01,
|
||||
0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xE7, 0x7F, 0x10, 0xC1, 0xE0, 0xF0, 0x78, 0x3C, 0x1E, 0x0F,
|
||||
0x07, 0x83, 0xC1, 0xE0, 0xFD, 0xEF, 0xE1, 0xE0, 0x30, 0x18, 0x01, 0x61, 0xB0, 0xD8, 0x6C, 0x36,
|
||||
0x1B, 0x0D, 0xCE, 0x7F, 0x09, 0x80, 0xE0, 0x70, 0x03, 0x80, 0x1F, 0x00, 0xCC, 0x30, 0xE3, 0xE7,
|
||||
0x8D, 0x9E, 0x36, 0x6C, 0xD9, 0xB3, 0x66, 0xDD, 0xBB, 0x66, 0xCD, 0x8F, 0x3E, 0x3C, 0x78, 0xF1,
|
||||
0xE3, 0xC7, 0x80, 0x07, 0x00, 0x7C, 0x03, 0x70, 0x84, 0x26, 0x71, 0xB3, 0xDD, 0x9E, 0xCD, 0xB6,
|
||||
0x6D, 0xB1, 0xE7, 0x8F, 0x3C, 0x71, 0xC0, 0x0E, 0x07, 0xC3, 0x33, 0x03, 0xE1, 0xD8, 0x63, 0x38,
|
||||
0xEC, 0x1E, 0x07, 0x80, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x18, 0x3C, 0x66, 0x01, 0xC3, 0xC3,
|
||||
0xC3, 0xC3, 0xC3, 0xC3, 0xE7, 0x7F, 0x13, 0x03, 0x7F, 0x7E, 0x33, 0x0F, 0xC1, 0x23, 0x03, 0xE1,
|
||||
0xD8, 0x63, 0x38, 0xEC, 0x1E, 0x07, 0x80, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x0E, 0x06, 0x02,
|
||||
0x0F, 0xF7, 0xF8, 0x1C, 0x0C, 0x0C, 0x0E, 0x0E, 0x0E, 0x06, 0x06, 0x07, 0xFF, 0xFE, 0x18, 0x30,
|
||||
0xC7, 0xEF, 0xE1, 0xC7, 0x1C, 0x71, 0xC3, 0xF7, 0xF0, 0x0C, 0x0E, 0x02, 0x0F, 0xF7, 0xF8, 0x1C,
|
||||
0x0C, 0x0C, 0x0E, 0x0E, 0x0E, 0x06, 0x06, 0x07, 0xFF, 0xFE, 0x30, 0x70, 0xC7, 0xEF, 0xE1, 0xC7,
|
||||
0x1C, 0x71, 0xC3, 0xF7, 0xF0, 0x37, 0x0F, 0x03, 0x0F, 0xF7, 0xF8, 0x1C, 0x0C, 0x0C, 0x0E, 0x0E,
|
||||
0x0E, 0x06, 0x06, 0x07, 0xFF, 0xFE, 0xCC, 0xF8, 0xE7, 0xEF, 0xE1, 0xC7, 0x1C, 0x71, 0xC3, 0xF7,
|
||||
0xF0, 0x3C, 0xF3, 0x1C, 0xF0, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x67, 0x30, 0x36, 0x60, 0x38, 0x79,
|
||||
0xB8, 0x20, 0xF9, 0x70, 0x7C, 0xF8, 0x4D, 0xF7, 0x80, 0x6D, 0x80, 0x6C, 0xD9, 0xB0, 0x73, 0xCE,
|
||||
0x60, 0x23, 0x96, 0xE0, 0x6D, 0xB7, 0x80, 0x66, 0xF8, 0xE0, 0x79, 0xB3, 0xC0, 0x39, 0xF4, 0xC0,
|
||||
0x69, 0xB0, 0x66, 0x60, 0x6D, 0x00, 0x6C, 0xD9, 0x00, 0x6D, 0xA0, 0x21, 0x8E, 0xF7, 0x00, 0x44,
|
||||
0x66, 0x4D, 0xF3, 0x80, 0x7C, 0xF8, 0x7C, 0xFC, 0x7F, 0xF7, 0xFF, 0x00, 0x03, 0x06, 0x06, 0x0C,
|
||||
0x18, 0x18, 0x30, 0x30, 0x60, 0x40, 0x00, 0x03, 0x06, 0x06, 0x06, 0x0C, 0x0C, 0x08, 0x18, 0x18,
|
||||
0x30, 0x30, 0x20, 0x60, 0x60, 0x40, 0xFF, 0xE0, 0xFF, 0x7F, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xC0, 0xFF, 0xFF, 0xFF, 0xC0, 0x06, 0x46, 0x60, 0x06, 0x73, 0x60, 0x06, 0x73, 0x60, 0x00, 0xD9,
|
||||
0x63, 0xE7, 0xC0, 0x00, 0x00, 0xF9, 0xF1, 0xA6, 0xC0, 0x00, 0x00, 0xF9, 0xF1, 0xA6, 0xC0, 0x00,
|
||||
0x18, 0x18, 0x18, 0x7E, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xFE,
|
||||
0xFF, 0x18, 0x18, 0xFE, 0xFF, 0x18, 0x18, 0x18, 0x6F, 0xFF, 0xF0, 0x00, 0x0D, 0xDD, 0xFB, 0x92,
|
||||
0x20, 0x78, 0x30, 0xFC, 0x60, 0xCC, 0xE0, 0xCD, 0xC0, 0x7D, 0x80, 0x3B, 0x00, 0x06, 0x44, 0x0F,
|
||||
0xFF, 0x1D, 0xBB, 0x19, 0x33, 0x31, 0xBB, 0x61, 0xFF, 0x00, 0x44, 0x6D, 0xA4, 0x6D, 0xE7, 0x96,
|
||||
0x58, 0x06, 0x3D, 0xE7, 0x07, 0x07, 0x83, 0x83, 0xC3, 0xC7, 0x87, 0x1D, 0xEE, 0x20, 0x00, 0x60,
|
||||
0x18, 0x07, 0x01, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x38, 0x06, 0x01, 0x80, 0x60, 0x00, 0x00,
|
||||
0x70, 0x6E, 0x1D, 0xC3, 0x00, 0xC0, 0x30, 0x0E, 0x03, 0x80, 0x60, 0x18, 0x06, 0x19, 0x87, 0xB0,
|
||||
0xF0, 0x04, 0x0F, 0x05, 0x0F, 0x8F, 0xEF, 0xFE, 0xFF, 0x7F, 0xA8, 0xFC, 0x7E, 0xFF, 0x7F, 0xBF,
|
||||
0xFB, 0xF9, 0xF0, 0xF0, 0x3F, 0x8F, 0xE3, 0x00, 0xC0, 0x30, 0x0F, 0xE3, 0xF8, 0xC0, 0x7C, 0x3F,
|
||||
0x83, 0x00, 0xC0, 0x1F, 0x0F, 0xE3, 0x1C, 0xC3, 0x30, 0xDF, 0x03, 0x01, 0xF0, 0x30, 0x0C, 0x07,
|
||||
0xF9, 0xFF, 0x38, 0x63, 0xC6, 0x3C, 0x63, 0xC6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x33, 0x63,
|
||||
0x3E, 0x31, 0xE3, 0x1E, 0x3F, 0x83, 0xFC, 0x30, 0xCF, 0xFF, 0xFF, 0xF3, 0x1C, 0x3F, 0xC3, 0xF0,
|
||||
0x30, 0x03, 0x00, 0x30, 0x03, 0x00, 0x63, 0xC6, 0x63, 0xC6, 0x63, 0xCE, 0x63, 0xCC, 0xFF, 0xFE,
|
||||
0xFF, 0xFE, 0xFF, 0xFE, 0xFF, 0xFE, 0x36, 0x6C, 0x3C, 0x78, 0x3C, 0x78, 0x1C, 0x38, 0x00, 0xC0,
|
||||
0xFC, 0x1F, 0x8E, 0x63, 0xFC, 0xE3, 0x98, 0x73, 0x06, 0x60, 0xCC, 0x39, 0xCF, 0x1F, 0xE0, 0xC0,
|
||||
0xFF, 0x80, 0x1F, 0x87, 0xF8, 0xC3, 0x98, 0x3F, 0xC7, 0xFC, 0x3F, 0x07, 0xF3, 0x70, 0x66, 0x1C,
|
||||
0xF7, 0x0F, 0xE0, 0x60, 0x30, 0xC6, 0x38, 0xCE, 0x1B, 0x83, 0xE1, 0xFF, 0x3F, 0xE1, 0xF0, 0x37,
|
||||
0x06, 0x70, 0xC7, 0x18, 0x70, 0x3F, 0x83, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7, 0xFF, 0x3F, 0xC3,
|
||||
0xF0, 0x30, 0x03, 0x00, 0x30, 0x03, 0x00, 0x08, 0x06, 0x0F, 0x8F, 0xEE, 0xDE, 0x6F, 0x37, 0x98,
|
||||
0xCF, 0xE7, 0xF3, 0x79, 0xBF, 0xFB, 0xFC, 0x70, 0x18, 0x08, 0x06, 0x0F, 0x8F, 0xEE, 0xDE, 0x6F,
|
||||
0x37, 0x98, 0xCC, 0x66, 0xF3, 0x79, 0xBF, 0xFB, 0xF8, 0x70, 0x18, 0xFF, 0xFF, 0xE0, 0x63, 0xFF,
|
||||
0xFF, 0x81, 0x8F, 0xE3, 0xF8, 0x06, 0x01, 0x80, 0x60, 0x18, 0x30, 0x18, 0x0F, 0x0F, 0x8F, 0x01,
|
||||
0xE3, 0xE7, 0x63, 0x31, 0x99, 0x8F, 0xC7, 0xC0, 0x0C, 0x03, 0x03, 0xF1, 0xFE, 0xED, 0xB3, 0x7C,
|
||||
0xCF, 0x33, 0xCC, 0xF3, 0x3C, 0xCF, 0x33, 0xC0, 0xF0, 0x30, 0x3F, 0x87, 0xF8, 0xC3, 0x18, 0x73,
|
||||
0x0C, 0xFF, 0xBF, 0xE1, 0x80, 0xFF, 0x06, 0x00, 0xC0, 0x18, 0x00, 0x1E, 0x07, 0x8F, 0xF3, 0xFE,
|
||||
0x30, 0xCC, 0x33, 0x0C, 0xFE, 0x3F, 0x8C, 0x73, 0x0C, 0xC3, 0xFF, 0xFF, 0xE1, 0xE0, 0x78, 0x08,
|
||||
0x00, 0xE0, 0x0E, 0x00, 0xE0, 0x0F, 0xFF, 0xBF, 0xFC, 0xC0, 0x03, 0x00, 0x0C, 0x00, 0x00, 0x00,
|
||||
0x0C, 0x07, 0x83, 0xF1, 0xF6, 0x6C, 0xC3, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x00,
|
||||
0x80, 0x06, 0x00, 0x18, 0x00, 0x6F, 0xFF, 0xBF, 0xFC, 0x01, 0xC0, 0x1C, 0x00, 0xC0, 0x00, 0x00,
|
||||
0x0C, 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC1, 0x32, 0x6D, 0xCF, 0xE1, 0xF0, 0x38, 0x00,
|
||||
0x00, 0x08, 0x80, 0xE6, 0x0E, 0x18, 0xE0, 0x6F, 0xFF, 0xBF, 0xFC, 0xC1, 0xC3, 0x1C, 0x0C, 0xC0,
|
||||
0x00, 0x00, 0x0C, 0x07, 0x83, 0xF1, 0xF6, 0x6C, 0xC3, 0x00, 0xC1, 0x32, 0x6D, 0xCF, 0xE1, 0xF0,
|
||||
0x38, 0x00, 0x00, 0x7C, 0x7F, 0x38, 0x1E, 0x0F, 0x86, 0xE3, 0x38, 0x0E, 0x03, 0x80, 0x00, 0x1F,
|
||||
0x1F, 0xC0, 0xE0, 0xF0, 0xF8, 0xEC, 0xE6, 0xE0, 0xE0, 0x00, 0x00, 0x00, 0x70, 0x1C, 0x27, 0x31,
|
||||
0xD8, 0x7C, 0x1E, 0x3F, 0x3F, 0x80, 0x00, 0x01, 0xE1, 0xD9, 0xCD, 0xC7, 0xC3, 0xC1, 0xF8, 0xFE,
|
||||
0x00, 0x38, 0x1E, 0x03, 0x87, 0xE7, 0xF7, 0x3B, 0x0F, 0x83, 0xC1, 0xE1, 0xB9, 0xCF, 0xC1, 0x80,
|
||||
0x01, 0x03, 0xC3, 0xF9, 0xDE, 0x66, 0xDB, 0xB6, 0xCD, 0xB3, 0x7B, 0x8F, 0xC3, 0xC0, 0xC0, 0x0E,
|
||||
0x07, 0x81, 0xE0, 0x6C, 0x33, 0x0C, 0xC3, 0x39, 0xC6, 0x61, 0x98, 0x67, 0xFF, 0xFF, 0xFF, 0x7F,
|
||||
0xB0, 0xD8, 0x6C, 0x36, 0x1B, 0x0D, 0x86, 0xC3, 0x61, 0xB0, 0xD8, 0x6C, 0x36, 0x1B, 0x0D, 0x82,
|
||||
0x7F, 0xDF, 0xF6, 0x00, 0xC0, 0x38, 0x07, 0x00, 0xC0, 0x18, 0x0E, 0x03, 0x01, 0x80, 0xE0, 0x70,
|
||||
0x18, 0x07, 0xFD, 0xFF, 0xFF, 0xFF, 0x06, 0x0C, 0x30, 0x60, 0xC3, 0x06, 0x0C, 0x30, 0x60, 0xC3,
|
||||
0x06, 0x0C, 0x30, 0x60, 0xC0, 0x77, 0xBF, 0xE0, 0x00, 0x00, 0xC0, 0x30, 0x0C, 0x06, 0x01, 0x80,
|
||||
0x60, 0x18, 0x0C, 0x73, 0x3C, 0xC3, 0x30, 0x78, 0x1E, 0x07, 0x81, 0xE0, 0x13, 0x1F, 0xE6, 0xCD,
|
||||
0xB3, 0x7F, 0x8E, 0xE0, 0x1C, 0xF3, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xCF, 0x38,
|
||||
0x3B, 0x7F, 0xCE, 0x3B, 0x7F, 0xCE, 0x00, 0x0C, 0x0C, 0xFF, 0xFF, 0x7F, 0xFF, 0x30, 0x30, 0x01,
|
||||
0x0F, 0x3E, 0xF0, 0xF0, 0x7C, 0x1F, 0x03, 0x7F, 0xFF, 0xC0, 0xF0, 0x7E, 0x0F, 0x07, 0x3E, 0xF8,
|
||||
0xC0, 0x7F, 0xFF,
|
||||
};
|
||||
|
||||
static const EpdGlyph spacegroteskGlyphs[] = {
|
||||
{ 0, 0, 10, 0, 0, 0, 0 }, //
|
||||
{ 0, 0, 4, 0, 0, 0, 0 }, //
|
||||
{ 4, 13, 4, 0, 12, 7, 0 }, // !
|
||||
{ 7, 6, 7, 0, 13, 6, 7 }, // "
|
||||
{ 10, 12, 10, 0, 12, 15, 13 }, // #
|
||||
{ 10, 16, 10, 0, 14, 20, 28 }, // $
|
||||
{ 13, 13, 13, 0, 12, 22, 48 }, // %
|
||||
{ 10, 12, 10, 0, 12, 15, 70 }, // &
|
||||
{ 4, 6, 4, 0, 13, 3, 85 }, // '
|
||||
{ 6, 17, 6, 1, 13, 13, 88 }, // (
|
||||
{ 6, 17, 6, 0, 13, 13, 101 }, // )
|
||||
{ 8, 8, 9, 0, 12, 8, 114 }, // *
|
||||
{ 8, 8, 10, 1, 10, 8, 122 }, // +
|
||||
{ 4, 6, 4, 0, 3, 3, 130 }, // ,
|
||||
{ 6, 2, 8, 1, 5, 2, 133 }, // -
|
||||
{ 4, 4, 4, 0, 3, 2, 135 }, // .
|
||||
{ 7, 16, 6, 0, 12, 14, 137 }, // /
|
||||
{ 9, 13, 11, 1, 12, 15, 151 }, // 0
|
||||
{ 6, 12, 7, 0, 12, 9, 166 }, // 1
|
||||
{ 10, 12, 10, 0, 12, 15, 175 }, // 2
|
||||
{ 10, 13, 10, 0, 12, 17, 190 }, // 3
|
||||
{ 10, 12, 10, 0, 12, 15, 207 }, // 4
|
||||
{ 10, 13, 10, 0, 12, 17, 222 }, // 5
|
||||
{ 9, 13, 10, 1, 12, 15, 239 }, // 6
|
||||
{ 9, 12, 9, 0, 12, 14, 254 }, // 7
|
||||
{ 10, 13, 10, 0, 12, 17, 268 }, // 8
|
||||
{ 10, 13, 10, 0, 12, 17, 285 }, // 9
|
||||
{ 4, 10, 4, 0, 9, 5, 302 }, // :
|
||||
{ 4, 12, 4, 0, 9, 6, 307 }, // ;
|
||||
{ 8, 8, 10, 1, 10, 8, 313 }, // <
|
||||
{ 8, 5, 10, 1, 8, 5, 321 }, // =
|
||||
{ 8, 8, 10, 1, 10, 8, 326 }, // >
|
||||
{ 9, 13, 10, 0, 12, 15, 334 }, // ?
|
||||
{ 15, 16, 17, 1, 12, 30, 349 }, // @
|
||||
{ 11, 12, 11, 0, 12, 17, 379 }, // A
|
||||
{ 11, 12, 11, 0, 12, 17, 396 }, // B
|
||||
{ 9, 13, 11, 1, 12, 15, 413 }, // C
|
||||
{ 11, 12, 11, 0, 12, 17, 428 }, // D
|
||||
{ 8, 12, 9, 1, 12, 12, 445 }, // E
|
||||
{ 8, 12, 9, 1, 12, 12, 457 }, // F
|
||||
{ 9, 13, 11, 1, 12, 15, 469 }, // G
|
||||
{ 9, 12, 11, 1, 12, 14, 484 }, // H
|
||||
{ 2, 12, 4, 1, 12, 3, 498 }, // I
|
||||
{ 10, 13, 10, 0, 12, 17, 501 }, // J
|
||||
{ 9, 12, 10, 1, 12, 14, 518 }, // K
|
||||
{ 8, 12, 9, 1, 12, 12, 532 }, // L
|
||||
{ 13, 12, 14, 1, 12, 20, 544 }, // M
|
||||
{ 9, 12, 11, 1, 12, 14, 564 }, // N
|
||||
{ 10, 13, 11, 1, 12, 17, 578 }, // O
|
||||
{ 9, 12, 10, 1, 12, 14, 595 }, // P
|
||||
{ 10, 15, 11, 1, 12, 19, 609 }, // Q
|
||||
{ 9, 12, 11, 1, 12, 14, 628 }, // R
|
||||
{ 10, 13, 10, 0, 12, 17, 642 }, // S
|
||||
{ 10, 12, 10, 0, 12, 15, 659 }, // T
|
||||
{ 9, 13, 11, 1, 12, 15, 674 }, // U
|
||||
{ 10, 12, 10, 0, 12, 15, 689 }, // V
|
||||
{ 14, 12, 15, 0, 12, 21, 704 }, // W
|
||||
{ 11, 12, 11, 0, 12, 17, 725 }, // X
|
||||
{ 10, 12, 10, 0, 12, 15, 742 }, // Y
|
||||
{ 9, 12, 10, 0, 12, 14, 757 }, // Z
|
||||
{ 5, 17, 6, 1, 13, 11, 771 }, // [
|
||||
{ 8, 16, 6, -1, 12, 16, 782 }, // <backslash>
|
||||
{ 5, 17, 6, 0, 13, 11, 798 }, // ]
|
||||
{ 9, 5, 10, 1, 12, 6, 809 }, // ^
|
||||
{ 9, 3, 10, 1, 0, 4, 815 }, // _
|
||||
{ 4, 3, 5, 0, 12, 2, 819 }, // `
|
||||
{ 10, 10, 10, 0, 9, 13, 821 }, // a
|
||||
{ 9, 13, 11, 1, 12, 15, 834 }, // b
|
||||
{ 10, 10, 10, 0, 9, 13, 849 }, // c
|
||||
{ 10, 13, 11, 0, 12, 17, 862 }, // d
|
||||
{ 9, 10, 10, 0, 9, 12, 879 }, // e
|
||||
{ 7, 12, 7, 0, 12, 11, 891 }, // f
|
||||
{ 10, 13, 11, 0, 9, 17, 902 }, // g
|
||||
{ 8, 12, 10, 1, 12, 12, 919 }, // h
|
||||
{ 3, 12, 4, 1, 12, 5, 931 }, // i
|
||||
{ 5, 16, 4, -1, 12, 10, 936 }, // j
|
||||
{ 8, 12, 9, 1, 12, 12, 946 }, // k
|
||||
{ 2, 12, 4, 1, 12, 3, 958 }, // l
|
||||
{ 13, 9, 14, 1, 9, 15, 961 }, // m
|
||||
{ 8, 9, 10, 1, 9, 9, 976 }, // n
|
||||
{ 10, 10, 10, 0, 9, 13, 985 }, // o
|
||||
{ 9, 13, 11, 1, 9, 15, 998 }, // p
|
||||
{ 10, 13, 11, 0, 9, 17, 1013 }, // q
|
||||
{ 5, 9, 6, 1, 9, 6, 1030 }, // r
|
||||
{ 8, 10, 9, 0, 9, 10, 1036 }, // s
|
||||
{ 7, 12, 8, 0, 12, 11, 1046 }, // t
|
||||
{ 8, 10, 10, 1, 9, 10, 1057 }, // u
|
||||
{ 9, 9, 9, 0, 9, 11, 1067 }, // v
|
||||
{ 13, 9, 13, 0, 9, 15, 1078 }, // w
|
||||
{ 10, 9, 10, 0, 9, 12, 1093 }, // x
|
||||
{ 8, 13, 10, 1, 9, 13, 1105 }, // y
|
||||
{ 7, 9, 9, 1, 9, 8, 1118 }, // z
|
||||
{ 7, 17, 7, 0, 13, 15, 1126 }, // {
|
||||
{ 2, 19, 4, 1, 14, 5, 1141 }, // |
|
||||
{ 7, 17, 7, 0, 13, 15, 1146 }, // }
|
||||
{ 8, 4, 10, 1, 8, 4, 1161 }, // ~
|
||||
{ 0, 0, 4, 0, 0, 0, 1165 }, //
|
||||
{ 4, 13, 4, 0, 9, 7, 1165 }, // ¡
|
||||
{ 9, 13, 10, 1, 11, 15, 1172 }, // ¢
|
||||
{ 10, 12, 10, 0, 12, 15, 1187 }, // £
|
||||
{ 10, 10, 10, 0, 11, 13, 1202 }, // ¤
|
||||
{ 11, 12, 10, 0, 12, 17, 1215 }, // ¥
|
||||
{ 2, 19, 4, 1, 14, 5, 1232 }, // ¦
|
||||
{ 8, 13, 8, 0, 12, 13, 1237 }, // §
|
||||
{ 7, 3, 7, 0, 12, 3, 1250 }, // ¨
|
||||
{ 10, 13, 12, 1, 12, 17, 1253 }, // ©
|
||||
{ 7, 7, 7, 0, 12, 7, 1270 }, // ª
|
||||
{ 11, 8, 11, 0, 8, 11, 1277 }, // «
|
||||
{ 8, 4, 10, 1, 7, 4, 1288 }, // ¬
|
||||
{ 6, 2, 8, 1, 5, 2, 1292 }, //
|
||||
{ 8, 8, 9, 0, 12, 8, 1294 }, // ®
|
||||
{ 7, 2, 7, 0, 11, 2, 1302 }, // ¯
|
||||
{ 6, 6, 6, 0, 12, 5, 1304 }, // °
|
||||
{ 8, 10, 10, 1, 10, 10, 1309 }, // ±
|
||||
{ 6, 7, 6, 0, 13, 6, 1319 }, // ²
|
||||
{ 6, 7, 6, 0, 12, 6, 1325 }, // ³
|
||||
{ 4, 3, 5, 0, 12, 2, 1331 }, // ´
|
||||
{ 9, 13, 10, 1, 9, 15, 1333 }, // µ
|
||||
{ 9, 12, 10, 0, 12, 14, 1348 }, // ¶
|
||||
{ 3, 4, 3, 0, 7, 2, 1362 }, // ·
|
||||
{ 5, 5, 5, 0, 1, 4, 1364 }, // ¸
|
||||
{ 4, 6, 4, 0, 12, 3, 1368 }, // ¹
|
||||
{ 7, 7, 7, 0, 12, 7, 1371 }, // º
|
||||
{ 10, 8, 11, 1, 8, 10, 1378 }, // »
|
||||
{ 14, 13, 14, 0, 12, 23, 1388 }, // ¼
|
||||
{ 14, 13, 14, 0, 12, 23, 1411 }, // ½
|
||||
{ 15, 13, 15, 0, 12, 25, 1434 }, // ¾
|
||||
{ 9, 13, 10, 0, 9, 15, 1459 }, // ¿
|
||||
{ 11, 15, 11, 0, 15, 21, 1474 }, // À
|
||||
{ 11, 15, 11, 0, 15, 21, 1495 }, // Á
|
||||
{ 11, 15, 11, 0, 15, 21, 1516 }, // Â
|
||||
{ 11, 15, 11, 0, 15, 21, 1537 }, // Ã
|
||||
{ 11, 15, 11, 0, 15, 21, 1558 }, // Ä
|
||||
{ 11, 16, 11, 0, 16, 22, 1579 }, // Å
|
||||
{ 14, 12, 14, 0, 12, 21, 1601 }, // Æ
|
||||
{ 9, 16, 11, 1, 12, 18, 1622 }, // Ç
|
||||
{ 8, 15, 9, 1, 15, 15, 1640 }, // È
|
||||
{ 8, 15, 9, 1, 15, 15, 1655 }, // É
|
||||
{ 8, 15, 9, 1, 15, 15, 1670 }, // Ê
|
||||
{ 8, 15, 9, 1, 15, 15, 1685 }, // Ë
|
||||
{ 3, 15, 4, 0, 15, 6, 1700 }, // Ì
|
||||
{ 3, 15, 4, 1, 15, 6, 1706 }, // Í
|
||||
{ 6, 15, 4, -1, 15, 12, 1712 }, // Î
|
||||
{ 6, 15, 4, -1, 15, 12, 1724 }, // Ï
|
||||
{ 11, 12, 11, 0, 12, 17, 1736 }, // Ð
|
||||
{ 9, 15, 11, 1, 15, 17, 1753 }, // Ñ
|
||||
{ 10, 16, 11, 1, 15, 20, 1770 }, // Ò
|
||||
{ 10, 16, 11, 1, 15, 20, 1790 }, // Ó
|
||||
{ 10, 16, 11, 1, 15, 20, 1810 }, // Ô
|
||||
{ 10, 16, 11, 1, 15, 20, 1830 }, // Õ
|
||||
{ 10, 16, 11, 1, 15, 20, 1850 }, // Ö
|
||||
{ 8, 8, 10, 1, 10, 8, 1870 }, // ×
|
||||
{ 10, 15, 11, 1, 13, 19, 1878 }, // Ø
|
||||
{ 9, 16, 11, 1, 15, 18, 1897 }, // Ù
|
||||
{ 9, 16, 11, 1, 15, 18, 1915 }, // Ú
|
||||
{ 9, 16, 11, 1, 15, 18, 1933 }, // Û
|
||||
{ 9, 16, 11, 1, 15, 18, 1951 }, // Ü
|
||||
{ 10, 15, 10, 0, 15, 19, 1969 }, // Ý
|
||||
{ 9, 12, 10, 1, 12, 14, 1988 }, // Þ
|
||||
{ 9, 13, 10, 1, 12, 15, 2002 }, // ß
|
||||
{ 10, 13, 10, 0, 12, 17, 2017 }, // à
|
||||
{ 10, 13, 10, 0, 12, 17, 2034 }, // á
|
||||
{ 10, 13, 10, 0, 12, 17, 2051 }, // â
|
||||
{ 10, 13, 10, 0, 12, 17, 2068 }, // ã
|
||||
{ 10, 13, 10, 0, 12, 17, 2085 }, // ä
|
||||
{ 10, 14, 10, 0, 13, 18, 2102 }, // å
|
||||
{ 15, 10, 15, 0, 9, 19, 2120 }, // æ
|
||||
{ 10, 13, 10, 0, 9, 17, 2139 }, // ç
|
||||
{ 9, 13, 10, 0, 12, 15, 2156 }, // è
|
||||
{ 9, 13, 10, 0, 12, 15, 2171 }, // é
|
||||
{ 9, 13, 10, 0, 12, 15, 2186 }, // ê
|
||||
{ 9, 13, 10, 0, 12, 15, 2201 }, // ë
|
||||
{ 3, 12, 4, 0, 12, 5, 2216 }, // ì
|
||||
{ 4, 12, 4, 1, 12, 6, 2221 }, // í
|
||||
{ 6, 12, 4, -1, 12, 9, 2227 }, // î
|
||||
{ 6, 12, 4, -1, 12, 9, 2236 }, // ï
|
||||
{ 10, 14, 10, 0, 13, 18, 2245 }, // ð
|
||||
{ 8, 12, 10, 1, 12, 12, 2263 }, // ñ
|
||||
{ 10, 13, 10, 0, 12, 17, 2275 }, // ò
|
||||
{ 10, 13, 10, 0, 12, 17, 2292 }, // ó
|
||||
{ 10, 13, 10, 0, 12, 17, 2309 }, // ô
|
||||
{ 10, 13, 10, 0, 12, 17, 2326 }, // õ
|
||||
{ 10, 13, 10, 0, 12, 17, 2343 }, // ö
|
||||
{ 8, 8, 10, 1, 10, 8, 2360 }, // ÷
|
||||
{ 10, 12, 10, 0, 10, 15, 2368 }, // ø
|
||||
{ 8, 13, 10, 1, 12, 13, 2383 }, // ù
|
||||
{ 8, 13, 10, 1, 12, 13, 2396 }, // ú
|
||||
{ 8, 13, 10, 1, 12, 13, 2409 }, // û
|
||||
{ 8, 13, 10, 1, 12, 13, 2422 }, // ü
|
||||
{ 8, 16, 10, 1, 12, 16, 2435 }, // ý
|
||||
{ 9, 16, 11, 1, 12, 18, 2451 }, // þ
|
||||
{ 8, 16, 10, 1, 12, 16, 2469 }, // ÿ
|
||||
{ 11, 14, 11, 0, 14, 20, 2485 }, // Ā
|
||||
{ 10, 12, 10, 0, 11, 15, 2505 }, // ā
|
||||
{ 11, 15, 11, 0, 15, 21, 2520 }, // Ă
|
||||
{ 10, 13, 10, 0, 12, 17, 2541 }, // ă
|
||||
{ 11, 15, 11, 0, 12, 21, 2558 }, // Ą
|
||||
{ 10, 12, 10, 0, 9, 15, 2579 }, // ą
|
||||
{ 9, 16, 11, 1, 15, 18, 2594 }, // Ć
|
||||
{ 10, 13, 10, 0, 12, 17, 2612 }, // ć
|
||||
{ 9, 16, 11, 1, 15, 18, 2629 }, // Ĉ
|
||||
{ 10, 13, 10, 0, 12, 17, 2647 }, // ĉ
|
||||
{ 9, 16, 11, 1, 15, 18, 2664 }, // Ċ
|
||||
{ 10, 13, 10, 0, 12, 17, 2682 }, // ċ
|
||||
{ 9, 16, 11, 1, 15, 18, 2699 }, // Č
|
||||
{ 10, 13, 10, 0, 12, 17, 2717 }, // č
|
||||
{ 11, 15, 11, 0, 15, 21, 2734 }, // Ď
|
||||
{ 13, 13, 12, 0, 12, 22, 2755 }, // ď
|
||||
{ 11, 12, 11, 0, 12, 17, 2777 }, // Đ
|
||||
{ 11, 13, 11, 0, 12, 18, 2794 }, // đ
|
||||
{ 8, 14, 9, 1, 14, 14, 2812 }, // Ē
|
||||
{ 9, 12, 10, 0, 11, 14, 2826 }, // ē
|
||||
{ 8, 15, 9, 1, 15, 15, 2840 }, // Ĕ
|
||||
{ 9, 13, 10, 0, 12, 15, 2855 }, // ĕ
|
||||
{ 8, 15, 9, 1, 15, 15, 2870 }, // Ė
|
||||
{ 9, 13, 10, 0, 12, 15, 2885 }, // ė
|
||||
{ 8, 15, 9, 1, 12, 15, 2900 }, // Ę
|
||||
{ 9, 12, 10, 0, 9, 14, 2915 }, // ę
|
||||
{ 8, 15, 9, 1, 15, 15, 2929 }, // Ě
|
||||
{ 9, 13, 10, 0, 12, 15, 2944 }, // ě
|
||||
{ 9, 16, 11, 1, 15, 18, 2959 }, // Ĝ
|
||||
{ 10, 16, 11, 0, 12, 20, 2977 }, // ĝ
|
||||
{ 9, 16, 11, 1, 15, 18, 2997 }, // Ğ
|
||||
{ 10, 16, 11, 0, 12, 20, 3015 }, // ğ
|
||||
{ 9, 16, 11, 1, 15, 18, 3035 }, // Ġ
|
||||
{ 10, 16, 11, 0, 12, 20, 3053 }, // ġ
|
||||
{ 9, 17, 11, 1, 12, 20, 3073 }, // Ģ
|
||||
{ 10, 17, 11, 0, 13, 22, 3093 }, // ģ
|
||||
{ 9, 15, 11, 1, 15, 17, 3115 }, // Ĥ
|
||||
{ 10, 15, 10, -1, 15, 19, 3132 }, // ĥ
|
||||
{ 11, 12, 11, 0, 12, 17, 3151 }, // Ħ
|
||||
{ 9, 12, 10, 0, 12, 14, 3168 }, // ħ
|
||||
{ 6, 15, 4, -1, 15, 12, 3182 }, // Ĩ
|
||||
{ 6, 12, 4, -1, 12, 9, 3194 }, // ĩ
|
||||
{ 6, 14, 4, -1, 14, 11, 3203 }, // Ī
|
||||
{ 6, 11, 4, -1, 11, 9, 3214 }, // ī
|
||||
{ 6, 15, 4, -1, 15, 12, 3223 }, // Ĭ
|
||||
{ 6, 12, 4, -1, 12, 9, 3235 }, // ĭ
|
||||
{ 3, 15, 4, 1, 12, 6, 3244 }, // Į
|
||||
{ 3, 15, 4, 1, 12, 6, 3250 }, // į
|
||||
{ 3, 15, 4, 1, 15, 6, 3256 }, // İ
|
||||
{ 2, 9, 4, 1, 9, 3, 3262 }, // ı
|
||||
{ 12, 13, 12, 0, 12, 20, 3265 }, // IJ
|
||||
{ 7, 16, 8, 1, 12, 14, 3285 }, // ij
|
||||
{ 10, 16, 10, 0, 15, 20, 3299 }, // Ĵ
|
||||
{ 6, 16, 4, -1, 12, 12, 3319 }, // ĵ
|
||||
{ 9, 17, 10, 1, 12, 20, 3331 }, // Ķ
|
||||
{ 8, 17, 9, 1, 12, 17, 3351 }, // ķ
|
||||
{ 8, 9, 9, 1, 9, 9, 3368 }, // ĸ
|
||||
{ 8, 15, 9, 1, 15, 15, 3377 }, // Ĺ
|
||||
{ 3, 15, 4, 1, 15, 6, 3392 }, // ĺ
|
||||
{ 8, 17, 9, 1, 12, 17, 3398 }, // Ļ
|
||||
{ 2, 17, 4, 1, 12, 5, 3415 }, // ļ
|
||||
{ 8, 12, 9, 1, 12, 12, 3420 }, // Ľ
|
||||
{ 5, 12, 5, 1, 12, 8, 3432 }, // ľ
|
||||
{ 8, 12, 9, 1, 12, 12, 3440 }, // Ŀ
|
||||
{ 6, 12, 7, 1, 12, 9, 3452 }, // ŀ
|
||||
{ 10, 12, 10, 0, 12, 15, 3461 }, // Ł
|
||||
{ 6, 12, 6, 0, 12, 9, 3476 }, // ł
|
||||
{ 9, 15, 11, 1, 15, 17, 3485 }, // Ń
|
||||
{ 8, 12, 10, 1, 12, 12, 3502 }, // ń
|
||||
{ 9, 17, 11, 1, 12, 20, 3514 }, // Ņ
|
||||
{ 8, 14, 10, 1, 9, 14, 3534 }, // ņ
|
||||
{ 9, 15, 11, 1, 15, 17, 3548 }, // Ň
|
||||
{ 8, 12, 10, 1, 12, 12, 3565 }, // ň
|
||||
{ 8, 13, 10, 1, 13, 13, 3577 }, // ʼn
|
||||
{ 9, 16, 11, 1, 12, 18, 3590 }, // Ŋ
|
||||
{ 8, 13, 10, 1, 9, 13, 3608 }, // ŋ
|
||||
{ 10, 15, 11, 1, 14, 19, 3621 }, // Ō
|
||||
{ 10, 12, 10, 0, 11, 15, 3640 }, // ō
|
||||
{ 10, 16, 11, 1, 15, 20, 3655 }, // Ŏ
|
||||
{ 10, 13, 10, 0, 12, 17, 3675 }, // ŏ
|
||||
{ 10, 16, 11, 1, 15, 20, 3692 }, // Ő
|
||||
{ 10, 13, 10, 0, 12, 17, 3712 }, // ő
|
||||
{ 13, 12, 14, 1, 12, 20, 3729 }, // Œ
|
||||
{ 17, 10, 17, 0, 9, 22, 3749 }, // œ
|
||||
{ 9, 15, 11, 1, 15, 17, 3771 }, // Ŕ
|
||||
{ 5, 12, 6, 1, 12, 8, 3788 }, // ŕ
|
||||
{ 9, 17, 11, 1, 12, 20, 3796 }, // Ŗ
|
||||
{ 5, 14, 6, 1, 9, 9, 3816 }, // ŗ
|
||||
{ 9, 15, 11, 1, 15, 17, 3825 }, // Ř
|
||||
{ 7, 12, 6, 0, 12, 11, 3842 }, // ř
|
||||
{ 10, 16, 10, 0, 15, 20, 3853 }, // Ś
|
||||
{ 8, 13, 9, 0, 12, 13, 3873 }, // ś
|
||||
{ 10, 16, 10, 0, 15, 20, 3886 }, // Ŝ
|
||||
{ 8, 13, 9, 0, 12, 13, 3906 }, // ŝ
|
||||
{ 10, 16, 10, 0, 12, 20, 3919 }, // Ş
|
||||
{ 8, 13, 9, 0, 9, 13, 3939 }, // ş
|
||||
{ 10, 16, 10, 0, 15, 20, 3952 }, // Š
|
||||
{ 8, 13, 9, 0, 12, 13, 3972 }, // š
|
||||
{ 10, 16, 10, 0, 12, 20, 3985 }, // Ţ
|
||||
{ 7, 16, 8, 0, 12, 14, 4005 }, // ţ
|
||||
{ 10, 15, 10, 0, 15, 19, 4019 }, // Ť
|
||||
{ 8, 13, 8, 0, 13, 13, 4038 }, // ť
|
||||
{ 10, 12, 10, 0, 12, 15, 4051 }, // Ŧ
|
||||
{ 7, 12, 8, 0, 12, 11, 4066 }, // ŧ
|
||||
{ 9, 16, 11, 1, 15, 18, 4077 }, // Ũ
|
||||
{ 8, 13, 10, 1, 12, 13, 4095 }, // ũ
|
||||
{ 9, 15, 11, 1, 14, 17, 4108 }, // Ū
|
||||
{ 8, 12, 10, 1, 11, 12, 4125 }, // ū
|
||||
{ 9, 16, 11, 1, 15, 18, 4137 }, // Ŭ
|
||||
{ 8, 13, 10, 1, 12, 13, 4155 }, // ŭ
|
||||
{ 9, 17, 11, 1, 16, 20, 4168 }, // Ů
|
||||
{ 8, 14, 10, 1, 13, 14, 4188 }, // ů
|
||||
{ 9, 16, 11, 1, 15, 18, 4202 }, // Ű
|
||||
{ 8, 13, 10, 1, 12, 13, 4220 }, // ű
|
||||
{ 9, 15, 11, 1, 12, 17, 4233 }, // Ų
|
||||
{ 9, 12, 10, 1, 9, 14, 4250 }, // ų
|
||||
{ 14, 15, 15, 0, 15, 27, 4264 }, // Ŵ
|
||||
{ 13, 12, 13, 0, 12, 20, 4291 }, // ŵ
|
||||
{ 10, 15, 10, 0, 15, 19, 4311 }, // Ŷ
|
||||
{ 8, 16, 10, 1, 12, 16, 4330 }, // ŷ
|
||||
{ 10, 15, 10, 0, 15, 19, 4346 }, // Ÿ
|
||||
{ 9, 15, 10, 0, 15, 17, 4365 }, // Ź
|
||||
{ 7, 12, 9, 1, 12, 11, 4382 }, // ź
|
||||
{ 9, 15, 10, 0, 15, 17, 4393 }, // Ż
|
||||
{ 7, 12, 9, 1, 12, 11, 4410 }, // ż
|
||||
{ 9, 15, 10, 0, 15, 17, 4421 }, // Ž
|
||||
{ 7, 12, 9, 1, 12, 11, 4438 }, // ž
|
||||
{ 6, 12, 6, 0, 12, 9, 4449 }, // ſ
|
||||
{ 4, 3, 0, 0, 12, 2, 4458 }, // ̀
|
||||
{ 4, 3, 0, 0, 12, 2, 4460 }, // ́
|
||||
{ 7, 3, 0, 0, 12, 3, 4462 }, // ̂
|
||||
{ 7, 3, 0, 0, 12, 3, 4465 }, // ̃
|
||||
{ 7, 2, 0, 0, 11, 2, 4468 }, // ̄
|
||||
{ 6, 3, 0, 0, 12, 3, 4470 }, // ̆
|
||||
{ 3, 3, 0, 0, 12, 2, 4473 }, // ̇
|
||||
{ 7, 3, 0, 0, 12, 3, 4475 }, // ̈
|
||||
{ 5, 4, 0, 0, 13, 3, 4478 }, // ̉
|
||||
{ 5, 4, 0, 0, 13, 3, 4481 }, // ̊
|
||||
{ 6, 3, 0, 0, 12, 3, 4484 }, // ̋
|
||||
{ 7, 3, 0, 0, 12, 3, 4487 }, // ̌
|
||||
{ 6, 3, 0, 0, 12, 3, 4490 }, // ̏
|
||||
{ 6, 3, 0, 0, 12, 3, 4493 }, // ̑
|
||||
{ 3, 4, 0, 0, 13, 2, 4496 }, // ̒
|
||||
{ 4, 3, 0, 0, 10, 2, 4498 }, // ̛
|
||||
{ 3, 3, 0, 0, -1, 2, 4500 }, // ̣
|
||||
{ 7, 3, 0, 0, -1, 3, 4502 }, // ̤
|
||||
{ 3, 4, 0, 0, -1, 2, 4505 }, // ̦
|
||||
{ 5, 5, 0, 0, 1, 4, 4507 }, // ̧
|
||||
{ 4, 4, 0, 0, 1, 2, 4511 }, // ̨
|
||||
{ 6, 3, 0, 0, -1, 3, 4513 }, // ̮
|
||||
{ 7, 2, 0, 0, -1, 2, 4516 }, // ̱
|
||||
{ 7, 2, 0, 0, 11, 2, 4518 }, // ̵
|
||||
{ 12, 2, 0, 0, 10, 3, 4520 }, // ̶
|
||||
{ 8, 12, 0, 0, 10, 12, 4523 }, // ̷
|
||||
{ 8, 15, 0, 0, 13, 15, 4535 }, // ̸
|
||||
{ 0, 0, 10, 0, 0, 0, 4550 }, //
|
||||
{ 0, 0, 4, 0, 0, 0, 4550 }, //
|
||||
{ 0, 0, 3, 0, 0, 0, 4550 }, //
|
||||
{ 0, 0, 1, 0, 0, 0, 4550 }, //
|
||||
{ 0, 0, 0, 0, 0, 0, 4550 }, //
|
||||
{ 6, 2, 8, 1, 5, 2, 4550 }, // ‐
|
||||
{ 9, 2, 10, 1, 5, 3, 4552 }, // ‒
|
||||
{ 8, 2, 10, 1, 5, 2, 4555 }, // –
|
||||
{ 13, 2, 15, 1, 5, 4, 4557 }, // —
|
||||
{ 13, 2, 15, 1, 5, 4, 4561 }, // ―
|
||||
{ 4, 6, 4, 0, 13, 3, 4565 }, // ‘
|
||||
{ 4, 6, 4, 0, 13, 3, 4568 }, // ’
|
||||
{ 4, 6, 4, 0, 3, 3, 4571 }, // ‚
|
||||
{ 7, 6, 7, 0, 13, 6, 4574 }, // “
|
||||
{ 7, 6, 7, 0, 13, 6, 4580 }, // ”
|
||||
{ 7, 6, 7, 0, 3, 6, 4586 }, // „
|
||||
{ 8, 12, 10, 1, 12, 12, 4592 }, // †
|
||||
{ 8, 12, 10, 1, 12, 12, 4604 }, // ‡
|
||||
{ 4, 5, 6, 1, 7, 3, 4616 }, // •
|
||||
{ 11, 4, 11, 0, 3, 6, 4619 }, // …
|
||||
{ 16, 13, 16, 0, 12, 26, 4625 }, // ‰
|
||||
{ 3, 5, 3, 0, 12, 2, 4651 }, // ′
|
||||
{ 6, 5, 6, 0, 12, 4, 4653 }, // ″
|
||||
{ 7, 8, 8, 0, 8, 7, 4657 }, // ‹
|
||||
{ 6, 8, 8, 1, 8, 6, 4664 }, // ›
|
||||
{ 11, 13, 11, 0, 12, 18, 4670 }, // ⁄
|
||||
{ 11, 13, 12, 0, 12, 18, 4688 }, // ⁒
|
||||
{ 9, 16, 11, 1, 14, 18, 4706 }, // ₡
|
||||
{ 10, 12, 10, 0, 12, 15, 4724 }, // ₣
|
||||
{ 10, 12, 10, 0, 12, 15, 4739 }, // ₤
|
||||
{ 12, 12, 13, 0, 12, 18, 4754 }, // ₦
|
||||
{ 12, 12, 12, 0, 12, 18, 4772 }, // ₧
|
||||
{ 16, 12, 16, 0, 12, 24, 4790 }, // ₩
|
||||
{ 11, 14, 12, 0, 12, 20, 4814 }, // ₫
|
||||
{ 11, 13, 11, 0, 12, 18, 4834 }, // €
|
||||
{ 11, 12, 11, 0, 12, 17, 4852 }, // ₭
|
||||
{ 12, 12, 12, 0, 12, 18, 4869 }, // ₱
|
||||
{ 9, 16, 11, 1, 14, 18, 4887 }, // ₲
|
||||
{ 9, 16, 11, 1, 14, 18, 4905 }, // ₵
|
||||
{ 10, 12, 11, 1, 12, 15, 4923 }, // ₹
|
||||
{ 9, 12, 9, 0, 12, 14, 4938 }, // ₺
|
||||
{ 10, 14, 12, 1, 14, 18, 4952 }, // ₼
|
||||
{ 11, 12, 11, 0, 12, 17, 4970 }, // ₽
|
||||
{ 10, 16, 12, 1, 14, 20, 4987 }, // ₿
|
||||
{ 13, 10, 13, 0, 9, 17, 5007 }, // ←
|
||||
{ 10, 12, 10, 0, 12, 15, 5024 }, // ↑
|
||||
{ 13, 10, 13, 0, 9, 17, 5039 }, // →
|
||||
{ 10, 13, 10, 0, 12, 17, 5056 }, // ↓
|
||||
{ 13, 10, 13, 0, 9, 17, 5073 }, // ↔
|
||||
{ 10, 13, 10, 0, 12, 17, 5090 }, // ↕
|
||||
{ 9, 10, 10, 1, 9, 12, 5107 }, // ↖
|
||||
{ 9, 10, 10, 0, 9, 12, 5119 }, // ↗
|
||||
{ 9, 9, 10, 0, 9, 11, 5131 }, // ↘
|
||||
{ 9, 9, 10, 1, 9, 11, 5142 }, // ↙
|
||||
{ 9, 13, 10, 1, 12, 15, 5153 }, // ∂
|
||||
{ 10, 12, 11, 0, 10, 15, 5168 }, // ∅
|
||||
{ 10, 12, 10, 0, 12, 15, 5183 }, // ∆
|
||||
{ 9, 16, 10, 1, 12, 18, 5198 }, // ∏
|
||||
{ 10, 16, 10, 0, 12, 20, 5216 }, // ∑
|
||||
{ 8, 2, 10, 1, 7, 2, 5236 }, // −
|
||||
{ 7, 17, 6, 0, 14, 15, 5238 }, // ∕
|
||||
{ 5, 5, 10, 3, 8, 4, 5253 }, // ∙
|
||||
{ 10, 15, 10, 0, 15, 19, 5257 }, // √
|
||||
{ 10, 6, 10, 0, 9, 8, 5276 }, // ∞
|
||||
{ 6, 16, 10, 2, 12, 12, 5284 }, // ∫
|
||||
{ 8, 7, 10, 1, 9, 7, 5296 }, // ≈
|
||||
{ 8, 8, 10, 1, 10, 8, 5303 }, // ≠
|
||||
{ 8, 10, 10, 1, 10, 10, 5311 }, // ≤
|
||||
{ 8, 10, 10, 1, 10, 10, 5321 }, // ≥
|
||||
};
|
||||
|
||||
static const EpdUnicodeInterval spacegroteskIntervals[] = {
|
||||
{ 0xD, 0xD, 0x0 },
|
||||
{ 0x20, 0x7E, 0x1 },
|
||||
{ 0xA0, 0xFF, 0x60 },
|
||||
{ 0x100, 0x17F, 0xC0 },
|
||||
{ 0x300, 0x304, 0x140 },
|
||||
{ 0x306, 0x30C, 0x145 },
|
||||
{ 0x30F, 0x30F, 0x14C },
|
||||
{ 0x311, 0x312, 0x14D },
|
||||
{ 0x31B, 0x31B, 0x14F },
|
||||
{ 0x323, 0x324, 0x150 },
|
||||
{ 0x326, 0x328, 0x152 },
|
||||
{ 0x32E, 0x32E, 0x155 },
|
||||
{ 0x331, 0x331, 0x156 },
|
||||
{ 0x335, 0x338, 0x157 },
|
||||
{ 0x2007, 0x200B, 0x15B },
|
||||
{ 0x2010, 0x2010, 0x160 },
|
||||
{ 0x2012, 0x2015, 0x161 },
|
||||
{ 0x2018, 0x201A, 0x165 },
|
||||
{ 0x201C, 0x201E, 0x168 },
|
||||
{ 0x2020, 0x2022, 0x16B },
|
||||
{ 0x2026, 0x2026, 0x16E },
|
||||
{ 0x2030, 0x2030, 0x16F },
|
||||
{ 0x2032, 0x2033, 0x170 },
|
||||
{ 0x2039, 0x203A, 0x172 },
|
||||
{ 0x2044, 0x2044, 0x174 },
|
||||
{ 0x2052, 0x2052, 0x175 },
|
||||
{ 0x20A1, 0x20A1, 0x176 },
|
||||
{ 0x20A3, 0x20A4, 0x177 },
|
||||
{ 0x20A6, 0x20A7, 0x179 },
|
||||
{ 0x20A9, 0x20A9, 0x17B },
|
||||
{ 0x20AB, 0x20AD, 0x17C },
|
||||
{ 0x20B1, 0x20B2, 0x17F },
|
||||
{ 0x20B5, 0x20B5, 0x181 },
|
||||
{ 0x20B9, 0x20BA, 0x182 },
|
||||
{ 0x20BC, 0x20BD, 0x184 },
|
||||
{ 0x20BF, 0x20BF, 0x186 },
|
||||
{ 0x2190, 0x2199, 0x187 },
|
||||
{ 0x2202, 0x2202, 0x191 },
|
||||
{ 0x2205, 0x2206, 0x192 },
|
||||
{ 0x220F, 0x220F, 0x194 },
|
||||
{ 0x2211, 0x2212, 0x195 },
|
||||
{ 0x2215, 0x2215, 0x197 },
|
||||
{ 0x2219, 0x221A, 0x198 },
|
||||
{ 0x221E, 0x221E, 0x19A },
|
||||
{ 0x222B, 0x222B, 0x19B },
|
||||
{ 0x2248, 0x2248, 0x19C },
|
||||
{ 0x2260, 0x2260, 0x19D },
|
||||
{ 0x2264, 0x2265, 0x19E },
|
||||
};
|
||||
|
||||
static const EpdFontData spacegrotesk = {
|
||||
spacegroteskBitmaps,
|
||||
spacegroteskGlyphs,
|
||||
spacegroteskIntervals,
|
||||
48,
|
||||
21,
|
||||
17,
|
||||
-5,
|
||||
false,
|
||||
};
|
||||
@ -8,39 +8,39 @@ echo "// The contents of this file are generated by ./lib/EpdFont/scripts/build-
|
||||
echo "#pragma once"
|
||||
echo ""
|
||||
|
||||
echo "#define BOOKERLY_12_FONT_ID ($(
|
||||
echo "#define ALEO_12_FONT_ID ($(
|
||||
ruby -rdigest -e 'puts [
|
||||
"./bookerly_12_regular.h",
|
||||
"./bookerly_12_bold.h",
|
||||
"./bookerly_12_bolditalic.h",
|
||||
"./bookerly_12_italic.h",
|
||||
"./aleo_12_regular.h",
|
||||
"./aleo_12_bold.h",
|
||||
"./aleo_12_bolditalic.h",
|
||||
"./aleo_12_italic.h",
|
||||
].map{|f| Digest::SHA256.hexdigest(File.read(f)).to_i(16) }.sum % (2 ** 32) - (2 ** 31)'
|
||||
))"
|
||||
|
||||
echo "#define BOOKERLY_14_FONT_ID ($(
|
||||
echo "#define ALEO_14_FONT_ID ($(
|
||||
ruby -rdigest -e 'puts [
|
||||
"./bookerly_14_regular.h",
|
||||
"./bookerly_14_bold.h",
|
||||
"./bookerly_14_bolditalic.h",
|
||||
"./bookerly_14_italic.h",
|
||||
"./aleo_14_regular.h",
|
||||
"./aleo_14_bold.h",
|
||||
"./aleo_14_bolditalic.h",
|
||||
"./aleo_14_italic.h",
|
||||
].map{|f| Digest::SHA256.hexdigest(File.read(f)).to_i(16) }.sum % (2 ** 32) - (2 ** 31)'
|
||||
))"
|
||||
|
||||
echo "#define BOOKERLY_16_FONT_ID ($(
|
||||
echo "#define ALEO_16_FONT_ID ($(
|
||||
ruby -rdigest -e 'puts [
|
||||
"./bookerly_16_regular.h",
|
||||
"./bookerly_16_bold.h",
|
||||
"./bookerly_16_bolditalic.h",
|
||||
"./bookerly_16_italic.h",
|
||||
"./aleo_16_regular.h",
|
||||
"./aleo_16_bold.h",
|
||||
"./aleo_16_bolditalic.h",
|
||||
"./aleo_16_italic.h",
|
||||
].map{|f| Digest::SHA256.hexdigest(File.read(f)).to_i(16) }.sum % (2 ** 32) - (2 ** 31)'
|
||||
))"
|
||||
|
||||
echo "#define BOOKERLY_18_FONT_ID ($(
|
||||
echo "#define ALEO_18_FONT_ID ($(
|
||||
ruby -rdigest -e 'puts [
|
||||
"./bookerly_18_regular.h",
|
||||
"./bookerly_18_bold.h",
|
||||
"./bookerly_18_bolditalic.h",
|
||||
"./bookerly_18_italic.h",
|
||||
"./aleo_18_regular.h",
|
||||
"./aleo_18_bold.h",
|
||||
"./aleo_18_bolditalic.h",
|
||||
"./aleo_18_italic.h",
|
||||
].map{|f| Digest::SHA256.hexdigest(File.read(f)).to_i(16) }.sum % (2 ** 32) - (2 ** 31)'
|
||||
))"
|
||||
|
||||
@ -132,6 +132,6 @@ ruby -rdigest -e 'puts [
|
||||
|
||||
echo "#define SMALL_FONT_ID ($(
|
||||
ruby -rdigest -e 'puts [
|
||||
"./notosans_8_regular.h",
|
||||
"./spacegrotesk.h",
|
||||
].map{|f| Digest::SHA256.hexdigest(File.read(f)).to_i(16) }.sum % (2 ** 32) - (2 ** 31)'
|
||||
))"
|
||||
|
||||
@ -5,14 +5,14 @@ set -e
|
||||
cd "$(dirname "$0")"
|
||||
|
||||
READER_FONT_STYLES=("Regular" "Italic" "Bold" "BoldItalic")
|
||||
BOOKERLY_FONT_SIZES=(12 14 16 18)
|
||||
ALEO_FONT_SIZES=(12 14 16 18)
|
||||
NOTOSANS_FONT_SIZES=(12 14 16 18)
|
||||
OPENDYSLEXIC_FONT_SIZES=(8 10 12 14)
|
||||
|
||||
for size in ${BOOKERLY_FONT_SIZES[@]}; do
|
||||
for size in ${ALEO_FONT_SIZES[@]}; do
|
||||
for style in ${READER_FONT_STYLES[@]}; do
|
||||
font_name="bookerly_${size}_$(echo $style | tr '[:upper:]' '[:lower:]')"
|
||||
font_path="../builtinFonts/source/Bookerly/Bookerly-${style}.ttf"
|
||||
font_name="aleo_${size}_$(echo $style | tr '[:upper:]' '[:lower:]')"
|
||||
font_path="../builtinFonts/source/Aleo/Aleo-${style}.ttf"
|
||||
output_path="../builtinFonts/${font_name}.h"
|
||||
python fontconvert.py $font_name $size $font_path --2bit > $output_path
|
||||
echo "Generated $output_path"
|
||||
@ -52,4 +52,4 @@ for size in ${UI_FONT_SIZES[@]}; do
|
||||
done
|
||||
done
|
||||
|
||||
python fontconvert.py notosans_8_regular 8 ../builtinFonts/source/NotoSans/NotoSans-Regular.ttf > ../builtinFonts/notosans_8_regular.h
|
||||
python fontconvert.py spacegrotesk 8 ../builtinFonts/source/SpaceGrotesk/SpaceGrotesk-Regular.ttf > ../builtinFonts/spacegrotesk.h
|
||||
|
||||
@ -72,9 +72,9 @@ bool Epub::parseContentOpf(BookMetadataCache::BookMetadata& bookMetadata) {
|
||||
|
||||
// Grab data from opfParser into epub
|
||||
bookMetadata.title = opfParser.title;
|
||||
bookMetadata.author = opfParser.author;
|
||||
// TODO: Parse author
|
||||
bookMetadata.author = "";
|
||||
bookMetadata.coverItemHref = opfParser.coverItemHref;
|
||||
bookMetadata.textReferenceHref = opfParser.textReferenceHref;
|
||||
|
||||
if (!opfParser.tocNcxPath.empty()) {
|
||||
tocNcxItem = opfParser.tocNcxPath;
|
||||
@ -109,20 +109,17 @@ bool Epub::parseTocNcxFile() const {
|
||||
|
||||
if (!ncxParser.setup()) {
|
||||
Serial.printf("[%lu] [EBP] Could not setup toc ncx parser\n", millis());
|
||||
tempNcxFile.close();
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto ncxBuffer = static_cast<uint8_t*>(malloc(1024));
|
||||
if (!ncxBuffer) {
|
||||
Serial.printf("[%lu] [EBP] Could not allocate memory for toc ncx parser\n", millis());
|
||||
tempNcxFile.close();
|
||||
return false;
|
||||
}
|
||||
|
||||
while (tempNcxFile.available()) {
|
||||
const auto readSize = tempNcxFile.read(ncxBuffer, 1024);
|
||||
if (readSize == 0) break;
|
||||
const auto processedSize = ncxParser.write(ncxBuffer, readSize);
|
||||
|
||||
if (processedSize != readSize) {
|
||||
@ -142,7 +139,7 @@ bool Epub::parseTocNcxFile() const {
|
||||
}
|
||||
|
||||
// load in the meta data for the epub file
|
||||
bool Epub::load(const bool buildIfMissing) {
|
||||
bool Epub::load() {
|
||||
Serial.printf("[%lu] [EBP] Loading ePub: %s\n", millis(), filepath.c_str());
|
||||
|
||||
// Initialize spine/TOC cache
|
||||
@ -154,11 +151,6 @@ bool Epub::load(const bool buildIfMissing) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// If we didn't load from cache above and we aren't allowed to build, fail now
|
||||
if (!buildIfMissing) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Cache doesn't exist or is invalid, build it
|
||||
Serial.printf("[%lu] [EBP] Cache not found, building spine/TOC cache\n", millis());
|
||||
setupCacheDir();
|
||||
@ -261,15 +253,6 @@ const std::string& Epub::getTitle() const {
|
||||
return bookMetadataCache->coreMetadata.title;
|
||||
}
|
||||
|
||||
const std::string& Epub::getAuthor() const {
|
||||
static std::string blank;
|
||||
if (!bookMetadataCache || !bookMetadataCache->isLoaded()) {
|
||||
return blank;
|
||||
}
|
||||
|
||||
return bookMetadataCache->coreMetadata.author;
|
||||
}
|
||||
|
||||
std::string Epub::getCoverBmpPath() const { return cachePath + "/cover.bmp"; }
|
||||
|
||||
bool Epub::generateCoverBmp() const {
|
||||
@ -435,35 +418,6 @@ size_t Epub::getBookSize() const {
|
||||
return getCumulativeSpineItemSize(getSpineItemsCount() - 1);
|
||||
}
|
||||
|
||||
int Epub::getSpineIndexForTextReference() const {
|
||||
if (!bookMetadataCache || !bookMetadataCache->isLoaded()) {
|
||||
Serial.printf("[%lu] [EBP] getSpineIndexForTextReference called but cache not loaded\n", millis());
|
||||
return 0;
|
||||
}
|
||||
Serial.printf("[%lu] [ERS] Core Metadata: cover(%d)=%s, textReference(%d)=%s\n", millis(),
|
||||
bookMetadataCache->coreMetadata.coverItemHref.size(),
|
||||
bookMetadataCache->coreMetadata.coverItemHref.c_str(),
|
||||
bookMetadataCache->coreMetadata.textReferenceHref.size(),
|
||||
bookMetadataCache->coreMetadata.textReferenceHref.c_str());
|
||||
|
||||
if (bookMetadataCache->coreMetadata.textReferenceHref.empty()) {
|
||||
// there was no textReference in epub, so we return 0 (the first chapter)
|
||||
return 0;
|
||||
}
|
||||
|
||||
// loop through spine items to get the correct index matching the text href
|
||||
for (size_t i = 0; i < getSpineItemsCount(); i++) {
|
||||
if (getSpineItem(i).href == bookMetadataCache->coreMetadata.textReferenceHref) {
|
||||
Serial.printf("[%lu] [ERS] Text reference %s found at index %d\n", millis(),
|
||||
bookMetadataCache->coreMetadata.textReferenceHref.c_str(), i);
|
||||
return i;
|
||||
}
|
||||
}
|
||||
// This should not happen, as we checked for empty textReferenceHref earlier
|
||||
Serial.printf("[%lu] [EBP] Section not found for text reference\n", millis());
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Calculate progress in book
|
||||
uint8_t Epub::calculateProgress(const int currentSpineIndex, const float currentSpineRead) const {
|
||||
const size_t bookSize = getBookSize();
|
||||
|
||||
@ -34,13 +34,12 @@ class Epub {
|
||||
}
|
||||
~Epub() = default;
|
||||
std::string& getBasePath() { return contentBasePath; }
|
||||
bool load(bool buildIfMissing = true);
|
||||
bool load();
|
||||
bool clearCache() const;
|
||||
void setupCacheDir() const;
|
||||
const std::string& getCachePath() const;
|
||||
const std::string& getPath() const;
|
||||
const std::string& getTitle() const;
|
||||
const std::string& getAuthor() const;
|
||||
std::string getCoverBmpPath() const;
|
||||
bool generateCoverBmp() const;
|
||||
uint8_t* readItemContentsToBytes(const std::string& itemHref, size_t* size = nullptr,
|
||||
@ -54,7 +53,6 @@ class Epub {
|
||||
int getSpineIndexForTocIndex(int tocIndex) const;
|
||||
int getTocIndexForSpineIndex(int spineIndex) const;
|
||||
size_t getCumulativeSpineItemSize(int spineIndex) const;
|
||||
int getSpineIndexForTextReference() const;
|
||||
|
||||
size_t getBookSize() const;
|
||||
uint8_t calculateProgress(int currentSpineIndex, float currentSpineRead) const;
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
#include "FsHelpers.h"
|
||||
|
||||
namespace {
|
||||
constexpr uint8_t BOOK_CACHE_VERSION = 3;
|
||||
constexpr uint8_t BOOK_CACHE_VERSION = 2;
|
||||
constexpr char bookBinFile[] = "/book.bin";
|
||||
constexpr char tmpSpineBinFile[] = "/spine.bin.tmp";
|
||||
constexpr char tmpTocBinFile[] = "/toc.bin.tmp";
|
||||
@ -87,8 +87,8 @@ bool BookMetadataCache::buildBookBin(const std::string& epubPath, const BookMeta
|
||||
|
||||
constexpr uint32_t headerASize =
|
||||
sizeof(BOOK_CACHE_VERSION) + /* LUT Offset */ sizeof(uint32_t) + sizeof(spineCount) + sizeof(tocCount);
|
||||
const uint32_t metadataSize = metadata.title.size() + metadata.author.size() + metadata.coverItemHref.size() +
|
||||
metadata.textReferenceHref.size() + sizeof(uint32_t) * 4;
|
||||
const uint32_t metadataSize =
|
||||
metadata.title.size() + metadata.author.size() + metadata.coverItemHref.size() + sizeof(uint32_t) * 3;
|
||||
const uint32_t lutSize = sizeof(uint32_t) * spineCount + sizeof(uint32_t) * tocCount;
|
||||
const uint32_t lutOffset = headerASize + metadataSize;
|
||||
|
||||
@ -101,7 +101,6 @@ bool BookMetadataCache::buildBookBin(const std::string& epubPath, const BookMeta
|
||||
serialization::writeString(bookFile, metadata.title);
|
||||
serialization::writeString(bookFile, metadata.author);
|
||||
serialization::writeString(bookFile, metadata.coverItemHref);
|
||||
serialization::writeString(bookFile, metadata.textReferenceHref);
|
||||
|
||||
// Loop through spine entries, writing LUT positions
|
||||
spineFile.seek(0);
|
||||
@ -290,7 +289,6 @@ bool BookMetadataCache::load() {
|
||||
serialization::readString(bookFile, coreMetadata.title);
|
||||
serialization::readString(bookFile, coreMetadata.author);
|
||||
serialization::readString(bookFile, coreMetadata.coverItemHref);
|
||||
serialization::readString(bookFile, coreMetadata.textReferenceHref);
|
||||
|
||||
loaded = true;
|
||||
Serial.printf("[%lu] [BMC] Loaded cache data: %d spine, %d TOC entries\n", millis(), spineCount, tocCount);
|
||||
|
||||
@ -10,7 +10,6 @@ class BookMetadataCache {
|
||||
std::string title;
|
||||
std::string author;
|
||||
std::string coverItemHref;
|
||||
std::string textReferenceHref;
|
||||
};
|
||||
|
||||
struct SpineEntry {
|
||||
|
||||
@ -57,6 +57,7 @@ void ChapterHtmlSlimParser::startNewTextBlock(const TextBlock::BLOCK_STYLE style
|
||||
|
||||
void XMLCALL ChapterHtmlSlimParser::startElement(void* userData, const XML_Char* name, const XML_Char** atts) {
|
||||
auto* self = static_cast<ChapterHtmlSlimParser*>(userData);
|
||||
(void)atts;
|
||||
|
||||
// Middle of skip
|
||||
if (self->skipUntilDepth < self->depth) {
|
||||
@ -92,7 +93,7 @@ void XMLCALL ChapterHtmlSlimParser::startElement(void* userData, const XML_Char*
|
||||
|
||||
if (matches(name, HEADER_TAGS, NUM_HEADER_TAGS)) {
|
||||
self->startNewTextBlock(TextBlock::CENTER_ALIGN);
|
||||
self->boldUntilDepth = std::min(self->boldUntilDepth, self->depth);
|
||||
self->boldUntilDepth = min(self->boldUntilDepth, self->depth);
|
||||
} else if (matches(name, BLOCK_TAGS, NUM_BLOCK_TAGS)) {
|
||||
if (strcmp(name, "br") == 0) {
|
||||
self->startNewTextBlock(self->currentTextBlock->getStyle());
|
||||
@ -100,9 +101,9 @@ void XMLCALL ChapterHtmlSlimParser::startElement(void* userData, const XML_Char*
|
||||
self->startNewTextBlock(TextBlock::JUSTIFIED);
|
||||
}
|
||||
} else if (matches(name, BOLD_TAGS, NUM_BOLD_TAGS)) {
|
||||
self->boldUntilDepth = std::min(self->boldUntilDepth, self->depth);
|
||||
self->boldUntilDepth = min(self->boldUntilDepth, self->depth);
|
||||
} else if (matches(name, ITALIC_TAGS, NUM_ITALIC_TAGS)) {
|
||||
self->italicUntilDepth = std::min(self->italicUntilDepth, self->depth);
|
||||
self->italicUntilDepth = min(self->italicUntilDepth, self->depth);
|
||||
}
|
||||
|
||||
self->depth += 1;
|
||||
@ -161,6 +162,7 @@ void XMLCALL ChapterHtmlSlimParser::characterData(void* userData, const XML_Char
|
||||
|
||||
void XMLCALL ChapterHtmlSlimParser::endElement(void* userData, const XML_Char* name) {
|
||||
auto* self = static_cast<ChapterHtmlSlimParser*>(userData);
|
||||
(void)name;
|
||||
|
||||
if (self->partWordBufferIndex > 0) {
|
||||
// Only flush out part word buffer if we're closing a block tag or are at the top of the HTML file.
|
||||
@ -243,9 +245,9 @@ bool ChapterHtmlSlimParser::parseAndBuildPages() {
|
||||
return false;
|
||||
}
|
||||
|
||||
const size_t len = file.read(buf, 1024);
|
||||
const size_t len = file.read(static_cast<uint8_t*>(buf), 1024);
|
||||
|
||||
if (len == 0 && file.available() > 0) {
|
||||
if (len == 0) {
|
||||
Serial.printf("[%lu] [EHP] File read error\n", millis());
|
||||
XML_StopParser(parser, XML_FALSE); // Stop any pending processing
|
||||
XML_SetElementHandler(parser, nullptr, nullptr); // Clear callbacks
|
||||
|
||||
@ -102,11 +102,6 @@ void XMLCALL ContentOpfParser::startElement(void* userData, const XML_Char* name
|
||||
return;
|
||||
}
|
||||
|
||||
if (self->state == IN_METADATA && strcmp(name, "dc:creator") == 0) {
|
||||
self->state = IN_BOOK_AUTHOR;
|
||||
return;
|
||||
}
|
||||
|
||||
if (self->state == IN_PACKAGE && (strcmp(name, "manifest") == 0 || strcmp(name, "opf:manifest") == 0)) {
|
||||
self->state = IN_MANIFEST;
|
||||
if (!SdMan.openFileForWrite("COF", self->cachePath + itemCacheFile, self->tempItemStore)) {
|
||||
@ -127,18 +122,6 @@ void XMLCALL ContentOpfParser::startElement(void* userData, const XML_Char* name
|
||||
return;
|
||||
}
|
||||
|
||||
if (self->state == IN_PACKAGE && (strcmp(name, "guide") == 0 || strcmp(name, "opf:guide") == 0)) {
|
||||
self->state = IN_GUIDE;
|
||||
// TODO Remove print
|
||||
Serial.printf("[%lu] [COF] Entering guide state.\n", millis());
|
||||
if (!SdMan.openFileForRead("COF", self->cachePath + itemCacheFile, self->tempItemStore)) {
|
||||
Serial.printf(
|
||||
"[%lu] [COF] Couldn't open temp items file for reading. This is probably going to be a fatal error.\n",
|
||||
millis());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (self->state == IN_METADATA && (strcmp(name, "meta") == 0 || strcmp(name, "opf:meta") == 0)) {
|
||||
bool isCover = false;
|
||||
std::string coverItemId;
|
||||
@ -217,29 +200,6 @@ void XMLCALL ContentOpfParser::startElement(void* userData, const XML_Char* name
|
||||
return;
|
||||
}
|
||||
}
|
||||
// parse the guide
|
||||
if (self->state == IN_GUIDE && (strcmp(name, "reference") == 0 || strcmp(name, "opf:reference") == 0)) {
|
||||
std::string type;
|
||||
std::string textHref;
|
||||
for (int i = 0; atts[i]; i += 2) {
|
||||
if (strcmp(atts[i], "type") == 0) {
|
||||
type = atts[i + 1];
|
||||
if (type == "text" || type == "start") {
|
||||
continue;
|
||||
} else {
|
||||
Serial.printf("[%lu] [COF] Skipping non-text reference in guide: %s\n", millis(), type.c_str());
|
||||
break;
|
||||
}
|
||||
} else if (strcmp(atts[i], "href") == 0) {
|
||||
textHref = self->baseContentPath + atts[i + 1];
|
||||
}
|
||||
}
|
||||
if ((type == "text" || (type == "start" && !self->textReferenceHref.empty())) && (textHref.length() > 0)) {
|
||||
Serial.printf("[%lu] [COF] Found %s reference in guide: %s.\n", millis(), type.c_str(), textHref.c_str());
|
||||
self->textReferenceHref = textHref;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void XMLCALL ContentOpfParser::characterData(void* userData, const XML_Char* s, const int len) {
|
||||
@ -249,11 +209,6 @@ void XMLCALL ContentOpfParser::characterData(void* userData, const XML_Char* s,
|
||||
self->title.append(s, len);
|
||||
return;
|
||||
}
|
||||
|
||||
if (self->state == IN_BOOK_AUTHOR) {
|
||||
self->author.append(s, len);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void XMLCALL ContentOpfParser::endElement(void* userData, const XML_Char* name) {
|
||||
@ -266,12 +221,6 @@ void XMLCALL ContentOpfParser::endElement(void* userData, const XML_Char* name)
|
||||
return;
|
||||
}
|
||||
|
||||
if (self->state == IN_GUIDE && (strcmp(name, "guide") == 0 || strcmp(name, "opf:guide") == 0)) {
|
||||
self->state = IN_PACKAGE;
|
||||
self->tempItemStore.close();
|
||||
return;
|
||||
}
|
||||
|
||||
if (self->state == IN_MANIFEST && (strcmp(name, "manifest") == 0 || strcmp(name, "opf:manifest") == 0)) {
|
||||
self->state = IN_PACKAGE;
|
||||
self->tempItemStore.close();
|
||||
@ -283,11 +232,6 @@ void XMLCALL ContentOpfParser::endElement(void* userData, const XML_Char* name)
|
||||
return;
|
||||
}
|
||||
|
||||
if (self->state == IN_BOOK_AUTHOR && strcmp(name, "dc:creator") == 0) {
|
||||
self->state = IN_METADATA;
|
||||
return;
|
||||
}
|
||||
|
||||
if (self->state == IN_METADATA && (strcmp(name, "metadata") == 0 || strcmp(name, "opf:metadata") == 0)) {
|
||||
self->state = IN_PACKAGE;
|
||||
return;
|
||||
|
||||
@ -12,10 +12,8 @@ class ContentOpfParser final : public Print {
|
||||
IN_PACKAGE,
|
||||
IN_METADATA,
|
||||
IN_BOOK_TITLE,
|
||||
IN_BOOK_AUTHOR,
|
||||
IN_MANIFEST,
|
||||
IN_SPINE,
|
||||
IN_GUIDE,
|
||||
};
|
||||
|
||||
const std::string& cachePath;
|
||||
@ -33,10 +31,8 @@ class ContentOpfParser final : public Print {
|
||||
|
||||
public:
|
||||
std::string title;
|
||||
std::string author;
|
||||
std::string tocNcxPath;
|
||||
std::string coverItemHref;
|
||||
std::string textReferenceHref;
|
||||
|
||||
explicit ContentOpfParser(const std::string& cachePath, const std::string& baseContentPath, const size_t xmlSize,
|
||||
BookMetadataCache* cache)
|
||||
|
||||
@ -37,7 +37,7 @@ class GfxRenderer {
|
||||
|
||||
public:
|
||||
explicit GfxRenderer(EInkDisplay& einkDisplay) : einkDisplay(einkDisplay), renderMode(BW), orientation(Portrait) {}
|
||||
~GfxRenderer() { freeBwBufferChunks(); }
|
||||
~GfxRenderer() = default;
|
||||
|
||||
static constexpr int VIEWABLE_MARGIN_TOP = 9;
|
||||
static constexpr int VIEWABLE_MARGIN_RIGHT = 3;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
[platformio]
|
||||
crosspoint_version = 0.11.1
|
||||
crosspoint_version = 0.10.0
|
||||
default_envs = default
|
||||
|
||||
[base]
|
||||
|
||||
@ -92,7 +92,7 @@ bool CrossPointSettings::loadFromFile() {
|
||||
|
||||
float CrossPointSettings::getReaderLineCompression() const {
|
||||
switch (fontFamily) {
|
||||
case BOOKERLY:
|
||||
case ALEO:
|
||||
default:
|
||||
switch (lineSpacing) {
|
||||
case TIGHT:
|
||||
@ -128,18 +128,18 @@ float CrossPointSettings::getReaderLineCompression() const {
|
||||
|
||||
int CrossPointSettings::getReaderFontId() const {
|
||||
switch (fontFamily) {
|
||||
case BOOKERLY:
|
||||
case ALEO:
|
||||
default:
|
||||
switch (fontSize) {
|
||||
case SMALL:
|
||||
return BOOKERLY_12_FONT_ID;
|
||||
return ALEO_12_FONT_ID;
|
||||
case MEDIUM:
|
||||
default:
|
||||
return BOOKERLY_14_FONT_ID;
|
||||
return ALEO_14_FONT_ID;
|
||||
case LARGE:
|
||||
return BOOKERLY_16_FONT_ID;
|
||||
return ALEO_16_FONT_ID;
|
||||
case EXTRA_LARGE:
|
||||
return BOOKERLY_18_FONT_ID;
|
||||
return ALEO_18_FONT_ID;
|
||||
}
|
||||
case NOTOSANS:
|
||||
switch (fontSize) {
|
||||
|
||||
@ -31,7 +31,7 @@ class CrossPointSettings {
|
||||
// Front button layout options
|
||||
// Default: Back, Confirm, Left, Right
|
||||
// Swapped: Left, Right, Back, Confirm
|
||||
enum FRONT_BUTTON_LAYOUT { BACK_CONFIRM_LEFT_RIGHT = 0, LEFT_RIGHT_BACK_CONFIRM = 1, LEFT_BACK_CONFIRM_RIGHT = 2 };
|
||||
enum FRONT_BUTTON_LAYOUT { BACK_CONFIRM_LEFT_RIGHT = 0, LEFT_RIGHT_BACK_CONFIRM = 1 };
|
||||
|
||||
// Side button layout options
|
||||
// Default: Previous, Next
|
||||
@ -39,7 +39,7 @@ class CrossPointSettings {
|
||||
enum SIDE_BUTTON_LAYOUT { PREV_NEXT = 0, NEXT_PREV = 1 };
|
||||
|
||||
// Font family options
|
||||
enum FONT_FAMILY { BOOKERLY = 0, NOTOSANS = 1, OPENDYSLEXIC = 2 };
|
||||
enum FONT_FAMILY { ALEO = 0, NOTOSANS = 1, OPENDYSLEXIC = 2 };
|
||||
// Font size options
|
||||
enum FONT_SIZE { SMALL = 0, MEDIUM = 1, LARGE = 2, EXTRA_LARGE = 3 };
|
||||
enum LINE_COMPRESSION { TIGHT = 0, NORMAL = 1, WIDE = 2 };
|
||||
@ -59,7 +59,7 @@ class CrossPointSettings {
|
||||
uint8_t frontButtonLayout = BACK_CONFIRM_LEFT_RIGHT;
|
||||
uint8_t sideButtonLayout = PREV_NEXT;
|
||||
// Reader font settings
|
||||
uint8_t fontFamily = BOOKERLY;
|
||||
uint8_t fontFamily = ALEO;
|
||||
uint8_t fontSize = MEDIUM;
|
||||
uint8_t lineSpacing = NORMAL;
|
||||
|
||||
|
||||
@ -11,8 +11,6 @@ decltype(InputManager::BTN_BACK) MappedInputManager::mapButton(const Button butt
|
||||
switch (frontLayout) {
|
||||
case CrossPointSettings::LEFT_RIGHT_BACK_CONFIRM:
|
||||
return InputManager::BTN_LEFT;
|
||||
case CrossPointSettings::LEFT_BACK_CONFIRM_RIGHT:
|
||||
return InputManager::BTN_CONFIRM;
|
||||
case CrossPointSettings::BACK_CONFIRM_LEFT_RIGHT:
|
||||
default:
|
||||
return InputManager::BTN_BACK;
|
||||
@ -21,8 +19,6 @@ decltype(InputManager::BTN_BACK) MappedInputManager::mapButton(const Button butt
|
||||
switch (frontLayout) {
|
||||
case CrossPointSettings::LEFT_RIGHT_BACK_CONFIRM:
|
||||
return InputManager::BTN_RIGHT;
|
||||
case CrossPointSettings::LEFT_BACK_CONFIRM_RIGHT:
|
||||
return InputManager::BTN_LEFT;
|
||||
case CrossPointSettings::BACK_CONFIRM_LEFT_RIGHT:
|
||||
default:
|
||||
return InputManager::BTN_CONFIRM;
|
||||
@ -30,7 +26,6 @@ decltype(InputManager::BTN_BACK) MappedInputManager::mapButton(const Button butt
|
||||
case Button::Left:
|
||||
switch (frontLayout) {
|
||||
case CrossPointSettings::LEFT_RIGHT_BACK_CONFIRM:
|
||||
case CrossPointSettings::LEFT_BACK_CONFIRM_RIGHT:
|
||||
return InputManager::BTN_BACK;
|
||||
case CrossPointSettings::BACK_CONFIRM_LEFT_RIGHT:
|
||||
default:
|
||||
@ -41,7 +36,6 @@ decltype(InputManager::BTN_BACK) MappedInputManager::mapButton(const Button butt
|
||||
case CrossPointSettings::LEFT_RIGHT_BACK_CONFIRM:
|
||||
return InputManager::BTN_CONFIRM;
|
||||
case CrossPointSettings::BACK_CONFIRM_LEFT_RIGHT:
|
||||
case CrossPointSettings::LEFT_BACK_CONFIRM_RIGHT:
|
||||
default:
|
||||
return InputManager::BTN_RIGHT;
|
||||
}
|
||||
@ -91,8 +85,6 @@ MappedInputManager::Labels MappedInputManager::mapLabels(const char* back, const
|
||||
switch (layout) {
|
||||
case CrossPointSettings::LEFT_RIGHT_BACK_CONFIRM:
|
||||
return {previous, next, back, confirm};
|
||||
case CrossPointSettings::LEFT_BACK_CONFIRM_RIGHT:
|
||||
return {previous, back, confirm, next};
|
||||
case CrossPointSettings::BACK_CONFIRM_LEFT_RIGHT:
|
||||
default:
|
||||
return {back, confirm, previous, next};
|
||||
|
||||
@ -1,41 +0,0 @@
|
||||
#include "ScreenComponents.h"
|
||||
|
||||
#include <GfxRenderer.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "Battery.h"
|
||||
#include "fontIds.h"
|
||||
|
||||
void ScreenComponents::drawBattery(const GfxRenderer& renderer, const int left, const int top) {
|
||||
// Left aligned battery icon and percentage
|
||||
const uint16_t percentage = battery.readPercentage();
|
||||
const auto percentageText = std::to_string(percentage) + "%";
|
||||
renderer.drawText(SMALL_FONT_ID, left + 20, top, percentageText.c_str());
|
||||
|
||||
// 1 column on left, 2 columns on right, 5 columns of battery body
|
||||
constexpr int batteryWidth = 15;
|
||||
constexpr int batteryHeight = 10;
|
||||
const int x = left;
|
||||
const int y = top + 8;
|
||||
|
||||
// Top line
|
||||
renderer.drawLine(x, y, x + batteryWidth - 4, y);
|
||||
// Bottom line
|
||||
renderer.drawLine(x, y + batteryHeight - 1, x + batteryWidth - 4, y + batteryHeight - 1);
|
||||
// Left line
|
||||
renderer.drawLine(x, y, x, y + batteryHeight - 1);
|
||||
// Battery end
|
||||
renderer.drawLine(x + batteryWidth - 4, y, x + batteryWidth - 4, y + batteryHeight - 1);
|
||||
renderer.drawLine(x + batteryWidth - 3, y + 2, x + batteryWidth - 1, y + 2);
|
||||
renderer.drawLine(x + batteryWidth - 3, y + batteryHeight - 3, x + batteryWidth - 1, y + batteryHeight - 3);
|
||||
renderer.drawLine(x + batteryWidth - 1, y + 2, x + batteryWidth - 1, y + batteryHeight - 3);
|
||||
|
||||
// The +1 is to round up, so that we always fill at least one pixel
|
||||
int filledWidth = percentage * (batteryWidth - 5) / 100 + 1;
|
||||
if (filledWidth > batteryWidth - 5) {
|
||||
filledWidth = batteryWidth - 5; // Ensure we don't overflow
|
||||
}
|
||||
|
||||
renderer.fillRect(x + 1, y + 1, filledWidth, batteryHeight - 2);
|
||||
}
|
||||
@ -1,8 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
class GfxRenderer;
|
||||
|
||||
class ScreenComponents {
|
||||
public:
|
||||
static void drawBattery(const GfxRenderer& renderer, int left, int top);
|
||||
};
|
||||
@ -1,12 +1,10 @@
|
||||
#include "HomeActivity.h"
|
||||
|
||||
#include <Epub.h>
|
||||
#include <GfxRenderer.h>
|
||||
#include <SDCardManager.h>
|
||||
|
||||
#include "CrossPointState.h"
|
||||
#include "MappedInputManager.h"
|
||||
#include "ScreenComponents.h"
|
||||
#include "fontIds.h"
|
||||
|
||||
void HomeActivity::taskTrampoline(void* param) {
|
||||
@ -24,33 +22,6 @@ void HomeActivity::onEnter() {
|
||||
// Check if we have a book to continue reading
|
||||
hasContinueReading = !APP_STATE.openEpubPath.empty() && SdMan.exists(APP_STATE.openEpubPath.c_str());
|
||||
|
||||
if (hasContinueReading) {
|
||||
// Extract filename from path for display
|
||||
lastBookTitle = APP_STATE.openEpubPath;
|
||||
const size_t lastSlash = lastBookTitle.find_last_of('/');
|
||||
if (lastSlash != std::string::npos) {
|
||||
lastBookTitle = lastBookTitle.substr(lastSlash + 1);
|
||||
}
|
||||
|
||||
const std::string ext4 = lastBookTitle.length() >= 4 ? lastBookTitle.substr(lastBookTitle.length() - 4) : "";
|
||||
const std::string ext5 = lastBookTitle.length() >= 5 ? lastBookTitle.substr(lastBookTitle.length() - 5) : "";
|
||||
// If epub, try to load the metadata for title/author
|
||||
if (ext5 == ".epub") {
|
||||
Epub epub(APP_STATE.openEpubPath, "/.crosspoint");
|
||||
epub.load(false);
|
||||
if (!epub.getTitle().empty()) {
|
||||
lastBookTitle = std::string(epub.getTitle());
|
||||
}
|
||||
if (!epub.getAuthor().empty()) {
|
||||
lastBookAuthor = std::string(epub.getAuthor());
|
||||
}
|
||||
} else if (ext5 == ".xtch") {
|
||||
lastBookTitle.resize(lastBookTitle.length() - 5);
|
||||
} else if (ext4 == ".xtc") {
|
||||
lastBookTitle.resize(lastBookTitle.length() - 4);
|
||||
}
|
||||
}
|
||||
|
||||
selectorIndex = 0;
|
||||
|
||||
// Trigger first update
|
||||
@ -132,191 +103,52 @@ void HomeActivity::render() const {
|
||||
renderer.clearScreen();
|
||||
|
||||
const auto pageWidth = renderer.getScreenWidth();
|
||||
const auto pageHeight = renderer.getScreenHeight();
|
||||
renderer.drawCenteredText(UI_12_FONT_ID, 10, "CrossPoint Reader", true, BOLD);
|
||||
|
||||
constexpr int margin = 20;
|
||||
constexpr int bottomMargin = 60;
|
||||
// Draw selection
|
||||
renderer.fillRect(0, 60 + selectorIndex * 30 - 2, pageWidth - 1, 30);
|
||||
|
||||
// --- Top "book" card for the current title (selectorIndex == 0) ---
|
||||
const int bookWidth = pageWidth / 2;
|
||||
const int bookHeight = pageHeight / 2;
|
||||
const int bookX = (pageWidth - bookWidth) / 2;
|
||||
constexpr int bookY = 30;
|
||||
const bool bookSelected = hasContinueReading && selectorIndex == 0;
|
||||
|
||||
// Draw book card regardless, fill with message based on `hasContinueReading`
|
||||
{
|
||||
if (bookSelected) {
|
||||
renderer.fillRect(bookX, bookY, bookWidth, bookHeight);
|
||||
} else {
|
||||
renderer.drawRect(bookX, bookY, bookWidth, bookHeight);
|
||||
}
|
||||
|
||||
// Bookmark icon in the top-right corner of the card
|
||||
const int bookmarkWidth = bookWidth / 8;
|
||||
const int bookmarkHeight = bookHeight / 5;
|
||||
const int bookmarkX = bookX + bookWidth - bookmarkWidth - 8;
|
||||
constexpr int bookmarkY = bookY + 1;
|
||||
|
||||
// Main bookmark body (solid)
|
||||
renderer.fillRect(bookmarkX, bookmarkY, bookmarkWidth, bookmarkHeight, !bookSelected);
|
||||
|
||||
// Carve out an inverted triangle notch at the bottom center to create angled points
|
||||
const int notchHeight = bookmarkHeight / 2; // depth of the notch
|
||||
for (int i = 0; i < notchHeight; ++i) {
|
||||
const int y = bookmarkY + bookmarkHeight - 1 - i;
|
||||
const int xStart = bookmarkX + i;
|
||||
const int width = bookmarkWidth - 2 * i;
|
||||
if (width <= 0) {
|
||||
break;
|
||||
}
|
||||
// Draw a horizontal strip in the opposite color to "cut" the notch
|
||||
renderer.fillRect(xStart, y, width, 1, bookSelected);
|
||||
}
|
||||
}
|
||||
int menuY = 60;
|
||||
int menuIndex = 0;
|
||||
|
||||
if (hasContinueReading) {
|
||||
// Split into words (avoid stringstream to keep this light on the MCU)
|
||||
std::vector<std::string> words;
|
||||
words.reserve(8);
|
||||
size_t pos = 0;
|
||||
while (pos < lastBookTitle.size()) {
|
||||
while (pos < lastBookTitle.size() && lastBookTitle[pos] == ' ') {
|
||||
++pos;
|
||||
}
|
||||
if (pos >= lastBookTitle.size()) {
|
||||
break;
|
||||
}
|
||||
const size_t start = pos;
|
||||
while (pos < lastBookTitle.size() && lastBookTitle[pos] != ' ') {
|
||||
++pos;
|
||||
}
|
||||
words.emplace_back(lastBookTitle.substr(start, pos - start));
|
||||
// Extract filename from path for display
|
||||
std::string bookName = APP_STATE.openEpubPath;
|
||||
const size_t lastSlash = bookName.find_last_of('/');
|
||||
if (lastSlash != std::string::npos) {
|
||||
bookName = bookName.substr(lastSlash + 1);
|
||||
}
|
||||
// Remove .epub extension
|
||||
if (bookName.length() > 5 && bookName.substr(bookName.length() - 5) == ".epub") {
|
||||
bookName.resize(bookName.length() - 5);
|
||||
}
|
||||
|
||||
std::vector<std::string> lines;
|
||||
std::string currentLine;
|
||||
// Extra padding inside the card so text doesn't hug the border
|
||||
const int maxLineWidth = bookWidth - 40;
|
||||
const int spaceWidth = renderer.getSpaceWidth(UI_12_FONT_ID);
|
||||
|
||||
for (auto& i : words) {
|
||||
// If we just hit the line limit (3), stop processing words
|
||||
if (lines.size() >= 3) {
|
||||
// Limit to 3 lines
|
||||
// Still have words left, so add ellipsis to last line
|
||||
lines.back().append("...");
|
||||
|
||||
while (!lines.back().empty() && renderer.getTextWidth(UI_12_FONT_ID, lines.back().c_str()) > maxLineWidth) {
|
||||
lines.back().resize(lines.back().size() - 5);
|
||||
lines.back().append("...");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
int wordWidth = renderer.getTextWidth(UI_12_FONT_ID, i.c_str());
|
||||
while (wordWidth > maxLineWidth && i.size() > 5) {
|
||||
// Word itself is too long, trim it
|
||||
i.resize(i.size() - 5);
|
||||
i.append("...");
|
||||
wordWidth = renderer.getTextWidth(UI_12_FONT_ID, i.c_str());
|
||||
}
|
||||
|
||||
int newLineWidth = renderer.getTextWidth(UI_12_FONT_ID, currentLine.c_str());
|
||||
if (newLineWidth > 0) {
|
||||
newLineWidth += spaceWidth;
|
||||
}
|
||||
newLineWidth += wordWidth;
|
||||
|
||||
if (newLineWidth > maxLineWidth && !currentLine.empty()) {
|
||||
// New line too long, push old line
|
||||
lines.push_back(currentLine);
|
||||
currentLine = i;
|
||||
} else {
|
||||
currentLine.append(" ").append(i);
|
||||
}
|
||||
// Truncate if too long
|
||||
std::string continueLabel = "Continue: " + bookName;
|
||||
int itemWidth = renderer.getTextWidth(UI_10_FONT_ID, continueLabel.c_str());
|
||||
while (itemWidth > renderer.getScreenWidth() - 40 && continueLabel.length() > 8) {
|
||||
continueLabel.replace(continueLabel.length() - 5, 5, "...");
|
||||
itemWidth = renderer.getTextWidth(UI_10_FONT_ID, continueLabel.c_str());
|
||||
Serial.printf("[%lu] [HOM] width: %lu, pageWidth: %lu\n", millis(), itemWidth, pageWidth);
|
||||
}
|
||||
|
||||
// If lower than the line limit, push remaining words
|
||||
if (!currentLine.empty() && lines.size() < 3) {
|
||||
lines.push_back(currentLine);
|
||||
}
|
||||
|
||||
// Book title text
|
||||
int totalTextHeight = renderer.getLineHeight(UI_12_FONT_ID) * static_cast<int>(lines.size());
|
||||
if (!lastBookAuthor.empty()) {
|
||||
totalTextHeight += renderer.getLineHeight(UI_10_FONT_ID) * 3 / 2;
|
||||
}
|
||||
|
||||
// Vertically center the title block within the card
|
||||
int titleYStart = bookY + (bookHeight - totalTextHeight) / 2;
|
||||
|
||||
for (const auto& line : lines) {
|
||||
renderer.drawCenteredText(UI_12_FONT_ID, titleYStart, line.c_str(), !bookSelected);
|
||||
titleYStart += renderer.getLineHeight(UI_12_FONT_ID);
|
||||
}
|
||||
|
||||
if (!lastBookAuthor.empty()) {
|
||||
titleYStart += renderer.getLineHeight(UI_10_FONT_ID) / 2;
|
||||
std::string trimmedAuthor = lastBookAuthor;
|
||||
// Trim author if too long
|
||||
while (renderer.getTextWidth(UI_10_FONT_ID, trimmedAuthor.c_str()) > maxLineWidth && !trimmedAuthor.empty()) {
|
||||
trimmedAuthor.resize(trimmedAuthor.size() - 5);
|
||||
trimmedAuthor.append("...");
|
||||
}
|
||||
renderer.drawCenteredText(UI_10_FONT_ID, titleYStart, trimmedAuthor.c_str(), !bookSelected);
|
||||
}
|
||||
|
||||
renderer.drawCenteredText(UI_10_FONT_ID, bookY + bookHeight - renderer.getLineHeight(UI_10_FONT_ID) * 3 / 2,
|
||||
"Continue Reading", !bookSelected);
|
||||
} else {
|
||||
// No book to continue reading
|
||||
const int y =
|
||||
bookY + (bookHeight - renderer.getLineHeight(UI_12_FONT_ID) - renderer.getLineHeight(UI_10_FONT_ID)) / 2;
|
||||
renderer.drawCenteredText(UI_12_FONT_ID, y, "No open book");
|
||||
renderer.drawCenteredText(UI_10_FONT_ID, y + renderer.getLineHeight(UI_12_FONT_ID), "Start reading below");
|
||||
renderer.drawText(UI_10_FONT_ID, 20, menuY, continueLabel.c_str(), selectorIndex != menuIndex);
|
||||
menuY += 30;
|
||||
menuIndex++;
|
||||
}
|
||||
|
||||
// --- Bottom menu tiles (indices 1-3) ---
|
||||
const int menuTileWidth = pageWidth - 2 * margin;
|
||||
constexpr int menuTileHeight = 50;
|
||||
constexpr int menuSpacing = 10;
|
||||
constexpr int totalMenuHeight = 3 * menuTileHeight + 2 * menuSpacing;
|
||||
renderer.drawText(UI_10_FONT_ID, 20, menuY, "Browse", selectorIndex != menuIndex);
|
||||
menuY += 30;
|
||||
menuIndex++;
|
||||
|
||||
int menuStartY = bookY + bookHeight + 20;
|
||||
// Ensure we don't collide with the bottom button legend
|
||||
const int maxMenuStartY = pageHeight - bottomMargin - totalMenuHeight - margin;
|
||||
if (menuStartY > maxMenuStartY) {
|
||||
menuStartY = maxMenuStartY;
|
||||
}
|
||||
renderer.drawText(UI_10_FONT_ID, 20, menuY, "File transfer", selectorIndex != menuIndex);
|
||||
menuY += 30;
|
||||
menuIndex++;
|
||||
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
constexpr const char* items[3] = {"Browse files", "File transfer", "Settings"};
|
||||
const int overallIndex = i + (getMenuItemCount() - 3);
|
||||
constexpr int tileX = margin;
|
||||
const int tileY = menuStartY + i * (menuTileHeight + menuSpacing);
|
||||
const bool selected = selectorIndex == overallIndex;
|
||||
renderer.drawText(UI_10_FONT_ID, 20, menuY, "Settings", selectorIndex != menuIndex);
|
||||
|
||||
if (selected) {
|
||||
renderer.fillRect(tileX, tileY, menuTileWidth, menuTileHeight);
|
||||
} else {
|
||||
renderer.drawRect(tileX, tileY, menuTileWidth, menuTileHeight);
|
||||
}
|
||||
|
||||
const char* label = items[i];
|
||||
const int textWidth = renderer.getTextWidth(UI_10_FONT_ID, label);
|
||||
const int textX = tileX + (menuTileWidth - textWidth) / 2;
|
||||
const int lineHeight = renderer.getLineHeight(UI_10_FONT_ID);
|
||||
const int textY = tileY + (menuTileHeight - lineHeight) / 2; // vertically centered assuming y is top of text
|
||||
|
||||
// Invert text when the tile is selected, to contrast with the filled background
|
||||
renderer.drawText(UI_10_FONT_ID, textX, textY, label, !selected);
|
||||
}
|
||||
|
||||
const auto labels = mappedInput.mapLabels("", "Confirm", "Up", "Down");
|
||||
const auto labels = mappedInput.mapLabels("Back", "Confirm", "Left", "Right");
|
||||
renderer.drawButtonHints(UI_10_FONT_ID, labels.btn1, labels.btn2, labels.btn3, labels.btn4);
|
||||
|
||||
ScreenComponents::drawBattery(renderer, 20, pageHeight - 70);
|
||||
|
||||
renderer.displayBuffer();
|
||||
}
|
||||
|
||||
@ -13,8 +13,6 @@ class HomeActivity final : public Activity {
|
||||
int selectorIndex = 0;
|
||||
bool updateRequired = false;
|
||||
bool hasContinueReading = false;
|
||||
std::string lastBookTitle;
|
||||
std::string lastBookAuthor;
|
||||
const std::function<void()> onContinueReading;
|
||||
const std::function<void()> onReaderOpen;
|
||||
const std::function<void()> onSettingsOpen;
|
||||
|
||||
@ -97,7 +97,7 @@ void NetworkModeSelectionActivity::render() const {
|
||||
const auto pageHeight = renderer.getScreenHeight();
|
||||
|
||||
// Draw header
|
||||
renderer.drawCenteredText(UI_12_FONT_ID, 15, "File Transfer", true, BOLD);
|
||||
renderer.drawCenteredText(UI_12_FONT_ID, 10, "File Transfer", true, BOLD);
|
||||
|
||||
// Draw subtitle
|
||||
renderer.drawCenteredText(UI_10_FONT_ID, 50, "How would you like to connect?");
|
||||
|
||||
@ -496,7 +496,7 @@ void WifiSelectionActivity::renderNetworkList() const {
|
||||
const auto pageHeight = renderer.getScreenHeight();
|
||||
|
||||
// Draw header
|
||||
renderer.drawCenteredText(UI_12_FONT_ID, 15, "WiFi Networks", true, BOLD);
|
||||
renderer.drawCenteredText(UI_12_FONT_ID, 10, "WiFi Networks", true, BOLD);
|
||||
|
||||
if (networks.empty()) {
|
||||
// No networks found or scan failed
|
||||
|
||||
@ -5,11 +5,11 @@
|
||||
#include <GfxRenderer.h>
|
||||
#include <SDCardManager.h>
|
||||
|
||||
#include "Battery.h"
|
||||
#include "CrossPointSettings.h"
|
||||
#include "CrossPointState.h"
|
||||
#include "EpubReaderChapterSelectionActivity.h"
|
||||
#include "MappedInputManager.h"
|
||||
#include "ScreenComponents.h"
|
||||
#include "fontIds.h"
|
||||
|
||||
namespace {
|
||||
@ -65,16 +65,6 @@ void EpubReaderActivity::onEnter() {
|
||||
}
|
||||
f.close();
|
||||
}
|
||||
// We may want a better condition to detect if we are opening for the first time.
|
||||
// This will trigger if the book is re-opened at Chapter 0.
|
||||
if (currentSpineIndex == 0) {
|
||||
int textSpineIndex = epub->getSpineIndexForTextReference();
|
||||
if (textSpineIndex != 0) {
|
||||
currentSpineIndex = textSpineIndex;
|
||||
Serial.printf("[%lu] [ERS] Opened for first time, navigating to text reference at index %d\n", millis(),
|
||||
textSpineIndex);
|
||||
}
|
||||
}
|
||||
|
||||
// Save current epub as last opened epub
|
||||
APP_STATE.openEpubPath = epub->getPath();
|
||||
@ -421,7 +411,8 @@ void EpubReaderActivity::renderStatusBar(const int orientedMarginRight, const in
|
||||
|
||||
// Position status bar near the bottom of the logical screen, regardless of orientation
|
||||
const auto screenHeight = renderer.getScreenHeight();
|
||||
const auto textY = screenHeight - orientedMarginBottom - 4;
|
||||
const auto textY = screenHeight - orientedMarginBottom - 2;
|
||||
int percentageTextWidth = 0;
|
||||
int progressTextWidth = 0;
|
||||
|
||||
if (showProgress) {
|
||||
@ -438,13 +429,42 @@ void EpubReaderActivity::renderStatusBar(const int orientedMarginRight, const in
|
||||
}
|
||||
|
||||
if (showBattery) {
|
||||
ScreenComponents::drawBattery(renderer, orientedMarginLeft, textY);
|
||||
// Left aligned battery icon and percentage
|
||||
const uint16_t percentage = battery.readPercentage();
|
||||
const auto percentageText = std::to_string(percentage) + "%";
|
||||
percentageTextWidth = renderer.getTextWidth(SMALL_FONT_ID, percentageText.c_str());
|
||||
renderer.drawText(SMALL_FONT_ID, 20 + orientedMarginLeft, textY, percentageText.c_str());
|
||||
|
||||
// 1 column on left, 2 columns on right, 5 columns of battery body
|
||||
constexpr int batteryWidth = 15;
|
||||
constexpr int batteryHeight = 10;
|
||||
const int x = orientedMarginLeft;
|
||||
const int y = screenHeight - orientedMarginBottom + 5;
|
||||
|
||||
// Top line
|
||||
renderer.drawLine(x, y, x + batteryWidth - 4, y);
|
||||
// Bottom line
|
||||
renderer.drawLine(x, y + batteryHeight - 1, x + batteryWidth - 4, y + batteryHeight - 1);
|
||||
// Left line
|
||||
renderer.drawLine(x, y, x, y + batteryHeight - 1);
|
||||
// Battery end
|
||||
renderer.drawLine(x + batteryWidth - 4, y, x + batteryWidth - 4, y + batteryHeight - 1);
|
||||
renderer.drawLine(x + batteryWidth - 3, y + 2, x + batteryWidth - 1, y + 2);
|
||||
renderer.drawLine(x + batteryWidth - 3, y + batteryHeight - 3, x + batteryWidth - 1, y + batteryHeight - 3);
|
||||
renderer.drawLine(x + batteryWidth - 1, y + 2, x + batteryWidth - 1, y + batteryHeight - 3);
|
||||
|
||||
// The +1 is to round up, so that we always fill at least one pixel
|
||||
int filledWidth = percentage * (batteryWidth - 5) / 100 + 1;
|
||||
if (filledWidth > batteryWidth - 5) {
|
||||
filledWidth = batteryWidth - 5; // Ensure we don't overflow
|
||||
}
|
||||
renderer.fillRect(x + 1, y + 1, filledWidth, batteryHeight - 2);
|
||||
}
|
||||
|
||||
if (showChapterTitle) {
|
||||
// Centered chatper title text
|
||||
// Page width minus existing content with 30px padding on each side
|
||||
const int titleMarginLeft = 50 + 30 + orientedMarginLeft; // 50px for battery
|
||||
const int titleMarginLeft = 20 + percentageTextWidth + 30 + orientedMarginLeft;
|
||||
const int titleMarginRight = progressTextWidth + 30 + orientedMarginRight;
|
||||
const int availableTextWidth = renderer.getScreenWidth() - titleMarginLeft - titleMarginRight;
|
||||
const int tocIndex = epub->getTocIndexForSpineIndex(currentSpineIndex);
|
||||
|
||||
@ -120,7 +120,7 @@ void EpubReaderChapterSelectionActivity::renderScreen() {
|
||||
|
||||
const auto pageWidth = renderer.getScreenWidth();
|
||||
const int pageItems = getPageItems();
|
||||
renderer.drawCenteredText(UI_12_FONT_ID, 15, "Select Chapter", true, BOLD);
|
||||
renderer.drawCenteredText(UI_12_FONT_ID, 10, "Select Chapter", true, BOLD);
|
||||
|
||||
const auto pageStartIndex = selectorIndex / pageItems * pageItems;
|
||||
renderer.fillRect(0, 60 + (selectorIndex % pageItems) * 30 - 2, pageWidth - 1, 30);
|
||||
|
||||
@ -165,7 +165,7 @@ void FileSelectionActivity::render() const {
|
||||
renderer.clearScreen();
|
||||
|
||||
const auto pageWidth = renderer.getScreenWidth();
|
||||
renderer.drawCenteredText(UI_12_FONT_ID, 15, "Books", true, BOLD);
|
||||
renderer.drawCenteredText(UI_12_FONT_ID, 10, "Books", true, BOLD);
|
||||
|
||||
// Help text
|
||||
const auto labels = mappedInput.mapLabels("« Home", "Open", "", "");
|
||||
|
||||
@ -130,7 +130,7 @@ void XtcReaderChapterSelectionActivity::renderScreen() {
|
||||
|
||||
const auto pageWidth = renderer.getScreenWidth();
|
||||
const int pageItems = getPageItems();
|
||||
renderer.drawCenteredText(UI_12_FONT_ID, 15, "Select Chapter", true, BOLD);
|
||||
renderer.drawCenteredText(UI_12_FONT_ID, 10, "Select Chapter", true, BOLD);
|
||||
|
||||
const auto& chapters = xtc->getChapters();
|
||||
if (chapters.empty()) {
|
||||
|
||||
@ -128,7 +128,7 @@ void OtaUpdateActivity::render() {
|
||||
const auto pageWidth = renderer.getScreenWidth();
|
||||
|
||||
renderer.clearScreen();
|
||||
renderer.drawCenteredText(UI_12_FONT_ID, 15, "Update", true, BOLD);
|
||||
renderer.drawCenteredText(UI_12_FONT_ID, 10, "Update", true, BOLD);
|
||||
|
||||
if (state == CHECKING_FOR_UPDATE) {
|
||||
renderer.drawCenteredText(UI_10_FONT_ID, 300, "Checking for update...", true, BOLD);
|
||||
|
||||
@ -23,15 +23,12 @@ const SettingInfo settingsList[settingsCount] = {
|
||||
{"Front Button Layout",
|
||||
SettingType::ENUM,
|
||||
&CrossPointSettings::frontButtonLayout,
|
||||
{"Bck, Cnfrm, Lft, Rght", "Lft, Rght, Bck, Cnfrm", "Lft, Bck, Cnfrm, Rght"}},
|
||||
{"Bck, Cnfrm, Lft, Rght", "Lft, Rght, Bck, Cnfrm"}},
|
||||
{"Side Button Layout (reader)",
|
||||
SettingType::ENUM,
|
||||
&CrossPointSettings::sideButtonLayout,
|
||||
{"Prev, Next", "Next, Prev"}},
|
||||
{"Reader Font Family",
|
||||
SettingType::ENUM,
|
||||
&CrossPointSettings::fontFamily,
|
||||
{"Bookerly", "Noto Sans", "Open Dyslexic"}},
|
||||
{"Reader Font Family", SettingType::ENUM, &CrossPointSettings::fontFamily, {"Aleo", "Noto Sans", "Open Dyslexic"}},
|
||||
{"Reader Font Size", SettingType::ENUM, &CrossPointSettings::fontSize, {"Small", "Medium", "Large", "X Large"}},
|
||||
{"Reader Line Spacing", SettingType::ENUM, &CrossPointSettings::lineSpacing, {"Tight", "Normal", "Wide"}},
|
||||
{"Check for updates", SettingType::ACTION, nullptr, {}},
|
||||
@ -163,7 +160,7 @@ void SettingsActivity::render() const {
|
||||
const auto pageHeight = renderer.getScreenHeight();
|
||||
|
||||
// Draw header
|
||||
renderer.drawCenteredText(UI_12_FONT_ID, 15, "Settings", true, BOLD);
|
||||
renderer.drawCenteredText(UI_12_FONT_ID, 10, "Settings", true, BOLD);
|
||||
|
||||
// Draw selection
|
||||
renderer.fillRect(0, 60 + selectedSettingIndex * 30 - 2, pageWidth - 1, 30);
|
||||
@ -172,6 +169,11 @@ void SettingsActivity::render() const {
|
||||
for (int i = 0; i < settingsCount; i++) {
|
||||
const int settingY = 60 + i * 30; // 30 pixels between settings
|
||||
|
||||
// Draw selection indicator for the selected setting
|
||||
if (i == selectedSettingIndex) {
|
||||
renderer.drawText(UI_10_FONT_ID, 5, settingY, ">");
|
||||
}
|
||||
|
||||
// Draw setting name
|
||||
renderer.drawText(UI_10_FONT_ID, 20, settingY, settingsList[i].name, i != selectedSettingIndex);
|
||||
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
// The contents of this file are generated by ./lib/EpdFont/scripts/build-font-ids.sh
|
||||
#pragma once
|
||||
|
||||
#define BOOKERLY_12_FONT_ID (-142329172)
|
||||
#define BOOKERLY_14_FONT_ID (104246423)
|
||||
#define BOOKERLY_16_FONT_ID (1909382491)
|
||||
#define BOOKERLY_18_FONT_ID (2056549737)
|
||||
#define ALEO_12_FONT_ID (2101191384)
|
||||
#define ALEO_14_FONT_ID (-1834656672)
|
||||
#define ALEO_16_FONT_ID (-1982848762)
|
||||
#define ALEO_18_FONT_ID (-365302307)
|
||||
#define NOTOSANS_12_FONT_ID (-1646794343)
|
||||
#define NOTOSANS_14_FONT_ID (-890242897)
|
||||
#define NOTOSANS_16_FONT_ID (241925189)
|
||||
@ -15,4 +15,4 @@
|
||||
#define OPENDYSLEXIC_14_FONT_ID (-1851285286)
|
||||
#define UI_10_FONT_ID (-823541435)
|
||||
#define UI_12_FONT_ID (-126318184)
|
||||
#define SMALL_FONT_ID (-874196069)
|
||||
#define SMALL_FONT_ID (-706443385)
|
||||
|
||||
54
src/main.cpp
54
src/main.cpp
@ -40,30 +40,26 @@ GfxRenderer renderer(einkDisplay);
|
||||
Activity* currentActivity;
|
||||
|
||||
// Fonts
|
||||
EpdFont bookerly12RegularFont(&bookerly_12_regular);
|
||||
EpdFont bookerly12BoldFont(&bookerly_12_bold);
|
||||
EpdFont bookerly12ItalicFont(&bookerly_12_italic);
|
||||
EpdFont bookerly12BoldItalicFont(&bookerly_12_bolditalic);
|
||||
EpdFontFamily bookerly12FontFamily(&bookerly12RegularFont, &bookerly12BoldFont, &bookerly12ItalicFont,
|
||||
&bookerly12BoldItalicFont);
|
||||
EpdFont bookerly14RegularFont(&bookerly_14_regular);
|
||||
EpdFont bookerly14BoldFont(&bookerly_14_bold);
|
||||
EpdFont bookerly14ItalicFont(&bookerly_14_italic);
|
||||
EpdFont bookerly14BoldItalicFont(&bookerly_14_bolditalic);
|
||||
EpdFontFamily bookerly14FontFamily(&bookerly14RegularFont, &bookerly14BoldFont, &bookerly14ItalicFont,
|
||||
&bookerly14BoldItalicFont);
|
||||
EpdFont bookerly16RegularFont(&bookerly_16_regular);
|
||||
EpdFont bookerly16BoldFont(&bookerly_16_bold);
|
||||
EpdFont bookerly16ItalicFont(&bookerly_16_italic);
|
||||
EpdFont bookerly16BoldItalicFont(&bookerly_16_bolditalic);
|
||||
EpdFontFamily bookerly16FontFamily(&bookerly16RegularFont, &bookerly16BoldFont, &bookerly16ItalicFont,
|
||||
&bookerly16BoldItalicFont);
|
||||
EpdFont bookerly18RegularFont(&bookerly_18_regular);
|
||||
EpdFont bookerly18BoldFont(&bookerly_18_bold);
|
||||
EpdFont bookerly18ItalicFont(&bookerly_18_italic);
|
||||
EpdFont bookerly18BoldItalicFont(&bookerly_18_bolditalic);
|
||||
EpdFontFamily bookerly18FontFamily(&bookerly18RegularFont, &bookerly18BoldFont, &bookerly18ItalicFont,
|
||||
&bookerly18BoldItalicFont);
|
||||
EpdFont aleo12RegularFont(&aleo_12_regular);
|
||||
EpdFont aleo12BoldFont(&aleo_12_bold);
|
||||
EpdFont aleo12ItalicFont(&aleo_12_italic);
|
||||
EpdFont aleo12BoldItalicFont(&aleo_12_bolditalic);
|
||||
EpdFontFamily aleo12FontFamily(&aleo12RegularFont, &aleo12BoldFont, &aleo12ItalicFont, &aleo12BoldItalicFont);
|
||||
EpdFont aleo14RegularFont(&aleo_14_regular);
|
||||
EpdFont aleo14BoldFont(&aleo_14_bold);
|
||||
EpdFont aleo14ItalicFont(&aleo_14_italic);
|
||||
EpdFont aleo14BoldItalicFont(&aleo_14_bolditalic);
|
||||
EpdFontFamily aleo14FontFamily(&aleo14RegularFont, &aleo14BoldFont, &aleo14ItalicFont, &aleo14BoldItalicFont);
|
||||
EpdFont aleo16RegularFont(&aleo_16_regular);
|
||||
EpdFont aleo16BoldFont(&aleo_16_bold);
|
||||
EpdFont aleo16ItalicFont(&aleo_16_italic);
|
||||
EpdFont aleo16BoldItalicFont(&aleo_16_bolditalic);
|
||||
EpdFontFamily aleo16FontFamily(&aleo16RegularFont, &aleo16BoldFont, &aleo16ItalicFont, &aleo16BoldItalicFont);
|
||||
EpdFont aleo18RegularFont(&aleo_18_regular);
|
||||
EpdFont aleo18BoldFont(&aleo_18_bold);
|
||||
EpdFont aleo18ItalicFont(&aleo_18_italic);
|
||||
EpdFont aleo18BoldItalicFont(&aleo_18_bolditalic);
|
||||
EpdFontFamily aleo18FontFamily(&aleo18RegularFont, &aleo18BoldFont, &aleo18ItalicFont, &aleo18BoldItalicFont);
|
||||
|
||||
EpdFont notosans12RegularFont(¬osans_12_regular);
|
||||
EpdFont notosans12BoldFont(¬osans_12_bold);
|
||||
@ -115,7 +111,7 @@ EpdFont opendyslexic14BoldItalicFont(&opendyslexic_14_bolditalic);
|
||||
EpdFontFamily opendyslexic14FontFamily(&opendyslexic14RegularFont, &opendyslexic14BoldFont, &opendyslexic14ItalicFont,
|
||||
&opendyslexic14BoldItalicFont);
|
||||
|
||||
EpdFont smallFont(¬osans_8_regular);
|
||||
EpdFont smallFont(&spacegrotesk);
|
||||
EpdFontFamily smallFontFamily(&smallFont);
|
||||
|
||||
EpdFont ui10RegularFont(&ubuntu_10_regular);
|
||||
@ -231,10 +227,10 @@ void onGoHome() {
|
||||
void setupDisplayAndFonts() {
|
||||
einkDisplay.begin();
|
||||
Serial.printf("[%lu] [ ] Display initialized\n", millis());
|
||||
renderer.insertFont(BOOKERLY_12_FONT_ID, bookerly12FontFamily);
|
||||
renderer.insertFont(BOOKERLY_14_FONT_ID, bookerly14FontFamily);
|
||||
renderer.insertFont(BOOKERLY_16_FONT_ID, bookerly16FontFamily);
|
||||
renderer.insertFont(BOOKERLY_18_FONT_ID, bookerly18FontFamily);
|
||||
renderer.insertFont(ALEO_12_FONT_ID, aleo12FontFamily);
|
||||
renderer.insertFont(ALEO_14_FONT_ID, aleo14FontFamily);
|
||||
renderer.insertFont(ALEO_16_FONT_ID, aleo16FontFamily);
|
||||
renderer.insertFont(ALEO_18_FONT_ID, aleo18FontFamily);
|
||||
renderer.insertFont(NOTOSANS_12_FONT_ID, notosans12FontFamily);
|
||||
renderer.insertFont(NOTOSANS_14_FONT_ID, notosans14FontFamily);
|
||||
renderer.insertFont(NOTOSANS_16_FONT_ID, notosans16FontFamily);
|
||||
|
||||
@ -50,14 +50,6 @@ void CrossPointWebServer::begin() {
|
||||
|
||||
Serial.printf("[%lu] [WEB] Creating web server on port %d...\n", millis(), port);
|
||||
server.reset(new WebServer(port));
|
||||
|
||||
// Disable WiFi sleep to improve responsiveness and prevent 'unreachable' errors.
|
||||
// This is critical for reliable web server operation on ESP32.
|
||||
WiFi.setSleep(false);
|
||||
|
||||
// Note: WebServer class doesn't have setNoDelay() in the standard ESP32 library.
|
||||
// We rely on disabling WiFi sleep for responsiveness.
|
||||
|
||||
Serial.printf("[%lu] [WEB] [MEM] Free heap after WebServer allocation: %d bytes\n", millis(), ESP.getFreeHeap());
|
||||
|
||||
if (!server) {
|
||||
@ -165,16 +157,15 @@ void CrossPointWebServer::handleStatus() const {
|
||||
// Get correct IP based on AP vs STA mode
|
||||
const String ipAddr = apMode ? WiFi.softAPIP().toString() : WiFi.localIP().toString();
|
||||
|
||||
JsonDocument doc;
|
||||
doc["version"] = CROSSPOINT_VERSION;
|
||||
doc["ip"] = ipAddr;
|
||||
doc["mode"] = apMode ? "AP" : "STA";
|
||||
doc["rssi"] = apMode ? 0 : WiFi.RSSI();
|
||||
doc["freeHeap"] = ESP.getFreeHeap();
|
||||
doc["uptime"] = millis() / 1000;
|
||||
String json = "{";
|
||||
json += "\"version\":\"" + String(CROSSPOINT_VERSION) + "\",";
|
||||
json += "\"ip\":\"" + ipAddr + "\",";
|
||||
json += "\"mode\":\"" + String(apMode ? "AP" : "STA") + "\",";
|
||||
json += "\"rssi\":" + String(apMode ? 0 : WiFi.RSSI()) + ","; // RSSI not applicable in AP mode
|
||||
json += "\"freeHeap\":" + String(ESP.getFreeHeap()) + ",";
|
||||
json += "\"uptime\":" + String(millis() / 1000);
|
||||
json += "}";
|
||||
|
||||
String json;
|
||||
serializeJson(doc, json);
|
||||
server->send(200, "application/json", json);
|
||||
}
|
||||
|
||||
@ -229,7 +220,6 @@ void CrossPointWebServer::scanFiles(const char* path, const std::function<void(F
|
||||
}
|
||||
|
||||
file.close();
|
||||
yield(); // Yield to allow WiFi and other tasks to process during long scans
|
||||
file = root.openNextFile();
|
||||
}
|
||||
root.close();
|
||||
@ -264,15 +254,12 @@ void CrossPointWebServer::handleFileListData() const {
|
||||
char output[512];
|
||||
constexpr size_t outputSize = sizeof(output);
|
||||
bool seenFirst = false;
|
||||
JsonDocument doc;
|
||||
|
||||
scanFiles(currentPath.c_str(), [this, &output, &doc, seenFirst](const FileInfo& info) mutable {
|
||||
doc.clear();
|
||||
scanFiles(currentPath.c_str(), [this, &output, seenFirst](const FileInfo& info) mutable {
|
||||
JsonDocument doc;
|
||||
doc["name"] = info.name;
|
||||
doc["size"] = info.size;
|
||||
doc["isDirectory"] = info.isDirectory;
|
||||
doc["isEpub"] = info.isEpub;
|
||||
|
||||
const size_t written = serializeJson(doc, output, outputSize);
|
||||
if (written >= outputSize) {
|
||||
// JSON output truncated; skip this entry to avoid sending malformed JSON
|
||||
|
||||
Loading…
Reference in New Issue
Block a user