rel_1.6.0 init

This commit is contained in:
guocheng.kgc 2020-06-18 20:06:52 +08:00 committed by shengdong.dsd
commit 27b3e2883d
19359 changed files with 8093121 additions and 0 deletions

View file

@ -0,0 +1,19 @@
NAME := littlevGL
$(NAME)_TYPE := framework
#default gcc
ifeq ($(COMPILER),)
$(NAME)_CFLAGS += -Wall -Werror
else ifeq ($(COMPILER),gcc)
$(NAME)_CFLAGS += -Wall -Werror
else ifeq ($(COMPILER),armcc)
GLOBAL_DEFINES += __BSD_VISIBLE
endif
GLOBAL_INCLUDES += .
GLOBAL_DEFINES += AOS_LITTLEVGL
ifneq ($(IDE),keil)
$(NAME)_COMPONENTS += framework.GUI.littlevGL.lvgl
endif

View file

@ -0,0 +1,17 @@
/**
* @file lv_conf.h
*
*/
#ifndef LV_CONF_H
#define LV_CONF_H
#ifdef LITTLEVGL_STARTERKIT
#include "lv_conf_starterkit.h"
#endif
#ifdef LITTLEVGL_SIMULATE
#include "lv_conf_simulate.h"
#endif
#endif /*LV_CONF_H*/

View file

@ -0,0 +1,75 @@
# Littlev Graphics Libraray
![LittlevGL cover](http://www.gl.littlev.hu/home/main_cover_small.png)
LittlevGL provides everything you need to create a Graphical User Interface (GUI) on embedded systems with easy-to-use graphical elements, beautiful visual effects and low memory footprint.
Homepage: https://littlevgl.com
### Table Of Content
* [Key features](#key-features)
* [Porting](#porting)
* [Project set-up](#project-set-up)
* [PC simulator](#pc-simulator)
* [Screenshots](#screenshots)
* [Contributing](#contributing)
* [Donate](#donate)
## Key features
* Powerful building blocks buttons, charts, lists, sliders, images etc
* Advanced graphics with animations, anti-aliasing, opacity, smooth scrolling
* Various input devices touch pad, mouse, keyboard, encoder etc
* Multi language support with UTF-8 decoding
* Fully customizable graphical elements
* Hardware independent to use with any microcontroller or display
* Scalable to operate with few memory (80 kB Flash, 10 kB RAM)
* OS, External memory and GPU supported but not required
* Single frame buffer operation even with advances graphical effects
* Written in C for maximal compatibility
* Simulator to develop on PC without embedded hardware
* Tutorials, examples, themes for rapid development
* Advanced support and professional GUI development service
* Documentation and API references online
* Free and open-source under MIT licence
## Porting
In the most sime case you need 4 things:
1. Call `lv_tick_inc(1)` in every millisecods in a Timer or Task
2. Register a function which can **copy a pixel array** to an area of the screen
3. Register a function which can **read an input device**. (E.g. touch pad)
4. Call `lv_task_handler()` periodically in every few milliseconds ()
For more information visit https://littlevgl.com/porting
## Project set-up
1. **Clone** or download the lvgl repository: `git clone https://github.com/littlevgl/lvgl.git`
2. **Create project** with your prefered IDE and add the *lvgl* folder
3. Copy **lvgl/lv_conf_templ.h** as **lv_conf.h** next to the *lvgl* folder
4. In the *_conf.h files delete the first `#if 0` and its `#endif`. Let the default configurations at first.
5. In your *main.c*: #include "lvgl/lvgl.h"
6. In your *main function*:
* lvgl_init();
* tick, display and input device initialization (see above)
7. To **test** create a label: `lv_obj_t * label = lv_label_create(lv_scr_act(), NULL);`
8. In the main *while(1)* call `lv_task_handler();` and make a few milliseconds delay (e.g. `my_delay_ms(5);`)
9. Compile the code and load it to your embedded hardware
## PC Simulator
If you don't have got an embedded hardware you can test the graphics library in a PC simulator. The simulator uses [SDL2](https://www.libsdl.org/) to emulate a display on your monitor and a touch pad with your mouse.
There is a pre-configured PC project for **Eclipse CDT** in this repository: https://github.com/littlevgl/pc_simulator
## Screenshots
![TFT material](http://www.gl.littlev.hu/github_res/tft_material.png)
![TFT zen](http://www.gl.littlev.hu/github_res/tft_zen.png)
![TFT alien](http://www.gl.littlev.hu/github_res/tft_alien.png)
![TFT night](http://www.gl.littlev.hu/github_res/tft_night.png)
## Contributing
See [CONTRIBUTING.md](https://github.com/littlevgl/lvgl/blob/master/docs/CONTRIBUTING.md)
## Donate
If you are pleased with the graphics library, found it useful or be happy with the support you got, please help its further development:
[![Donate](https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=GJV3SC5EHDANS)

View file

@ -0,0 +1,46 @@
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at [atom@github.com](mailto:atom@github.com). All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
[homepage]: http://contributor-covenant.org
[version]: http://contributor-covenant.org/version/1/4/

View file

@ -0,0 +1,186 @@
# Contributing to Littlev Graphics Library
First of all thank you for reading these guide before contributing!
In this guide you can read how can you help in developing the Littlev Graphic Library. If you have a constructive idea just create pull request on this document!
### Table Of Content
* [Who can contribute?](#who-can-contribute)
* [How to report an issue?](#how-to-report-an-issue)
* [Simple issue](#simple-issue)
* [Complex issue](#complex-issue)
* [How to suggest a feature?](#how-to-suggest-a-feature)
* [How to implement a feature?](#how-to-implement-a-feature)
* [Styling guide](#styling-guide)
* [File format](#file-format)
* [Functions](#functions)
* [Variables](#variables)
* [Defines](#defines)
* [Typedefs](#typedefs)
* [Comments](#comments)
* [Formatting](#formatting)
## Who can contribute?
As graphical interfaces for embedded systems has an increasing relevance today. You also might find important to work with a good graphics library. Now - independently from skills, programming level or any personal attributes - you can influence the development of the graphics library with:
* Report an issue
* Suggest feature
* Fix an issue
* Implement a feature
Please, take a look at [CODE_OF_CONDUCT](https://github.com/littlevgl/lvgl/blob/master/docs/CODE_OF_CONDUCT.md)
Continue reading to know how you can be part of the development! We are waiting for you!
## How to report an issue?
### Simple issue
If you find an issue which is very simple to fix, and you fixed it, please send a pull request against `beta` branch.
A simple issue could be:
* Misspelled names
* Comment: misspelling or grammatical error in comments
* Variable: misspelled variable name (e.g. ***ojb**_next* instead of ***obj**_next*)
* Define: only local defines in files because global defines affect API
* Function: only static function name because global functions affect API
* Not handled error case:
* A parameter can be NULL (during normal usage)
* Negative index in array or over indexing
* Overflow in variable
* Anything which is local an can be fixed with a few lines of code
### Complex issue
If you find a complex issue which:
* might be simple but you don't know its origin
* affects a whole file, module or even the architecture
* needs deeper discussion
please create a **new issue** and describe
* what you experience
* how to reproduce the issue (maybe with example code)
* version you are using (lvgl.h)
* misc library version (misc.h)
## How to suggest a feature?
If you have a good and useful idea you can use GitHub issues to suggest a new feature. Please note the followings on feature requests:
* What the new feature is about?
* Why/Where/In which case is it useful/helpful/relevant?
* Can you help in implementing it?
After a discussion we figure out the specification of the new feature and the technical details/implementation possibilities.
With the knowledge of how to do it somebody can implement the new feature.
Keep in mind if you wouldn't like to do the implementation there is no guarantee that it will be ready in the new future.
However if you would like to force it, take a look at this page: [Feature request service](http://www.gl.littlev.hu/services#feature)
## How to implement a feature?
In [docs/TODO_MINOR.md](https://github.com/littlevgl/lvgl/blob/master/docs/TODO_MINOR.md) and [docs/TODO_PATCH.md](https://github.com/littlevgl/lvgl/blob/master/docs/TODO_PATCH.md) you can see some ideas which are waiting for somebody to realize them! If want to deal with a feature from this files, please start an issue and discusse the details.
The new feature should be in a new branch.
## Styling guide
### File format
Use [misc/templ/templ.c](https://github.com/littlevgl/misc/blob/master/templ/templ.c) and [misc/templ/templ.h](https://github.com/littlevgl/misc/blob/master/templ/templ.h)
### Abbreviations
Please read this document to see the list of accepted abbreviations: [abbreviations-in-code](https://github.com/kisvegabor/abbreviations-in-code)
### Functions
* try to write function shorter then is 40 lines
* always shorter then 100 lines (except very straightforwards)
* in function names:
* words sparated by '_'
* only lower case letters
* only clear abbreviation (OK: *lv_xy_get_title_txt*, BAD: *lv_xy_get_ttxt*)
#### Global functions names (API)
An example: *lv_btn_set_state()*
* starts with *lv*
* followed by module name: *btn*, *label*, *style* etc.
* followed by the action: *set*, *get*, *refr* etc.
* closed with subject: *name*, *size*, *state* etc.
* optional like in *lv_obj_del()* it is missing
* could contain more words: *long_mode*, *point_all*
#### Static functions names
Names can be used freely.
### Variables
* words sparated by '_'
* always lower case
* one line, one declaration (BAD: char x, y;)
* use `<stdint.h>` (*uint8_t*, *int32_t* etc)
* declare variables when needed (not all at function start)
* use the smallest required scope
* variables in a file (outside functions) are always *static*
* do not use global variables (use functions to set/get static variables)
### Defines
* always upper case
* starts with *LV_*
* followed by the modul: *OBJ*, *BTN* etc.
* closed by the subject: *ANIM_TIME*, *VALUE_MIN*, *WIDTH_DEF*
### Typedefs
- prefer `typedef struct` instead of `struct name`
- prefer `typedef enum` instead of `enum name`
- types always lowercase speperated by '_'
- first word for public typedefs is *lv_...*
- next word identifies the modul: *lv_obj_...*, *lv_btn_...*
- always add closing *..._t*
- Examples: *lv_obj_t*, *lv_cont_layout_t*
### Comments
Before every function have a comment like this:
```c
/**
* Return with the screen of an object
* @param obj pointer to an object
* @return pointer to a screen
*/
lv_obj_t * lv_obj_get_scr(lv_obj_t * obj);
```
Always use `/* Something */` format and NOT `//Something`
Write readable code to avoid descriptive comments like:
`x++; /* Add 1 to x */`.
The code should show clearly what you are doing.
You should write **why** have you done this:
`x++; /*Because of closing '\0' of the string */`
Short "code summaries" of a few lines are accepted. E.g. `/*Calculate the new coordinates*/`
In comments use `' '` when refering to a variable. E.g. `/*Update the value of 'x_act'*/`
### Formatting
Here is example to show bracket placing and using of white spaces:
```c
/**
* Set a new text for a label. Memory will be allocated to store the text by the label.
* @param label pointer to a label object
* @param text '\0' terminated character string. NULL to refresh with the current text.
*/
void lv_label_set_text(lv_obj_t * label, const char * text)
{ /*Main bracket in new line*/
if(label == NULL) return; /*No bracket only if the command is inline with the if statement*/
lv_obj_inv(label);
lv_label_ext_t * ext = lv_obj_get_ext(label);
/*Comment before a section */
if(text == ext->txt || text == NULL) { /*Bracket start inline*/
lv_label_refr_text(label);
return;
}
.
.
.
}
```
Use 4 spaces indentation instead of tab.

View file

@ -0,0 +1,30 @@
# TODOs for major versions
Major versions released typically when API changes are required
## Contributing
Please create an issue to suggest a new feature instead of adding pull request to this file.
## v5 (released at: 20.12.2017)
**Architectural changes**
- [x] Rename repository from *proj_pc* to *pc_simulator*
- [x] Integrate *hal* in LittlevGL as a normal folder
- [x] Create a new repository for examples
- [x] Convert Applications into simple examples
- [x] Add tests for all object types
**API changes**
- [x] Rework lv_style_t structure
- [x] Remove LV_DOWNSCALE (LV_ANTIALIAS will be used instead)
- [x] Rename (and slightly rework) some function, defines and enums to be more descriptive
- [x] lv_btnm: rework width control. Now a control byte is used for *width*, *hide* and *no long press* settings.
- [x] LV_LABEL_LONG_DOTS removed, use LV_LABEL_LONG_ROLL instead
- [x] *lv_list_set_element_text_roll()* removed.
- [x] *lv_ddlist_set_fix_height()* instead of *auto_size*
- [x] *lv_list_set_sb_out()* removed because now the scrollbar style can position the scrollbar
- [x] *lv_gauge* rework to make it more like line meter (remove background but add scale lines)
- [x] rename *lv_dispi_...* to *lv_indev_...*
- [x] *lv_dispi_t* removed from *lv_action_type_t*. Use lv_indev_act() instead
- [x] make styles to global variable to ensure less typing
- [x] make fonts to global variables to ensure less typing and easy user-font adding
- [x] join symbol fonts into normal built-in fonts
- [x] add inline functions to avoide direct use of anchestor functions (e.g. for buttons: lv_cont_set_fit -> lv_btn_set_fit)

View file

@ -0,0 +1,49 @@
# TODOs for minor versions
Minor versions (x.1.0, x.2.0 ...) released when one or more new feature is addded without changing the API. New features can be added with major versions (1.0.0, 2.0.0 ...) too.
## Contributing
Please create an issue to suggest a new feature instead of adding pull request to this file.
## Ideas
Here are ideas which are not assigned to a minor version yet:
- label: add a horzintal line (e.g. underline or line through).
- lv_split: new object type, a hor. or ver. line for decoration purpose
- lv_valset: new object type, a label with "+" and "-" buttons
- lv_listctrl: new object type, a list various controls on th right (sw, cb erc.)
- lv_inlist: new object type, inline drop down list (a button wich opens a list in place)
- lv_char: new_object type: characteristic set (like chart with draggable points)
- lv_vol: new_object type: volume meter (like a bar with segments)
- anim. paths: monentum (tnh(x)), curve (exp), shake
- hover, hover_lost signals
## v5.1 (released at: in progress)
- [ ] Lua interface to craete GUI with script
- [ ] Font handling extension for effective Chiese font handling (cutsom read functions)
- [ ] lv_group: different default style_mod function with LV_COLOR_DEPTH 1
- [ ] lv_img_set_data() for const. image data instead of file system usage
- [ ] Arabic glyph convert (based on letter position)
- [ ] Right-to-left write support
- [ ] Detached area (for video rendering where LittlevGL don't put pixels)
- [ ] lv_ta: add placeholder text
- [ ] lv_ibtn: new object type: an image wich acts as a button (different image for different states)
## v5.0 (released at: 20.12.2017)
- [x] UTF-8 support
- [x] lv_tabview: new object type to organise content with tabs
- [x] lv_sw: new object type, switch, turn on/off by tap (a little slider)
- [x] lv_roller: new object type, a roller to select a value (like on smartphones)
- [x] lv_kb: new object type, Keyboard
- [x] lv_btnm: lv_btnm_set_tgl() to toggle last button
- [x] lv_ta: cursor types
- [x] add themes with predefined styles
- [x] partial border draw in styles
## v4.2 (released at: 17.08.2017)
- [x] Double VDB support: one for rendering, another to transfer former rendered image to frame buffer in the background (e.g. with DMA) [#15](https://github.com/littlevgl/lvgl/issues/15)
- [x] lv_group: to control without touch pad. Issue [#14](https://github.com/littlevgl/lvgl/issues/14)
- [x] lv_page: scrl def fit modification: hor:false, ver:true, and always set width to parent width
- [x] lv_btn: add lv_btn_get_..._action
- [x] lv_list: add lv_list_get_element_label/img
- [x] lv_ta: lv_ta_set_one_line to configure the Text area to one lined input field
- [x] style animations add
- [x] lv_btnm: besides 0. byte (width dsc) 1. byte: hidden (\177, 0x7F, delete)

View file

@ -0,0 +1,37 @@
# TODOs for patch versions
Patch versions (x.y.1, x.y.2) contain bugfixes without changing the API but they can apppear in minor (x.1.0, x.2.0) or major (1.0.0, 2.0.0) versions too.
Bugfixes are done in `bugfix` branche.
The bugfixes of the still not released version are in `beta` branche.
## Contributing
Please create an issue to introduce a bug instead of adding pull request to this file.
## v5.0.2 (released at: in progress)
- [x] Fix dependencied (Thanks to Zaltora)
- [x] lv_group: fix memory leak (Thanks to BenQoo)
- [x] LV_INDEV_READ_PERIOD 0 build bugfix
- [x] lv_roller: lv_roller_get_selected_str: bugfix (was recursive call)
- [x] lv_obj_get_style: with NULL style check if the parent is focused and use the focused style
- [x] lv_roller: add missing action handling
- [ ] Set 24 bit colors upper byte (alpha) to 0xFF
## v5.0.1 (released at: 02.01.2018)
- [x] lv_list: fixed when mouse and keyboard used together
- [x] lv_btnm: fix bottom border visibility
- [x] theme updates
- [x] line width fix width anti-aliasing
- [x] lv_conf_templ.h add more info
## v5.0 (released at: 21.12.2017)
- [x] lv_btnm: check hide code (\177) at 0. byte position too (if width is not specified)
- [x] lv_img: define *lv_img_raw_header* in *lv_draw.h* because now lv_img can't be disabled
- [x] lv_list: ignore image related things when *lv_img* is not enebled
- [x] lv_ta: fix hegiht if *one_line* and *FONT_ANTIALIAS*
- [x] lv_obj_set_style: fix to update self style too (not only children)
## v4.2 (released at: 17.08.2017)
- [x] lv_slider: don't let indicator or bar to disappear because of hpad/vpad
- [x] lv_ta: memory leak if deleted in password mode
- [x] lv_list: work without *lv_img* by ignore the image file name parameter of *lv_list_add()*

View file

@ -0,0 +1,8 @@
MIT licence
Copyright (c) 2016 Gábor Kiss-Vámosi
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.

View file

@ -0,0 +1,288 @@
/**
* @file lv_conf.h
*
*/
#if 0 /*Remove this to enable the content (Delete the last #endif too!)*/
#ifndef LV_CONF_H
#define LV_CONF_H
/*----------------
* Dynamic memory
*----------------*/
/*
* Memory size which will be used by the library
* to store the graphical objects and other data
*/
#define LV_MEM_CUSTOM 0 /*1: use custom malloc/free, 0: use the built-in lv_mem_alloc/lv_mem_free*/
#if LV_MEM_CUSTOM == 0
#define LV_MEM_SIZE (32U * 1024U) /*Size memory used by mem_alloc (in bytes)*/
#define LV_MEM_ATTR /*Complier prefix for big array declaration*/
#define LV_MEM_AUTO_DEFRAG 1 /*Automatically defrag on free*/
#else /*LV_MEM_CUSTOM*/
#define LV_MEM_CUSTOM_INCLUDE <stdlib.h> /*Header for the dynamic memory function*/
#define LV_MEM_CUSTOM_ALLOC malloc /*Wrapper to malloc*/
#define LV_MEM_CUSTOM_FREE free /*Wrapper to free*/
#endif /*LV_MEM_CUSTOM*/
/*===================
Graphical settings
*=====================*/
/* Horizontal and vertical resolution of the library.*/
#define LV_HOR_RES (320)
#define LV_VER_RES (240)
#define LV_DPI 100
/* Size of internal graphics buffer (required for buffered drawing)
* VDB means Virtual Display Buffer (the internal graphics buffer)
* Set to 0 for unbuffered drawing
* Set to >= LV_HOR_RES for buffered drawing if LV_ANTIALIAS = 0
* Set to >= 2 * LV_HOR_RES for buffered drawing if LV_ANTIALIAS = 1
* More info: https://littlevgl.com/basics#drawing-and-rendering*/
#define LV_VDB_SIZE (20 * 1024) /*Size of VDB in pixel count*/
#define LV_VDB_ADR 0 /*Place VDB to a specific address (e.g. in external RAM) (0: allocate automatically into RAM)*/
/* Use two Virtual Display buffers (VDB) parallelize rendering and flushing (optional)
* The flushing should use DMA to write the frame buffer in the background*/
#define LV_VDB_DOUBLE 0 /*1: Enable the use of 2 VDBs*/
#define LV_VDB2_ADR 0 /*Place VDB2 to a specific address (e.g. in external RAM) (0: allocate automatically into RAM)*/
/* Enable anti-aliasing
* If enabled everything will be rendered in double size and filtered to normal size.
* Fonts and Images will be downscaled */
#define LV_ANTIALIAS 0 /*1: Enable anti-aliasing*/
/* Enable anti-aliasing only for fonts (texts)
* It downscales the fonts to half size so you should use double sized fonts
* Much faster then normal anti-aliasing */
#define LV_FONT_ANTIALIAS 1 /*1: Enable font anti-aliasing*/
/*Screen refresh settings*/
#define LV_REFR_PERIOD 50 /*Screen refresh period in milliseconds*/
#define LV_INV_FIFO_SIZE 32 /*The average count of objects on a screen */
/*=================
Misc. setting
*=================*/
/*Input device settings*/
#define LV_INDEV_READ_PERIOD 50 /*Input device read period in milliseconds*/
#define LV_INDEV_POINT_MARKER 0 /*Mark the pressed points*/
#define LV_INDEV_DRAG_LIMIT 10 /*Drag threshold in pixels */
#define LV_INDEV_DRAG_THROW 20 /*Drag throw slow-down in [%]. Greater value means faster slow-down */
#define LV_INDEV_LONG_PRESS_TIME 400 /*Long press time in milliseconds*/
#define LV_INDEV_LONG_PRESS_REP_TIME 100 /*Repeated trigger period in long press [ms] */
/*Color settings*/
#define LV_COLOR_DEPTH 16 /*Color depth: 1/8/16/24*/
#define LV_COLOR_TRANSP LV_COLOR_LIME /*Images pixels with this color will not be drawn (chroma keying)*/
/*Text settings*/
#define LV_TXT_UTF8 1 /*Enable UTF-8 coded Unicode character usage */
#define LV_TXT_BREAK_CHARS " ,.;:-_" /*Can break texts on these chars*/
/*Graphics feature usage*/
#define USE_LV_ANIMATION 1 /*1: Enable all animations*/
#define USE_LV_SHADOW 1 /*1: Enable shadows*/
#define USE_LV_GROUP 1 /*1: Enable object groups (for keyboards)*/
#define USE_LV_GPU 1 /*1: Enable GPU interface*/
#define USE_LV_FILESYSTEM 1 /*1: Enable file system (required by images*/
/*Compiler attributes*/
#define LV_ATTRIBUTE_TICK_INC /* Define a custom attribute to tick increment function */
#define LV_ATTRIBUTE_TASK_HANDLER /* Define a custom attribute to task handler function */
/*================
* THEME USAGE
*================*/
#define USE_LV_THEME_TEMPL 0 /*Just for test*/
#define USE_LV_THEME_DEFAULT 0 /*Built mainly from the built-in styles. Consumes very few RAM*/
#define USE_LV_THEME_ALIEN 0 /*Dark futuristic theme*/
#define USE_LV_THEME_NIGHT 0 /*Dark elegant theme*/
#define USE_LV_THEME_MONO 0 /*Mono color theme for monochrome displays*/
#define USE_LV_THEME_MATERIAL 0 /*Flat theme with bold colors and light shadows*/
#define USE_LV_THEME_ZEN 0 /*Peaceful, mainly light theme */
/*==================
* FONT USAGE
*===================*/
/*More info about fonts: https://littlevgl.com/basics#fonts*/
#define LV_FONT_DEFAULT &lv_font_dejavu_40 /*Always set a default font from the built-in fonts*/
#define USE_LV_FONT_DEJAVU_10 0
#define USE_LV_FONT_DEJAVU_10_SUP 0
#define USE_LV_FONT_DEJAVU_10_LATIN_EXT_A 0
#define USE_LV_FONT_DEJAVU_10_LATIN_EXT_B 0
#define USE_LV_FONT_DEJAVU_10_CYRILLIC 0
#define USE_LV_FONT_SYMBOL_10_BASIC 0
#define USE_LV_FONT_SYMBOL_10_FILE 0
#define USE_LV_FONT_SYMBOL_10_FEEDBACK 0
#define USE_LV_FONT_DEJAVU_20 0
#define USE_LV_FONT_DEJAVU_20_SUP 0
#define USE_LV_FONT_DEJAVU_20_LATIN_EXT_A 0
#define USE_LV_FONT_DEJAVU_20_LATIN_EXT_B 0
#define USE_LV_FONT_DEJAVU_20_CYRILLIC 0
#define USE_LV_FONT_SYMBOL_20_BASIC 0
#define USE_LV_FONT_SYMBOL_20_FILE 0
#define USE_LV_FONT_SYMBOL_20_FEEDBACK 0
#define USE_LV_FONT_DEJAVU_30 0
#define USE_LV_FONT_DEJAVU_30_SUP 0
#define USE_LV_FONT_DEJAVU_30_LATIN_EXT_A 0
#define USE_LV_FONT_DEJAVU_30_LATIN_EXT_B 0
#define USE_LV_FONT_DEJAVU_30_CYRILLIC 0
#define USE_LV_FONT_SYMBOL_30_BASIC 0
#define USE_LV_FONT_SYMBOL_30_FILE 0
#define USE_LV_FONT_SYMBOL_30_FEEDBACK 0
#define USE_LV_FONT_DEJAVU_40 1
#define USE_LV_FONT_DEJAVU_40_SUP 0
#define USE_LV_FONT_DEJAVU_40_LATIN_EXT_A 0
#define USE_LV_FONT_DEJAVU_40_LATIN_EXT_B 0
#define USE_LV_FONT_DEJAVU_40_CYRILLIC 0
#define USE_LV_FONT_SYMBOL_40_BASIC 1
#define USE_LV_FONT_SYMBOL_40_FILE 1
#define USE_LV_FONT_SYMBOL_40_FEEDBACK 1
#define USE_LV_FONT_DEJAVU_60 0
#define USE_LV_FONT_DEJAVU_60_SUP 0
#define USE_LV_FONT_DEJAVU_60_LATIN_EXT_A 0
#define USE_LV_FONT_DEJAVU_60_LATIN_EXT_B 0
#define USE_LV_FONT_DEJAVU_60_CYRILLIC 0
#define USE_LV_FONT_SYMBOL_60_BASIC 0
#define USE_LV_FONT_SYMBOL_60_FILE 0
#define USE_LV_FONT_SYMBOL_60_FEEDBACK 0
#define USE_LV_FONT_DEJAVU_80 0
#define USE_LV_FONT_DEJAVU_80_SUP 0
#define USE_LV_FONT_DEJAVU_80_LATIN_EXT_A 0
#define USE_LV_FONT_DEJAVU_80_LATIN_EXT_B 0
#define USE_LV_FONT_DEJAVU_80_CYRILLIC 0
#define USE_LV_FONT_SYMBOL_80_BASIC 0
#define USE_LV_FONT_SYMBOL_80_FILE 0
#define USE_LV_FONT_SYMBOL_80_FEEDBACK 0
/*===================
* LV_OBJ SETTINGS
*==================*/
#define LV_OBJ_FREE_NUM_TYPE uint32_t /*Type of free number attribute (comment out disable free number)*/
#define LV_OBJ_FREE_PTR 1 /*Enable the free pointer attribute*/
/*==================
* LV OBJ X USAGE
*================*/
/*
* Documentation of the object types: https://littlevgl.com/object-types
*/
/*****************
* Simple object
*****************/
/*Label (dependencies: -*/
#define USE_LV_LABEL 1
#if USE_LV_LABEL != 0
#define LV_LABEL_SCROLL_SPEED 25 /*Hor, or ver. scroll speed (px/sec) in 'LV_LABEL_LONG_SCROLL/ROLL' mode*/
#endif
/*Image (dependencies: lv_label, lv_filesystem*/
#define USE_LV_IMG 1
/*Line (dependencies: -*/
#define USE_LV_LINE 1
/*******************
* Container objects
*******************/
/*Container (dependencies: -*/
#define USE_LV_CONT 1
/*Page (dependencies: lv_cont)*/
#define USE_LV_PAGE 1
/*Window (dependencies: lv_btn, lv_label, lv_img, lv_page)*/
#define USE_LV_WIN 1
/*Tab view (dependencies: lv_page, lv_btnm)*/
#define USE_LV_TABVIEW 1
#if USE_LV_TABVIEW != 0
#define LV_TABVIEW_ANIM_TIME 300 /*Time of slide animation [ms] (0: no animation)*/
#endif
/*************************
* Data visualizer objects
*************************/
/*Bar (dependencies: -)*/
#define USE_LV_BAR 1
/*Line meter (dependencies: - )*/
#define USE_LV_LMETER 1
/*Gauge (dependencies:bar, lmeter)*/
#define USE_LV_GAUGE 1
/*Chart (dependencies: -)*/
#define USE_LV_CHART 1
/*LED (dependencies: -)*/
#define USE_LV_LED 1
/*Message box (dependencies: lv_cont, lv_btnm, lv_label)*/
#define USE_LV_MBOX 1
/*Text area (dependencies: lv_label, lv_page)*/
#define USE_LV_TA 1
#if USE_LV_TA != 0
#define LV_TA_CURSOR_BLINK_TIME 400 /*ms*/
#define LV_TA_PWD_SHOW_TIME 1500 /*ms*/
#endif
/*************************
* User input objects
*************************/
/*Button (dependencies: lv_cont*/
#define USE_LV_BTN 1
/*Button matrix (dependencies: -)*/
#define USE_LV_BTNM 1
/*Keyboard (dependencies: lv_btnm, lv_ta)*/
#define USE_LV_KB 1
/*Check box (dependencies: lv_btn, lv_label)*/
#define USE_LV_CB 1
/*List (dependencies: lv_page, lv_btn, lv_label, (lv_img optionally for icons ))*/
#define USE_LV_LIST 1
#if USE_LV_LIST != 0
#define LV_LIST_FOCUS_TIME 100 /*Default animation time of focusing to a list element [ms] (0: no animation) */
#endif
/*Drop down list (dependencies: lv_page, lv_label)*/
#define USE_LV_DDLIST 1
#if USE_LV_DDLIST != 0
#define LV_DDLIST_ANIM_TIME 200 /*Open and close default animation time [ms] (0: no animation)*/
#endif
/*Roller (dependencies: lv_ddlist)*/
#define USE_LV_ROLLER 1
#if USE_LV_ROLLER != 0
#define LV_ROLLER_ANIM_TIME 200 /*Focus animation time [ms] (0: no animation)*/
#endif
/*Slider (dependencies: lv_bar)*/
#define USE_LV_SLIDER 1
/*Switch (dependencies: lv_slider)*/
#define USE_LV_SW 1
#endif /*LV_CONF_H*/
#endif /*Remove this to enable the content*/

View file

@ -0,0 +1,11 @@
NAME := lv_core
$(NAME)_SOURCES += lv_group.c
$(NAME)_SOURCES += lv_indev.c
$(NAME)_SOURCES += lv_obj.c
$(NAME)_SOURCES += lv_refr.c
$(NAME)_SOURCES += lv_style.c
$(NAME)_SOURCES += lv_vdb.c
$(NAME)_INCLUDES += ../../
$(NAME)_INCLUDES += ../

View file

@ -0,0 +1,280 @@
/**
* @file lv_group.c
*
*/
/*********************
* INCLUDES
*********************/
#include "lv_group.h"
#if USE_LV_GROUP != 0
#include <stddef.h>
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
static void style_mod_def(lv_style_t * style);
/**********************
* STATIC VARIABLES
**********************/
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
/**
* Create a new object group
* @return pointer to the new object group
*/
lv_group_t * lv_group_create(void)
{
lv_group_t * group = lv_mem_alloc(sizeof(lv_group_t));
lv_ll_init(&group->obj_ll, sizeof(lv_obj_t *));
group->style_mod = style_mod_def;
group->obj_focus = NULL;
group->frozen = 0;
return group;
}
/**
* Delete a group object
* @param group pointer to a group
*/
void lv_group_del(lv_group_t * group)
{
lv_ll_clear(&(group->obj_ll));
lv_mem_free(group);
}
/**
* Add an object to a group
* @param group pointer to a group
* @param obj pointer to an object to add
*/
void lv_group_add_obj(lv_group_t * group, lv_obj_t * obj)
{
obj->group_p = group;
lv_obj_t ** next = lv_ll_ins_tail(&group->obj_ll);
*next = obj;
/* If the head and the tail is equal then there is only one object in the linked list.
* In this case automatically activate it*/
if(lv_ll_get_head(&group->obj_ll) == next) {
lv_group_focus_next(group);
}
}
/**
* Remove an object from its group
* @param obj pointer to an object to remove
*/
void lv_group_remove_obj(lv_obj_t * obj)
{
lv_group_t * g = obj->group_p;
if(g == NULL) return;
/*Search the object and remove it from its group */
lv_obj_t ** i;
LL_READ(g->obj_ll, i) {
if(*i == obj) {
lv_ll_rem(&g->obj_ll, i);
lv_mem_free(i);
obj->group_p = NULL;
}
}
if(*g->obj_focus == obj) {
g->obj_focus = NULL;
lv_group_focus_next(g);
}
}
/**
* Focus on an object (defocus the current)
* @param obj pointer to an object to focus on
*/
void lv_group_focus_obj(lv_obj_t * obj)
{
lv_group_t * g = obj->group_p;
if(g == NULL) return;
if(g->frozen != 0) return;
lv_obj_t ** i;
LL_READ(g->obj_ll, i) {
if(*i == obj) {
if(g->obj_focus != NULL) {
(*g->obj_focus)->signal_func(*g->obj_focus, LV_SIGNAL_DEFOCUS, NULL);
lv_obj_invalidate(*g->obj_focus);
}
g->obj_focus = i;
if(g->obj_focus != NULL){
(*g->obj_focus)->signal_func(*g->obj_focus, LV_SIGNAL_FOCUS, NULL);
lv_obj_invalidate(*g->obj_focus);
}
break;
}
}
}
/**
* Focus the next object in a group (defocus the current)
* @param group pointer to a group
*/
void lv_group_focus_next(lv_group_t * group)
{
if(group->frozen) return;
if(group->obj_focus) {
(*group->obj_focus)->signal_func(*group->obj_focus, LV_SIGNAL_DEFOCUS, NULL);
lv_obj_invalidate(*group->obj_focus);
}
lv_obj_t ** obj_next;
if(group->obj_focus == NULL) obj_next = lv_ll_get_head(&group->obj_ll);
else obj_next = lv_ll_get_next(&group->obj_ll, group->obj_focus);
if(obj_next == NULL) obj_next = lv_ll_get_head(&group->obj_ll);
group->obj_focus = obj_next;
if(group->obj_focus){
(*group->obj_focus)->signal_func(*group->obj_focus, LV_SIGNAL_FOCUS, NULL);
lv_obj_invalidate(*group->obj_focus);
}
}
/**
* Focus the previous object in a group (defocus the current)
* @param group pointer to a group
*/
void lv_group_focus_prev(lv_group_t * group)
{
if(group->frozen) return;
if(group->obj_focus) {
(*group->obj_focus)->signal_func(*group->obj_focus, LV_SIGNAL_DEFOCUS, NULL);
lv_obj_invalidate(*group->obj_focus);
}
lv_obj_t ** obj_next;
if(group->obj_focus == NULL) obj_next = lv_ll_get_tail(&group->obj_ll);
else obj_next = lv_ll_get_prev(&group->obj_ll, group->obj_focus);
if(obj_next == NULL) obj_next = lv_ll_get_tail(&group->obj_ll);
group->obj_focus = obj_next;
if(group->obj_focus != NULL){
(*group->obj_focus)->signal_func(*group->obj_focus, LV_SIGNAL_FOCUS, NULL);
lv_obj_invalidate(*group->obj_focus);
}
}
/**
* Do not let to change the focus from the current object
* @param group pointer to a group
* @param en true: freeze, false: release freezing (normal mode)
*/
void lv_group_focus_freeze(lv_group_t * group, bool en)
{
if(en == false) group->frozen = 0;
else group->frozen = 1;
}
/**
* Send a control character to the focuses object of a group
* @param group pointer to a group
* @param c a character (use LV_GROUP_KEY_.. to navigate)
*/
void lv_group_send_data(lv_group_t * group, uint32_t c)
{
lv_obj_t * act = lv_group_get_focused(group);
if(act == NULL) return;
act->signal_func(act, LV_SIGNAL_CONTROLL, &c);
}
/**
* Set a function for a group which will modify the object's style if it is in focus
* @param group pointer to a group
* @param style_cb the style modifier function pointer
*/
void lv_group_set_style_mod_cb(lv_group_t * group, void (*style_cb)(lv_style_t * style))
{
group->style_mod = style_cb;
if(group->obj_focus != NULL) lv_obj_invalidate(*group->obj_focus);
}
/**
* Modify a style with the set 'style_mod' function. The input style remains unchanged.
* @param group pointer to group
* @param style pointer to a style to modify
* @return a copy of the input style but modified with the 'style_mod' function
*/
lv_style_t * lv_group_mod_style(lv_group_t * group, const lv_style_t * style)
{
lv_style_copy(&group->style_tmp, style);
if(group->style_mod != NULL) group->style_mod(&group->style_tmp);
else style_mod_def(&group->style_tmp);
return &group->style_tmp;
}
/**
* Get the focused object or NULL if there isn't one
* @param group pointer to a group
* @return pointer to the focused object
*/
lv_obj_t * lv_group_get_focused(lv_group_t * group)
{
if(group == NULL) return NULL;
if(group->obj_focus == NULL) return NULL;
return *group->obj_focus;
}
/**********************
* STATIC FUNCTIONS
**********************/
/**
* Default style modifier function
* @param style pointer to a style to modify. (Typically group.style_tmp) It will be OVERWRITTEN.
*/
static void style_mod_def(lv_style_t * style)
{
/*Make the style to be a little bit orange*/
style->body.border.opa = LV_OPA_COVER;
style->body.border.color = LV_COLOR_ORANGE;
/*If not empty or has border then emphasis the border*/
if(style->body.empty == 0 || style->body.border.width != 0) style->body.border.width = LV_DPI / 20;
style->body.main_color = lv_color_mix(style->body.main_color, LV_COLOR_ORANGE, LV_OPA_70);
style->body.grad_color = lv_color_mix(style->body.grad_color, LV_COLOR_ORANGE, LV_OPA_70);
style->body.shadow.color = lv_color_mix(style->body.shadow.color, LV_COLOR_ORANGE, LV_OPA_60);
style->text.color = lv_color_mix(style->text.color, LV_COLOR_ORANGE, LV_OPA_70);
}
#endif /*USE_LV_GROUP != 0*/

View file

@ -0,0 +1,134 @@
/**
* @file lv_group.h
*
*/
#ifndef LV_GROUP_H
#define LV_GROUP_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include "../../lv_conf.h"
#include "lv_obj.h"
/*********************
* DEFINES
*********************/
/*Predefined keys to control the focused object via lv_group_send(group, c)*/
/*For compatibility in signal function define the keys regardless to LV_GROUP*/
#define LV_GROUP_KEY_UP 17 /*0x11*/
#define LV_GROUP_KEY_DOWN 18 /*0x12*/
#define LV_GROUP_KEY_RIGHT 19 /*0x13*/
#define LV_GROUP_KEY_LEFT 20 /*0x14*/
#define LV_GROUP_KEY_ESC 33 /*0x1B*/
#define LV_GROUP_KEY_ENTER 10 /*0x0A, '\n'*/
#define LV_GROUP_KEY_NEXT 9 /*0x09, '\t'*/
#define LV_GROUP_KEY_PREV 11 /*0x0B, '*/
#if USE_LV_GROUP != 0
/**********************
* TYPEDEFS
**********************/
typedef struct _lv_group_t
{
lv_ll_t obj_ll;
lv_obj_t ** obj_focus;
void (*style_mod)(lv_style_t * style);
lv_style_t style_tmp;
uint8_t frozen:1;
}lv_group_t;
/**********************
* GLOBAL PROTOTYPES
**********************/
/**
* Create a new object group
* @return pointer to the new object group
*/
lv_group_t * lv_group_create(void);
/**
* Add an object to a group
* @param group pointer to a group
* @param obj pointer to an object to add
*/
void lv_group_add_obj(lv_group_t * group, lv_obj_t * obj);
/**
* Remove an object from its group
* @param obj pointer to an object to remove
*/
void lv_group_remove_obj(lv_obj_t * obj);
/**
* Focus on an object (defocus the current)
* @param obj pointer to an object to focus on
*/
void lv_group_focus_obj(lv_obj_t * obj);
/**
* Focus the next object in a group (defocus the current)
* @param group pointer to a group
*/
void lv_group_focus_next(lv_group_t * group);
/**
* Focus the previous object in a group (defocus the current)
* @param group pointer to a group
*/
void lv_group_focus_prev(lv_group_t * group);
/**
* Do not let to change the focus from the current object
* @param group pointer to a group
* @param en true: freeze, false: release freezing (normal mode)
*/
void lv_group_focus_freeze(lv_group_t * group, bool en);
/**
* Send a control character to the focuses object of a group
* @param group pointer to a group
* @param c a character (use LV_GROUP_KEY_.. to navigate)
*/
void lv_group_send_data(lv_group_t * group, uint32_t c);
/**
* Set a function for a group which will modify the object's style if it is in focus
* @param group pointer to a group
* @param style_cb the style modifier function pointer
*/
void lv_group_set_style_mod_cb(lv_group_t * group, void (*style_cb)(lv_style_t * style));
/**
* Modify a style with the set 'style_mod' function. The input style remains unchanged.
* @param group pointer to group
* @param style pointer to a style to modify
* @return a copy of the input style but modified with the 'style_mod' function
*/
lv_style_t * lv_group_mod_style(lv_group_t * group, const lv_style_t * style);
/**
* Get the focused object or NULL if there isn't one
* @param group pointer to a group
* @return pointer to the focused object
*/
lv_obj_t * lv_group_get_focused(lv_group_t * group);
/**********************
* MACROS
**********************/
#endif /*USE_LV_GROUP != 0*/
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /*LV_GROUP_H*/

View file

@ -0,0 +1,626 @@
/**
* @file lv_indev_proc.c
*
*/
/*********************
* INCLUDES
********************/
#include "lv_indev.h"
#include "../../lv_conf.h"
#include "../lv_hal/lv_hal_tick.h"
#include "../lv_core/lv_group.h"
#include "../lv_misc/lv_task.h"
#include "../lv_misc/lv_math.h"
#include "../lv_draw/lv_draw_rbasic.h"
#include "lv_obj.h"
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
#if LV_INDEV_READ_PERIOD != 0
static void indev_proc_task(void * param);
static void indev_proc_point(lv_indev_proc_t * indev);
static void indev_proc_press(lv_indev_proc_t * info);
static void indev_proc_release(lv_indev_proc_t * state);
static lv_obj_t * indev_search_obj(const lv_indev_proc_t * indev, lv_obj_t * obj);
static void indev_drag(lv_indev_proc_t * state);
static void indev_drag_throw(lv_indev_proc_t * state);
#endif
/**********************
* STATIC VARIABLES
**********************/
static lv_indev_t *indev_act;
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
/**
* Initialize the display input device subsystem
*/
void lv_indev_init(void)
{
#if LV_INDEV_READ_PERIOD != 0
lv_task_create(indev_proc_task, LV_INDEV_READ_PERIOD, LV_TASK_PRIO_MID, NULL);
#endif
lv_indev_reset(NULL); /*Reset all input devices*/
}
/**
* Get the currently processed input device. Can be used in action functions too.
* @return pointer to the currently processed input device or NULL if no input device processing right now
*/
lv_indev_t * lv_indev_get_act(void)
{
return indev_act;
}
/**
* Reset one or all input devices
* @param indev pointer to an input device to reset or NULL to reset all of them
*/
void lv_indev_reset(lv_indev_t * indev)
{
if(indev) indev->proc.reset_query = 1;
else {
lv_indev_t * i = lv_indev_next(NULL);
while(i) {
i->proc.reset_query = 1;
i = lv_indev_next(i);
}
}
}
/**
* Reset the long press state of an input device
* @param indev pointer to an input device
*/
void lv_indev_reset_lpr(lv_indev_t * indev)
{
indev->proc.long_pr_sent = 0;
indev->proc.longpr_rep_timestamp = lv_tick_get();
indev->proc.pr_timestamp = lv_tick_get();
}
/**
* Enable input devices device by type
* @param type Input device type
* @param enable true: enable this type; false: disable this type
*/
void lv_indev_enable(lv_hal_indev_type_t type, bool enable)
{
lv_indev_t *i = lv_indev_next(NULL);
while (i) {
if (i->driver.type == type) i->proc.disabled = enable == false ? 1 : 0;
i = lv_indev_next(i);
}
}
/**
* Set a cursor for a pointer input device
* @param indev pointer to an input device (type: 'LV_INDEV_TYPE_POINTER')
* @param cur_obj pointer to an object to be used as cursor
*/
void lv_indev_set_cursor(lv_indev_t *indev, lv_obj_t *cur_obj)
{
if(indev->driver.type != LV_INDEV_TYPE_POINTER) return;
indev->cursor = cur_obj;
lv_obj_set_parent(indev->cursor, lv_layer_sys());
lv_obj_set_pos(indev->cursor, indev->proc.act_point.x, indev->proc.act_point.y);
}
#if USE_LV_GROUP
/**
* Set a destination group for a keypad input device
* @param indev pointer to an input device (type: 'LV_INDEV_TYPE_KEYPAD')
* @param group point to a group
*/
void lv_indev_set_group(lv_indev_t *indev, lv_group_t *group)
{
indev->group = group;
}
#endif
/**
* Get the last point of an input device
* @param indev pointer to an input device
* @param point pointer to a point to store the result
*/
void lv_indev_get_point(lv_indev_t * indev, lv_point_t * point)
{
point->x = indev->proc.act_point.x;
point->y = indev->proc.act_point.y;
}
/**
* Check if there is dragging with an input device or not
* @param indev pointer to an input device
* @return true: drag is in progress
*/
bool lv_indev_is_dragging(lv_indev_t * indev)
{
if(indev == NULL) return false;
return indev->proc.drag_in_prog == 0 ? false : true;
}
/**
* Get the vector of dragging of an input device
* @param indev pointer to an input device
* @param point pointer to a point to store the vector
*/
void lv_indev_get_vect(lv_indev_t * indev, lv_point_t * point)
{
point->x = indev->proc.vect.x;
point->y = indev->proc.vect.y;
}
/**
* Get elapsed time since last press
* @param indev pointer to an input device (NULL to get the overall smallest inactivity)
* @return Elapsed ticks (milliseconds) since last press
*/
uint32_t lv_indev_get_inactive_time(lv_indev_t * indev)
{
uint32_t t;
if(indev) return t = lv_tick_elaps(indev->last_activity_time);
lv_indev_t *i;
t = UINT16_MAX;
i = lv_indev_next(NULL);
while(i) {
t = LV_MATH_MIN(t, lv_tick_elaps(i->last_activity_time));
i = lv_indev_next(i);
}
return t;
}
/**
* Do nothing until the next release
* @param indev pointer to an input device
*/
void lv_indev_wait_release(lv_indev_t * indev)
{
indev->proc.wait_unil_release = 1;
}
/**********************
* STATIC FUNCTIONS
**********************/
#if LV_INDEV_READ_PERIOD != 0
/**
* Called periodically to handle the input devices
* @param param unused
*/
static void indev_proc_task(void * param)
{
(void)param;
lv_indev_data_t data;
lv_indev_t * i;
i = lv_indev_next(NULL);
/*Read and process all indevs*/
while(i) {
indev_act = i;
/*Handle reset query before processing the point*/
if(i->proc.reset_query) {
i->proc.act_obj = NULL;
i->proc.last_obj = NULL;
i->proc.drag_range_out = 0;
i->proc.drag_in_prog = 0;
i->proc.long_pr_sent = 0;
i->proc.pr_timestamp = 0;
i->proc.longpr_rep_timestamp = 0;
i->proc.drag_sum.x = 0;
i->proc.drag_sum.y = 0;
i->proc.reset_query = 0;
}
if(i->proc.disabled == 0) {
/*Read the data*/
lv_indev_read(i, &data);
i->proc.state = data.state;
if(i->proc.state == LV_INDEV_STATE_PR) {
i->last_activity_time = lv_tick_get();
}
/*Move the cursor if set and moved*/
if(i->driver.type == LV_INDEV_TYPE_POINTER &&
i->cursor != NULL &&
(i->proc.last_point.x != data.point.x ||
i->proc.last_point.y != data.point.y))
{
lv_obj_set_pos(i->cursor, data.point.x, data.point.y);
}
if(i->driver.type == LV_INDEV_TYPE_POINTER)
{
i->proc.act_point.x = data.point.x;
i->proc.act_point.y = data.point.y;;
/*Process the current point*/
indev_proc_point(&i->proc);
}
else if (i->driver.type == LV_INDEV_TYPE_KEYPAD) {
#if USE_LV_GROUP
if(i->group != NULL && data.key != 0 &&
data.state == LV_INDEV_STATE_PR && i->proc.last_state == LV_INDEV_STATE_REL)
{
if(data.key == LV_GROUP_KEY_NEXT) {
lv_group_focus_next(i->group);
}
else if(data.key == LV_GROUP_KEY_PREV) {
lv_group_focus_prev(i->group);
}
else {
lv_group_send_data(i->group, data.key);
}
}
i->proc.last_state = data.state;
#endif
}
}
/*Handle reset query if it happened in during processing*/
if(i->proc.reset_query) {
i->proc.act_obj = NULL;
i->proc.last_obj = NULL;
i->proc.drag_range_out = 0;
i->proc.drag_in_prog = 0;
i->proc.long_pr_sent = 0;
i->proc.pr_timestamp = 0;
i->proc.longpr_rep_timestamp = 0;
i->proc.drag_sum.x = 0;
i->proc.drag_sum.y = 0;
i->proc.reset_query = 0;
}
i = lv_indev_next(i); /*Go to the next indev*/
}
indev_act = NULL; /*End of indev processing, so no act indev*/
}
/**
* Process new points from a input device. indev->state.pressed has to be set
* @param indev pointer to an input device state
* @param x x coordinate of the next point
* @param y y coordinate of the next point
*/
static void indev_proc_point(lv_indev_proc_t * indev)
{
if(indev->state == LV_INDEV_STATE_PR){
#if LV_INDEV_POINT_MARKER != 0
lv_area_t area;
area.x1 = indev->act_point.x - (LV_INDEV_POINT_MARKER >> 1);
area.y1 = indev->act_point.y - (LV_INDEV_POINT_MARKER >> 1);
area.x2 = indev->act_point.x + ((LV_INDEV_POINT_MARKER >> 1) | 0x1);
area.y2 = indev->act_point.y + ((LV_INDEV_POINT_MARKER >> 1) | 0x1);
lv_rfill(&area, NULL, LV_COLOR_MAKE(0xFF, 0, 0), LV_OPA_COVER);
#endif
indev_proc_press(indev);
} else {
indev_proc_release(indev);
}
indev->last_point.x = indev->act_point.x;
indev->last_point.y = indev->act_point.y;
}
/**
* Process the pressed state
* @param indev pointer to an input device state
*/
static void indev_proc_press(lv_indev_proc_t * info)
{
lv_obj_t * pr_obj = info->act_obj;
if(info->wait_unil_release != 0) return;
/*If there is no last object then search*/
if(info->act_obj == NULL) {
pr_obj = indev_search_obj(info, lv_layer_top());
if(pr_obj == NULL) pr_obj = indev_search_obj(info, lv_scr_act());
}
/*If there is last object but it is not dragged also search*/
else if(info->drag_in_prog == 0) {/*Now act_obj != NULL*/
pr_obj = indev_search_obj(info, lv_layer_top());
if(pr_obj == NULL) pr_obj = indev_search_obj(info, lv_scr_act());
}
/*If a dragable object was the last then keep it*/
else {
}
/*If a new object was found reset some variables and send a pressed signal*/
if(pr_obj != info->act_obj) {
info->last_point.x = info->act_point.x;
info->last_point.y = info->act_point.y;
/*If a new object found the previous was lost, so send a signal*/
if(info->act_obj != NULL) {
info->act_obj->signal_func(info->act_obj, LV_SIGNAL_PRESS_LOST, indev_act);
if(info->reset_query != 0) return;
}
if(pr_obj != NULL) {
/* Save the time when the obj pressed.
* It is necessary to count the long press time.*/
info->pr_timestamp = lv_tick_get();
info->long_pr_sent = 0;
info->drag_range_out = 0;
info->drag_in_prog = 0;
info->drag_sum.x = 0;
info->drag_sum.y = 0;
/*Search for 'top' attribute*/
lv_obj_t * i = pr_obj;
lv_obj_t * last_top = NULL;
while(i != NULL){
if(i->top != 0) last_top = i;
i = lv_obj_get_parent(i);
}
if(last_top != NULL) {
/*Move the last_top object to the foreground*/
lv_obj_t * par = lv_obj_get_parent(last_top);
/*After list change it will be the new head*/
lv_ll_chg_list(&par->child_ll, &par->child_ll, last_top);
lv_obj_invalidate(last_top);
}
/*Send a signal about the press*/
pr_obj->signal_func(pr_obj, LV_SIGNAL_PRESSED, indev_act);
if(info->reset_query != 0) return;
}
}
info->act_obj = pr_obj; /*Save the pressed object*/
info->last_obj = info->act_obj; /*Refresh the last_obj*/
/*Calculate the vector*/
info->vect.x = info->act_point.x - info->last_point.x;
info->vect.y = info->act_point.y - info->last_point.y;
/*If there is active object and it can be dragged run the drag*/
if(info->act_obj != NULL) {
info->act_obj->signal_func(info->act_obj, LV_SIGNAL_PRESSING, indev_act);
if(info->reset_query != 0) return;
indev_drag(info);
if(info->reset_query != 0) return;
/*If there is no drag then check for long press time*/
if(info->drag_in_prog == 0 && info->long_pr_sent == 0) {
/*Send a signal about the long press if enough time elapsed*/
if(lv_tick_elaps(info->pr_timestamp) > LV_INDEV_LONG_PRESS_TIME) {
pr_obj->signal_func(pr_obj, LV_SIGNAL_LONG_PRESS, indev_act);
if(info->reset_query != 0) return;
/*Mark the signal sending to do not send it again*/
info->long_pr_sent = 1;
/*Save the long press time stamp for the long press repeat handler*/
info->longpr_rep_timestamp = lv_tick_get();
}
}
/*Send long press repeated signal*/
if(info->drag_in_prog == 0 && info->long_pr_sent == 1) {
/*Send a signal about the long press repeate if enough time elapsed*/
if(lv_tick_elaps(info->longpr_rep_timestamp) > LV_INDEV_LONG_PRESS_REP_TIME) {
pr_obj->signal_func(pr_obj, LV_SIGNAL_LONG_PRESS_REP, indev_act);
if(info->reset_query != 0) return;
info->longpr_rep_timestamp = lv_tick_get();
}
}
}
}
/**
* Process the released state
* @param indev_proc_p pointer to an input device state
*/
static void indev_proc_release(lv_indev_proc_t * state)
{
if(state->wait_unil_release != 0) {
state->act_obj = NULL;
state->last_obj = NULL;
state->pr_timestamp = 0;
state->longpr_rep_timestamp = 0;
state->wait_unil_release = 0;
}
/*Forgot the act obj and send a released signal */
if(state->act_obj != NULL) {
state->act_obj->signal_func(state->act_obj, LV_SIGNAL_RELEASED, indev_act);
if(state->reset_query != 0) return;
state->act_obj = NULL;
state->pr_timestamp = 0;
state->longpr_rep_timestamp = 0;
}
/*The reset can be set in the signal function.
* In case of reset query ignore the remaining parts.*/
if(state->last_obj != NULL && state->reset_query == 0) {
indev_drag_throw(state);
if(state->reset_query != 0) return;
}
}
/**
* Search the most top, clickable object on the last point of an input device
* @param indev pointer to an input device
* @param obj pointer to a start object, typically the screen
* @return pointer to the found object or NULL if there was no suitable object
*/
static lv_obj_t * indev_search_obj(const lv_indev_proc_t * indev, lv_obj_t * obj)
{
lv_obj_t * found_p = NULL;
/*If the point is on this object*/
/*Check its children too*/
if(lv_area_is_point_on(&obj->coords, &indev->act_point)) {
lv_obj_t * i;
LL_READ(obj->child_ll, i) {
found_p = indev_search_obj(indev, i);
/*If a child was found then break*/
if(found_p != NULL) {
break;
}
}
/*If then the children was not ok, and this obj is clickable
* and it or its parent is not hidden then save this object*/
if(found_p == NULL && lv_obj_get_click(obj) != false) {
lv_obj_t * hidden_i = obj;
while(hidden_i != NULL) {
if(lv_obj_get_hidden(hidden_i) == true) break;
hidden_i = lv_obj_get_parent(hidden_i);
}
/*No parent found with hidden == true*/
if(hidden_i == NULL) found_p = obj;
}
}
return found_p;
}
/**
* Handle the dragging of indev_proc_p->act_obj
* @param indev pointer to a input device state
*/
static void indev_drag(lv_indev_proc_t * state)
{
lv_obj_t * drag_obj = state->act_obj;
/*If drag parent is active check recursively the drag_parent attribute*/
while(lv_obj_get_drag_parent(drag_obj) != false &&
drag_obj != NULL) {
drag_obj = lv_obj_get_parent(drag_obj);
}
if(drag_obj == NULL) return;
if(lv_obj_get_drag(drag_obj) == false) return;
/*If still there is no drag then count the movement*/
if(state->drag_range_out == 0) {
state->drag_sum.x += state->vect.x;
state->drag_sum.y += state->vect.y;
/*If a move is greater then LV_DRAG_LIMIT then begin the drag*/
if(LV_MATH_ABS(state->drag_sum.x) >= LV_INDEV_DRAG_LIMIT ||
LV_MATH_ABS(state->drag_sum.y) >= LV_INDEV_DRAG_LIMIT)
{
state->drag_range_out = 1;
}
}
/*If the drag limit is stepped over then handle the dragging*/
if(state->drag_range_out != 0) {
/*Set new position if the vector is not zero*/
if(state->vect.x != 0 ||
state->vect.y != 0) {
/*Get the coordinates of the object end modify them*/
lv_coord_t act_x = lv_obj_get_x(drag_obj);
lv_coord_t act_y = lv_obj_get_y(drag_obj);
lv_obj_set_pos(drag_obj, act_x + state->vect.x, act_y + state->vect.y);
/*Set the drag in progress flag if the object is really moved*/
if(lv_obj_get_x(drag_obj) != act_x || lv_obj_get_y(drag_obj) != act_y) {
if(state->drag_range_out != 0) { /*Send the drag begin signal on first move*/
drag_obj->signal_func(drag_obj, LV_SIGNAL_DRAG_BEGIN, indev_act);
if(state->reset_query != 0) return;
}
state->drag_in_prog = 1;
}
}
}
}
/**
* Handle throwing by drag if the drag is ended
* @param indev pointer to an input device state
*/
static void indev_drag_throw(lv_indev_proc_t * state)
{
if(state->drag_in_prog == 0) return;
/*Set new position if the vector is not zero*/
lv_obj_t * drag_obj = state->last_obj;
/*If drag parent is active check recursively the drag_parent attribute*/
while(lv_obj_get_drag_parent(drag_obj) != false &&
drag_obj != NULL) {
drag_obj = lv_obj_get_parent(drag_obj);
}
if(drag_obj == NULL) return;
/*Return if the drag throw is not enabled*/
if(lv_obj_get_drag_throw(drag_obj) == false ){
state->drag_in_prog = 0;
drag_obj->signal_func(drag_obj, LV_SIGNAL_DRAG_END, indev_act);
return;
}
/*Reduce the vectors*/
state->vect.x = state->vect.x * (100 -LV_INDEV_DRAG_THROW) / 100;
state->vect.y = state->vect.y * (100 -LV_INDEV_DRAG_THROW) / 100;
if(state->vect.x != 0 ||
state->vect.y != 0)
{
/*Get the coordinates and modify them*/
lv_coord_t act_x = lv_obj_get_x(drag_obj) + state->vect.x;
lv_coord_t act_y = lv_obj_get_y(drag_obj) + state->vect.y;
lv_obj_set_pos(drag_obj, act_x, act_y);
/*If non of the coordinates are changed then do not continue throwing*/
if((lv_obj_get_x(drag_obj) != act_x || state->vect.x == 0) &&
(lv_obj_get_y(drag_obj) != act_y || state->vect.y == 0)) {
state->drag_in_prog = 0;
state->vect.x = 0;
state->vect.y = 0;
drag_obj->signal_func(drag_obj, LV_SIGNAL_DRAG_END, indev_act);
}
}
/*If the vectors become 0 -> drag_in_prog = 0 and send a drag end signal*/
else {
state->drag_in_prog = 0;
drag_obj->signal_func(drag_obj, LV_SIGNAL_DRAG_END, indev_act);
}
}
#endif

View file

@ -0,0 +1,119 @@
/**
* @file lv_indev_proc.h
*
*/
#ifndef LV_INDEV_H
#define LV_INDEV_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include "lv_obj.h"
#include "../lv_hal/lv_hal_indev.h"
#include "../lv_core/lv_group.h"
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
/**
* Initialize the display input device subsystem
*/
void lv_indev_init(void);
/**
* Get the currently processed input device. Can be used in action functions too.
* @return pointer to the currently processed input device or NULL if no input device processing right now
*/
lv_indev_t * lv_indev_get_act(void);
/**
* Reset one or all input devices
* @param indev pointer to an input device to reset or NULL to reset all of them
*/
void lv_indev_reset(lv_indev_t * indev);
/**
* Reset the long press state of an input device
* @param indev_proc pointer to an input device
*/
void lv_indev_reset_lpr(lv_indev_t * indev);
/**
* Enable input devices device by type
* @param type Input device type
* @param enable true: enable this type; false: disable this type
*/
void lv_indev_enable(lv_hal_indev_type_t type, bool enable);
/**
* Set a cursor for a pointer input device
* @param indev pointer to an input device (type: 'LV_INDEV_TYPE_POINTER')
* @param cur_obj pointer to an object to be used as cursor
*/
void lv_indev_set_cursor(lv_indev_t *indev, lv_obj_t *cur_obj);
#if USE_LV_GROUP
/**
* Set a destination group for a keypad input device
* @param indev pointer to an input device (type: 'LV_INDEV_TYPE_KEYPAD')
* @param group point to a group
*/
void lv_indev_set_group(lv_indev_t *indev, lv_group_t *group);
#endif
/**
* Get the last point of an input device
* @param indev pointer to an input device
* @param point pointer to a point to store the result
*/
void lv_indev_get_point(lv_indev_t * indev, lv_point_t * point);
/**
* Check if there is dragging with an input device or not
* @param indev pointer to an input device
* @return true: drag is in progress
*/
bool lv_indev_is_dragging(lv_indev_t * indev);
/**
* Get the vector of dragging of an input device
* @param indev pointer to an input device
* @param point pointer to a point to store the vector
*/
void lv_indev_get_vect(lv_indev_t * indev, lv_point_t * point);
/**
* Get elapsed time since last press
* @param indev pointer to an input device (NULL to get the overall smallest inactivity)
* @return Elapsed ticks (milliseconds) since last press
*/
uint32_t lv_indev_get_inactive_time(lv_indev_t * indev);
/**
* Do nothing until the next release
* @param indev pointer to an input device
*/
void lv_indev_wait_release(lv_indev_t * indev);
/**********************
* MACROS
**********************/
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /*LV_INDEV_H*/

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,716 @@
/**
* @file lv_obj.h
*
*/
#ifndef LV_OBJ_H
#define LV_OBJ_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include "../../lv_conf.h"
#include <stddef.h>
#include <stdbool.h>
#include "lv_style.h"
#include "../lv_misc/lv_area.h"
#include "../lv_misc/lv_mem.h"
#include "../lv_misc/lv_ll.h"
#include "../lv_misc/lv_color.h"
/*********************
* DEFINES
*********************/
/*Error check of lv_conf.h*/
#if LV_HOR_RES == 0 || LV_VER_RES == 0
#error "LV: LV_HOR_RES and LV_VER_RES must be greater then 0"
#endif
#if LV_ANTIALIAS != 0 && LV_ANTIALIAS != 1
#error "LV: LV_ATIALIAS can be only 0 or 1"
#endif
#if LV_VDB_SIZE == 0 && LV_ANTIALIAS != 0
#error "LV: If LV_VDB_SIZE == 0 the antialaissing must be disabled"
#endif
#if LV_VDB_SIZE != 0 && LV_VDB_SIZE < LV_HOR_RES && LV_ANTIALIAS == 0
#error "LV: Small Virtual Display Buffer (lv_conf.h: LV_VDB_SIZE >= LV_HOR_RES)"
#endif
#if LV_VDB_SIZE != 0 && LV_VDB_SIZE < 2 *LV_HOR_RES && LV_ANTIALIAS != 0
#error "LV: Small Virtual Display Buffer (lv_conf.h: LV_VDB_SIZE >= (2 * LV_HOR_RES))"
#endif
#define LV_ANIM_IN 0x00 /*Animation to show an object. 'OR' it with lv_anim_builtin_t*/
#define LV_ANIM_OUT 0x80 /*Animation to hide an object. 'OR' it with lv_anim_builtin_t*/
#define LV_ANIM_DIR_MASK 0x80 /*ANIM_IN/ANIM_OUT mask*/
/**********************
* TYPEDEFS
**********************/
struct _lv_obj_t;
typedef enum
{
LV_DESIGN_DRAW_MAIN,
LV_DESIGN_DRAW_POST,
LV_DESIGN_COVER_CHK,
}lv_design_mode_t;
typedef bool (* lv_design_func_t) (struct _lv_obj_t * obj, const lv_area_t * mask_p, lv_design_mode_t mode);
typedef enum
{
LV_RES_INV = 0, /*Typically indicates that the object is deleted (become invalid) in the action function*/
LV_RES_OK, /*The object is valid (no deleted) after the action*/
}lv_res_t;
typedef enum
{
/*General signals*/
LV_SIGNAL_CLEANUP,
LV_SIGNAL_CHILD_CHG,
LV_SIGNAL_CORD_CHG,
LV_SIGNAL_STYLE_CHG,
LV_SIGNAL_REFR_EXT_SIZE,
/*Input device related*/
LV_SIGNAL_PRESSED,
LV_SIGNAL_PRESSING,
LV_SIGNAL_PRESS_LOST,
LV_SIGNAL_RELEASED,
LV_SIGNAL_LONG_PRESS,
LV_SIGNAL_LONG_PRESS_REP,
LV_SIGNAL_DRAG_BEGIN,
LV_SIGNAL_DRAG_END,
/*Group related*/
LV_SIGNAL_FOCUS,
LV_SIGNAL_DEFOCUS,
LV_SIGNAL_CONTROLL,
}lv_signal_t;
typedef lv_res_t (* lv_signal_func_t) (struct _lv_obj_t * obj, lv_signal_t sign, void * param);
typedef struct _lv_obj_t
{
struct _lv_obj_t * par; /*Pointer to the parent object*/
lv_ll_t child_ll; /*Linked list to store the children objects*/
lv_area_t coords; /*Coordinates of the object (x1, y1, x2, y2)*/
lv_signal_func_t signal_func; /*Object type specific signal function*/
lv_design_func_t design_func; /*Object type specific design function*/
void * ext_attr; /*Object type specific extended data*/
lv_style_t * style_p; /*Pointer to the object's style*/
#if LV_OBJ_FREE_PTR != 0
void * free_ptr; /*Application specific pointer (set it freely)*/
#endif
void * group_p; /*Pointer to the group of the object*/
/*Attributes and states*/
uint8_t click :1; /*1: Can be pressed by an input device*/
uint8_t drag :1; /*1: Enable the dragging*/
uint8_t drag_throw:1; /*1: Enable throwing with drag*/
uint8_t drag_parent :1; /*1: Parent will be dragged instead*/
uint8_t hidden :1; /*1: Object is hidden*/
uint8_t top :1; /*1: If the object or its children is clicked it goes to the foreground*/
uint8_t reserved :1;
uint8_t protect; /*Automatically happening actions can be prevented. 'OR'ed values from lv_obj_prot_t*/
lv_coord_t ext_size; /*EXTtend the size of the object in every direction. E.g. for shadow drawing*/
#ifdef LV_OBJ_FREE_NUM_TYPE
LV_OBJ_FREE_NUM_TYPE free_num; /*Application specific identifier (set it freely)*/
#endif
}lv_obj_t;
typedef lv_res_t (*lv_action_t) (struct _lv_obj_t * obj);
/*Protect some attributes (max. 8 bit)*/
typedef enum
{
LV_PROTECT_NONE = 0x00,
LV_PROTECT_CHILD_CHG = 0x01, /*Disable the child change signal. Used by the library*/
LV_PROTECT_PARENT = 0x02, /*Prevent automatic parent change (e.g. in lv_page)*/
LV_PROTECT_POS = 0x04, /*Prevent automatic positioning (e.g. in lv_cont layout)*/
LV_PROTECT_FOLLOW = 0x08, /*Prevent the object be followed in automatic ordering (e.g. in lv_cont PRETTY layout)*/
}lv_protect_t;
typedef enum
{
LV_ALIGN_CENTER = 0,
LV_ALIGN_IN_TOP_LEFT,
LV_ALIGN_IN_TOP_MID,
LV_ALIGN_IN_TOP_RIGHT,
LV_ALIGN_IN_BOTTOM_LEFT,
LV_ALIGN_IN_BOTTOM_MID,
LV_ALIGN_IN_BOTTOM_RIGHT,
LV_ALIGN_IN_LEFT_MID,
LV_ALIGN_IN_RIGHT_MID,
LV_ALIGN_OUT_TOP_LEFT,
LV_ALIGN_OUT_TOP_MID,
LV_ALIGN_OUT_TOP_RIGHT,
LV_ALIGN_OUT_BOTTOM_LEFT,
LV_ALIGN_OUT_BOTTOM_MID,
LV_ALIGN_OUT_BOTTOM_RIGHT,
LV_ALIGN_OUT_LEFT_TOP,
LV_ALIGN_OUT_LEFT_MID,
LV_ALIGN_OUT_LEFT_BOTTOM,
LV_ALIGN_OUT_RIGHT_TOP,
LV_ALIGN_OUT_RIGHT_MID,
LV_ALIGN_OUT_RIGHT_BOTTOM,
}lv_align_t;
typedef enum
{
LV_ANIM_NONE = 0,
LV_ANIM_FLOAT_TOP, /*Float from/to the top*/
LV_ANIM_FLOAT_LEFT, /*Float from/to the left*/
LV_ANIM_FLOAT_BOTTOM, /*Float from/to the bottom*/
LV_ANIM_FLOAT_RIGHT, /*Float from/to the right*/
LV_ANIM_GROW_H, /*Grow/shrink horizontally*/
LV_ANIM_GROW_V, /*Grow/shrink vertically*/
}lv_anim_builtin_t;
/**********************
* GLOBAL PROTOTYPES
**********************/
/**
* Init. the 'lv' library.
*/
void lv_init(void);
/*--------------------
* Create and delete
*-------------------*/
/**
* Create a basic object
* @param parent pointer to a parent object.
* If NULL then a screen will be created
* @param copy pointer to a base object, if not NULL then the new object will be copied from it
* @return pointer to the new object
*/
lv_obj_t * lv_obj_create(lv_obj_t * parent, lv_obj_t * copy);
/**
* Delete 'obj' and all of its children
* @param obj pointer to an object to delete
* @return LV_RES_INV because the object is deleted
*/
lv_res_t lv_obj_del(lv_obj_t * obj);
/**
* Delete all children of an object
* @param obj pointer to an object
*/
void lv_obj_clean(lv_obj_t *obj);
/**
* Mark the object as invalid therefore its current position will be redrawn by 'lv_refr_task'
* @param obj pointer to an object
*/
void lv_obj_invalidate(lv_obj_t * obj);
/*=====================
* Setter functions
*====================*/
/*--------------
* Screen set
*--------------*/
/**
* Load a new screen
* @param scr pointer to a screen
*/
void lv_scr_load(lv_obj_t * scr);
/*--------------------
* Parent/children set
*--------------------*/
/**
* Set a new parent for an object. Its relative position will be the same.
* @param obj pointer to an object
* @param parent pointer to the new parent object
*/
void lv_obj_set_parent(lv_obj_t * obj, lv_obj_t * parent);
/*--------------------
* Coordinate set
* ------------------*/
/**
* Set relative the position of an object (relative to the parent)
* @param obj pointer to an object
* @param x new distance from the left side of the parent
* @param y new distance from the top of the parent
*/
void lv_obj_set_pos(lv_obj_t * obj, lv_coord_t x, lv_coord_t y);
/**
* Set the x coordinate of a object
* @param obj pointer to an object
* @param x new distance from the left side from the parent
*/
void lv_obj_set_x(lv_obj_t * obj, lv_coord_t x);
/**
* Set the y coordinate of a object
* @param obj pointer to an object
* @param y new distance from the top of the parent
*/
void lv_obj_set_y(lv_obj_t * obj, lv_coord_t y);
/**
* Set the size of an object
* @param obj pointer to an object
* @param w new width
* @param h new height
*/
void lv_obj_set_size(lv_obj_t * obj, lv_coord_t w, lv_coord_t h);
/**
* Set the width of an object
* @param obj pointer to an object
* @param w new width
*/
void lv_obj_set_width(lv_obj_t * obj, lv_coord_t w);
/**
* Set the height of an object
* @param obj pointer to an object
* @param h new height
*/
void lv_obj_set_height(lv_obj_t * obj, lv_coord_t h);
/**
* Align an object to an other object.
* @param obj pointer to an object to align
* @param base pointer to an object (if NULL the parent is used). 'obj' will be aligned to it.
* @param align type of alignment (see 'lv_align_t' enum)
* @param x_mod x coordinate shift after alignment
* @param y_mod y coordinate shift after alignment
*/
void lv_obj_align(lv_obj_t * obj,lv_obj_t * base, lv_align_t align, lv_coord_t x_mod, lv_coord_t y_mod);
/*---------------------
* Appearance set
*--------------------*/
/**
* Set a new style for an object
* @param obj pointer to an object
* @param style_p pointer to the new style
*/
void lv_obj_set_style(lv_obj_t * obj, lv_style_t * style);
/**
* Notify an object about its style is modified
* @param obj pointer to an object
*/
void lv_obj_refresh_style(lv_obj_t * obj);
/**
* Notify all object if a style is modified
* @param style pointer to a style. Only the objects with this style will be notified
* (NULL to notify all objects)
*/
void lv_obj_report_style_mod(lv_style_t * style);
/*-----------------
* Attribute set
*----------------*/
/**
* Hide an object. It won't be visible and clickable.
* @param obj pointer to an object
* @param en true: hide the object
*/
void lv_obj_set_hidden(lv_obj_t * obj, bool en);
/**
* Enable or disable the clicking of an object
* @param obj pointer to an object
* @param en true: make the object clickable
*/
void lv_obj_set_click(lv_obj_t * obj, bool en);
/**
* Enable to bring this object to the foreground if it
* or any of its children is clicked
* @param obj pointer to an object
* @param en true: enable the auto top feature
*/
void lv_obj_set_top(lv_obj_t * obj, bool en);
/**
* Enable the dragging of an object
* @param obj pointer to an object
* @param en true: make the object dragable
*/
void lv_obj_set_drag(lv_obj_t * obj, bool en);
/**
* Enable the throwing of an object after is is dragged
* @param obj pointer to an object
* @param en true: enable the drag throw
*/
void lv_obj_set_drag_throw(lv_obj_t * obj, bool en);
/**
* Enable to use parent for drag related operations.
* If trying to drag the object the parent will be moved instead
* @param obj pointer to an object
* @param en true: enable the 'drag parent' for the object
*/
void lv_obj_set_drag_parent(lv_obj_t * obj, bool en);
/**
* Set a bit or bits in the protect filed
* @param obj pointer to an object
* @param prot 'OR'-ed values from lv_obj_prot_t
*/
void lv_obj_set_protect(lv_obj_t * obj, uint8_t prot);
/**
* Clear a bit or bits in the protect filed
* @param obj pointer to an object
* @param prot 'OR'-ed values from lv_obj_prot_t
*/
void lv_obj_clear_protect(lv_obj_t * obj, uint8_t prot);
/**
* Set the signal function of an object.
* Always call the previous signal function in the new.
* @param obj pointer to an object
* @param fp the new signal function
*/
void lv_obj_set_signal_func(lv_obj_t * obj, lv_signal_func_t fp);
/**
* Set a new design function for an object
* @param obj pointer to an object
* @param fp the new design function
*/
void lv_obj_set_design_func(lv_obj_t * obj, lv_design_func_t fp);
/*----------------
* Other set
*--------------*/
/**
* Allocate a new ext. data for an object
* @param obj pointer to an object
* @param ext_size the size of the new ext. data
* @return Normal pointer to the allocated ext
*/
void * lv_obj_allocate_ext_attr(lv_obj_t * obj, uint16_t ext_size);
/**
* Send a 'LV_SIGNAL_REFR_EXT_SIZE' signal to the object
* @param obj pointer to an object
*/
void lv_obj_refresh_ext_size(lv_obj_t * obj);
#ifdef LV_OBJ_FREE_NUM_TYPE
/**
* Set an application specific number for an object.
* It can help to identify objects in the application.
* @param obj pointer to an object
* @param free_num the new free number
*/
void lv_obj_set_free_num(lv_obj_t * obj, LV_OBJ_FREE_NUM_TYPE free_num);
#endif
#if LV_OBJ_FREE_PTR != 0
/**
* Set an application specific pointer for an object.
* It can help to identify objects in the application.
* @param obj pointer to an object
* @param free_p the new free pinter
*/
void lv_obj_set_free_ptr(lv_obj_t * obj, void * free_p);
#endif
#if USE_LV_ANIMATION
/**
* Animate an object
* @param obj pointer to an object to animate
* @param type type of animation from 'lv_anim_builtin_t'. 'OR' it with ANIM_IN or ANIM_OUT
* @param time time of animation in milliseconds
* @param delay delay before the animation in milliseconds
* @param cb a function to call when the animation is ready
*/
void lv_obj_animate(lv_obj_t * obj, lv_anim_builtin_t type, uint16_t time, uint16_t delay, void (*cb) (lv_obj_t *));
#endif
/*=======================
* Getter functions
*======================*/
/*------------------
* Screen get
*-----------------*/
/**
* Return with a pointer to the active screen
* @return pointer to the active screen object (loaded by 'lv_scr_load()')
*/
lv_obj_t * lv_scr_act(void);
/**
* Return with the top layer. (Same on every screen and it is above the normal screen layer)
* @return pointer to the top layer object (transparent screen sized lv_obj)
*/
lv_obj_t * lv_layer_top(void);
/**
* Return with the system layer. (Same on every screen and it is above the all other layers)
* It is used for example by the cursor
* @return pointer to the system layer object (transparent screen sized lv_obj)
*/
lv_obj_t * lv_layer_sys(void);
/**
* Return with the screen of an object
* @param obj pointer to an object
* @return pointer to a screen
*/
lv_obj_t * lv_obj_get_screen(lv_obj_t * obj);
/*---------------------
* Parent/children get
*--------------------*/
/**
* Returns with the parent of an object
* @param obj pointer to an object
* @return pointer to the parent of 'obj'
*/
lv_obj_t * lv_obj_get_parent(lv_obj_t * obj);
/**
* Iterate through the children of an object (start from the "youngest, lastly created")
* @param obj pointer to an object
* @param child NULL at first call to get the next children
* and the previous return value later
* @return the child after 'act_child' or NULL if no more child
*/
lv_obj_t * lv_obj_get_child(lv_obj_t * obj, lv_obj_t * child);
/**
* Iterate through the children of an object (start from the "oldest", firstly created)
* @param obj pointer to an object
* @param child NULL at first call to get the next children
* and the previous return value later
* @return the child after 'act_child' or NULL if no more child
*/
lv_obj_t * lv_obj_get_child_back(lv_obj_t * obj, lv_obj_t * child);
/**
* Count the children of an object (only children directly on 'obj')
* @param obj pointer to an object
* @return children number of 'obj'
*/
uint16_t lv_obj_count_children(lv_obj_t * obj);
/*---------------------
* Coordinate get
*--------------------*/
/**
* Copy the coordinates of an object to an area
* @param obj pointer to an object
* @param cords_p pointer to an area to store the coordinates
*/
void lv_obj_get_coords(lv_obj_t * obj, lv_area_t * cords_p);
/**
* Get the x coordinate of object
* @param obj pointer to an object
* @return distance of 'obj' from the left side of its parent
*/
lv_coord_t lv_obj_get_x(lv_obj_t * obj);
/**
* Get the y coordinate of object
* @param obj pointer to an object
* @return distance of 'obj' from the top of its parent
*/
lv_coord_t lv_obj_get_y(lv_obj_t * obj);
/**
* Get the width of an object
* @param obj pointer to an object
* @return the width
*/
lv_coord_t lv_obj_get_width(lv_obj_t * obj);
/**
* Get the height of an object
* @param obj pointer to an object
* @return the height
*/
lv_coord_t lv_obj_get_height(lv_obj_t * obj);
/**
* Get the extended size attribute of an object
* @param obj pointer to an object
* @return the extended size attribute
*/
lv_coord_t lv_obj_get_ext_size(lv_obj_t * obj);
/*-----------------
* Appearance get
*---------------*/
/**
* Get the style pointer of an object (if NULL get style of the parent)
* @param obj pointer to an object
* @return pointer to a style
*/
lv_style_t * lv_obj_get_style(lv_obj_t * obj);
/*-----------------
* Attribute get
*----------------*/
/**
* Get the hidden attribute of an object
* @param obj pointer to an object
* @return true: the object is hidden
*/
bool lv_obj_get_hidden(lv_obj_t * obj);
/**
* Get the click enable attribute of an object
* @param obj pointer to an object
* @return true: the object is clickable
*/
bool lv_obj_get_click(lv_obj_t * obj);
/**
* Get the top enable attribute of an object
* @param obj pointer to an object
* @return true: the auto top feture is enabled
*/
bool lv_obj_get_top(lv_obj_t * obj);
/**
* Get the drag enable attribute of an object
* @param obj pointer to an object
* @return true: the object is dragable
*/
bool lv_obj_get_drag(lv_obj_t * obj);
/**
* Get the drag thow enable attribute of an object
* @param obj pointer to an object
* @return true: drag throw is enabled
*/
bool lv_obj_get_drag_throw(lv_obj_t * obj);
/**
* Get the drag parent attribute of an object
* @param obj pointer to an object
* @return true: drag parent is enabled
*/
bool lv_obj_get_drag_parent(lv_obj_t * obj);
/**
* Get the protect field of an object
* @param obj pointer to an object
* @return protect field ('OR'ed values of lv_obj_prot_t)
*/
uint8_t lv_obj_get_protect(lv_obj_t * obj);
/**
* Check at least one bit of a given protect bitfield is set
* @param obj pointer to an object
* @param prot protect bits to test ('OR'ed values of lv_obj_prot_t)
* @return false: none of the given bits are set, true: at least one bit is set
*/
bool lv_obj_is_protected(lv_obj_t * obj, uint8_t prot);
/**
* Get the signal function of an object
* @param obj pointer to an object
* @return the signal function
*/
lv_signal_func_t lv_obj_get_signal_func(lv_obj_t * obj);
/**
* Get the design function of an object
* @param obj pointer to an object
* @return the design function
*/
lv_design_func_t lv_obj_get_design_func(lv_obj_t * obj);
/*------------------
* Other get
*-----------------*/
/**
* Get the ext pointer
* @param obj pointer to an object
* @return the ext pointer but not the dynamic version
* Use it as ext->data1, and NOT da(ext)->data1
*/
void * lv_obj_get_ext_attr(lv_obj_t * obj);
#ifdef LV_OBJ_FREE_NUM_TYPE
/**
* Get the free number
* @param obj pointer to an object
* @return the free number
*/
LV_OBJ_FREE_NUM_TYPE lv_obj_get_free_num(lv_obj_t * obj);
#endif
#if LV_OBJ_FREE_PTR != 0
/**
* Get the free pointer
* @param obj pointer to an object
* @return the free pointer
*/
void * lv_obj_get_free_ptr(lv_obj_t * obj);
#endif
#if USE_LV_GROUP
/**
* Get the group of the object
* @param obj pointer to an object
* @return the pointer to group of the object
*/
void * lv_obj_get_group(lv_obj_t * obj);
#endif
/**********************
* MACROS
**********************/
#define LV_SCALE(x) (x << LV_ANTIALIAS)
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /*LV_OBJ_H*/

View file

@ -0,0 +1,488 @@
/**
* @file lv_refr.c
*
*/
/*********************
* INCLUDES
*********************/
#include "../../lv_conf.h"
#include <stddef.h>
#include "lv_refr.h"
#include "lv_vdb.h"
#include "../lv_hal/lv_hal_tick.h"
#include "../lv_misc/lv_task.h"
#include "../lv_misc/lv_mem.h"
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
typedef struct
{
lv_area_t area;
uint8_t joined;
}lv_join_t;
/**********************
* STATIC PROTOTYPES
**********************/
static void lv_refr_task(void * param);
static void lv_refr_join_area(void);
static void lv_refr_areas(void);
#if LV_VDB_SIZE == 0
static void lv_refr_area_no_vdb(const lv_area_t * area_p);
#else
static void lv_refr_area_with_vdb(const lv_area_t * area_p);
static void lv_refr_area_part_vdb(const lv_area_t * area_p);
#endif
static lv_obj_t * lv_refr_get_top_obj(const lv_area_t * area_p, lv_obj_t * obj);
static void lv_refr_obj_and_children(lv_obj_t * top_p, const lv_area_t * mask_p);
static void lv_refr_obj(lv_obj_t * obj, const lv_area_t * mask_ori_p);
/**********************
* STATIC VARIABLES
**********************/
static lv_join_t inv_buf[LV_INV_FIFO_SIZE];
static uint16_t inv_buf_p;
static void (*monitor_cb)(uint32_t, uint32_t);
static uint32_t px_num;
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
/**
* Initialize the screen refresh subsystem
*/
void lv_refr_init(void)
{
inv_buf_p = 0;
memset(inv_buf, 0, sizeof(inv_buf));
lv_task_t* task;
task = lv_task_create(lv_refr_task, LV_REFR_PERIOD, LV_TASK_PRIO_MID, NULL);
lv_mem_assert(task);
}
/**
* Invalidate an area
* @param area_p pointer to area which should be invalidated
*/
void lv_inv_area(const lv_area_t * area_p)
{
/*Clear the invalidate buffer if the parameter is NULL*/
if(area_p == NULL) {
inv_buf_p = 0;
return;
}
lv_area_t scr_area;
scr_area.x1 = 0;
scr_area.y1 = 0;
scr_area.x2 = LV_HOR_RES - 1;
scr_area.y2 = LV_VER_RES - 1;
lv_area_t com_area;
bool suc;
suc = lv_area_union(&com_area, area_p, &scr_area);
/*The area is truncated to the screen*/
if(suc != false)
{
#if LV_ANTIALIAS == 1
/*Rounding*/
com_area.x1 = com_area.x1 & (~0x1);
com_area.y1 = com_area.y1 & (~0x1);
com_area.x2 = com_area.x2 | 0x1;
com_area.y2 = com_area.y2 | 0x1;
#endif
/*Save only if this area is not in one of the saved areas*/
uint16_t i;
for(i = 0; i < inv_buf_p; i++) {
if(lv_area_is_in(&com_area, &inv_buf[i].area) != false) return;
}
/*Save the area*/
if(inv_buf_p < LV_INV_FIFO_SIZE) {
lv_area_copy(&inv_buf[inv_buf_p].area,&com_area);
} else {/*If no place for the area add the screen*/
inv_buf_p = 0;
lv_area_copy(&inv_buf[inv_buf_p].area,&scr_area);
}
inv_buf_p ++;
}
}
/**
* Set a function to call after every refresh to announce the refresh time and the number of refreshed pixels
* @param cb pointer to a callback function (void my_refr_cb(uint32_t time_ms, uint32_t px_num))
* time_ms: refresh time in [ms]
* px_num: not the drawn pixels but the number of affected pixels of the screen
* (more pixels are drawn because of overlapping objects)
*/
void lv_refr_set_monitor_cb(void (*cb)(uint32_t, uint32_t))
{
monitor_cb = cb;
}
/**********************
* STATIC FUNCTIONS
**********************/
/**
* Called periodically to handle the refreshing
* @param param unused
*/
static void lv_refr_task(void * param)
{
(void)param;
uint32_t start = lv_tick_get();
lv_refr_join_area();
lv_refr_areas();
bool refr_done = false;
if(inv_buf_p != 0) refr_done = true;
memset(inv_buf, 0, sizeof(inv_buf));
inv_buf_p = 0;
/* In the callback lv_obj_inv can occur
* therefore be sure the inv_buf is cleared prior to it*/
if(refr_done != false) {
if(monitor_cb != NULL) {
monitor_cb(lv_tick_elaps(start), px_num);
}
}
}
/**
* Join the areas which has got common parts
*/
static void lv_refr_join_area(void)
{
uint32_t join_from;
uint32_t join_in;
lv_area_t joined_area;
for(join_in = 0; join_in < inv_buf_p; join_in++) {
if(inv_buf[join_in].joined != 0) continue;
/*Check all areas to join them in 'join_in'*/
for(join_from = 0; join_from < inv_buf_p; join_from++) {
/*Handle only unjoined areas and ignore itself*/
if(inv_buf[join_from].joined != 0 || join_in == join_from) {
continue;
}
/*Check if the areas are on each other*/
if(lv_area_is_on(&inv_buf[join_in].area,
&inv_buf[join_from].area) == false)
{
continue;
}
lv_area_join(&joined_area, &inv_buf[join_in].area,
&inv_buf[join_from].area);
/*Join two area only if the joined area size is smaller*/
if(lv_area_get_size(&joined_area) <
(lv_area_get_size(&inv_buf[join_in].area) + lv_area_get_size(&inv_buf[join_from].area))) {
lv_area_copy(&inv_buf[join_in].area, &joined_area);
/*Mark 'join_form' is joined into 'join_in'*/
inv_buf[join_from].joined = 1;
}
}
}
}
/**
* Refresh the joined areas
*/
static void lv_refr_areas(void)
{
px_num = 0;
uint32_t i;
for(i = 0; i < inv_buf_p; i++) {
/*Refresh the unjoined areas*/
if(inv_buf[i].joined == 0) {
/*If there is no VDB do simple drawing*/
#if LV_VDB_SIZE == 0
lv_refr_area_no_vdb(&inv_buf[i].area);
#else
/*If VDB is used...*/
lv_refr_area_with_vdb(&inv_buf[i].area);
#endif
if(monitor_cb != NULL) px_num += lv_area_get_size(&inv_buf[i].area);
}
}
}
#if LV_VDB_SIZE == 0
/**
* Refresh an area if there is no Virtual Display Buffer
* @param area_p pointer to an area to refresh
*/
static void lv_refr_area_no_vdb(const lv_area_t * area_p)
{
lv_obj_t * top_p;
/*Get top object which is not covered by others*/
top_p = lv_refr_get_top_obj(area_p, lv_scr_act());
/*Do the refreshing*/
lv_refr_obj_and_children(top_p, area_p);
}
#else
/**
* Refresh an area if there is Virtual Display Buffer
* @param area_p pointer to an area to refresh
*/
static void lv_refr_area_with_vdb(const lv_area_t * area_p)
{
/*Calculate the max row num*/
lv_coord_t w = lv_area_get_width(area_p);
lv_coord_t h = lv_area_get_height(area_p);
lv_coord_t y2 = area_p->y2 >= LV_VER_RES ? y2 = LV_VER_RES - 1 : area_p->y2;
uint32_t max_row = (uint32_t) LV_VDB_SIZE / (w << LV_AA);
if(max_row > (h << LV_AA)) max_row = (h << LV_AA);
max_row = max_row >> LV_AA ;
/*Always use the full row*/
uint32_t row;
lv_coord_t row_last = 0;
for(row = area_p->y1; row + max_row - 1 <= y2; row += max_row) {
lv_vdb_t * vdb_p = lv_vdb_get();
/*Calc. the next y coordinates of VDB*/
vdb_p->area.x1 = area_p->x1;
vdb_p->area.x2 = area_p->x2;
vdb_p->area.y1 = row;
vdb_p->area.y2 = row + max_row - 1;
if(vdb_p->area.y2 > y2) vdb_p->area.y2 = y2;
row_last = vdb_p->area.y2;
lv_refr_area_part_vdb(area_p);
}
/*If the last y coordinates are not handled yet ...*/
if(y2 != row_last) {
lv_vdb_t * vdb_p = lv_vdb_get();
/*Calc. the next y coordinates of VDB*/
vdb_p->area.x1 = area_p->x1;
vdb_p->area.x2 = area_p->x2;
vdb_p->area.y1 = row;
vdb_p->area.y2 = y2;
/*Refresh this part too*/
lv_refr_area_part_vdb(area_p);
}
}
/**
* Refresh a part of an area which is on the actual Virtual Display Buffer
* @param area_p pointer to an area to refresh
*/
static void lv_refr_area_part_vdb(const lv_area_t * area_p)
{
lv_vdb_t * vdb_p = lv_vdb_get();
lv_obj_t * top_p;
/*Get the new mask from the original area and the act. VDB
It will be a part of 'area_p'*/
lv_area_t start_mask;
lv_area_union(&start_mask, area_p, &vdb_p->area);
#if LV_ANTIALIAS
vdb_p->area.x1 = vdb_p->area.x1 << LV_AA;
vdb_p->area.x2 = (vdb_p->area.x2 << LV_AA) + 1;
vdb_p->area.y1 = (vdb_p->area.y1 << LV_AA);
vdb_p->area.y2 = (vdb_p->area.y2 << LV_AA) + 1;
#endif
/*Get the most top object which is not covered by others*/
top_p = lv_refr_get_top_obj(&start_mask, lv_scr_act());
/*Do the refreshing from the top object*/
lv_refr_obj_and_children(top_p, &start_mask);
/*Also refresh top and sys layer unconditionally*/
lv_refr_obj_and_children(lv_layer_top(), &start_mask);
lv_refr_obj_and_children(lv_layer_sys(), &start_mask);
/*Flush the content of the VDB*/
lv_vdb_flush();
}
#endif /*LV_VDB_SIZE == 0*/
/**
* Search the most top object which fully covers an area
* @param area_p pointer to an area
* @param obj the first object to start the searching (typically a screen)
* @return
*/
static lv_obj_t * lv_refr_get_top_obj(const lv_area_t * area_p, lv_obj_t * obj)
{
lv_obj_t * i;
lv_obj_t * found_p = NULL;
/*If this object is fully cover the draw area check the children too */
if(lv_area_is_in(area_p, &obj->coords) && obj->hidden == 0)
{
LL_READ(obj->child_ll, i) {
found_p = lv_refr_get_top_obj(area_p, i);
/*If a children is ok then break*/
if(found_p != NULL) {
break;
}
}
/*If no better children check this object*/
if(found_p == NULL) {
lv_style_t * style = lv_obj_get_style(obj);
if(style->body.opa == LV_OPA_COVER &&
obj->design_func(obj, area_p, LV_DESIGN_COVER_CHK) != false) {
found_p = obj;
}
}
}
return found_p;
}
/**
* Make the refreshing from an object. Draw all its children and the youngers too.
* @param top_p pointer to an objects. Start the drawing from it.
* @param mask_p pointer to an area, the objects will be drawn only here
*/
static void lv_refr_obj_and_children(lv_obj_t * top_p, const lv_area_t * mask_p)
{
/* Normally always will be a top_obj (at least the screen)
* but in special cases (e.g. if the screen has alpha) it won't.
* In this case use the screen directly */
if(top_p == NULL) top_p = lv_scr_act();
/*Refresh the top object and its children*/
lv_refr_obj(top_p, mask_p);
/*Draw the 'younger' sibling objects because they can be on top_obj */
lv_obj_t * par;
lv_obj_t * i;
lv_obj_t * border_p = top_p;
par = lv_obj_get_parent(top_p);
/*Do until not reach the screen*/
while(par != NULL) {
/*object before border_p has to be redrawn*/
i = lv_ll_get_prev(&(par->child_ll), border_p);
while(i != NULL) {
/*Refresh the objects*/
lv_refr_obj(i, mask_p);
i = lv_ll_get_prev(&(par->child_ll), i);
}
/*The new border will be there last parents,
*so the 'younger' brothers of parent will be refreshed*/
border_p = par;
/*Go a level deeper*/
par = lv_obj_get_parent(par);
}
/*Call the post draw design function of the parents of the to object*/
par = lv_obj_get_parent(top_p);
while(par != NULL) {
par->design_func(par, mask_p, LV_DESIGN_DRAW_POST);
par = lv_obj_get_parent(par);
}
}
/**
* Refresh an object an all of its children. (Called recursively)
* @param obj pointer to an object to refresh
* @param mask_ori_p pointer to an area, the objects will be drawn only here
*/
static void lv_refr_obj(lv_obj_t * obj, const lv_area_t * mask_ori_p)
{
/*Do not refresh hidden objects*/
if(obj->hidden != 0) return;
bool union_ok; /* Store the return value of area_union */
/* Truncate the original mask to the coordinates of the parent
* because the parent and its children are visible only here */
lv_area_t obj_mask;
lv_area_t obj_ext_mask;
lv_area_t obj_area;
lv_coord_t ext_size = obj->ext_size;
lv_obj_get_coords(obj, &obj_area);
obj_area.x1 -= ext_size;
obj_area.y1 -= ext_size;
obj_area.x2 += ext_size;
obj_area.y2 += ext_size;
union_ok = lv_area_union(&obj_ext_mask, mask_ori_p, &obj_area);
/*Draw the parent and its children only if they ore on 'mask_parent'*/
if(union_ok != false) {
/* Redraw the object */
lv_style_t * style = lv_obj_get_style(obj);
if(style->body.opa != LV_OPA_TRANSP) {
obj->design_func(obj, &obj_ext_mask, LV_DESIGN_DRAW_MAIN);
//tick_wait_ms(100); /*DEBUG: Wait after every object draw to see the order of drawing*/
}
/*Create a new 'obj_mask' without 'ext_size' because the children can't be visible there*/
lv_obj_get_coords(obj, &obj_area);
union_ok = lv_area_union(&obj_mask, mask_ori_p, &obj_area);
if(union_ok != false) {
lv_area_t mask_child; /*Mask from obj and its child*/
lv_obj_t * child_p;
lv_area_t child_area;
LL_READ_BACK(obj->child_ll, child_p)
{
lv_obj_get_coords(child_p, &child_area);
ext_size = child_p->ext_size;
child_area.x1 -= ext_size;
child_area.y1 -= ext_size;
child_area.x2 += ext_size;
child_area.y2 += ext_size;
/* Get the union (common parts) of original mask (from obj)
* and its child */
union_ok = lv_area_union(&mask_child, &obj_mask, &child_area);
/*If the parent and the child has common area then refresh the child */
if(union_ok) {
/*Refresh the next children*/
lv_refr_obj(child_p, &mask_child);
}
}
}
/* If all the children are redrawn make 'post draw' design */
if(style->body.opa != LV_OPA_TRANSP) {
obj->design_func(obj, &obj_ext_mask, LV_DESIGN_DRAW_POST);
}
}
}

View file

@ -0,0 +1,70 @@
/**
* @file lv_refr.h
*
*/
#ifndef LV_REFR_H
#define LV_REFR_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include "lv_obj.h"
#include <stdbool.h>
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
/**********************
* STATIC VARIABLES
**********************/
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
/**
* Initialize the screen refresh subsystem
*/
void lv_refr_init(void);
/**
* Invalidate an area
* @param area_p pointer to area which should be invalidated
*/
void lv_inv_area(const lv_area_t * area_p);
/**
* Set a function to call after every refresh to announce the refresh time and the number of refreshed pixels
* @param cb pointer to a callback function (void my_refr_cb(uint32_t time_ms, uint32_t px_num))
*/
void lv_refr_set_monitor_cb(void (*cb)(uint32_t, uint32_t));
/**********************
* STATIC FUNCTIONS
**********************/
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /*LV_REFR_H*/

View file

@ -0,0 +1,319 @@
/**
* @file lv_style.c
*
*/
/*********************
* INCLUDES
*********************/
#include "../../lv_conf.h"
#include "lv_style.h"
#include "lv_obj.h"
#include "../lv_misc/lv_mem.h"
/*********************
* DEFINES
*********************/
#if USE_LV_ANIMATION
#define LV_STYLE_ANIM_RES 256
#define LV_STYLE_ANIM_SHIFT 8 /*log2(LV_STYLE_ANIM_RES)*/
#define VAL_PROP(v1, v2, r) v1 + (((v2-v1) * r) >> LV_STYLE_ANIM_SHIFT)
#define STYLE_ATTR_ANIM(attr, r) if(start->attr != end->attr) act->attr = VAL_PROP(start->attr, end->attr, r)
#endif
/**********************
* TYPEDEFS
**********************/
#if USE_LV_ANIMATION
typedef struct {
lv_style_t style_start; /*Save not only pointers because can be same as 'style_anim' then it will be modified too*/
lv_style_t style_end;
lv_style_t *style_anim;
void (*end_cb)(void *);
}lv_style_anim_dsc_t;
#endif
/**********************
* STATIC PROTOTYPES
**********************/
#if USE_LV_ANIMATION
static void style_animator(lv_style_anim_dsc_t * dsc, int32_t val);
static void style_animation_common_end_cb(void *ptr);
#endif
/**********************
* STATIC VARIABLES
**********************/
lv_style_t lv_style_scr;
lv_style_t lv_style_transp;
lv_style_t lv_style_transp_fit;
lv_style_t lv_style_transp_tight;
lv_style_t lv_style_plain;
lv_style_t lv_style_plain_color;
lv_style_t lv_style_pretty;
lv_style_t lv_style_pretty_color;
lv_style_t lv_style_btn_rel;
lv_style_t lv_style_btn_pr;
lv_style_t lv_style_btn_tgl_rel;
lv_style_t lv_style_btn_tgl_pr;
lv_style_t lv_style_btn_ina;
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
/**
* Init the basic styles
*/
void lv_style_init (void)
{
/* Not White/Black/Gray colors are created by HSV model with
* HUE = 210*/
/*Screen style*/
lv_style_scr.glass = 0;
lv_style_scr.body.opa = LV_OPA_COVER;
lv_style_scr.body.main_color = LV_COLOR_WHITE;
lv_style_scr.body.grad_color = LV_COLOR_WHITE;
lv_style_scr.body.radius = 0;
lv_style_scr.body.padding.ver = LV_DPI / 12;
lv_style_scr.body.padding.hor = LV_DPI / 12;
lv_style_scr.body.padding.inner = LV_DPI / 12;
lv_style_scr.body.border.color = LV_COLOR_BLACK;
lv_style_scr.body.border.opa = LV_OPA_COVER;
lv_style_scr.body.border.width = 0;
lv_style_scr.body.border.part = LV_BORDER_FULL;
lv_style_scr.body.shadow.color = LV_COLOR_GRAY;
lv_style_scr.body.shadow.type = LV_SHADOW_FULL;
lv_style_scr.body.shadow.width = 0;
lv_style_scr.text.opa = LV_OPA_COVER;
lv_style_scr.text.color = LV_COLOR_MAKE(0x30, 0x30, 0x30);
lv_style_scr.text.font = LV_FONT_DEFAULT;
lv_style_scr.text.letter_space = 2;
lv_style_scr.text.line_space = 2;
lv_style_scr.image.opa = LV_OPA_COVER;
lv_style_scr.image.color = LV_COLOR_MAKE(0x20, 0x20, 0x20);
lv_style_scr.image.intense = LV_OPA_TRANSP;
lv_style_scr.line.opa = LV_OPA_COVER;
lv_style_scr.line.color = LV_COLOR_MAKE(0x20, 0x20, 0x20);
lv_style_scr.line.width = 1;
/*Plain style (by default near the same as the screen style)*/
memcpy(&lv_style_plain, &lv_style_scr, sizeof(lv_style_t));
/*Plain color style*/
memcpy(&lv_style_plain_color, &lv_style_plain, sizeof(lv_style_t));
lv_style_plain_color.text.color = LV_COLOR_MAKE(0xf0, 0xf0, 0xf0);
lv_style_plain_color.image.color = LV_COLOR_MAKE(0xf0, 0xf0, 0xf0);
lv_style_plain_color.line.color = LV_COLOR_MAKE(0xf0, 0xf0, 0xf0);
lv_style_plain_color.body.main_color = LV_COLOR_MAKE(0x55, 0x96, 0xd8);
lv_style_plain_color.body.grad_color = lv_style_plain_color.body.main_color;
/*Pretty style */
memcpy(&lv_style_pretty, &lv_style_plain, sizeof(lv_style_t));
lv_style_pretty.text.color = LV_COLOR_MAKE(0x20, 0x20, 0x20);
lv_style_pretty.image.color = LV_COLOR_MAKE(0x20, 0x20, 0x20);
lv_style_pretty.line.color = LV_COLOR_MAKE(0x20, 0x20, 0x20);
lv_style_pretty.body.main_color = LV_COLOR_WHITE;
lv_style_pretty.body.grad_color = LV_COLOR_SILVER;
lv_style_pretty.body.radius = LV_DPI / 15;
lv_style_pretty.body.border.color = LV_COLOR_MAKE(0x40, 0x40, 0x40);
lv_style_pretty.body.border.width = LV_DPI / 50 >= 1 ? LV_DPI / 50 : 1;
lv_style_pretty.body.border.opa = LV_OPA_30;
/*Pretty color style*/
memcpy(&lv_style_pretty_color, &lv_style_pretty, sizeof(lv_style_t));
lv_style_pretty_color.text.color = LV_COLOR_MAKE(0xe0, 0xe0, 0xe0);
lv_style_pretty_color.image.color = LV_COLOR_MAKE(0xe0, 0xe0, 0xe0);
lv_style_pretty_color.line.color = LV_COLOR_MAKE(0xc0, 0xc0, 0xc0);
lv_style_pretty_color.body.main_color = LV_COLOR_MAKE(0x6b, 0x9a, 0xc7);
lv_style_pretty_color.body.grad_color = LV_COLOR_MAKE(0x2b, 0x59, 0x8b);
lv_style_pretty_color.body.border.color = LV_COLOR_MAKE(0x15, 0x2c, 0x42);
/*Transparent style*/
memcpy(&lv_style_transp, &lv_style_plain, sizeof(lv_style_t));
lv_style_transp.body.empty = 1;
lv_style_transp.glass = 1;
lv_style_transp.body.border.width = 0;
/*Transparent tight style*/
memcpy(&lv_style_transp_fit, &lv_style_transp, sizeof(lv_style_t));
lv_style_transp_fit.body.padding.hor = 0;
lv_style_transp_fit.body.padding.ver = 0;
/*Transparent fitting size*/
memcpy(&lv_style_transp_tight, &lv_style_transp_fit, sizeof(lv_style_t));
lv_style_transp_tight.body.padding.inner = 0;
/*Button released style*/
memcpy(&lv_style_btn_rel, &lv_style_plain, sizeof(lv_style_t));
lv_style_btn_rel.body.main_color = LV_COLOR_MAKE(0x76, 0xa2, 0xd0);
lv_style_btn_rel.body.grad_color = LV_COLOR_MAKE(0x19, 0x3a, 0x5d);
lv_style_btn_rel.body.radius = LV_DPI / 15;
lv_style_btn_rel.body.padding.hor = LV_DPI / 4;
lv_style_btn_rel.body.padding.ver = LV_DPI / 6;
lv_style_btn_rel.body.padding.inner = LV_DPI / 10;
lv_style_btn_rel.body.border.color = LV_COLOR_MAKE(0x0b, 0x19, 0x28);
lv_style_btn_rel.body.border.width = LV_DPI / 50 >= 1 ? LV_DPI / 50 : 1;
lv_style_btn_rel.body.border.opa = LV_OPA_70;
lv_style_btn_rel.text.color = LV_COLOR_MAKE(0xff, 0xff, 0xff);
lv_style_btn_rel.body.shadow.color = LV_COLOR_GRAY;
lv_style_btn_rel.body.shadow.width = 0;
/*Button pressed style*/
memcpy(&lv_style_btn_pr, &lv_style_btn_rel, sizeof(lv_style_t));
lv_style_btn_pr.body.main_color = LV_COLOR_MAKE(0x33, 0x62, 0x94);
lv_style_btn_pr.body.grad_color = LV_COLOR_MAKE(0x10, 0x26, 0x3c);
lv_style_btn_pr.text.color = LV_COLOR_MAKE(0xa4, 0xb5, 0xc6);
lv_style_btn_pr.image.color = LV_COLOR_MAKE(0xa4, 0xb5, 0xc6);
lv_style_btn_pr.line.color = LV_COLOR_MAKE(0xa4, 0xb5, 0xc6);
/*Button toggle released style*/
memcpy(&lv_style_btn_tgl_rel, &lv_style_btn_rel, sizeof(lv_style_t));
lv_style_btn_tgl_rel.body.main_color = LV_COLOR_MAKE(0x0a, 0x11, 0x22);
lv_style_btn_tgl_rel.body.grad_color = LV_COLOR_MAKE(0x37, 0x62, 0x90);
lv_style_btn_tgl_rel.body.border.color = LV_COLOR_MAKE(0x01, 0x07, 0x0d);
lv_style_btn_tgl_rel.text.color = LV_COLOR_MAKE(0xc8, 0xdd, 0xf4);
lv_style_btn_tgl_rel.image.color = LV_COLOR_MAKE(0xc8, 0xdd, 0xf4);
lv_style_btn_tgl_rel.line.color = LV_COLOR_MAKE(0xc8, 0xdd, 0xf4);
/*Button toggle pressed style*/
memcpy(&lv_style_btn_tgl_pr, &lv_style_btn_tgl_rel, sizeof(lv_style_t));
lv_style_btn_tgl_pr.body.main_color = LV_COLOR_MAKE(0x02, 0x14, 0x27);
lv_style_btn_tgl_pr.body.grad_color = LV_COLOR_MAKE(0x2b, 0x4c, 0x70);
lv_style_btn_tgl_pr.text.color = LV_COLOR_MAKE(0xa4, 0xb5, 0xc6);
lv_style_btn_tgl_pr.image.color = LV_COLOR_MAKE(0xa4, 0xb5, 0xc6);
lv_style_btn_tgl_pr.line.color = LV_COLOR_MAKE(0xa4, 0xb5, 0xc6);
/*Button inactive style*/
memcpy(&lv_style_btn_ina, &lv_style_btn_rel, sizeof(lv_style_t));
lv_style_btn_ina.body.main_color = LV_COLOR_MAKE(0xd8, 0xd8, 0xd8);
lv_style_btn_ina.body.grad_color = LV_COLOR_MAKE(0xd8, 0xd8, 0xd8);
lv_style_btn_ina.body.border.color = LV_COLOR_MAKE(0x90, 0x90, 0x90);
lv_style_btn_ina.text.color = LV_COLOR_MAKE(0x70, 0x70, 0x70);
lv_style_btn_ina.image.color = LV_COLOR_MAKE(0x70, 0x70, 0x70);
lv_style_btn_ina.line.color = LV_COLOR_MAKE(0x70, 0x70, 0x70);
}
/**
* Copy a style to an other
* @param dest pointer to the destination style
* @param src pointer to the source style
*/
void lv_style_copy(lv_style_t * dest, const lv_style_t * src)
{
memcpy(dest, src, sizeof(lv_style_t));
}
#if USE_LV_ANIMATION
/**
* Create an animation from a pre-configured 'lv_style_anim_t' variable
* @param anim pointer to a pre-configured 'lv_style_anim_t' variable (will be copied)
*/
void lv_style_anim_create(lv_style_anim_t * anim)
{
lv_style_anim_dsc_t * dsc;
dsc = lv_mem_alloc(sizeof(lv_style_anim_dsc_t));
dsc->style_anim = anim->style_anim;
memcpy(&dsc->style_start, anim->style_start, sizeof(lv_style_t));
memcpy(&dsc->style_end, anim->style_end, sizeof(lv_style_t));
dsc->end_cb = anim->end_cb;
lv_anim_t a;
a.var = (void*)dsc;
a.start = 0;
a.end = LV_STYLE_ANIM_RES;
a.fp = (lv_anim_fp_t)style_animator;
a.path = lv_anim_path_linear;
a.end_cb = style_animation_common_end_cb;
a.act_time = anim->act_time;
a.time = anim->time;
a.playback = anim->playback;
a.playback_pause = anim->playback_pause;
a.repeat = anim->repeat;
a.repeat_pause = anim->repeat_pause;
lv_anim_create(&a);
}
#endif
/**********************
* STATIC FUNCTIONS
**********************/
#if USE_LV_ANIMATION
/**
* Used by the style animations to set the values of a style according to start and end style.
* @param dsc the 'animated variable' set by lv_style_anim_create()
* @param val the current state of the animation between 0 and LV_STYLE_ANIM_RES
*/
static void style_animator(lv_style_anim_dsc_t * dsc, int32_t val)
{
const lv_style_t * start = &dsc->style_start;
const lv_style_t * end = &dsc->style_end;
lv_style_t * act = dsc->style_anim;
STYLE_ATTR_ANIM(body.opa, val);
STYLE_ATTR_ANIM(body.radius, val);
STYLE_ATTR_ANIM(body.border.width, val);
STYLE_ATTR_ANIM(body.shadow.width, val);
STYLE_ATTR_ANIM(body.padding.hor, val);
STYLE_ATTR_ANIM(body.padding.ver, val);
STYLE_ATTR_ANIM(body.padding.inner, val);
STYLE_ATTR_ANIM(text.line_space, val);
STYLE_ATTR_ANIM(text.letter_space, val);
STYLE_ATTR_ANIM(line.width, val);
STYLE_ATTR_ANIM(image.intense, val);
lv_opa_t opa = val == LV_STYLE_ANIM_RES ? LV_OPA_COVER : val;
act->body.main_color = lv_color_mix(end->body.main_color, start->body.main_color, opa);
act->body.grad_color = lv_color_mix(end->body.grad_color, start->body.grad_color, opa);
act->body.border.color = lv_color_mix(end->body.border.color, start->body.border.color, opa);
act->body.shadow.color = lv_color_mix(end->body.shadow.color, start->body.shadow.color, opa);
act->text.color = lv_color_mix(end->text.color, start->text.color, opa);
act->image.color = lv_color_mix(end->image.color, start->image.color, opa);
act->line.color = lv_color_mix(end->line.color, start->line.color, opa);
if(val == 0) {
act->body.empty = start->body.empty;
act->glass = start->glass;
act->text.font = start->text.font;
act->body.shadow.type = start->body.shadow.type;
}
if(val == LV_STYLE_ANIM_RES) {
act->body.empty = end->body.empty;
act->glass = end->glass;
act->text.font = end->text.font;
act->body.shadow.type = end->body.shadow.type;
}
lv_obj_report_style_mod(dsc->style_anim);
}
/**
* Called when a style animation is ready
* It called the user defined call back and free the allocated memories
* @param ptr the 'animated variable' set by lv_style_anim_create()
*/
static void style_animation_common_end_cb(void *ptr)
{
lv_style_anim_dsc_t *dsc = ptr; /*To avoid casting*/
if(dsc->end_cb) dsc->end_cb(dsc);
lv_mem_free(dsc);
}
#endif

View file

@ -0,0 +1,184 @@
/**
* @file lv_style.h
*
*/
#ifndef LV_STYLE_H
#define LV_STYLE_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include <stdbool.h>
#include "../lv_misc/lv_color.h"
#include "../lv_misc/lv_area.h"
#include "../lv_misc/lv_font.h"
#include "../lv_misc/lv_anim.h"
/*********************
* DEFINES
*********************/
#define LV_RADIUS_CIRCLE (LV_COORD_MAX) /*A very big radius to always draw as circle*/
#define LV_AA LV_ANTIALIAS /*Just a shorter form of LV_ANTIALIAS*/
/**********************
* TYPEDEFS
**********************/
/*Border types (Use 'OR'ed values)*/
typedef enum
{
LV_BORDER_NONE = 0x00,
LV_BORDER_BOTTOM = 0x01,
LV_BORDER_TOP = 0x02,
LV_BORDER_LEFT = 0x04,
LV_BORDER_RIGHT = 0x08,
LV_BORDER_FULL = 0x0F,
}lv_border_part_t;
/*Shadow types*/
typedef enum
{
LV_SHADOW_BOTTOM = 0,
LV_SHADOW_FULL,
}lv_shadow_type_t;
typedef struct
{
uint8_t glass :1; /*1: Do not inherit this style*/
struct {
lv_color_t main_color;
lv_color_t grad_color;
lv_coord_t radius;
lv_opa_t opa;
struct {
lv_color_t color;
lv_coord_t width;
lv_border_part_t part;
lv_opa_t opa;
}border;
struct {
lv_color_t color;
lv_coord_t width;
uint8_t type;
}shadow;
struct {
lv_coord_t ver;
lv_coord_t hor;
lv_coord_t inner;
}padding;
uint8_t empty :1; /*Transparent background (border still drawn)*/
}body;
struct {
lv_color_t color;
const lv_font_t * font;
lv_coord_t letter_space;
lv_coord_t line_space;
lv_opa_t opa;
}text;
struct {
lv_color_t color;
lv_opa_t intense;
lv_opa_t opa;
}image;
struct {
lv_color_t color;
lv_coord_t width;
lv_opa_t opa;
}line;
}lv_style_t;
#if USE_LV_ANIMATION
typedef struct {
const lv_style_t * style_start; /*Pointer to the starting style*/
const lv_style_t * style_end; /*Pointer to the destination style*/
lv_style_t * style_anim; /*Pointer to a style to animate*/
lv_anim_cb_t end_cb; /*Call it when the animation is ready (NULL if unused)*/
int16_t time; /*Animation time in ms*/
int16_t act_time; /*Current time in animation. Set to negative to make delay.*/
uint16_t playback_pause; /*Wait before play back*/
uint16_t repeat_pause; /*Wait before repeat*/
uint8_t playback :1; /*When the animation is ready play it back*/
uint8_t repeat :1; /*Repeat the animation infinitely*/
}lv_style_anim_t;
/* Example initialization
lv_style_anim_t a;
a.style_anim = &style_to_anim;
a.style_start = &style_1;
a.style_end = &style_2;
a.act_time = 0;
a.time = 1000;
a.playback = 0;
a.playback_pause = 0;
a.repeat = 0;
a.repeat_pause = 0;
a.end_cb = NULL;
lv_style_anim_create(&a);
*/
#endif
/**********************
* GLOBAL PROTOTYPES
**********************/
/**
* Init the basic styles
*/
void lv_style_init (void);
/**
* Copy a style to an other
* @param dest pointer to the destination style
* @param src pointer to the source style
*/
void lv_style_copy(lv_style_t * dest, const lv_style_t * src);
#if USE_LV_ANIMATION
/**
* Create an animation from a pre-configured 'lv_style_anim_t' variable
* @param anim pointer to a pre-configured 'lv_style_anim_t' variable (will be copied)
*/
void lv_style_anim_create(lv_style_anim_t * anim);
#endif
/*************************
* GLOBAL VARIABLES
*************************/
extern lv_style_t lv_style_scr;
extern lv_style_t lv_style_transp;
extern lv_style_t lv_style_transp_fit;
extern lv_style_t lv_style_transp_tight;
extern lv_style_t lv_style_plain;
extern lv_style_t lv_style_plain_color;
extern lv_style_t lv_style_pretty;
extern lv_style_t lv_style_pretty_color;
extern lv_style_t lv_style_btn_rel;
extern lv_style_t lv_style_btn_pr;
extern lv_style_t lv_style_btn_tgl_rel;
extern lv_style_t lv_style_btn_tgl_pr;;
extern lv_style_t lv_style_btn_ina;
/**********************
* MACROS
**********************/
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /*LV_STYLE_H*/

View file

@ -0,0 +1,203 @@
/**
* @file lv_vdb.c
*
*/
#include "../../lv_conf.h"
#if LV_VDB_SIZE != 0
#include "../lv_hal/lv_hal_disp.h"
#include <stddef.h>
#include "lv_vdb.h"
/*********************
* INCLUDES
*********************/
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
typedef enum {
LV_VDB_STATE_FREE = 0,
LV_VDB_STATE_ACTIVE,
LV_VDB_STATE_FLUSH,
} lv_vdb_state_t;
/**********************
* STATIC PROTOTYPES
**********************/
/**********************
* STATIC VARIABLES
**********************/
#if LV_VDB_DOUBLE == 0
/*Simple VDB*/
static volatile lv_vdb_state_t vdb_state = LV_VDB_STATE_ACTIVE;
# if LV_VDB_ADR == 0
/*If the buffer address is not specified simply allocate it*/
static lv_color_t vdb_buf[LV_VDB_SIZE];
static lv_vdb_t vdb = {.buf = vdb_buf};
# else
/*If the buffer address is specified use that address*/
static lv_vdb_t vdb = {.buf = (lv_color_t *)LV_VDB_ADR};
# endif
#else
/*Double VDB*/
static volatile lv_vdb_state_t vdb_state[2] = {LV_VDB_STATE_FREE, LV_VDB_STATE_FREE};
# if LV_VDB_ADR == 0
/*If the buffer address is not specified simply allocate it*/
static lv_color_t vdb_buf1[LV_VDB_SIZE];
static lv_color_t vdb_buf2[LV_VDB_SIZE];
static lv_vdb_t vdb[2] = {{.buf = vdb_buf1}, {.buf = vdb_buf2}};
# else
/*If the buffer address is specified use that address*/
static lv_vdb_t vdb[2] = {{.buf = (lv_color_t *)LV_VDB_ADR}, {.buf = (lv_color_t *)LV_VDB2_ADR}};
# endif
#endif
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
/**
* Get the 'vdb' variable or allocate one in LV_VDB_DOUBLE mode
* @return pointer to a 'vdb' variable
*/
lv_vdb_t * lv_vdb_get(void)
{
#if LV_VDB_DOUBLE == 0
/* Wait until VDB become ACTIVE from FLUSH by the
* user call of 'lv_flush_ready()' in display drivers's flush function*/
while(vdb_state != LV_VDB_STATE_ACTIVE);
return &vdb;
#else
/*If already there is an active do nothing*/
if(vdb_state[0] == LV_VDB_STATE_ACTIVE) return &vdb[0];
if(vdb_state[1] == LV_VDB_STATE_ACTIVE) return &vdb[1];
/*Try to allocate a free VDB*/
if(vdb_state[0] == LV_VDB_STATE_FREE) {
vdb_state[0] = LV_VDB_STATE_ACTIVE;
return &vdb[0];
}
if(vdb_state[1] == LV_VDB_STATE_FREE) {
vdb_state[1] = LV_VDB_STATE_ACTIVE;
return &vdb[1];
}
return NULL; /*There wasn't free VDB (never happen)*/
#endif
}
/**
* Flush the content of the VDB
*/
void lv_vdb_flush(void)
{
lv_vdb_t * vdb_act = lv_vdb_get();
if(vdb_act == NULL) return;
#if LV_VDB_DOUBLE == 0
vdb_state = LV_VDB_STATE_FLUSH; /*User call to 'lv_flush_ready()' will set to ACTIVE 'disp_flush'*/
#else
/* Wait the pending flush before starting this one
* (Don't forget: 'lv_flush_ready()' has to be called when flushing is ready)*/
while(vdb_state[0] == LV_VDB_STATE_FLUSH || vdb_state[1] == LV_VDB_STATE_FLUSH);
/*Turn the active VDB to flushing*/
if(vdb_state[0] == LV_VDB_STATE_ACTIVE) vdb_state[0] = LV_VDB_STATE_FLUSH;
if(vdb_state[1] == LV_VDB_STATE_ACTIVE) vdb_state[1] = LV_VDB_STATE_FLUSH;
#endif
#if LV_ANTIALIAS == 0
lv_disp_flush(vdb_act->area.x1, vdb_act->area.y1, vdb_act->area.x2, vdb_act->area.y2, vdb_act->buf);
#else
/* Get the average of 2x2 pixels and put the result back to the VDB
* The reading goes much faster then the write back
* so useful data won't be overwritten
* Example:
* -----------------------------
* in1_buf |2,2|6,8| 3,7
* in2_buf |4,4|7,7| 1,2
* --------- ==>
* in1_buf |1,1|1,3|
* in2_buf |1,1|1,3|
* */
lv_coord_t x;
lv_coord_t y;
lv_coord_t w = lv_area_get_width(&vdb_act->area);
lv_color_t * in1_buf = vdb_act->buf; /*Pointer to the first row*/
lv_color_t * in2_buf = vdb_act->buf + w; /*Pointer to the second row*/
lv_color_t * out_buf = vdb_act->buf; /*Store the result here*/
for(y = vdb_act->area.y1; y < vdb_act->area.y2; y += 2) {
for(x = vdb_act->area.x1; x < vdb_act->area.x2; x += 2) {
/*If the pixels are the same do not calculate the average */
if(in1_buf->full == (in1_buf + 1)->full &&
in1_buf->full == in2_buf->full &&
in1_buf->full == (in2_buf + 1)->full) {
out_buf->full = in1_buf->full;
} else {
/*Get the average of 2x2 red*/
out_buf->red = (in1_buf->red + (in1_buf + 1)->red +
in2_buf->red + (in2_buf+ 1)->red) >> 2;
/*Get the average of 2x2 green*/
out_buf->green = (in1_buf->green + (in1_buf + 1)->green +
in2_buf->green + (in2_buf + 1)->green) >> 2;
/*Get the average of 2x2 blue*/
out_buf->blue = (in1_buf->blue + (in1_buf + 1)->blue +
in2_buf->blue + (in2_buf + 1)->blue) >> 2;
}
in1_buf += 2; /*Skip the next pixel because it is already used above*/
in2_buf += 2;
out_buf ++;
}
/*2 row is ready so go the next 2*/
in1_buf += w; /*Skip the next row because it is processed from in2_buf*/
in2_buf += w;
}
/* Now the full the VDB is filtered and the result is stored in the first quarter of it
* Write out the filtered map to the display*/
lv_disp_flush(vdb_act->area.x1 >> 1, vdb_act->area.y1 >> 1, vdb_act->area.x2 >> 1, vdb_act->area.y2 >> 1, vdb_act->buf);
#endif
}
/**
* Call in the display driver's 'disp_flush' function when the flushing is finished
*/
void lv_flush_ready(void)
{
#if LV_VDB_DOUBLE == 0
vdb_state = LV_VDB_STATE_ACTIVE;
#else
if(vdb_state[0] == LV_VDB_STATE_FLUSH) vdb_state[0] = LV_VDB_STATE_FREE;
if(vdb_state[1] == LV_VDB_STATE_FLUSH) vdb_state[1] = LV_VDB_STATE_FREE;
#endif
}
/**********************
* STATIC FUNCTIONS
**********************/
#else
/**
* Just for compatibility
*/
void lv_flush_ready(void)
{
/*Do nothing. It is used only for VDB*/
}
#endif

View file

@ -0,0 +1,73 @@
/**
* @file lv_vdb.h
*
*/
#ifndef LV_VDB_H
#define LV_VDB_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include "../../lv_conf.h"
#if LV_VDB_SIZE != 0
#include "../lv_misc/lv_color.h"
#include "../lv_misc/lv_area.h"
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
typedef struct
{
lv_area_t area;
lv_color_t *buf;
}lv_vdb_t;
/**********************
* GLOBAL PROTOTYPES
**********************/
/**
* Get the 'vdb' variable or allocate one in LV_VDB_DOUBLE mode
* @return pointer to a 'vdb' variable
*/
lv_vdb_t * lv_vdb_get(void);
/**
* Flush the content of the vdb
*/
void lv_vdb_flush(void);
/**
* In 'LV_VDB_DOUBLE' mode has to be called when 'disp_map()'
* is ready with copying the map to a frame buffer.
*/
void lv_flush_ready(void);
/**********************
* MACROS
**********************/
#else /*LV_VDB_SIZE != 0*/
/*Just for compatibility*/
void lv_flush_ready(void);
#endif
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /*LV_VDB_H*/

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,105 @@
/**
* @file lv_draw.h
*
*/
#ifndef LV_DRAW_H
#define LV_DRAW_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include "../lv_core/lv_style.h"
#include "../lv_misc/lv_txt.h"
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/* Image header it is compatible with
* the result image converter utility*/
typedef struct
{
uint32_t w:12; /*Width of the image map*/
uint32_t h:12; /*Height of the image map*/
uint32_t transp:1; /*1: The image contains transparent pixels with LV_COLOR_TRANSP color*/
uint32_t cd:3; /*Color depth (0: reserved, 1: 8 bit, 2: 16 bit or 3: 24 bit, 4-7: reserved)*/
uint32_t res :4; /*Reserved*/
}lv_img_raw_header_t;
/**********************
* GLOBAL PROTOTYPES
**********************/
/**
* Draw a rectangle
* @param cords_p the coordinates of the rectangle
* @param mask_p the rectangle will be drawn only in this mask
* @param style_p pointer to a style
*/
void lv_draw_rect(const lv_area_t * cords_p, const lv_area_t * mask_p, const lv_style_t * style_p);
/*Experimental use for 3D modeling*/
#define USE_LV_TRIANGLE 0
#if USE_LV_TRIANGLE != 0
/**
*
* @param points pointer to an array with 3 points
* @param mask_p the triangle will be drawn only in this mask
* @param color color of the triangle
*/
void lv_draw_triangle(const lv_point_t * points, const lv_area_t * mask_p, lv_color_t color);
#endif
/**
* Write a text
* @param cords_p coordinates of the label
* @param mask_p the label will be drawn only in this area
* @param style_p pointer to a style
* @param txt 0 terminated text to write
* @param flags settings for the text from 'txt_flag_t' enum
* @param offset text offset in x and y direction (NULL if unused)
*/
void lv_draw_label(const lv_area_t * cords_p,const lv_area_t * mask_p, const lv_style_t * style_p,
const char * txt, lv_txt_flag_t flag, lv_point_t * offset);
#if USE_LV_IMG
/**
* Draw an image
* @param cords_p the coordinates of the image
* @param mask_p the image will be drawn only in this area
* @param map_p pointer to a lv_color_t array which contains the pixels of the image
*/
void lv_draw_img(const lv_area_t * cords_p, const lv_area_t * mask_p,
const lv_style_t * style_p, const char * fn);
#endif
/**
* Draw a line
* @param p1 first point of the line
* @param p2 second point of the line
* @param mask_pthe line will be drawn only on this area
* @param style_p pointer to a style
*/
void lv_draw_line(const lv_point_t * p1, const lv_point_t * p2, const lv_area_t * mask_p,
const lv_style_t * style_p);
/**********************
* MACROS
**********************/
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /*LV_DRAW_H*/

View file

@ -0,0 +1,8 @@
NAME := lv_draw
$(NAME)_SOURCES += lv_draw.c
$(NAME)_SOURCES += lv_draw_rbasic.c
$(NAME)_SOURCES += lv_draw_vbasic.c
$(NAME)_INCLUDES += ../../
$(NAME)_INCLUDES += ../

View file

@ -0,0 +1,231 @@
/**
* @file lv_draw_rbasic.c
*
*/
/*********************
* INCLUDES
*********************/
#include "../lv_hal/lv_hal_disp.h"
#include "lv_draw_rbasic.h"
#include "../../lv_conf.h"
#include "../lv_misc/lv_font.h"
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
/**********************
* STATIC VARIABLES
**********************/
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
/**
* Put a pixel to the display
* @param x x coordinate of the pixel
* @param y y coordinate of the pixel
* @param mask_p the pixel will be drawn on this area
* @param color color of the pixel
* @param opa opacity (ignored, only for compatibility with lv_vpx)
*/
void lv_rpx(lv_coord_t x, lv_coord_t y, const lv_area_t * mask_p, lv_color_t color, lv_opa_t opa)
{
(void)opa; /*Opa is used only for compatibility with lv_vpx*/
lv_area_t area;
area.x1 = x;
area.y1 = y;
area.x2 = x;
area.y2 = y;
lv_rfill(&area, mask_p, color, LV_OPA_COVER);
}
/**
* Fill an area on the display
* @param cords_p coordinates of the area to fill
* @param mask_p fill only o this mask
* @param color fill color
* @param opa opacity (ignored, only for compatibility with lv_vfill)
*/
void lv_rfill(const lv_area_t * cords_p, const lv_area_t * mask_p,
lv_color_t color, lv_opa_t opa)
{
(void)opa; /*Opa is used only for compatibility with lv_vfill*/
lv_area_t masked_area;
bool union_ok = true;
if(mask_p != NULL) {
union_ok = lv_area_union(&masked_area, cords_p, mask_p);
} else {
lv_area_t scr_area;
lv_area_set(&scr_area, 0, 0, LV_HOR_RES - 1, LV_HOR_RES - 1);
union_ok = lv_area_union(&masked_area, cords_p, &scr_area);
}
if(union_ok != false){
lv_disp_fill(masked_area.x1, masked_area.y1, masked_area.x2, masked_area.y2, color);
}
}
/**
* Draw a letter to the display
* @param pos_p left-top coordinate of the latter
* @param mask_p the letter will be drawn only on this area
* @param font_p pointer to font
* @param letter a letter to draw
* @param color color of letter
* @param opa opacity of letter (ignored, only for compatibility with lv_vletter)
*/
void lv_rletter(const lv_point_t * pos_p, const lv_area_t * mask_p,
const lv_font_t * font_p, uint32_t letter,
lv_color_t color, lv_opa_t opa)
{
(void)opa; /*Opa is used only for compatibility with lv_vletter*/
uint8_t w = lv_font_get_width(font_p, letter);
if(letter == 'C') {
letter = 'C';
}
const uint8_t * bitmap_p = lv_font_get_bitmap(font_p, letter);
uint8_t col, col_sub, row;
#if LV_FONT_ANTIALIAS == 0
for(row = 0; row < font_p->height_row; row ++) {
for(col = 0, col_sub = 7; col < w; col ++, col_sub--) {
if(*bitmap_p & (1 << col_sub)) {
lv_rpx(pos_p->x + col, pos_p->y + row, mask_p, color, opa);
}
if(col_sub == 0) {
bitmap_p++;
col_sub = 8;
}
}
/*Go to the next row*/
if(col_sub != 7) bitmap_p ++; /*Go to the next byte if it not done in the last step*/
}
#else
uint8_t width_byte = w >> 3; /*Width in bytes (e.g. w = 11 -> 2 bytes wide)*/
if(w & 0x7) width_byte++;
const uint8_t * map1_p = bitmap_p;
const uint8_t * map2_p = bitmap_p + width_byte;
uint8_t px_cnt;
uint8_t col_byte_cnt;
for(row = 0; row < (font_p->height_row >> 1); row ++) {
col_byte_cnt = 0;
col_sub = 7;
for(col = 0; col < (w >> 1); col ++) {
px_cnt = 0;
if((*map1_p & (1 << col_sub)) != 0) px_cnt++;
if((*map2_p & (1 << col_sub)) != 0) px_cnt++;
if(col_sub != 0) col_sub --;
else {
col_sub = 7;
col_byte_cnt ++;
map1_p ++;
map2_p ++;
}
if((*map1_p & (1 << col_sub)) != 0) px_cnt++;
if((*map2_p & (1 << col_sub)) != 0) px_cnt++;
if(col_sub != 0) col_sub --;
else {
col_sub = 7;
col_byte_cnt ++;
map1_p ++;
map2_p ++;
}
if(px_cnt != 0) {
lv_rpx(pos_p->x + col, pos_p->y + row, mask_p, lv_color_mix(color, LV_COLOR_SILVER, 63 * px_cnt), LV_OPA_COVER);
}
}
map1_p += width_byte;
map2_p += width_byte;
map1_p += width_byte - col_byte_cnt;
map2_p += width_byte - col_byte_cnt;
}
#endif
}
/**
* Draw a color map to the display
* @param cords_p coordinates the color map
* @param mask_p the map will drawn only on this area
* @param map_p pointer to a lv_color_t array
* @param opa opacity of the map (ignored, only for compatibility with lv_vmap)
* @param transp true: enable transparency of LV_IMG_LV_COLOR_TRANSP color pixels
* @param upscale true: upscale to double size (not supported)
* @param recolor mix the pixels with this color (not supported)
* @param recolor_opa the intense of recoloring (not supported)
*/
void lv_rmap(const lv_area_t * cords_p, const lv_area_t * mask_p,
const lv_color_t * map_p, lv_opa_t opa, bool transp, bool upscale,
lv_color_t recolor, lv_opa_t recolor_opa)
{
(void)opa; /*opa is used only for compatibility with lv_vmap*/
(void)recolor_opa; /*recolor_opa is used only for compatibility with lv_vmap*/
(void)recolor; /*recolor is used only for compatibility with lv_vmap*/
(void)upscale; /*upscale is used only for compatibility with lv_vmap*/
lv_area_t masked_a;
bool union_ok;
union_ok = lv_area_union(&masked_a, cords_p, mask_p);
/*If there are common part of the mask and map then draw the map*/
if(union_ok == false) return;
/*Go to the first pixel*/
lv_coord_t map_width = lv_area_get_width(cords_p);
map_p+= (masked_a.y1 - cords_p->y1) * map_width;
map_p += masked_a.x1 - cords_p->x1;
if(transp == false) {
lv_coord_t row;
lv_coord_t mask_w = lv_area_get_width(&masked_a) - 1;
for(row = 0; row < lv_area_get_height(&masked_a); row++) {
lv_disp_map(masked_a.x1, masked_a.y1 + row, masked_a.x1 + mask_w, masked_a.y1 + row, map_p);
map_p += map_width;
}
}else {
lv_color_t transp_color = LV_COLOR_TRANSP;
lv_coord_t row;
for(row = 0; row < lv_area_get_height(&masked_a); row++) {
lv_coord_t col;
for(col = 0; col < lv_area_get_width(&masked_a); col ++) {
if(map_p[col].full != transp_color.full) {
lv_rpx(masked_a.x1 + col, masked_a.y1 + row, mask_p, map_p[col], opa);
}
}
map_p += map_width;
}
}
}
/**********************
* STATIC FUNCTIONS
**********************/

View file

@ -0,0 +1,80 @@
/**
* @file lv_draw_rbasic..h
*
*/
#ifndef LV_DRAW_RBASIC_H
#define LV_DRAW_RBASIC_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include "../lv_misc/lv_color.h"
#include "../lv_misc/lv_area.h"
#include "../lv_misc/lv_font.h"
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
void lv_rpx(lv_coord_t x, lv_coord_t y, const lv_area_t * mask_p, lv_color_t color, lv_opa_t opa);
/**
* Fill an area on the display
* @param cords_p coordinates of the area to fill
* @param mask_p fill only o this mask
* @param color fill color
* @param opa opacity (ignored, only for compatibility with lv_vfill)
*/
void lv_rfill(const lv_area_t * cords_p, const lv_area_t * mask_p,
lv_color_t color, lv_opa_t opa);
/**
* Draw a letter to the display
* @param pos_p left-top coordinate of the latter
* @param mask_p the letter will be drawn only on this area
* @param font_p pointer to font
* @param letter a letter to draw
* @param color color of letter
* @param opa opacity of letter (ignored, only for compatibility with lv_vletter)
*/
void lv_rletter(const lv_point_t * pos_p, const lv_area_t * mask_p,
const lv_font_t * font_p, uint32_t letter,
lv_color_t color, lv_opa_t opa);
/**
* Draw a color map to the display
* @param cords_p coordinates the color map
* @param mask_p the map will drawn only on this area
* @param map_p pointer to a lv_color_t array
* @param opa opacity of the map (ignored, only for compatibility with lv_vmap)
* @param transp true: enable transparency of LV_IMG_LV_COLOR_TRANSP color pixels
* @param upscale true: upscale to double size (not supported)
* @param recolor mix the pixels with this color (not supported)
* @param recolor_opa the intense of recoloring (not supported)
*/
void lv_rmap(const lv_area_t * cords_p, const lv_area_t * mask_p,
const lv_color_t * map_p, lv_opa_t opa, bool transp, bool upscale,
lv_color_t recolor, lv_opa_t recolor_opa);
/**********************
* MACROS
**********************/
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /*LV_DRAW_RBASIC_H*/

View file

@ -0,0 +1,593 @@
/**
* @file lv_vdraw.c
*
*/
#include "../../lv_conf.h"
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include "../lv_hal/lv_hal_disp.h"
#include "../lv_misc/lv_area.h"
#include "../lv_misc/lv_font.h"
#include "../lv_misc/lv_color.h"
#if LV_VDB_SIZE != 0
#include <stddef.h>
#include "../lv_core/lv_vdb.h"
/*********************
* INCLUDES
*********************/
/*********************
* DEFINES
*********************/
#define VFILL_HW_ACC_SIZE_LIMIT 50 /*Always fill < 50 px with 'sw_color_fill' because of the hw. init overhead*/
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
static void sw_mem_blend(lv_color_t * dest, const lv_color_t * src, uint32_t length, lv_opa_t opa);
static void sw_color_fill(lv_area_t * mem_area, lv_color_t * mem, const lv_area_t * fill_area, lv_color_t color, lv_opa_t opa);
/**********************
* STATIC VARIABLES
**********************/
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
/**
* Put a pixel in the Virtual Display Buffer
* @param x pixel x coordinate
* @param y pixel y coordinate
* @param mask_p fill only on this mask (truncated to VDB area)
* @param color pixel color
* @param opa opacity of the area (0..255)
*/
void lv_vpx(lv_coord_t x, lv_coord_t y, const lv_area_t * mask_p, lv_color_t color, lv_opa_t opa)
{
lv_vdb_t * vdb_p = lv_vdb_get();
/*Pixel out of the mask*/
if(x < mask_p->x1 || x > mask_p->x2 ||
y < mask_p->y1 || y > mask_p->y2) {
return;
}
uint32_t vdb_width = lv_area_get_width(&vdb_p->area);
/*Make the coordinates relative to VDB*/
x-=vdb_p->area.x1;
y-=vdb_p->area.y1;
lv_color_t * vdb_px_p = vdb_p->buf + y * vdb_width + x;
if(opa == LV_OPA_COVER) {
*vdb_px_p = color;
}
else {
*vdb_px_p = lv_color_mix(color,*vdb_px_p, opa);
}
}
/**
* Fill an area in the Virtual Display Buffer
* @param cords_p coordinates of the area to fill
* @param mask_p fill only o this mask (truncated to VDB area)
* @param color fill color
* @param opa opacity of the area (0..255)
*/
void lv_vfill(const lv_area_t * cords_p, const lv_area_t * mask_p,
lv_color_t color, lv_opa_t opa)
{
lv_area_t res_a;
bool union_ok;
lv_vdb_t * vdb_p = lv_vdb_get();
/*Get the union of cord and mask*/
/* The mask is already truncated to the vdb size
* in 'lv_refr_area_with_vdb' function */
union_ok = lv_area_union(&res_a, cords_p, mask_p);
/*If there are common part of the three area then draw to the vdb*/
if(union_ok == false) return;
lv_area_t vdb_rel_a; /*Stores relative coordinates on vdb*/
vdb_rel_a.x1 = res_a.x1 - vdb_p->area.x1;
vdb_rel_a.y1 = res_a.y1 - vdb_p->area.y1;
vdb_rel_a.x2 = res_a.x2 - vdb_p->area.x1;
vdb_rel_a.y2 = res_a.y2 - vdb_p->area.y1;
lv_color_t * vdb_buf_tmp = vdb_p->buf;
uint32_t vdb_width = lv_area_get_width(&vdb_p->area);
/*Move the vdb_tmp to the first row*/
vdb_buf_tmp += vdb_width * vdb_rel_a.y1;
#if USE_LV_GPU
static lv_color_t color_array_tmp[LV_HOR_RES << LV_ANTIALIAS]; /*Used by 'sw_color_fill'*/
static lv_coord_t last_width = -1;
lv_coord_t w = lv_area_get_width(&vdb_rel_a);
/*Don't use hw. acc. for every small fill (because of the init overhead)*/
if(w < VFILL_HW_ACC_SIZE_LIMIT) {
sw_color_fill(&vdb_p->area, vdb_buf_tmp, &vdb_rel_a, color, opa);
}
/*Not opaque fill*/
else if(opa == LV_OPA_COVER) {
/*Use hw fill if present*/
if(lv_disp_is_mem_fill_supported()) {
lv_coord_t row;
for(row = vdb_rel_a.y1;row <= vdb_rel_a.y2; row++) {
lv_disp_mem_fill(&vdb_buf_tmp[vdb_rel_a.x1], w, color);
vdb_buf_tmp += vdb_width;
}
}
/*Use hw blend if present and the area is not too small*/
else if(lv_area_get_height(&vdb_rel_a) > VFILL_HW_ACC_SIZE_LIMIT &&
lv_disp_is_mem_blend_supported())
{
if(color_array_tmp[0].full != color.full || last_width != w) {
uint16_t i;
for(i = 0; i < w; i++) {
color_array_tmp[i].full = color.full;
}
last_width = w;
}
lv_coord_t row;
for(row = vdb_rel_a.y1;row <= vdb_rel_a.y2; row++) {
lv_disp_mem_blend(&vdb_buf_tmp[vdb_rel_a.x1], color_array_tmp, w, opa);
vdb_buf_tmp += vdb_width;
}
}
/*Else use sw fill if no better option*/
else {
sw_color_fill(&vdb_p->area, vdb_buf_tmp, &vdb_rel_a, color, opa);
}
}
/*Fill with opacity*/
else {
/*Use hw blend if present*/
if(lv_disp_is_mem_blend_supported()) {
if(color_array_tmp[0].full != color.full || last_width != w) {
uint16_t i;
for(i = 0; i < w; i++) {
color_array_tmp[i].full = color.full;
}
last_width = w;
}
lv_coord_t row;
for(row = vdb_rel_a.y1;row <= vdb_rel_a.y2; row++) {
lv_disp_mem_blend(&vdb_buf_tmp[vdb_rel_a.x1], color_array_tmp, w, opa);
vdb_buf_tmp += vdb_width;
}
}
/*Use sw fill with opa if no better option*/
else {
sw_color_fill(&vdb_p->area, vdb_buf_tmp, &vdb_rel_a, color, opa);
}
}
#else
sw_color_fill(&vdb_p->area, vdb_buf_tmp, &vdb_rel_a, color, opa);
#endif
}
/**
* Draw a letter in the Virtual Display Buffer
* @param pos_p left-top coordinate of the latter
* @param mask_p the letter will be drawn only on this area (truncated to VDB area)
* @param font_p pointer to font
* @param letter a letter to draw
* @param color color of letter
* @param opa opacity of letter (0..255)
*/
void lv_vletter(const lv_point_t * pos_p, const lv_area_t * mask_p,
const lv_font_t * font_p, uint32_t letter,
lv_color_t color, lv_opa_t opa)
{
if(font_p == NULL) return;
uint8_t letter_w = lv_font_get_width(font_p, letter);
uint8_t letter_h = lv_font_get_height(font_p);
const uint8_t * map_p = lv_font_get_bitmap(font_p, letter);
if(map_p == NULL) return;
/*If the letter is completely out of mask don't draw it */
if(pos_p->x + letter_w < mask_p->x1 || pos_p->x > mask_p->x2 ||
pos_p->y + letter_h < mask_p->y1 || pos_p->y > mask_p->y2) return;
lv_vdb_t * vdb_p = lv_vdb_get();
lv_coord_t vdb_width = lv_area_get_width(&vdb_p->area);
lv_color_t * vdb_buf_tmp = vdb_p->buf;
lv_coord_t col, row;
uint8_t col_bit;
uint8_t col_byte_cnt;
uint8_t width_byte = letter_w >> 3; /*Width in bytes (e.g. w = 11 -> 2 bytes wide)*/
if(letter_w & 0x7) width_byte++;
/* Calculate the col/row start/end on the map
* If font anti alaiassing is enabled use the reduced letter sizes*/
lv_coord_t col_start = pos_p->x > mask_p->x1 ? 0 : mask_p->x1 - pos_p->x;
lv_coord_t col_end = pos_p->x + (letter_w >> LV_FONT_ANTIALIAS) < mask_p->x2 ? (letter_w >> LV_FONT_ANTIALIAS) : mask_p->x2 - pos_p->x + 1;
lv_coord_t row_start = pos_p->y > mask_p->y1 ? 0 : mask_p->y1 - pos_p->y;
lv_coord_t row_end = pos_p->y + (letter_h >> LV_FONT_ANTIALIAS) < mask_p->y2 ? (letter_h >> LV_FONT_ANTIALIAS) : mask_p->y2 - pos_p->y + 1;
/*Set a pointer on VDB to the first pixel of the letter*/
vdb_buf_tmp += ((pos_p->y - vdb_p->area.y1) * vdb_width)
+ pos_p->x - vdb_p->area.x1;
/*If the letter is partially out of mask the move there on VDB*/
vdb_buf_tmp += (row_start * vdb_width) + col_start;
/*Move on the map too*/
map_p += ((row_start << LV_FONT_ANTIALIAS) * width_byte) + ((col_start << LV_FONT_ANTIALIAS) >> 3);
#if LV_FONT_ANTIALIAS != 0
lv_opa_t opa_tmp = opa;
if(opa_tmp != LV_OPA_COVER) opa_tmp = opa_tmp >> 2; /*Opacity per pixel (used when sum the pixels)*/
const uint8_t * map1_p = map_p;
const uint8_t * map2_p = map_p + width_byte;
uint8_t px_cnt;
for(row = row_start; row < row_end; row ++) {
col_byte_cnt = 0;
col_bit = 7 - ((col_start << LV_FONT_ANTIALIAS) % 8);
for(col = col_start; col < col_end; col ++) {
px_cnt = 0;
if((*map1_p & (1 << col_bit)) != 0) px_cnt++;
if((*map2_p & (1 << col_bit)) != 0) px_cnt++;
if(col_bit != 0) col_bit --;
else {
col_bit = 7;
col_byte_cnt ++;
map1_p ++;
map2_p ++;
}
if((*map1_p & (1 << col_bit)) != 0) px_cnt++;
if((*map2_p & (1 << col_bit)) != 0) px_cnt++;
if(col_bit != 0) col_bit --;
else {
col_bit = 7;
col_byte_cnt ++;
map1_p ++;
map2_p ++;
}
if(px_cnt != 0) {
if(opa == LV_OPA_COVER) *vdb_buf_tmp = lv_color_mix(color, *vdb_buf_tmp, 63*px_cnt);
else *vdb_buf_tmp = lv_color_mix(color, *vdb_buf_tmp, opa_tmp * px_cnt);
}
vdb_buf_tmp++;
}
map1_p += width_byte;
map2_p += width_byte;
map1_p += width_byte - col_byte_cnt;
map2_p += width_byte - col_byte_cnt;
vdb_buf_tmp += vdb_width - ((col_end) - (col_start)); /*Next row in VDB*/
}
#else
for(row = row_start; row < row_end; row ++) {
col_byte_cnt = 0;
col_bit = 7 - (col_start % 8);
for(col = col_start; col < col_end; col ++) {
if((*map_p & (1 << col_bit)) != 0) {
if(opa == LV_OPA_COVER) *vdb_buf_tmp = color;
else *vdb_buf_tmp = lv_color_mix(color, *vdb_buf_tmp, opa);
}
vdb_buf_tmp++;
if(col_bit != 0) col_bit --;
else {
col_bit = 7;
col_byte_cnt ++;
map_p ++;
}
}
map_p += width_byte - col_byte_cnt;
vdb_buf_tmp += vdb_width - (col_end - col_start); /*Next row in VDB*/
}
#endif
}
/**
* Draw a color map to the display
* @param cords_p coordinates the color map
* @param mask_p the map will drawn only on this area (truncated to VDB area)
* @param map_p pointer to a lv_color_t array
* @param opa opacity of the map (ignored, only for compatibility with lv_vmap)
* @param transp true: enable transparency of LV_IMG_LV_COLOR_TRANSP color pixels
* @param upscale true: upscale to double size
* @param recolor mix the pixels with this color
* @param recolor_opa the intense of recoloring
*/
void lv_vmap(const lv_area_t * cords_p, const lv_area_t * mask_p,
const lv_color_t * map_p, lv_opa_t opa, bool transp, bool upscale,
lv_color_t recolor, lv_opa_t recolor_opa)
{
lv_area_t masked_a;
bool union_ok;
lv_vdb_t * vdb_p = lv_vdb_get();
/*Get the union of map size and mask*/
/* The mask is already truncated to the vdb size
* in 'lv_refr_area_with_vdb' function */
union_ok = lv_area_union(&masked_a, cords_p, mask_p);
/*If there are common part of the three area then draw to the vdb*/
if(union_ok == false) return;
uint8_t ds_shift = 0;
if(upscale != false) ds_shift = 1;
/*If the map starts OUT of the masked area then calc. the first pixel*/
lv_coord_t map_width = lv_area_get_width(cords_p) >> ds_shift;
if(cords_p->y1 < masked_a.y1) {
map_p += (uint32_t) map_width * ((masked_a.y1 - cords_p->y1) >> ds_shift);
}
if(cords_p->x1 < masked_a.x1) {
map_p += (masked_a.x1 - cords_p->x1) >> ds_shift;
}
/*Stores coordinates relative to the act vdb*/
masked_a.x1 = masked_a.x1 - vdb_p->area.x1;
masked_a.y1 = masked_a.y1 - vdb_p->area.y1;
masked_a.x2 = masked_a.x2 - vdb_p->area.x1;
masked_a.y2 = masked_a.y2 - vdb_p->area.y1;
lv_coord_t vdb_width = lv_area_get_width(&vdb_p->area);
lv_color_t * vdb_buf_tmp = vdb_p->buf;
vdb_buf_tmp += (uint32_t) vdb_width * masked_a.y1; /*Move to the first row*/
map_p -= (masked_a.x1 >> ds_shift); /*Move back. It will be easier to index 'map_p' later*/
/*No upscalse*/
if(upscale == false) {
if(transp == false) { /*Simply copy the pixels to the VDB*/
lv_coord_t row;
lv_coord_t map_useful_w = lv_area_get_width(&masked_a);
for(row = masked_a.y1; row <= masked_a.y2; row++) {
#if USE_LV_GPU
if(lv_disp_is_mem_blend_supported() == false) {
sw_mem_blend(&vdb_buf_tmp[masked_a.x1], &map_p[masked_a.x1], map_useful_w, opa);
} else {
lv_disp_mem_blend(&vdb_buf_tmp[masked_a.x1], &map_p[masked_a.x1], map_useful_w, opa);
}
#else
sw_mem_blend(&vdb_buf_tmp[masked_a.x1], &map_p[masked_a.x1], map_useful_w, opa);
#endif
map_p += map_width; /*Next row on the map*/
vdb_buf_tmp += vdb_width; /*Next row on the VDB*/
}
/*To recolor draw simply a rectangle above the image*/
if(recolor_opa != LV_OPA_TRANSP) {
lv_vfill(cords_p, mask_p, recolor, recolor_opa);
}
} else { /*transp == true: Check all pixels */
lv_coord_t row;
lv_coord_t col;
lv_color_t transp_color = LV_COLOR_TRANSP;
if(recolor_opa == LV_OPA_TRANSP) {/*No recolor*/
if(opa == LV_OPA_COVER) { /*no opa */
for(row = masked_a.y1; row <= masked_a.y2; row++) {
for(col = masked_a.x1; col <= masked_a.x2; col ++) {
if(map_p[col].full != transp_color.full) {
vdb_buf_tmp[col] = map_p[col];
}
}
map_p += map_width; /*Next row on the map*/
vdb_buf_tmp += vdb_width; /*Next row on the VDB*/
}
} else {
for(row = masked_a.y1; row <= masked_a.y2; row++) {
for(col = masked_a.x1; col <= masked_a.x2; col ++) {
if(map_p[col].full != transp_color.full) {
vdb_buf_tmp[col] = lv_color_mix( map_p[col], vdb_buf_tmp[col], opa);
}
}
map_p += map_width; /*Next row on the map*/
vdb_buf_tmp += vdb_width; /*Next row on the VDB*/
}
}
} else { /*Recolor needed*/
lv_color_t lv_color_tmp;
if(opa == LV_OPA_COVER) { /*no opa */
for(row = masked_a.y1; row <= masked_a.y2; row++) {
for(col = masked_a.x1; col <= masked_a.x2; col ++) {
if(map_p[col].full != transp_color.full) {
lv_color_tmp = lv_color_mix(recolor, map_p[col], recolor_opa);
vdb_buf_tmp[col] = lv_color_tmp;
}
}
map_p += map_width; /*Next row on the map*/
vdb_buf_tmp += vdb_width; /*Next row on the VDB*/
}
} else {
for(row = masked_a.y1; row <= masked_a.y2; row++) {
for(col = masked_a.x1; col <= masked_a.x2; col ++) {
if(map_p[col].full != transp_color.full) {
lv_color_tmp = lv_color_mix(recolor, map_p[col], recolor_opa);
vdb_buf_tmp[col] = lv_color_mix(lv_color_tmp, vdb_buf_tmp[col], opa);
}
}
map_p += map_width; /*Next row on the map*/
vdb_buf_tmp += vdb_width; /*Next row on the VDB*/
}
}
}
}
}
/*Upscalse*/
else {
lv_coord_t row;
lv_coord_t col;
lv_color_t transp_color = LV_COLOR_TRANSP;
lv_color_t lv_color_tmp;
lv_color_t prev_color = LV_COLOR_BLACK;
lv_coord_t map_col;
/*The most simple case (but upscale): 0 opacity, no recolor, no transp. pixels*/
if(transp == false && opa == LV_OPA_COVER && recolor_opa == LV_OPA_TRANSP) {
lv_coord_t map_col_start = masked_a.x1 >> 1;
lv_coord_t map_col_end = masked_a.x2 >> 1;
lv_coord_t vdb_col; /*Col. in this row*/
lv_coord_t vdb_col2; /*Col. in next row*/
for(row = masked_a.y1; row <= masked_a.y2; row += 2) {
map_col_start = masked_a.x1 >> 1;
map_col_end = masked_a.x2 >> 1;
vdb_col = masked_a.x1;
vdb_col2 = masked_a.x1 + vdb_width;
for(map_col = map_col_start; map_col <= map_col_end; map_col ++, vdb_col += 2, vdb_col2 += 2) {
vdb_buf_tmp[vdb_col].full = map_p[map_col].full;
vdb_buf_tmp[vdb_col + 1].full = map_p[map_col].full;
vdb_buf_tmp[vdb_col2].full = map_p[map_col].full;
vdb_buf_tmp[vdb_col2 + 1].full = map_p[map_col].full;
}
map_p += map_width;
vdb_buf_tmp += 2 * vdb_width ; /*+ 2 row on the VDB (2 rows are filled because of the upscale)*/
}
}
/*Handle other cases*/
else {
lv_color_tmp = lv_color_mix(recolor, prev_color, recolor_opa);
for(row = masked_a.y1; row <= masked_a.y2; row++) {
for(col = masked_a.x1; col <= masked_a.x2; col ++) {
map_col = col >> 1;
/*Handle recoloring*/
if(recolor_opa == LV_OPA_TRANSP) {
lv_color_tmp.full = map_p[map_col].full;
} else {
if(map_p[map_col].full != prev_color.full) {
prev_color.full = map_p[map_col].full;
lv_color_tmp = lv_color_mix(recolor, prev_color, recolor_opa);
}
}
/*Put the NOT transparent pixels*/
if(transp == false || map_p[map_col].full != transp_color.full) {
/*Handle opacity*/
if(opa == LV_OPA_COVER) {
vdb_buf_tmp[col] = lv_color_tmp;
} else {
vdb_buf_tmp[col] = lv_color_mix( lv_color_tmp, vdb_buf_tmp[col], opa);
}
}
}
if((row & 0x1) != 0) map_p += map_width; /*Next row on the map*/
vdb_buf_tmp += vdb_width ; /*Next row on the VDB*/
}
}
}
}
/**********************
* STATIC FUNCTIONS
**********************/
/**
* Blend pixels to destination memory using opacity
* @param dest a memory address. Copy 'src' here.
* @param src pointer to pixel map. Copy it to 'dest'.
* @param length number of pixels in 'src'
* @param opa opacity (0, LV_OPA_TRANSP: transparent ... 255, LV_OPA_COVER, fully cover)
*/
static void sw_mem_blend(lv_color_t * dest, const lv_color_t * src, uint32_t length, lv_opa_t opa)
{
if(opa == LV_OPA_COVER) {
memcpy(dest, src, length * sizeof(lv_color_t));
} else {
uint32_t col;
for(col = 0; col < length; col++) {
dest[col] = lv_color_mix(src[col], dest[col], opa);
}
}
}
/**
*
* @param mem_area coordinates of 'mem' memory area
* @param mem a memory address. Considered to a rectangular window according to 'mem_area'
* @param fill_area coordinates of an area to fill. Relative to 'mem_area'.
* @param color fill color
* @param opa opacity (0, LV_OPA_TRANSP: transparent ... 255, LV_OPA_COVER, fully cover)
*/
static void sw_color_fill(lv_area_t * mem_area, lv_color_t * mem, const lv_area_t * fill_area, lv_color_t color, lv_opa_t opa)
{
/*Set all row in vdb to the given color*/
lv_coord_t row;
lv_coord_t col;
lv_coord_t mem_width = lv_area_get_width(mem_area);
/*Run simpler function without opacity*/
if(opa == LV_OPA_COVER) {
/*Fill the first row with 'color'*/
for(col = fill_area->x1; col <= fill_area->x2; col++) {
mem[col] = color;
}
/*Copy the first row to all other rows*/
lv_color_t * mem_first = &mem[fill_area->x1];
lv_coord_t copy_size = (fill_area->x2 - fill_area->x1 + 1) * sizeof(lv_color_t);
mem += mem_width;
for(row = fill_area->y1 + 1; row <= fill_area->y2; row++) {
memcpy(&mem[fill_area->x1], mem_first, copy_size);
mem += mem_width;
}
}
/*Calculate with alpha too*/
else {
lv_color_t bg_tmp = LV_COLOR_BLACK;
lv_color_t opa_tmp = lv_color_mix(color, bg_tmp, opa);
for(row = fill_area->y1; row <= fill_area->y2; row++) {
for(col = fill_area->x1; col <= fill_area->x2; col++) {
/*If the bg color changed recalculate the result color*/
if(mem[col].full != bg_tmp.full) {
bg_tmp = mem[col];
opa_tmp = lv_color_mix(color, bg_tmp, opa);
}
mem[col] = opa_tmp;
}
mem += mem_width;
}
}
}
#endif

View file

@ -0,0 +1,91 @@
/**
* @file lv_draw_vbasic.h
*
*/
#ifndef LV_DRAW_VBASIC_H
#define LV_DRAW_VBASIC_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include "../../lv_conf.h"
#if LV_VDB_SIZE != 0
#include "../lv_misc/lv_color.h"
#include "../lv_misc/lv_area.h"
#include "../lv_misc/lv_font.h"
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
void lv_vpx(lv_coord_t x, lv_coord_t y, const lv_area_t * mask_p, lv_color_t color, lv_opa_t opa);
/**
* Fill an area in the Virtual Display Buffer
* @param cords_p coordinates of the area to fill
* @param mask_p fill only o this mask
* @param color fill color
* @param opa opacity of the area (0..255)
*/
void lv_vfill(const lv_area_t * cords_p, const lv_area_t * mask_p,
lv_color_t color, lv_opa_t opa);
/**
* Draw a letter in the Virtual Display Buffer
* @param pos_p left-top coordinate of the latter
* @param mask_p the letter will be drawn only on this area
* @param font_p pointer to font
* @param letter a letter to draw
* @param color color of letter
* @param opa opacity of letter (0..255)
*/
void lv_vletter(const lv_point_t * pos_p, const lv_area_t * mask_p,
const lv_font_t * font_p, uint32_t letter,
lv_color_t color, lv_opa_t opa);
/**
* Draw a color map to the display
* @param cords_p coordinates the color map
* @param mask_p the map will drawn only on this area
* @param map_p pointer to a lv_color_t array
* @param opa opacity of the map (ignored, only for compatibility with lv_vmap)
* @param transp true: enable transparency of LV_IMG_LV_COLOR_TRANSP color pixels
* @param upscale true: upscale to double size
* @param recolor mix the pixels with this color
* @param recolor_opa the intense of recoloring
*/
void lv_vmap(const lv_area_t * cords_p, const lv_area_t * mask_p,
const lv_color_t * map_p, lv_opa_t opa, bool transp, bool upscale,
lv_color_t recolor, lv_opa_t recolor_opa);
/**
* Reallocate 'color_map_tmp' to the new hor. res. size. It is used in 'sw_fill'
*/
void lv_vdraw_refresh_temp_arrays(void);
/**********************
* MACROS
**********************/
#endif /*LV_VDB_SIZE != 0*/
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /*LV_DRAW_RBASIC_H*/

View file

@ -0,0 +1,40 @@
/**
* @file hal.h
*
*/
#ifndef HAL_H
#define HAL_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include "lv_hal_disp.h"
#include "lv_hal_indev.h"
#include "lv_hal_tick.h"
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
/**********************
* MACROS
**********************/
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif

View file

@ -0,0 +1,8 @@
NAME := lv_hal
$(NAME)_SOURCES += lv_hal_disp.c
$(NAME)_SOURCES += lv_hal_indev.c
$(NAME)_SOURCES += lv_hal_tick.c
$(NAME)_INCLUDES += ../../
$(NAME)_INCLUDES += ../

View file

@ -0,0 +1,221 @@
/**
* @file hal_disp.c
*
* @description HAL layer for display driver
*
*/
/*********************
* INCLUDES
*********************/
#include <stdint.h>
#include <stddef.h>
#include "../lv_hal/lv_hal_disp.h"
#include "../lv_misc/lv_mem.h"
#include "../lv_core/lv_obj.h"
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
/**********************
* STATIC VARIABLES
**********************/
static lv_disp_t *disp_list = NULL;
static lv_disp_t *active;
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
/**
* Initialize a display driver with default values.
* It is used to surly have known values in the fields ant not memory junk.
* After it you can set the fields.
* @param driver pointer to driver variable to initialize
*/
void lv_disp_drv_init(lv_disp_drv_t *driver)
{
driver->disp_fill = NULL;
driver->disp_map = NULL;
driver->disp_flush = NULL;
#if USE_LV_GPU
driver->mem_blend = NULL;
driver->mem_fill = NULL;
#endif
}
/**
* Register an initialized display driver.
* Automatically set the first display as active.
* @param driver pointer to an initialized 'lv_disp_drv_t' variable (can be local variable)
* @return pointer to the new display or NULL on error
*/
lv_disp_t * lv_disp_drv_register(lv_disp_drv_t *driver)
{
lv_disp_t *node;
node = lv_mem_alloc(sizeof(lv_disp_t));
if (!node) return NULL;
memcpy(&node->driver,driver, sizeof(lv_disp_drv_t));
node->next = NULL;
/* Set first display as active by default */
if (disp_list == NULL) {
disp_list = node;
active = node;
lv_obj_invalidate(lv_scr_act());
} else {
node->next = disp_list;
}
return node;
}
/**
* Set the active display
* @param disp pointer to a display (return value of 'lv_disp_register')
*/
void lv_disp_set_active(lv_disp_t * disp)
{
active = disp;
lv_obj_invalidate(lv_scr_act());
}
/**
* Get a pointer to the active display
* @return pointer to the active display
*/
lv_disp_t * lv_disp_get_active(void)
{
return active;
}
/**
* Get the next display.
* @param disp pointer to the current display. NULL to initialize.
* @return the next display or NULL if no more. Give the first display when the parameter is NULL
*/
lv_disp_t * lv_disp_next(lv_disp_t * disp)
{
if(disp == NULL) {
return disp_list;
} else {
if(disp_list->next == NULL) return NULL;
else return disp_list->next;
}
}
/**
* Write the content of the internal buffer (VDB) to the display
* @param x1 left coordinate of the rectangle
* @param x2 right coordinate of the rectangle
* @param y1 top coordinate of the rectangle
* @param y2 bottom coordinate of the rectangle
* @param color_p fill color
*/
void lv_disp_fill(int32_t x1, int32_t y1, int32_t x2, int32_t y2, lv_color_t color)
{
if(active == NULL) return;
if(active->driver.disp_fill != NULL) active->driver.disp_fill(x1, y1, x2, y2, color);
}
/**
* Fill a rectangular area with a color on the active display
* @param x1 left coordinate of the rectangle
* @param x2 right coordinate of the rectangle
* @param y1 top coordinate of the rectangle
* @param y2 bottom coordinate of the rectangle
* @param color_p pointer to an array of colors
*/
void lv_disp_flush(int32_t x1, int32_t y1, int32_t x2, int32_t y2, lv_color_t *color_p)
{
if(active == NULL) return;
if(active->driver.disp_flush != NULL) active->driver.disp_flush(x1, y1, x2, y2, color_p);
}
/**
* Put a color map to a rectangular area on the active display
* @param x1 left coordinate of the rectangle
* @param x2 right coordinate of the rectangle
* @param y1 top coordinate of the rectangle
* @param y2 bottom coordinate of the rectangle
* @param color_map pointer to an array of colors
*/
void lv_disp_map(int32_t x1, int32_t y1, int32_t x2, int32_t y2, const lv_color_t * color_map)
{
if(active == NULL) return;
if(active->driver.disp_map != NULL) active->driver.disp_map(x1, y1, x2, y2, color_map);
}
#if USE_LV_GPU
/**
* Blend pixels to a destination memory from a source memory
* In 'lv_disp_drv_t' 'mem_blend' is optional. (NULL if not available)
* @param dest a memory address. Blend 'src' here.
* @param src pointer to pixel map. Blend it to 'dest'.
* @param length number of pixels in 'src'
* @param opa opacity (0, LV_OPA_TRANSP: transparent ... 255, LV_OPA_COVER, fully cover)
*/
void lv_disp_mem_blend(lv_color_t * dest, const lv_color_t * src, uint32_t length, lv_opa_t opa)
{
if(active == NULL) return;
if(active->driver.mem_blend != NULL) active->driver.mem_blend(dest, src, length, opa);
}
/**
* Fill a memory with a color (GPUs may support it)
* In 'lv_disp_drv_t' 'mem_fill' is optional. (NULL if not available)
* @param dest a memory address. Copy 'src' here.
* @param src pointer to pixel map. Copy it to 'dest'.
* @param length number of pixels in 'src'
* @param opa opacity (0, LV_OPA_TRANSP: transparent ... 255, LV_OPA_COVER, fully cover)
*/
void lv_disp_mem_fill(lv_color_t * dest, uint32_t length, lv_color_t color)
{
if(active == NULL) return;
if(active->driver.mem_fill != NULL) active->driver.mem_fill(dest, length, color);
}
/**
* Shows if memory blending (by GPU) is supported or not
* @return false: 'mem_blend' is not supported in the driver; true: 'mem_blend' is supported in the driver
*/
bool lv_disp_is_mem_blend_supported(void)
{
if(active->driver.mem_blend) return true;
else return false;
}
/**
* Shows if memory fill (by GPU) is supported or not
* @return false: 'mem_fill' is not supported in the drover; true: 'mem_fill' is supported in the driver
*/
bool lv_disp_is_mem_fill_supported(void)
{
if(active->driver.mem_fill) return true;
else return false;
}
#endif
/**********************
* STATIC FUNCTIONS
**********************/

View file

@ -0,0 +1,168 @@
/**
* @file hal_disp.h
*
* @description Display Driver HAL interface header file
*
*/
#ifndef HAL_DISP_H
#define HAL_DISP_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include <stdint.h>
#include <stdbool.h>
#include "lv_hal.h"
#include "../lv_misc/lv_color.h"
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**
* Display Driver structure to be registered by HAL
*/
typedef struct _disp_drv_t {
/*Write the internal buffer (VDB) to the display. 'lv_flush_ready()' has to be called when finished*/
void (*disp_flush)(int32_t x1, int32_t y1, int32_t x2, int32_t y2, const lv_color_t * color_p);
/*Fill an area with a color on the display*/
void (*disp_fill)(int32_t x1, int32_t y1, int32_t x2, int32_t y2, lv_color_t color);
/*Write pixel map (e.g. image) to the display*/
void (*disp_map)(int32_t x1, int32_t y1, int32_t x2, int32_t y2, const lv_color_t * color_p);
#if USE_LV_GPU
/*Blend two memories using opacity (GPU only)*/
void (*mem_blend)(lv_color_t * dest, const lv_color_t * src, uint32_t length, lv_opa_t opa);
/*Fill a memory with a color (GPU only)*/
void (*mem_fill)(lv_color_t * dest, uint32_t length, lv_color_t color);
#endif
} lv_disp_drv_t;
typedef struct _disp_t {
lv_disp_drv_t driver;
struct _disp_t *next;
} lv_disp_t;
/**********************
* GLOBAL PROTOTYPES
**********************/
/**
* Initialize a display driver with default values.
* It is used to surly have known values in the fields ant not memory junk.
* After it you can set the fields.
* @param driver pointer to driver variable to initialize
*/
void lv_disp_drv_init(lv_disp_drv_t *driver);
/**
* Register an initialized display driver.
* Automatically set the first display as active.
* @param driver pointer to an initialized 'lv_disp_drv_t' variable (can be local variable)
* @return pointer to the new display or NULL on error
*/
lv_disp_t * lv_disp_drv_register(lv_disp_drv_t *driver);
/**
* Set the active display
* @param disp pointer to a display (return value of 'lv_disp_register')
*/
void lv_disp_set_active(lv_disp_t * disp);
/**
* Get a pointer to the active display
* @return pointer to the active display
*/
lv_disp_t * lv_disp_get_active(void);
/**
* Get the next display.
* @param disp pointer to the current display. NULL to initialize.
* @return the next display or NULL if no more. Give the first display when the parameter is NULL
*/
lv_disp_t * lv_disp_next(lv_disp_t * disp);
/**
* Fill a rectangular area with a color on the active display
* @param x1 left coordinate of the rectangle
* @param x2 right coordinate of the rectangle
* @param y1 top coordinate of the rectangle
* @param y2 bottom coordinate of the rectangle
* @param color_p pointer to an array of colors
*/
void lv_disp_flush(int32_t x1, int32_t y1, int32_t x2, int32_t y2, lv_color_t *color_p);
/**
* Fill a rectangular area with a color on the active display
* @param x1 left coordinate of the rectangle
* @param x2 right coordinate of the rectangle
* @param y1 top coordinate of the rectangle
* @param y2 bottom coordinate of the rectangle
* @param color fill color
*/
void lv_disp_fill(int32_t x1, int32_t y1, int32_t x2, int32_t y2, lv_color_t color);
/**
* Put a color map to a rectangular area on the active display
* @param x1 left coordinate of the rectangle
* @param x2 right coordinate of the rectangle
* @param y1 top coordinate of the rectangle
* @param y2 bottom coordinate of the rectangle
* @param color_map pointer to an array of colors
*/
void lv_disp_map(int32_t x1, int32_t y1, int32_t x2, int32_t y2, const lv_color_t * color_map);
#if USE_LV_GPU
/**
* Blend pixels to a destination memory from a source memory
* In 'lv_disp_drv_t' 'mem_blend' is optional. (NULL if not available)
* @param dest a memory address. Blend 'src' here.
* @param src pointer to pixel map. Blend it to 'dest'.
* @param length number of pixels in 'src'
* @param opa opacity (0, LV_OPA_TRANSP: transparent ... 255, LV_OPA_COVER, fully cover)
*/
void lv_disp_mem_blend(lv_color_t * dest, const lv_color_t * src, uint32_t length, lv_opa_t opa);
/**
* Fill a memory with a color (GPUs may support it)
* In 'lv_disp_drv_t' 'mem_fill' is optional. (NULL if not available)
* @param dest a memory address. Copy 'src' here.
* @param src pointer to pixel map. Copy it to 'dest'.
* @param length number of pixels in 'src'
* @param opa opacity (0, LV_OPA_TRANSP: transparent ... 255, LV_OPA_COVER, fully cover)
*/
void lv_disp_mem_fill(lv_color_t * dest, uint32_t length, lv_color_t color);
/**
* Shows if memory blending (by GPU) is supported or not
* @return false: 'mem_blend' is not supported in the driver; true: 'mem_blend' is supported in the driver
*/
bool lv_disp_is_mem_blend_supported(void);
/**
* Shows if memory fill (by GPU) is supported or not
* @return false: 'mem_fill' is not supported in the drover; true: 'mem_fill' is supported in the driver
*/
bool lv_disp_is_mem_fill_supported(void);
#endif
/**********************
* MACROS
**********************/
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif

View file

@ -0,0 +1,120 @@
/**
* @file hal_indev.c
*
* @description Input device HAL interface
*
*/
/*********************
* INCLUDES
*********************/
#include "../lv_hal/lv_hal_indev.h"
#include "../lv_misc/lv_mem.h"
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
static lv_indev_t *indev_list = NULL;
/**********************
* STATIC VARIABLES
**********************/
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
/**
* Initialize an input device driver with default values.
* It is used to surly have known values in the fields ant not memory junk.
* After it you can set the fields.
* @param driver pointer to driver variable to initialize
*/
void lv_indev_drv_init(lv_indev_drv_t *driver)
{
driver->read = NULL;
driver->type = LV_INDEV_TYPE_NONE;
}
/**
* Register an initialized input device driver.
* @param driver pointer to an initialized 'lv_indev_drv_t' variable (can be local variable)
* @return pointer to the new input device or NULL on error
*/
lv_indev_t * lv_indev_drv_register(lv_indev_drv_t *driver)
{
lv_indev_t *node;
node = lv_mem_alloc(sizeof(lv_indev_t));
if (!node) return NULL;
memcpy(&node->driver, driver, sizeof(lv_indev_drv_t));
node->next = NULL;
node->proc.reset_query = 1;
node->cursor = NULL;
node->group = NULL;
if (indev_list == NULL) {
indev_list = node;
} else {
lv_indev_t *last = indev_list;
while (last->next)
last = last->next;
last->next = node;
}
return node;
}
/**
* Get the next input device.
* @param indev pointer to the current input device. NULL to initialize.
* @return the next input devise or NULL if no more. Give the first input device when the parameter is NULL
*/
lv_indev_t * lv_indev_next(lv_indev_t * indev)
{
if(indev == NULL) {
return indev_list;
} else {
if(indev->next == NULL) return NULL;
else return indev->next;
}
}
/**
* Read data from an input device.
* @param indev pointer to an input device
* @param data input device will write its data here
* @return false: no more data; true: there more data to read (buffered)
*/
bool lv_indev_read(lv_indev_t * indev, lv_indev_data_t *data)
{
bool cont = false;
if(indev->driver.read) {
cont = indev->driver.read(data);
} else {
memset(data, 0, sizeof(lv_indev_data_t));
}
return cont;
}
/**********************
* STATIC FUNCTIONS
**********************/

View file

@ -0,0 +1,148 @@
/**
* @file hal_indev.h
*
* @description Input Device HAL interface layer header file
*
*/
#ifndef HAL_INDEV_H
#define HAL_INDEV_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include <stdbool.h>
#include <stdint.h>
#include "lv_hal.h"
#include "../lv_misc/lv_area.h"
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/*Possible input device types*/
typedef enum {
LV_INDEV_TYPE_NONE, /*Show uninitialized state*/
LV_INDEV_TYPE_POINTER, /*Touch pad, mouse, external button*/
LV_INDEV_TYPE_KEYPAD, /*Keypad or keyboard*/
} lv_hal_indev_type_t;
/*States for input devices*/
typedef enum {
LV_INDEV_STATE_REL,
LV_INDEV_STATE_PR
}lv_indev_state_t;
/*Data type when an input device is read */
typedef struct {
union {
lv_point_t point; /*For INDEV_TYPE_POINTER*/
uint32_t key; /*For INDEV_TYPE_KEYPAD*/
};
lv_indev_state_t state; /*LV_INDEV_EVENT_REL or LV_INDEV_EVENT_PR*/
}lv_indev_data_t;
/*Initialized by the user and registered by 'lv_indev_add()'*/
typedef struct {
lv_hal_indev_type_t type; /*Input device type*/
bool (*read)(lv_indev_data_t *data); /*Function pointer to read data. Return 'true' if there is still data to be read (buffered)*/
}lv_indev_drv_t;
struct _lv_obj_t;
typedef struct _lv_indev_state_t {
lv_indev_state_t state;
union {
struct { /*Pointer data*/
lv_point_t act_point;
lv_point_t last_point;
lv_point_t vect;
lv_point_t drag_sum; /*Count the dragged pixels to check LV_INDEV_DRAG_LIMIT*/
struct _lv_obj_t * act_obj;
struct _lv_obj_t * last_obj;
/*Flags*/
uint8_t drag_range_out :1;
uint8_t drag_in_prog :1;
uint8_t wait_unil_release :1;
};
struct { /*Keypad data*/
lv_indev_state_t last_state;
};
};
uint32_t pr_timestamp; /*Pressed time stamp*/
uint32_t longpr_rep_timestamp; /*Long press repeat time stamp*/
/*Flags*/
uint8_t long_pr_sent :1;
uint8_t reset_query :1;
uint8_t disabled :1;
}lv_indev_proc_t;
struct _lv_obj_t;
struct _lv_group_t;
typedef struct _lv_indev_t {
lv_indev_drv_t driver;
lv_indev_proc_t proc;
uint32_t last_activity_time;
union {
struct _lv_obj_t *cursor;
struct _lv_group_t *group; /*Keypad destination group*/
};
struct _lv_indev_t *next;
} lv_indev_t;
/**********************
* GLOBAL PROTOTYPES
**********************/
/**
* Initialize an input device driver with default values.
* It is used to surly have known values in the fields ant not memory junk.
* After it you can set the fields.
* @param driver pointer to driver variable to initialize
*/
void lv_indev_drv_init(lv_indev_drv_t *driver);
/**
* Register an initialized input device driver.
* @param driver pointer to an initialized 'lv_indev_drv_t' variable (can be local variable)
* @return pointer to the new input device or NULL on error
*/
lv_indev_t * lv_indev_drv_register(lv_indev_drv_t *driver);
/**
* Get the next input device.
* @param indev pointer to the current input device. NULL to initialize.
* @return the next input devise or NULL if no more. Gives the first input device when the parameter is NULL
*/
lv_indev_t * lv_indev_next(lv_indev_t * indev);
/**
* Read data from an input device.
* @param indev pointer to an input device
* @param data input device will write its data here
* @return false: no more data; true: there more data to read (buffered)
*/
bool lv_indev_read(lv_indev_t * indev, lv_indev_data_t *data);
/**********************
* MACROS
**********************/
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif

View file

@ -0,0 +1,87 @@
/**
* @file systick.c
* Provide access to the system tick with 1 millisecond resolution
*/
/*********************
* INCLUDES
*********************/
#include "lv_hal_tick.h"
#include <stddef.h>
#include "../../lv_conf.h"
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
/**********************
* STATIC VARIABLES
**********************/
static uint32_t sys_time = 0;
static volatile uint8_t tick_irq_flag;
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
/**
* You have to call this function periodically
* @param tick_period the call period of this function in milliseconds
*/
inline void LV_ATTRIBUTE_TICK_INC lv_tick_inc(uint32_t tick_period)
{
tick_irq_flag = 0;
sys_time += tick_period;
}
/**
* Get the elapsed milliseconds since start up
* @return the elapsed milliseconds
*/
uint32_t lv_tick_get(void)
{
uint32_t result;
do {
tick_irq_flag = 1;
result = sys_time;
} while(!tick_irq_flag); /*'lv_tick_inc()' clears this flag which can be in an interrupt. Continue until make a non interrupted cycle */
return result;
}
/**
* Get the elapsed milliseconds science a previous time stamp
* @param prev_tick a previous time stamp (return value of systick_get() )
* @return the elapsed milliseconds since 'prev_tick'
*/
uint32_t lv_tick_elaps(uint32_t prev_tick)
{
uint32_t act_time = lv_tick_get();
/*If there is no overflow in sys_time simple subtract*/
if(act_time >= prev_tick) {
prev_tick = act_time - prev_tick;
} else {
prev_tick = UINT32_MAX - prev_tick + 1;
prev_tick += act_time;
}
return prev_tick;
}
/**********************
* STATIC FUNCTIONS
**********************/

View file

@ -0,0 +1,61 @@
/**
* @file lv_hal_tick.h
* Provide access to the system tick with 1 millisecond resolution
*/
#ifndef LV_HAL_TICK_H
#define LV_HAL_TICK_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include <stdint.h>
#include <stdbool.h>
/*********************
* DEFINES
*********************/
#ifndef LV_ATTRIBUTE_TICK_INC
#define LV_ATTRIBUTE_TICK_INC
#endif
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
/**
* You have to call this function periodically
* @param tick_period the call period of this function in milliseconds
*/
void lv_tick_inc(uint32_t tick_period);
/**
* Get the elapsed milliseconds since start up
* @return the elapsed milliseconds
*/
uint32_t lv_tick_get(void);
/**
* Get the elapsed milliseconds science a previous time stamp
* @param prev_tick a previous time stamp (return value of systick_get() )
* @return the elapsed milliseconds since 'prev_tick'
*/
uint32_t lv_tick_elaps(uint32_t prev_tick);
/**********************
* MACROS
**********************/
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /*LV_HAL_TICK_H*/

View file

@ -0,0 +1,259 @@
/**
* @file anim.c
*
*/
/*********************
* INCLUDES
*********************/
#include "lv_anim.h"
#if USE_LV_ANIMATION
#include <stddef.h>
#include <string.h>
#include "../lv_hal/lv_hal_tick.h"
#include "lv_task.h"
#include "lv_math.h"
/*********************
* DEFINES
*********************/
#define LV_ANIM_RESOLUTION 1024
#define LV_ANIM_RES_SHIFT 10
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
static void anim_task (void * param);
static bool anim_ready_handler(lv_anim_t * a);
/**********************
* STATIC VARIABLES
**********************/
static lv_ll_t anim_ll;
static uint32_t last_task_run;
static bool anim_del_global_flag = false;
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
/**
* Init. the animation module
*/
void lv_anim_init(void)
{
lv_ll_init(&anim_ll, sizeof(lv_anim_t));
last_task_run = lv_tick_get();
lv_task_create(anim_task, LV_REFR_PERIOD, LV_TASK_PRIO_MID, NULL);
}
/**
* Create an animation
* @param anim_p an initialized 'anim_t' variable. Not required after call.
*/
void lv_anim_create(lv_anim_t * anim_p)
{
/* Do not let two animations for the same 'var' with the same 'fp'*/
if(anim_p->fp != NULL) lv_anim_del(anim_p->var, anim_p->fp); /*fp == NULL would delete all animations of var*/
/*Add the new animation to the animation linked list*/
lv_anim_t * new_anim = lv_ll_ins_head(&anim_ll);
lv_mem_assert(new_anim);
/*Initialize the animation descriptor*/
anim_p->playback_now = 0;
memcpy(new_anim, anim_p, sizeof(lv_anim_t));
/*Set the start value*/
if(new_anim->fp != NULL) new_anim->fp(new_anim->var, new_anim->start);
}
/**
* Delete an animation for a variable with a given animator function
* @param var pointer to variable
* @param fp a function pointer which is animating 'var',
* or NULL to delete all animations of 'var'
* @return true: at least 1 animation is deleted, false: no animation is deleted
*/
bool lv_anim_del(void * var, lv_anim_fp_t fp)
{
bool del = false;
lv_anim_t * a;
lv_anim_t * a_next;
a = lv_ll_get_head(&anim_ll);
while(a != NULL) {
/*'a' might be deleted, so get the next object while 'a' is valid*/
a_next = lv_ll_get_next(&anim_ll, a);
if(a->var == var && (a->fp == fp || fp == NULL)) {
lv_ll_rem(&anim_ll, a);
lv_mem_free(a);
del = true;
anim_del_global_flag = true;
}
a = a_next;
}
return del;
}
/**
* Calculate the time of an animation with a given speed and the start and end values
* @param speed speed of animation in unit/sec
* @param start start value of the animation
* @param end end value of the animation
* @return the required time [ms] for the animation with the given parameters
*/
uint16_t lv_anim_speed_to_time(uint16_t speed, int32_t start, int32_t end)
{
int32_t d = LV_MATH_ABS((int32_t) start - end);
uint16_t time = (int32_t)((int32_t)(d * 1000) / speed);
if(time == 0) {
time++;
}
return time;
}
/**
* Calculate the current value of an animation applying linear characteristic
* @param a pointer to an animation
* @return the current value to set
*/
int32_t lv_anim_path_linear(const lv_anim_t *a)
{
/*Calculate the current step*/
uint16_t step;
if(a->time == a->act_time) step = LV_ANIM_RESOLUTION; /*Use the last value id the time fully elapsed*/
else step = (a->act_time * LV_ANIM_RESOLUTION) / a->time;
/* Get the new value which will be proportional to the current element of 'path_p'
* and the 'start' and 'end' values*/
int32_t new_value;
new_value = (int32_t) step * (a->end - a->start);
new_value = new_value >> LV_ANIM_RES_SHIFT;
new_value += a->start;
return new_value;
}
/**
* Calculate the current value of an animation applying step characteristic.
* (Set end value on the end of the animation)
* @param a pointer to an animation
* @return the current value to set
*/
int32_t lv_anim_path_step(const lv_anim_t *a)
{
if(a->act_time >= a->time) return a->end;
else return a->start;
}
/**********************
* STATIC FUNCTIONS
**********************/
/**
* Periodically handle the animations.
* @param param unused
*/
static void anim_task (void * param)
{
(void)param;
volatile uint32_t elaps;
elaps = lv_tick_elaps(last_task_run);
lv_anim_t * a;
lv_anim_t * a_next;
a = lv_ll_get_head(&anim_ll);
while(a != NULL) {
/*'a' might be deleted, so get the next object while 'a' is valid*/
a_next = lv_ll_get_next(&anim_ll, a);
a->act_time += elaps;
if(a->act_time >= 0) {
if(a->act_time > a->time) a->act_time = a->time;
int32_t new_value;
new_value = a->path(a);
if(a->fp != NULL) a->fp(a->var, new_value); /*Apply the calculated value*/
/*If the time is elapsed the animation is ready*/
if(a->act_time >= a->time) {
bool invalid;
invalid = anim_ready_handler(a);
if(invalid != false) {
a_next = lv_ll_get_head(&anim_ll); /*a_next might be invalid if animation delete occurred*/
}
}
}
a = a_next;
}
last_task_run = lv_tick_get();
}
/**
* Called when an animation is ready to do the necessary thinks
* e.g. repeat, play back, delete etc.
* @param a pointer to an animation descriptor
* @return true: animation delete occurred
* */
static bool anim_ready_handler(lv_anim_t * a)
{
bool invalid = false;
/*Delete the animation if
* - no repeat and no play back (simple one shot animation)
* - no repeat, play back is enabled and play back is ready */
if((a->repeat == 0 && a->playback == 0) ||
(a->repeat == 0 && a->playback == 1 && a->playback_now == 1)) {
void (*cb) (void *) = a->end_cb;
void * p = a->var;
lv_ll_rem(&anim_ll, a);
lv_mem_free(a);
/*Call the callback function at the end*/
/* Check if an animation is deleted in the cb function
* if yes then the caller function has to know this*/
anim_del_global_flag = false;
if(cb != NULL) cb(p);
invalid = anim_del_global_flag;
}
/*If the animation is not deleted then restart it*/
else {
a->act_time = - a->repeat_pause; /*Restart the animation*/
/*Swap the start and end values in play back mode*/
if(a->playback != 0) {
/*If now turning back use the 'playback_pause*/
if(a->playback_now == 0) a->act_time = - a->playback_pause;
/*Toggle the play back state*/
a->playback_now = a->playback_now == 0 ? 1: 0;
/*Swap the start and end values*/
int32_t tmp;
tmp = a->start;
a->start = a->end;
a->end = tmp;
}
}
return invalid;
}
#endif

View file

@ -0,0 +1,129 @@
/**
* @file anim.h
*
*/
#ifndef ANIM_H
#define ANIM_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include "../../lv_conf.h"
#if USE_LV_ANIMATION
#include <stdint.h>
#include <stdbool.h>
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
struct _lv_anim_t;
typedef int32_t(*lv_anim_path_t)(const struct _lv_anim_t*);
typedef void (*lv_anim_fp_t)(void *, int32_t);
typedef void (*lv_anim_cb_t)(void *);
typedef struct _lv_anim_t
{
void * var; /*Variable to animate*/
lv_anim_fp_t fp; /*Animator function*/
lv_anim_cb_t end_cb; /*Call it when the animation is ready*/
lv_anim_path_t path; /*An array with the steps of animations*/
int32_t start; /*Start value*/
int32_t end; /*End value*/
int16_t time; /*Animation time in ms*/
int16_t act_time; /*Current time in animation. Set to negative to make delay.*/
uint16_t playback_pause; /*Wait before play back*/
uint16_t repeat_pause; /*Wait before repeat*/
uint8_t playback :1; /*When the animation is ready play it back*/
uint8_t repeat :1; /*Repeat the animation infinitely*/
/*Animation system use these - user shouldn't set*/
uint8_t playback_now :1; /*Play back is in progress*/
}lv_anim_t;
/*Example initialization
lv_anim_t a;
a.var = obj;
a.start = lv_obj_get_height(obj);
a.end = new_height;
a.fp = (lv_anim_fp_t)lv_obj_set_height;
a.path = lv_anim_path_linear;
a.end_cb = NULL;
a.act_time = 0;
a.time = 200;
a.playback = 0;
a.playback_pause = 0;
a.repeat = 0;
a.repeat_pause = 0;
*/
/**********************
* GLOBAL PROTOTYPES
**********************/
/**
* Init. the animation module
*/
void lv_anim_init(void);
/**
* Create an animation
* @param anim_p an initialized 'anim_t' variable. Not required after call.
*/
void lv_anim_create(lv_anim_t * anim_p);
/**
* Delete an animation for a variable with a given animatior function
* @param var pointer to variable
* @param fp a function pointer which is animating 'var',
* or NULL to ignore it and delete all animation with 'var
* @return true: at least 1 animation is deleted, false: no animation is deleted
*/
bool lv_anim_del(void * var, lv_anim_fp_t fp);
/**
* Calculate the time of an animation with a given speed and the start and end values
* @param speed speed of animation in unit/sec
* @param start start value of the animation
* @param end end value of the animation
* @return the required time [ms] for the animation with the given parameters
*/
uint16_t lv_anim_speed_to_time(uint16_t speed, int32_t start, int32_t end);
/**
* Calculate the current value of an animation applying linear characteristic
* @param a pointer to an animation
* @return the current value to set
*/
int32_t lv_anim_path_linear(const lv_anim_t *a);
/**
* Calculate the current value of an animation applying step characteristic.
* (Set end value on the end of the animation)
* @param a pointer to an animation
* @return the current value to set
*/
int32_t lv_anim_path_step(const lv_anim_t *a);
/**********************
* MACROS
**********************/
#endif /*LV_NO_ANIM == 0*/
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /*LV_ANIM_H*/

View file

@ -0,0 +1,233 @@
/**
* @file lv_area.c
*
*/
/*********************
* INCLUDES
*********************/
#include "lv_area.h"
#include "lv_math.h"
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
/**********************
* STATIC VARIABLES
**********************/
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
/**
* Initialize an area
* @param area_p pointer to an area
* @param x1 left coordinate of the area
* @param y1 top coordinate of the area
* @param x2 right coordinate of the area
* @param y2 bottom coordinate of the area
*/
void lv_area_set(lv_area_t * area_p, lv_coord_t x1, lv_coord_t y1, lv_coord_t x2, lv_coord_t y2)
{
area_p->x1 = x1;
area_p->y1 = y1;
area_p->x2 = x2;
area_p->y2 = y2;
}
/**
* Set the width of an area
* @param area_p pointer to an area
* @param w the new width of the area (w == 1 makes x1 == x2)
*/
void lv_area_set_width(lv_area_t * area_p, lv_coord_t w)
{
area_p->x2 = area_p->x1 + w - 1;
}
/**
* Set the height of an area
* @param area_p pointer to an area
* @param h the new height of the area (h == 1 makes y1 == y2)
*/
void lv_area_set_height(lv_area_t * area_p, lv_coord_t h)
{
area_p->y2 = area_p->y1 + h - 1;
}
/**
* Set the position of an area (width and height will be kept)
* @param area_p pointer to an area
* @param x the new x coordinate of the area
* @param y the new y coordinate of the area
*/
void lv_area_set_pos(lv_area_t * area_p, lv_coord_t x, lv_coord_t y)
{
lv_coord_t w = lv_area_get_width(area_p);
lv_coord_t h = lv_area_get_height(area_p);
area_p->x1 = x;
area_p->y1 = y;
lv_area_set_width(area_p, w);
lv_area_set_height(area_p, h);
}
/**
* Return with area of an area (x * y)
* @param area_p pointer to an area
* @return size of area
*/
uint32_t lv_area_get_size(const lv_area_t * area_p)
{
uint32_t size;
size = (uint32_t)(area_p->x2 - area_p->x1 + 1) *
(area_p->y2 - area_p->y1 + 1);
return size;
}
/**
* Get the common parts of two areas
* @param res_p pointer to an area, the result will be stored her
* @param a1_p pointer to the first area
* @param a2_p pointer to the second area
* @return false: the two area has NO common parts, res_p is invalid
*/
bool lv_area_union(lv_area_t * res_p, const lv_area_t * a1_p, const lv_area_t * a2_p)
{
/* Get the smaller area from 'a1_p' and 'a2_p' */
res_p->x1 = LV_MATH_MAX(a1_p->x1, a2_p->x1);
res_p->y1 = LV_MATH_MAX(a1_p->y1, a2_p->y1);
res_p->x2 = LV_MATH_MIN(a1_p->x2, a2_p->x2);
res_p->y2 = LV_MATH_MIN(a1_p->y2, a2_p->y2);
/*If x1 or y1 greater then x2 or y2 then the areas union is empty*/
bool union_ok = true;
if((res_p->x1 > res_p->x2) ||
(res_p->y1 > res_p->y2))
{
union_ok = false;
}
return union_ok;
}
/**
* Join two areas into a third which involves the other two
* @param res_p pointer to an area, the result will be stored here
* @param a1_p pointer to the first area
* @param a2_p pointer to the second area
*/
void lv_area_join(lv_area_t * a_res_p, const lv_area_t * a1_p, const lv_area_t * a2_p)
{
a_res_p->x1 = LV_MATH_MIN(a1_p->x1, a2_p->x1);
a_res_p->y1 = LV_MATH_MIN(a1_p->y1, a2_p->y1);
a_res_p->x2 = LV_MATH_MAX(a1_p->x2, a2_p->x2);
a_res_p->y2 = LV_MATH_MAX(a1_p->y2, a2_p->y2);
}
/**
* Check if a point is on an area
* @param a_p pointer to an area
* @param p_p pointer to a point
* @return false:the point is out of the area
*/
bool lv_area_is_point_on(const lv_area_t * a_p, const lv_point_t * p_p)
{
bool is_on = false;
if((p_p->x >= a_p->x1 && p_p->x <= a_p->x2) &&
((p_p->y >= a_p->y1 && p_p->y <= a_p->y2)))
{
is_on = true;
}
return is_on;
}
/**
* Check if two area has common parts
* @param a1_p pointer to an area.
* @param a2_p pointer to an other area
* @return false: a1_p and a2_p has no common parts
*/
bool lv_area_is_on(const lv_area_t * a1_p, const lv_area_t * a2_p)
{
/*Two area are on each other if... */
lv_point_t p;
/*a2 left-top corner is on a1*/
p.x = a2_p->x1;
p.y = a2_p->y1;
if(lv_area_is_point_on(a1_p, &p)) return true;
/*a2 right-top corner is on a1*/
p.x = a2_p->x1;
p.y = a2_p->y1;
if(lv_area_is_point_on(a1_p, &p)) return true;
/*a2 left-bottom corner is on a1*/
p.x = a2_p->x1;
p.y = a2_p->y2;
if(lv_area_is_point_on(a1_p, &p)) return true;
/*a2 right-bottom corner is on a1*/
p.x = a2_p->x2;
p.y = a2_p->y2;
if(lv_area_is_point_on(a1_p, &p)) return true;
/*a2 is horizontally bigger then a1 and covers it*/
if((a2_p->x1 <= a1_p->x1 && a2_p->x2 >= a1_p->x2) && /*a2 hor. cover a1?*/
((a2_p->y1 <= a1_p->y1 && a2_p->y1 >= a1_p->y2) || /*upper edge is on a1?*/
(a2_p->y2 <= a1_p->y1 && a2_p->y2 >= a1_p->y2) ||/* or lower edge is on a1?*/
(a2_p->y1 <= a1_p->y1 && a2_p->y2 >= a1_p->y2))) /*or a2 vert bigger then a1*/
return true;
/*a2 is vertically bigger then a1 and covers it*/
if((a2_p->y1 <= a1_p->y1 && a2_p->y2 >= a1_p->y2) && /*a2 vert. cover a1?*/
((a2_p->x1 <= a1_p->x1 && a2_p->x1 >= a1_p->x2) || /*left edge is on a1?*/
(a2_p->x2 <= a1_p->x1 && a2_p->x2 >= a1_p->x2) ||/* or right edge is on a1?*/
(a2_p->x1 <= a1_p->x1 && a2_p->x2 >= a1_p->x2))) /*or a2 hor. bigger then a1*/
return true;
/*Else no cover*/
return false;
}
/**
* Check if an area is fully on an other
* @param ain_p pointer to an area which could be in 'aholder_p'
* @param aholder pointer to an area which could involve 'ain_p'
* @return
*/
bool lv_area_is_in(const lv_area_t * ain_p, const lv_area_t * aholder_p)
{
bool is_in = false;
if(ain_p->x1 >= aholder_p->x1 &&
ain_p->y1 >= aholder_p->y1 &&
ain_p->x2 <= aholder_p->x2 &&
ain_p->y2 <= aholder_p->y2)
{
is_in = true;
}
return is_in;
}
/**********************
* STATIC FUNCTIONS
**********************/

View file

@ -0,0 +1,169 @@
/**
* @file lv_area.h
*
*/
#ifndef LV_AREA_H
#define LV_AREA_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include <string.h>
#include <stdbool.h>
#include <stdint.h>
/*********************
* DEFINES
*********************/
#define LV_COORD_MAX (16383) /*To avoid overflow don't let the max [-32,32k] range */
#define LV_COORD_MIN (-16384)
/**********************
* TYPEDEFS
**********************/
typedef int16_t lv_coord_t;
typedef struct
{
lv_coord_t x;
lv_coord_t y;
}lv_point_t;
typedef struct
{
lv_coord_t x1;
lv_coord_t y1;
lv_coord_t x2;
lv_coord_t y2;
}lv_area_t;
/**********************
* GLOBAL PROTOTYPES
**********************/
/**
* Initialize an area
* @param area_p pointer to an area
* @param x1 left coordinate of the area
* @param y1 top coordinate of the area
* @param x2 right coordinate of the area
* @param y2 bottom coordinate of the area
*/
void lv_area_set(lv_area_t * area_p, lv_coord_t x1, lv_coord_t y1, lv_coord_t x2, lv_coord_t y2);
/**
* Copy an area
* @param dest pointer to the destination area
* @param src pointer to the source area
*/
inline static void lv_area_copy(lv_area_t * dest, const lv_area_t * src)
{
memcpy(dest, src, sizeof(lv_area_t));
}
/**
* Get the width of an area
* @param area_p pointer to an area
* @return the width of the area (if x1 == x2 -> width = 1)
*/
static inline lv_coord_t lv_area_get_width(const lv_area_t * area_p)
{
return area_p->x2 - area_p->x1 + 1;
}
/**
* Get the height of an area
* @param area_p pointer to an area
* @return the height of the area (if y1 == y2 -> height = 1)
*/
static inline lv_coord_t lv_area_get_height(const lv_area_t * area_p)
{
return area_p->y2 - area_p->y1 + 1;
}
/**
* Set the width of an area
* @param area_p pointer to an area
* @param w the new width of the area (w == 1 makes x1 == x2)
*/
void lv_area_set_width(lv_area_t * area_p, lv_coord_t w);
/**
* Set the height of an area
* @param area_p pointer to an area
* @param h the new height of the area (h == 1 makes y1 == y2)
*/
void lv_area_set_height(lv_area_t * area_p, lv_coord_t h);
/**
* Set the position of an area (width and height will be kept)
* @param area_p pointer to an area
* @param x the new x coordinate of the area
* @param y the new y coordinate of the area
*/
void lv_area_set_pos(lv_area_t * area_p, lv_coord_t x, lv_coord_t y);
/**
* Return with area of an area (x * y)
* @param area_p pointer to an area
* @return size of area
*/
uint32_t lv_area_get_size(const lv_area_t * area_p);
/**
* Get the common parts of two areas
* @param res_p pointer to an area, the result will be stored her
* @param a1_p pointer to the first area
* @param a2_p pointer to the second area
* @return false: the two area has NO common parts, res_p is invalid
*/
bool lv_area_union(lv_area_t * res_p, const lv_area_t * a1_p, const lv_area_t * a2_p);
/**
* Join two areas into a third which involves the other two
* @param res_p pointer to an area, the result will be stored here
* @param a1_p pointer to the first area
* @param a2_p pointer to the second area
*/
void lv_area_join(lv_area_t * a_res_p, const lv_area_t * a1_p, const lv_area_t * a2_p);
/**
* Check if a point is on an area
* @param a_p pointer to an area
* @param p_p pointer to a point
* @return false:the point is out of the area
*/
bool lv_area_is_point_on(const lv_area_t * a_p, const lv_point_t * p_p);
/**
* Check if two area has common parts
* @param a1_p pointer to an area.
* @param a2_p pointer to an other area
* @return false: a1_p and a2_p has no common parts
*/
bool lv_area_is_on(const lv_area_t * a1_p, const lv_area_t * a2_p);
/**
* Check if an area is fully on an other
* @param ain_p pointer to an area which could be on aholder_p
* @param aholder pointer to an area which could involve ain_p
* @return
*/
bool lv_area_is_in(const lv_area_t * ain_p, const lv_area_t * aholder_p);
/**********************
* MACROS
**********************/
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif

View file

@ -0,0 +1,79 @@
/**
* @file lv_circ.c
* Circle drawing algorithm (with Bresenham)
* Only a 1/8 circle is calculated. Use CIRC_OCT1_X, CIRC_OCT1_Y macros to get
* the other octets.
*/
/*********************
* INCLUDES
*********************/
#include "lv_area.h"
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
/**********************
* STATIC VARIABLES
**********************/
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
/**
* Initialize the circle drawing
* @param c pointer to a point. The coordinates will be calculated here
* @param tmp point to a variable. It will store temporary data
* @param radius radius of the circle
*/
void lv_circ_init(lv_point_t * c, lv_coord_t * tmp, lv_coord_t radius)
{
c->x = radius;
c->y = 0;
*tmp = 1 - radius;
}
/**
* Test the circle drawing is ready or not
* @param c same as in circ_init
* @return true if the circle is not ready yet
*/
bool lv_circ_cont(lv_point_t * c)
{
return c->y <= c->x ? true : false;
}
/**
* Get the next point from the circle
* @param c same as in circ_init. The next point stored here.
* @param tmp same as in circ_init.
*/
void lv_circ_next(lv_point_t * c, lv_coord_t * tmp)
{
c->y++;
if (*tmp <= 0) {
(*tmp) += 2 * c->y + 1; // Change in decision criterion for y -> y+1
} else {
c->x--;
(*tmp) += 2 * (c->y - c->x) + 1; // Change for y -> y+1, x -> x-1
}
}
/**********************
* STATIC FUNCTIONS
**********************/

View file

@ -0,0 +1,79 @@
/**
* @file lv_circ.h
*
*/
#ifndef LV_CIRC_H
#define LV_CIRC_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include <stddef.h>
#include "lv_area.h"
/*********************
* DEFINES
*********************/
#define LV_CIRC_OCT1_X(p) (p.x)
#define LV_CIRC_OCT1_Y(p) (p.y)
#define LV_CIRC_OCT2_X(p) (p.y)
#define LV_CIRC_OCT2_Y(p) (p.x)
#define LV_CIRC_OCT3_X(p) (-p.y)
#define LV_CIRC_OCT3_Y(p) (p.x)
#define LV_CIRC_OCT4_X(p) (-p.x)
#define LV_CIRC_OCT4_Y(p) (p.y)
#define LV_CIRC_OCT5_X(p) (-p.x)
#define LV_CIRC_OCT5_Y(p) (-p.y)
#define LV_CIRC_OCT6_X(p) (-p.y)
#define LV_CIRC_OCT6_Y(p) (-p.x)
#define LV_CIRC_OCT7_X(p) (p.y)
#define LV_CIRC_OCT7_Y(p) (-p.x)
#define LV_CIRC_OCT8_X(p) (p.x)
#define LV_CIRC_OCT8_Y(p) (-p.y)
/**********************
* TYPEDEFS
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
/**
* Initialize the circle drawing
* @param c pointer to a point. The coordinates will be calculated here
* @param tmp point to a variable. It will store temporary data
* @param radius radius of the circle
*/
void lv_circ_init(lv_point_t * c, lv_coord_t * tmp, lv_coord_t radius);
/**
* Test the circle drawing is ready or not
* @param c same as in circ_init
* @return true if the circle is not ready yet
*/
bool lv_circ_cont(lv_point_t * c);
/**
* Get the next point from the circle
* @param c same as in circ_init. The next point stored here.
* @param tmp same as in circ_init.
*/
void lv_circ_next(lv_point_t * c, lv_coord_t * tmp);
/**********************
* MACROS
**********************/
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif

View file

@ -0,0 +1,135 @@
/**
* @file lv_color.c
*
*/
/*********************
* INCLUDES
*********************/
#include "lv_color.h"
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
/**********************
* STATIC VARIABLES
**********************/
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
/**********************
* STATIC FUNCTIONS
**********************/
/**
* Convert a HSV color to RGB
* @param h hue [0..359]
* @param s saturation [0..100]
* @param v value [0..100]
* @return the given RGB color in RGB (with LV_COLOR_DEPTH depth)
*/
lv_color_t lv_color_hsv_to_rgb(uint16_t h, uint8_t s, uint8_t v)
{
h = (uint32_t)((uint32_t)h * 255) / 360;
s = (uint16_t)((uint16_t)s * 255) / 100;
v = (uint16_t)((uint16_t)v * 255) / 100;
uint8_t r, g, b;
uint8_t region, remainder, p, q, t;
if (s == 0)
{
r = v;
g = v;
b = v;
return LV_COLOR_MAKE(v, v, v);
}
region = h / 43;
remainder = (h - (region * 43)) * 6;
p = (v * (255 - s)) >> 8;
q = (v * (255 - ((s * remainder) >> 8))) >> 8;
t = (v * (255 - ((s * (255 - remainder)) >> 8))) >> 8;
switch (region)
{
case 0:
r = v; g = t; b = p;
break;
case 1:
r = q; g = v; b = p;
break;
case 2:
r = p; g = v; b = t;
break;
case 3:
r = p; g = q; b = v;
break;
case 4:
r = t; g = p; b = v;
break;
default:
r = v; g = p; b = q;
break;
}
lv_color_t result = LV_COLOR_MAKE(r, g, b);
return result;
}
/**
* Convert an RGB color to HSV
* @param r red
* @param g green
* @param b blue
* @return the given RGB color n HSV
*/
lv_color_hsv_t lv_color_rgb_to_hsv(uint8_t r, uint8_t g, uint8_t b)
{
lv_color_hsv_t hsv;
uint8_t rgbMin, rgbMax;
rgbMin = r < g ? (r < b ? r : b) : (g < b ? g : b);
rgbMax = r > g ? (r > b ? r : b) : (g > b ? g : b);
hsv.v = rgbMax;
if (hsv.v == 0)
{
hsv.h = 0;
hsv.s = 0;
return hsv;
}
hsv.s = 255 * (long)(rgbMax - rgbMin) / hsv.v;
if (hsv.s == 0)
{
hsv.h = 0;
return hsv;
}
if (rgbMax == r)
hsv.h = 0 + 43 * (g - b) / (rgbMax - rgbMin);
else if (rgbMax == g)
hsv.h = 85 + 43 * (b - r) / (rgbMax - rgbMin);
else
hsv.h = 171 + 43 * (r - g) / (rgbMax - rgbMin);
return hsv;
}

View file

@ -0,0 +1,328 @@
/**
* @file lv_color.h
*
*/
#ifndef LV_COLOR_H
#define LV_COLOR_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include "../../lv_conf.h"
#include <stdint.h>
/*********************
* DEFINES
*********************/
#define LV_COLOR_BLACK LV_COLOR_MAKE(0x00,0x00,0x00)
#define LV_COLOR_WHITE LV_COLOR_MAKE(0xFF,0xFF,0xFF)
#define LV_COLOR_RED LV_COLOR_MAKE(0xFF,0x00,0x00)
#define LV_COLOR_LIME LV_COLOR_MAKE(0x00,0xFF,0x00)
#define LV_COLOR_BLUE LV_COLOR_MAKE(0x00,0x00,0xFF)
#define LV_COLOR_YELLOW LV_COLOR_MAKE(0xFF,0xFF,0x00)
#define LV_COLOR_CYAN LV_COLOR_MAKE(0x00,0xFF,0xFF)
#define LV_COLOR_AQUA LV_COLOR_CYAN
#define LV_COLOR_MAGENTA LV_COLOR_MAKE(0xFF,0x00,0xFF)
#define LV_COLOR_SILVER LV_COLOR_MAKE(0xC0,0xC0,0xC0)
#define LV_COLOR_GRAY LV_COLOR_MAKE(0x80,0x80,0x80)
#define LV_COLOR_MARRON LV_COLOR_MAKE(0x80,0x00,0x00)
#define LV_COLOR_OLIVE LV_COLOR_MAKE(0x80,0x80,0x00)
#define LV_COLOR_GREEN LV_COLOR_MAKE(0x00,0x80,0x00)
#define LV_COLOR_PURPLE LV_COLOR_MAKE(0x80,0x00,0x80)
#define LV_COLOR_TEAL LV_COLOR_MAKE(0x00,0x80,0x80)
#define LV_COLOR_NAVY LV_COLOR_MAKE(0x00,0x00,0x80)
#define LV_COLOR_ORANGE LV_COLOR_MAKE(0xFF,0xA5,0x00)
#define LV_OPA_TRANSP 0
#define LV_OPA_0 0
#define LV_OPA_10 25
#define LV_OPA_20 51
#define LV_OPA_30 76
#define LV_OPA_40 102
#define LV_OPA_50 127
#define LV_OPA_60 153
#define LV_OPA_70 178
#define LV_OPA_80 204
#define LV_OPA_90 229
#define LV_OPA_100 255
#define LV_OPA_COVER 255
/**********************
* TYPEDEFS
**********************/
typedef union
{
uint8_t blue :1;
uint8_t green :1;
uint8_t red :1;
uint8_t full :1;
}lv_color1_t;
typedef union
{
struct
{
uint8_t blue :2;
uint8_t green :3;
uint8_t red :3;
};
uint8_t full;
}lv_color8_t;
typedef union
{
struct
{
uint16_t blue :5;
uint16_t green :6;
uint16_t red :5;
};
uint16_t full;
}lv_color16_t;
typedef union
{
struct
{
uint8_t blue;
uint8_t green;
uint8_t red;
uint8_t alpha;
};
uint32_t full;
}lv_color24_t;
#if LV_COLOR_DEPTH == 1
typedef uint8_t lv_color_int_t;
typedef lv_color1_t lv_color_t;
#elif LV_COLOR_DEPTH == 8
typedef uint8_t lv_color_int_t;
typedef lv_color8_t lv_color_t;
#elif LV_COLOR_DEPTH == 16
typedef uint16_t lv_color_int_t;
typedef lv_color16_t lv_color_t;
#elif LV_COLOR_DEPTH == 24
typedef uint32_t lv_color_int_t;
typedef lv_color24_t lv_color_t;
#else
#error "Invalid LV_COLOR_DEPTH in misc_conf.h! Set it to 1, 8, 16 or 24!"
#endif
typedef uint8_t lv_opa_t;
typedef struct
{
uint16_t h;
uint8_t s;
uint8_t v;
} lv_color_hsv_t;
/**********************
* GLOBAL PROTOTYPES
**********************/
/*In color conversations:
* - When converting to bigger color type the LSB weight of 1 LSB is calculated
* E.g. 16 bit Red has 5 bits
* 8 bit Red has 2 bits
* ----------------------
* 8 bit red LSB = (2^5 - 1) / (2^2 - 1) = 31 / 3 = 10
*
* - When calculating to smaller color type simply shift out the LSBs
* E.g. 8 bit Red has 2 bits
* 16 bit Red has 5 bits
* ----------------------
* Shift right with 5 - 3 = 2
*/
static inline uint8_t lv_color_to1(lv_color_t color)
{
#if LV_COLOR_DEPTH == 1
return color.full;
#elif LV_COLOR_DEPTH == 8
if((color.red & 0x4) ||
(color.green & 0x4) ||
(color.blue & 0x2)) {
return 1;
} else {
return 0;
}
#elif LV_COLOR_DEPTH == 16
if((color.red & 0x10) ||
(color.green & 0x20) ||
(color.blue & 0x10)) {
return 1;
} else {
return 0;
}
#elif LV_COLOR_DEPTH == 24
if((color.red & 0x80) ||
(color.green & 0x80) ||
(color.blue & 0x80)) {
return 1;
} else {
return 0;
}
#endif
}
static inline uint8_t lv_color_to8(lv_color_t color)
{
#if LV_COLOR_DEPTH == 1
if(color.full == 0) return 0;
else return 0xFF;
#elif LV_COLOR_DEPTH == 8
return color.full;
#elif LV_COLOR_DEPTH == 16
lv_color8_t ret;
ret.red = color.red >> 2; /* 5 - 3 = 2*/
ret.green = color.green >> 3; /* 6 - 3 = 3*/
ret.blue = color.blue >> 3; /* 5 - 2 = 3*/
return ret.full;
#elif LV_COLOR_DEPTH == 24
lv_color8_t ret;
ret.red = color.red >> 5; /* 8 - 3 = 5*/
ret.green = color.green >> 5; /* 8 - 3 = 5*/
ret.blue = color.blue >> 6; /* 8 - 2 = 6*/
return ret.full;
#endif
}
static inline uint16_t lv_color_to16(lv_color_t color)
{
#if LV_COLOR_DEPTH == 1
if(color.full == 0) return 0;
else return 0xFFFF;
#elif LV_COLOR_DEPTH == 8
lv_color16_t ret;
ret.red = color.red * 4; /*(2^5 - 1)/(2^3 - 1) = 31/7 = 4*/
ret.green = color.green * 9; /*(2^6 - 1)/(2^3 - 1) = 63/7 = 9*/
ret.blue = color.blue * 10; /*(2^5 - 1)/(2^2 - 1) = 31/3 = 10*/
return ret.full;
#elif LV_COLOR_DEPTH == 16
return color.full;
#elif LV_COLOR_DEPTH == 24
lv_color16_t ret;
ret.red = color.red >> 3; /* 8 - 5 = 3*/
ret.green = color.green >> 2; /* 8 - 6 = 2*/
ret.blue = color.blue >> 3; /* 8 - 5 = 3*/
return ret.full;
#endif
}
static inline uint32_t lv_color_to24(lv_color_t color)
{
#if LV_COLOR_DEPTH == 1
if(color.full == 0) return 0;
else return 0xFFFFFFFF;
#elif LV_COLOR_DEPTH == 8
lv_color24_t ret;
ret.red = color.red * 36; /*(2^8 - 1)/(2^3 - 1) = 255/7 = 36*/
ret.green = color.green * 36; /*(2^8 - 1)/(2^3 - 1) = 255/7 = 36*/
ret.blue = color.blue * 85; /*(2^8 - 1)/(2^2 - 1) = 255/3 = 85*/
ret.alpha = 0xFF;
return ret.full;
#elif LV_COLOR_DEPTH == 16
lv_color24_t ret;
ret.red = color.red * 8; /*(2^8 - 1)/(2^5 - 1) = 255/31 = 8*/
ret.green = color.green * 4; /*(2^8 - 1)/(2^6 - 1) = 255/63 = 4*/
ret.blue = color.blue * 8; /*(2^8 - 1)/(2^5 - 1) = 255/31 = 8*/
ret.alpha = 0xFF;
return ret.full;
#elif LV_COLOR_DEPTH == 24
return color.full;
#endif
}
static inline lv_color_t lv_color_mix(lv_color_t c1, lv_color_t c2, uint8_t mix)
{
lv_color_t ret;
ret.red = (uint16_t)((uint16_t) c1.red * mix + (c2.red * (255 - mix))) >> 8;
ret.green = (uint16_t)((uint16_t) c1.green * mix + (c2.green * (255 - mix))) >> 8;
ret.blue = (uint16_t)((uint16_t) c1.blue * mix + (c2.blue * (255 - mix))) >> 8;
return ret;
}
/**
* Get the brightness of a color
* @param color a color
* @return the brightness [0..255]
*/
static inline uint8_t lv_color_brightness(lv_color_t color)
{
lv_color24_t c24;
c24.full = lv_color_to24(color);
uint16_t bright = 3 * c24.red + c24.blue + 4 * c24.green;
return (uint16_t) bright >> 3;
}
/* The most simple macro to create a color from R,G and B values
* The order of bit field is different on Big-endian and Little-endian machines*/
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
#if LV_COLOR_DEPTH == 1
#define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){(b8 >> 7 | g8 >> 7 | r8 >> 7)})
#elif LV_COLOR_DEPTH == 8
#define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){{b8 >> 6, g8 >> 5, r8 >> 5}})
#elif LV_COLOR_DEPTH == 16
#define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){{b8 >> 3, g8 >> 2, r8 >> 3}})
#elif LV_COLOR_DEPTH == 24
#define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){{b8, g8, r8, 0xff}}) /*Fix 0xff alpha*/
#endif
#else
#if LV_COLOR_DEPTH == 1
#define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){(r8 >> 7 | g8 >> 7 | b8 >> 7)})
#elif LV_COLOR_DEPTH == 8
#define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){{r8 >> 6, g8 >> 5, b8 >> 5}})
#elif LV_COLOR_DEPTH == 16
#define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){{r8 >> 3, g8 >> 2, b8 >> 3}})
#elif LV_COLOR_DEPTH == 24
#define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){{0xff, r8, g8, b8}}) /*Fix 0xff alpha*/
#endif
#endif
#define LV_COLOR_HEX(c) LV_COLOR_MAKE(((uint32_t)((uint32_t)c >> 16) & 0xFF), \
((uint32_t)((uint32_t)c >> 8) & 0xFF), \
((uint32_t) c & 0xFF))
/*Usage LV_COLOR_HEX3(0x16C) which means LV_COLOR_HEX(0x1166CC)*/
#define LV_COLOR_HEX3(c) LV_COLOR_MAKE((((c >> 4) & 0xF0) | ((c >> 8) & 0xF)), \
((uint32_t)(c & 0xF0) | ((c & 0xF0) >> 4)), \
((uint32_t)(c & 0xF) | ((c & 0xF) << 4)))
/**
* Convert a HSV color to RGB
* @param h hue [0..359]
* @param s saturation [0..100]
* @param v value [0..100]
* @return the given RGB color in RGB (with LV_COLOR_DEPTH depth)
*/
lv_color_t lv_color_hsv_to_rgb(uint16_t h, uint8_t s, uint8_t v);
/**
* Convert an RGB color to HSV
* @param r red
* @param g green
* @param b blue
* @return the given RGB color n HSV
*/
lv_color_hsv_t lv_color_rgb_to_hsv(uint8_t r, uint8_t g, uint8_t b);
/**********************
* MACROS
**********************/
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /*USE_COLOR*/

View file

@ -0,0 +1,482 @@
/**
* @file lv_font.c
*
*/
/*********************
* INCLUDES
*********************/
#include "../../lv_conf.h"
#include <stddef.h>
#include "lv_font.h"
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
/**********************
* STATIC VARIABLES
**********************/
/**********************
* GLOBAL PROTOTYPES
**********************/
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
/**
* Initialize the built-in fonts
*/
void lv_font_init(void)
{
/*DEJAVU 10*/
#if USE_LV_FONT_DEJAVU_10 != 0
lv_font_add(&lv_font_dejavu_10, NULL);
#endif
#if USE_LV_FONT_DEJAVU_10_SUP != 0
#if USE_LV_FONT_DEJAVU_10 != 0
lv_font_add(&lv_font_dejavu_10_sup, &lv_font_dejavu_10);
#else
lv_font_add(&lv_font_dejavu_10_sup, NULL);
#endif
#endif
#if USE_LV_FONT_DEJAVU_10_LATIN_EXT_A != 0
#if USE_LV_FONT_DEJAVU_10 != 0
lv_font_add(&lv_font_dejavu_10_latin_ext_a, &lv_font_dejavu_10);
#else
lv_font_add(&lv_font_dejavu_10_latine_ext_a, NULL);
#endif
#endif
#if USE_LV_FONT_DEJAVU_10_LATIN_EXT_B != 0
#if USE_LV_FONT_DEJAVU_10 != 0
lv_font_add(&lv_font_dejavu_10_latin_ext_b, &lv_font_dejavu_10);
#else
lv_font_add(&lv_font_dejavu_10_latin_ext_b, NULL);
#endif
#endif
#if USE_LV_FONT_DEJAVU_10_CYRILLIC != 0
#if USE_LV_FONT_DEJAVU_10 != 0
lv_font_add(&lv_font_dejavu_10_cyrillic, &lv_font_dejavu_10);
#else
lv_font_add(&lv_font_dejavu_10_cyrillic, NULL);
#endif
#endif
/*SYMBOL 10*/
#if USE_LV_FONT_SYMBOL_10_BASIC != 0
#if USE_LV_FONT_DEJAVU_10 != 0
lv_font_add(&lv_font_symbol_10_basic, &lv_font_dejavu_10);
#else
lv_font_add(&lv_font_symbol_10_basic, NULL);
#endif
#endif
#if USE_LV_FONT_SYMBOL_10_FILE != 0
#if USE_LV_FONT_SYMBOL_10_BASIC != 0
lv_font_add(&lv_font_symbol_10_file, &lv_font_symbol_10_basic);
#else
lv_font_add(&lv_font_symbol_10_file, NULL);
#endif
#endif
#if USE_LV_FONT_SYMBOL_10_FEEDBACK != 0
#if USE_LV_FONT_SYMBOL_10_BASIC != 0
lv_font_add(&lv_font_symbol_10_feedback, &lv_font_symbol_10_basic);
#else
lv_font_add(&lv_font_symbol_10_feedback, NULL);
#endif
#endif
/*DEJAVU 20*/
#if USE_LV_FONT_DEJAVU_20 != 0
lv_font_add(&lv_font_dejavu_20, NULL);
#endif
#if USE_LV_FONT_DEJAVU_20_SUP != 0
#if USE_LV_FONT_DEJAVU_20 != 0
lv_font_add(&lv_font_dejavu_20_sup, &lv_font_dejavu_20);
#else
lv_font_add(&lv_font_symbol_20_sup, NULL);
#endif
#endif
#if USE_LV_FONT_DEJAVU_20_LATIN_EXT_A != 0
#if USE_LV_FONT_DEJAVU_20 != 0
lv_font_add(&lv_font_dejavu_20_latin_ext_a, &lv_font_dejavu_20);
#else
lv_font_add(&lv_font_dejavu_20_latin_ext_a, NULL);
#endif
#endif
#if USE_LV_FONT_DEJAVU_20_LATIN_EXT_B != 0
#if USE_LV_FONT_DEJAVU_20 != 0
lv_font_add(&lv_font_dejavu_20_latin_ext_b, &lv_font_dejavu_20);
#else
lv_font_add(&lv_font_dejavu_20_latin_ext_b, NULL);
#endif
#endif
#if USE_LV_FONT_DEJAVU_20_CYRILLIC != 0
#if USE_LV_FONT_DEJAVU_20 != 0
lv_font_add(&lv_font_dejavu_20_cyrillic, &lv_font_dejavu_20);
#else
lv_font_add(&lv_font_dejavu_20_cyrillic, NULL);
#endif
#endif
/*SYMBOL 20*/
#if USE_LV_FONT_SYMBOL_20_BASIC != 0
#if USE_LV_FONT_DEJAVU_20 != 0
lv_font_add(&lv_font_symbol_20_basic, &lv_font_dejavu_20);
#else
lv_font_add(&lv_font_symbol_20_basic, NULL);
#endif
#endif
#if USE_LV_FONT_SYMBOL_20_FILE != 0
#if USE_LV_FONT_SYMBOL_20_BASIC != 0
lv_font_add(&lv_font_symbol_20_file, &lv_font_symbol_20_basic);
#else
lv_font_add(&lv_font_symbol_20_file, NULL);
#endif
#endif
#if USE_LV_FONT_SYMBOL_20_FEEDBACK != 0
#if USE_LV_FONT_SYMBOL_20_BASIC != 0
lv_font_add(&lv_font_symbol_20_feedback, &lv_font_symbol_20_basic);
#else
lv_font_add(&lv_font_symbol_20_feedback, NULL);
#endif
#endif
/*DEJAVU 30*/
#if USE_LV_FONT_DEJAVU_30 != 0
lv_font_add(&lv_font_dejavu_30, NULL);
#endif
#if USE_LV_FONT_DEJAVU_30_SUP != 0
#if USE_LV_FONT_DEJAVU_30 != 0
lv_font_add(&lv_font_dejavu_30_sup, &lv_font_dejavu_30);
#else
lv_font_add(&lv_font_dejavu_30_sup, NULL);
#endif
#endif
#if USE_LV_FONT_DEJAVU_30_LATIN_EXT_A != 0
#if USE_LV_FONT_DEJAVU_30 != 0
lv_font_add(&lv_font_dejavu_30_latin_ext_a, &lv_font_dejavu_30);
#else
lv_font_add(&lv_font_dejavu_30_latin_ext_a, NULL);
#endif
#endif
#if USE_LV_FONT_DEJAVU_30_LATIN_EXT_B != 0
#if USE_LV_FONT_DEJAVU_30 != 0
lv_font_add(&lv_font_dejavu_30_latin_ext_b, &lv_font_dejavu_30);
#else
lv_font_add(&lv_font_dejavu_30_latin_ext_b, NULL);
#endif
#endif
#if USE_LV_FONT_DEJAVU_30_CYRILLIC != 0
#if USE_LV_FONT_DEJAVU_30 != 0
lv_font_add(&lv_font_dejavu_30_cyrillic, &lv_font_dejavu_30);
#else
lv_font_add(&lv_font_dejavu_30_cyrillic, NULL);
#endif
#endif
/*SYMBOL 30*/
#if USE_LV_FONT_SYMBOL_30_BASIC != 0
#if USE_LV_FONT_DEJAVU_30 != 0
lv_font_add(&lv_font_symbol_30_basic, &lv_font_dejavu_30);
#else
lv_font_add(&lv_font_symbol_30_basic, NULL);
#endif
#endif
#if USE_LV_FONT_SYMBOL_30_FILE != 0
#if USE_LV_FONT_SYMBOL_30_BASIC != 0
lv_font_add(&lv_font_symbol_30_file, &lv_font_symbol_30_basic);
#else
lv_font_add(&lv_font_symbol_30_file, NULL);
#endif
#endif
#if USE_LV_FONT_SYMBOL_30_FEEDBACK != 0
#if USE_LV_FONT_SYMBOL_30_BASIC != 0
lv_font_add(&lv_font_symbol_30_feedback, &lv_font_symbol_30_basic);
#else
lv_font_add(&lv_font_symbol_30_feedback, NULL);
#endif
#endif
/*DEJAVU 40*/
#if USE_LV_FONT_DEJAVU_40 != 0
lv_font_add(&lv_font_dejavu_40, NULL);
#endif
#if USE_LV_FONT_DEJAVU_40_SUP != 0
#if USE_LV_FONT_DEJAVU_40 != 0
lv_font_add(&lv_font_dejavu_40_sup, &lv_font_dejavu_40);
#else
lv_font_add(&lv_font_dejavu_40_sup, NULL);
#endif
#endif
#if USE_LV_FONT_DEJAVU_40_LATIN_EXT_A != 0
#if USE_LV_FONT_DEJAVU_40 != 0
lv_font_add(&lv_font_dejavu_40_latin_ext_a, &lv_font_dejavu_40);
#else
lv_font_add(&lv_font_dejavu_40_latin_ext_a, NULL);
#endif
#endif
#if USE_LV_FONT_DEJAVU_40_LATIN_EXT_B != 0
#if USE_LV_FONT_DEJAVU_40 != 0
lv_font_add(&lv_font_dejavu_40_latin_ext_b, &lv_font_dejavu_40);
#else
lv_font_add(&lv_font_dejavu_40_latin_ext_b, NULL);
#endif
#endif
#if USE_LV_FONT_DEJAVU_40_CYRILLIC != 0
#if USE_LV_FONT_DEJAVU_40 != 0
lv_font_add(&lv_font_dejavu_40_cyrillic, &lv_font_dejavu_40);
#else
lv_font_add(&lv_font_dejavu_40_cyrillic, NULL);
#endif
#endif
/*SYMBOL 40*/
#if USE_LV_FONT_SYMBOL_40_BASIC != 0
#if USE_LV_FONT_DEJAVU_40 != 0
lv_font_add(&lv_font_symbol_40_basic, &lv_font_dejavu_40);
#else
lv_font_add(&lv_font_symbol_40_basic, NULL);
#endif
#endif
#if USE_LV_FONT_SYMBOL_40_FILE != 0
#if USE_LV_FONT_SYMBOL_40_BASIC != 0
lv_font_add(&lv_font_symbol_40_file, &lv_font_symbol_40_basic);
#else
lv_font_add(&lv_font_symbol_40_file, NULL);
#endif
#endif
#if USE_LV_FONT_SYMBOL_40_FEEDBACK != 0
#if USE_LV_FONT_SYMBOL_40_BASIC != 0
lv_font_add(&lv_font_symbol_40_feedback, &lv_font_symbol_40_basic);
#else
lv_font_add(&lv_font_symbol_40_feedback, NULL);
#endif
#endif
/*DEJAVU 60*/
#if USE_LV_FONT_DEJAVU_60 != 0
lv_font_add(&lv_font_dejavu_60, NULL);
#endif
#if USE_LV_FONT_DEJAVU_60_SUP != 0
#if USE_LV_FONT_DEJAVU_60 != 0
lv_font_add(&lv_font_dejavu_60_sup, &lv_font_dejavu_60);
#else
lv_font_add(&lv_font_dejavu_60_sup, NULL);
#endif
#endif
#if USE_LV_FONT_DEJAVU_60_LATIN_EXT_A != 0
#if USE_LV_FONT_DEJAVU_60 != 0
lv_font_add(&lv_font_dejavu_60_latin_ext_a, &lv_font_dejavu_60);
#else
lv_font_add(&lv_font_dejavu_60_latin_ext_a, NULL);
#endif
#endif
#if USE_LV_FONT_DEJAVU_60_LATIN_EXT_B != 0
#if USE_LV_FONT_DEJAVU_60 != 0
lv_font_add(&lv_font_dejavu_60_latin_ext_b, &lv_font_dejavu_60);
#else
lv_font_add(&lv_font_dejavu_60_latin_ext_b, NULL);
#endif
#endif
#if USE_LV_FONT_DEJAVU_60_CYRILLIC != 0
#if USE_LV_FONT_DEJAVU_60 != 0
lv_font_add(&lv_font_dejavu_60_cyrillic, &lv_font_dejavu_60);
#else
lv_font_add(&lv_font_dejavu_60_cyrillic, NULL);
#endif
#endif
/*SYMBOL 60*/
#if USE_LV_FONT_SYMBOL_60_BASIC != 0
#if USE_LV_FONT_DEJAVU_60 != 0
lv_font_add(&lv_font_symbol_60_basic, &lv_font_dejavu_60);
#else
lv_font_add(&lv_font_symbol_60_basic, NULL);
#endif
#endif
#if USE_LV_FONT_SYMBOL_60_FILE != 0
#if USE_LV_FONT_SYMBOL_60_BASIC != 0
lv_font_add(&lv_font_symbol_60_file, &lv_font_symbol_60_basic);
#else
lv_font_add(&lv_font_symbol_60_file, NULL);
#endif
#endif
#if USE_LV_FONT_SYMBOL_60_FEEDBACK != 0
#if USE_LV_FONT_SYMBOL_60_BASIC != 0
lv_font_add(&lv_font_symbol_60_feedback, &lv_font_symbol_60_basic);
#else
lv_font_add(&lv_font_symbol_60_feedback, NULL);
#endif
#endif
/*DEJAVU 80*/
#if USE_LV_FONT_DEJAVU_80 != 0
lv_font_add(&lv_font_dejavu_80, NULL);
#endif
#if USE_LV_FONT_DEJAVU_80_SUP != 0
#if USE_LV_FONT_DEJAVU_80 != 0
lv_font_add(&lv_font_dejavu_80_sup, &lv_font_dejavu_80);
#else
lv_font_add(&lv_font_dejavu_80_sup, NULL);
#endif
#endif
#if USE_LV_FONT_DEJAVU_80_LATIN_EXT_A != 0
#if USE_LV_FONT_DEJAVU_80 != 0
lv_font_add(&lv_font_dejavu_80_latin_ext_a, &lv_font_dejavu_80);
#else
lv_font_add(&lv_font_dejavu_80_latin_ext_a, NULL);
#endif
#endif
#if USE_LV_FONT_DEJAVU_80_LATIN_EXT_B != 0
#if USE_LV_FONT_DEJAVU_80 != 0
lv_font_add(&lv_font_dejavu_80_latin_ext_b, &lv_font_dejavu_80);
#else
lv_font_add(&lv_font_dejavu_80_latin_ext_b, NULL);
#endif
#endif
#if USE_LV_FONT_DEJAVU_80_CYRILLIC != 0
#if USE_LV_FONT_DEJAVU_80 != 0
lv_font_add(&lv_font_dejavu_80_cyrillic, &lv_font_dejavu_80);
#else
lv_font_add(&lv_font_dejavu_80_cyrillic, NULL);
#endif
#endif
/*SYMBOL 80*/
#if USE_LV_FONT_SYMBOL_80_BASIC != 0
#if USE_LV_FONT_DEJAVU_80 != 0
lv_font_add(&lv_font_symbol_80_basic, &lv_font_dejavu_80);
#else
lv_font_add(&lv_font_symbol_80_basic, NULL);
#endif
#endif
#if USE_LV_FONT_SYMBOL_80_FILE != 0
#if USE_LV_FONT_SYMBOL_80_BASIC != 0
lv_font_add(&lv_font_symbol_80_file, &lv_font_symbol_80_basic);
#else
lv_font_add(&lv_font_symbol_80_file, NULL);
#endif
#endif
#if USE_LV_FONT_SYMBOL_80_FEEDBACK != 0
#if USE_LV_FONT_SYMBOL_80_BASIC != 0
lv_font_add(&lv_font_symbol_80_feedback, &lv_font_symbol_80_basic);
#else
lv_font_add(&lv_font_symbol_80_feedback, NULL);
#endif
#endif
}
/**
* Create a pair from font name and font dsc. get function. After it 'font_get' can be used for this font
* @param name name of the font
* @param dsc_get_fp the font descriptor get function
* @param parent add this font as charter set extension of 'parent'
*/
void lv_font_add(lv_font_t *child, lv_font_t *parent)
{
if(parent == NULL) return;
while(parent->next_page != NULL) {
parent = parent->next_page; /*Got to the last page and add the new font there*/
}
parent->next_page = child;
}
/**
* Return with the bitmap of a font.
* @param font_p pointer to a font
* @param letter a letter
* @return pointer to the bitmap of the letter
*/
const uint8_t * lv_font_get_bitmap(const lv_font_t * font_p, uint32_t letter)
{
const lv_font_t * font_i = font_p;
while(font_i != NULL) {
if(letter >= font_i->first_ascii && letter <= font_i->last_ascii) {
uint32_t index = (letter - font_i->first_ascii);
return &font_i->bitmap[font_i->map[index]];
}
font_i = font_i->next_page;
}
return NULL;
}
/**
* Get the width of a letter in a font
* @param font_p pointer to a font
* @param letter a letter
* @return the width of a letter
*/
uint8_t lv_font_get_width(const lv_font_t * font_p, uint32_t letter)
{
const lv_font_t * font_i = font_p;
while(font_i != NULL) {
if(letter >= font_i->first_ascii && letter <= font_i->last_ascii) {
uint32_t index = (letter - font_i->first_ascii);
return font_i->width[index];
}
font_i = font_i->next_page;
}
return 0;
}
/**********************
* STATIC FUNCTIONS
**********************/

View file

@ -0,0 +1,175 @@
/**
* @file lv_font.h
*
*/
#ifndef LV_FONT_H
#define LV_FONT_H
#ifdef __cplusplus
extern "C" {
#endif
/*********************
* INCLUDES
*********************/
#include "../../lv_conf.h"
#include <stdint.h>
#include <stddef.h>
#include "lv_fonts/lv_symbol_def.h"
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
typedef struct _lv_font_struct
{
uint32_t first_ascii;
uint32_t last_ascii;
uint8_t height_row;
const uint8_t * bitmap;
const uint32_t * map;
const uint8_t * width;
struct _lv_font_struct * next_page; /*Pointer to a font extension*/
}lv_font_t;
/**********************
* GLOBAL PROTOTYPES
**********************/
/**
* Initialize the built-in fonts
*/
void lv_font_init(void);
/**
* Create a pair from font name and font dsc. get function. After it 'font_get' can be used for this font
* @param child pointer to a font to join to the 'parent'
* @param parent pointer to a font. 'child' will be joined here
*/
void lv_font_add(lv_font_t *child, lv_font_t *parent);
/**
* Return with the bitmap of a font.
* @param font_p pointer to a font
* @param letter a letter
* @return pointer to the bitmap of the letter
*/
const uint8_t * lv_font_get_bitmap(const lv_font_t * font_p, uint32_t letter);
/**
* Get the height of a font
* @param font_p pointer to a font
* @return the height of a font
*/
static inline uint8_t lv_font_get_height(const lv_font_t * font_p)
{
return font_p->height_row;
}
/**
* Get the height of a font. Give the real size on the screen (half size if LV_FONT_ANTIALIAS is enabled)
* @param font_p pointer to a font
* @return the height of a font
*/
static inline uint8_t lv_font_get_height_scale(const lv_font_t * font_p)
{
return (font_p->height_row >> LV_FONT_ANTIALIAS) >> LV_ANTIALIAS;
}
/**
* Get the width of a letter in a font
* @param font_p pointer to a font
* @param letter a letter
* @return the width of a letter
*/
uint8_t lv_font_get_width(const lv_font_t * font_p, uint32_t letter);
/**
* Get the width of a letter in a font )Give the real size on the screen (half size if LV_FONT_ANTIALIAS is enabled)
* @param font_p pointer to a font
* @param letter a letter
* @return the width of a letter
*/
static inline uint8_t lv_font_get_width_scale(const lv_font_t * font_p, uint32_t letter)
{
return (lv_font_get_width(font_p, letter) >> LV_FONT_ANTIALIAS) >> LV_ANTIALIAS;
}
/**********************
* MACROS
**********************/
/***********************
* POST INCLUDES
***********************/
/*Add built-in fonts*/
#include "lv_fonts/dejavu_10.h"
#include "lv_fonts/dejavu_10_sup.h"
#include "lv_fonts/dejavu_10_latin_ext_a.h"
#include "lv_fonts/dejavu_10_latin_ext_b.h"
#include "lv_fonts/dejavu_10_cyrillic.h"
#include "lv_fonts/symbol_10_basic.h"
#include "lv_fonts/symbol_10_file.h"
#include "lv_fonts/symbol_10_feedback.h"
#include "lv_fonts/dejavu_20.h"
#include "lv_fonts/dejavu_20_sup.h"
#include "lv_fonts/dejavu_20_latin_ext_a.h"
#include "lv_fonts/dejavu_20_latin_ext_b.h"
#include "lv_fonts/dejavu_20_cyrillic.h"
#include "lv_fonts/symbol_20_basic.h"
#include "lv_fonts/symbol_20_file.h"
#include "lv_fonts/symbol_20_feedback.h"
#include "lv_fonts/dejavu_30.h"
#include "lv_fonts/dejavu_30_sup.h"
#include "lv_fonts/dejavu_30_latin_ext_a.h"
#include "lv_fonts/dejavu_30_latin_ext_b.h"
#include "lv_fonts/dejavu_30_cyrillic.h"
#include "lv_fonts/symbol_30_basic.h"
#include "lv_fonts/symbol_30_file.h"
#include "lv_fonts/symbol_30_feedback.h"
#include "lv_fonts/dejavu_40.h"
#include "lv_fonts/dejavu_40_sup.h"
#include "lv_fonts/dejavu_40_latin_ext_a.h"
#include "lv_fonts/dejavu_40_latin_ext_b.h"
#include "lv_fonts/dejavu_40_cyrillic.h"
#include "lv_fonts/symbol_40_basic.h"
#include "lv_fonts/symbol_40_file.h"
#include "lv_fonts/symbol_40_feedback.h"
#include "lv_fonts/dejavu_60.h"
#include "lv_fonts/dejavu_60_sup.h"
#include "lv_fonts/dejavu_60_latin_ext_a.h"
#include "lv_fonts/dejavu_60_latin_ext_b.h"
#include "lv_fonts/dejavu_60_cyrillic.h"
#include "lv_fonts/symbol_60_basic.h"
#include "lv_fonts/symbol_60_file.h"
#include "lv_fonts/symbol_60_feedback.h"
#include "lv_fonts/dejavu_80.h"
#include "lv_fonts/dejavu_80_sup.h"
#include "lv_fonts/dejavu_80_latin_ext_a.h"
#include "lv_fonts/dejavu_80_latin_ext_b.h"
#include "lv_fonts/dejavu_80_cyrillic.h"
#include "lv_fonts/symbol_80_basic.h"
#include "lv_fonts/symbol_80_file.h"
#include "lv_fonts/symbol_80_feedback.h"
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /*USE_FONT*/

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,15 @@
#ifndef DEJAVU_10_H
#define DEJAVU_10_H
/*Use UTF-8 encoding in the IDE*/
#include "../../../lv_conf.h"
#if USE_LV_FONT_DEJAVU_10
#include <stdint.h>
#include "../lv_font.h"
extern lv_font_t lv_font_dejavu_10;
#endif /*USE_LV_FONT_DEJAVU_10*/
#endif /*DEJAVU_10_H*/

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,15 @@
#ifndef DEJAVU_10_CYRILLIC_H
#define DEJAVU_10_CYRILLIC_H
/*Use UTF-8 encoding in the IDE*/
#include "../../../lv_conf.h"
#if USE_LV_FONT_DEJAVU_10_CYRILLIC
#include <stdint.h>
#include "../lv_font.h"
extern lv_font_t lv_font_dejavu_10_cyrillic;
#endif /*USE_LV_FONT_DEJAVU_10_CYRILLIC*/
#endif /*DEJAVU_10_CYRILLIC_H*/

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,15 @@
#ifndef DEJAVU_10_LATIN_EXT_A_H
#define DEJAVU_10_LATIN_EXT_A_H
/*Use UTF-8 encoding in the IDE*/
#include "../../../lv_conf.h"
#if USE_LV_FONT_DEJAVU_10_LATIN_EXT_A
#include <stdint.h>
#include "../lv_font.h"
extern lv_font_t lv_font_dejavu_10_latin_ext_a;
#endif /*USE_LV_FONT_DEJAVU_10_LATIN_EXT_A*/
#endif /*DEJAVU_10_LATIN_EXT_A_H*/

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,15 @@
#ifndef DEJAVU_10_LATIN_EXT_B_H
#define DEJAVU_10_LATIN_EXT_B_H
/*Use UTF-8 encoding in the IDE*/
#include "../../../lv_conf.h"
#if USE_LV_FONT_DEJAVU_10_LATIN_EXT_B
#include <stdint.h>
#include "../lv_font.h"
extern lv_font_t lv_font_dejavu_10_latin_ext_b;
#endif /*USE_LV_FONT_DEJAVU_10_LATIN_EXT_B*/
#endif /*DEJAVU_10_LATIN_EXT_B_H*/

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,15 @@
#ifndef DEJAVU_10_SUP_H
#define DEJAVU_10_SUP_H
/*Use UTF-8 encoding in the IDE*/
#include "../../../lv_conf.h"
#if USE_LV_FONT_DEJAVU_10_SUP
#include <stdint.h>
#include "../lv_font.h"
extern lv_font_t lv_font_dejavu_10_sup;
#endif /*USE_LV_FONT_DEJAVU_10_SUP*/
#endif /*DEJAVU_10_SUP_H*/

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,15 @@
#ifndef DEJAVU_20_H
#define DEJAVU_20_H
/*Use UTF-8 encoding in the IDE*/
#include "../../../lv_conf.h"
#if USE_LV_FONT_DEJAVU_20
#include <stdint.h>
#include "../lv_font.h"
extern lv_font_t lv_font_dejavu_20;
#endif /*USE_LV_FONT_DEJAVU_20*/
#endif /*DEJAVU_20_H*/

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,15 @@
#ifndef DEJAVU_20_CYRILLIC_H
#define DEJAVU_20_CYRILLIC_H
/*Use UTF-8 encoding in the IDE*/
#include "../../../lv_conf.h"
#if USE_LV_FONT_DEJAVU_20_CYRILLIC
#include <stdint.h>
#include "../lv_font.h"
extern lv_font_t lv_font_dejavu_20_cyrillic;
#endif /*USE_LV_FONT_DEJAVU_20_CYRILLIC*/
#endif /*DEJAVU_20_CYRILLIC_H*/

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,15 @@
#ifndef DEJAVU_20_LATIN_EXT_A_H
#define DEJAVU_20_LATIN_EXT_A_H
/*Use UTF-8 encoding in the IDE*/
#include "../../../lv_conf.h"
#if USE_LV_FONT_DEJAVU_20_LATIN_EXT_A
#include <stdint.h>
#include "../lv_font.h"
extern lv_font_t lv_font_dejavu_20_latin_ext_a;
#endif /*USE_LV_FONT_DEJAVU_20_LATIN_EXT_A*/
#endif /*DEJAVU_20_LATIN_EXT_A_H*/

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,15 @@
#ifndef DEJAVU_20_LATIN_EXT_B_H
#define DEJAVU_20_LATIN_EXT_B_H
/*Use UTF-8 encoding in the IDE*/
#include "../../../lv_conf.h"
#if USE_LV_FONT_DEJAVU_20_LATIN_EXT_B
#include <stdint.h>
#include "../lv_font.h"
extern lv_font_t lv_font_dejavu_20_latin_ext_b;
#endif /*USE_LV_FONT_DEJAVU_20_LATIN_EXT_B*/
#endif /*DEJAVU_20_LATIN_EXT_B_H*/

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,15 @@
#ifndef DEJAVU_20_SUP_H
#define DEJAVU_20_SUP_H
/*Use UTF-8 encoding in the IDE*/
#include "../../../lv_conf.h"
#if USE_LV_FONT_DEJAVU_20_SUP
#include <stdint.h>
#include "../lv_font.h"
extern lv_font_t lv_font_dejavu_20_sup;
#endif /*USE_LV_FONT_DEJAVU_20_SUP*/
#endif /*DEJAVU_20_SUP_H*/

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,15 @@
#ifndef DEJAVU_30_H
#define DEJAVU_30_H
/*Use UTF-8 encoding in the IDE*/
#include "../../../lv_conf.h"
#if USE_LV_FONT_DEJAVU_30
#include <stdint.h>
#include "../lv_font.h"
extern lv_font_t lv_font_dejavu_30;
#endif /*USE_LV_FONT_DEJAVU_30*/
#endif /*DEJAVU_30_H*/

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,15 @@
#ifndef DEJAVU_30_CYRILLIC_H
#define DEJAVU_30_CYRILLIC_H
/*Use UTF-8 encoding in the IDE*/
#include "../../../lv_conf.h"
#if USE_LV_FONT_DEJAVU_30_CYRILLIC
#include <stdint.h>
#include "../lv_font.h"
extern lv_font_t lv_font_dejavu_30_cyrillic;
#endif /*USE_LV_FONT_DEJAVU_30_CYRILLIC*/
#endif /*DEJAVU_30_CYRILLIC_H*/

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,15 @@
#ifndef DEJAVU_30_LATIN_EXT_A_H
#define DEJAVU_30_LATIN_EXT_A_H
/*Use UTF-8 encoding in the IDE*/
#include "../../../lv_conf.h"
#if USE_LV_FONT_DEJAVU_30_LATIN_EXT_A
#include <stdint.h>
#include "../lv_font.h"
extern lv_font_t lv_font_dejavu_30_latin_ext_a;
#endif /*USE_LV_FONT_DEJAVU_30_LATIN_EXT_A*/
#endif /*DEJAVU_30_LATIN_EXT_A_H*/

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,15 @@
#ifndef DEJAVU_30_LATIN_EXT_B_H
#define DEJAVU_30_LATIN_EXT_B_H
/*Use UTF-8 encoding in the IDE*/
#include "../../../lv_conf.h"
#if USE_LV_FONT_DEJAVU_30_LATIN_EXT_B
#include <stdint.h>
#include "../lv_font.h"
extern lv_font_t lv_font_dejavu_30_latin_ext_b;
#endif /*USE_LV_FONT_DEJAVU_30_LATIN_EXT_B*/
#endif /*DEJAVU_30_LATIN_EXT_B_H*/

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,15 @@
#ifndef DEJAVU_30_SUP_H
#define DEJAVU_30_SUP_H
/*Use UTF-8 encoding in the IDE*/
#include "../../../lv_conf.h"
#if USE_LV_FONT_DEJAVU_30_SUP
#include <stdint.h>
#include "../lv_font.h"
extern lv_font_t lv_font_dejavu_30_sup;
#endif /*USE_LV_FONT_DEJAVU_30_SUP*/
#endif /*DEJAVU_30_SUP_H*/

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,15 @@
#ifndef DEJAVU_40_H
#define DEJAVU_40_H
/*Use UTF-8 encoding in the IDE*/
#include "../../../lv_conf.h"
#if USE_LV_FONT_DEJAVU_40
#include <stdint.h>
#include "../lv_font.h"
extern lv_font_t lv_font_dejavu_40;
#endif /*USE_LV_FONT_DEJAVU_40*/
#endif /*DEJAVU_40_H*/

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,15 @@
#ifndef DEJAVU_40_CYRILLIC_H
#define DEJAVU_40_CYRILLIC_H
/*Use UTF-8 encoding in the IDE*/
#include "../../../lv_conf.h"
#if USE_LV_FONT_DEJAVU_40_CYRILLIC
#include <stdint.h>
#include "../lv_font.h"
extern lv_font_t lv_font_dejavu_40_cyrillic;
#endif /*USE_LV_FONT_DEJAVU_40_CYRILLIC*/
#endif /*DEJAVU_40_CYRILLIC_H*/

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,15 @@
#ifndef DEJAVU_40_LATIN_EXT_A_H
#define DEJAVU_40_LATIN_EXT_A_H
/*Use UTF-8 encoding in the IDE*/
#include "../../../lv_conf.h"
#if USE_LV_FONT_DEJAVU_40_LATIN_EXT_A
#include <stdint.h>
#include "../lv_font.h"
extern lv_font_t lv_font_dejavu_40_latin_ext_a;
#endif /*USE_LV_FONT_DEJAVU_40_LATIN_EXT_A*/
#endif /*DEJAVU_40_LATIN_EXT_A_H*/

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,15 @@
#ifndef DEJAVU_40_LATIN_EXT_B_H
#define DEJAVU_40_LATIN_EXT_B_H
/*Use UTF-8 encoding in the IDE*/
#include "../../../lv_conf.h"
#if USE_LV_FONT_DEJAVU_40_LATIN_EXT_B
#include <stdint.h>
#include "../lv_font.h"
extern lv_font_t lv_font_dejavu_40_latin_ext_b;
#endif /*USE_LV_FONT_DEJAVU_40_LATIN_EXT_B*/
#endif /*DEJAVU_40_LATIN_EXT_B_H*/

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,15 @@
#ifndef DEJAVU_40_SUP_H
#define DEJAVU_40_SUP_H
/*Use UTF-8 encoding in the IDE*/
#include "../../../lv_conf.h"
#if USE_LV_FONT_DEJAVU_40_SUP
#include <stdint.h>
#include "../lv_font.h"
extern lv_font_t lv_font_dejavu_40_sup;
#endif /*USE_LV_FONT_DEJAVU_40_SUP*/
#endif /*DEJAVU_40_SUP_H*/

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,15 @@
#ifndef DEJAVU_60_H
#define DEJAVU_60_H
/*Use UTF-8 encoding in the IDE*/
#include "../../../lv_conf.h"
#if USE_LV_FONT_DEJAVU_60
#include <stdint.h>
#include "../lv_font.h"
extern lv_font_t lv_font_dejavu_60;
#endif /*USE_LV_FONT_DEJAVU_60*/
#endif /*DEJAVU_60_H*/

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,15 @@
#ifndef DEJAVU_60_CYRILLIC_H
#define DEJAVU_60_CYRILLIC_H
/*Use UTF-8 encoding in the IDE*/
#include "../../../lv_conf.h"
#if USE_LV_FONT_DEJAVU_60_CYRILLIC
#include <stdint.h>
#include "../lv_font.h"
extern lv_font_t lv_font_dejavu_60_cyrillic;
#endif /*USE_LV_FONT_DEJAVU_60_CYRILLIC*/
#endif /*DEJAVU_60_CYRILLIC_H*/

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,15 @@
#ifndef DEJAVU_60_LATIN_EXT_A_H
#define DEJAVU_60_LATIN_EXT_A_H
/*Use UTF-8 encoding in the IDE*/
#include "../../../lv_conf.h"
#if USE_LV_FONT_DEJAVU_60_LATIN_EXT_A
#include <stdint.h>
#include "../lv_font.h"
extern lv_font_t lv_font_dejavu_60_latin_ext_a;
#endif /*USE_LV_FONT_DEJAVU_60_LATIN_EXT_A*/
#endif /*DEJAVU_60_LATIN_EXT_A_H*/

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,15 @@
#ifndef DEJAVU_60_LATIN_EXT_B_H
#define DEJAVU_60_LATIN_EXT_B_H
/*Use UTF-8 encoding in the IDE*/
#include "../../../lv_conf.h"
#if USE_LV_FONT_DEJAVU_60_LATIN_EXT_B
#include <stdint.h>
#include "../lv_font.h"
extern lv_font_t lv_font_dejavu_60_latin_ext_b;
#endif /*USE_LV_FONT_DEJAVU_60_LATIN_EXT_B*/
#endif /*DEJAVU_60_LATIN_EXT_B_H*/

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,15 @@
#ifndef DEJAVU_60_SUP_H
#define DEJAVU_60_SUP_H
/*Use UTF-8 encoding in the IDE*/
#include "../../../lv_conf.h"
#if USE_LV_FONT_DEJAVU_60_SUP
#include <stdint.h>
#include "../lv_font.h"
extern lv_font_t lv_font_dejavu_60_sup;
#endif /*USE_LV_FONT_DEJAVU_60_SUP*/
#endif /*DEJAVU_60_SUP_H*/

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,15 @@
#ifndef DEJAVU_80_H
#define DEJAVU_80_H
/*Use UTF-8 encoding in the IDE*/
#include "../../../lv_conf.h"
#if USE_LV_FONT_DEJAVU_80
#include <stdint.h>
#include "../lv_font.h"
extern lv_font_t lv_font_dejavu_80;
#endif /*USE_LV_FONT_DEJAVU_80*/
#endif /*DEJAVU_80_H*/

Some files were not shown because too many files have changed in this diff Show more