mirror of
https://github.com/daveallie/crosspoint-reader.git
synced 2026-02-06 15:47:39 +03:00
Compare commits
11 Commits
e43fec79be
...
941643cf97
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
941643cf97 | ||
|
|
9bba41ed96 | ||
|
|
34cf5f0636 | ||
|
|
f2ca65d752 | ||
|
|
6a8971fc20 | ||
|
|
e2cba5be83 | ||
|
|
52a0b5bbe9 | ||
|
|
3abcd0d05d | ||
|
|
03f0ce04cc | ||
|
|
be1b5bad21 | ||
|
|
3dd52f30fa |
@ -2,8 +2,7 @@
|
||||
|
||||
#include <Utf8.h>
|
||||
|
||||
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; }
|
||||
#include <algorithm>
|
||||
|
||||
void EpdFont::getTextBounds(const char* string, const int startX, const int startY, int* minX, int* minY, int* maxX,
|
||||
int* maxY) const {
|
||||
@ -32,10 +31,10 @@ void EpdFont::getTextBounds(const char* string, const int startX, const int star
|
||||
continue;
|
||||
}
|
||||
|
||||
*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);
|
||||
*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);
|
||||
cursorX += glyph->advanceX;
|
||||
}
|
||||
}
|
||||
|
||||
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
@ -1,21 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#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/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/notosans_12_bold.h>
|
||||
#include <builtinFonts/notosans_12_bolditalic.h>
|
||||
#include <builtinFonts/notosans_12_italic.h>
|
||||
@ -48,7 +49,6 @@
|
||||
#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>
|
||||
|
||||
4018
lib/EpdFont/builtinFonts/bookerly_12_bold.h
Normal file
4018
lib/EpdFont/builtinFonts/bookerly_12_bold.h
Normal file
File diff suppressed because it is too large
Load Diff
4099
lib/EpdFont/builtinFonts/bookerly_12_bolditalic.h
Normal file
4099
lib/EpdFont/builtinFonts/bookerly_12_bolditalic.h
Normal file
File diff suppressed because it is too large
Load Diff
3867
lib/EpdFont/builtinFonts/bookerly_12_italic.h
Normal file
3867
lib/EpdFont/builtinFonts/bookerly_12_italic.h
Normal file
File diff suppressed because it is too large
Load Diff
3758
lib/EpdFont/builtinFonts/bookerly_12_regular.h
Normal file
3758
lib/EpdFont/builtinFonts/bookerly_12_regular.h
Normal file
File diff suppressed because it is too large
Load Diff
5005
lib/EpdFont/builtinFonts/bookerly_14_bold.h
Normal file
5005
lib/EpdFont/builtinFonts/bookerly_14_bold.h
Normal file
File diff suppressed because it is too large
Load Diff
5193
lib/EpdFont/builtinFonts/bookerly_14_bolditalic.h
Normal file
5193
lib/EpdFont/builtinFonts/bookerly_14_bolditalic.h
Normal file
File diff suppressed because it is too large
Load Diff
4870
lib/EpdFont/builtinFonts/bookerly_14_italic.h
Normal file
4870
lib/EpdFont/builtinFonts/bookerly_14_italic.h
Normal file
File diff suppressed because it is too large
Load Diff
4734
lib/EpdFont/builtinFonts/bookerly_14_regular.h
Normal file
4734
lib/EpdFont/builtinFonts/bookerly_14_regular.h
Normal file
File diff suppressed because it is too large
Load Diff
6139
lib/EpdFont/builtinFonts/bookerly_16_bold.h
Normal file
6139
lib/EpdFont/builtinFonts/bookerly_16_bold.h
Normal file
File diff suppressed because it is too large
Load Diff
6348
lib/EpdFont/builtinFonts/bookerly_16_bolditalic.h
Normal file
6348
lib/EpdFont/builtinFonts/bookerly_16_bolditalic.h
Normal file
File diff suppressed because it is too large
Load Diff
5967
lib/EpdFont/builtinFonts/bookerly_16_italic.h
Normal file
5967
lib/EpdFont/builtinFonts/bookerly_16_italic.h
Normal file
File diff suppressed because it is too large
Load Diff
5808
lib/EpdFont/builtinFonts/bookerly_16_regular.h
Normal file
5808
lib/EpdFont/builtinFonts/bookerly_16_regular.h
Normal file
File diff suppressed because it is too large
Load Diff
7842
lib/EpdFont/builtinFonts/bookerly_18_bold.h
Normal file
7842
lib/EpdFont/builtinFonts/bookerly_18_bold.h
Normal file
File diff suppressed because it is too large
Load Diff
8050
lib/EpdFont/builtinFonts/bookerly_18_bolditalic.h
Normal file
8050
lib/EpdFont/builtinFonts/bookerly_18_bolditalic.h
Normal file
File diff suppressed because it is too large
Load Diff
7568
lib/EpdFont/builtinFonts/bookerly_18_italic.h
Normal file
7568
lib/EpdFont/builtinFonts/bookerly_18_italic.h
Normal file
File diff suppressed because it is too large
Load Diff
7392
lib/EpdFont/builtinFonts/bookerly_18_regular.h
Normal file
7392
lib/EpdFont/builtinFonts/bookerly_18_regular.h
Normal file
File diff suppressed because it is too large
Load Diff
1558
lib/EpdFont/builtinFonts/notosans_8_regular.h
Normal file
1558
lib/EpdFont/builtinFonts/notosans_8_regular.h
Normal file
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,93 +0,0 @@
|
||||
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.
|
||||
BIN
lib/EpdFont/builtinFonts/source/Bookerly/Bookerly-Bold.ttf
Executable file
BIN
lib/EpdFont/builtinFonts/source/Bookerly/Bookerly-Bold.ttf
Executable file
Binary file not shown.
BIN
lib/EpdFont/builtinFonts/source/Bookerly/Bookerly-BoldItalic.ttf
Executable file
BIN
lib/EpdFont/builtinFonts/source/Bookerly/Bookerly-BoldItalic.ttf
Executable file
Binary file not shown.
BIN
lib/EpdFont/builtinFonts/source/Bookerly/Bookerly-Italic.ttf
Executable file
BIN
lib/EpdFont/builtinFonts/source/Bookerly/Bookerly-Italic.ttf
Executable file
Binary file not shown.
BIN
lib/EpdFont/builtinFonts/source/Bookerly/Bookerly-Regular.ttf
Executable file
BIN
lib/EpdFont/builtinFonts/source/Bookerly/Bookerly-Regular.ttf
Executable file
Binary file not shown.
@ -1,93 +0,0 @@
|
||||
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.
@ -1,826 +0,0 @@
|
||||
/**
|
||||
* 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 ALEO_12_FONT_ID ($(
|
||||
echo "#define BOOKERLY_12_FONT_ID ($(
|
||||
ruby -rdigest -e 'puts [
|
||||
"./aleo_12_regular.h",
|
||||
"./aleo_12_bold.h",
|
||||
"./aleo_12_bolditalic.h",
|
||||
"./aleo_12_italic.h",
|
||||
"./bookerly_12_regular.h",
|
||||
"./bookerly_12_bold.h",
|
||||
"./bookerly_12_bolditalic.h",
|
||||
"./bookerly_12_italic.h",
|
||||
].map{|f| Digest::SHA256.hexdigest(File.read(f)).to_i(16) }.sum % (2 ** 32) - (2 ** 31)'
|
||||
))"
|
||||
|
||||
echo "#define ALEO_14_FONT_ID ($(
|
||||
echo "#define BOOKERLY_14_FONT_ID ($(
|
||||
ruby -rdigest -e 'puts [
|
||||
"./aleo_14_regular.h",
|
||||
"./aleo_14_bold.h",
|
||||
"./aleo_14_bolditalic.h",
|
||||
"./aleo_14_italic.h",
|
||||
"./bookerly_14_regular.h",
|
||||
"./bookerly_14_bold.h",
|
||||
"./bookerly_14_bolditalic.h",
|
||||
"./bookerly_14_italic.h",
|
||||
].map{|f| Digest::SHA256.hexdigest(File.read(f)).to_i(16) }.sum % (2 ** 32) - (2 ** 31)'
|
||||
))"
|
||||
|
||||
echo "#define ALEO_16_FONT_ID ($(
|
||||
echo "#define BOOKERLY_16_FONT_ID ($(
|
||||
ruby -rdigest -e 'puts [
|
||||
"./aleo_16_regular.h",
|
||||
"./aleo_16_bold.h",
|
||||
"./aleo_16_bolditalic.h",
|
||||
"./aleo_16_italic.h",
|
||||
"./bookerly_16_regular.h",
|
||||
"./bookerly_16_bold.h",
|
||||
"./bookerly_16_bolditalic.h",
|
||||
"./bookerly_16_italic.h",
|
||||
].map{|f| Digest::SHA256.hexdigest(File.read(f)).to_i(16) }.sum % (2 ** 32) - (2 ** 31)'
|
||||
))"
|
||||
|
||||
echo "#define ALEO_18_FONT_ID ($(
|
||||
echo "#define BOOKERLY_18_FONT_ID ($(
|
||||
ruby -rdigest -e 'puts [
|
||||
"./aleo_18_regular.h",
|
||||
"./aleo_18_bold.h",
|
||||
"./aleo_18_bolditalic.h",
|
||||
"./aleo_18_italic.h",
|
||||
"./bookerly_18_regular.h",
|
||||
"./bookerly_18_bold.h",
|
||||
"./bookerly_18_bolditalic.h",
|
||||
"./bookerly_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 [
|
||||
"./spacegrotesk.h",
|
||||
"./notosans_8_regular.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")
|
||||
ALEO_FONT_SIZES=(12 14 16 18)
|
||||
BOOKERLY_FONT_SIZES=(12 14 16 18)
|
||||
NOTOSANS_FONT_SIZES=(12 14 16 18)
|
||||
OPENDYSLEXIC_FONT_SIZES=(8 10 12 14)
|
||||
|
||||
for size in ${ALEO_FONT_SIZES[@]}; do
|
||||
for size in ${BOOKERLY_FONT_SIZES[@]}; do
|
||||
for style in ${READER_FONT_STYLES[@]}; do
|
||||
font_name="aleo_${size}_$(echo $style | tr '[:upper:]' '[:lower:]')"
|
||||
font_path="../builtinFonts/source/Aleo/Aleo-${style}.ttf"
|
||||
font_name="bookerly_${size}_$(echo $style | tr '[:upper:]' '[:lower:]')"
|
||||
font_path="../builtinFonts/source/Bookerly/Bookerly-${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 spacegrotesk 8 ../builtinFonts/source/SpaceGrotesk/SpaceGrotesk-Regular.ttf > ../builtinFonts/spacegrotesk.h
|
||||
python fontconvert.py notosans_8_regular 8 ../builtinFonts/source/NotoSans/NotoSans-Regular.ttf > ../builtinFonts/notosans_8_regular.h
|
||||
|
||||
@ -72,9 +72,9 @@ bool Epub::parseContentOpf(BookMetadataCache::BookMetadata& bookMetadata) {
|
||||
|
||||
// Grab data from opfParser into epub
|
||||
bookMetadata.title = opfParser.title;
|
||||
// TODO: Parse author
|
||||
bookMetadata.author = "";
|
||||
bookMetadata.author = opfParser.author;
|
||||
bookMetadata.coverItemHref = opfParser.coverItemHref;
|
||||
bookMetadata.textReferenceHref = opfParser.textReferenceHref;
|
||||
|
||||
if (!opfParser.tocNcxPath.empty()) {
|
||||
tocNcxItem = opfParser.tocNcxPath;
|
||||
@ -109,17 +109,20 @@ 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) {
|
||||
@ -139,7 +142,7 @@ bool Epub::parseTocNcxFile() const {
|
||||
}
|
||||
|
||||
// load in the meta data for the epub file
|
||||
bool Epub::load() {
|
||||
bool Epub::load(const bool buildIfMissing) {
|
||||
Serial.printf("[%lu] [EBP] Loading ePub: %s\n", millis(), filepath.c_str());
|
||||
|
||||
// Initialize spine/TOC cache
|
||||
@ -151,6 +154,11 @@ bool Epub::load() {
|
||||
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();
|
||||
@ -253,6 +261,15 @@ 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 {
|
||||
@ -418,6 +435,35 @@ 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,12 +34,13 @@ class Epub {
|
||||
}
|
||||
~Epub() = default;
|
||||
std::string& getBasePath() { return contentBasePath; }
|
||||
bool load();
|
||||
bool load(bool buildIfMissing = true);
|
||||
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,
|
||||
@ -53,6 +54,7 @@ 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 = 2;
|
||||
constexpr uint8_t BOOK_CACHE_VERSION = 3;
|
||||
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() + sizeof(uint32_t) * 3;
|
||||
const uint32_t metadataSize = metadata.title.size() + metadata.author.size() + metadata.coverItemHref.size() +
|
||||
metadata.textReferenceHref.size() + sizeof(uint32_t) * 4;
|
||||
const uint32_t lutSize = sizeof(uint32_t) * spineCount + sizeof(uint32_t) * tocCount;
|
||||
const uint32_t lutOffset = headerASize + metadataSize;
|
||||
|
||||
@ -101,6 +101,7 @@ 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);
|
||||
@ -289,6 +290,7 @@ 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,6 +10,7 @@ class BookMetadataCache {
|
||||
std::string title;
|
||||
std::string author;
|
||||
std::string coverItemHref;
|
||||
std::string textReferenceHref;
|
||||
};
|
||||
|
||||
struct SpineEntry {
|
||||
|
||||
@ -57,7 +57,6 @@ 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) {
|
||||
@ -93,7 +92,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 = min(self->boldUntilDepth, self->depth);
|
||||
self->boldUntilDepth = std::min(self->boldUntilDepth, self->depth);
|
||||
} else if (matches(name, BLOCK_TAGS, NUM_BLOCK_TAGS)) {
|
||||
if (strcmp(name, "br") == 0) {
|
||||
self->startNewTextBlock(self->currentTextBlock->getStyle());
|
||||
@ -101,9 +100,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 = min(self->boldUntilDepth, self->depth);
|
||||
self->boldUntilDepth = std::min(self->boldUntilDepth, self->depth);
|
||||
} else if (matches(name, ITALIC_TAGS, NUM_ITALIC_TAGS)) {
|
||||
self->italicUntilDepth = min(self->italicUntilDepth, self->depth);
|
||||
self->italicUntilDepth = std::min(self->italicUntilDepth, self->depth);
|
||||
}
|
||||
|
||||
self->depth += 1;
|
||||
@ -162,7 +161,6 @@ 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.
|
||||
@ -245,9 +243,9 @@ bool ChapterHtmlSlimParser::parseAndBuildPages() {
|
||||
return false;
|
||||
}
|
||||
|
||||
const size_t len = file.read(static_cast<uint8_t*>(buf), 1024);
|
||||
const size_t len = file.read(buf, 1024);
|
||||
|
||||
if (len == 0) {
|
||||
if (len == 0 && file.available() > 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,6 +102,11 @@ 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)) {
|
||||
@ -122,6 +127,18 @@ 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;
|
||||
@ -200,6 +217,29 @@ 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) {
|
||||
@ -209,6 +249,11 @@ 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) {
|
||||
@ -221,6 +266,12 @@ 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();
|
||||
@ -232,6 +283,11 @@ 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,8 +12,10 @@ 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;
|
||||
@ -31,8 +33,10 @@ 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() = default;
|
||||
~GfxRenderer() { freeBwBufferChunks(); }
|
||||
|
||||
static constexpr int VIEWABLE_MARGIN_TOP = 9;
|
||||
static constexpr int VIEWABLE_MARGIN_RIGHT = 3;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
[platformio]
|
||||
crosspoint_version = 0.10.0
|
||||
crosspoint_version = 0.11.1
|
||||
default_envs = default
|
||||
|
||||
[base]
|
||||
|
||||
@ -92,7 +92,7 @@ bool CrossPointSettings::loadFromFile() {
|
||||
|
||||
float CrossPointSettings::getReaderLineCompression() const {
|
||||
switch (fontFamily) {
|
||||
case ALEO:
|
||||
case BOOKERLY:
|
||||
default:
|
||||
switch (lineSpacing) {
|
||||
case TIGHT:
|
||||
@ -128,18 +128,18 @@ float CrossPointSettings::getReaderLineCompression() const {
|
||||
|
||||
int CrossPointSettings::getReaderFontId() const {
|
||||
switch (fontFamily) {
|
||||
case ALEO:
|
||||
case BOOKERLY:
|
||||
default:
|
||||
switch (fontSize) {
|
||||
case SMALL:
|
||||
return ALEO_12_FONT_ID;
|
||||
return BOOKERLY_12_FONT_ID;
|
||||
case MEDIUM:
|
||||
default:
|
||||
return ALEO_14_FONT_ID;
|
||||
return BOOKERLY_14_FONT_ID;
|
||||
case LARGE:
|
||||
return ALEO_16_FONT_ID;
|
||||
return BOOKERLY_16_FONT_ID;
|
||||
case EXTRA_LARGE:
|
||||
return ALEO_18_FONT_ID;
|
||||
return BOOKERLY_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 };
|
||||
enum FRONT_BUTTON_LAYOUT { BACK_CONFIRM_LEFT_RIGHT = 0, LEFT_RIGHT_BACK_CONFIRM = 1, LEFT_BACK_CONFIRM_RIGHT = 2 };
|
||||
|
||||
// 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 { ALEO = 0, NOTOSANS = 1, OPENDYSLEXIC = 2 };
|
||||
enum FONT_FAMILY { BOOKERLY = 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 = ALEO;
|
||||
uint8_t fontFamily = BOOKERLY;
|
||||
uint8_t fontSize = MEDIUM;
|
||||
uint8_t lineSpacing = NORMAL;
|
||||
|
||||
|
||||
@ -11,6 +11,8 @@ 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;
|
||||
@ -19,6 +21,8 @@ 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;
|
||||
@ -26,6 +30,7 @@ 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:
|
||||
@ -36,6 +41,7 @@ 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;
|
||||
}
|
||||
@ -85,6 +91,8 @@ 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};
|
||||
|
||||
41
src/ScreenComponents.cpp
Normal file
41
src/ScreenComponents.cpp
Normal file
@ -0,0 +1,41 @@
|
||||
#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);
|
||||
}
|
||||
8
src/ScreenComponents.h
Normal file
8
src/ScreenComponents.h
Normal file
@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
class GfxRenderer;
|
||||
|
||||
class ScreenComponents {
|
||||
public:
|
||||
static void drawBattery(const GfxRenderer& renderer, int left, int top);
|
||||
};
|
||||
@ -1,10 +1,12 @@
|
||||
#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) {
|
||||
@ -22,6 +24,33 @@ 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
|
||||
@ -103,52 +132,191 @@ void HomeActivity::render() const {
|
||||
renderer.clearScreen();
|
||||
|
||||
const auto pageWidth = renderer.getScreenWidth();
|
||||
renderer.drawCenteredText(UI_12_FONT_ID, 10, "CrossPoint Reader", true, BOLD);
|
||||
const auto pageHeight = renderer.getScreenHeight();
|
||||
|
||||
// Draw selection
|
||||
renderer.fillRect(0, 60 + selectorIndex * 30 - 2, pageWidth - 1, 30);
|
||||
constexpr int margin = 20;
|
||||
constexpr int bottomMargin = 60;
|
||||
|
||||
int menuY = 60;
|
||||
int menuIndex = 0;
|
||||
// --- 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;
|
||||
|
||||
if (hasContinueReading) {
|
||||
// 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);
|
||||
// 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);
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
// 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;
|
||||
|
||||
renderer.drawText(UI_10_FONT_ID, 20, menuY, continueLabel.c_str(), selectorIndex != menuIndex);
|
||||
menuY += 30;
|
||||
menuIndex++;
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
renderer.drawText(UI_10_FONT_ID, 20, menuY, "Browse", selectorIndex != menuIndex);
|
||||
menuY += 30;
|
||||
menuIndex++;
|
||||
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));
|
||||
}
|
||||
|
||||
renderer.drawText(UI_10_FONT_ID, 20, menuY, "File transfer", selectorIndex != menuIndex);
|
||||
menuY += 30;
|
||||
menuIndex++;
|
||||
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);
|
||||
|
||||
renderer.drawText(UI_10_FONT_ID, 20, menuY, "Settings", selectorIndex != menuIndex);
|
||||
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("...");
|
||||
|
||||
const auto labels = mappedInput.mapLabels("Back", "Confirm", "Left", "Right");
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
// 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");
|
||||
}
|
||||
|
||||
// --- 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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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");
|
||||
renderer.drawButtonHints(UI_10_FONT_ID, labels.btn1, labels.btn2, labels.btn3, labels.btn4);
|
||||
|
||||
ScreenComponents::drawBattery(renderer, 20, pageHeight - 70);
|
||||
|
||||
renderer.displayBuffer();
|
||||
}
|
||||
|
||||
@ -13,6 +13,8 @@ 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, 10, "File Transfer", true, BOLD);
|
||||
renderer.drawCenteredText(UI_12_FONT_ID, 15, "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, 10, "WiFi Networks", true, BOLD);
|
||||
renderer.drawCenteredText(UI_12_FONT_ID, 15, "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,6 +65,16 @@ 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();
|
||||
@ -411,8 +421,7 @@ 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 - 2;
|
||||
int percentageTextWidth = 0;
|
||||
const auto textY = screenHeight - orientedMarginBottom - 4;
|
||||
int progressTextWidth = 0;
|
||||
|
||||
if (showProgress) {
|
||||
@ -429,42 +438,13 @@ void EpubReaderActivity::renderStatusBar(const int orientedMarginRight, const in
|
||||
}
|
||||
|
||||
if (showBattery) {
|
||||
// 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);
|
||||
ScreenComponents::drawBattery(renderer, orientedMarginLeft, textY);
|
||||
}
|
||||
|
||||
if (showChapterTitle) {
|
||||
// Centered chatper title text
|
||||
// Page width minus existing content with 30px padding on each side
|
||||
const int titleMarginLeft = 20 + percentageTextWidth + 30 + orientedMarginLeft;
|
||||
const int titleMarginLeft = 50 + 30 + orientedMarginLeft; // 50px for battery
|
||||
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, 10, "Select Chapter", true, BOLD);
|
||||
renderer.drawCenteredText(UI_12_FONT_ID, 15, "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, 10, "Books", true, BOLD);
|
||||
renderer.drawCenteredText(UI_12_FONT_ID, 15, "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, 10, "Select Chapter", true, BOLD);
|
||||
renderer.drawCenteredText(UI_12_FONT_ID, 15, "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, 10, "Update", true, BOLD);
|
||||
renderer.drawCenteredText(UI_12_FONT_ID, 15, "Update", true, BOLD);
|
||||
|
||||
if (state == CHECKING_FOR_UPDATE) {
|
||||
renderer.drawCenteredText(UI_10_FONT_ID, 300, "Checking for update...", true, BOLD);
|
||||
|
||||
@ -23,12 +23,15 @@ const SettingInfo settingsList[settingsCount] = {
|
||||
{"Front Button Layout",
|
||||
SettingType::ENUM,
|
||||
&CrossPointSettings::frontButtonLayout,
|
||||
{"Bck, Cnfrm, Lft, Rght", "Lft, Rght, Bck, Cnfrm"}},
|
||||
{"Bck, Cnfrm, Lft, Rght", "Lft, Rght, Bck, Cnfrm", "Lft, Bck, Cnfrm, Rght"}},
|
||||
{"Side Button Layout (reader)",
|
||||
SettingType::ENUM,
|
||||
&CrossPointSettings::sideButtonLayout,
|
||||
{"Prev, Next", "Next, Prev"}},
|
||||
{"Reader Font Family", SettingType::ENUM, &CrossPointSettings::fontFamily, {"Aleo", "Noto Sans", "Open Dyslexic"}},
|
||||
{"Reader Font Family",
|
||||
SettingType::ENUM,
|
||||
&CrossPointSettings::fontFamily,
|
||||
{"Bookerly", "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, {}},
|
||||
@ -160,7 +163,7 @@ void SettingsActivity::render() const {
|
||||
const auto pageHeight = renderer.getScreenHeight();
|
||||
|
||||
// Draw header
|
||||
renderer.drawCenteredText(UI_12_FONT_ID, 10, "Settings", true, BOLD);
|
||||
renderer.drawCenteredText(UI_12_FONT_ID, 15, "Settings", true, BOLD);
|
||||
|
||||
// Draw selection
|
||||
renderer.fillRect(0, 60 + selectedSettingIndex * 30 - 2, pageWidth - 1, 30);
|
||||
@ -169,11 +172,6 @@ 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 ALEO_12_FONT_ID (2101191384)
|
||||
#define ALEO_14_FONT_ID (-1834656672)
|
||||
#define ALEO_16_FONT_ID (-1982848762)
|
||||
#define ALEO_18_FONT_ID (-365302307)
|
||||
#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 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 (-706443385)
|
||||
#define SMALL_FONT_ID (-874196069)
|
||||
|
||||
54
src/main.cpp
54
src/main.cpp
@ -40,26 +40,30 @@ GfxRenderer renderer(einkDisplay);
|
||||
Activity* currentActivity;
|
||||
|
||||
// Fonts
|
||||
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 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 notosans12RegularFont(¬osans_12_regular);
|
||||
EpdFont notosans12BoldFont(¬osans_12_bold);
|
||||
@ -111,7 +115,7 @@ EpdFont opendyslexic14BoldItalicFont(&opendyslexic_14_bolditalic);
|
||||
EpdFontFamily opendyslexic14FontFamily(&opendyslexic14RegularFont, &opendyslexic14BoldFont, &opendyslexic14ItalicFont,
|
||||
&opendyslexic14BoldItalicFont);
|
||||
|
||||
EpdFont smallFont(&spacegrotesk);
|
||||
EpdFont smallFont(¬osans_8_regular);
|
||||
EpdFontFamily smallFontFamily(&smallFont);
|
||||
|
||||
EpdFont ui10RegularFont(&ubuntu_10_regular);
|
||||
@ -227,10 +231,10 @@ void onGoHome() {
|
||||
void setupDisplayAndFonts() {
|
||||
einkDisplay.begin();
|
||||
Serial.printf("[%lu] [ ] Display initialized\n", millis());
|
||||
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(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(NOTOSANS_12_FONT_ID, notosans12FontFamily);
|
||||
renderer.insertFont(NOTOSANS_14_FONT_ID, notosans14FontFamily);
|
||||
renderer.insertFont(NOTOSANS_16_FONT_ID, notosans16FontFamily);
|
||||
|
||||
@ -50,6 +50,14 @@ 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) {
|
||||
@ -157,15 +165,16 @@ void CrossPointWebServer::handleStatus() const {
|
||||
// Get correct IP based on AP vs STA mode
|
||||
const String ipAddr = apMode ? WiFi.softAPIP().toString() : WiFi.localIP().toString();
|
||||
|
||||
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 += "}";
|
||||
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;
|
||||
serializeJson(doc, json);
|
||||
server->send(200, "application/json", json);
|
||||
}
|
||||
|
||||
@ -220,6 +229,7 @@ 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();
|
||||
@ -254,12 +264,15 @@ void CrossPointWebServer::handleFileListData() const {
|
||||
char output[512];
|
||||
constexpr size_t outputSize = sizeof(output);
|
||||
bool seenFirst = false;
|
||||
scanFiles(currentPath.c_str(), [this, &output, seenFirst](const FileInfo& info) mutable {
|
||||
JsonDocument doc;
|
||||
JsonDocument doc;
|
||||
|
||||
scanFiles(currentPath.c_str(), [this, &output, &doc, seenFirst](const FileInfo& info) mutable {
|
||||
doc.clear();
|
||||
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