add some code
This commit is contained in:
2
managed_components/lvgl__lvgl/scripts/.gitignore
vendored
Normal file
2
managed_components/lvgl__lvgl/scripts/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
CHANGELOG_LAST.md
|
||||
CHANGELOG_LAST.rst
|
||||
1500
managed_components/lvgl__lvgl/scripts/LVGLImage.py
Normal file
1500
managed_components/lvgl__lvgl/scripts/LVGLImage.py
Normal file
File diff suppressed because it is too large
Load Diff
45
managed_components/lvgl__lvgl/scripts/build_html_examples.sh
Normal file
45
managed_components/lvgl__lvgl/scripts/build_html_examples.sh
Normal file
@@ -0,0 +1,45 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
# These variables allow us to specify an alternate repository URL and commit reference
|
||||
# This is particularly useful when running in CI environments for pull requests
|
||||
# where we need to build from the contributor's forked repository
|
||||
REPO_URL="${1:-}"
|
||||
COMMIT_REF="${2:-}"
|
||||
|
||||
export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH"
|
||||
rm -rf emscripten_builder
|
||||
git clone https://github.com/lvgl/lv_sim_emscripten.git emscripten_builder
|
||||
scripts/genexamplelist.sh > emscripten_builder/examplelist.c
|
||||
cd emscripten_builder
|
||||
git submodule update --init -- lvgl
|
||||
cd lvgl
|
||||
if [ -n "$REPO_URL" ] && [ -n "$COMMIT_REF" ]; then
|
||||
echo "Using provided repo URL: $REPO_URL and commit ref: $COMMIT_REF for lvgl submodule"
|
||||
git remote set-url origin "$REPO_URL"
|
||||
git fetch origin
|
||||
git checkout "$COMMIT_REF"
|
||||
else
|
||||
CURRENT_REF="$(git rev-parse HEAD)"
|
||||
echo "Using current commit ref: $CURRENT_REF for lvgl"
|
||||
git checkout "$CURRENT_REF"
|
||||
fi
|
||||
cd ..
|
||||
|
||||
# Generate lv_conf
|
||||
LV_CONF_PATH=`pwd`/lvgl/configs/ci/docs/lv_conf_docs.h
|
||||
|
||||
cp lvgl/lv_conf_template.h $LV_CONF_PATH
|
||||
python ./lvgl/scripts/generate_lv_conf.py \
|
||||
--template lvgl/lv_conf_template.h \
|
||||
--config $LV_CONF_PATH \
|
||||
--defaults lvgl/configs/ci/docs/lv_conf_docs.defaults
|
||||
|
||||
mkdir cmbuild
|
||||
cd cmbuild
|
||||
emcmake cmake .. -DLV_BUILD_CONF_PATH=$LV_CONF_PATH -DLVGL_CHOSEN_DEMO=lv_example_noop -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache
|
||||
emmake make -j$(nproc)
|
||||
rm -rf CMakeFiles
|
||||
cd ../..
|
||||
cp -a emscripten_builder/cmbuild docs/src/_static/built_lv_examples
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,62 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import argparse
|
||||
from argparse import RawTextHelpFormatter
|
||||
import os
|
||||
import sys
|
||||
|
||||
parser = argparse.ArgumentParser(description="""Create fonts for LVGL including the built-in symbols. lv_font_conv needs to be installed. See https://github.com/lvgl/lv_font_conv
|
||||
Example: python built_in_font_gen.py --size 16 -o lv_font_roboto_16.c --bpp 4 -r 0x20-0x7F""", formatter_class=RawTextHelpFormatter)
|
||||
parser.add_argument('-s', '--size',
|
||||
type=int,
|
||||
metavar = 'px',
|
||||
nargs='?',
|
||||
help='Size of the font in px')
|
||||
parser.add_argument('--bpp',
|
||||
type=int,
|
||||
metavar = '1,2,4',
|
||||
nargs='?',
|
||||
help='Bit per pixel')
|
||||
parser.add_argument('-r', '--range',
|
||||
nargs='+',
|
||||
metavar = 'start-end',
|
||||
default=['0x20-0x7F,0xB0,0x2022'],
|
||||
help='Ranges and/or characters to include. Default is 0x20-7F (ASCII). E.g. -r 0x20-0x7F, 0x200, 324')
|
||||
parser.add_argument('--symbols',
|
||||
nargs='+',
|
||||
metavar = 'sym',
|
||||
default=[''],
|
||||
help=u'Symbols to include. E.g. -s ÁÉŐ'.encode('utf-8'))
|
||||
parser.add_argument('--font',
|
||||
metavar = 'file',
|
||||
nargs='?',
|
||||
default='Montserrat-Medium.ttf',
|
||||
help='A TTF or WOFF file')
|
||||
parser.add_argument('-o', '--output',
|
||||
nargs='?',
|
||||
metavar='file',
|
||||
help='Output file name. E.g. my_font_20.c')
|
||||
parser.add_argument('--compressed', action='store_true',
|
||||
help='Compress the bitmaps')
|
||||
parser.add_argument('--subpx', action='store_true',
|
||||
help='3 times wider letters for sub pixel rendering')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.compressed == False:
|
||||
compr = "--no-compress --no-prefilter"
|
||||
else:
|
||||
compr = ""
|
||||
|
||||
if len(args.symbols[0]) != 0:
|
||||
args.symbols[0] = "--symbols " + args.symbols[0]
|
||||
|
||||
subpx = ""
|
||||
if args.subpx: subpx = "--lcd"
|
||||
|
||||
#Built in symbols
|
||||
syms = "61441,61448,61451,61452,61452,61453,61457,61459,61461,61465,61468,61473,61478,61479,61480,61502,61507,61512,61515,61516,61517,61521,61522,61523,61524,61543,61544,61550,61552,61553,61556,61559,61560,61561,61563,61587,61589,61636,61637,61639,61641,61664,61671,61674,61683,61724,61732,61787,61931,62016,62017,62018,62019,62020,62087,62099,62212,62189,62810,63426,63650"
|
||||
|
||||
#Run the command (Add degree and bullet symbol)
|
||||
cmd = "lv_font_conv {} {} --bpp {} --size {} --font {} -r {} {} --font FontAwesome5-Solid+Brands+Regular.woff -r {} --format lvgl -o {} --force-fast-kern-format".format(subpx, compr, args.bpp, args.size, args.font, args.range[0], args.symbols[0], syms, args.output)
|
||||
os.system(cmd)
|
||||
@@ -0,0 +1,99 @@
|
||||
Fonts are (c) Bitstream (see below). DejaVu changes are in public domain.
|
||||
Glyphs imported from Arev fonts are (c) Tavmjong Bah (see below)
|
||||
|
||||
Bitstream Vera Fonts Copyright
|
||||
------------------------------
|
||||
|
||||
Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is
|
||||
a trademark of Bitstream, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of the fonts accompanying this license ("Fonts") and associated
|
||||
documentation files (the "Font Software"), to reproduce and distribute the
|
||||
Font Software, including without limitation the rights to use, copy, merge,
|
||||
publish, distribute, and/or sell copies of the Font Software, and to permit
|
||||
persons to whom the Font Software is furnished to do so, subject to the
|
||||
following conditions:
|
||||
|
||||
The above copyright and trademark notices and this permission notice shall
|
||||
be included in all copies of one or more of the Font Software typefaces.
|
||||
|
||||
The Font Software may be modified, altered, or added to, and in particular
|
||||
the designs of glyphs or characters in the Fonts may be modified and
|
||||
additional glyphs or characters may be added to the Fonts, only if the fonts
|
||||
are renamed to names not containing either the words "Bitstream" or the word
|
||||
"Vera".
|
||||
|
||||
This License becomes null and void to the extent applicable to Fonts or Font
|
||||
Software that has been modified and is distributed under the "Bitstream
|
||||
Vera" names.
|
||||
|
||||
The Font Software may be sold as part of a larger software package but no
|
||||
copy of one or more of the Font Software typefaces may be sold by itself.
|
||||
|
||||
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 BITSTREAM OR THE GNOME
|
||||
FOUNDATION 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.
|
||||
|
||||
Except as contained in this notice, the names of Gnome, the Gnome
|
||||
Foundation, and Bitstream Inc., shall not be used in advertising or
|
||||
otherwise to promote the sale, use or other dealings in this Font Software
|
||||
without prior written authorization from the Gnome Foundation or Bitstream
|
||||
Inc., respectively. For further information, contact: fonts at gnome dot
|
||||
org.
|
||||
|
||||
Arev Fonts Copyright
|
||||
------------------------------
|
||||
|
||||
Copyright (c) 2006 by Tavmjong Bah. All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the fonts accompanying this license ("Fonts") and
|
||||
associated documentation files (the "Font Software"), to reproduce
|
||||
and distribute the modifications to the Bitstream Vera Font Software,
|
||||
including without limitation the rights to use, copy, merge, publish,
|
||||
distribute, and/or sell copies of the Font Software, and to permit
|
||||
persons to whom the Font Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright and trademark notices and this permission notice
|
||||
shall be included in all copies of one or more of the Font Software
|
||||
typefaces.
|
||||
|
||||
The Font Software may be modified, altered, or added to, and in
|
||||
particular the designs of glyphs or characters in the Fonts may be
|
||||
modified and additional glyphs or characters may be added to the
|
||||
Fonts, only if the fonts are renamed to names not containing either
|
||||
the words "Tavmjong Bah" or the word "Arev".
|
||||
|
||||
This License becomes null and void to the extent applicable to Fonts
|
||||
or Font Software that has been modified and is distributed under the
|
||||
"Tavmjong Bah Arev" names.
|
||||
|
||||
The Font Software may be sold as part of a larger software package but
|
||||
no copy of one or more of the Font Software typefaces may be sold by
|
||||
itself.
|
||||
|
||||
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
|
||||
TAVMJONG BAH 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.
|
||||
|
||||
Except as contained in this notice, the name of Tavmjong Bah shall not
|
||||
be used in advertising or otherwise to promote the sale, use or other
|
||||
dealings in this Font Software without prior written authorization
|
||||
from Tavmjong Bah. For further information, contact: tavmjong @ free
|
||||
. fr.
|
||||
|
||||
$Id: LICENSE 2133 2007-11-28 02:46:28Z lechimp $
|
||||
@@ -0,0 +1,165 @@
|
||||
Fonticons, Inc. (https://fontawesome.com)
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Font Awesome Free License
|
||||
|
||||
Font Awesome Free is free, open source, and GPL friendly. You can use it for
|
||||
commercial projects, open source projects, or really almost whatever you want.
|
||||
Full Font Awesome Free license: https://fontawesome.com/license/free.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
# Icons: CC BY 4.0 License (https://creativecommons.org/licenses/by/4.0/)
|
||||
|
||||
The Font Awesome Free download is licensed under a Creative Commons
|
||||
Attribution 4.0 International License and applies to all icons packaged
|
||||
as SVG and JS file types.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
# Fonts: SIL OFL 1.1 License
|
||||
|
||||
In the Font Awesome Free download, the SIL OFL license applies to all icons
|
||||
packaged as web and desktop font files.
|
||||
|
||||
Copyright (c) 2022 Fonticons, Inc. (https://fontawesome.com)
|
||||
with Reserved Font Name: "Font Awesome".
|
||||
|
||||
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:
|
||||
http://scripts.sil.org/OFL
|
||||
|
||||
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.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
# Code: MIT License (https://opensource.org/licenses/MIT)
|
||||
|
||||
In the Font Awesome Free download, the MIT license applies to all non-font and
|
||||
non-icon files.
|
||||
|
||||
Copyright 2022 Fonticons, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in the
|
||||
Software without restriction, including without limitation the rights to use, copy,
|
||||
modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
and to permit persons to whom the Software is furnished to do so, subject to the
|
||||
following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
# Attribution
|
||||
|
||||
Attribution is required by MIT, SIL OFL, and CC BY licenses. Downloaded Font
|
||||
Awesome Free files already contain embedded comments with sufficient
|
||||
attribution, so you shouldn't need to do anything additional when using these
|
||||
files normally.
|
||||
|
||||
We've kept attribution comments terse, so we ask that you do not actively work
|
||||
to remove them from files, especially code. They're a great way for folks to
|
||||
learn about Font Awesome.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
# Brand Icons
|
||||
|
||||
All brand icons are trademarks of their respective owners. The use of these
|
||||
trademarks does not indicate endorsement of the trademark holder by Font
|
||||
Awesome, nor vice versa. **Please do not use brand logos for any purpose except
|
||||
to represent the company, product, or service to which they refer.**
|
||||
@@ -0,0 +1,93 @@
|
||||
Copyright 2011 The Montserrat Project Authors (https://github.com/JulietaUla/Montserrat)
|
||||
|
||||
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:
|
||||
http://scripts.sil.org/OFL
|
||||
|
||||
|
||||
-----------------------------------------------------------
|
||||
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.
|
||||
@@ -0,0 +1,96 @@
|
||||
Copyright 2014-2021 Adobe (http://www.adobe.com/), with Reserved Font
|
||||
Name 'Source'. Source is a trademark of Adobe in the United States
|
||||
and/or other countries.
|
||||
|
||||
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:
|
||||
http://scripts.sil.org/OFL
|
||||
|
||||
-----------------------------------------------------------
|
||||
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.
|
||||
@@ -0,0 +1,275 @@
|
||||
<html>
|
||||
<meta charset="UTF-8" />
|
||||
<head>
|
||||
<title>Unscii - a bitmapped Unicode font for blocky graphics</title>
|
||||
<style>
|
||||
<!--
|
||||
@font-face{font-family:"unscii16";
|
||||
src: url("unscii-16.woff") format("woff"),
|
||||
url("unscii-16.ttf") format("ttf"); }
|
||||
@font-face{font-family:"unscii8";
|
||||
src: url("unscii-8.woff") format("woff"),
|
||||
url("unscii-8.ttf") format("ttf"); }
|
||||
a{color:#003;}
|
||||
ul{list-style-type:square;}
|
||||
h1{font-family:"unscii16",monospace;font-size:32px;text-align:center;}
|
||||
body{font-family:"unscii16",monospace; background-color:#ccc;color:#000;width:640px;}
|
||||
pre{font-family:"unscii16",monospace; font-size:16px;line-height:16px}
|
||||
-->
|
||||
</style>
|
||||
<body>
|
||||
|
||||
<p align="center"><img src="unsciilogo.png" alt="UNSCII" /></p>
|
||||
|
||||
<p>Unscii is a set of bitmapped Unicode fonts based on classic system fonts.
|
||||
Unscii attempts to support character cell art well while also being suitable
|
||||
for terminal and programming use.</p>
|
||||
|
||||
<p>The two main variants are unscii-8 (8×8 pixels per glyph) and unscii-16
|
||||
(8×16). There are also several alternative styles for unscii-8, as well as
|
||||
an 8x16 "full" variant that incorporates missing Unicode glyphs from
|
||||
Fixedsys Excelsior and GNU Unifont. "unscii-16-full" falls under GPL because
|
||||
of how Unifont is licensed; the other variants are in the Public Domain.</p>
|
||||
|
||||
<p>Unscii was created by Viznut.</p>
|
||||
|
||||
<br />
|
||||
|
||||
<h1>UNSCII 2.0</h1>
|
||||
|
||||
<p>In 2020-03-10, the new <a
|
||||
href="http://www.unicode.org/versions/Unicode13.0.0/">Unicode version
|
||||
13.0</a> added 214 graphics characters for "legacy computing" (including,
|
||||
among all, the missing PETSCII characters, and a majority of missing
|
||||
Teletext/Videotex characters). Most of these were already included in Unscii
|
||||
1.x, but now I have been able to give them proper Unicode mappings as well.
|
||||
This is the main reason for the Unscii 2.0 release.</p>
|
||||
|
||||
<p>Additionally, Unscii 2.0 fixes errors in some characters, legibility in
|
||||
some others and adds a bunch of new ones.</p>
|
||||
|
||||
<p>A test picture representing what is currently available in Unicode (feel
|
||||
free to copy-paste it to your editor to see what it looks like in other
|
||||
fonts):</p>
|
||||
|
||||
<pre>
|
||||
╎┆┊ ╱🭽▔🭾╲ 🮲🮳 🮸🮀🮵🮶🮀🮁🮁🮀🮼🯁🯂🯃 ▵ ↑ ◬
|
||||
╶─╴╺━╸ ═ ╎┆┊ ⎹ ⎸▣⎹ ⎸ ▝▛▀▜▘ 🯲🯷🯶 △ ▴ ╽ ◭⬘◮
|
||||
╷┌┬┐┍┯┑╒╤╕╏┇┋ 🮷 🭼▁🭿 ⎸ ▚▌█▐▞ 🯹🯵🯱 🯰 ▁▂▃▄▅▆▇█ ◃◅◁╳▷▻▹ ▲ ←╼╋╾→ ◩⬒⬔
|
||||
│├┼┤┝┿┥╞╪╡╏┇┋ ⎹╱ ╳ ╲⎸ ▗▙▄▟▖ 🯴🯳🯸 █🮆🮅🮄▀🮃🮂▔⎹ ▽ ◂◄◀🮽▶►▸╿ ⮝ ⬖◧◫◨⬗
|
||||
╵└┴┘┕┷┙╘╧╛┞╀┦ ▔▔▔▔▔ 🬑🬜🬰🬪🬟 🮞🮟 ▕▉ ◞◡◯◡ ◎🭵 ▿ ▼ ↓ ⮜◈⮞ ⬕⬓◪
|
||||
╻┎┰┒┏┳┓ ┭╆╈╅┮╍╍╌╌ 🬥🬦🬍🬲🬵🬹🬱🬷🬌🬓🬙 🮝🮜 🮇▊◝◠◯◉◯◡◟🭴 ▾ ⮟ ◕ ⬙ ◔
|
||||
┃┠╂┨┣╋┫ ╺┽╊◙╉┾┅┅┄┄ 🬔🬡🬖🬻🬞🬭🬏🬺🬢🬒🬧 🮈▋◍ ◠◯◠◜ 🭳 ◿◺
|
||||
╹┖┸┚┗┻┛ ━┵╄╇╃┶┉┉┈┈ 🬃🬤🬫🬴🬠🬋🬐🬸🬛🬗🬇 🭇🬼 ▐▌ ◌🮣🮢 🮦 🭲 ◹◸ 🭯 🮀⚞⚟🮀 🯊 ◙◛◶─◵
|
||||
╓╥╖ ╔╦╗┢╁┪ ┟┱┲┧ 🬣🬯🬈🬬🬁🬂🬀🬝🬅🬮🬘 🭢🭗 🮉▍ 🮤🮪🮫🮥🮧 🭱 🭯 🭮◙🭬╭──╮⎫🮻⎧ ◘◙│◲┼◱╭◒╮
|
||||
║╟╫╢🮐🮒🮐╠╬╣ ╹┃ ┡┹┺┩ 🬳🬉🬩🬕🬊🬎🬆🬨🬚🬄🬶 🭊🬿 🮊▎ 🮩🮬🮭🮨 🭰 ◢🭫◣ 🮚 │ ▢ ⎮🏎⎪ ◙◚◷┼◴│◑╋◐
|
||||
╙╨╜🮔 ╚╩╝ 🯆 🯅 🯇 🮣🮢 🯉 🯈 🭥🭚 🮋▏🮮 🮡🮠 ⎸🭮🭪◆🭨🮛🮿🭬╰─🮯─╯⎬⎯⎨ ◳─◰╰◓╯
|
||||
░░🮐🮑🮐▓▓██🮗🮗▤▤▥▥▦▦▩▩▧▧🮘🮘🮙🮙▨▨🮕🮕🮖🮖 🭋🭀 █▁🭻🭺🭹🭸🭷🭶▔ ◥🭩◤ 🭭 ⎮⯊⎪ ▱▰ ▭▬
|
||||
░░▒🮎▒▓▓██🮗🮗▤▤▥▥▦▦▩▩▧▧🮘🮘🮙🮙▨▨🮕🮕🮖🮖 🭦🭛 🮰 🭇🬼🭭 🭊🬿 🭋🭀 ⎭⯋⎩ ▯▮ ▫◻□■◼▪⬝·
|
||||
🮌█🮍 ╲╱ 🭇🬼🭈🬽🭉🬾◢◣🭇🭃🭎🬼🭈🭆🭂🭍🭑🬽🭉🭁🭌🬾🭈🭄🭏🬽🭅🭐 ◦○◯⬤◖◗ ⬫⬦⬨♢◊◇◆♦⬧⬥⬩⬪
|
||||
▒🮏▒ 🭢🭗🭣🭘🭤🭙◥◤🭢🭔🭟🭗🭣🭧🭓🭞🭜🭘🭤🭒🭝🭙🭣🭕🭠🭘🭖🭡 ∘⭘●
|
||||
🭢🭗 🭥🭚 🭦🭛 •
|
||||
</pre>
|
||||
|
||||
<h1>EXAMPLES</h1>
|
||||
|
||||
<p>Here are some conversions of legacy character set art into Unscii.</p>
|
||||
|
||||
<p>Amiga ansi: Divine Stylers by Hellbeard, as rendered with unscii-16.
|
||||
<a href="http://sixteencolors.net/pack/impure54/xz-dvn.ans">Source</a></p>
|
||||
|
||||
<img src="xz-dvn.png" />
|
||||
|
||||
<p>PC ansi: Ansi Love by Rad Man, as rendered with unscii-16.
|
||||
<a
|
||||
href="http://sixteencolors.net/pack/blocktronics_blockalypse/rad-LOVE.ANS">Source</a></p>
|
||||
|
||||
<img src="rad-love.png" />
|
||||
|
||||
<p>Commodore 64 petscii pictures as rendered with unscii-8, using the
|
||||
256-color xterm palette: I Has Floppy by Redcrab; The First Ball by
|
||||
Dr.TerrorZ; Gary by Mermaid.</p>
|
||||
<p align="center">
|
||||
<img src="ihasfloppy.png" />
|
||||
<img src="thefirstball.png" />
|
||||
<img src="gary.png" />
|
||||
</p>
|
||||
|
||||
<p>The source code package includes a generic bitmap-to-unscii converter. Here's an
|
||||
example of a conversion to unscii-8 using the 256-color xterm
|
||||
palette, without dithering:</p>
|
||||
<p align="center">
|
||||
<img src="tta.png" />
|
||||
</p>
|
||||
|
||||
<br />
|
||||
|
||||
<h1>DOWNLOADS</h1>
|
||||
|
||||
<p>HEX and PCF are the only actual bitmapped formats here. HEX is the same
|
||||
simple hexdump format as used by the Unifont project. TTF, OTF and WOFF
|
||||
are vectorized.</p>
|
||||
|
||||
<p>NOTE: Due to format limitations, the PCF versions lack all the characters
|
||||
above U+FFFF! However, all the new graphics characters are provided in the
|
||||
good old PUA range as well. A mapping is in the file <a
|
||||
href="uns2uni.tr">uns2uni.tr</a>.</p>
|
||||
|
||||
<table>
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
<img src="unscii16.png" alt="[Some Unscii16 glyphs]" />
|
||||
</td><td>
|
||||
<p>unscii-16: <a href="unscii-16.hex">hex</a> <a href="unscii-16.pcf">pcf</a> <a href="unscii-16.ttf">ttf</a> <a href="unscii-16.otf">otf</a> <a href="unscii-16.woff">woff</a><br />
|
||||
unscii-16-full: <a href="unscii-16-full.hex">hex</a> <a href="unscii-16-full.pcf">pcf</a> <a href="unscii-16-full.ttf">ttf</a> <a href="unscii-16-full.otf">otf</a> <a href="unscii-16-full.woff">woff</a><br />
|
||||
8x16. The latter is recommended for serious terminal use where a large
|
||||
Unicode coverage is needed. (Warning: unscii16-full files range from 2
|
||||
to 12 megabytes in size; the others range from 40 to 400 kilobytes.)</p>
|
||||
</td></tr>
|
||||
|
||||
<tr bgcolor="#999">
|
||||
<td>
|
||||
<img src="unscii8.png" alt="[Some Unscii8 glyphs]" />
|
||||
</td><td>
|
||||
<p>unscii-8: <a href="unscii-8.hex">hex</a> <a href="unscii-8.pcf">pcf</a> <a href="unscii-8.ttf">ttf</a> <a href="unscii-8.otf">otf</a> <a href="unscii-8.woff">woff</a></p>
|
||||
</td></tr>
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
<img src="unscii8-tall.png" alt="[Ascii range in Unscii8-tall" />
|
||||
</td><td>
|
||||
<p>unscii-8-tall: <a href="unscii-8-tall.hex">hex</a> <a href="unscii-8-tall.pcf">pcf</a> <a href="unscii-8-tall.ttf">ttf</a> <a href="unscii-8-tall.otf">otf</a> <a href="unscii-8-tall.woff">woff</a><br />
|
||||
Double-height version of unscii8.</p>
|
||||
</td></tr>
|
||||
|
||||
<tr bgcolor="#999">
|
||||
<td>
|
||||
<img src="unscii8-thin.png" alt="[Ascii range in Unscii8-tall" />
|
||||
</td><td>
|
||||
<p>unscii-8-thin: <a href="unscii-8-thin.hex">hex</a> <a href="unscii-8-thin.pcf">pcf</a> <a href="unscii-8-thin.ttf">ttf</a> <a href="unscii-8-thin.otf">otf</a> <a href="unscii-8-thin.woff">woff</a><br />
|
||||
Based on system fonts with 1-pixel-wide lines.</p>
|
||||
</td></tr>
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
<img src="unscii8-alt.png" alt="[Ascii range in Unscii8-alt" />
|
||||
</td><td>
|
||||
<p>unscii-8-alt: <a href="unscii-8-alt.hex">hex</a> <a href="unscii-8-alt.pcf">pcf</a> <a href="unscii-8-alt.ttf">ttf</a> <a href="unscii-8-alt.otf">otf</a> <a href="unscii-8-alt.woff">woff</a><br />
|
||||
Based on the more peculiar glyph forms of the reference fonts.</p>
|
||||
</td></tr>
|
||||
|
||||
<tr bgcolor="#999">
|
||||
<td>
|
||||
<img src="unscii8-mcr.png" alt="[Ascii range in Unscii8-alt" />
|
||||
</td><td>
|
||||
<p>unscii-8-mcr: <a href="unscii-8-mcr.hex">hex</a> <a href="unscii-8-mcr.pcf">pcf</a> <a href="unscii-8-mcr.ttf">ttf</a> <a href="unscii-8-mcr.otf">otf</a> <a href="unscii-8-mcr.woff">woff</a><br />
|
||||
Based on retrofuturistic MCR-like 8×8 fonts used in various games, demos,
|
||||
etc.</p>
|
||||
</td></tr>
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
<img src="unscii8-fantasy.png" alt="[Ascii range in Unscii8-alt" />
|
||||
</td><td>
|
||||
<p>unscii-8-fantasy: <a href="unscii-8-fantasy.hex">hex</a> <a href="unscii-8-fantasy.pcf">pcf</a> <a href="unscii-8-fantasy.ttf">ttf</a> <a href="unscii-8-fantasy.otf">otf</a> <a href="unscii-8-fantasy.woff">woff</a><br />
|
||||
Based on fonts used in fantasy games.</p>
|
||||
</td></tr>
|
||||
|
||||
<tr bgcolor="#999">
|
||||
<td>
|
||||
|
||||
</td><td>
|
||||
<p><a href="unscii-2.1-src.tar.gz">Source code for current Unscii version (2.1)</a></p>
|
||||
<p><a href="unscii-2.0-src.tar.gz">Source code for Unscii 2.0</a></p>
|
||||
<p><a href="unscii-1.1-src.tar.gz">Source code for Unscii 1.1</a></p>
|
||||
</td></tr>
|
||||
|
||||
</table>
|
||||
|
||||
<br />
|
||||
|
||||
<h1>BACKSTORY</h1>
|
||||
|
||||
<p>Years ago, I noticed that Unicode had a bunch of pseudographic characters
|
||||
that could be used to enrichen Ansi art. However, no one seemed to use them.
|
||||
Even MUDs that used the 256-color Xterm palette and had no issues with
|
||||
Unicode still preferred to stick to the blocks available in the MS-DOS
|
||||
codepage 437.</p>
|
||||
|
||||
<p>After looking into existing Unicode fonts, the reason became obvious: the
|
||||
implementation of non-CP437 graphics characters was shaky at best. Unicode
|
||||
Consortium doesn't even care how pseudographics are implemented. It was a
|
||||
kind of chicken-and-egg problem: No commonly accepted Unicode graphics font,
|
||||
no Unicode art scene; no art scene, no font support. The idea of an
|
||||
art-compatible Unicode font was born.</p>
|
||||
|
||||
<p>For Unscii, I studied a bunch of classic system fonts and how their
|
||||
characters had been used in Ascii and "extended-Ascii" art.</p>
|
||||
|
||||
<p>8×8 system fonts can be divided in two major categories according to
|
||||
their line thickness: 1-pixel and 2-pixel. 2-pixel-wide lines are used in
|
||||
more prominent classic systems, so I chose it. Also, 2-pixel 8×8 system
|
||||
fonts are surprisingly similar to one another which made it easier to choose
|
||||
neutral shapes.</p>
|
||||
|
||||
<p>The basic look of the 8×8 variant of Unscii is based on the following
|
||||
systems:</p>
|
||||
<ul>
|
||||
<li>Amiga (Topaz-8)</li>
|
||||
<li>Amstrad CPC</li>
|
||||
<li>Atari 8-bit (as in 800, XL etc.)</li>
|
||||
<li>Atari Arcade (the iconic ROM font)</li>
|
||||
<li>Atari 32-bit (as in ST etc.)</li>
|
||||
<li>BBC Micro (graphics mode font)</li>
|
||||
<li>Commodore 64</li>
|
||||
<li>IBM PC (the 8×8 ROM font as in CGA, or VGA 80×50)</li>
|
||||
</ul>
|
||||
|
||||
<p>The 8×16 variant of Unscii has been mostly derived from the 8×8 variant
|
||||
by using a set of transformation principles. When in doubt, the following
|
||||
fonts have been looked at for additional reference:</p>
|
||||
<ul>
|
||||
<li>Windows Fixedsys 8×15 (and its modern successor Fixedsys Excelsior)</li>
|
||||
<li>IBM PC VGA ROM font(s) (and their modern successor U_VGA)</li>
|
||||
<li>X Window System fonts 8x13(B) and 9x15(B)</li>
|
||||
<li>Classic Macintosh 12-point Monaco</li>
|
||||
<li>Digital VT420 10×16 font (used in the 80×24 mode)</li>
|
||||
<li>Modern monospaced vector fonts: DejaVu Sans Mono, Lucida Console,
|
||||
Inconsolata</li>
|
||||
</ul>
|
||||
|
||||
<p>In general, neutral shapes are preferred, unless art, legibility or
|
||||
readability require otherwise: The characters /\XY are connective because of
|
||||
their connetive use in ascii art, and the serifs in iIl are longer than in
|
||||
most classic systems.</p>
|
||||
|
||||
<p>Whenever a 8×16 shape has not been defined, Unscii falls back to
|
||||
height-doubled 8×8.</p>
|
||||
|
||||
<p>I also studied game fonts and thin-line system fonts. This resulted in
|
||||
the variants unscii-8-thin, unscii-8-mcr and unscii-8-fantasy.</p>
|
||||
|
||||
<p>When studying legacy character sets, I found literally hundreds of
|
||||
characters without proper Unicode codepoints. These are mapped in the PUA
|
||||
range as follows:</p>
|
||||
|
||||
<ul>
|
||||
<li>U+E080..E0FF: Teletext/Videotex block mosaics.</li>
|
||||
<li>U+E100..: The most prominent and useful non-Unicode pseudographics:
|
||||
everything found in PETSCII, Videotex smooth mosaics, extra shades,
|
||||
round corners, X/Y doublers.</li>
|
||||
<li>U+E800..: Somewhat stranger but still potentially useful: junctions with
|
||||
border-aligned lines, diagonal line junctions, non-straight lines, weirder
|
||||
fill patterns, etc.</li>
|
||||
<li>U+EC00..: Total oddities. Mostly game-oriented bitmaps and other
|
||||
depictive characters from Sharp MZ, Aquarius, etc.</li>
|
||||
</ul>
|
||||
|
||||
<p>Since Unicode 13.0, many of these are also available in Unicode, but
|
||||
the PUA mappings are retained for compatibility.</p>
|
||||
|
||||
<br />
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,91 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import os
|
||||
|
||||
print("Generating 8 px")
|
||||
os.system("./built_in_font_gen.py --size 8 -o lv_font_montserrat_8.c --bpp 4")
|
||||
|
||||
print("\nGenerating 10 px")
|
||||
os.system("./built_in_font_gen.py --size 10 -o lv_font_montserrat_10.c --bpp 4")
|
||||
|
||||
print("\nGenerating 12 px")
|
||||
os.system("./built_in_font_gen.py --size 12 -o lv_font_montserrat_12.c --bpp 4")
|
||||
|
||||
print("\nGenerating 14 px")
|
||||
os.system("./built_in_font_gen.py --size 14 -o lv_font_montserrat_14.c --bpp 4")
|
||||
|
||||
print("\nGenerating 16 px")
|
||||
os.system("./built_in_font_gen.py --size 16 -o lv_font_montserrat_16.c --bpp 4")
|
||||
|
||||
print("\nGenerating 18 px")
|
||||
os.system("./built_in_font_gen.py --size 18 -o lv_font_montserrat_18.c --bpp 4")
|
||||
|
||||
print("\nGenerating 20 px")
|
||||
os.system("./built_in_font_gen.py --size 20 -o lv_font_montserrat_20.c --bpp 4")
|
||||
|
||||
print("\nGenerating 22 px")
|
||||
os.system("./built_in_font_gen.py --size 22 -o lv_font_montserrat_22.c --bpp 4")
|
||||
|
||||
print("\nGenerating 24 px")
|
||||
os.system("./built_in_font_gen.py --size 24 -o lv_font_montserrat_24.c --bpp 4")
|
||||
|
||||
print("\nGenerating 26 px")
|
||||
os.system("./built_in_font_gen.py --size 26 -o lv_font_montserrat_26.c --bpp 4")
|
||||
|
||||
print("\nGenerating 28 px")
|
||||
os.system("./built_in_font_gen.py --size 28 -o lv_font_montserrat_28.c --bpp 4")
|
||||
|
||||
print("\nGenerating 30 px")
|
||||
os.system("./built_in_font_gen.py --size 30 -o lv_font_montserrat_30.c --bpp 4")
|
||||
|
||||
print("\nGenerating 32 px")
|
||||
os.system("./built_in_font_gen.py --size 32 -o lv_font_montserrat_32.c --bpp 4")
|
||||
|
||||
print("\nGenerating 34 px")
|
||||
os.system("./built_in_font_gen.py --size 34 -o lv_font_montserrat_34.c --bpp 4")
|
||||
|
||||
print("\nGenerating 36 px")
|
||||
os.system("./built_in_font_gen.py --size 36 -o lv_font_montserrat_36.c --bpp 4")
|
||||
|
||||
print("\nGenerating 38 px")
|
||||
os.system("./built_in_font_gen.py --size 38 -o lv_font_montserrat_38.c --bpp 4")
|
||||
|
||||
print("\nGenerating 40 px")
|
||||
os.system("./built_in_font_gen.py --size 40 -o lv_font_montserrat_40.c --bpp 4")
|
||||
|
||||
print("\nGenerating 42 px")
|
||||
os.system("./built_in_font_gen.py --size 42 -o lv_font_montserrat_42.c --bpp 4")
|
||||
|
||||
print("\nGenerating 44 px")
|
||||
os.system("./built_in_font_gen.py --size 44 -o lv_font_montserrat_44.c --bpp 4")
|
||||
|
||||
print("\nGenerating 46 px")
|
||||
os.system("./built_in_font_gen.py --size 46 -o lv_font_montserrat_46.c --bpp 4")
|
||||
|
||||
print("\nGenerating 48 px")
|
||||
os.system("./built_in_font_gen.py --size 48 -o lv_font_montserrat_48.c --bpp 4")
|
||||
|
||||
print("\nGenerating 12 px subpx")
|
||||
os.system("./built_in_font_gen.py --size 12 -o lv_font_montserrat_12_subpx.c --bpp 4 --subpx")
|
||||
|
||||
print("\nGenerating 28 px compressed")
|
||||
os.system("./built_in_font_gen.py --size 28 -o lv_font_montserrat_28_compressed.c --bpp 4 --compressed")
|
||||
|
||||
print("\nGenerating 16 px Hebrew, Persian")
|
||||
os.system("./built_in_font_gen.py --size 16 -o lv_font_dejavu_16_persian_hebrew.c --bpp 4 --font DejaVuSans.ttf -r 0x20-0x7f,0x5d0-0x5ea,0x600-0x6FF,0xFB50-0xFDFF,0xFE70-0xFEFF")
|
||||
|
||||
print("\nGenerating 14 px CJK")
|
||||
os.system(u"./built_in_font_gen.py --size 14 -o lv_font_source_han_sans_sc_14_cjk.c --bpp 4 --font SourceHanSansSC-Normal.otf -r 0x20-0x7f --symbols (),盗提陽帯鼻画輕ッ冊ェル写父ぁフ結想正四O夫源庭場天續鳥れ講猿苦階給了製守8祝己妳薄泣塩帰ぺ吃変輪那着仍嗯爭熱創味保字宿捨準查達肯ァ薬得査障該降察ね網加昼料等図邪秋コ態品屬久原殊候路願楽確針上被怕悲風份重歡っ附ぷ既4黨價娘朝凍僅際洋止右航よ专角應酸師個比則響健昇豐筆歷適修據細忙跟管長令家ザ期般花越ミ域泳通些油乏ラ。營ス返調農叫樹刊愛間包知把ヤ貧橋拡普聞前ジ建当繰ネ送習渇用補ィ覺體法遊宙ョ酔余利壊語くつ払皆時辺追奇そ們只胸械勝住全沈力光ん深溝二類北面社值試9和五勵ゃ貿幾逐打課ゲて領3鼓辦発評1渉詳暇込计駄供嘛郵頃腦反構絵お容規借身妻国慮剛急乗静必議置克土オ乎荷更肉還混古渡授合主離條値決季晴東大尚央州が嗎験流先医亦林田星晩拿60旅婦量為痛テ孫う環友況玩務其ぼち揺坐一肩腰犯タょ希即果ぶ物練待み高九找やヶ都グ去」サ、气仮雑酒許終企笑録形リ銀切ギ快問滿役単黄集森毎實研喜蘇司鉛洲川条媽ノ才兩話言雖媒出客づ卻現異故り誌逮同訊已視本題ぞを横開音第席費持眾怎選元退限ー賽処喝就残無いガ多ケ沒義遠歌隣錢某雪析嬉採自透き側員予ゼ白婚电へ顯呀始均畫似懸格車騒度わ親店週維億締慣免帳電甚來園浴ゅ愈京と杯各海怒ぜ排敗挙老買7極模実紀ヒ携隻告シ並屋這孩讓質ワブ富賃争康由辞マ火於短樣削弟材注節另室ダ招擁ぃ若套底波行勤關著泊背疲狭作念推ぐ民貸祖介說ビ代温契你我レ入描變再札ソ派頭智遅私聽舉灣山伸放直安ト誕煙付符幅ふ絡她届耳飲忘参革團仕様載ど歩獲嫌息の汚交興魚指資雙與館初学年幸史位柱族走括び考青也共腕Lで販擔理病イ今逃當寺猫邊菓係ム秘示解池影ド文例斷曾事茶寫明科桃藝売便え導禁財飛替而亡到し具空寝辛業ウ府セ國何基菜厳市努張缺雲根外だ断万砂ゴ超使台实ぽ礼最慧算軟界段律像夕丈窓助刻月夏政呼ぴざ擇趣除動従涼方勉名線対存請子氏將5少否諸論美感或西者定食御表は參歳緑命進易性錯房も捕皿判中觀戦ニ緩町ピ番ず金千ろ?不た象治関ャ每看徒卒統じ手範訪押座步号ベ旁以母すほ密減成往歲件緒読歯效院种七謂凝濃嵌震喉繼クュ拭死円2積水欲如ポにさ寒道區精啦姐ア聯能足及停思壓2春且メ裏株官答概黒過氷柿戻厚ぱ党祭織引計け委暗複誘港バ失下村較続神ぇ尤強秀膝兒来績十書済化服破新廠1紹您情半式產系好教暑早め樂地休協良な哪常要揮周かエ麗境働避護ンツ香夜太見設非改広聲他検求危清彼經未在起葉控靴所差內造寄南望尺換向展備眠點完約ぎ裡分説申童優伝島机須塊日立拉,鉄軽單気信很転識支布数紙此迎受心輸坊モ處「訳三曇兄野顔戰增ナ伊列又髪両有取左毛至困吧昔赤狀相夠整別士経頼然簡ホ会發隨営需脱ヨば接永居冬迫圍甘醫誰部充消連弱宇會咲覚姉麼的増首统帶糖朋術商担移景功育庫曲總劃牛程駅犬報ロ學責因パ嚴八世後平負公げ曜陸專午之閉ぬ談ご災昨冷職悪謝對它近射敢意運船臉局難什産頗!球真記ま但蔵究制機案湖臺ひ害券男留内木驗雨施種特復句末濟キ色訴依せ百型る石牠討呢时任執飯歐宅組傳配小活ゆべ暖ズ漸站素らボ束価チ浅回女片独妹英目從認生違策僕楚ペ米こ掛む爸六状落漢プ投カ校做啊洗声探あ割体項履触々訓技ハ低工映是標速善点人デ口次可廿节宵植树端阳旦腊妇费愚劳动儿军师庆圣诞闰".encode('utf-8'))
|
||||
|
||||
print("\nGenerating 16 px CJK")
|
||||
os.system(u"./built_in_font_gen.py --size 16 -o lv_font_source_han_sans_sc_16_cjk.c --bpp 4 --font SourceHanSansSC-Normal.otf -r 0x20-0x7f --symbols (),盗提陽帯鼻画輕ッ冊ェル写父ぁフ結想正四O夫源庭場天續鳥れ講猿苦階給了製守8祝己妳薄泣塩帰ぺ吃変輪那着仍嗯爭熱創味保字宿捨準查達肯ァ薬得査障該降察ね網加昼料等図邪秋コ態品屬久原殊候路願楽確針上被怕悲風份重歡っ附ぷ既4黨價娘朝凍僅際洋止右航よ专角應酸師個比則響健昇豐筆歷適修據細忙跟管長令家ザ期般花越ミ域泳通些油乏ラ。營ス返調農叫樹刊愛間包知把ヤ貧橋拡普聞前ジ建当繰ネ送習渇用補ィ覺體法遊宙ョ酔余利壊語くつ払皆時辺追奇そ們只胸械勝住全沈力光ん深溝二類北面社值試9和五勵ゃ貿幾逐打課ゲて領3鼓辦発評1渉詳暇込计駄供嘛郵頃腦反構絵お容規借身妻国慮剛急乗静必議置克土オ乎荷更肉還混古渡授合主離條値決季晴東大尚央州が嗎験流先医亦林田星晩拿60旅婦量為痛テ孫う環友況玩務其ぼち揺坐一肩腰犯タょ希即果ぶ物練待み高九找やヶ都グ去」サ、气仮雑酒許終企笑録形リ銀切ギ快問滿役単黄集森毎實研喜蘇司鉛洲川条媽ノ才兩話言雖媒出客づ卻現異故り誌逮同訊已視本題ぞを横開音第席費持眾怎選元退限ー賽処喝就残無いガ多ケ沒義遠歌隣錢某雪析嬉採自透き側員予ゼ白婚电へ顯呀始均畫似懸格車騒度わ親店週維億締慣免帳電甚來園浴ゅ愈京と杯各海怒ぜ排敗挙老買7極模実紀ヒ携隻告シ並屋這孩讓質ワブ富賃争康由辞マ火於短樣削弟材注節另室ダ招擁ぃ若套底波行勤關著泊背疲狭作念推ぐ民貸祖介說ビ代温契你我レ入描變再札ソ派頭智遅私聽舉灣山伸放直安ト誕煙付符幅ふ絡她届耳飲忘参革團仕様載ど歩獲嫌息の汚交興魚指資雙與館初学年幸史位柱族走括び考青也共腕Lで販擔理病イ今逃當寺猫邊菓係ム秘示解池影ド文例斷曾事茶寫明科桃藝売便え導禁財飛替而亡到し具空寝辛業ウ府セ國何基菜厳市努張缺雲根外だ断万砂ゴ超使台实ぽ礼最慧算軟界段律像夕丈窓助刻月夏政呼ぴざ擇趣除動従涼方勉名線対存請子氏將5少否諸論美感或西者定食御表は參歳緑命進易性錯房も捕皿判中觀戦ニ緩町ピ番ず金千ろ?不た象治関ャ每看徒卒統じ手範訪押座步号ベ旁以母すほ密減成往歲件緒読歯效院种七謂凝濃嵌震喉繼クュ拭死円2積水欲如ポにさ寒道區精啦姐ア聯能足及停思壓2春且メ裏株官答概黒過氷柿戻厚ぱ党祭織引計け委暗複誘港バ失下村較続神ぇ尤強秀膝兒来績十書済化服破新廠1紹您情半式產系好教暑早め樂地休協良な哪常要揮周かエ麗境働避護ンツ香夜太見設非改広聲他検求危清彼經未在起葉控靴所差內造寄南望尺換向展備眠點完約ぎ裡分説申童優伝島机須塊日立拉,鉄軽單気信很転識支布数紙此迎受心輸坊モ處「訳三曇兄野顔戰增ナ伊列又髪両有取左毛至困吧昔赤狀相夠整別士経頼然簡ホ会發隨営需脱ヨば接永居冬迫圍甘醫誰部充消連弱宇會咲覚姉麼的増首统帶糖朋術商担移景功育庫曲總劃牛程駅犬報ロ學責因パ嚴八世後平負公げ曜陸專午之閉ぬ談ご災昨冷職悪謝對它近射敢意運船臉局難什産頗!球真記ま但蔵究制機案湖臺ひ害券男留内木驗雨施種特復句末濟キ色訴依せ百型る石牠討呢时任執飯歐宅組傳配小活ゆべ暖ズ漸站素らボ束価チ浅回女片独妹英目從認生違策僕楚ペ米こ掛む爸六状落漢プ投カ校做啊洗声探あ割体項履触々訓技ハ低工映是標速善点人デ口次可廿节宵植树端阳旦腊妇费愚劳动儿军师庆圣诞闰".encode('utf-8'))
|
||||
|
||||
print("\nGenerating 8 px unscii")
|
||||
os.system("lv_font_conv --no-compress --no-prefilter --bpp 1 --size 8 --font unscii-8.ttf -r 0x20-0x7F --format lvgl -o lv_font_unscii_8.c --force-fast-kern-format")
|
||||
|
||||
print("\nGenerating 16 px unscii")
|
||||
os.system("lv_font_conv --no-compress --no-prefilter --bpp 1 --size 16 --font unscii-8.ttf -r 0x20-0x7F --format lvgl -o lv_font_unscii_16.c --force-fast-kern-format")
|
||||
|
||||
os.system('sed -i \'s|#include "lvgl/lvgl.h"|#include "../../lvgl.h"|\' lv_font_*.c')
|
||||
os.system('astyle --ignore-exclude-errors --options=../code-format.cfg "lv_font_*.c"')
|
||||
os.system('mv lv_font_*.c ../../src/font/')
|
||||
BIN
managed_components/lvgl__lvgl/scripts/built_in_font/unscii-8.ttf
Normal file
BIN
managed_components/lvgl__lvgl/scripts/built_in_font/unscii-8.ttf
Normal file
Binary file not shown.
122
managed_components/lvgl__lvgl/scripts/changelog-template.hbs
Normal file
122
managed_components/lvgl__lvgl/scripts/changelog-template.hbs
Normal file
@@ -0,0 +1,122 @@
|
||||
{{#each releases}}
|
||||
`{{title}} <{{href}}>`__ {{niceDate}}
|
||||
---------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
Breaking Changes
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
{{#commit-list merges heading='' message='BREAKING CHANGE'}}
|
||||
- .. warning: {{message}} `{{id}} <{{href}}>`__
|
||||
{{/commit-list}}
|
||||
{{#commit-list commits heading='' message='BREAKING CHANGE'}}
|
||||
- .. warning: {{subject}} `{{shorthash}} <{{href}}>`__
|
||||
{{/commit-list}}
|
||||
{{#commit-list fixes heading='' message='BREAKING CHANGE'}}
|
||||
- **{{commit.subject}}** `{{commit.shorthash}} <{{commit.href}}>`__
|
||||
{{/commit-list}}
|
||||
|
||||
Architectural
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
{{#commit-list merges heading='' message='^arch' exclude='BREAKING CHANGE'}}
|
||||
- **{{message}}** `{{id}} <{{href}}>`__
|
||||
{{/commit-list}}
|
||||
{{#commit-list commits heading='' message='^arch' exclude='BREAKING CHANGE'}}
|
||||
- **{{subject}}** `{{shorthash}} <{{href}}>`__
|
||||
{{/commit-list}}
|
||||
{{#commit-list fixes heading='' message='^arch' exclude='BREAKING CHANGE'}}
|
||||
- **{{commit.subject}}** `{{commit.shorthash}} <{{commit.href}}>`__
|
||||
{{/commit-list}}
|
||||
|
||||
New Features
|
||||
~~~~~~~~~~~~
|
||||
|
||||
{{#commit-list merges heading='' message='^feat' exclude='BREAKING CHANGE'}}
|
||||
- **{{message}}** `{{id}} <{{href}}>`__
|
||||
{{/commit-list}}
|
||||
{{#commit-list commits heading='' message='^feat' exclude='BREAKING CHANGE'}}
|
||||
- **{{subject}}** `{{shorthash}} <{{href}}>`__
|
||||
{{/commit-list}}
|
||||
{{#commit-list fixes heading='' message='^feat' exclude='BREAKING CHANGE'}}
|
||||
- **{{commit.subject}}** `{{commit.shorthash}} <{{commit.href}}>`__
|
||||
{{/commit-list}}
|
||||
|
||||
Performance
|
||||
~~~~~~~~~~~
|
||||
|
||||
{{#commit-list merges heading='' message='^perf' exclude='BREAKING CHANGE'}}
|
||||
- **{{message}}** `{{id}} <{{href}}>`__
|
||||
{{/commit-list}}
|
||||
{{#commit-list commits heading='' message='^perf' exclude='BREAKING CHANGE'}}
|
||||
- **{{subject}}** `{{shorthash}} <{{href}}>`__
|
||||
{{/commit-list}}
|
||||
{{#commit-list fixes heading='' message='^perf' exclude='BREAKING CHANGE'}}
|
||||
- **{{commit.subject}}** `{{commit.shorthash}} <{{commit.href}}>`__
|
||||
{{/commit-list}}
|
||||
|
||||
Fixes
|
||||
~~~~~
|
||||
|
||||
{{#commit-list merges heading='' message='^fix' exclude='(^fix conflict|^fix warning|BREAKING CHANGE)'}}
|
||||
- **{{message}}** `{{id}} <{{href}}>`__
|
||||
{{/commit-list}}
|
||||
{{#commit-list commits heading='' message='^fix' exclude='(^fix conflict|^fix warning|BREAKING CHANGE)'}}
|
||||
- **{{subject}}** `{{shorthash}} <{{href}}>`__
|
||||
{{/commit-list}}
|
||||
{{#commit-list fixes heading='' message='^fix' exclude='(^fix conflict|^fix warning|BREAKING CHANGE)'}}
|
||||
- **{{commit.subject}}** `{{commit.shorthash}} <{{commit.href}}>`__
|
||||
{{/commit-list}}
|
||||
|
||||
Examples
|
||||
~~~~~~~~
|
||||
|
||||
{{#commit-list merges heading='' message='^example'}}
|
||||
- **{{message}}** `{{id}} <({{href}})>`__
|
||||
{{/commit-list}}
|
||||
{{#commit-list commits heading='' message='^example'}}
|
||||
- **{{subject}}** `{{shorthash}} <{{href}}>`__
|
||||
{{/commit-list}}
|
||||
{{#commit-list fixes heading='' message='^example'}}
|
||||
- **{{commit.subject}}** `{{commit.shorthash}} <{{commit.href}}>`__
|
||||
{{/commit-list}}
|
||||
|
||||
Docs
|
||||
~~~~
|
||||
|
||||
{{#commit-list merges heading='' message='^docs'}}
|
||||
- **{{message}}** `{{id}} <{{href}}>`__
|
||||
{{/commit-list}}
|
||||
{{#commit-list commits heading='' message='^docs'}}
|
||||
- **{{subject}}** `{{shorthash}} <{{href}}>`__
|
||||
{{/commit-list}}
|
||||
{{#commit-list fixes heading='' message='^docs'}}
|
||||
- **{{commit.subject}}** `{{commit.shorthash}} <{{commit.href}}>`__
|
||||
{{/commit-list}}
|
||||
|
||||
CI and tests
|
||||
~~~~~~~~~~~~
|
||||
|
||||
{{#commit-list merges heading='' message='(^ci|^test)'}}
|
||||
- **{{message}}** `{{id}} <{{href}}>`__
|
||||
{{/commit-list}}
|
||||
{{#commit-list commits heading='' message='(^ci|^test)'}}
|
||||
- **{{subject}}** `{{shorthash }} <{{href}}>`__
|
||||
{{/commit-list}}
|
||||
{{#commit-list fixes heading='' message='(^ci|^test)'}}
|
||||
- **{{commit.subject}}** `{{commit.shorthash}} <{{commit.href}}>`__
|
||||
{{/commit-list}}
|
||||
|
||||
Others
|
||||
~~~~~~
|
||||
|
||||
{{#commit-list merges heading='' exclude='(^fix|^feat|^perf|^docs|^example|^ci|^test)'}}
|
||||
- **{{message}}** `{{id }} <{{href}}>`__
|
||||
{{/commit-list}}
|
||||
{{#commit-list commits heading='' exclude='(^fix|^feat|^perf|^docs|^example|^ci|^test)'}}
|
||||
- **{{subject}}** `{{shorthash }} <{{href}}>`__
|
||||
{{/commit-list}}
|
||||
{{#commit-list fixes heading='' exclude='(^fix|^feat|^perf|^docs|^example|^ci|^test)'}}
|
||||
- **{{commit.subject}}** `{{commit.shorthash}} <{{commit.href}}>`__
|
||||
{{/commit-list}}
|
||||
|
||||
{{/each}}
|
||||
16
managed_components/lvgl__lvgl/scripts/changelog_gen.sh
Normal file
16
managed_components/lvgl__lvgl/scripts/changelog_gen.sh
Normal file
@@ -0,0 +1,16 @@
|
||||
#!/bin/sh
|
||||
# Generate CHANGELOG_LAST.md from changes since the last version tag. (vx.y.z-dev tags are ignored)
|
||||
# CHANGELOG_LAST.md can be edited manually if required and manually added to docs/CHANGELOG.md
|
||||
#
|
||||
# Requirements:
|
||||
# npm install -g auto-changelog
|
||||
#
|
||||
# Usage:
|
||||
# changelog-gen <next-version>
|
||||
#
|
||||
# Example: if the latest version is v5.6.7 the following can be used for bugfix, minor or major versions:
|
||||
# changelog-gen v5.6.8
|
||||
# changelog-gen v5.7.0
|
||||
# changelog-gen v6.0.0
|
||||
|
||||
auto-changelog -t changelog-template.hbs -l false --latest-version $1 --unreleased-only --tag-pattern ^v[0-9]+.[0-9]+.[0-9]+$ -o CHANGELOG_LAST.rst
|
||||
60
managed_components/lvgl__lvgl/scripts/code-format.cfg
Normal file
60
managed_components/lvgl__lvgl/scripts/code-format.cfg
Normal file
@@ -0,0 +1,60 @@
|
||||
--style=kr
|
||||
--indent=spaces=4
|
||||
--indent-classes
|
||||
--indent-switches
|
||||
--indent-cases
|
||||
--indent-preproc-block
|
||||
--indent-preproc-define
|
||||
--indent-col1-comments
|
||||
--pad-oper
|
||||
--unpad-paren
|
||||
--align-pointer=middle
|
||||
--align-reference=middle
|
||||
--convert-tabs
|
||||
--max-code-length=120
|
||||
--break-after-logical
|
||||
--break-closing-braces
|
||||
--attach-closing-while
|
||||
--min-conditional-indent=0
|
||||
--max-continuation-indent=120
|
||||
--mode=c
|
||||
# Allows each platform to use its own line endings. This then does
|
||||
# what Git does out of the box: uses platform line endings in the
|
||||
# working directory, but uses only LF line endings in the repository.
|
||||
# `astyle` also natively uses line the endings it finds in the files,
|
||||
# so this will be LF-only on Linux and CR/LF on Windows, in alignment
|
||||
# with Git's default behavior. This prevents `astyle` from modifying
|
||||
# every source file, which Git perceives as a change on Windows platforms.
|
||||
#--lineend=linux
|
||||
--suffix=none
|
||||
--preserve-date
|
||||
--formatted
|
||||
--ignore-exclude-errors
|
||||
--ignore-exclude-errors-x
|
||||
--exclude=assets
|
||||
--exclude=test_assets
|
||||
--exclude=test_fonts
|
||||
--exclude=../src/lv_conf_internal.h
|
||||
--exclude=../src/core/lv_obj_style_gen.c
|
||||
--exclude=../src/core/lv_obj_style_gen.h
|
||||
--exclude=../src/libs/gif/gifdec.c
|
||||
--exclude=../src/libs/gif/gifdec.h
|
||||
--exclude=../src/libs/lodepng/lodepng.c
|
||||
--exclude=../src/libs/lodepng/lodepng.h
|
||||
--exclude=../src/libs/qrcode/qrcodegen.c
|
||||
--exclude=../src/libs/qrcode/qrcodegen.h
|
||||
--exclude=../src/libs/tjpgd/tjpgd.c
|
||||
--exclude=../src/libs/tjpgd/tjpgd.h
|
||||
--exclude=../src/libs/tjpgd/tjpgdcnf.h
|
||||
--exclude=../src/libs/thorvg
|
||||
--exclude=../src/libs/expat
|
||||
--exclude=../src/libs/lz4
|
||||
--exclude=../src/others/vg_lite_tvg/vg_lite.h
|
||||
--exclude=../demos/high_res/fonts
|
||||
--exclude=../tests/unity/unity.c
|
||||
--exclude=../tests/unity/unity_internals.h
|
||||
--exclude=../tests/unity/unity_support.c
|
||||
--exclude=../tests/unity/unity_support.h
|
||||
--exclude=../tests/test_images
|
||||
--exclude=../tests/build_test_defheap
|
||||
--exclude=../tests/build_test_sysheap
|
||||
65
managed_components/lvgl__lvgl/scripts/code-format.py
Normal file
65
managed_components/lvgl__lvgl/scripts/code-format.py
Normal file
@@ -0,0 +1,65 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
# Argument enhancement: to only run `astyle` on a specified directory, to
|
||||
# only include changed source code, these arguments have been added. If
|
||||
# run with no arguments, all the normal directories are examined as before:
|
||||
# - /demos/
|
||||
# - /examples/
|
||||
# - /src/
|
||||
# - /tests/
|
||||
#
|
||||
# Args:
|
||||
# If ANY args are specified, ONLY run `astyle` on the specified directories.
|
||||
# Any combination can be specified.
|
||||
include_demos = True
|
||||
include_examples = True
|
||||
include_src = True
|
||||
include_tests = True
|
||||
|
||||
args = sys.argv[1:]
|
||||
|
||||
# Have any args been specified?
|
||||
if args:
|
||||
include_demos = False
|
||||
include_examples = False
|
||||
include_src = False
|
||||
include_tests = False
|
||||
|
||||
for arg in args:
|
||||
if arg == "demos":
|
||||
include_demos = True
|
||||
elif arg == "examples":
|
||||
include_examples = True
|
||||
elif arg == "src":
|
||||
include_src = True
|
||||
elif arg == "tests":
|
||||
include_tests = True
|
||||
else:
|
||||
print(f'Argument [{arg}] not recognized.')
|
||||
print('Usage:')
|
||||
print(' python code-format.py [dir [dir ...]]')
|
||||
print(' where: dir can be demos, examples, src or tests.')
|
||||
exit(1)
|
||||
|
||||
script_dir = os.path.realpath(__file__)
|
||||
script_dir = os.path.dirname(script_dir)
|
||||
cfg_file = os.path.join(script_dir, 'code-format.cfg')
|
||||
|
||||
if include_demos:
|
||||
print("\nFormatting demos")
|
||||
os.system(f'astyle --options={cfg_file} --recursive "{script_dir}/../demos/*.c,*.cpp,*.h"')
|
||||
|
||||
if include_examples:
|
||||
print("\nFormatting examples")
|
||||
os.system(f'astyle --options={cfg_file} --recursive "{script_dir}/../examples/*.c,*.cpp,*.h"')
|
||||
|
||||
if include_src:
|
||||
print("\nFormatting src")
|
||||
os.system(f'astyle --options={cfg_file} --recursive "{script_dir}/../src/*.c,*.cpp,*.h"')
|
||||
|
||||
if include_tests:
|
||||
print("\nFormatting tests")
|
||||
os.system(f'astyle --options={cfg_file} --recursive "{script_dir}/../tests/*.c,*.cpp,*.h"')
|
||||
3
managed_components/lvgl__lvgl/scripts/cppcheck_run.sh
Normal file
3
managed_components/lvgl__lvgl/scripts/cppcheck_run.sh
Normal file
@@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
cppcheck -j8 --template="{severity}\t{file}:{line}\t{id}: {message}" --enable=all ../src/ --output-file=cppcheck_res.txt --suppress=unusedFunction --suppress=preprocessorErrorDirective --force
|
||||
18
managed_components/lvgl__lvgl/scripts/filetohex.py
Normal file
18
managed_components/lvgl__lvgl/scripts/filetohex.py
Normal file
@@ -0,0 +1,18 @@
|
||||
#!/usr/bin/env python3
|
||||
import sys
|
||||
import textwrap
|
||||
import re
|
||||
|
||||
with open(sys.argv[1], 'r') as file:
|
||||
s = file.read()
|
||||
|
||||
b = bytearray()
|
||||
|
||||
if '--filter-character' in sys.argv:
|
||||
s = re.sub(r'[^\x00-\xff]', '', s)
|
||||
if '--null-terminate' in sys.argv:
|
||||
s += '\x00'
|
||||
|
||||
b.extend(map(ord, s))
|
||||
|
||||
print(textwrap.fill(', '.join([hex(a) for a in b]), 96))
|
||||
4
managed_components/lvgl__lvgl/scripts/find_version.sh
Normal file
4
managed_components/lvgl__lvgl/scripts/find_version.sh
Normal file
@@ -0,0 +1,4 @@
|
||||
#!/bin/sh
|
||||
|
||||
SCRIPTPATH="$( cd -- "$(dirname "$0")" >/dev/null 2>&1 || exit ; pwd -P )"
|
||||
sed -n '/LVGL_VERSION_MAJOR/ {N;s@#define \+LVGL_VERSION_M.... \+@@g;s@\n@.@p}' "$SCRIPTPATH/../lv_version.h"
|
||||
110
managed_components/lvgl__lvgl/scripts/font_license_verify.py
Normal file
110
managed_components/lvgl__lvgl/scripts/font_license_verify.py
Normal file
@@ -0,0 +1,110 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import argparse
|
||||
from typing import List, Tuple
|
||||
import sys
|
||||
import os
|
||||
|
||||
try:
|
||||
from fontTools.ttLib import TTFont
|
||||
except ImportError:
|
||||
print("Need fonttools package, do `pip3 install fonttools`")
|
||||
sys.exit(1)
|
||||
|
||||
# Fonts that are excluded from the license check
|
||||
# Only add fonts that are known to be public domain or have a compatible license
|
||||
_EXCLUDED_FONTS = {
|
||||
"OpenTypeTest GPOS One",
|
||||
}
|
||||
|
||||
# Font name mapping to remove any style suffix
|
||||
_FONT_NAME_MAP = {
|
||||
"Montserrat Medium": "Montserrat",
|
||||
"Montserrat SemiBold": "Montserrat",
|
||||
"Montserrat Bold": "Montserrat",
|
||||
"Source Han Sans SC Normal": "Source Han Sans SC",
|
||||
}
|
||||
|
||||
|
||||
def get_font_full_name(font_path: str) -> str:
|
||||
font = TTFont(font_path)
|
||||
name_records = font["name"].names
|
||||
fallback = None
|
||||
for record in name_records:
|
||||
if record.nameID == 1: # ID 1 corresponds to the font family name and will be used if full name doesn't exists
|
||||
fallback = record.toStr()
|
||||
if record.nameID == 4: # ID 4 corresponds to the full font name
|
||||
return record.toStr()
|
||||
return fallback
|
||||
|
||||
|
||||
def list_intree_fonts(path: str) -> List[Tuple[str, str]]:
|
||||
fonts = []
|
||||
for root, _, files in os.walk(path):
|
||||
for file in files:
|
||||
if file.lower().endswith((".ttf", ".otf", ".woff", ".woff2")):
|
||||
font_path = os.path.join(root, file)
|
||||
font_name = get_font_full_name(font_path).strip()
|
||||
if font_name:
|
||||
# Add a no-strict mode to ignore missing license files
|
||||
fonts.append((font_path, font_name))
|
||||
return fonts
|
||||
|
||||
|
||||
def has_intree_license(license_root_folder: str, font_name: str) -> bool:
|
||||
if font_name in _EXCLUDED_FONTS:
|
||||
return True
|
||||
|
||||
# Prepare candidate folder names, ignoring casing
|
||||
candidates = {
|
||||
font_name.lower(),
|
||||
font_name.replace(" ", "_").lower(),
|
||||
font_name.replace(" ", "").lower(),
|
||||
}
|
||||
|
||||
if font_name in _FONT_NAME_MAP:
|
||||
candidates.add(_FONT_NAME_MAP[font_name].lower())
|
||||
candidates.add(_FONT_NAME_MAP[font_name].replace(" ", "_").lower())
|
||||
candidates.add(_FONT_NAME_MAP[font_name].replace(" ", "").lower())
|
||||
|
||||
# List all directories in the license_root_folder
|
||||
for entry in os.listdir(license_root_folder):
|
||||
entry_path = os.path.join(license_root_folder, entry)
|
||||
if os.path.isdir(entry_path):
|
||||
# Compare the directory name in lowercase with candidates
|
||||
if entry.lower() in candidates:
|
||||
# Check if the directory contains at least one file (ignoring subdirectories)
|
||||
for item in os.listdir(entry_path):
|
||||
item_path = os.path.join(entry_path, item)
|
||||
if os.path.isfile(item_path):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(description="Verify font licenses")
|
||||
parser.add_argument(
|
||||
"--no-strict",
|
||||
action="store_true",
|
||||
help="Ignore missing license files",
|
||||
default=False,
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
SCRIPT_DIR = os.path.dirname(__file__)
|
||||
# List of font files in the tree
|
||||
fonts = list_intree_fonts(os.path.join(SCRIPT_DIR, ".."))
|
||||
has_font_without_license = False
|
||||
|
||||
print("Verifying license for fonts:")
|
||||
for path, name in fonts:
|
||||
if has_intree_license(
|
||||
os.path.join(SCRIPT_DIR, "built_in_font", "font_license"), name
|
||||
):
|
||||
print(f" [OK] '{name}'")
|
||||
else:
|
||||
print(f" [MISSING] '{name}' - {path}")
|
||||
has_font_without_license = True
|
||||
|
||||
if has_font_without_license and not args.no_strict:
|
||||
sys.exit(1)
|
||||
13
managed_components/lvgl__lvgl/scripts/gdb/gdbinit.py
Normal file
13
managed_components/lvgl__lvgl/scripts/gdb/gdbinit.py
Normal file
@@ -0,0 +1,13 @@
|
||||
import sys
|
||||
from os import path
|
||||
|
||||
here = path.dirname(path.abspath(__file__))
|
||||
|
||||
if __name__ == "__main__":
|
||||
if here not in sys.path:
|
||||
sys.path.insert(0, here)
|
||||
|
||||
for key in tuple(filter(lambda m: m.startswith("lvglgdb"), sys.modules.keys())):
|
||||
del sys.modules[key]
|
||||
|
||||
import lvglgdb # noqa: F401
|
||||
@@ -0,0 +1,16 @@
|
||||
from .lvgl import *
|
||||
from .value import *
|
||||
from .debugger import *
|
||||
|
||||
# Debugger
|
||||
Debugger()
|
||||
|
||||
# Dumps
|
||||
DumpObj()
|
||||
|
||||
# Infos
|
||||
InfoStyle()
|
||||
InfoDrawUnit()
|
||||
|
||||
# Set instance
|
||||
set_lvgl_instance(None)
|
||||
@@ -0,0 +1,73 @@
|
||||
import argparse
|
||||
|
||||
import gdb
|
||||
|
||||
|
||||
class Debugger(gdb.Command):
|
||||
"""Start debugpy server or connect to a debug server, so we can debug python code from IDE like PyCharm/VSCode"""
|
||||
|
||||
def __init__(self, host="localhost", port=11451):
|
||||
self.__host = host
|
||||
self.__port = port
|
||||
super().__init__("debugger", gdb.COMMAND_USER)
|
||||
|
||||
def invoke(self, args, from_tty):
|
||||
parser = argparse.ArgumentParser(description=Debugger.__doc__)
|
||||
parser.add_argument(
|
||||
"--host",
|
||||
type=str,
|
||||
help="Server listening host",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-p",
|
||||
"--port",
|
||||
type=int,
|
||||
help="Server listening port",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-t",
|
||||
"--type",
|
||||
choices=["pycharm", "vscode", "eclipse"],
|
||||
help="Debugger type",
|
||||
required=True,
|
||||
)
|
||||
|
||||
try:
|
||||
args = parser.parse_args(gdb.string_to_argv(args))
|
||||
except SystemExit:
|
||||
return
|
||||
|
||||
if args.host:
|
||||
self.__host = args.host
|
||||
|
||||
if args.port:
|
||||
self.__port = args.port
|
||||
|
||||
if args.type == "pycharm":
|
||||
self.connect_to_pycharm()
|
||||
elif args.type == "vscode":
|
||||
self.connect_to_vscode()
|
||||
elif args.type == "eclipse":
|
||||
self.connect_to_eclipse()
|
||||
|
||||
def connect_to_pycharm(self):
|
||||
try:
|
||||
import pydevd_pycharm
|
||||
except ImportError:
|
||||
print("pydevd_pycharm module not found. Please install it using pip.")
|
||||
return
|
||||
|
||||
pydevd_pycharm.settrace(self.__host, port=self.__port, stdoutToServer=True, stderrToServer=True)
|
||||
|
||||
def connect_to_vscode(self):
|
||||
try:
|
||||
import debugpy
|
||||
except ImportError:
|
||||
print("debugpy module not found. Please install it using pip.")
|
||||
return
|
||||
|
||||
debugpy.listen((self.__host, self.__port))
|
||||
debugpy.wait_for_client()
|
||||
|
||||
def connect_to_eclipse(self):
|
||||
print("Eclipse is not implemented yet")
|
||||
335
managed_components/lvgl__lvgl/scripts/gdb/lvglgdb/lvgl.py
Normal file
335
managed_components/lvgl__lvgl/scripts/gdb/lvglgdb/lvgl.py
Normal file
@@ -0,0 +1,335 @@
|
||||
import argparse
|
||||
from typing import Iterator, Union, Optional
|
||||
|
||||
import gdb
|
||||
|
||||
from .value import Value
|
||||
|
||||
gdb.execute("set pagination off")
|
||||
gdb.write("set pagination off\n")
|
||||
gdb.execute("set python print-stack full")
|
||||
gdb.write("set python print-stack full\n")
|
||||
|
||||
g_lvgl_instance = None
|
||||
|
||||
|
||||
class LVList(Value):
|
||||
"""LVGL linked list iterator"""
|
||||
|
||||
def __init__(self, ll: Value, nodetype: Union[gdb.Type, str] = None):
|
||||
if not ll:
|
||||
raise ValueError("Invalid linked list")
|
||||
super().__init__(ll)
|
||||
|
||||
self.nodetype = (
|
||||
gdb.lookup_type(nodetype).pointer()
|
||||
if isinstance(nodetype, str)
|
||||
else nodetype
|
||||
)
|
||||
self.lv_ll_node_t = gdb.lookup_type("lv_ll_node_t").pointer()
|
||||
self.current = self.head
|
||||
self._next_offset = self.n_size + self.lv_ll_node_t.sizeof
|
||||
self._prev_offset = self.n_size
|
||||
|
||||
def _next(self, node):
|
||||
next_value = Value(int(node) + self._next_offset)
|
||||
return next_value.cast(self.lv_ll_node_t, ptr=True).dereference()
|
||||
|
||||
def _prev(self, node):
|
||||
prev_value = Value(int(node) + self._prev_offset)
|
||||
return prev_value.cast(self.lv_ll_node_t, ptr=True).dereference()
|
||||
|
||||
def __iter__(self):
|
||||
return self
|
||||
|
||||
def __next__(self):
|
||||
if not self.current:
|
||||
raise StopIteration
|
||||
|
||||
nodetype = self.nodetype if self.nodetype else self.lv_ll_node_t
|
||||
node = self.current.cast(nodetype)
|
||||
|
||||
self.current = self._next(self.current)
|
||||
return node
|
||||
|
||||
@property
|
||||
def len(self):
|
||||
len = 0
|
||||
node = self.head
|
||||
while node:
|
||||
len += 1
|
||||
node = self._next(node)
|
||||
return len
|
||||
|
||||
|
||||
class LVObject(Value):
|
||||
"""LVGL object"""
|
||||
|
||||
def __init__(self, obj: Value):
|
||||
super().__init__(obj.cast("lv_obj_t", ptr=True))
|
||||
|
||||
@property
|
||||
def class_name(self):
|
||||
name = self.class_p.name
|
||||
return name.string() if name else "unknown"
|
||||
|
||||
@property
|
||||
def x1(self):
|
||||
return int(self.coords.x1)
|
||||
|
||||
@property
|
||||
def y1(self):
|
||||
return int(self.coords.y1)
|
||||
|
||||
@property
|
||||
def x2(self):
|
||||
return int(self.coords.x2)
|
||||
|
||||
@property
|
||||
def y2(self):
|
||||
return int(self.coords.y2)
|
||||
|
||||
@property
|
||||
def child_count(self):
|
||||
return self.spec_attr.child_cnt if self.spec_attr else 0
|
||||
|
||||
@property
|
||||
def childs(self):
|
||||
if not self.spec_attr:
|
||||
return
|
||||
|
||||
for i in range(self.child_count):
|
||||
child = self.spec_attr.children[i]
|
||||
yield LVObject(child)
|
||||
|
||||
@property
|
||||
def styles(self):
|
||||
LV_STYLE_PROP_INV = 0
|
||||
LV_STYLE_PROP_ANY = 0xFF
|
||||
count = self.style_cnt
|
||||
if count == 0:
|
||||
return
|
||||
|
||||
styles = self.super_value("styles")
|
||||
for i in range(count):
|
||||
style = styles[i].style
|
||||
prop_cnt = style.prop_cnt
|
||||
values_and_props = style.values_and_props.cast("lv_style_const_prop_t", ptr=True)
|
||||
for j in range(prop_cnt):
|
||||
prop = values_and_props[j].prop
|
||||
if prop == LV_STYLE_PROP_INV or prop == LV_STYLE_PROP_ANY:
|
||||
continue
|
||||
yield values_and_props[j]
|
||||
|
||||
def get_child(self, index: int):
|
||||
return (
|
||||
self.spec_attr.children[index] if self.spec_attr else None
|
||||
)
|
||||
|
||||
|
||||
class LVDisplay(Value):
|
||||
"""LVGL display"""
|
||||
|
||||
def __init__(self, disp: Value):
|
||||
super().__init__(disp)
|
||||
|
||||
@property
|
||||
def screens(self):
|
||||
screens = self.super_value("screens")
|
||||
for i in range(self.screen_cnt):
|
||||
yield LVObject(screens[i])
|
||||
|
||||
|
||||
class LVGL:
|
||||
"""LVGL instance"""
|
||||
|
||||
def __init__(self, lv_global: Value):
|
||||
self.lv_global = lv_global.cast("lv_global_t", ptr=True)
|
||||
|
||||
def displays(self) -> Iterator[LVDisplay]:
|
||||
ll = self.lv_global.disp_ll
|
||||
if not ll:
|
||||
return
|
||||
|
||||
for disp in LVList(ll, "lv_display_t"):
|
||||
yield LVDisplay(disp)
|
||||
|
||||
def screen_active(self):
|
||||
disp = self.lv_global.disp_default
|
||||
return disp.act_scr if disp else None
|
||||
|
||||
def draw_units(self):
|
||||
unit = self.lv_global.draw_info.unit_head
|
||||
|
||||
# Iterate through all draw units
|
||||
while unit:
|
||||
yield unit
|
||||
unit = unit.next
|
||||
|
||||
|
||||
def set_lvgl_instance(lv_global: Union[gdb.Value, Value, None]):
|
||||
global g_lvgl_instance
|
||||
|
||||
if not lv_global:
|
||||
try:
|
||||
lv_global = Value(gdb.parse_and_eval("lv_global").address)
|
||||
except gdb.error as e:
|
||||
print(f"Failed to get lv_global: {e}")
|
||||
return
|
||||
|
||||
if not isinstance(lv_global, Value):
|
||||
lv_global = Value(lv_global)
|
||||
|
||||
inited = lv_global.inited
|
||||
if not inited:
|
||||
print("\x1b[31mlvgl is not initialized yet. Please call `set_lvgl_instance(None)` later.\x1b[0m")
|
||||
return
|
||||
|
||||
g_lvgl_instance = LVGL(lv_global)
|
||||
|
||||
|
||||
def dump_obj_info(obj: LVObject):
|
||||
clzname = obj.class_name
|
||||
coords = f"{obj.x1},{obj.y1},{obj.x2},{obj.y2}"
|
||||
print(f"{clzname}@{hex(obj)} {coords}")
|
||||
|
||||
|
||||
# Dump lv_style_const_prop_t
|
||||
def dump_style_info(style: Value):
|
||||
prop = int(style.prop)
|
||||
value = style.value
|
||||
print(f"{prop} = {value}")
|
||||
|
||||
|
||||
class DumpObj(gdb.Command):
|
||||
"""dump obj tree from specified obj"""
|
||||
|
||||
def __init__(self):
|
||||
super(DumpObj, self).__init__(
|
||||
"dump obj", gdb.COMMAND_USER, gdb.COMPLETE_EXPRESSION
|
||||
)
|
||||
|
||||
def dump_obj(self, obj: LVObject, depth=0, limit=None):
|
||||
if not obj:
|
||||
return
|
||||
|
||||
# dump self
|
||||
print(" " * depth, end="")
|
||||
dump_obj_info(obj)
|
||||
|
||||
if limit is not None and depth >= limit:
|
||||
return
|
||||
|
||||
# dump children
|
||||
for child in obj.childs:
|
||||
self.dump_obj(child, depth + 1, limit=limit)
|
||||
|
||||
def invoke(self, args, from_tty):
|
||||
parser = argparse.ArgumentParser(description="Dump lvgl obj tree.")
|
||||
parser.add_argument(
|
||||
"-L",
|
||||
"--level",
|
||||
type=int,
|
||||
default=None,
|
||||
help="Limit the depth of the tree.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"root",
|
||||
type=str,
|
||||
nargs="?",
|
||||
default=None,
|
||||
help="Optional root obj to dump.",
|
||||
)
|
||||
try:
|
||||
args = parser.parse_args(gdb.string_to_argv(args))
|
||||
except SystemExit:
|
||||
return
|
||||
|
||||
if args.root:
|
||||
root = gdb.parse_and_eval(args.root)
|
||||
root = LVObject(root)
|
||||
self.dump_obj(root, limit=args.level)
|
||||
else:
|
||||
# dump all displays
|
||||
depth = 0
|
||||
for disp in g_lvgl_instance.displays():
|
||||
print(f"Display {hex(disp)}")
|
||||
for screen in disp.screens:
|
||||
print(f'{" " * (depth + 1)}Screen@{hex(screen)}')
|
||||
self.dump_obj(screen, depth=depth + 1, limit=args.level)
|
||||
|
||||
|
||||
class InfoStyle(gdb.Command):
|
||||
"""dump obj style value for specified obj"""
|
||||
|
||||
def __init__(self):
|
||||
super(InfoStyle, self).__init__(
|
||||
"info style", gdb.COMMAND_USER, gdb.COMPLETE_EXPRESSION
|
||||
)
|
||||
|
||||
def invoke(self, args, from_tty):
|
||||
parser = argparse.ArgumentParser(description="Dump lvgl obj local style.")
|
||||
parser.add_argument(
|
||||
"obj",
|
||||
type=str,
|
||||
help="obj to show style.",
|
||||
)
|
||||
|
||||
try:
|
||||
args = parser.parse_args(gdb.string_to_argv(args))
|
||||
except SystemExit:
|
||||
return
|
||||
|
||||
obj = gdb.parse_and_eval(args.obj)
|
||||
if not obj:
|
||||
print("Invalid obj: ", args.obj)
|
||||
return
|
||||
|
||||
obj = Value(obj)
|
||||
|
||||
# show all styles applied to this obj
|
||||
for style in LVObject(obj).styles:
|
||||
print(" ", end="")
|
||||
dump_style_info(style)
|
||||
|
||||
|
||||
class InfoDrawUnit(gdb.Command):
|
||||
"""dump draw unit info"""
|
||||
|
||||
def __init__(self):
|
||||
super(InfoDrawUnit, self).__init__(
|
||||
"info draw_unit", gdb.COMMAND_USER, gdb.COMPLETE_EXPRESSION
|
||||
)
|
||||
|
||||
def dump_draw_unit(self, draw_unit: Value):
|
||||
# Dereference to get the string content of the name from draw_unit
|
||||
name = draw_unit.name.string()
|
||||
|
||||
# Print draw_unit information and the name
|
||||
print(f"Draw Unit: {draw_unit}, Name: {name}")
|
||||
|
||||
# Handle different draw_units based on the name
|
||||
def lookup_type(name):
|
||||
try:
|
||||
return gdb.lookup_type(name)
|
||||
except gdb.error:
|
||||
return None
|
||||
|
||||
types = {
|
||||
"DMA2D": lookup_type("lv_draw_dma2d_unit_t"),
|
||||
"NEMA_GFX": lookup_type("lv_draw_nema_gfx_unit_t"),
|
||||
"NXP_PXP": lookup_type("lv_draw_pxp_unit_t"),
|
||||
"NXP_VGLITE": lookup_type("lv_draw_vglite_unit_t"),
|
||||
"OPENGLES": lookup_type("lv_draw_opengles_unit_t"),
|
||||
"DAVE2D": lookup_type("lv_draw_dave2d_unit_t"),
|
||||
"SDL": lookup_type("lv_draw_sdl_unit_t"),
|
||||
"SW": lookup_type("lv_draw_sw_unit_t"),
|
||||
"VG_LITE": lookup_type("lv_draw_vg_lite_unit_t"),
|
||||
}
|
||||
|
||||
type = types.get(name, lookup_type("lv_draw_unit_t"))
|
||||
print(draw_unit.cast(type, ptr=True).dereference().format_string(pretty_structs=True, symbols=True))
|
||||
|
||||
def invoke(self, args, from_tty):
|
||||
for unit in g_lvgl_instance.draw_units():
|
||||
self.dump_draw_unit(unit)
|
||||
32
managed_components/lvgl__lvgl/scripts/gdb/lvglgdb/value.py
Normal file
32
managed_components/lvgl__lvgl/scripts/gdb/lvglgdb/value.py
Normal file
@@ -0,0 +1,32 @@
|
||||
import gdb
|
||||
|
||||
from typing import Optional, Union
|
||||
|
||||
|
||||
class Value(gdb.Value):
|
||||
def __init__(self, value: Union[gdb.Value, 'Value']):
|
||||
super().__init__(value)
|
||||
|
||||
def __getitem__(self, key):
|
||||
try:
|
||||
value = super().__getitem__(key)
|
||||
except gdb.error:
|
||||
value = super().__getattr__(key)
|
||||
return Value(value)
|
||||
|
||||
def __getattr__(self, key):
|
||||
if hasattr(super(), key):
|
||||
return Value(super().__getattribute__(key))
|
||||
return Value(super().__getitem__(key))
|
||||
|
||||
def cast(self, type_name: str | gdb.Type, ptr: bool = False) -> Optional['Value']:
|
||||
try:
|
||||
gdb_type = gdb.lookup_type(type_name) if isinstance(type_name, str) else type_name
|
||||
if ptr:
|
||||
gdb_type = gdb_type.pointer()
|
||||
return Value(super().cast(gdb_type))
|
||||
except gdb.error:
|
||||
return None
|
||||
|
||||
def super_value(self, attr: str) -> 'Value':
|
||||
return self[attr]
|
||||
File diff suppressed because one or more lines are too long
335
managed_components/lvgl__lvgl/scripts/gen_json/gen_json.py
Normal file
335
managed_components/lvgl__lvgl/scripts/gen_json/gen_json.py
Normal file
@@ -0,0 +1,335 @@
|
||||
import os
|
||||
import sys
|
||||
import argparse
|
||||
import shutil
|
||||
import tempfile
|
||||
import json
|
||||
import subprocess
|
||||
|
||||
base_path = os.path.abspath(os.path.dirname(__file__))
|
||||
sys.path.insert(0, base_path)
|
||||
|
||||
project_dir = os.path.abspath(os.path.join(base_path, '..', '..'))
|
||||
docs_path = os.path.join(project_dir, 'docs')
|
||||
sys.path.insert(0, docs_path)
|
||||
|
||||
import create_fake_lib_c # NOQA
|
||||
import pycparser_monkeypatch # NOQA
|
||||
import pycparser # NOQA
|
||||
|
||||
doxyfile_filename = 'Doxyfile'
|
||||
DEVELOP = False
|
||||
|
||||
|
||||
intermediate_dir = tempfile.mkdtemp(suffix='.lvgl_json')
|
||||
|
||||
|
||||
def run(output_path, lv_conf_file, output_to_stdout, target_header, filter_private, no_docstrings, *compiler_args):
|
||||
|
||||
pycparser_monkeypatch.FILTER_PRIVATE = filter_private
|
||||
|
||||
lvgl_dir = project_dir
|
||||
lvgl_src_dir = os.path.join(lvgl_dir, 'src')
|
||||
int_lvgl_dir = os.path.join(intermediate_dir, 'lvgl')
|
||||
lv_conf_dest_file = os.path.join(intermediate_dir, 'lv_conf.h')
|
||||
target_header_base_name = (
|
||||
os.path.splitext(os.path.split(target_header)[-1])[0]
|
||||
)
|
||||
|
||||
try:
|
||||
os.mkdir(int_lvgl_dir)
|
||||
shutil.copytree(lvgl_src_dir, os.path.join(int_lvgl_dir, 'src'))
|
||||
shutil.copyfile(os.path.join(lvgl_dir, 'lvgl.h'), os.path.join(int_lvgl_dir, 'lvgl.h'))
|
||||
|
||||
pp_file = os.path.join(intermediate_dir, target_header_base_name + '.pp')
|
||||
|
||||
if lv_conf_file is None:
|
||||
lv_conf_templ_file = os.path.join(lvgl_dir, 'lv_conf_template.h')
|
||||
|
||||
with open(lv_conf_templ_file, 'rb') as f:
|
||||
lines = f.read().decode('utf-8').split('\n')
|
||||
|
||||
for i, line in enumerate(lines):
|
||||
if line.startswith('#if 0'):
|
||||
lines[i] = '#if 1'
|
||||
else:
|
||||
for item in (
|
||||
'LV_USE_LOG',
|
||||
'LV_USE_OBJ_ID',
|
||||
'LV_USE_OBJ_ID_BUILTIN',
|
||||
'LV_USE_FLOAT',
|
||||
'LV_USE_BIDI',
|
||||
'LV_USE_LODEPNG',
|
||||
'LV_USE_LIBPNG',
|
||||
'LV_USE_BMP',
|
||||
'LV_USE_TJPGD',
|
||||
'LV_USE_LIBJPEG_TURBO',
|
||||
'LV_USE_GIF',
|
||||
'LV_BIN_DECODER_RAM_LOAD',
|
||||
'LV_USE_RLE',
|
||||
'LV_USE_QRCODE',
|
||||
'LV_USE_BARCODE',
|
||||
'LV_USE_TINY_TTF',
|
||||
'LV_USE_GRIDNAV',
|
||||
'LV_USE_FRAGMENT',
|
||||
'LV_USE_IMGFONT',
|
||||
'LV_USE_SNAPSHOT',
|
||||
'LV_USE_FREETYPE'
|
||||
):
|
||||
if line.startswith(f'#define {item} '):
|
||||
lines[i] = f'#define {item} 1'
|
||||
break
|
||||
|
||||
with open(lv_conf_dest_file, 'wb') as f:
|
||||
f.write('\n'.join(lines).encode('utf-8'))
|
||||
else:
|
||||
shutil.copyfile(lv_conf_file, lv_conf_dest_file)
|
||||
|
||||
include_dirs = [intermediate_dir, project_dir]
|
||||
|
||||
if sys.platform.startswith('win'):
|
||||
import get_sdl2
|
||||
|
||||
try:
|
||||
import pyMSVC # NOQA
|
||||
except ImportError:
|
||||
sys.stderr.write(
|
||||
'\nThe pyMSVC library is missing, '
|
||||
'please run "pip install pyMSVC" to install it.\n'
|
||||
)
|
||||
sys.stderr.flush()
|
||||
sys.exit(-500)
|
||||
|
||||
env = pyMSVC.setup_environment() # NOQA
|
||||
cpp_cmd = ['cl', '/std:c11', '/nologo', '/P']
|
||||
output_pp = f'/Fi"{pp_file}"'
|
||||
sdl2_include, _ = get_sdl2.get_sdl2(intermediate_dir)
|
||||
include_dirs.append(sdl2_include)
|
||||
include_path_env_key = 'INCLUDE'
|
||||
|
||||
elif sys.platform.startswith('darwin'):
|
||||
include_path_env_key = 'C_INCLUDE_PATH'
|
||||
cpp_cmd = [
|
||||
'clang', '-std=c11', '-E', '-DINT32_MIN=0x80000000',
|
||||
]
|
||||
output_pp = f' >> "{pp_file}"'
|
||||
else:
|
||||
include_path_env_key = 'C_INCLUDE_PATH'
|
||||
cpp_cmd = [
|
||||
'gcc', '-std=c11', '-E', '-Wno-incompatible-pointer-types',
|
||||
]
|
||||
output_pp = f' >> "{pp_file}"'
|
||||
|
||||
fake_libc_path = create_fake_lib_c.run(intermediate_dir)
|
||||
|
||||
if include_path_env_key not in os.environ:
|
||||
os.environ[include_path_env_key] = ''
|
||||
|
||||
os.environ[include_path_env_key] = (
|
||||
f'{fake_libc_path}{os.pathsep}{os.environ[include_path_env_key]}'
|
||||
)
|
||||
|
||||
if 'PATH' not in os.environ:
|
||||
os.environ['PATH'] = ''
|
||||
|
||||
os.environ['PATH'] = (
|
||||
f'{fake_libc_path}{os.pathsep}{os.environ["PATH"]}'
|
||||
)
|
||||
|
||||
cpp_cmd.extend(compiler_args)
|
||||
cpp_cmd.extend([
|
||||
'-DLV_LVGL_H_INCLUDE_SIMPLE',
|
||||
'-DLV_CONF_INCLUDE_SIMPLE',
|
||||
'-DLV_USE_DEV_VERSION'
|
||||
])
|
||||
|
||||
cpp_cmd.extend(['-DPYCPARSER', f'"-I{fake_libc_path}"'])
|
||||
cpp_cmd.extend([f'"-I{item}"' for item in include_dirs])
|
||||
cpp_cmd.append(f'"{target_header}"')
|
||||
|
||||
if sys.platform.startswith('win'):
|
||||
cpp_cmd.insert(len(cpp_cmd) - 2, output_pp)
|
||||
else:
|
||||
cpp_cmd.append(output_pp)
|
||||
|
||||
cpp_cmd = ' '.join(cpp_cmd)
|
||||
|
||||
p = subprocess.Popen(
|
||||
cpp_cmd,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
env=os.environ,
|
||||
shell=True
|
||||
)
|
||||
out, err = p.communicate()
|
||||
exit_code = p.returncode
|
||||
|
||||
if not os.path.exists(pp_file):
|
||||
sys.stdout.write(out.decode('utf-8').strip() + '\n')
|
||||
sys.stdout.write('EXIT CODE: ' + str(exit_code) + '\n')
|
||||
sys.stderr.write(err.decode('utf-8').strip() + '\n')
|
||||
sys.stdout.flush()
|
||||
sys.stderr.flush()
|
||||
|
||||
raise RuntimeError('Unknown Failure')
|
||||
|
||||
with open(pp_file, 'r') as f:
|
||||
pp_data = f.read()
|
||||
|
||||
cparser = pycparser.CParser()
|
||||
ast = cparser.parse(pp_data, target_header)
|
||||
doxyfile_src_file = os.path.join(docs_path, doxyfile_filename)
|
||||
|
||||
ast.setup_docs(no_docstrings, lvgl_src_dir,
|
||||
intermediate_dir, doxyfile_src_file, output_to_stdout)
|
||||
|
||||
if not output_to_stdout and output_path is None:
|
||||
if not DEVELOP:
|
||||
shutil.rmtree(intermediate_dir)
|
||||
|
||||
return ast
|
||||
|
||||
elif output_to_stdout:
|
||||
# stdout.reset()
|
||||
print(json.dumps(ast.to_dict(), indent=4))
|
||||
else:
|
||||
if not os.path.exists(output_path):
|
||||
os.makedirs(output_path)
|
||||
|
||||
output_path = os.path.join(output_path, target_header_base_name + '.json')
|
||||
|
||||
with open(output_path, 'w') as f:
|
||||
f.write(json.dumps(ast.to_dict(), indent=4))
|
||||
|
||||
except Exception as err:
|
||||
try:
|
||||
print(cpp_cmd) # NOQA
|
||||
print()
|
||||
except: # NOQA
|
||||
pass
|
||||
|
||||
for key, value in os.environ.items():
|
||||
print(key + ':', value)
|
||||
|
||||
print()
|
||||
import traceback
|
||||
|
||||
traceback.print_exc()
|
||||
print()
|
||||
|
||||
exceptions = [
|
||||
ArithmeticError,
|
||||
AssertionError,
|
||||
AttributeError,
|
||||
EOFError,
|
||||
FloatingPointError,
|
||||
GeneratorExit,
|
||||
ImportError,
|
||||
IndentationError,
|
||||
IndexError,
|
||||
KeyError,
|
||||
KeyboardInterrupt,
|
||||
LookupError,
|
||||
MemoryError,
|
||||
NameError,
|
||||
NotImplementedError,
|
||||
OverflowError,
|
||||
ReferenceError,
|
||||
RuntimeError,
|
||||
StopIteration,
|
||||
SyntaxError,
|
||||
TabError,
|
||||
SystemExit,
|
||||
TypeError,
|
||||
UnboundLocalError,
|
||||
UnicodeError,
|
||||
UnicodeEncodeError,
|
||||
UnicodeDecodeError,
|
||||
UnicodeTranslateError,
|
||||
ValueError,
|
||||
ZeroDivisionError,
|
||||
SystemError
|
||||
]
|
||||
|
||||
if isinstance(err, OSError):
|
||||
error = err.errno
|
||||
else:
|
||||
if type(err) in exceptions:
|
||||
error = ~exceptions.index(type(err))
|
||||
else:
|
||||
error = -100
|
||||
else:
|
||||
error = 0
|
||||
|
||||
if DEVELOP:
|
||||
print('temporary file path:', intermediate_dir)
|
||||
else:
|
||||
shutil.rmtree(intermediate_dir)
|
||||
|
||||
sys.exit(error)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser('-')
|
||||
parser.add_argument(
|
||||
'--output-path',
|
||||
dest='output_path',
|
||||
help=(
|
||||
'output directory for JSON file. If one is not '
|
||||
'supplied then it will be output stdout'
|
||||
),
|
||||
action='store',
|
||||
default=None
|
||||
)
|
||||
parser.add_argument(
|
||||
'--lvgl-config',
|
||||
dest='lv_conf',
|
||||
help=(
|
||||
'path to lv_conf.h (including file name), if this is not set then '
|
||||
'a config file will be generated that has everything turned on.'
|
||||
),
|
||||
action='store',
|
||||
default=None
|
||||
)
|
||||
parser.add_argument(
|
||||
'--develop',
|
||||
dest='develop',
|
||||
help='this option leaves the temporary folder in place.',
|
||||
action='store_true',
|
||||
)
|
||||
parser.add_argument(
|
||||
"--target-header",
|
||||
dest="target_header",
|
||||
help=(
|
||||
"path to a custom header file. When using this to supply a custom"
|
||||
"header file you MUST insure that any LVGL includes are done so "
|
||||
"they are relitive to the LVGL repository root folder.\n\n"
|
||||
'#include "src/lvgl_private.h"\n\n'
|
||||
"If you have includes to header files that are not LVGL then you "
|
||||
"will need to add the include locations for those header files "
|
||||
"when running this script. It is done using the same manner that "
|
||||
"is used when calling a C compiler\n\n"
|
||||
"You need to provide the absolute path to the header file when "
|
||||
"using this feature."
|
||||
),
|
||||
action="store",
|
||||
default=os.path.join(intermediate_dir, "lvgl", "lvgl.h")
|
||||
)
|
||||
parser.add_argument(
|
||||
'--filter-private',
|
||||
dest='filter_private',
|
||||
help='Internal Use',
|
||||
action='store_true',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--no-docstrings',
|
||||
dest='no_docstrings',
|
||||
help='Internal Use',
|
||||
action='store_true',
|
||||
)
|
||||
|
||||
args, extra_args = parser.parse_known_args()
|
||||
|
||||
DEVELOP = args.develop
|
||||
|
||||
run(args.output_path, args.lv_conf, args.output_path is None, args.target_header, args.filter_private, args.no_docstrings, *extra_args)
|
||||
66
managed_components/lvgl__lvgl/scripts/gen_json/get_sdl2.py
Normal file
66
managed_components/lvgl__lvgl/scripts/gen_json/get_sdl2.py
Normal file
@@ -0,0 +1,66 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import zipfile
|
||||
import io
|
||||
import os
|
||||
|
||||
|
||||
SDL2_URL = 'https://github.com/libsdl-org/SDL/releases/download/release-2.26.5/SDL2-devel-2.26.5-VC.zip' # NOQA
|
||||
|
||||
|
||||
def get_path(name: str, p: str) -> str:
|
||||
for file in os.listdir(p):
|
||||
file = os.path.join(p, file)
|
||||
|
||||
if file.endswith(name):
|
||||
return file
|
||||
|
||||
if os.path.isdir(file):
|
||||
if res := get_path(name, file):
|
||||
return res
|
||||
|
||||
|
||||
def get_sdl2(path, url=SDL2_URL):
|
||||
import requests # NOQA
|
||||
|
||||
stream = io.BytesIO()
|
||||
|
||||
with requests.get(url, stream=True) as r:
|
||||
r.raise_for_status()
|
||||
|
||||
content_length = int(r.headers['Content-Length'])
|
||||
chunks = 0
|
||||
# print()
|
||||
# sys.stdout.write('\r' + str(chunks) + '/' + str(content_length))
|
||||
# sys.stdout.flush()
|
||||
|
||||
for chunk in r.iter_content(chunk_size=1024):
|
||||
stream.write(chunk)
|
||||
chunks += len(chunk)
|
||||
# sys.stdout.write('\r' + str(chunks) + '/' + str(content_length))
|
||||
# sys.stdout.flush()
|
||||
|
||||
# print()
|
||||
stream.seek(0)
|
||||
zf = zipfile.ZipFile(stream)
|
||||
|
||||
for z_item in zf.infolist():
|
||||
for ext in ('.h', '.dll', '.lib'):
|
||||
if not z_item.filename.endswith(ext):
|
||||
continue
|
||||
|
||||
zf.extract(z_item, path=path)
|
||||
break
|
||||
|
||||
include_path = get_path('include', path)
|
||||
lib_path = get_path('lib\\x64', path)
|
||||
dll_path = get_path('SDL2.dll', lib_path)
|
||||
|
||||
sdl_include_path = os.path.split(include_path)[0]
|
||||
if not os.path.exists(os.path.join(sdl_include_path, 'SDL2')):
|
||||
os.rename(include_path, os.path.join(sdl_include_path, 'SDL2'))
|
||||
|
||||
zf.close()
|
||||
stream.close()
|
||||
|
||||
return os.path.abspath(sdl_include_path), dll_path
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,16 @@
|
||||
pycparser>=2.22
|
||||
pyMSVC>=0.5.3; platform_system == "Windows"
|
||||
Sphinx
|
||||
breathe
|
||||
imagesize
|
||||
importlib-metadata
|
||||
sphinx-rtd-theme
|
||||
sphinx-sitemap
|
||||
sphinxcontrib-applehelp
|
||||
sphinxcontrib-devhelp
|
||||
sphinxcontrib-htmlhelp
|
||||
sphinxcontrib-jsmath
|
||||
sphinxcontrib-qthelp
|
||||
sphinxcontrib-serializinghtml
|
||||
sphinx-rtd-dark-mode
|
||||
typing-extensions
|
||||
@@ -0,0 +1,132 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
#
|
||||
# Generate the cmake variables CONFIG_LV_USE_* or CONFIG_LV_BUILD_* from the
|
||||
# preprocessed lv_conf_internal.h
|
||||
#
|
||||
# Author: David TRUAN (david.truan@edgemtech.ch)
|
||||
# Author: Erik Tagirov (erik.tagirov@edgemtech.ch)
|
||||
#
|
||||
|
||||
import os
|
||||
import argparse
|
||||
import re
|
||||
|
||||
def fatal(msg):
|
||||
print()
|
||||
print("ERROR! " + msg)
|
||||
exit(1)
|
||||
|
||||
def get_args():
|
||||
parser = argparse.ArgumentParser(formatter_class=argparse.RawTextHelpFormatter, description=""
|
||||
"Convert the expanded lv_conf_internal.h to cmake variables."
|
||||
"It converts all LV_USE_*, LV_BUILD_* configurations."
|
||||
)
|
||||
|
||||
parser.add_argument('--input', type=str, required=True, nargs='?',
|
||||
help='Path of the macro expanded lv_conf_internal.h, which should be generated during a cmake build')
|
||||
|
||||
parser.add_argument('--output', type=str, required=True, nargs='?',
|
||||
help='Path of the output file, where the cmake variables declaration will be written (ex: build/lv_conf.cmake)')
|
||||
|
||||
parser.add_argument("--kconfig", action="store_true", help="Enable kconfig flag")
|
||||
|
||||
parser.add_argument("--debug", action="store_true", required=False, help="Show unhandled expressions")
|
||||
|
||||
parser.add_argument("--parentscope", action="store_true", required=False, help="Additionaly set the variables in the parent scope")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
# The input must exist
|
||||
if not os.path.exists(args.input):
|
||||
fatal(f"Input {args.input} not found")
|
||||
|
||||
return args
|
||||
|
||||
def write_set_cmd(fout, expr, is_parent_scope):
|
||||
|
||||
fout.write(f'set({expr})\n')
|
||||
|
||||
# This makes the variable usable from the top level directory
|
||||
if is_parent_scope == True:
|
||||
fout.write(f'set({expr} PARENT_SCOPE)\n')
|
||||
|
||||
def generate_cmake_variables(path_input: str, path_output: str, kconfig: bool, debug: bool, is_parent_scope: bool):
|
||||
fin = open(path_input)
|
||||
fout = open(path_output, "w", newline='')
|
||||
|
||||
# If we use Kconfig, we must check the CONFIG_LV_USE_* and
|
||||
# CONFIG_LV_BUILD_* defines
|
||||
if kconfig:
|
||||
CONFIG_PATTERN="^#define +(CONFIG_LV_USE|CONFIG_LV_BUILD)"
|
||||
CONFIG_PREFIX=""
|
||||
# Otherwise check the LV_USE_* and LV_BUILD_* defines
|
||||
else:
|
||||
CONFIG_PATTERN="^#define +(LV_USE|LV_BUILD)"
|
||||
CONFIG_PREFIX="CONFIG_"
|
||||
|
||||
|
||||
# Using the expanded lv_conf_internal, we don't have to deal with regexp,
|
||||
# as all the #define will be aligned on the left with a single space before the value
|
||||
for line in fin.read().splitlines():
|
||||
|
||||
# Treat the LV_USE_STDLIB_* configs in a special way, as we need
|
||||
# to convert the define to full config with 1 value when enabled
|
||||
if re.search(f'{CONFIG_PATTERN}_STDLIB', line):
|
||||
|
||||
parts = line.split()
|
||||
if len(parts) < 3:
|
||||
continue
|
||||
|
||||
name = parts[1]
|
||||
value = parts[2].strip()
|
||||
|
||||
type = value.split("LV_STDLIB_")[1]
|
||||
|
||||
name = name.replace("STDLIB", type)
|
||||
|
||||
write_set_cmd(fout, f'{CONFIG_PREFIX}{name} 1', is_parent_scope)
|
||||
|
||||
# Treat the LV_USE_OS config in a special way, as we need
|
||||
# to convert the define to full config with 1 value when enabled
|
||||
if re.search(f'{CONFIG_PATTERN}_OS', line):
|
||||
|
||||
parts = line.split()
|
||||
if len(parts) < 3:
|
||||
continue
|
||||
|
||||
name = parts[1]
|
||||
value = parts[2].strip()
|
||||
|
||||
type = value.split("LV_OS")[1]
|
||||
|
||||
name += type
|
||||
|
||||
write_set_cmd(fout, f'{CONFIG_PREFIX}{name} 1', is_parent_scope)
|
||||
|
||||
# For the rest of the configs, simply add CONFIG_ and write the name of the define
|
||||
# all LV_USE_* or LV_BUILD_* configs where the value is 0 or 1,
|
||||
# as these are the ones that are needed in cmake
|
||||
# To detect the configuration of LVGL to perform conditional compilation/linking
|
||||
elif re.search(f'{CONFIG_PATTERN}.* +[01] *$', line):
|
||||
|
||||
parts = line.split()
|
||||
if len(parts) < 3:
|
||||
continue
|
||||
|
||||
name = parts[1]
|
||||
value = parts[2].strip()
|
||||
|
||||
write_set_cmd(fout, f'{CONFIG_PREFIX}{name} {value}', is_parent_scope)
|
||||
|
||||
else:
|
||||
# Useful for debugging expressions that are unhandled,
|
||||
# if the script fails in 'unexpected ways'
|
||||
if debug == True:
|
||||
print(f"DBG: Skipping expression: '{line} - not handled'")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
args = get_args()
|
||||
|
||||
generate_cmake_variables(args.input, args.output, args.kconfig, args.debug, args.parentscope)
|
||||
121
managed_components/lvgl__lvgl/scripts/generate_lv_conf.py
Normal file
121
managed_components/lvgl__lvgl/scripts/generate_lv_conf.py
Normal file
@@ -0,0 +1,121 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import os
|
||||
import re
|
||||
import argparse
|
||||
|
||||
DIR_SCRIPTS = os.path.dirname(__file__)
|
||||
REPO_ROOT = os.path.join(DIR_SCRIPTS, "..")
|
||||
DIR_CWD = os.getcwd()
|
||||
|
||||
|
||||
def fatal(msg):
|
||||
print()
|
||||
print("ERROR! " + msg)
|
||||
exit(1)
|
||||
|
||||
|
||||
def get_args():
|
||||
parser = argparse.ArgumentParser(formatter_class=argparse.RawTextHelpFormatter, description=""
|
||||
"Update the configuration file of your existing project based on default parameters and latest LVGL template. Eg.:\n"
|
||||
" python3 generate_lv_conf.py ./src \n"
|
||||
" python3 generate_lv_conf.py --template modules/lvgl/lv_conf_template.h ./my_config_folder"
|
||||
)
|
||||
|
||||
parser.add_argument('--template', type=str, default=REPO_ROOT, nargs='?',
|
||||
help='Path of "lv_conf_template.h" file or the folder containing it\n(optional, 1 folder above the python script by default)')
|
||||
|
||||
parser.add_argument('--config', type=str, default=None, nargs='?',
|
||||
help='Path of "lv_conf.h" file (optional)')
|
||||
|
||||
parser.add_argument('--defaults', type=str, default=None, nargs='?',
|
||||
help='Path of "lv_conf.defaults" file (optional)')
|
||||
|
||||
parser.add_argument('target', metavar='target', type=str, default=DIR_CWD, nargs='?',
|
||||
help='Folder containing "lv_conf.h" and "lv_conf.defaults" files\n(optional, current work folder by default)')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if os.path.isdir(args.template):
|
||||
args.template = os.path.join(args.template, "lv_conf_template.h")
|
||||
|
||||
if not args.config:
|
||||
args.config = os.path.join(args.target, "lv_conf.h")
|
||||
|
||||
if not args.defaults:
|
||||
args.defaults = os.path.join(args.target, "lv_conf.defaults")
|
||||
|
||||
if not os.path.exists(args.template):
|
||||
fatal(f"Template file not found at {args.template}")
|
||||
if not os.path.exists(args.config):
|
||||
fatal(f"User config file not found at {args.config}")
|
||||
if not os.path.exists(args.defaults):
|
||||
fatal(f"User defaults not found at {args.defaults}")
|
||||
|
||||
return args
|
||||
|
||||
|
||||
def parse_defaults(path: str):
|
||||
defaults = {}
|
||||
|
||||
with open(path, 'r', encoding='utf-8') as file:
|
||||
for line in file.readlines():
|
||||
if len(line.strip()) == 0 or line.startswith('#'):
|
||||
continue
|
||||
groups = re.search(r'([A-Z0-9_]+)\s+(.+)', line).groups()
|
||||
defaults[groups[0]] = groups[1]
|
||||
|
||||
return defaults
|
||||
|
||||
|
||||
def generate_config(path_destination: str, path_source: str, defaults: dict):
|
||||
with open(path_source, 'r', encoding='utf-8') as f_src:
|
||||
src_lines = f_src.readlines()
|
||||
|
||||
keys_used = set()
|
||||
dst_lines = []
|
||||
|
||||
for src_line in src_lines:
|
||||
res = re.search(r'#define\s+([A-Z0-9_]+)\s+(.+)', src_line)
|
||||
key = res.groups()[0] if res else None
|
||||
|
||||
if key in defaults.keys():
|
||||
value = defaults[key]
|
||||
pattern = r'(#define\s+[A-Z0-9_]+\s+)(.+)'
|
||||
repl = r'\g<1>' + value
|
||||
dst_line, _ = re.subn(pattern, repl, src_line)
|
||||
|
||||
if not dst_line:
|
||||
fatal(f"Failed to apply key '{key}' to line '{src_line}'")
|
||||
|
||||
print(f"Applying: {key} = {value}")
|
||||
keys_used.add(key)
|
||||
elif 'Set this to "1" to enable content' in src_line:
|
||||
dst_line = '#if 1 /* Enable content */'
|
||||
else:
|
||||
dst_line = src_line
|
||||
|
||||
dst_lines.append(dst_line)
|
||||
|
||||
if len(keys_used) != len(defaults):
|
||||
unused_keys = [k for k in defaults.keys() if k not in keys_used]
|
||||
fatal('The following keys are deprecated:\n ' + '\n '.join(unused_keys))
|
||||
|
||||
with open(path_destination, 'w', encoding='utf-8') as f_dst:
|
||||
for dst_line in dst_lines:
|
||||
f_dst.write(dst_line)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
args = get_args()
|
||||
|
||||
print("Template:", args.template)
|
||||
print("User config:", args.config)
|
||||
print("User defaults:", args.defaults)
|
||||
|
||||
defaults = parse_defaults(args.defaults)
|
||||
print(f"Loaded {len(defaults)} defaults")
|
||||
|
||||
generate_config(args.config, args.template, defaults)
|
||||
print()
|
||||
print('New config successfully generated!')
|
||||
15
managed_components/lvgl__lvgl/scripts/genexamplelist.sh
Normal file
15
managed_components/lvgl__lvgl/scripts/genexamplelist.sh
Normal file
@@ -0,0 +1,15 @@
|
||||
#!/bin/bash
|
||||
echo "/* Autogenerated */"
|
||||
echo '#include <stddef.h>'
|
||||
echo '#include "examplelist.h"'
|
||||
TMPFILE=$(mktemp)
|
||||
find examples demos -name \*.h | xargs grep -hE "^void lv_(example|demo)" | sed 's/(/ /g' | awk '{print $2}' > $TMPFILE
|
||||
cat $TMPFILE | while read -r line; do
|
||||
echo "extern void ${line}(void);"
|
||||
done
|
||||
echo "const struct lv_ci_example lv_ci_example_list[] = {"
|
||||
cat $TMPFILE | while read -r line; do
|
||||
echo " { \"$line\", $line },";
|
||||
done
|
||||
echo " { NULL, NULL }"
|
||||
echo "};"
|
||||
31
managed_components/lvgl__lvgl/scripts/image_viewer.py
Normal file
31
managed_components/lvgl__lvgl/scripts/image_viewer.py
Normal file
@@ -0,0 +1,31 @@
|
||||
#!/usr/bin/env python3
|
||||
from LVGLImage import LVGLImage
|
||||
import argparse
|
||||
import logging
|
||||
import os
|
||||
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
|
||||
parser = argparse.ArgumentParser(description="LVGL Binary Image Viewer")
|
||||
parser.add_argument("file", help="the .bin image file")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
name, ext = os.path.splitext(args.file)
|
||||
if ext != ".bin":
|
||||
raise ValueError("Only support LVGL .bin image file")
|
||||
|
||||
output = name + ".png"
|
||||
img = LVGLImage().from_bin(args.file)
|
||||
img.to_png(output)
|
||||
logging.info(f"convert {args.file} to {output}")
|
||||
|
||||
if os.name == "posix":
|
||||
os.system(f"open {output}")
|
||||
else:
|
||||
try:
|
||||
from PIL import Image
|
||||
except ImportError:
|
||||
raise ImportError("Need pillow package, do `pip3 install pillow`")
|
||||
image = Image.open(output)
|
||||
image.show(title=output)
|
||||
10
managed_components/lvgl__lvgl/scripts/infer_run.sh
Normal file
10
managed_components/lvgl__lvgl/scripts/infer_run.sh
Normal file
@@ -0,0 +1,10 @@
|
||||
#!/bin/sh
|
||||
# https://github.com/facebook/infer
|
||||
#
|
||||
# Install:
|
||||
# VERSION=0.17.0; \
|
||||
# curl -sSL "https://github.com/facebook/infer/releases/download/v$VERSION/infer-linux64-v$VERSION.tar.xz" \
|
||||
# | sudo tar -C /opt -xJ && \
|
||||
# sudoln -s "/opt/infer-linux64-v$VERSION/bin/infer" /usr/local/bin/infer
|
||||
|
||||
infer run -- make -j8
|
||||
@@ -0,0 +1,4 @@
|
||||
vcpkg install vcpkg-tool-ninja libpng freetype opengl glfw3 glew
|
||||
if %errorlevel% neq 0 exit /b %errorlevel%
|
||||
pip install pypng lz4 kconfiglib
|
||||
if %errorlevel% neq 0 exit /b %errorlevel%
|
||||
@@ -0,0 +1,15 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Install Linux package prerequisites needed for LVGL development
|
||||
# and testing. Some less-common development packages are not included
|
||||
# here, such as MicroPython and PC simulator packages.
|
||||
#
|
||||
# Note: This script is run by the CI workflows.
|
||||
SCRIPT_PATH=$(readlink -f $0)
|
||||
SCRIPT_DIR=$(dirname $SCRIPT_PATH)
|
||||
|
||||
sudo dpkg --add-architecture i386
|
||||
sudo apt update
|
||||
|
||||
cat $SCRIPT_DIR/prerequisites-apt.txt | xargs sudo apt install -y
|
||||
pip3 install --user -r $SCRIPT_DIR/prerequisites-pip.txt
|
||||
16
managed_components/lvgl__lvgl/scripts/install_astyle.sh
Normal file
16
managed_components/lvgl__lvgl/scripts/install_astyle.sh
Normal file
@@ -0,0 +1,16 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Check if the script is being run as root
|
||||
if [ "$(id -u)" -ne 0 ]; then
|
||||
echo "This script must be run as root or with sudo" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
rm -rf astyle
|
||||
git clone https://github.com/lvgl/astyle.git
|
||||
cd astyle/build/gcc
|
||||
git checkout v3.4.12
|
||||
make -j
|
||||
make install
|
||||
cd ../../..
|
||||
rm -rf astyle
|
||||
11
managed_components/lvgl__lvgl/scripts/install_pngquant.sh
Normal file
11
managed_components/lvgl__lvgl/scripts/install_pngquant.sh
Normal file
@@ -0,0 +1,11 @@
|
||||
#!/bin/sh
|
||||
|
||||
rm -rf pngquant
|
||||
git clone https://github.com/kornelski/pngquant
|
||||
cd pngquant
|
||||
git checkout 2.17.0
|
||||
./configure
|
||||
make -j
|
||||
sudo make install
|
||||
cd ..
|
||||
rm -rf pngquant
|
||||
140
managed_components/lvgl__lvgl/scripts/jpg_to_sjpg.py
Normal file
140
managed_components/lvgl__lvgl/scripts/jpg_to_sjpg.py
Normal file
@@ -0,0 +1,140 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
##################################################################
|
||||
# sjpeg converter script version 1.0
|
||||
# Dependencies: (PYTHON-3)
|
||||
##################################################################
|
||||
SJPG_FILE_FORMAT_VERSION = "V1.00" #
|
||||
JPEG_SPLIT_HEIGHT = 16
|
||||
##################################################################
|
||||
import math, os, sys, time
|
||||
from PIL import Image
|
||||
|
||||
|
||||
OUTPUT_FILE_NAME = ""
|
||||
INPUT_FILE = ""
|
||||
|
||||
|
||||
if len(sys.argv) == 2:
|
||||
INPUT_FILE = sys.argv[1]
|
||||
OUTPUT_FILE_NAME = INPUT_FILE.split("/")[-1].split("\\")[-1].split(".")[0]
|
||||
else:
|
||||
print("usage:\n\t python " + sys.argv[0] + " input_file.jpg")
|
||||
sys.exit(0)
|
||||
|
||||
try:
|
||||
im = Image.open(INPUT_FILE)
|
||||
except:
|
||||
print("\nFile not found!")
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
print("\nConversion started...\n")
|
||||
start_time = time.time()
|
||||
width, height = im.size
|
||||
|
||||
print("Input:")
|
||||
print("\t" + INPUT_FILE)
|
||||
print("\tRES = " + str(width) + " x " + str(height) + '\n')
|
||||
|
||||
|
||||
lenbuf = []
|
||||
block_size = JPEG_SPLIT_HEIGHT;
|
||||
splits = math.ceil(height/block_size)
|
||||
|
||||
c_code = '''//LVGL SJPG C ARRAY\n#include "lvgl/lvgl.h"\n\nconst uint8_t ''' + OUTPUT_FILE_NAME + '''_map[] = {\n'''
|
||||
|
||||
sjpeg_data = bytearray()
|
||||
sjpeg = bytearray()
|
||||
|
||||
|
||||
row_remaining = height;
|
||||
for i in range(splits):
|
||||
if row_remaining < block_size:
|
||||
crop = im.crop((0, i*block_size, width, row_remaining + i*block_size))
|
||||
else:
|
||||
crop = im.crop((0, i*block_size, width, block_size + i*block_size))
|
||||
|
||||
row_remaining = row_remaining - block_size;
|
||||
crop.save(str(i)+".jpg", quality=90)
|
||||
|
||||
|
||||
|
||||
|
||||
for i in range(splits):
|
||||
f = open(str(i)+".jpg", "rb")
|
||||
a = f.read()
|
||||
f.close()
|
||||
sjpeg_data = sjpeg_data + a
|
||||
lenbuf.append(len(a))
|
||||
|
||||
header = bytearray()
|
||||
|
||||
#4 BYTES
|
||||
header = header + bytearray("_SJPG__".encode("UTF-8"));
|
||||
|
||||
#6 BYTES VERSION
|
||||
header = header + bytearray(("\x00" + SJPG_FILE_FORMAT_VERSION + "\x00").encode("UTF-8"));
|
||||
|
||||
#WIDTH 2 BYTES
|
||||
header = header + width.to_bytes(2, byteorder='little');
|
||||
|
||||
#HEIGHT 2 BYTES
|
||||
header = header + height.to_bytes(2, byteorder='little');
|
||||
|
||||
#NUMBER OF ITEMS 2 BYTES
|
||||
header = header + splits.to_bytes(2, byteorder='little');
|
||||
|
||||
#NUMBER OF ITEMS 2 BYTES
|
||||
header = header + int(JPEG_SPLIT_HEIGHT).to_bytes(2, byteorder='little');
|
||||
|
||||
for item_len in lenbuf:
|
||||
# WIDTH 2 BYTES
|
||||
header = header + item_len.to_bytes(2, byteorder='little');
|
||||
|
||||
|
||||
data = bytearray()
|
||||
|
||||
sjpeg = header + sjpeg_data;
|
||||
|
||||
if 1:
|
||||
for i in range(len(lenbuf)):
|
||||
os.remove(str(i) + ".jpg")
|
||||
|
||||
|
||||
f = open(OUTPUT_FILE_NAME+".sjpg","wb");
|
||||
f.write(sjpeg)
|
||||
f.close()
|
||||
|
||||
new_line_threshold = 0
|
||||
for i in range(len(sjpeg)):
|
||||
c_code = c_code + "\t" + str(hex(sjpeg[i])) + ","
|
||||
new_line_threshold = new_line_threshold + 1
|
||||
if (new_line_threshold >= 16):
|
||||
c_code = c_code + "\n"
|
||||
new_line_threshold = 0
|
||||
|
||||
|
||||
c_code = c_code + "\n};\n\nlv_image_dsc_t "
|
||||
c_code = c_code + OUTPUT_FILE_NAME + " = {\n"
|
||||
c_code = c_code + "\t.header.always_zero = 0,\n"
|
||||
c_code = c_code + "\t.header.w = " + str(width) + ",\n"
|
||||
c_code = c_code + "\t.header.h = " + str(height) + ",\n"
|
||||
c_code = c_code + "\t.data_size = " + str(len(sjpeg)) + ",\n"
|
||||
c_code = c_code + "\t.header.cf = LV_IMG_CF_RAW,\n"
|
||||
c_code = c_code + "\t.data = " + OUTPUT_FILE_NAME+"_map" + ",\n};"
|
||||
|
||||
|
||||
f = open(OUTPUT_FILE_NAME + '.c', 'w')
|
||||
f.write(c_code)
|
||||
f.close()
|
||||
|
||||
|
||||
time_taken = (time.time() - start_time)
|
||||
|
||||
print("Output:")
|
||||
print("\tTime taken = " + str(round(time_taken,2)) + " sec")
|
||||
print("\tbin size = " + str(round(len(sjpeg)/1024, 1)) + " KB" )
|
||||
print("\t" + OUTPUT_FILE_NAME + ".sjpg\t(bin file)" + "\n\t" + OUTPUT_FILE_NAME + ".c\t\t(c array)")
|
||||
|
||||
print("\nAll good!")
|
||||
346
managed_components/lvgl__lvgl/scripts/kconfig.py
Normal file
346
managed_components/lvgl__lvgl/scripts/kconfig.py
Normal file
@@ -0,0 +1,346 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# Originally modified from:
|
||||
# https://github.com/zephyrproject-rtos/zephyr/blob/main/scripts/kconfig/kconfig.py
|
||||
|
||||
# SPDX-License-Identifier: ISC
|
||||
|
||||
# Writes/updates the lvgl/.config configuration file by merging configuration
|
||||
# files passed as arguments
|
||||
#
|
||||
# When fragments haven't changed, lvgl/.config is both the input and the
|
||||
# output, which just updates it. This is handled in the CMake files.
|
||||
#
|
||||
# Also does various checks (most via Kconfiglib warnings).
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import textwrap
|
||||
|
||||
# Lvgl doesn't use tristate symbols. They're supported here just to make the
|
||||
# script a bit more generic.
|
||||
from kconfiglib import (
|
||||
Kconfig,
|
||||
split_expr,
|
||||
expr_value,
|
||||
expr_str,
|
||||
BOOL,
|
||||
TRISTATE,
|
||||
TRI_TO_STR,
|
||||
AND,
|
||||
OR,
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
print(sys.argv)
|
||||
args = parse_args()
|
||||
|
||||
print("Parsing " + args.kconfig_file)
|
||||
kconf = Kconfig(args.kconfig_file, warn_to_stderr=False, suppress_traceback=True)
|
||||
|
||||
if args.handwritten_input_configs:
|
||||
# Warn for assignments to undefined symbols, but only for handwritten
|
||||
# fragments, to avoid warnings-turned-errors when using an old
|
||||
# configuration file together with updated Kconfig files
|
||||
kconf.warn_assign_undef = True
|
||||
|
||||
# prj.conf may override settings from the board configuration, so
|
||||
# disable warnings about symbols being assigned more than once
|
||||
kconf.warn_assign_override = False
|
||||
kconf.warn_assign_redun = False
|
||||
|
||||
if args.forced_input_configs:
|
||||
# Do not warn on a redundant config.
|
||||
# The reason is that a regular .config will be followed by the forced
|
||||
# config which under normal circumstances should be identical to the
|
||||
# configured setting.
|
||||
# Only if user has modified to a value that gets overruled by the forced
|
||||
# a warning shall be issued.
|
||||
kconf.warn_assign_redun = False
|
||||
|
||||
# Load files
|
||||
print(kconf.load_config(args.configs_in[0]))
|
||||
for config in args.configs_in[1:]:
|
||||
# replace=False creates a merged configuration
|
||||
print(kconf.load_config(config, replace=False))
|
||||
|
||||
if args.handwritten_input_configs:
|
||||
# Check that there are no assignments to promptless symbols, which
|
||||
# have no effect.
|
||||
#
|
||||
# This only makes sense when loading handwritten fragments and not when
|
||||
# loading lvgl/.config, because lvgl/.config is configuration
|
||||
# output and also assigns promptless symbols.
|
||||
check_no_promptless_assign(kconf)
|
||||
|
||||
# Print warnings for symbols that didn't get the assigned value. Only
|
||||
# do this for handwritten input too, to avoid likely unhelpful warnings
|
||||
# when using an old configuration and updating Kconfig files.
|
||||
check_assigned_sym_values(kconf)
|
||||
check_assigned_choice_values(kconf)
|
||||
|
||||
if kconf.syms.get("WARN_DEPRECATED", kconf.y).tri_value == 2:
|
||||
check_deprecated(kconf)
|
||||
|
||||
if kconf.syms.get("WARN_EXPERIMENTAL", kconf.y).tri_value == 2:
|
||||
check_experimental(kconf)
|
||||
|
||||
# Hack: Force all symbols to be evaluated, to catch warnings generated
|
||||
# during evaluation. Wait till the end to write the actual output files, so
|
||||
# that we don't generate any output if there are warnings-turned-errors.
|
||||
#
|
||||
# Kconfiglib caches calculated symbol values internally, so this is still
|
||||
# fast.
|
||||
kconf.write_config(os.devnull)
|
||||
|
||||
warn_only = r"warning:.*set more than once."
|
||||
|
||||
if kconf.warnings:
|
||||
if args.forced_input_configs:
|
||||
error_out = False
|
||||
else:
|
||||
error_out = True
|
||||
|
||||
# Put a blank line between warnings to make them easier to read
|
||||
for warning in kconf.warnings:
|
||||
print("\n" + warning, file=sys.stderr)
|
||||
|
||||
if not error_out and not re.search(warn_only, warning):
|
||||
# The warning is not a warn_only, fail the Kconfig.
|
||||
error_out = True
|
||||
|
||||
# Turn all warnings into errors, so that e.g. assignments to undefined
|
||||
# Kconfig symbols become errors.
|
||||
#
|
||||
# A warning is generated by this script whenever a symbol gets a
|
||||
# different value than the one it was assigned. Keep that one as just a
|
||||
# warning for now.
|
||||
if error_out:
|
||||
err("Aborting due to Kconfig warnings")
|
||||
|
||||
# Write the merged configuration and the C header
|
||||
print(kconf.write_config(args.config_out))
|
||||
print(kconf.write_autoconf(args.header_out))
|
||||
|
||||
# Write the list of parsed Kconfig files to a file
|
||||
write_kconfig_filenames(kconf, args.kconfig_list_out)
|
||||
|
||||
|
||||
def check_no_promptless_assign(kconf):
|
||||
# Checks that no promptless symbols are assigned
|
||||
|
||||
for sym in kconf.unique_defined_syms:
|
||||
if sym.user_value is not None and promptless(sym):
|
||||
err(
|
||||
f"""\
|
||||
{sym.name_and_loc} is assigned in a configuration file, but is not directly
|
||||
user-configurable (has no prompt). It gets its value indirectly from other
|
||||
symbols. """
|
||||
+ SYM_INFO_HINT.format(sym)
|
||||
)
|
||||
|
||||
|
||||
def check_assigned_sym_values(kconf):
|
||||
# Verifies that the values assigned to symbols "took" (matches the value
|
||||
# the symbols actually got), printing warnings otherwise. Choice symbols
|
||||
# are checked separately, in check_assigned_choice_values().
|
||||
|
||||
for sym in kconf.unique_defined_syms:
|
||||
if sym.choice:
|
||||
continue
|
||||
|
||||
user_value = sym.user_value
|
||||
if user_value is None:
|
||||
continue
|
||||
|
||||
# Tristate values are represented as 0, 1, 2. Having them as "n", "m",
|
||||
# "y" is more convenient here, so convert.
|
||||
if sym.type in (BOOL, TRISTATE):
|
||||
user_value = TRI_TO_STR[user_value]
|
||||
|
||||
if user_value != sym.str_value:
|
||||
msg = (
|
||||
f"{sym.name_and_loc} was assigned the value '{user_value}'"
|
||||
f" but got the value '{sym.str_value}'. "
|
||||
)
|
||||
|
||||
# List any unsatisfied 'depends on' dependencies in the warning
|
||||
mdeps = missing_deps(sym)
|
||||
if mdeps:
|
||||
expr_strs = []
|
||||
for expr in mdeps:
|
||||
estr = expr_str(expr)
|
||||
if isinstance(expr, tuple):
|
||||
# Add () around dependencies that aren't plain symbols.
|
||||
# Gives '(FOO || BAR) (=n)' instead of
|
||||
# 'FOO || BAR (=n)', which might be clearer.
|
||||
estr = f"({estr})"
|
||||
expr_strs.append(f"{estr} " f"(={TRI_TO_STR[expr_value(expr)]})")
|
||||
|
||||
msg += (
|
||||
"Check these unsatisfied dependencies: "
|
||||
+ ", ".join(expr_strs)
|
||||
+ ". "
|
||||
)
|
||||
|
||||
warn(msg + SYM_INFO_HINT.format(sym))
|
||||
|
||||
|
||||
def missing_deps(sym):
|
||||
# check_assigned_sym_values() helper for finding unsatisfied dependencies.
|
||||
#
|
||||
# Given direct dependencies
|
||||
#
|
||||
# depends on <expr> && <expr> && ... && <expr>
|
||||
#
|
||||
# on 'sym' (which can also come from e.g. a surrounding 'if'), returns a
|
||||
# list of all <expr>s with a value less than the value 'sym' was assigned
|
||||
# ("less" instead of "not equal" just to be general and handle tristates,
|
||||
# even though lvgl doesn't use them).
|
||||
#
|
||||
# For string/int/hex symbols, just looks for <expr> = n.
|
||||
#
|
||||
# Note that <expr>s can be something more complicated than just a symbol,
|
||||
# like 'FOO || BAR' or 'FOO = "string"'.
|
||||
|
||||
deps = split_expr(sym.direct_dep, AND)
|
||||
|
||||
if sym.type in (BOOL, TRISTATE):
|
||||
return [dep for dep in deps if expr_value(dep) < sym.user_value]
|
||||
# string/int/hex
|
||||
return [dep for dep in deps if expr_value(dep) == 0]
|
||||
|
||||
|
||||
def check_assigned_choice_values(kconf):
|
||||
# Verifies that any choice symbols that were selected (by setting them to
|
||||
# y) ended up as the selection, printing warnings otherwise.
|
||||
#
|
||||
# We check choice symbols separately to avoid warnings when two different
|
||||
# choice symbols within the same choice are set to y. This might happen if
|
||||
# a choice selection from a board defconfig is overridden in a prj.conf,
|
||||
# for example. The last choice symbol set to y becomes the selection (and
|
||||
# all other choice symbols get the value n).
|
||||
#
|
||||
# Without special-casing choices, we'd detect that the first symbol set to
|
||||
# y ended up as n, and print a spurious warning.
|
||||
|
||||
for choice in kconf.unique_choices:
|
||||
if choice.user_selection and choice.user_selection is not choice.selection:
|
||||
|
||||
warn(
|
||||
f"""\
|
||||
The choice symbol {choice.user_selection.name_and_loc} was selected (set =y),
|
||||
but {choice.selection.name_and_loc if choice.selection else "no symbol"} ended
|
||||
up as the choice selection. """
|
||||
+ SYM_INFO_HINT.format(choice.user_selection)
|
||||
)
|
||||
|
||||
|
||||
# Hint on where to find symbol information. Used like
|
||||
# SYM_INFO_HINT.format(sym).
|
||||
SYM_INFO_HINT = """\
|
||||
See https://docs.lvgl.io/master/intro/add-lvgl-to-your-project/configuration.html
|
||||
look up {0.name} in the menuconfig/guiconfig interface. The Application
|
||||
Development Primer, Setting Configuration Values, and Kconfig - Tips and Best
|
||||
Practices sections of the manual might be helpful too.\
|
||||
"""
|
||||
|
||||
|
||||
def check_deprecated(kconf):
|
||||
deprecated = kconf.syms.get("DEPRECATED")
|
||||
dep_expr = kconf.n if deprecated is None else deprecated.rev_dep
|
||||
|
||||
if dep_expr is not kconf.n:
|
||||
selectors = [s for s in split_expr(dep_expr, OR) if expr_value(s) == 2]
|
||||
for selector in selectors:
|
||||
selector_name = split_expr(selector, AND)[0].name
|
||||
warn(f"Deprecated symbol {selector_name} is enabled.")
|
||||
|
||||
|
||||
def check_experimental(kconf):
|
||||
experimental = kconf.syms.get("EXPERIMENTAL")
|
||||
dep_expr = kconf.n if experimental is None else experimental.rev_dep
|
||||
|
||||
if dep_expr is not kconf.n:
|
||||
selectors = [s for s in split_expr(dep_expr, OR) if expr_value(s) == 2]
|
||||
for selector in selectors:
|
||||
selector_name = split_expr(selector, AND)[0].name
|
||||
warn(f"Experimental symbol {selector_name} is enabled.")
|
||||
|
||||
|
||||
def promptless(sym):
|
||||
# Returns True if 'sym' has no prompt. Since the symbol might be defined in
|
||||
# multiple locations, we need to check all locations.
|
||||
|
||||
return not any(node.prompt for node in sym.nodes)
|
||||
|
||||
|
||||
def write_kconfig_filenames(kconf, kconfig_list_path):
|
||||
# Writes a sorted list with the absolute paths of all parsed Kconfig files
|
||||
# to 'kconfig_list_path'. The paths are realpath()'d, and duplicates are
|
||||
# removed. This file is used by CMake to look for changed Kconfig files. It
|
||||
# needs to be deterministic.
|
||||
|
||||
with open(kconfig_list_path, "w") as out:
|
||||
for path in sorted(
|
||||
{
|
||||
os.path.realpath(os.path.join(kconf.srctree, path))
|
||||
for path in kconf.kconfig_filenames
|
||||
}
|
||||
):
|
||||
print(path, file=out)
|
||||
|
||||
|
||||
def parse_args():
|
||||
parser = argparse.ArgumentParser(allow_abbrev=False)
|
||||
|
||||
parser.add_argument(
|
||||
"--handwritten-input-configs",
|
||||
action="store_true",
|
||||
help="Assume the input configuration fragments are "
|
||||
"handwritten fragments and do additional checks "
|
||||
"on them, like no promptless symbols being "
|
||||
"assigned",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--forced-input-configs",
|
||||
action="store_true",
|
||||
help="Indicate the input configuration files are "
|
||||
"followed by an forced configuration file."
|
||||
"The forced configuration is used to forcefully "
|
||||
"set specific configuration settings to a "
|
||||
"pre-defined value and thereby remove any user "
|
||||
" adjustments.",
|
||||
)
|
||||
parser.add_argument("kconfig_file", help="Top-level Kconfig file")
|
||||
parser.add_argument("config_out", help="Output configuration file")
|
||||
parser.add_argument("header_out", help="Output header file")
|
||||
parser.add_argument(
|
||||
"kconfig_list_out", help="Output file for list of parsed Kconfig files"
|
||||
)
|
||||
parser.add_argument(
|
||||
"configs_in",
|
||||
nargs="+",
|
||||
help="Input configuration fragments. Will be merged " "together.",
|
||||
)
|
||||
|
||||
return parser.parse_args()
|
||||
|
||||
|
||||
def warn(msg):
|
||||
# Use a large fill() width to try to avoid linebreaks in the symbol
|
||||
# reference link, and add some extra newlines to set the message off from
|
||||
# surrounding text (this usually gets printed as part of spammy CMake
|
||||
# output)
|
||||
print("\n" + textwrap.fill("warning: " + msg, 100) + "\n", file=sys.stderr)
|
||||
|
||||
|
||||
def err(msg):
|
||||
sys.exit("\n" + textwrap.fill("error: " + msg, 100) + "\n")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
29
managed_components/lvgl__lvgl/scripts/kconfig_verify.py
Normal file
29
managed_components/lvgl__lvgl/scripts/kconfig_verify.py
Normal file
@@ -0,0 +1,29 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import sys
|
||||
|
||||
try:
|
||||
import kconfiglib
|
||||
except ImportError:
|
||||
print("Need kconfiglib package, do `pip3 install kconfiglib`")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def verify_kconfig(kconfig_file):
|
||||
kconf = kconfiglib.Kconfig(kconfig_file)
|
||||
|
||||
if kconf.warnings:
|
||||
print("Warnings found:")
|
||||
for warning in kconf.warnings:
|
||||
print(warning)
|
||||
sys.exit(1)
|
||||
else:
|
||||
print("No warnings found.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
if len(sys.argv) != 2:
|
||||
print("Usage: python check_kconfig.py <Kconfig_file>")
|
||||
sys.exit(1)
|
||||
|
||||
verify_kconfig(sys.argv[1])
|
||||
286
managed_components/lvgl__lvgl/scripts/lv_conf_internal_gen.py
Normal file
286
managed_components/lvgl__lvgl/scripts/lv_conf_internal_gen.py
Normal file
@@ -0,0 +1,286 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
'''
|
||||
Generates lv_conf_internal.h from lv_conf_template.h to provide default values
|
||||
'''
|
||||
|
||||
import os
|
||||
import sys
|
||||
import re
|
||||
|
||||
SCRIPT_DIR = os.path.dirname(__file__)
|
||||
LV_CONF_TEMPLATE = os.path.join(SCRIPT_DIR, "..", "lv_conf_template.h")
|
||||
LV_CONF_INTERNAL = os.path.join(SCRIPT_DIR, "..", "src", "lv_conf_internal.h")
|
||||
|
||||
if sys.version_info < (3,6,0):
|
||||
print("Python >=3.6 is required", file=sys.stderr)
|
||||
exit(1)
|
||||
|
||||
def check_for_tabs(file_path):
|
||||
errors = []
|
||||
with open(file_path, 'r') as file:
|
||||
for line_number, line in enumerate(file, 1):
|
||||
if '\t' in line:
|
||||
errors.append(f" {file_path}:{line_number}")
|
||||
|
||||
if errors:
|
||||
print(f"Tabs found in the following files:", file=sys.stderr)
|
||||
for error in errors:
|
||||
print(error, file=sys.stderr)
|
||||
print("Please replace tabs with spaces.", file=sys.stderr)
|
||||
exit(1)
|
||||
|
||||
check_for_tabs(LV_CONF_TEMPLATE)
|
||||
|
||||
fin = open(LV_CONF_TEMPLATE)
|
||||
fout = open(LV_CONF_INTERNAL, "w", newline='')
|
||||
|
||||
fout.write(
|
||||
'''/**
|
||||
* GENERATED FILE, DO NOT EDIT IT!
|
||||
* @file lv_conf_internal.h
|
||||
* This file ensures all defines of lv_conf.h have a default value.
|
||||
*/
|
||||
|
||||
#ifndef LV_CONF_INTERNAL_H
|
||||
#define LV_CONF_INTERNAL_H
|
||||
/* clang-format off */
|
||||
|
||||
/* Config options */
|
||||
#define LV_OS_NONE 0
|
||||
#define LV_OS_PTHREAD 1
|
||||
#define LV_OS_FREERTOS 2
|
||||
#define LV_OS_CMSIS_RTOS2 3
|
||||
#define LV_OS_RTTHREAD 4
|
||||
#define LV_OS_WINDOWS 5
|
||||
#define LV_OS_MQX 6
|
||||
#define LV_OS_SDL2 7
|
||||
#define LV_OS_CUSTOM 255
|
||||
|
||||
#define LV_STDLIB_BUILTIN 0
|
||||
#define LV_STDLIB_CLIB 1
|
||||
#define LV_STDLIB_MICROPYTHON 2
|
||||
#define LV_STDLIB_RTTHREAD 3
|
||||
#define LV_STDLIB_CUSTOM 255
|
||||
|
||||
#define LV_DRAW_SW_ASM_NONE 0
|
||||
#define LV_DRAW_SW_ASM_NEON 1
|
||||
#define LV_DRAW_SW_ASM_HELIUM 2
|
||||
#define LV_DRAW_SW_ASM_CUSTOM 255
|
||||
|
||||
#define LV_NEMA_HAL_CUSTOM 0
|
||||
#define LV_NEMA_HAL_STM32 1
|
||||
|
||||
/** Handle special Kconfig options. */
|
||||
#ifndef LV_KCONFIG_IGNORE
|
||||
#include "lv_conf_kconfig.h"
|
||||
#if defined(CONFIG_LV_CONF_SKIP) && !defined(LV_CONF_SKIP)
|
||||
#define LV_CONF_SKIP
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* If "lv_conf.h" is available from here try to use it later. */
|
||||
#ifdef __has_include
|
||||
#if __has_include("lv_conf.h")
|
||||
#ifndef LV_CONF_INCLUDE_SIMPLE
|
||||
#define LV_CONF_INCLUDE_SIMPLE
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* If lv_conf.h is not skipped, include it. */
|
||||
#if !defined(LV_CONF_SKIP) || defined(LV_CONF_PATH)
|
||||
#ifdef LV_CONF_PATH /* If there is a path defined for lv_conf.h, use it */
|
||||
#include LV_CONF_PATH /* Note: Make sure to define custom CONF_PATH as a string */
|
||||
#elif defined(LV_CONF_INCLUDE_SIMPLE) /* Or simply include lv_conf.h is enabled. */
|
||||
#include "lv_conf.h"
|
||||
#else
|
||||
#include "../../lv_conf.h" /* Else assume lv_conf.h is next to the lvgl folder. */
|
||||
#endif
|
||||
#if !defined(LV_CONF_H) && !defined(LV_CONF_SUPPRESS_DEFINE_CHECK)
|
||||
/* #include will sometimes silently fail when __has_include is used */
|
||||
/* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80753 */
|
||||
#pragma message("Possible failure to include lv_conf.h, please read the comment in this file if you get errors")
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_LV_COLOR_DEPTH
|
||||
#define LV_KCONFIG_PRESENT
|
||||
#endif
|
||||
|
||||
/*----------------------------------
|
||||
* Start parsing lv_conf_template.h
|
||||
-----------------------------------*/
|
||||
'''
|
||||
)
|
||||
|
||||
started = 0
|
||||
|
||||
for line in fin.read().splitlines():
|
||||
if not started:
|
||||
if '#define LV_CONF_H' in line:
|
||||
started = 1
|
||||
continue
|
||||
else:
|
||||
continue
|
||||
|
||||
if '/*--END OF LV_CONF_H--*/' in line: break
|
||||
|
||||
#Is there a #define in this line?
|
||||
r = re.search(r'^([\s]*)#[\s]*(undef|define)[\s]+([^\s]+).*$', line) # \s means any white space character
|
||||
|
||||
if r:
|
||||
indent = r[1]
|
||||
|
||||
name = r[3]
|
||||
name = re.sub(r'\(.*?\)', '', name, count=1) #remove parentheses from macros. E.g. MY_FUNC(5) -> MY_FUNC
|
||||
|
||||
line = re.sub(r'[\s]*', '', line, count=1)
|
||||
|
||||
#If the value should be 1 (enabled) by default use a more complex structure for Kconfig checks because
|
||||
#if a not defined CONFIG_... value should be interpreted as 0 and not the LVGL default
|
||||
is_one = re.search(r'#[\s]*define[\s]*[A-Z0-9_]+[\s]+1([\s]*$|[\s]+)', line)
|
||||
if is_one:
|
||||
#1. Use the value if already set from lv_conf.h or anything else (i.e. do nothing)
|
||||
#2. In Kconfig environment use the CONFIG_... value if set, else use 0
|
||||
#3. In not Kconfig environment use the LVGL's default value
|
||||
|
||||
fout.write(
|
||||
f'{indent}#ifndef {name}\n'
|
||||
f'{indent} #ifdef LV_KCONFIG_PRESENT\n'
|
||||
f'{indent} #ifdef CONFIG_{name.upper()}\n'
|
||||
f'{indent} #define {name} CONFIG_{name.upper()}\n'
|
||||
f'{indent} #else\n'
|
||||
f'{indent} #define {name} 0\n'
|
||||
f'{indent} #endif\n'
|
||||
f'{indent} #else\n'
|
||||
f'{indent} {line}\n'
|
||||
f'{indent} #endif\n'
|
||||
f'{indent}#endif\n'
|
||||
)
|
||||
else:
|
||||
#1. Use the value if already set from lv_conf.h or anything else (i.e. do nothing)
|
||||
#2. Use the Kconfig value if set
|
||||
#3. Use the LVGL's default value
|
||||
|
||||
fout.write(
|
||||
f'{indent}#ifndef {name}\n'
|
||||
f'{indent} #ifdef CONFIG_{name.upper()}\n'
|
||||
f'{indent} #define {name} CONFIG_{name.upper()}\n'
|
||||
f'{indent} #else\n'
|
||||
f'{indent} {line}\n'
|
||||
f'{indent} #endif\n'
|
||||
f'{indent}#endif\n'
|
||||
)
|
||||
|
||||
elif re.search('^ *typedef .*;.*$', line):
|
||||
continue #ignore typedefs to avoid redeclaration
|
||||
else:
|
||||
fout.write(f'{line}\n')
|
||||
|
||||
fout.write(
|
||||
r'''
|
||||
|
||||
/*----------------------------------
|
||||
* End of parsing lv_conf_template.h
|
||||
-----------------------------------*/
|
||||
|
||||
/*Fix inconsistent name*/
|
||||
#define LV_USE_ANIMIMAGE LV_USE_ANIMIMG
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
LV_EXPORT_CONST_INT(LV_DPI_DEF);
|
||||
LV_EXPORT_CONST_INT(LV_DRAW_BUF_STRIDE_ALIGN);
|
||||
LV_EXPORT_CONST_INT(LV_DRAW_BUF_ALIGN);
|
||||
#endif
|
||||
|
||||
#undef LV_KCONFIG_PRESENT
|
||||
|
||||
/* Set some defines if a dependency is disabled. */
|
||||
#if LV_USE_LOG == 0
|
||||
#define LV_LOG_LEVEL LV_LOG_LEVEL_NONE
|
||||
#define LV_LOG_TRACE_MEM 0
|
||||
#define LV_LOG_TRACE_TIMER 0
|
||||
#define LV_LOG_TRACE_INDEV 0
|
||||
#define LV_LOG_TRACE_DISP_REFR 0
|
||||
#define LV_LOG_TRACE_EVENT 0
|
||||
#define LV_LOG_TRACE_OBJ_CREATE 0
|
||||
#define LV_LOG_TRACE_LAYOUT 0
|
||||
#define LV_LOG_TRACE_ANIM 0
|
||||
#endif /*LV_USE_LOG*/
|
||||
|
||||
#if LV_USE_WAYLAND == 0
|
||||
#define LV_WAYLAND_USE_DMABUF 0
|
||||
#define LV_WAYLAND_WINDOW_DECORATIONS 0
|
||||
#define LV_WAYLAND_WL_SHELL 0
|
||||
#endif /* LV_USE_WAYLAND */
|
||||
|
||||
#if LV_USE_SYSMON == 0
|
||||
#define LV_USE_PERF_MONITOR 0
|
||||
#define LV_USE_MEM_MONITOR 0
|
||||
#endif /*LV_USE_SYSMON*/
|
||||
|
||||
#if LV_USE_PERF_MONITOR == 0
|
||||
#define LV_USE_PERF_MONITOR_LOG_MODE 0
|
||||
#endif /*LV_USE_PERF_MONITOR*/
|
||||
|
||||
#if LV_BUILD_DEMOS == 0
|
||||
#define LV_USE_DEMO_WIDGETS 0
|
||||
#define LV_USE_DEMO_KEYPAD_AND_ENCODER 0
|
||||
#define LV_USE_DEMO_BENCHMARK 0
|
||||
#define LV_USE_DEMO_RENDER 0
|
||||
#define LV_USE_DEMO_STRESS 0
|
||||
#define LV_USE_DEMO_MUSIC 0
|
||||
#define LV_USE_DEMO_VECTOR_GRAPHIC 0
|
||||
#define LV_USE_DEMO_FLEX_LAYOUT 0
|
||||
#define LV_USE_DEMO_MULTILANG 0
|
||||
#define LV_USE_DEMO_TRANSFORM 0
|
||||
#define LV_USE_DEMO_SCROLL 0
|
||||
#define LV_USE_DEMO_EBIKE 0
|
||||
#define LV_USE_DEMO_HIGH_RES 0
|
||||
#define LV_USE_DEMO_SMARTWATCH 0
|
||||
#endif /* LV_BUILD_DEMOS */
|
||||
|
||||
#ifndef LV_USE_LZ4
|
||||
#if (LV_USE_LZ4_INTERNAL || LV_USE_LZ4_EXTERNAL)
|
||||
#define LV_USE_LZ4 1
|
||||
#else
|
||||
#define LV_USE_LZ4 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef LV_USE_THORVG
|
||||
#if (LV_USE_THORVG_INTERNAL || LV_USE_THORVG_EXTERNAL)
|
||||
#define LV_USE_THORVG 1
|
||||
#else
|
||||
#define LV_USE_THORVG 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if LV_USE_OS
|
||||
#if (LV_USE_FREETYPE || LV_USE_THORVG) && LV_DRAW_THREAD_STACK_SIZE < (32 * 1024)
|
||||
#warning "Increase LV_DRAW_THREAD_STACK_SIZE to at least 32KB for FreeType or ThorVG."
|
||||
#endif
|
||||
|
||||
#if defined(LV_DRAW_THREAD_STACKSIZE) && !defined(LV_DRAW_THREAD_STACK_SIZE)
|
||||
#warning "LV_DRAW_THREAD_STACKSIZE was renamed to LV_DRAW_THREAD_STACK_SIZE. Please update lv_conf.h or run menuconfig again."
|
||||
#define LV_DRAW_THREAD_STACK_SIZE LV_DRAW_THREAD_STACKSIZE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*Allow only upper case letters and '/' ('/' is a special case for backward compatibility)*/
|
||||
#define LV_FS_IS_VALID_LETTER(l) ((l) == '/' || ((l) >= 'A' && (l) <= 'Z'))
|
||||
|
||||
/* If running without lv_conf.h, add typedefs with default value. */
|
||||
#ifdef LV_CONF_SKIP
|
||||
#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS) /*Disable warnings for Visual Studio*/
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
#endif /*defined(LV_CONF_SKIP)*/
|
||||
|
||||
#endif /*LV_CONF_INTERNAL_H*/
|
||||
'''
|
||||
)
|
||||
|
||||
fin.close()
|
||||
fout.close()
|
||||
@@ -0,0 +1,192 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
#
|
||||
# Preprocess the lv_conf_internal.h to generate a header file
|
||||
# containing the evaluated definitions. This output will be used to
|
||||
# generate the cmake variables
|
||||
#
|
||||
# Author: David TRUAN (david.truan@edgemtech.ch)
|
||||
# Author: Erik Tagirov (erik.tagirov@edgemtech.ch)
|
||||
#
|
||||
|
||||
import sys
|
||||
import subprocess
|
||||
import os
|
||||
import argparse
|
||||
import re
|
||||
import importlib.util
|
||||
|
||||
|
||||
def get_args():
|
||||
parser = argparse.ArgumentParser(description="Preprocess a C header file and remove indentation.")
|
||||
parser.add_argument("--input", help="Path to the input C header file", required=True)
|
||||
parser.add_argument("--tmp_file", help="Path to save the preprocessed output", required=True)
|
||||
parser.add_argument("--output", help="Path to save the cleaned output with removed indentation", required=True)
|
||||
parser.add_argument("--workfolder", help="Path used to create a python environnement", required=True)
|
||||
|
||||
parser.add_argument(
|
||||
"--defs",
|
||||
nargs='+',
|
||||
default=[],
|
||||
help="Definitions to be added to pcpp (flag -D)"
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"--include",
|
||||
nargs='+',
|
||||
default=[],
|
||||
help="Paths to include directories for the preprocessor (flag -I)"
|
||||
)
|
||||
|
||||
|
||||
return parser.parse_args()
|
||||
|
||||
def preprocess_file(pcpp_exe, input_file, tmp_file, output_file, include_dirs, defs):
|
||||
|
||||
try:
|
||||
pcpp_command = [pcpp_exe, "-o", tmp_file, "--passthru-defines", "--line-directive=", input_file]
|
||||
|
||||
for include_path in include_dirs:
|
||||
pcpp_command.append(f"-I{include_path}")
|
||||
|
||||
for definition in defs:
|
||||
pcpp_command.append(f"-D{definition}")
|
||||
|
||||
subprocess.run(pcpp_command, check=True)
|
||||
print(f"Preprocessing completed. Output saved to {tmp_file}")
|
||||
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(f"Error during preprocessing: {e}")
|
||||
exit(1)
|
||||
|
||||
|
||||
# Read the temporary files and return an array of lines
|
||||
def read_lines(tmp_file):
|
||||
|
||||
try:
|
||||
with open(tmp_file, "r") as f:
|
||||
lines = f.readlines()
|
||||
except Exception as e:
|
||||
print(f"Failed to pre-process file: {e}")
|
||||
exit(1)
|
||||
|
||||
return lines
|
||||
|
||||
def remove_indentation(lines):
|
||||
|
||||
clean_lines = []
|
||||
|
||||
try:
|
||||
for line in lines:
|
||||
stripped = line.lstrip()
|
||||
|
||||
# Remove extra spaces after #
|
||||
if stripped.startswith("#"):
|
||||
stripped = re.sub(r"^#\s+", "#", stripped)
|
||||
|
||||
clean_lines.append(stripped)
|
||||
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error during indentation removal: {e}")
|
||||
exit(1)
|
||||
|
||||
return clean_lines
|
||||
|
||||
# This is required - to avoid include errors when Kconfig is used and
|
||||
# LVGL is installed on the system - i.e when lvgl.h is used as a system include
|
||||
def add_include_guards(lines):
|
||||
|
||||
lines.insert(0, "#define LV_CONF_H\n\n")
|
||||
lines.insert(0, "#ifndef LV_CONF_H\n")
|
||||
lines.append("#endif /* END LV_CONF_H */\n")
|
||||
return lines
|
||||
|
||||
def init_venv(venv_path):
|
||||
"""
|
||||
Creates a virtual env named .venv in the `workfolder` directory
|
||||
It is usually set to the path of the build directory.
|
||||
If the .venv already exists it enters the venv
|
||||
Returns the path to the venv
|
||||
"""
|
||||
try:
|
||||
if os.path.exists(venv_path) == False:
|
||||
# Create venv
|
||||
subprocess.check_call([sys.executable, "-m", "venv", venv_path])
|
||||
|
||||
# Enter venv
|
||||
venv_path = os.path.join(venv_path, ".venv")
|
||||
subprocess.check_call([sys.executable, "-m", "venv", venv_path])
|
||||
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(f"Error during the setup of python venv: {e}")
|
||||
exit(1)
|
||||
|
||||
return venv_path
|
||||
|
||||
def install_pcpp_in_venv(venv_path):
|
||||
"""
|
||||
Install pcpp a python implementation of the C pre-processor
|
||||
On success - Returns the path to pcpp, None on failure
|
||||
"""
|
||||
|
||||
if sys.platform == "win32":
|
||||
venv_pip = os.path.join(venv_path, "Scripts", "pip.exe")
|
||||
venv_pcpp = os.path.join(venv_path, "Scripts", "pcpp.exe")
|
||||
else:
|
||||
venv_pip = os.path.join(venv_path, "bin", "pip")
|
||||
venv_pcpp = os.path.join(venv_path, "bin", "pcpp")
|
||||
|
||||
if os.path.exists(venv_pcpp) == False:
|
||||
# Install pcpp
|
||||
try:
|
||||
subprocess.check_call([venv_pip, "install", "pcpp"])
|
||||
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(f"Failed to install PCPP: {e}")
|
||||
return None
|
||||
else:
|
||||
print("PCPP is already installed in venv")
|
||||
|
||||
|
||||
return venv_pcpp
|
||||
|
||||
def main():
|
||||
|
||||
args = get_args()
|
||||
|
||||
# Check if PCPP is already present on the system
|
||||
# if it's not - create a python venv inside the workfolder directory
|
||||
# and install it there
|
||||
res = subprocess.run(["which", "pcpp"], capture_output=True)
|
||||
if res.returncode == 0:
|
||||
pcpp_exe = res.stdout.decode().replace("\n", "")
|
||||
print(f"Found PCPP: {pcpp_exe}")
|
||||
else:
|
||||
print("Failed to locate pcpp - installing it")
|
||||
venv_path = init_venv(args.workfolder)
|
||||
pcpp_exe = install_pcpp_in_venv(venv_path)
|
||||
if pcpp_exe is None:
|
||||
exit(1)
|
||||
|
||||
preprocess_file(pcpp_exe, args.input, args.tmp_file, args.output, args.include, args.defs)
|
||||
|
||||
lines = read_lines(args.tmp_file)
|
||||
lines = remove_indentation(lines)
|
||||
lines = add_include_guards(lines)
|
||||
|
||||
# Write the resulting output header file with include guards and no indentation
|
||||
try:
|
||||
with open(args.output, "w") as f:
|
||||
f.writelines(lines)
|
||||
except Exception as e:
|
||||
print(f"Writing resulting file failed: {e}")
|
||||
exit(1)
|
||||
|
||||
print(f"Expanded configuration header saved to {args.output}")
|
||||
|
||||
os.remove(args.tmp_file)
|
||||
print(f"Temporary preprocessed file {args.tmp_file} removed.")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
37
managed_components/lvgl__lvgl/scripts/prerequisites-apt.txt
Normal file
37
managed_components/lvgl__lvgl/scripts/prerequisites-apt.txt
Normal file
@@ -0,0 +1,37 @@
|
||||
git
|
||||
gcc
|
||||
gcc-multilib
|
||||
g++-multilib
|
||||
ninja-build
|
||||
libpng-dev
|
||||
libjpeg-turbo8-dev
|
||||
libfreetype6-dev
|
||||
libglew-dev
|
||||
libglfw3-dev
|
||||
libsdl2-dev
|
||||
libpng-dev:i386
|
||||
libjpeg-dev:i386
|
||||
libfreetype6-dev:i386
|
||||
ruby-full
|
||||
gcovr
|
||||
cmake
|
||||
python3
|
||||
python3-pip
|
||||
libinput-dev
|
||||
libxkbcommon-dev
|
||||
libdrm-dev
|
||||
pkg-config
|
||||
wayland-protocols
|
||||
libwayland-dev
|
||||
libwayland-bin
|
||||
libwayland-dev:i386
|
||||
libxkbcommon-dev:i386
|
||||
libudev-dev
|
||||
libavformat-dev
|
||||
libavcodec-dev
|
||||
libswscale-dev
|
||||
libavutil-dev
|
||||
libavformat-dev:i386
|
||||
libavcodec-dev:i386
|
||||
libswscale-dev:i386
|
||||
libavutil-dev:i386
|
||||
@@ -0,0 +1,3 @@
|
||||
pypng
|
||||
lz4
|
||||
kconfiglib
|
||||
217
managed_components/lvgl__lvgl/scripts/properties.py
Normal file
217
managed_components/lvgl__lvgl/scripts/properties.py
Normal file
@@ -0,0 +1,217 @@
|
||||
#!/usr/bin/env python3
|
||||
import os
|
||||
import re
|
||||
import argparse
|
||||
from collections import defaultdict
|
||||
|
||||
|
||||
style_properties_type = {
|
||||
"LV_STYLE_BG_COLOR": "LV_PROPERTY_TYPE_COLOR",
|
||||
"LV_STYLE_BG_GRAD_COLOR": "LV_PROPERTY_TYPE_COLOR",
|
||||
"LV_STYLE_BG_IMAGE_SRC": "LV_PROPERTY_TYPE_IMGSRC",
|
||||
"LV_STYLE_BG_IMAGE_RECOLOR": "LV_PROPERTY_TYPE_COLOR",
|
||||
"LV_STYLE_BORDER_COLOR": "LV_PROPERTY_TYPE_COLOR",
|
||||
"LV_STYLE_OUTLINE_COLOR": "LV_PROPERTY_TYPE_COLOR",
|
||||
"LV_STYLE_SHADOW_COLOR": "LV_PROPERTY_TYPE_COLOR",
|
||||
"LV_STYLE_IMAGE_RECOLOR": "LV_PROPERTY_TYPE_COLOR",
|
||||
"LV_STYLE_ARCH_IMAGE_SRC": "LV_PROPERTY_TYPE_IMGSRC",
|
||||
"LV_STYLE_ARCH_COLOR": "LV_PROPERTY_TYPE_COLOR",
|
||||
"LV_STYLE_TEXT_COLOR": "LV_PROPERTY_TYPE_COLOR",
|
||||
"LV_STYLE_TEXT_FONT": "LV_PROPERTY_TYPE_FONT",
|
||||
"LV_STYLE_LINE_COLOR": "LV_PROPERTY_TYPE_COLOR",
|
||||
}
|
||||
|
||||
|
||||
class Property:
|
||||
def __init__(self, widget, name, type, index, id):
|
||||
self.widget = widget
|
||||
self.name = name
|
||||
self.type = type
|
||||
self.index = index
|
||||
self.id = id
|
||||
|
||||
|
||||
def find_headers(directory):
|
||||
if os.path.isfile(directory):
|
||||
yield directory
|
||||
return
|
||||
|
||||
for root, dirs, files in os.walk(directory):
|
||||
for file in files:
|
||||
if file.endswith('.h'):
|
||||
yield os.path.join(root, file)
|
||||
|
||||
|
||||
def read_widget_properties(directory):
|
||||
|
||||
def match_properties(file_path):
|
||||
pattern = r'^\s*LV_PROPERTY_ID2?\((\w+),\s*(\w+),\s*(\w+)(,\s*(\w+))?,\s*(\d+)\)'
|
||||
with open(file_path, 'r') as file:
|
||||
for line in file.readlines():
|
||||
match = re.match(pattern, line)
|
||||
if match:
|
||||
id = f"LV_PROPERTY_{match.group(1).upper()}_{match.group(2).upper()}"
|
||||
yield Property(
|
||||
match.group(1).lower(),
|
||||
match.group(2).lower(), match.group(3), match.group(4),
|
||||
id)
|
||||
|
||||
def match_styles(file_path):
|
||||
pattern = r'^\s+LV_STYLE_(\w+)\s*=\s*(\d+),'
|
||||
with open(file_path, 'r') as file:
|
||||
for line in file.readlines():
|
||||
match = re.match(pattern, line)
|
||||
if match:
|
||||
name = match.group(1).upper()
|
||||
id = f"LV_PROPERTY_STYLE_{name}"
|
||||
yield Property("style",
|
||||
match.group(1).lower(), "style",
|
||||
match.group(2), id)
|
||||
|
||||
properties_by_widget = defaultdict(list)
|
||||
for file_path in find_headers(directory):
|
||||
for property in match_properties(file_path):
|
||||
properties_by_widget[property.widget].append(property)
|
||||
|
||||
for property in match_styles(file_path):
|
||||
properties_by_widget[property.widget].append(property)
|
||||
|
||||
for widget, properties in properties_by_widget.items():
|
||||
# sort properties by property name
|
||||
properties.sort(key=lambda x: x.name)
|
||||
properties_by_widget[widget] = properties
|
||||
|
||||
return properties_by_widget
|
||||
|
||||
|
||||
def write_widget_properties(output, properties_by_widget):
|
||||
# Open header file for update.
|
||||
with open(f'{output}/lv_obj_property_names.h', "w") as header:
|
||||
header.write(f'''
|
||||
/**
|
||||
* @file lv_obj_property_names.h
|
||||
* GENERATED FILE, DO NOT EDIT IT!
|
||||
*/
|
||||
#ifndef LV_OBJ_PROPERTY_NAMES_H
|
||||
#define LV_OBJ_PROPERTY_NAMES_H
|
||||
|
||||
#include "../../misc/lv_types.h"
|
||||
|
||||
#if LV_USE_OBJ_PROPERTY && LV_USE_OBJ_PROPERTY_NAME
|
||||
|
||||
''')
|
||||
|
||||
for widget in sorted(properties_by_widget.keys()):
|
||||
properties = properties_by_widget[widget]
|
||||
file_name = f'lv_{widget}_properties.c'
|
||||
output_file = f'{output}/{file_name}'
|
||||
|
||||
count = len(properties)
|
||||
if widget == 'style':
|
||||
include = "lv_style_properties.h"
|
||||
guard = None
|
||||
elif widget == "obj":
|
||||
include = "../../core/lv_obj.h"
|
||||
guard = None
|
||||
else:
|
||||
include = f'../{widget}/lv_{widget}.h'
|
||||
guard = f"#if LV_USE_{widget.upper()}"
|
||||
|
||||
with open(output_file, 'w') as f:
|
||||
f.write(f'''
|
||||
/**
|
||||
* GENERATED FILE, DO NOT EDIT IT!
|
||||
* @file {file_name}
|
||||
*/
|
||||
|
||||
#include "{include}"
|
||||
|
||||
#if LV_USE_OBJ_PROPERTY && LV_USE_OBJ_PROPERTY_NAME
|
||||
|
||||
{guard if guard else ""}
|
||||
/**
|
||||
* {widget.capitalize() + ' widget' if widget != 'style' else 'Style'} property names, name must be in order.
|
||||
* Generated code from properties.py
|
||||
*/
|
||||
/* *INDENT-OFF* */
|
||||
const lv_property_name_t lv_{widget}_property_names[{count}] = {{
|
||||
''')
|
||||
|
||||
for property in properties:
|
||||
name = property.name
|
||||
name_str = '"' + name + '",'
|
||||
f.write(f" {{{name_str :25} {property.id},}},\n")
|
||||
|
||||
f.write('};\n')
|
||||
if guard:
|
||||
f.write(f"#endif /*LV_USE_{widget.upper()}*/\n\n")
|
||||
f.write("/* *INDENT-ON* */\n")
|
||||
f.write('#endif\n')
|
||||
header.write(
|
||||
f' extern const lv_property_name_t lv_{widget}_property_names[{count}];\n'
|
||||
)
|
||||
header.write('#endif\n')
|
||||
header.write('#endif\n')
|
||||
|
||||
|
||||
def write_style_header(output, properties_by_widget):
|
||||
properties = properties_by_widget['style']
|
||||
|
||||
output_file = f'{output}/lv_style_properties.h'
|
||||
|
||||
with open(output_file, 'w') as f:
|
||||
f.write(f'''
|
||||
/**
|
||||
* GENERATED FILE, DO NOT EDIT IT!
|
||||
* @file lv_style_properties.h
|
||||
*/
|
||||
#ifndef LV_STYLE_PROPERTIES_H
|
||||
#define LV_STYLE_PROPERTIES_H
|
||||
|
||||
#include "../../core/lv_obj_property.h"
|
||||
#if LV_USE_OBJ_PROPERTY
|
||||
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
enum {{
|
||||
''')
|
||||
|
||||
for property in properties:
|
||||
name = property.name
|
||||
id_type = style_properties_type.get(f"LV_STYLE_{name.upper()}",
|
||||
"LV_PROPERTY_TYPE_INT")
|
||||
f.write(
|
||||
f" LV_PROPERTY_ID(STYLE, {name.upper() + ',' :25} {id_type+',' :28} LV_STYLE_{name.upper()}),\n"
|
||||
)
|
||||
|
||||
f.write('};\n\n')
|
||||
f.write('#endif\n')
|
||||
f.write('#endif\n')
|
||||
|
||||
|
||||
def main(directory, output):
|
||||
property = read_widget_properties(directory)
|
||||
write_widget_properties(output, property)
|
||||
write_style_header(output, property)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(
|
||||
description='Search files and filter lines.')
|
||||
parser.add_argument('-d', '--directory',
|
||||
help='Directory to lvgl root path')
|
||||
parser.add_argument(
|
||||
'-o', '--output', help='Folders to write generated properties for all widgets.')
|
||||
args = parser.parse_args()
|
||||
|
||||
# default directory is the lvgl root path of where this script sits
|
||||
if args.directory is None:
|
||||
args.directory = os.path.join(os.path.dirname(__file__), "../")
|
||||
|
||||
if args.output is None:
|
||||
args.output = os.path.join(args.directory, "src/widgets/property/")
|
||||
|
||||
# create output directory if it doesn't exist
|
||||
os.makedirs(args.output, exist_ok=True)
|
||||
|
||||
main(args.directory, args.output)
|
||||
260
managed_components/lvgl__lvgl/scripts/release_branch_updater.py
Normal file
260
managed_components/lvgl__lvgl/scripts/release_branch_updater.py
Normal file
@@ -0,0 +1,260 @@
|
||||
import subprocess
|
||||
import re
|
||||
import argparse
|
||||
import os
|
||||
import shutil
|
||||
import sys
|
||||
|
||||
# v10.0.0 -> fail if release/v10.0 is not there
|
||||
# v10.0.1 -> update release/v10.0
|
||||
# v10.1.0 -> create release/v10.1 from release/v10.0 and update it
|
||||
# v10.1.1 -> update release/v10.1
|
||||
|
||||
LOG = "[release_branch_updater.py]"
|
||||
|
||||
def git_repository(repository: str, token: str):
|
||||
if not token:
|
||||
return f"https://{repository}"
|
||||
return f"https://{token}@{repository}"
|
||||
|
||||
def main():
|
||||
|
||||
arg_parser = argparse.ArgumentParser()
|
||||
arg_parser.add_argument("--port-clone-tmpdir", default="port_tmpdir")
|
||||
arg_parser.add_argument("--port-urls-path", default=os.path.join(os.path.dirname(__file__), "release_branch_updater_port_urls.txt"))
|
||||
arg_parser.add_argument("--lvgl-path", default=os.path.join(os.path.dirname(__file__), ".."))
|
||||
arg_parser.add_argument("--dry-run", action="store_true")
|
||||
arg_parser.add_argument("--oldest-major", type=int)
|
||||
arg_parser.add_argument("--github-token", type=str)
|
||||
arg_parser.add_argument("--skip-master", action="store_true")
|
||||
|
||||
args = arg_parser.parse_args()
|
||||
|
||||
port_clone_tmpdir = args.port_clone_tmpdir
|
||||
port_urls_path = args.port_urls_path
|
||||
lvgl_path = args.lvgl_path
|
||||
dry_run = args.dry_run
|
||||
oldest_major = args.oldest_major
|
||||
skip_master = args.skip_master
|
||||
|
||||
if not args.github_token and not dry_run:
|
||||
print(LOG, "Warning: No github token was provided for this production run. Continuing anyway...")
|
||||
|
||||
lvgl_release_branches, lvgl_default_branch = get_release_branches(lvgl_path)
|
||||
print(LOG, "LVGL release branches:", ", ".join(fmt_release(br) for br in lvgl_release_branches) or "(none)")
|
||||
assert lvgl_default_branch is not None
|
||||
print(LOG, "LVGL default branch:", lvgl_default_branch)
|
||||
if oldest_major is not None:
|
||||
lvgl_release_branches = [br for br in lvgl_release_branches if br[0] >= oldest_major]
|
||||
print(LOG, 'LVGL release branches after "oldest-major" filter:',
|
||||
", ".join(fmt_release(br) for br in lvgl_release_branches) or "(none)")
|
||||
|
||||
with open(port_urls_path) as f:
|
||||
urls = f.read()
|
||||
urls = [url for url in map(str.strip, urls.splitlines()) if url]
|
||||
|
||||
# ensure this script creates the directory i.e. it doesn't belong to the user since it will rm -rf at the end
|
||||
assert not os.path.exists(port_clone_tmpdir), "the port clone tmpdir should not exist yet"
|
||||
|
||||
for url in urls:
|
||||
print(LOG, "working with port:", url)
|
||||
|
||||
if dry_run:
|
||||
port_clone_tmpdir = url[len("https://github.com/lvgl/"): ]
|
||||
print("port_clone_tmpdir: " + port_clone_tmpdir)
|
||||
|
||||
# It's very important to not leak the github_token here
|
||||
# So make sure the stdout and stderr are piped here
|
||||
subprocess.run(("git", "clone",
|
||||
git_repository(url.replace("https://", ""), args.github_token),
|
||||
port_clone_tmpdir),
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE)
|
||||
|
||||
port_release_branches, port_default_branch = get_release_branches(port_clone_tmpdir)
|
||||
print(LOG, "port release branches:", ", ".join(fmt_release(br) for br in port_release_branches) or "(none)")
|
||||
print(LOG, "port default branch:", port_default_branch if port_default_branch is not None else "(none)")
|
||||
|
||||
# we want to
|
||||
# 1. create (if necessary) the port's release branch
|
||||
# 2. update the LVGL submodule to match the LVGL's release branch version
|
||||
# 3. update the lv_conf.h based on the lv_conf.defaults
|
||||
|
||||
branches_to_update = lvgl_release_branches
|
||||
if not skip_master:
|
||||
branches_to_update += [lvgl_default_branch]
|
||||
|
||||
# from oldest to newest release...
|
||||
for lvgl_branch in branches_to_update:
|
||||
if isinstance(lvgl_branch, tuple):
|
||||
port_branch = lvgl_branch
|
||||
print(LOG, f"attempting to update release branch {fmt_release(port_branch)} ...")
|
||||
else:
|
||||
port_branch = port_default_branch
|
||||
if port_branch is None:
|
||||
print(LOG, "the port does not have a default branch to update. continuing to next.")
|
||||
continue
|
||||
print(LOG, f"attempting to update default branch {port_branch} ...")
|
||||
|
||||
port_does_not_have_the_branch = False
|
||||
port_submodule_was_updated = False
|
||||
port_lv_conf_h_was_updated = False
|
||||
|
||||
# if the branch does not exist in the port, create it from
|
||||
# the closest minor of the same major.
|
||||
if port_branch in port_release_branches:
|
||||
print(LOG, "... this port has a matching release branch.")
|
||||
subprocess.run(("git", "-C", port_clone_tmpdir, "branch", "--track",
|
||||
fmt_release(port_branch),
|
||||
f"origin/{fmt_release(port_branch)}"))
|
||||
elif port_branch != port_default_branch:
|
||||
print(LOG, "... this port does not have this release branch minor ...")
|
||||
port_does_not_have_the_branch = True
|
||||
|
||||
# get the port branch with this major and the next smallest minor
|
||||
create_from = next((
|
||||
br
|
||||
for br in reversed(port_release_branches) # reverse it to get the newest (largest) minor
|
||||
if br[0] == port_branch[0] # same major
|
||||
and br[1] < port_branch[1] # smaller minor because exact minor does not exist
|
||||
), None)
|
||||
if create_from is None:
|
||||
# there are no branches in the port that are this major
|
||||
# version. One must be created manually.
|
||||
print(LOG, "... this port has no major from which to create the minor. one must be created manually. continuing to next.")
|
||||
continue
|
||||
|
||||
print(LOG, f"... creating the new branch {fmt_release(port_branch)} "
|
||||
f"from {fmt_release(create_from)}")
|
||||
res = subprocess.run(("git", "-C", port_clone_tmpdir, "branch",
|
||||
fmt_release(port_branch), # new branch name
|
||||
fmt_release(create_from))) # start point
|
||||
|
||||
if res.returncode != 0: continue
|
||||
|
||||
port_release_branches.append(port_branch)
|
||||
port_release_branches.sort()
|
||||
|
||||
# checkout the same release in both LVGL and the port
|
||||
subprocess.check_call(("git", "-C", lvgl_path, "checkout", f"origin/{fmt_release(lvgl_branch)}"))
|
||||
subprocess.check_call(("git", "-C", port_clone_tmpdir, "checkout", fmt_release(port_branch)))
|
||||
|
||||
# update the submodule in the port if it exists
|
||||
port_lvgl_submodule_path = None
|
||||
if os.path.exists(os.path.join(port_clone_tmpdir, ".gitmodules")):
|
||||
out = subprocess.check_output(("git", "-C", port_clone_tmpdir, "config", "--file",
|
||||
".gitmodules", "--get-regexp", "path"))
|
||||
port_lvgl_submodule_path = next((
|
||||
line.partition("lvgl.path ")[2]
|
||||
for line
|
||||
in out.decode().strip().splitlines()
|
||||
if "lvgl.path " in line
|
||||
), None)
|
||||
|
||||
if port_lvgl_submodule_path is None:
|
||||
print(LOG, "this port has no LVGL submodule")
|
||||
else:
|
||||
print(LOG, "lvgl submodule found in port at:", port_lvgl_submodule_path)
|
||||
|
||||
# get the SHA of LVGL in this release of LVGL
|
||||
out = subprocess.check_output(("git", "-C", lvgl_path, "rev-parse", "--verify", "--quiet", "HEAD"))
|
||||
lvgl_sha = out.decode().strip()
|
||||
print(LOG, "the SHA of LVGL in this release should be:", lvgl_sha)
|
||||
|
||||
# get the SHA of LVGL this port wants to use in this release
|
||||
out = subprocess.check_output(("git", "-C", port_clone_tmpdir, "rev-parse",
|
||||
"--verify", "--quiet", f"HEAD:{port_lvgl_submodule_path}"))
|
||||
port_lvgl_submodule_sha = out.decode().strip()
|
||||
print(LOG, "the SHA of LVGL in the submodule of this port is:", port_lvgl_submodule_sha)
|
||||
|
||||
if lvgl_sha == port_lvgl_submodule_sha:
|
||||
print(LOG, "the submodule's version of LVGL is already up to date")
|
||||
else:
|
||||
print(LOG, "the submodule's version of LVGL is NOT up to date")
|
||||
port_submodule_was_updated = True
|
||||
|
||||
# update the version of the submodule in the index. no need to `git submodule update --init` it.
|
||||
# also no need to `git add .` afterwards because it stages the change.
|
||||
# 160000 is a git file mode which means submodule.
|
||||
subprocess.check_call(("git", "-C", port_clone_tmpdir, "update-index", "--cacheinfo",
|
||||
f"160000,{lvgl_sha},{port_lvgl_submodule_path}"))
|
||||
|
||||
# update the lv_conf.h if there's an lv_conf.defaults
|
||||
out = subprocess.check_output(("find", ".", "-name", "lv_conf.defaults", "-print", "-quit"), cwd=port_clone_tmpdir)
|
||||
port_lv_conf_defaults = next(iter(out.decode().strip().splitlines()), None)
|
||||
if port_lv_conf_defaults is None:
|
||||
print(LOG, "this port has no lv_conf.defaults")
|
||||
else:
|
||||
out = subprocess.check_output(("find", ".", "-name", "lv_conf.h", "-print", "-quit"), cwd=port_clone_tmpdir)
|
||||
port_lv_conf_h = next(iter(out.decode().strip().splitlines()), None)
|
||||
if port_lv_conf_h is None:
|
||||
print(LOG, "this port has an lv_conf.defaults but no lv_conf.h")
|
||||
else:
|
||||
subprocess.check_call((sys.executable, os.path.join(lvgl_path, "scripts/generate_lv_conf.py"),
|
||||
"--defaults", os.path.abspath(os.path.join(port_clone_tmpdir, port_lv_conf_defaults)),
|
||||
"--config", os.path.abspath(os.path.join(port_clone_tmpdir, port_lv_conf_h)), ))
|
||||
|
||||
# check if lv_conf.h actually changed. it will not detect the submodule change as a false positive.
|
||||
out = subprocess.check_output(("git", "-C", port_clone_tmpdir, "diff"))
|
||||
diff = out.decode().strip()
|
||||
if not diff:
|
||||
print(LOG, "this port's lv_conf.h did NOT change")
|
||||
else:
|
||||
print(LOG, "this port's lv_conf.h changed")
|
||||
port_lv_conf_h_was_updated = True
|
||||
subprocess.check_call(("git", "-C", port_clone_tmpdir, "add", port_lv_conf_h))
|
||||
out = subprocess.check_output(("git", "-C", port_clone_tmpdir, "diff"))
|
||||
diff = out.decode().strip()
|
||||
assert not diff
|
||||
|
||||
if port_does_not_have_the_branch or port_submodule_was_updated or port_lv_conf_h_was_updated:
|
||||
print(LOG, "changes were made. ready to push.")
|
||||
# keep it brief for commit message 50 character limit suggestion.
|
||||
# max length will be 50 characters in this case: "bot: New branch. Update LVGL submodule. lv_conf.h."
|
||||
commit_msg = ("bot:"
|
||||
+ (" New branch." if port_does_not_have_the_branch else "")
|
||||
+ (" Update LVGL submodule." if port_submodule_was_updated else "")
|
||||
+ (" lv_conf.h." if port_lv_conf_h_was_updated else "")
|
||||
)
|
||||
print(LOG, f"commit message: '{commit_msg}'")
|
||||
subprocess.check_call(("git", "-C", port_clone_tmpdir, "commit", "--allow-empty", "-m", commit_msg))
|
||||
if dry_run:
|
||||
print(LOG, "this is a dry run so nothing will be pushed")
|
||||
else:
|
||||
subprocess.check_call(("git", "-C", port_clone_tmpdir, "push", "origin", fmt_release(port_branch)))
|
||||
print(LOG, "the changes were pushed.")
|
||||
else:
|
||||
print(LOG, "nothing to push for this release. it is up to date.")
|
||||
|
||||
if not dry_run:
|
||||
shutil.rmtree(port_clone_tmpdir)
|
||||
|
||||
print(LOG, "port update complete:", url)
|
||||
|
||||
def get_release_branches(working_dir):
|
||||
|
||||
out = subprocess.check_output(("git", "-C", working_dir, "branch", "--quiet", "--format", "%(refname)", "--all"))
|
||||
branches = out.decode().strip().splitlines()
|
||||
|
||||
release_versions = []
|
||||
for branch_name in branches:
|
||||
release_branch = re.fullmatch(r"refs/remotes/origin/release/v([0-9]+)\.([0-9]+)", branch_name)
|
||||
if release_branch is None:
|
||||
continue
|
||||
release_versions.append((int(release_branch[1]), int(release_branch[2])))
|
||||
|
||||
release_versions.sort()
|
||||
|
||||
default_branch = None
|
||||
if "refs/remotes/origin/master" in branches:
|
||||
default_branch = "master"
|
||||
elif "refs/remotes/origin/main" in branches:
|
||||
default_branch = "main"
|
||||
|
||||
return release_versions, default_branch
|
||||
|
||||
def fmt_release(release_tuple):
|
||||
return f"release/v{release_tuple[0]}.{release_tuple[1]}" if isinstance(release_tuple, tuple) else release_tuple
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,9 @@
|
||||
https://github.com/lvgl/lv_port_linux
|
||||
https://github.com/lvgl/lv_port_pc_eclipse
|
||||
https://github.com/lvgl/lv_port_pc_vscode
|
||||
https://github.com/lvgl/lv_port_renesas_ek-ra8d1_gcc
|
||||
https://github.com/lvgl/lv_port_riverdi_stm32u5
|
||||
https://github.com/lvgl/lv_nuttx
|
||||
https://github.com/lvgl/lv_zephyr
|
||||
https://github.com/lvgl/lv_esp_idf
|
||||
https://github.com/lvgl/lv_port_actions_technology
|
||||
759
managed_components/lvgl__lvgl/scripts/style_api_gen.py
Normal file
759
managed_components/lvgl__lvgl/scripts/style_api_gen.py
Normal file
@@ -0,0 +1,759 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
|
||||
props = [
|
||||
{'section': 'Size and position', 'dsc':'Properties related to size, position, alignment and layout of Widgets.' },
|
||||
{'name': 'WIDTH',
|
||||
'style_type': 'num', 'var_type': 'int32_t' , 'default':'Widget dependent', 'inherited': 0, 'layout': 1, 'ext_draw': 0,
|
||||
'dsc': "Sets width of Widget. Pixel, percentage and `LV_SIZE_CONTENT` values can be used. Percentage values are relative to the width of the parent's content area."},
|
||||
|
||||
{'name': 'MIN_WIDTH',
|
||||
'style_type': 'num', 'var_type': 'int32_t' , 'default':0, 'inherited': 0, 'layout': 1, 'ext_draw': 0,
|
||||
'dsc': "Sets a minimal width. Pixel and percentage values can be used. Percentage values are relative to the width of the parent's content area."},
|
||||
|
||||
{'name': 'MAX_WIDTH',
|
||||
'style_type': 'num', 'var_type': 'int32_t' , 'default':'LV_COORD_MAX', 'inherited': 0, 'layout': 1, 'ext_draw': 0,
|
||||
'dsc': "Sets a maximal width. Pixel and percentage values can be used. Percentage values are relative to the width of the parent's content area."},
|
||||
|
||||
{'name': 'HEIGHT',
|
||||
'style_type': 'num', 'var_type': 'int32_t' , 'default':'Widget dependent', 'inherited': 0, 'layout': 1, 'ext_draw': 0,
|
||||
'dsc': "Sets height of Widget. Pixel, percentage and `LV_SIZE_CONTENT` can be used. Percentage values are relative to the height of the parent's content area."},
|
||||
|
||||
{'name': 'MIN_HEIGHT',
|
||||
'style_type': 'num', 'var_type': 'int32_t' , 'default':0, 'inherited': 0, 'layout': 1, 'ext_draw': 0,
|
||||
'dsc': "Sets a minimal height. Pixel and percentage values can be used. Percentage values are relative to the width of the parent's content area."},
|
||||
|
||||
{'name': 'MAX_HEIGHT',
|
||||
'style_type': 'num', 'var_type': 'int32_t' , 'default':'LV_COORD_MAX', 'inherited': 0, 'layout': 1, 'ext_draw': 0,
|
||||
'dsc': "Sets a maximal height. Pixel and percentage values can be used. Percentage values are relative to the height of the parent's content area."},
|
||||
|
||||
{'name': 'LENGTH',
|
||||
'style_type': 'num', 'var_type': 'int32_t' , 'default':'0', 'inherited': 0, 'layout': 0, 'ext_draw': 1,
|
||||
'dsc': "Its meaning depends on the type of Widget. For example in case of lv_scale it means the length of the ticks."},
|
||||
|
||||
{'name': 'X',
|
||||
'style_type': 'num', 'var_type': 'int32_t' , 'default':0, 'inherited': 0, 'layout': 1, 'ext_draw': 0,
|
||||
'dsc': "Set X coordinate of Widget considering the ``align`` setting. Pixel and percentage values can be used. Percentage values are relative to the width of the parent's content area."},
|
||||
|
||||
{'name': 'Y',
|
||||
'style_type': 'num', 'var_type': 'int32_t', 'default':0, 'inherited': 0, 'layout': 1, 'ext_draw': 0,
|
||||
'dsc': "Set Y coordinate of Widget considering the ``align`` setting. Pixel and percentage values can be used. Percentage values are relative to the height of the parent's content area."},
|
||||
|
||||
{'name': 'ALIGN',
|
||||
'style_type': 'num', 'var_type': 'lv_align_t', 'default':'`LV_ALIGN_DEFAULT`', 'inherited': 0, 'layout': 1, 'ext_draw': 0,
|
||||
'dsc': "Set the alignment which tells from which point of the parent the X and Y coordinates should be interpreted. Possible values are: `LV_ALIGN_DEFAULT`, `LV_ALIGN_TOP_LEFT/MID/RIGHT`, `LV_ALIGN_BOTTOM_LEFT/MID/RIGHT`, `LV_ALIGN_LEFT/RIGHT_MID`, `LV_ALIGN_CENTER`. `LV_ALIGN_DEFAULT` means `LV_ALIGN_TOP_LEFT` with LTR base direction and `LV_ALIGN_TOP_RIGHT` with RTL base direction."},
|
||||
|
||||
{'name': 'TRANSFORM_WIDTH',
|
||||
'style_type': 'num', 'var_type': 'int32_t', 'default':0, 'inherited': 0, 'layout': 0, 'ext_draw': 1,
|
||||
'dsc': "Make Widget wider on both sides with this value. Pixel and percentage (with `lv_pct(x)`) values can be used. Percentage values are relative to Widget's width." },
|
||||
|
||||
{'name': 'TRANSFORM_HEIGHT',
|
||||
'style_type': 'num', 'var_type': 'int32_t', 'default':0, 'inherited': 0, 'layout': 0, 'ext_draw': 1,
|
||||
'dsc': "Make Widget higher on both sides with this value. Pixel and percentage (with `lv_pct(x)`) values can be used. Percentage values are relative to Widget's height." },
|
||||
|
||||
{'name': 'TRANSLATE_X',
|
||||
'style_type': 'num', 'var_type': 'int32_t', 'default':0, 'inherited': 0, 'layout': 1, 'ext_draw': 0,
|
||||
'dsc': "Move Widget with this value in X direction. Applied after layouts, aligns and other positioning. Pixel and percentage (with `lv_pct(x)`) values can be used. Percentage values are relative to Widget's width." },
|
||||
|
||||
{'name': 'TRANSLATE_Y',
|
||||
'style_type': 'num', 'var_type': 'int32_t', 'default':0, 'inherited': 0, 'layout': 1, 'ext_draw': 0,
|
||||
'dsc': "Move Widget with this value in Y direction. Applied after layouts, aligns and other positioning. Pixel and percentage (with `lv_pct(x)`) values can be used. Percentage values are relative to Widget's height." },
|
||||
|
||||
{'name': 'TRANSLATE_RADIAL',
|
||||
'style_type': 'num', 'var_type': 'int32_t' , 'default':0, 'inherited': 0, 'layout': 1, 'ext_draw': 0,
|
||||
'dsc': "Move object around the centre of the parent object (e.g. around the circumference of a scale)"},
|
||||
|
||||
{'name': 'TRANSFORM_SCALE_X',
|
||||
'style_type': 'num', 'var_type': 'int32_t', 'default':0, 'inherited': 0, 'layout': 1, 'ext_draw': 1,
|
||||
'dsc': "Zoom Widget horizontally. The value 256 (or `LV_SCALE_NONE`) means normal size, 128 half size, 512 double size, and so on" },
|
||||
|
||||
{'name': 'TRANSFORM_SCALE_Y',
|
||||
'style_type': 'num', 'var_type': 'int32_t', 'default':0, 'inherited': 0, 'layout': 1, 'ext_draw': 1,
|
||||
'dsc': "Zoom Widget vertically. The value 256 (or `LV_SCALE_NONE`) means normal size, 128 half size, 512 double size, and so on" },
|
||||
|
||||
{'name': 'TRANSFORM_ROTATION',
|
||||
'style_type': 'num', 'var_type': 'int32_t', 'default':0, 'inherited': 0, 'layout': 1, 'ext_draw': 1,
|
||||
'dsc': "Rotate Widget. The value is interpreted in 0.1 degree units. E.g. 450 means 45 deg."},
|
||||
|
||||
{'name': 'TRANSFORM_PIVOT_X',
|
||||
'style_type': 'num', 'var_type': 'int32_t', 'default':0, 'inherited': 0, 'layout': 0, 'ext_draw': 0,
|
||||
'dsc': "Set pivot point's X coordinate for transformations. Relative to Widget's top left corner'"},
|
||||
|
||||
{'name': 'TRANSFORM_PIVOT_Y',
|
||||
'style_type': 'num', 'var_type': 'int32_t', 'default':0, 'inherited': 0, 'layout': 0, 'ext_draw': 0,
|
||||
'dsc': "Set pivot point's Y coordinate for transformations. Relative to Widget's top left corner'"},
|
||||
|
||||
{'name': 'TRANSFORM_SKEW_X',
|
||||
'style_type': 'num', 'var_type': 'int32_t', 'default':0, 'inherited': 0, 'layout': 1, 'ext_draw': 1,
|
||||
'dsc': "Skew Widget horizontally. The value is interpreted in 0.1 degree units. E.g. 450 means 45 deg."},
|
||||
|
||||
{'name': 'TRANSFORM_SKEW_Y',
|
||||
'style_type': 'num', 'var_type': 'int32_t', 'default':0, 'inherited': 0, 'layout': 1, 'ext_draw': 1,
|
||||
'dsc': "Skew Widget vertically. The value is interpreted in 0.1 degree units. E.g. 450 means 45 deg."},
|
||||
|
||||
{'section': 'Padding', 'dsc' : "Properties to describe spacing between the parent's sides and the children and among the children. Very similar to the padding properties in HTML."},
|
||||
{'name': 'PAD_TOP',
|
||||
'style_type': 'num', 'var_type': 'int32_t', 'default':0, 'inherited': 0, 'layout': 1, 'ext_draw': 0,
|
||||
'dsc': "Sets the padding on the top. It makes the content area smaller in this direction."},
|
||||
|
||||
{'name': 'PAD_BOTTOM',
|
||||
'style_type': 'num', 'var_type': 'int32_t', 'default':0, 'inherited': 0, 'layout': 1, 'ext_draw': 0,
|
||||
'dsc': "Sets the padding on the bottom. It makes the content area smaller in this direction."},
|
||||
|
||||
{'name': 'PAD_LEFT',
|
||||
'style_type': 'num', 'var_type': 'int32_t', 'default':0, 'inherited': 0, 'layout': 1, 'ext_draw': 0,
|
||||
'dsc': "Sets the padding on the left. It makes the content area smaller in this direction."},
|
||||
|
||||
{'name': 'PAD_RIGHT',
|
||||
'style_type': 'num', 'var_type': 'int32_t', 'default':0, 'inherited': 0, 'layout': 1, 'ext_draw': 0,
|
||||
'dsc': "Sets the padding on the right. It makes the content area smaller in this direction."},
|
||||
|
||||
{'name': 'PAD_ROW',
|
||||
'style_type': 'num', 'var_type': 'int32_t', 'default':0, 'inherited': 0, 'layout': 1, 'ext_draw': 0,
|
||||
'dsc': "Sets the padding between the rows. Used by the layouts."},
|
||||
|
||||
{'name': 'PAD_COLUMN',
|
||||
'style_type': 'num', 'var_type': 'int32_t', 'default':0, 'inherited': 0, 'layout': 1, 'ext_draw': 0,
|
||||
'dsc': "Sets the padding between the columns. Used by the layouts."},
|
||||
|
||||
{'name': 'PAD_RADIAL',
|
||||
'style_type': 'num', 'var_type': 'int32_t' , 'default':0, 'inherited': 0, 'layout': 0, 'ext_draw': 0,
|
||||
'dsc': "Pad text labels away from the scale ticks/remainder of the ``LV_PART_``"},
|
||||
|
||||
{'section': 'Margin', 'dsc' : "Properties to describe spacing around a Widget. Very similar to the margin properties in HTML."},
|
||||
{'name': 'MARGIN_TOP',
|
||||
'style_type': 'num', 'var_type': 'int32_t', 'default':0, 'inherited': 0, 'layout': 1, 'ext_draw': 0,
|
||||
'dsc': "Sets margin on the top. Widget will keep this space from its siblings in layouts."},
|
||||
|
||||
{'name': 'MARGIN_BOTTOM',
|
||||
'style_type': 'num', 'var_type': 'int32_t', 'default':0, 'inherited': 0, 'layout': 1, 'ext_draw': 0,
|
||||
'dsc': "Sets margin on the bottom. Widget will keep this space from its siblings in layouts."},
|
||||
|
||||
{'name': 'MARGIN_LEFT',
|
||||
'style_type': 'num', 'var_type': 'int32_t', 'default':0, 'inherited': 0, 'layout': 1, 'ext_draw': 0,
|
||||
'dsc': "Sets margin on the left. Widget will keep this space from its siblings in layouts."},
|
||||
|
||||
{'name': 'MARGIN_RIGHT',
|
||||
'style_type': 'num', 'var_type': 'int32_t', 'default':0, 'inherited': 0, 'layout': 1, 'ext_draw': 0,
|
||||
'dsc': "Sets margin on the right. Widget will keep this space from its siblings in layouts."},
|
||||
|
||||
{'section': 'Background', 'dsc':'Properties to describe the background color and image of Widget.' },
|
||||
{'name': 'BG_COLOR',
|
||||
'style_type': 'color', 'var_type': 'lv_color_t', 'default':'`0xffffff`', 'inherited': 0, 'layout': 0, 'ext_draw': 0, 'filtered': 1,
|
||||
'dsc': "Set background color of Widget."},
|
||||
|
||||
{'name': 'BG_OPA',
|
||||
'style_type': 'num', 'var_type': 'lv_opa_t', 'default':'`LV_OPA_TRANSP`', 'inherited': 0, 'layout': 0, 'ext_draw': 0,
|
||||
'dsc': "Set opacity of the background. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 255, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency."},
|
||||
|
||||
{'name': 'BG_GRAD_COLOR',
|
||||
'style_type': 'color', 'var_type': 'lv_color_t', 'default':'`0x000000`', 'inherited': 0, 'layout': 0, 'ext_draw': 0, 'filtered': 1,
|
||||
'dsc': "Set gradient color of the background. Used only if `grad_dir` is not `LV_GRAD_DIR_NONE`"},
|
||||
|
||||
{'name': 'BG_GRAD_DIR',
|
||||
'style_type': 'num', 'var_type': 'lv_grad_dir_t', 'default':'`LV_GRAD_DIR_NONE`', 'inherited': 0, 'layout': 0, 'ext_draw': 0,
|
||||
'dsc': "Set direction of the gradient of the background. Possible values are `LV_GRAD_DIR_NONE/HOR/VER`."},
|
||||
|
||||
{'name': 'BG_MAIN_STOP',
|
||||
'style_type': 'num', 'var_type': 'int32_t', 'default':0, 'inherited': 0, 'layout': 0, 'ext_draw': 0,
|
||||
'dsc': "Set point from which background color should start for gradients. 0 means to top/left side, 255 the bottom/right side, 128 the center, and so on"},
|
||||
|
||||
{'name': 'BG_GRAD_STOP',
|
||||
'style_type': 'num', 'var_type': 'int32_t', 'default':255, 'inherited': 0, 'layout': 0, 'ext_draw': 0,
|
||||
'dsc': "Set point from which background's gradient color should start. 0 means to top/left side, 255 the bottom/right side, 128 the center, and so on"},
|
||||
|
||||
{'name': 'BG_MAIN_OPA',
|
||||
'style_type': 'num', 'var_type': 'lv_opa_t', 'default':255, 'inherited': 0, 'layout': 0, 'ext_draw': 0,
|
||||
'dsc': "Set opacity of the first gradient color"},
|
||||
|
||||
{'name': 'BG_GRAD_OPA',
|
||||
'style_type': 'num', 'var_type': 'lv_opa_t', 'default':255, 'inherited': 0, 'layout': 0, 'ext_draw': 0,
|
||||
'dsc': "Set opacity of the second gradient color"},
|
||||
|
||||
{'name': 'BG_GRAD',
|
||||
'style_type': 'ptr', 'var_type': 'const lv_grad_dsc_t *', 'default':'`NULL`', 'inherited': 0, 'layout': 0, 'ext_draw': 0,
|
||||
'dsc': "Set gradient definition. The pointed instance must exist while Widget is alive. NULL to disable. It wraps `BG_GRAD_COLOR`, `BG_GRAD_DIR`, `BG_MAIN_STOP` and `BG_GRAD_STOP` into one descriptor and allows creating gradients with more colors as well. If it's set other gradient related properties will be ignored'"},
|
||||
|
||||
{'name': 'BG_IMAGE_SRC',
|
||||
'style_type': 'ptr', 'var_type': 'const void *', 'default':'`NULL`', 'inherited': 0, 'layout': 0, 'ext_draw': 1,
|
||||
'dsc': "Set a background image. Can be a pointer to `lv_image_dsc_t`, a path to a file or an `LV_SYMBOL_...`"},
|
||||
|
||||
{'name': 'BG_IMAGE_OPA',
|
||||
'style_type': 'num', 'var_type': 'lv_opa_t', 'default':'`LV_OPA_COVER`', 'inherited': 0, 'layout': 0, 'ext_draw': 0,
|
||||
'dsc': "Set opacity of the background image. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 255, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency."},
|
||||
|
||||
{'name': 'BG_IMAGE_RECOLOR',
|
||||
'style_type': 'color', 'var_type': 'lv_color_t', 'default':'`0x000000`', 'inherited': 0, 'layout': 0, 'ext_draw': 0, 'filtered': 1,
|
||||
'dsc': "Set a color to mix to the background image."},
|
||||
|
||||
{'name': 'BG_IMAGE_RECOLOR_OPA',
|
||||
'style_type': 'num', 'var_type': 'lv_opa_t', 'default':'`LV_OPA_TRANSP`', 'inherited': 0, 'layout': 0, 'ext_draw': 0,
|
||||
'dsc': "Set intensity of background image recoloring. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means no mixing, 255, `LV_OPA_100` or `LV_OPA_COVER` means full recoloring, other values or LV_OPA_10, LV_OPA_20, etc are interpreted proportionally."},
|
||||
|
||||
{'name': 'BG_IMAGE_TILED',
|
||||
'style_type': 'num', 'var_type': 'bool', 'default':0, 'inherited': 0, 'layout': 0, 'ext_draw': 0,
|
||||
'dsc': "If enabled the background image will be tiled. Possible values are `true` or `false`."},
|
||||
|
||||
{'section': 'Border', 'dsc':'Properties to describe the borders' },
|
||||
{'name': 'BORDER_COLOR',
|
||||
'style_type': 'color', 'var_type': 'lv_color_t', 'default':'`0x000000`', 'inherited': 0, 'layout': 0, 'ext_draw': 0, 'filtered': 1,
|
||||
'dsc': "Set color of the border"},
|
||||
|
||||
{'name': 'BORDER_OPA',
|
||||
'style_type': 'num', 'var_type': 'lv_opa_t' , 'default':'`LV_OPA_COVER`', 'inherited': 0, 'layout': 0, 'ext_draw': 0,
|
||||
'dsc': "Set opacity of the border. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 255, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency."},
|
||||
|
||||
{'name': 'BORDER_WIDTH',
|
||||
'style_type': 'num', 'var_type': 'int32_t' , 'default':0, 'inherited': 0, 'layout': 1, 'ext_draw': 0,
|
||||
'dsc': "Set width of the border. Only pixel values can be used."},
|
||||
|
||||
{'name': 'BORDER_SIDE',
|
||||
'style_type': 'num', 'var_type': 'lv_border_side_t', 'default':'`LV_BORDER_SIDE_NONE`', 'inherited': 0, 'layout': 0, 'ext_draw': 0,
|
||||
'dsc': "Set only which side(s) the border should be drawn. Possible values are `LV_BORDER_SIDE_NONE/TOP/BOTTOM/LEFT/RIGHT/INTERNAL`. OR-ed values can be used as well, e.g. `LV_BORDER_SIDE_TOP | LV_BORDER_SIDE_LEFT`."},
|
||||
|
||||
{'name': 'BORDER_POST',
|
||||
'style_type': 'num', 'var_type': 'bool' , 'default':0, 'inherited': 0, 'layout': 0, 'ext_draw': 0,
|
||||
'dsc': "Sets whether the border should be drawn before or after the children are drawn. `true`: after children, `false`: before children"},
|
||||
|
||||
{'section': 'Outline', 'dsc':'Properties to describe the outline. It\'s like a border but drawn outside of the rectangles.' },
|
||||
{'name': 'OUTLINE_WIDTH',
|
||||
'style_type': 'num', 'var_type': 'int32_t' , 'default':0, 'inherited': 0, 'layout': 0, 'ext_draw': 1,
|
||||
'dsc': "Set width of outline in pixels."},
|
||||
|
||||
{'name': 'OUTLINE_COLOR',
|
||||
'style_type': 'color', 'var_type': 'lv_color_t' , 'default':'`0x000000`', 'inherited': 0, 'layout': 0, 'ext_draw': 0, 'filtered': 1,
|
||||
'dsc': "Set color of outline."},
|
||||
|
||||
{'name': 'OUTLINE_OPA',
|
||||
'style_type': 'num', 'var_type': 'lv_opa_t' , 'default':'`LV_OPA_COVER`', 'inherited': 0, 'layout': 0, 'ext_draw': 1,
|
||||
'dsc': "Set opacity of outline. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 255, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency."},
|
||||
|
||||
{'name': 'OUTLINE_PAD',
|
||||
'style_type': 'num', 'var_type': 'int32_t' , 'default':0, 'inherited': 0, 'layout': 0, 'ext_draw': 1,
|
||||
'dsc': "Set padding of outline, i.e. the gap between Widget and the outline."},
|
||||
|
||||
{'section': 'Shadow', 'dsc':'Properties to describe the shadow drawn under the rectangles.' },
|
||||
{'name': 'SHADOW_WIDTH',
|
||||
'style_type': 'num', 'var_type': 'int32_t', 'default':0, 'inherited': 0, 'layout': 0, 'ext_draw': 1,
|
||||
'dsc': "Set width of the shadow in pixels. The value should be >= 0."},
|
||||
|
||||
{'name': 'SHADOW_OFFSET_X',
|
||||
'style_type': 'num', 'var_type': 'int32_t' , 'default':0, 'inherited': 0, 'layout': 0, 'ext_draw': 1,
|
||||
'dsc': "Set an offset on the shadow in pixels in X direction."},
|
||||
|
||||
{'name': 'SHADOW_OFFSET_Y',
|
||||
'style_type': 'num', 'var_type': 'int32_t' , 'default':0, 'inherited': 0, 'layout': 0, 'ext_draw': 1,
|
||||
'dsc': "Set an offset on the shadow in pixels in Y direction."},
|
||||
|
||||
{'name': 'SHADOW_SPREAD',
|
||||
'style_type': 'num', 'var_type': 'int32_t' , 'default':0, 'inherited': 0, 'layout': 0, 'ext_draw': 1,
|
||||
'dsc': "Make shadow calculation to use a larger or smaller rectangle as base. The value can be in pixels to make the area larger/smaller"},
|
||||
|
||||
{'name': 'SHADOW_COLOR',
|
||||
'style_type': 'color', 'var_type': 'lv_color_t' , 'default':'`0x000000`', 'inherited': 0, 'layout': 0, 'ext_draw': 0, 'filtered': 1,
|
||||
'dsc': "Set color of shadow"},
|
||||
|
||||
{'name': 'SHADOW_OPA',
|
||||
'style_type': 'num', 'var_type': 'lv_opa_t' , 'default':'`LV_OPA_COVER`', 'inherited': 0, 'layout': 0, 'ext_draw': 1,
|
||||
'dsc': "Set opacity of shadow. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 255, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency."},
|
||||
|
||||
{'section': 'Image', 'dsc':'Properties to describe the images' },
|
||||
{'name': 'IMAGE_OPA',
|
||||
'style_type': 'num', 'var_type': 'lv_opa_t' , 'default':'`LV_OPA_COVER`', 'inherited': 0, 'layout': 0, 'ext_draw': 0,
|
||||
'dsc': "Set opacity of an image. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 255, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency."},
|
||||
|
||||
{'name': 'IMAGE_RECOLOR',
|
||||
'style_type': 'color', 'var_type': 'lv_color_t', 'default':'`0x000000`', 'inherited': 0, 'layout': 0, 'ext_draw': 0, 'filtered': 1,
|
||||
'dsc': "Set color to mix with the image."},
|
||||
|
||||
{'name': 'IMAGE_RECOLOR_OPA',
|
||||
'style_type': 'num', 'var_type': 'lv_opa_t' , 'default':0, 'inherited': 0, 'layout': 0, 'ext_draw': 0,
|
||||
'dsc': "Set intensity of color mixing. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 255, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency."},
|
||||
|
||||
{'section': 'Line', 'dsc':'Properties to describe line-like Widgets' },
|
||||
{'name': 'LINE_WIDTH',
|
||||
'style_type': 'num', 'var_type': 'int32_t' , 'default':0, 'inherited': 0, 'layout': 0, 'ext_draw': 1,
|
||||
'dsc': "Set width of lines in pixels."},
|
||||
|
||||
{'name': 'LINE_DASH_WIDTH',
|
||||
'style_type': 'num', 'var_type': 'int32_t' , 'default':0, 'inherited': 0, 'layout': 0, 'ext_draw': 0,
|
||||
'dsc': "Set width of dashes in pixels. Note that dash works only on horizontal and vertical lines"},
|
||||
|
||||
{'name': 'LINE_DASH_GAP',
|
||||
'style_type': 'num', 'var_type': 'int32_t', 'default':0, 'inherited': 0, 'layout': 0, 'ext_draw': 0,
|
||||
'dsc': "Set gap between dashes in pixels. Note that dash works only on horizontal and vertical lines"},
|
||||
|
||||
{'name': 'LINE_ROUNDED',
|
||||
'style_type': 'num', 'var_type': 'bool' , 'default':0, 'inherited': 0, 'layout': 0, 'ext_draw': 0,
|
||||
'dsc': "Make end points of the lines rounded. `true`: rounded, `false`: perpendicular line ending"},
|
||||
|
||||
{'name': 'LINE_COLOR',
|
||||
'style_type': 'color', 'var_type': 'lv_color_t' , 'default':'`0x000000`', 'inherited': 0, 'layout': 0, 'ext_draw': 0, 'filtered': 1,
|
||||
'dsc': "Set color of lines."},
|
||||
|
||||
{'name': 'LINE_OPA',
|
||||
'style_type': 'num', 'var_type': 'lv_opa_t' , 'default':'`LV_OPA_COVER`', 'inherited': 0, 'layout': 0, 'ext_draw': 0,
|
||||
'dsc': "Set opacity of lines."},
|
||||
|
||||
{'section': 'Arc', 'dsc':'TODO' },
|
||||
{'name': 'ARC_WIDTH',
|
||||
'style_type': 'num', 'var_type': 'int32_t' , 'default':0, 'inherited': 0, 'layout': 0, 'ext_draw': 1,
|
||||
'dsc': "Set width (thickness) of arcs in pixels."},
|
||||
|
||||
{'name': 'ARC_ROUNDED',
|
||||
'style_type': 'num', 'var_type': 'bool' , 'default':0, 'inherited': 0, 'layout': 0, 'ext_draw': 0,
|
||||
'dsc': "Make end points of arcs rounded. `true`: rounded, `false`: perpendicular line ending"},
|
||||
|
||||
{'name': 'ARC_COLOR',
|
||||
'style_type': 'color', 'var_type': 'lv_color_t', 'default':'`0x000000`', 'inherited': 0, 'layout': 0, 'ext_draw': 0, 'filtered': 1,
|
||||
'dsc': "Set color of arc."},
|
||||
|
||||
{'name': 'ARC_OPA',
|
||||
'style_type': 'num', 'var_type': 'lv_opa_t' , 'default':'`LV_OPA_COVER`', 'inherited': 0, 'layout': 0, 'ext_draw': 0,
|
||||
'dsc': "Set opacity of arcs."},
|
||||
|
||||
{'name': 'ARC_IMAGE_SRC',
|
||||
'style_type': 'ptr', 'var_type': 'const void *', 'default':'`NULL`', 'inherited': 0, 'layout': 0, 'ext_draw': 0,
|
||||
'dsc': "Set an image from which arc will be masked out. It's useful to display complex effects on the arcs. Can be a pointer to `lv_image_dsc_t` or a path to a file"},
|
||||
|
||||
{'section': 'Text', 'dsc':'Properties to describe the properties of text. All these properties are inherited.' },
|
||||
{'name': 'TEXT_COLOR',
|
||||
'style_type': 'color', 'var_type': 'lv_color_t', 'default':'`0x000000`', 'inherited': 1, 'layout': 0, 'ext_draw': 0, 'filtered': 1,
|
||||
'dsc': "Sets color of text."},
|
||||
|
||||
{'name': 'TEXT_OPA',
|
||||
'style_type': 'num', 'var_type': 'lv_opa_t', 'default':'`LV_OPA_COVER`', 'inherited': 1, 'layout': 0, 'ext_draw': 0,
|
||||
'dsc': "Set opacity of text. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 255, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency."},
|
||||
|
||||
{'name': 'TEXT_FONT',
|
||||
'style_type': 'ptr', 'var_type': 'const lv_font_t *', 'default':'`LV_FONT_DEFAULT`', 'inherited': 1, 'layout': 1, 'ext_draw': 0,
|
||||
'dsc': "Set font of text (a pointer `lv_font_t *`)."},
|
||||
|
||||
{'name': 'TEXT_LETTER_SPACE',
|
||||
'style_type': 'num', 'var_type': 'int32_t' , 'default':0, 'inherited': 1, 'layout': 1, 'ext_draw': 0,
|
||||
'dsc': "Set letter space in pixels"},
|
||||
|
||||
{'name': 'TEXT_LINE_SPACE',
|
||||
'style_type': 'num', 'var_type': 'int32_t' , 'default':0, 'inherited': 1, 'layout': 1, 'ext_draw': 0,
|
||||
'dsc': "Set line space in pixels."},
|
||||
|
||||
{'name': 'TEXT_DECOR',
|
||||
'style_type': 'num', 'var_type': 'lv_text_decor_t' , 'default':'`LV_TEXT_DECOR_NONE`', 'inherited': 1, 'layout': 0, 'ext_draw': 0,
|
||||
'dsc': "Set decoration for the text. Possible values are `LV_TEXT_DECOR_NONE/UNDERLINE/STRIKETHROUGH`. OR-ed values can be used as well." },
|
||||
|
||||
{'name': 'TEXT_ALIGN',
|
||||
'style_type': 'num', 'var_type': 'lv_text_align_t' , 'default':'`LV_TEXT_ALIGN_AUTO`', 'inherited': 1, 'layout': 1, 'ext_draw': 0,
|
||||
'dsc': "Set how to align the lines of the text. Note that it doesn't align the Widget itself, only the lines inside the Widget. Possible values are `LV_TEXT_ALIGN_LEFT/CENTER/RIGHT/AUTO`. `LV_TEXT_ALIGN_AUTO` detect the text base direction and uses left or right alignment accordingly"},
|
||||
|
||||
{'name': 'TEXT_OUTLINE_STROKE_COLOR',
|
||||
'style_type': 'color', 'var_type': 'lv_color_t', 'default':'`0x000000`', 'inherited': 1, 'layout': 0, 'ext_draw': 0, 'filtered': 1,
|
||||
'dsc': "Sets the color of letter outline stroke."},
|
||||
|
||||
{'name': 'TEXT_OUTLINE_STROKE_WIDTH',
|
||||
'style_type': 'num', 'var_type': 'int32_t' , 'default':0, 'inherited': 1, 'layout': 1, 'ext_draw': 0,
|
||||
'dsc': "Set the letter outline stroke width in pixels."},
|
||||
|
||||
{'name': 'TEXT_OUTLINE_STROKE_OPA',
|
||||
'style_type': 'num', 'var_type': 'lv_opa_t', 'default':'`LV_OPA_COVER`', 'inherited': 1, 'layout': 0, 'ext_draw': 0,
|
||||
'dsc': "Set the opacity of the letter outline stroke. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 255, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency."},
|
||||
|
||||
{'section': 'Miscellaneous', 'dsc':'Mixed properties for various purposes.' },
|
||||
{'name': 'RADIUS',
|
||||
'style_type': 'num', 'var_type': 'int32_t', 'default':0, 'inherited': 0, 'layout': 0, 'ext_draw': 0,
|
||||
'dsc': "Set radius on every corner. The value is interpreted in pixels (>= 0) or `LV_RADIUS_CIRCLE` for max. radius"},
|
||||
|
||||
{'name': 'RADIAL_OFFSET',
|
||||
'style_type': 'num', 'var_type': 'int32_t' , 'default':0, 'inherited': 0, 'layout': 0, 'ext_draw': 0,
|
||||
'dsc': "Move start point of object (e.g. scale tick) radially"},
|
||||
|
||||
{'name': 'CLIP_CORNER',
|
||||
'style_type': 'num', 'var_type': 'bool', 'default':0, 'inherited': 0, 'layout': 0, 'ext_draw': 0,
|
||||
'dsc': "Enable to clip the overflowed content on the rounded corner. Can be `true` or `false`." },
|
||||
|
||||
{'name': 'OPA',
|
||||
'style_type': 'num', 'var_type': 'lv_opa_t', 'default':'`LV_OPA_COVER`', 'inherited': 1, 'layout': 0, 'ext_draw': 0,
|
||||
'dsc': "Scale down all opacity values of the Widget by this factor. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 255, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency." },
|
||||
|
||||
{'name': 'OPA_LAYERED',
|
||||
'style_type': 'num', 'var_type': 'lv_opa_t', 'default':'`LV_OPA_COVER`', 'inherited': 1, 'layout': 0, 'ext_draw': 0,
|
||||
'dsc': "First draw Widget on the layer, then scale down layer opacity factor. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 255, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency." },
|
||||
|
||||
{'name': 'COLOR_FILTER_DSC',
|
||||
'style_type': 'ptr', 'var_type': 'const lv_color_filter_dsc_t *', 'default':'`NULL`', 'inherited': 0, 'layout': 0, 'ext_draw': 0,
|
||||
'dsc': "Mix a color with all colors of the Widget." },
|
||||
|
||||
{'name': 'COLOR_FILTER_OPA',
|
||||
'style_type': 'num', 'var_type': 'lv_opa_t' , 'default':'`LV_OPA_TRANSP`', 'inherited': 0, 'layout': 0, 'ext_draw': 0,
|
||||
'dsc': "The intensity of mixing of color filter."},
|
||||
|
||||
{'name': 'RECOLOR',
|
||||
'style_type': 'color', 'var_type': 'lv_color_t', 'default':'`0x000000`', 'inherited': 0, 'layout': 0, 'ext_draw': 0,
|
||||
'dsc': "Set a color to mix to the obj."},
|
||||
|
||||
{'name': 'RECOLOR_OPA',
|
||||
'style_type': 'num', 'var_type': 'lv_opa_t', 'default':'`LV_OPA_TRANSP`', 'inherited': 0, 'layout': 0, 'ext_draw': 0,
|
||||
'dsc': "Set intensity of color mixing. Value 0, `LV_OPA_0` or `LV_OPA_TRANSP` means fully transparent, 255, `LV_OPA_100` or `LV_OPA_COVER` means fully covering, other values or LV_OPA_10, LV_OPA_20, etc means semi transparency."},
|
||||
|
||||
{'name': 'ANIM',
|
||||
'style_type': 'ptr', 'var_type': 'const lv_anim_t *', 'default':'`NULL`', 'inherited': 0, 'layout': 0, 'ext_draw': 0,
|
||||
'dsc': "Animation template for Widget's animation. Should be a pointer to `lv_anim_t`. The animation parameters are widget specific, e.g. animation time could be the E.g. blink time of the cursor on the Text Area or scroll time of a roller. See Widgets' documentation to learn more."},
|
||||
|
||||
{'name': 'ANIM_DURATION',
|
||||
'style_type': 'num', 'var_type': 'uint32_t' , 'default':0, 'inherited': 0, 'layout': 0, 'ext_draw': 0,
|
||||
'dsc': "Animation duration in milliseconds. Its meaning is widget specific. E.g. blink time of the cursor on the Text Area or scroll time of a roller. See Widgets' documentation to learn more."},
|
||||
|
||||
{'name': 'TRANSITION',
|
||||
'style_type': 'ptr', 'var_type': 'const lv_style_transition_dsc_t *' , 'default':'`NULL`', 'inherited': 0, 'layout': 0, 'ext_draw': 0,
|
||||
'dsc': "An initialized ``lv_style_transition_dsc_t`` to describe a transition."},
|
||||
|
||||
{'name': 'BLEND_MODE',
|
||||
'style_type': 'num', 'var_type': 'lv_blend_mode_t' , 'default':'`LV_BLEND_MODE_NORMAL`', 'inherited': 0, 'layout': 0, 'ext_draw': 0,
|
||||
'dsc': "Describes how to blend the colors to the background. Possible values are `LV_BLEND_MODE_NORMAL/ADDITIVE/SUBTRACTIVE/MULTIPLY/DIFFERENCE`"},
|
||||
|
||||
{'name': 'LAYOUT',
|
||||
'style_type': 'num', 'var_type': 'uint16_t', 'default':0, 'inherited': 0, 'layout': 1, 'ext_draw': 0,
|
||||
'dsc': "Set layout of Widget. Children will be repositioned and resized according to policies set for the layout. For possible values see documentation of the layouts."},
|
||||
|
||||
{'name': 'BASE_DIR',
|
||||
'style_type': 'num', 'var_type': 'lv_base_dir_t', 'default':'`LV_BASE_DIR_AUTO`', 'inherited': 1, 'layout': 1, 'ext_draw': 0,
|
||||
'dsc': "Set base direction of Widget. Possible values are `LV_BIDI_DIR_LTR/RTL/AUTO`."},
|
||||
|
||||
{'name': 'BITMAP_MASK_SRC',
|
||||
'style_type': 'ptr', 'var_type': 'const void *', 'default':'`NULL`', 'inherited': 0, 'layout': 0, 'ext_draw': 0,
|
||||
'dsc': "If set, a layer will be created for the widget and the layer will be masked with this A8 bitmap mask."},
|
||||
|
||||
{'name': 'ROTARY_SENSITIVITY',
|
||||
'style_type': 'num', 'var_type': 'uint32_t', 'default':'`256`', 'inherited': 1, 'layout': 0, 'ext_draw': 0,
|
||||
'dsc': "Adjust sensitivity for rotary encoders in 1/256 unit. It means, 128: slow down the rotary to half, 512: speeds up to double, 256: no change"},
|
||||
|
||||
{'section': 'Flex', 'dsc':'Flex layout properties.', 'guard':'LV_USE_FLEX'},
|
||||
|
||||
|
||||
{'name': 'FLEX_FLOW',
|
||||
'style_type': 'num', 'var_type': 'lv_flex_flow_t', 'default':'`LV_FLEX_FLOW_NONE`', 'inherited': 0, 'layout': 1, 'ext_draw': 0,
|
||||
'dsc': "Defines in which direct the flex layout should arrange the children"},
|
||||
|
||||
|
||||
{'name': 'FLEX_MAIN_PLACE',
|
||||
'style_type': 'num', 'var_type': 'lv_flex_align_t', 'default':'`LV_FLEX_ALIGN_NONE`', 'inherited': 0, 'layout': 1, 'ext_draw': 0,
|
||||
'dsc': "Defines how to align the children in the direction of flex flow"},
|
||||
|
||||
|
||||
{'name': 'FLEX_CROSS_PLACE',
|
||||
'style_type': 'num', 'var_type': 'lv_flex_align_t', 'default':'`LV_FLEX_ALIGN_NONE`', 'inherited': 0, 'layout': 1, 'ext_draw': 0,
|
||||
'dsc': "Defines how to align the children perpendicular to the direction of flex flow"},
|
||||
|
||||
|
||||
{'name': 'FLEX_TRACK_PLACE',
|
||||
'style_type': 'num', 'var_type': 'lv_flex_align_t', 'default':'`LV_FLEX_ALIGN_NONE`', 'inherited': 0, 'layout': 1, 'ext_draw': 0,
|
||||
'dsc': "Defines how to align the tracks of the flow"},
|
||||
|
||||
{'name': 'FLEX_GROW',
|
||||
'style_type': 'num', 'var_type': 'uint8_t', 'default':'`LV_FLEX_ALIGN_ROW`', 'inherited': 0, 'layout': 1, 'ext_draw': 0,
|
||||
'dsc': "Defines how much space to take proportionally from the free space of the Widget's track"},
|
||||
|
||||
|
||||
|
||||
{'section': 'Grid', 'dsc':'Grid layout properties.', 'guard':'LV_USE_GRID'},
|
||||
|
||||
|
||||
{'name': 'GRID_COLUMN_DSC_ARRAY',
|
||||
'style_type': 'ptr', 'var_type': 'const int32_t *', 'default':'`NULL`', 'inherited': 0, 'layout': 1, 'ext_draw': 0,
|
||||
'dsc': "An array to describe the columns of the grid. Should be LV_GRID_TEMPLATE_LAST terminated"},
|
||||
|
||||
{'name': 'GRID_COLUMN_ALIGN',
|
||||
'style_type': 'num', 'var_type': 'lv_grid_align_t', 'default':'`LV_GRID_ALIGN_START`', 'inherited': 0, 'layout': 1, 'ext_draw': 0,
|
||||
'dsc': "Defines how to distribute the columns"},
|
||||
|
||||
|
||||
{'name': 'GRID_ROW_DSC_ARRAY',
|
||||
'style_type': 'ptr', 'var_type': 'const int32_t *', 'default':'`NULL`', 'inherited': 0, 'layout': 1, 'ext_draw': 0,
|
||||
'dsc': "An array to describe the rows of the grid. Should be LV_GRID_TEMPLATE_LAST terminated"},
|
||||
|
||||
{'name': 'GRID_ROW_ALIGN',
|
||||
'style_type': 'num', 'var_type': 'lv_grid_align_t', 'default':'`LV_GRID_ALIGN_START`', 'inherited': 0, 'layout': 1, 'ext_draw': 0,
|
||||
'dsc': "Defines how to distribute the rows."},
|
||||
|
||||
{'name': 'GRID_CELL_COLUMN_POS',
|
||||
'style_type': 'num', 'var_type': 'int32_t', 'default':'`LV_GRID_ALIGN_START`', 'inherited': 0, 'layout': 1, 'ext_draw': 0,
|
||||
'dsc': "Set column in which Widget should be placed."},
|
||||
|
||||
{'name': 'GRID_CELL_X_ALIGN',
|
||||
'style_type': 'num', 'var_type': 'lv_grid_align_t', 'default':'`LV_GRID_ALIGN_START`', 'inherited': 0, 'layout': 1, 'ext_draw': 0,
|
||||
'dsc': "Set how to align Widget horizontally."},
|
||||
|
||||
{'name': 'GRID_CELL_COLUMN_SPAN',
|
||||
'style_type': 'num', 'var_type': 'int32_t', 'default':'`LV_GRID_ALIGN_START`', 'inherited': 0, 'layout': 1, 'ext_draw': 0,
|
||||
'dsc': "Set how many columns Widget should span. Needs to be >= 1."},
|
||||
|
||||
{'name': 'GRID_CELL_ROW_POS',
|
||||
'style_type': 'num', 'var_type': 'int32_t', 'default':'`LV_GRID_ALIGN_START`', 'inherited': 0, 'layout': 1, 'ext_draw': 0,
|
||||
'dsc': "Set row in which Widget should be placed."},
|
||||
|
||||
{'name': 'GRID_CELL_Y_ALIGN',
|
||||
'style_type': 'num', 'var_type': 'lv_grid_align_t', 'default':'`LV_GRID_ALIGN_START`', 'inherited': 0, 'layout': 1, 'ext_draw': 0,
|
||||
'dsc': "Set how to align Widget vertically."},
|
||||
|
||||
{'name': 'GRID_CELL_ROW_SPAN',
|
||||
'style_type': 'num', 'var_type': 'int32_t', 'default':'`LV_GRID_ALIGN_START`', 'inherited': 0, 'layout': 1, 'ext_draw': 0,
|
||||
'dsc': "Set how many rows Widget should span. Needs to be >= 1."},
|
||||
]
|
||||
|
||||
|
||||
def style_get_cast(style_type, var_type):
|
||||
cast = ""
|
||||
if style_type != 'color':
|
||||
cast = "(" + var_type + ")"
|
||||
return cast
|
||||
|
||||
|
||||
def obj_style_get(p):
|
||||
if 'section' in p: return
|
||||
|
||||
cast = style_get_cast(p['style_type'], p['var_type'])
|
||||
print("static inline " + p['var_type'] + " lv_obj_get_style_" + p['name'].lower() +"(const lv_obj_t * obj, lv_part_t part)")
|
||||
print("{")
|
||||
print(" lv_style_value_t v = lv_obj_get_style_prop(obj, part, LV_STYLE_" + p['name'] + ");")
|
||||
print(" return " + cast + "v." + p['style_type'] + ";")
|
||||
print("}")
|
||||
print("")
|
||||
|
||||
if 'filtered' in p and p['filtered']:
|
||||
print("static inline " + p['var_type'] + " lv_obj_get_style_" + p['name'].lower() +"_filtered(const lv_obj_t * obj, lv_part_t part)")
|
||||
print("{")
|
||||
print(" lv_style_value_t v = lv_obj_style_apply_color_filter(obj, part, lv_obj_get_style_prop(obj, part, LV_STYLE_" + p['name'] + "));")
|
||||
print(" return " + cast + "v." + p['style_type'] + ";")
|
||||
print("}")
|
||||
print("")
|
||||
|
||||
|
||||
|
||||
def style_set_cast(style_type):
|
||||
cast = ""
|
||||
if style_type == 'num':
|
||||
cast = "(int32_t)"
|
||||
return cast
|
||||
|
||||
|
||||
def style_set_c(p):
|
||||
if 'section' in p: return
|
||||
|
||||
cast = style_set_cast(p['style_type'])
|
||||
print("")
|
||||
print("void lv_style_set_" + p['name'].lower() +"(lv_style_t * style, "+ p['var_type'] +" value)")
|
||||
print("{")
|
||||
print(" lv_style_value_t v = {")
|
||||
print(" ." + p['style_type'] +" = " + cast + "value")
|
||||
print(" };")
|
||||
print(" lv_style_set_prop(style, LV_STYLE_" + p['name'] +", v);")
|
||||
print("}")
|
||||
|
||||
|
||||
def style_set_h(p):
|
||||
if 'section' in p: return
|
||||
|
||||
print("void lv_style_set_" + p['name'].lower() +"(lv_style_t * style, "+ p['var_type'] +" value);")
|
||||
|
||||
|
||||
def local_style_set_c(p):
|
||||
if 'section' in p: return
|
||||
|
||||
cast = style_set_cast(p['style_type'])
|
||||
print("")
|
||||
print("void lv_obj_set_style_" + p['name'].lower() + "(lv_obj_t * obj, " + p['var_type'] +" value, lv_style_selector_t selector)")
|
||||
print("{")
|
||||
print(" lv_style_value_t v = {")
|
||||
print(" ." + p['style_type'] +" = " + cast + "value")
|
||||
print(" };")
|
||||
print(" lv_obj_set_local_style_prop(obj, LV_STYLE_" + p['name'] +", v, selector);")
|
||||
print("}")
|
||||
|
||||
|
||||
def local_style_set_h(p):
|
||||
if 'section' in p: return
|
||||
print("void lv_obj_set_style_" + p['name'].lower() + "(lv_obj_t * obj, " + p['var_type'] +" value, lv_style_selector_t selector);")
|
||||
|
||||
|
||||
def style_const_set(p):
|
||||
if 'section' in p: return
|
||||
|
||||
cast = style_set_cast(p['style_type'])
|
||||
print("")
|
||||
print("#define LV_STYLE_CONST_" + p['name'] + "(val) \\")
|
||||
print(" { \\")
|
||||
print(" .prop = LV_STYLE_" + p['name'] + ", .value = { ." + p['style_type'] +" = " + cast + "val } \\")
|
||||
print(" }")
|
||||
|
||||
|
||||
def docs(p):
|
||||
if "section" in p:
|
||||
print("")
|
||||
print(p['section'])
|
||||
print("-" * len(p['section']))
|
||||
print("")
|
||||
print(p['dsc'])
|
||||
return
|
||||
|
||||
if "default" not in p: return
|
||||
|
||||
d = str(p["default"])
|
||||
|
||||
i = "No"
|
||||
if p["inherited"]: i = "Yes"
|
||||
|
||||
l = "No"
|
||||
if p["layout"]: l = "Yes"
|
||||
|
||||
e = "No"
|
||||
if p["ext_draw"]: e = "Yes"
|
||||
|
||||
li_style = "style='display:inline-block; margin-right: 20px; margin-left: 0px"
|
||||
|
||||
dsc = p['dsc']
|
||||
|
||||
print("")
|
||||
print(p["name"].lower())
|
||||
print("~" * len(p["name"].lower()))
|
||||
print("")
|
||||
print(dsc)
|
||||
|
||||
|
||||
print("")
|
||||
print(".. raw:: html")
|
||||
print("")
|
||||
print(" <ul>")
|
||||
print(" <li " + li_style + "'><strong>Default</strong> " + d + "</li>")
|
||||
print(" <li " + li_style + "'><strong>Inherited</strong> " + i + "</li>")
|
||||
print(" <li " + li_style + "'><strong>Layout</strong> " + l + "</li>")
|
||||
print(" <li " + li_style + "'><strong>Ext. draw</strong> " + e + "</li>")
|
||||
print(" </ul>")
|
||||
|
||||
def guard_proc(p):
|
||||
global guard
|
||||
if 'section' in p:
|
||||
if guard:
|
||||
guard_close()
|
||||
if 'guard' in p:
|
||||
guard = p['guard']
|
||||
print(f"#if {guard}")
|
||||
|
||||
def guard_close():
|
||||
global guard
|
||||
if guard:
|
||||
print(f"#endif /*{guard}*/\n")
|
||||
guard = ""
|
||||
|
||||
base_dir = os.path.abspath(os.path.dirname(__file__))
|
||||
sys.stdout = open(base_dir + '/../src/core/lv_obj_style_gen.h', 'w')
|
||||
|
||||
|
||||
HEADING = f'''
|
||||
/*
|
||||
**********************************************************************
|
||||
* DO NOT EDIT
|
||||
* This file is automatically generated by "{os.path.split(__file__)[-1]}"
|
||||
**********************************************************************
|
||||
*/
|
||||
|
||||
'''
|
||||
|
||||
print(HEADING)
|
||||
print('#ifndef LV_OBJ_STYLE_GEN_H')
|
||||
print('#define LV_OBJ_STYLE_GEN_H')
|
||||
print()
|
||||
print('''\
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
''')
|
||||
print("#include \"../misc/lv_area.h\"")
|
||||
print("#include \"../misc/lv_style.h\"")
|
||||
print("#include \"../core/lv_obj_style.h\"")
|
||||
print("#include \"../misc/lv_types.h\"")
|
||||
print()
|
||||
|
||||
guard = ""
|
||||
for p in props:
|
||||
guard_proc(p)
|
||||
obj_style_get(p)
|
||||
guard_close()
|
||||
|
||||
for p in props:
|
||||
guard_proc(p)
|
||||
local_style_set_h(p)
|
||||
guard_close()
|
||||
|
||||
print()
|
||||
print('''\
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
''')
|
||||
|
||||
print('#endif /* LV_OBJ_STYLE_GEN_H */')
|
||||
|
||||
sys.stdout = open(base_dir + '/../src/core/lv_obj_style_gen.c', 'w')
|
||||
|
||||
print(HEADING)
|
||||
print("#include \"lv_obj.h\"")
|
||||
print()
|
||||
|
||||
for p in props:
|
||||
guard_proc(p)
|
||||
local_style_set_c(p)
|
||||
guard_close()
|
||||
|
||||
sys.stdout = open(base_dir + '/../src/misc/lv_style_gen.c', 'w')
|
||||
|
||||
print(HEADING)
|
||||
print("#include \"lv_style.h\"")
|
||||
print()
|
||||
|
||||
for p in props:
|
||||
guard_proc(p)
|
||||
style_set_c(p)
|
||||
guard_close()
|
||||
|
||||
sys.stdout = open(base_dir + '/../src/misc/lv_style_gen.h', 'w')
|
||||
|
||||
print(HEADING)
|
||||
print('#ifndef LV_STYLE_GEN_H')
|
||||
print('#define LV_STYLE_GEN_H')
|
||||
print()
|
||||
print('''\
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
''')
|
||||
|
||||
for p in props:
|
||||
guard_proc(p)
|
||||
style_set_h(p)
|
||||
guard_close()
|
||||
|
||||
for p in props:
|
||||
guard_proc(p)
|
||||
style_const_set(p)
|
||||
guard_close()
|
||||
|
||||
print()
|
||||
print('''\
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
''')
|
||||
print('#endif /* LV_STYLE_GEN_H */')
|
||||
|
||||
sys.stdout = open(base_dir + '/../docs/details/base-widget/styles/style-properties.rst', 'w')
|
||||
|
||||
print('.. _style_properties:')
|
||||
print()
|
||||
print('================')
|
||||
print('Style Properties')
|
||||
print('================')
|
||||
|
||||
for p in props:
|
||||
docs(p)
|
||||
45
managed_components/lvgl__lvgl/scripts/trace_filter.py
Normal file
45
managed_components/lvgl__lvgl/scripts/trace_filter.py
Normal file
@@ -0,0 +1,45 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import argparse
|
||||
import re
|
||||
from pathlib import Path
|
||||
|
||||
MARK_LIST = ['tracing_mark_write']
|
||||
|
||||
|
||||
def get_arg():
|
||||
parser = argparse.ArgumentParser(description='Filter a log file to a trace file.')
|
||||
parser.add_argument('log_file', metavar='log_file', type=str,
|
||||
help='The input log file to process.')
|
||||
parser.add_argument('trace_file', metavar='trace_file', type=str, nargs='?',
|
||||
help='The output trace file. If not provided, defaults to \'<log_file>.systrace\'.')
|
||||
|
||||
args = parser.parse_args()
|
||||
return args
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
args = get_arg()
|
||||
|
||||
if not args.trace_file:
|
||||
log_file = Path(args.log_file)
|
||||
args.trace_file = log_file.with_suffix('.systrace').as_posix()
|
||||
|
||||
print('log_file :', args.log_file)
|
||||
print('trace_file:', args.trace_file)
|
||||
|
||||
with open(args.log_file, 'r') as f:
|
||||
content = f.read()
|
||||
|
||||
# compile regex pattern
|
||||
pattern = re.compile(r'(^.+-[0-9]+\s\[[0-9]]\s[0-9]+\.[0-9]+:\s('
|
||||
+ "|".join(MARK_LIST)
|
||||
+ r'):\s[B|E]\|[0-9]+\|.+$)', re.M)
|
||||
|
||||
matches = pattern.findall(content)
|
||||
|
||||
# write to args.trace_file
|
||||
with open(args.trace_file, 'w') as f:
|
||||
f.write('# tracer: nop\n#\n')
|
||||
for match in matches:
|
||||
f.write(match[0] + '\n')
|
||||
177
managed_components/lvgl__lvgl/scripts/update_version.py
Normal file
177
managed_components/lvgl__lvgl/scripts/update_version.py
Normal file
@@ -0,0 +1,177 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import os
|
||||
import re
|
||||
import argparse
|
||||
from typing import List, Union
|
||||
|
||||
|
||||
def get_arg():
|
||||
parser = argparse.ArgumentParser(formatter_class=argparse.RawTextHelpFormatter, description=""
|
||||
"Apply the specified version to affected source files. Eg.:\n"
|
||||
" python3 update_version.py 9.1.2-dev\n"
|
||||
" python3 update_version.py 9.2.0"
|
||||
)
|
||||
parser.add_argument('version', metavar='version', type=str,
|
||||
help='The version to apply')
|
||||
|
||||
return parser.parse_args()
|
||||
|
||||
|
||||
class Version:
|
||||
RE_PATTERN = r"(\d+)\.(\d+)\.(\d+)(-[\w\d]+)?"
|
||||
|
||||
def __init__(self, user_input: str):
|
||||
|
||||
if not re.match(r'^' + self.RE_PATTERN + r'$', user_input):
|
||||
raise Exception(f"Invalid version format: {user_input}")
|
||||
|
||||
groups = re.search(self.RE_PATTERN, user_input).groups()
|
||||
|
||||
self.major = groups[0]
|
||||
self.minor = groups[1]
|
||||
self.patch = groups[2]
|
||||
self.info = groups[3].lstrip('-') if groups[3] else ""
|
||||
|
||||
self.is_release = len(self.info) == 0
|
||||
self.as_string = user_input
|
||||
|
||||
def __str__(self):
|
||||
return self.as_string
|
||||
|
||||
|
||||
class RepoFileVersionReplacer:
|
||||
DIR_SCRIPTS = os.path.dirname(__file__)
|
||||
DIR_REPO_ROOT = os.path.join(DIR_SCRIPTS, "..")
|
||||
|
||||
def __init__(self, relative_path_segments: List[str], expected_occurrences: int):
|
||||
self.path_relative = os.path.join(*relative_path_segments)
|
||||
self.path = os.path.join(self.DIR_REPO_ROOT, self.path_relative)
|
||||
self.expected_occurrences = expected_occurrences
|
||||
|
||||
def applyVersionToLine(self, line: str, version: Version) -> Union[str, None]:
|
||||
return None
|
||||
|
||||
def applyVersion(self, version: Version):
|
||||
with open(self.path, 'r', encoding='utf-8') as file:
|
||||
lines = file.readlines()
|
||||
|
||||
occurrences = 0
|
||||
for i, line in enumerate(lines):
|
||||
line_with_version = self.applyVersionToLine(line, version)
|
||||
if line_with_version:
|
||||
lines[i] = line_with_version
|
||||
occurrences += 1
|
||||
|
||||
# not perfect, but will catch obvious pitfalls
|
||||
if occurrences != self.expected_occurrences:
|
||||
raise Exception(f"Bad lines in {self.path_relative}")
|
||||
|
||||
with open(self.path, 'w', encoding='utf-8') as file:
|
||||
file.writelines(lines)
|
||||
|
||||
|
||||
class PrefixReplacer(RepoFileVersionReplacer):
|
||||
|
||||
def __init__(self, relative_path_segments: List[str], prefix: str, expected_occurrences=1):
|
||||
super().__init__(relative_path_segments, expected_occurrences)
|
||||
self.prefix = prefix
|
||||
|
||||
def applyVersionToLine(self, line: str, version: Version):
|
||||
pattern = r'(' + re.escape(self.prefix) + ')' + Version.RE_PATTERN
|
||||
repl = r'\g<1>' + str(version)
|
||||
replaced, n = re.subn(pattern, repl, line)
|
||||
return replaced if n > 0 else None
|
||||
|
||||
|
||||
class MacroReplacer(RepoFileVersionReplacer):
|
||||
def __init__(self, relative_path_segments: List[str]):
|
||||
super().__init__(relative_path_segments, 4)
|
||||
|
||||
def applyVersionToLine(self, line: str, version: Version):
|
||||
targets = {
|
||||
'LVGL_VERSION_MAJOR': version.major,
|
||||
'LVGL_VERSION_MINOR': version.minor,
|
||||
'LVGL_VERSION_PATCH': version.patch,
|
||||
'LVGL_VERSION_INFO': version.info,
|
||||
}
|
||||
|
||||
for key, val in targets.items():
|
||||
pattern = self.getPattern(key)
|
||||
repl = self.getReplacement(val)
|
||||
replaced, n = re.subn(pattern, repl, line)
|
||||
if n > 0:
|
||||
return replaced
|
||||
|
||||
return None
|
||||
|
||||
def getPattern(self, key: str):
|
||||
return r'(^#define ' + key + r' +).+'
|
||||
|
||||
def getReplacement(self, val: str):
|
||||
if not val.isnumeric():
|
||||
val = f'"{val}"'
|
||||
|
||||
return r'\g<1>' + val
|
||||
|
||||
|
||||
class CmakeReplacer(MacroReplacer):
|
||||
def getPattern(self, key: str):
|
||||
return r'(^set\(' + key + r' +")([^"]*)(.+)'
|
||||
|
||||
def getReplacement(self, val: str):
|
||||
return r'\g<1>' + val + r'\g<3>'
|
||||
|
||||
class KconfigReplacer(RepoFileVersionReplacer):
|
||||
"""Replace version info in Kconfig file"""
|
||||
|
||||
def __init__(self, relative_path_segments: List[str]):
|
||||
super().__init__(relative_path_segments, 3)
|
||||
|
||||
def applyVersionToLine(self, line: str, version: Version):
|
||||
targets = {
|
||||
'LVGL_VERSION_MAJOR': version.major,
|
||||
'LVGL_VERSION_MINOR': version.minor,
|
||||
'LVGL_VERSION_PATCH': version.patch,
|
||||
}
|
||||
|
||||
for key, val in targets.items():
|
||||
pattern = self.getPattern(key)
|
||||
repl = self.getReplacement(val)
|
||||
replaced, n = re.subn(pattern, repl, line)
|
||||
if n > 0:
|
||||
return replaced
|
||||
|
||||
return None
|
||||
def getPattern(self, key: str):
|
||||
# Match the version fields in Kconfig file
|
||||
return rf'(^\s+default\s+)(\d+) # ({key})'
|
||||
|
||||
def getReplacement(self, val: str):
|
||||
# Replace the version value
|
||||
return r'\g<1>' + val + r' # \g<3>'
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
args = get_arg()
|
||||
|
||||
version = Version(args.version)
|
||||
print(f"Applying version {version} to:")
|
||||
|
||||
targets = [
|
||||
MacroReplacer(['lv_version.h']),
|
||||
CmakeReplacer(['env_support', 'cmake', 'version.cmake']),
|
||||
PrefixReplacer(['lv_conf_template.h'], 'Configuration file for v'),
|
||||
KconfigReplacer(['Kconfig']),
|
||||
]
|
||||
|
||||
if version.is_release:
|
||||
targets.extend([
|
||||
PrefixReplacer(['library.json'], '"version": "'),
|
||||
PrefixReplacer(['library.properties'], 'version='),
|
||||
PrefixReplacer(['Kconfig'], 'Kconfig file for LVGL v'),
|
||||
])
|
||||
|
||||
for target in targets:
|
||||
print(f" - {target.path_relative}")
|
||||
target.applyVersion(version)
|
||||
Reference in New Issue
Block a user