1
0
mirror of https://github.com/lvgl/lvgl.git synced 2025-01-14 06:42:58 +08:00

Merge branch 'beta' into beta

This commit is contained in:
Gabor Kiss-Vamosi 2018-07-22 21:11:38 +02:00 committed by GitHub
commit de3ef5fc1f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
234 changed files with 149726 additions and 219083 deletions

View File

@ -18,34 +18,32 @@ Homepage: https://littlevgl.com
## Key features ## Key features
* Powerful building blocks buttons, charts, lists, sliders, images etc * Powerful building blocks buttons, charts, lists, sliders, images etc
* Advanced graphics with animations, anti-aliasing, opacity, smooth scrolling * Advanced graphics with animations, anti-aliasing, opacity, smooth scrolling
* Various input devices touch pad, mouse, keyboard, encoder etc * Various input devices touch pad, mouse, keyboard, encoder, buttons etc
* Multi language support with UTF-8 decoding * Multi language support with UTF-8 decoding
* Fully customizable graphical elements * Fully customizable graphical elements
* Hardware independent to use with any microcontroller or display * Hardware independent to use with any microcontroller or display
* Scalable to operate with few memory (80 kB Flash, 10 kB RAM) * Scalable to operate with few memory (50 kB Flash, 10 kB RAM)
* OS, External memory and GPU supported but not required * OS, External memory and GPU supported but not required
* Single frame buffer operation even with advances graphical effects * Single frame buffer operation even with advances graphical effects
* Written in C for maximal compatibility * Written in C for maximal compatibility
* Simulator to develop on PC without embedded hardware * Simulator to develop on PC without embedded hardware
* Tutorials, examples, themes for rapid development * Tutorials, examples, themes for rapid development
* Advanced support and professional GUI development service
* Documentation and API references online * Documentation and API references online
* Free and open-source under MIT licence
## Porting ## Porting
In the most sime case you need 4 things: In the most sime case you need 4 things:
1. Call `lv_tick_inc(1)` in every millisecods in a Timer or Task 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 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) 3. Register a function which can **read an input device**. (E.g. touch pad)
4. Call `lv_task_handler()` periodically in every few milliseconds () 4. Call `lv_task_handler()` periodically in every few milliseconds
For more information visit https://littlevgl.com/porting For more information visit https://littlevgl.com/porting
Or check the [Porting tutorial](https://github.com/littlevgl/lv_examples/blob/master/lv_tutorial/0_porting/lv_tutorial_porting.c)
## Project set-up ## Project set-up
1. **Clone** or download the lvgl repository: `git clone https://github.com/littlevgl/lvgl.git` 1. **Clone** or [Download](https://littlevgl.com/download) the lvgl repository: `git clone https://github.com/littlevgl/lvgl.git`
2. **Create project** with your prefered IDE and add the *lvgl* folder 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 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. 4. In the lv_conf.h delete the first `#if 0` and its `#endif`. Let the default configurations at first.
5. In your *main.c*: #include "lvgl/lvgl.h" 5. In your *main.c*: #include "lvgl/lvgl.h"
6. In your *main function*: 6. In your *main function*:
* lvgl_init(); * lvgl_init();
@ -71,5 +69,4 @@ See [CONTRIBUTING.md](https://github.com/littlevgl/lvgl/blob/master/docs/CONTRIB
## Donate ## 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: 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) [![Donate](https://littlevgl.com/donate_dir/donate_btn.png)](https://littlevgl.com/donate)

1
astyle_c Normal file
View File

@ -0,0 +1 @@
--style=kr --convert-tabs --indent=spaces=4 --indent-switches --pad-oper --unpad-paren --align-pointer=middle --suffix=.bak --lineend=linux --min-conditional-indent=

1
astyle_h Normal file
View File

@ -0,0 +1 @@
--convert-tabs --indent=spaces=4

View File

@ -1,74 +1,80 @@
# Contributing to Littlev Graphics Library # Contributing to Littlev Graphics Library
First of all thank you for reading these guide before contributing! It's glad to see that you are interested in Contributing to LittlevGL!
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! In this guide you can learn how can you help to develop LittlevGL.
### Table Of Content ### Table Of Content
* [Who can contribute?](#who-can-contribute) * [Who can contribute?](#who-can-contribute)
* [How to report an issue?](#how-to-report-an-issue) * [How to report an issue?](#how-to-report-a-bug)
* [Simple issue](#simple-issue)
* [Complex issue](#complex-issue)
* [How to suggest a feature?](#how-to-suggest-a-feature) * [How to suggest a feature?](#how-to-suggest-a-feature)
* [How to implement a feature?](#how-to-implement-a-feature) * [How to implement a feature?](#how-to-implement-a-feature)
* [Styling guide](#styling-guide) * [Styling guide](#styling-guide)
* [File format](#file-format)
* [Functions](#functions)
* [Variables](#variables)
* [Defines](#defines)
* [Typedefs](#typedefs)
* [Comments](#comments)
* [Formatting](#formatting)
## Who can contribute? ## 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: 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 and help the development of Littlev Graphics Library with:
* Report an issue * Report an issue
* Suggest feature * Suggest feature
* Fix an issue * Fix an issue
* Implement a feature * Implement a feature
* Help with testing bugfixes and new features
Please, take a look at [CODE_OF_CONDUCT](https://github.com/littlevgl/lvgl/blob/master/docs/CODE_OF_CONDUCT.md) 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! There are few **general rules**
* We use [GitHub's issue tracker](https://github.com/littlevgl/lvgl/issues)
* Be kind and respectful. Strating with "Hi" is always a good idea :)
* If somebedy helped you give a feedback.
* One issue should be about one topic. If you have other questions please open a new issue.
* Always create an issue before creating a [Pull request](https://help.github.com/articles/about-pull-requests/) to discuss the idea first
* Create small, "digestable" Pull requests.
* Tell your remarks in a structured way. Use paragraphs and the [Markdown](https://guides.github.com/features/mastering-markdown/) support of GitHub.
* Be sure you are using the lates version (from `master` branch)
* Keep in mind LittlevGL should be and should remain:
- usable on small MCUs as well (think about memory footprint)
- compilable with "non-standard" tools like Arduino (no gcc specific options)
- C compatible (no C++ specific code and features)
- all configuration should be in `lv_conf.h`. (Instead of modifying the library)
- the API clean and easiy to understand
## How to report an issue? ## How to report a bug?
If you found a **simple and straightforward bug** like:
* misspelling (in comments function/variable names or grammatical issues in comments)
* not handled error cases (negative array index, overflow etc)
* anything else which can be fixed locally with a few lines of code
* or defective documentation
### Simple issue then tell
If you find an issue which is very simple to fix, and you fixed it, please send a pull request against `beta` branch. * where you found the bug (which file/function/variable)
A simple issue could be: * how can it cause problem
* Misspelled names * what is your suggeseted solution if you have
* 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 faced with **something more clomplex** like:
If you find a complex issue which:
* might be simple but you don't know its origin * might be simple but you don't know its origin
* affects a whole file, module or even the architecture * affects a whole file, module or even the architecture
* needs deeper discussion * needs deeper discussion
please create a **new issue** and describe then please
* what you experience * tell what do you experience
* how to reproduce the issue (maybe with example code) * tell what do you expect to happen
* version you are using (lvgl.h) * tell how to reproduce the issue
* misc library version (misc.h) * provide a simlified code example (better if can be tested with copy-paste)
* attache your lv_conf.h (if you feel it's important)
* logs and long codes should be attached in a file (instead of copying into a comment)
## How to suggest a feature? ## 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: If you have a good and useful idea open issue to tell it! Please note the followings on suggesting new features:
* What the new feature is about? * What the new feature is about?
* Why/Where/In which case is it useful/helpful/relevant? * Why/Where/In which case is it useful/helpful/relevant?
* Can you mention real life usecases/examples for the use this feature?
* Can you help in implementing it? * Can you help in implementing it?
After a discussion we figure out the specification of the new feature and the technical details/implementation possibilities. Your suggestion can have 4 possible outcomes:
With the knowledge of how to do it somebody can implement the new feature. 1. This feature is already exists. In this case you will learn how to achive your goal.
2. You can simply realize it with the current functionality.
3. Although it's a new feature but it would break LittlevGL's platform independent and/or resource minimalist nature.
4. It's really a new feature which would be good to be in LittlevGL. Hurray! In a discussion we figure out the technical details and implementation options. 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. Keep in mind if you wouldn't like to do the implementation there is no guarantee that it will be ready in the near 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) 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? ## How to implement a feature?
@ -79,55 +85,35 @@ The new feature should be in a new branch.
## Styling guide ## Styling guide
### File format ### 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) Use [lv_misc/lv_templ.c](https://github.com/littlevgl/lvgl/blob/master/lv_misc/lv_templ.c) and [lv_misc/lv_templ.h](https://github.com/littlevgl/lvgl/blob/master/lv_misc/lv_templ.h)
### Abbreviations ### Naming conventions
Please read this document to see the list of accepted abbreviations: [abbreviations-in-code](https://github.com/kisvegabor/abbreviations-in-code) * Words are sparated by '_'
* In variable and function names use only lower case letters (e.g. *height_tmp*)
* In enums and defines use only upper case letters (e.g. *e.g. MAX_LINE_NUM*)
* Global names (API):
* starts with *lv*
* followed by module name: *btn*, *label*, *style* etc.
* followed by the action (for functions): *set*, *get*, *refr* etc.
* closed with the subject: *name*, *size*, *state* etc.
* Typedefs
* prefer `typedef struct` and `typedef enum` instead of `struct name` and `enum name`
* always add a closing *..._t*
* Abbreviations:
* Use abbreviations on public names only if they become longer then 32 characters
* Use only very straightforward (e.g. pos: position) or well established (e.g. pr: press) abbreviatons
### Functions ### Coding guide
* try to write function shorter then is 40 lines * Functions:
* always shorter then 100 lines (except very straightforwards) * Try to write function shorter then is 50 lines
* in function names: * Always shorter then 100 lines (except very straightforwards)
* words sparated by '_' * Variables:
* only lower case letters * One line, one declaration (BAD: char x, y;)
* only clear abbreviation (OK: *lv_xy_get_title_txt*, BAD: *lv_xy_get_ttxt*) * Use `<stdint.h>` (*uint8_t*, *int32_t* etc)
* Declare variables when needed (not all at function start)
#### Global functions names (API) * Use the smallest required scope
An example: *lv_btn_set_state()* * Variables in a file (outside functions) are always *static*
* starts with *lv* * Do not use global variables (use functions to set/get static variables)
* 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 ### Comments
Before every function have a comment like this: Before every function have a comment like this:
@ -152,7 +138,7 @@ You should write **why** have you done this:
Short "code summaries" of a few lines are accepted. E.g. `/*Calculate the new coordinates*/` 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'*/` In comments use \` \` when refering to a variable. E.g. ``/*Update the value of `x_act`*/``
### Formatting ### Formatting
Here is example to show bracket placing and using of white spaces: Here is example to show bracket placing and using of white spaces:
@ -163,7 +149,7 @@ Here is example to show bracket placing and using of white spaces:
* @param text '\0' terminated character string. NULL to refresh with the current text. * @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) void lv_label_set_text(lv_obj_t * label, const char * text)
{ /*Main bracket in new line*/ { /* Main bracket of functions in new line*/
if(label == NULL) return; /*No bracket only if the command is inline with the if statement*/ if(label == NULL) return; /*No bracket only if the command is inline with the if statement*/
@ -172,15 +158,24 @@ void lv_label_set_text(lv_obj_t * label, const char * text)
lv_label_ext_t * ext = lv_obj_get_ext(label); lv_label_ext_t * ext = lv_obj_get_ext(label);
/*Comment before a section */ /*Comment before a section */
if(text == ext->txt || text == NULL) { /*Bracket start inline*/ if(text == ext->txt || text == NULL) { /*Bracket of statements start inline*/
lv_label_refr_text(label); lv_label_refr_text(label);
return; return;
} }
. ...
.
.
} }
``` ```
Use 4 spaces indentation instead of tab. Use 4 spaces indentation instead of tab.
You can use **astyle** to format the code. The required config flies are: `docs/astyle_c` and `docs/astyle_h`.
To format the header files:
`$ find . -type f -name "*.c" | xargs astyle --options=docs/astyle_c`
To format the sorce files:
`$ find . -type f -name "*.h" | xargs astyle --options=docs/astyle_h`
Append `-n` to the end to skip creation of backup file or use `$ find . -type f -name "*.bak" -delete` (for source file's backups) and `find . -type f -name "*.orig" -delete` (for header file's backups)

View File

@ -4,7 +4,16 @@ Major versions released typically when API changes are required
## Contributing ## Contributing
Please create an issue to suggest a new feature instead of adding pull request to this file. Please create an issue to suggest a new feature instead of adding pull request to this file.
## v5 (released at: 20.12.2017) ## v6 (released on: in progrss)
- [ ] lv_img_upscale removal (generate image with with opacity instead)
- [ ] disp_map and disp_fill removal
- [ ] disp_flush, mem_blend, mem_fill rework: usea lv_area_t as parameter an GPU support 2D area
- [ ] disp_flush: not const color map
- [ ] ext size removal, enable drawing on full parent.
- [ ] multiple display support
- [ ] lv_ufs removal (was required only in the the old image system)
## v5 (released on: 20.12.2017)
**Architectural changes** **Architectural changes**
- [x] Rename repository from *proj_pc* to *pc_simulator* - [x] Rename repository from *proj_pc* to *pc_simulator*
- [x] Integrate *hal* in LittlevGL as a normal folder - [x] Integrate *hal* in LittlevGL as a normal folder

View File

@ -13,20 +13,56 @@ Here are ideas which are not assigned to a minor version yet:
- lv_inlist: new object type, inline drop down list (a button wich opens a list in place) - 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_char: new_object type: characteristic set (like chart with draggable points)
- lv_vol: new_object type: volume meter (like a bar with segments) - lv_vol: new_object type: volume meter (like a bar with segments)
- anim. paths: monentum (tnh(x)), curve (exp), shake - Anim. paths: monentum (tnh(x)), curve (exp), shake
- hover, hover_lost signals - Hover, hover_lost signals
- Detached area (for video rendering where LittlevGL don't put pixels)
- lv_ta: add placeholder text
- image rotate
## v5.1 (released at: in progress) ## v5.3 (planned)
- [ ] Lua interface to craete GUI with script Mainly graphical/drawing improvments and Lua support
- [ ] Font handling extension for effective Chiese font handling (cutsom read functions) - [ ] API extension: turn the relevant "lv_obj" functions to the specific type (lv_btn_set_size)
- [ ] lv_group: different default style_mod function with LV_COLOR_DEPTH 1 - [ ] Lua interface to create GUI with script
- [ ] lv_img_set_data() for const. image data instead of file system usage
- [ ] Arabic glyph convert (based on letter position) - [ ] Arabic glyph convert (based on letter position)
- [ ] Arc rawing
- [ ] Right-to-left write support - [ ] Right-to-left write support
- [ ] Detached area (for video rendering where LittlevGL don't put pixels) - [ ] Bit based VDB: 1, 2 or 4 bit
- [ ] lv_ta: add placeholder text - [ ] Ttriangle drawing
## v5.0 (released at: 20.12.2017) ## v5.2 (in progress)
Mainly new object and new feauters:
- [ ] New object type: Listview (table) #137
- [ ] New object type: Calendar
- [ ] New object type: Icon (button like image) #182
- [ ] New object type: QR code #199
- [ ] lv_page: scroll on LV_GROUP_KEY_UP/DOWN/LEFT/RIGHT
- [ ] lv_obj_align: option in lv_conf.h sav the last alignment's coordinate ad aply it on lv_obj_realign
- [ ] lv_line: perpndicular line ending
- [ ] lv_gauge: option to put lables outside of the scale
- [ ] lv_img: png support #254
- [ ] lv_tabview: add option to put the tab button to the bottom
- [ ] Error callback: add an option to register a callback called on error
- [ ] Support more character coding (e.g. UTF8, UTF16 etc)
## v5.1 (released on: 09.03.2018)
- [x] lv_refr_set_roundig_callback: set a function to modify the invalidated area for special display controllers
- [x] lv_group_set_focus_callback: set function to call when a new object is focused #94
- [x] lv_obj_get_type() return string, e.g. "lv_slider", "lv_btn" etc #91
- [x] Font handling extension for effective Chiese font handling (cutsom read functions)
- [x] Remove LV_FONT_ANTIALIAS and add fonts with BPP (bit-per-pixel): 1, 2, 4 and 8
- [x] lv_img: add pixel level opacity option (ARGB8888 or ARGB8565) (make image upscale pointless)
- [x] LV_ANTIALIAS rework: meaning anti-alias lines and curves
- [x] Merge symbol fonts (basic, file and feedback) into one font
- [x] lv_group: different default style_mod function with LV_COLOR_DEPTH 1
- [x] lv_img_set_src() to handle file path, symbols and const variables with one function
- [x] LV_PROTECT_PRESS_LOST: prevent the input devices to NOT find new object when the object's pressing is lost
- [x] lv_label: draw style.body.padding.hor/ver greater body if body_draw is enabled
- [x] LV_LAYOUT_PRETTY: in one row align obeóject vertically to middle
- [x] Add user data option to lv_indev_drv_t and pass it with lv_indev_data_t to the read function. #115
- [x] LV_GROUP_KEY_ENTER_LONG: sent by the library on long press of LV_GROUP_KEY_ENTER to trigger long press of the object #113
- [x] LV_INDEV_TYPE_BUTTON: for a hatdware buttons which press a point on a screen
## v5.0 (released on: 20.12.2017)
- [x] UTF-8 support - [x] UTF-8 support
- [x] lv_tabview: new object type to organise content with tabs - [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_sw: new object type, switch, turn on/off by tap (a little slider)
@ -37,7 +73,7 @@ Here are ideas which are not assigned to a minor version yet:
- [x] add themes with predefined styles - [x] add themes with predefined styles
- [x] partial border draw in styles - [x] partial border draw in styles
## v4.2 (released at: 17.08.2017) ## v4.2 (released on: 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] 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_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_page: scrl def fit modification: hor:false, ver:true, and always set width to parent width

View File

@ -1,37 +1,62 @@
# TODOs for patch versions # 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. 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. The bugfixes of the still not released version are in `beta` branche.
## Contributing ## Contributing
Please create an issue to introduce a bug instead of adding pull request to this file. Please create an issue to introduce a bug instead of adding pull request to this file.
## v5.0.2 (released at: in progress) ## v5.1.1 (released on: 20.05.2018)
- [x] lv_line: set line.width ext. size to not trim parts on x = 0, y = 0 coordinates
- [x] lv_conf.h: add LV_COMPILER_VLA_SUPPORTED
- [x] lv_group_create: init focus_cb
- [x] fix of 16 bit image drawing with alpha bytes
- [x] fix text opacity
- [x] lv_mbox: enable navigation with LV_GROUP_KEY_DOWN/UP too
- [x] lv_conf.h: add LV_COMPILER_VLA_SUPPORTED
- [x] lv_slider: inicator draw bugfix
- [x] lv_slider: draw greater background on negative padding if knob_in == 1
- [x] mono theme: fix typo
- [x] style animations: add opacity handling to image, text and line
- [x] lv_kb: before ok/close action don't deassign the lv_ta if there is user defined action
- [x] in lv_objx_set_... functions apply the new value only if it's different from the current
- [x] don't invalide hidden objects
- [x] lv_group_del: remove the objects from the groups too
## v5.0.3 (released on: 09.03.2018)
- [x] lv_chart: Fix the use of point_num more then 256 (Thanks to upbeat27)
- [x] lv_label: fix 'offset' with LV_ANTIALIAS (LV_LABEL_LONG_ROLL was effected)
- [x] lv_label: anim. time wasn't allyed for LV_LABEL_LONG_ROLL
- [x] lv_txt_ut8_size fiy for 4 byte characters
- [x] lv_slider: fix knob_in with not zero min value
- [x] lv_area_is_on: handled some cases wrong
- [x] lv_indev: buffered indevs (return *true* in indev_read) was handled as non-buffered
- [x] drag: don't invalidate if the object wasn't moved
## v5.0.2 (released on: 19.01.2018)
- [x] Fix dependencied (Thanks to Zaltora) - [x] Fix dependencied (Thanks to Zaltora)
- [x] lv_group: fix memory leak (Thanks to BenQoo) - [x] lv_group: fix memory leak (Thanks to BenQoo)
- [x] LV_INDEV_READ_PERIOD 0 build bugfix - [x] LV_INDEV_READ_PERIOD 0 build bugfix
- [x] lv_roller: lv_roller_get_selected_str: bugfix (was recursive call) - [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_obj_get_style: with NULL style check if the parent is focused and use the focused style
- [x] lv_roller: add missing action handling - [x] lv_roller: add missing action handling
- [ ] Set 24 bit colors upper byte (alpha) to 0xFF - [x] Set 24 bit colors upper byte (alpha) to 0xFF
## v5.0.1 (released at: 02.01.2018) ## v5.0.1 (released on: 02.01.2018)
- [x] lv_list: fixed when mouse and keyboard used together - [x] lv_list: fixed when mouse and keyboard used together
- [x] lv_btnm: fix bottom border visibility - [x] lv_btnm: fix bottom border visibility
- [x] theme updates - [x] theme updates
- [x] line width fix width anti-aliasing - [x] line width fix width anti-aliasing
- [x] lv_conf_templ.h add more info - [x] lv_conf_templ.h add more info
## v5.0 (released at: 21.12.2017) ## v5.0 (released on: 21.12.2017)
- [x] lv_btnm: check hide code (\177) at 0. byte position too (if width is not specified) - [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_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_list: ignore image related things when *lv_img* is not enebled
- [x] lv_ta: fix hegiht if *one_line* and *FONT_ANTIALIAS* - [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) - [x] lv_obj_set_style: fix to update self style too (not only children)
## v4.2 (released at: 17.08.2017) ## v4.2 (released on: 17.08.2017)
- [x] lv_slider: don't let indicator or bar to disappear because of hpad/vpad - [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_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()* - [x] lv_list: work without *lv_img* by ignore the image file name parameter of *lv_list_add()*

1
docs/astyle_c Normal file
View File

@ -0,0 +1 @@
--style=kr --convert-tabs --indent=spaces=4 --indent-switches --pad-oper --unpad-paren --align-pointer=middle --suffix=.bak --lineend=linux --min-conditional-indent=

1
docs/astyle_h Normal file
View File

@ -0,0 +1 @@
--convert-tabs --indent=spaces=4

View File

@ -11,13 +11,12 @@
/*---------------- /*----------------
* Dynamic memory * Dynamic memory
*----------------*/ *----------------*/
/*
* Memory size which will be used by the library /* Memory size which will be used by the library
* to store the graphical objects and other data * 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*/ #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 #if LV_MEM_CUSTOM == 0
#define LV_MEM_SIZE (32U * 1024U) /*Size memory used by mem_alloc (in bytes)*/ #define LV_MEM_SIZE (32U * 1024U) /*Size memory used by `lv_mem_alloc` in bytes (>= 2kB)*/
#define LV_MEM_ATTR /*Complier prefix for big array declaration*/ #define LV_MEM_ATTR /*Complier prefix for big array declaration*/
#define LV_MEM_AUTO_DEFRAG 1 /*Automatically defrag on free*/ #define LV_MEM_AUTO_DEFRAG 1 /*Automatically defrag on free*/
#else /*LV_MEM_CUSTOM*/ #else /*LV_MEM_CUSTOM*/
@ -28,20 +27,18 @@
/*=================== /*===================
Graphical settings Graphical settings
*=====================*/ *===================*/
/* Horizontal and vertical resolution of the library.*/ /* Horizontal and vertical resolution of the library.*/
#define LV_HOR_RES (320) #define LV_HOR_RES (320)
#define LV_VER_RES (240) #define LV_VER_RES (240)
#define LV_DPI 100 #define LV_DPI 100
/* Size of internal graphics buffer (required for buffered drawing) /* Size of VDB (Virtual Display Buffer: the internal graphics buffer).
* VDB means Virtual Display Buffer (the internal graphics buffer) * Required for buffered drawing, opacity and anti-aliasing
* Set to 0 for unbuffered drawing * VDB makes the double buffering, you don't need to deal with it!
* Set to >= LV_HOR_RES for buffered drawing if LV_ANTIALIAS = 0 * Typical size: ~1/10 screen */
* Set to >= 2 * LV_HOR_RES for buffered drawing if LV_ANTIALIAS = 1 #define LV_VDB_SIZE (20 * LV_HOR_RES) /*Size of VDB in pixel count (1/10 screen size is good for first)*/
* 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)*/ #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) /* Use two Virtual Display buffers (VDB) parallelize rendering and flushing (optional)
@ -49,16 +46,9 @@
#define LV_VDB_DOUBLE 0 /*1: Enable the use of 2 VDBs*/ #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)*/ #define LV_VDB2_ADR 0 /*Place VDB2 to a specific address (e.g. in external RAM) (0: allocate automatically into RAM)*/
/* Enable anti-aliasing /* Enable anti-aliasing (lines, and radiuses will be smoothed) */
* If enabled everything will be rendered in double size and filtered to normal size.
* Fonts and Images will be downscaled */
#define LV_ANTIALIAS 1 /*1: Enable anti-aliasing*/ #define LV_ANTIALIAS 1 /*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 0 /*1: Enable font anti-aliasing*/
/*Screen refresh settings*/ /*Screen refresh settings*/
#define LV_REFR_PERIOD 50 /*Screen refresh period in milliseconds*/ #define LV_REFR_PERIOD 50 /*Screen refresh period in milliseconds*/
#define LV_INV_FIFO_SIZE 32 /*The average count of objects on a screen */ #define LV_INV_FIFO_SIZE 32 /*The average count of objects on a screen */
@ -69,7 +59,7 @@
/*Input device settings*/ /*Input device settings*/
#define LV_INDEV_READ_PERIOD 50 /*Input device read period in milliseconds*/ #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_POINT_MARKER 0 /*Mark the pressed points (required: USE_LV_REAL_DRAW = 1)*/
#define LV_INDEV_DRAG_LIMIT 10 /*Drag threshold in pixels */ #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_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_TIME 400 /*Long press time in milliseconds*/
@ -77,7 +67,7 @@
/*Color settings*/ /*Color settings*/
#define LV_COLOR_DEPTH 16 /*Color depth: 1/8/16/24*/ #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)*/ #define LV_COLOR_TRANSP LV_COLOR_LIME /*Images pixels with this color will not be drawn (with chroma keying)*/
/*Text settings*/ /*Text settings*/
#define LV_TXT_UTF8 1 /*Enable UTF-8 coded Unicode character usage */ #define LV_TXT_UTF8 1 /*Enable UTF-8 coded Unicode character usage */
@ -88,8 +78,16 @@
#define USE_LV_SHADOW 1 /*1: Enable shadows*/ #define USE_LV_SHADOW 1 /*1: Enable shadows*/
#define USE_LV_GROUP 1 /*1: Enable object groups (for keyboards)*/ #define USE_LV_GROUP 1 /*1: Enable object groups (for keyboards)*/
#define USE_LV_GPU 1 /*1: Enable GPU interface*/ #define USE_LV_GPU 1 /*1: Enable GPU interface*/
#define USE_LV_REAL_DRAW 1 /*1: Enable function which draw directly to the frame buffer instead of VDB (required if LV_VDB_SIZE = 0)*/
#define USE_LV_FILESYSTEM 1 /*1: Enable file system (required by images*/ #define USE_LV_FILESYSTEM 1 /*1: Enable file system (required by images*/
/*Compiler settings*/
#define LV_ATTRIBUTE_TICK_INC /* Define a custom attribute to `lv_tick_inc` function */
#define LV_ATTRIBUTE_TASK_HANDLER /* Define a custom attribute to `lv_task_handler` function */
#define LV_COMPILER_VLA_SUPPORTED 0 /* 1: Variable length array is supported. (In Visual studio it is not supported)*/
#define LV_COMPILER_NON_CONST_INIT_SUPPORTED 0 /* 1: Initialization with non constant values are supported (In Visual studio it is not supported)*/
//#define _CRT_SECURE_NO_WARNINGS /* Visual Studio needs it to use `strcpy`, `sprintf` etc*/
/*================ /*================
* THEME USAGE * THEME USAGE
*================*/ *================*/
@ -104,62 +102,39 @@
/*================== /*==================
* FONT USAGE * 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*/
/* More info about fonts: https://littlevgl.com/basics#fonts
* To enable a built-in font use 1,2,4 or 8 values
* which will determine the bit-per-pixel */
#define USE_LV_FONT_DEJAVU_10 0 #define USE_LV_FONT_DEJAVU_10 0
#define USE_LV_FONT_DEJAVU_10_SUP 0 #define USE_LV_FONT_DEJAVU_10_LATIN_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_DEJAVU_10_CYRILLIC 0
#define USE_LV_FONT_SYMBOL_10_BASIC 0 #define USE_LV_FONT_SYMBOL_10 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 4
#define USE_LV_FONT_DEJAVU_20_SUP 0 #define USE_LV_FONT_DEJAVU_20_LATIN_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_DEJAVU_20_CYRILLIC 0
#define USE_LV_FONT_SYMBOL_20_BASIC 0 #define USE_LV_FONT_SYMBOL_20 4
#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 0
#define USE_LV_FONT_DEJAVU_30_SUP 0 #define USE_LV_FONT_DEJAVU_30_LATIN_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_DEJAVU_30_CYRILLIC 0
#define USE_LV_FONT_SYMBOL_30_BASIC 0 #define USE_LV_FONT_SYMBOL_30 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 0
#define USE_LV_FONT_DEJAVU_40_SUP 1 #define USE_LV_FONT_DEJAVU_40_LATIN_SUP 0
#define USE_LV_FONT_DEJAVU_40_LATIN_EXT_A 1 #define USE_LV_FONT_DEJAVU_40_CYRILLIC 0
#define USE_LV_FONT_DEJAVU_40_LATIN_EXT_B 1 #define USE_LV_FONT_SYMBOL_40 0
#define USE_LV_FONT_DEJAVU_40_CYRILLIC 1
#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 /* Optionally declare your custom fonts here.
#define USE_LV_FONT_DEJAVU_60_SUP 0 * You can use these fonts as defult font too
#define USE_LV_FONT_DEJAVU_60_LATIN_EXT_A 0 * and they will be avialale globally. E.g.
#define USE_LV_FONT_DEJAVU_60_LATIN_EXT_B 0 * #define LV_FONT_CUSTOM_DECLARE LV_FONT_DECLARE(my_font_1) \
#define USE_LV_FONT_DEJAVU_60_CYRILLIC 0 * LV_FONT_DECLARE(my_font_2) \
#define USE_LV_FONT_SYMBOL_60_BASIC 0 */
#define USE_LV_FONT_SYMBOL_60_FILE 0 #define LV_FONT_CUSTOM_DECLARE
#define USE_LV_FONT_SYMBOL_60_FEEDBACK 0
#define USE_LV_FONT_DEJAVU_80 0 #define LV_FONT_DEFAULT &lv_font_dejavu_20 /*Always set a default font from the built-in fonts*/
#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 * LV_OBJ SETTINGS
@ -181,7 +156,7 @@
/*Label (dependencies: -*/ /*Label (dependencies: -*/
#define USE_LV_LABEL 1 #define USE_LV_LABEL 1
#if USE_LV_LABEL != 0 #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*/ #define LV_LABEL_SCROLL_SPEED 25 /*Hor, or ver. scroll speed [px/sec] in 'LV_LABEL_LONG_SCROLL/ROLL' mode*/
#endif #endif
/*Image (dependencies: lv_label*/ /*Image (dependencies: lv_label*/
@ -278,7 +253,15 @@
/*Switch (dependencies: lv_slider)*/ /*Switch (dependencies: lv_slider)*/
#define USE_LV_SW 1 #define USE_LV_SW 1
/*************************
* Non-user section
*************************/
#ifdef _MSC_VER /* Disable warnings for Visual Studio*/
# define _CRT_SECURE_NO_WARNINGS
#endif
#endif /*LV_CONF_H*/ #endif /*LV_CONF_H*/
#endif /*Remove this to enable the content*/ #endif /*Remove this to enable the content*/

View File

@ -47,10 +47,33 @@ lv_group_t * lv_group_create(void)
group->style_mod = style_mod_def; group->style_mod = style_mod_def;
group->obj_focus = NULL; group->obj_focus = NULL;
group->frozen = 0; group->frozen = 0;
group->focus_cb = NULL;
return group; return group;
} }
/**
* Delete a group object
* @param group pointer to a group
*/
void lv_group_del(lv_group_t * group)
{
/*Defocus the the currently focused object*/
if(group->obj_focus != NULL) {
(*group->obj_focus)->signal_func(*group->obj_focus, LV_SIGNAL_DEFOCUS, NULL);
lv_obj_invalidate(*group->obj_focus);
}
/*Remove the objects from the group*/
lv_obj_t ** obj;
LL_READ(group->obj_ll, obj) {
(*obj)->group_p = NULL;
}
lv_ll_clear(&(group->obj_ll));
lv_mem_free(group);
}
/** /**
* Add an object to a group * Add an object to a group
* @param group pointer to a group * @param group pointer to a group
@ -58,6 +81,8 @@ lv_group_t * lv_group_create(void)
*/ */
void lv_group_add_obj(lv_group_t * group, lv_obj_t * obj) void lv_group_add_obj(lv_group_t * group, lv_obj_t * obj)
{ {
if(group == NULL) return;
obj->group_p = group; obj->group_p = group;
lv_obj_t ** next = lv_ll_ins_tail(&group->obj_ll); lv_obj_t ** next = lv_ll_ins_tail(&group->obj_ll);
*next = obj; *next = obj;
@ -77,21 +102,27 @@ void lv_group_remove_obj(lv_obj_t * obj)
{ {
lv_group_t * g = obj->group_p; lv_group_t * g = obj->group_p;
if(g == NULL) return; if(g == NULL) return;
if(g->obj_focus == NULL) return; /*Just to be sure (Not possible if there is at least one object in the group)*/
if(*g->obj_focus == obj) {
lv_group_focus_next(g);
}
/* If the focuses object is still the same then it was the only object in the group but it will be deleted.
* Set the `obj_focus` to NULL to get back to the initial state of the group with zero objects*/
if(*g->obj_focus == obj) {
g->obj_focus = NULL;
}
/*Search the object and remove it from its group */ /*Search the object and remove it from its group */
lv_obj_t ** i; lv_obj_t ** i;
LL_READ(g->obj_ll, i) { LL_READ(g->obj_ll, i) {
if(*i == obj) { if(*i == obj) {
lv_ll_rem(&g->obj_ll, i); lv_ll_rem(&g->obj_ll, i);
lv_mem_free(i);
obj->group_p = NULL; obj->group_p = NULL;
break;
} }
} }
if(*g->obj_focus == obj) {
g->obj_focus = NULL;
lv_group_focus_next(g);
}
} }
/** /**
@ -106,7 +137,6 @@ void lv_group_focus_obj(lv_obj_t * obj)
if(g->frozen != 0) return; if(g->frozen != 0) return;
lv_obj_t ** i; lv_obj_t ** i;
LL_READ(g->obj_ll, i) { LL_READ(g->obj_ll, i) {
if(*i == obj) { if(*i == obj) {
if(g->obj_focus != NULL) { if(g->obj_focus != NULL) {
@ -116,7 +146,7 @@ void lv_group_focus_obj(lv_obj_t * obj)
g->obj_focus = i; g->obj_focus = i;
if(g->obj_focus != NULL){ if(g->obj_focus != NULL) {
(*g->obj_focus)->signal_func(*g->obj_focus, LV_SIGNAL_FOCUS, NULL); (*g->obj_focus)->signal_func(*g->obj_focus, LV_SIGNAL_FOCUS, NULL);
lv_obj_invalidate(*g->obj_focus); lv_obj_invalidate(*g->obj_focus);
} }
@ -145,9 +175,11 @@ void lv_group_focus_next(lv_group_t * group)
if(obj_next == NULL) obj_next = lv_ll_get_head(&group->obj_ll); if(obj_next == NULL) obj_next = lv_ll_get_head(&group->obj_ll);
group->obj_focus = obj_next; group->obj_focus = obj_next;
if(group->obj_focus){ if(group->obj_focus) {
(*group->obj_focus)->signal_func(*group->obj_focus, LV_SIGNAL_FOCUS, NULL); (*group->obj_focus)->signal_func(*group->obj_focus, LV_SIGNAL_FOCUS, NULL);
lv_obj_invalidate(*group->obj_focus); lv_obj_invalidate(*group->obj_focus);
if(group->focus_cb) group->focus_cb(group);
} }
} }
@ -171,9 +203,11 @@ void lv_group_focus_prev(lv_group_t * group)
if(obj_next == NULL) obj_next = lv_ll_get_tail(&group->obj_ll); if(obj_next == NULL) obj_next = lv_ll_get_tail(&group->obj_ll);
group->obj_focus = obj_next; group->obj_focus = obj_next;
if(group->obj_focus != NULL){ if(group->obj_focus != NULL) {
(*group->obj_focus)->signal_func(*group->obj_focus, LV_SIGNAL_FOCUS, NULL); (*group->obj_focus)->signal_func(*group->obj_focus, LV_SIGNAL_FOCUS, NULL);
lv_obj_invalidate(*group->obj_focus); lv_obj_invalidate(*group->obj_focus);
if(group->focus_cb) group->focus_cb(group);
} }
} }
@ -202,18 +236,28 @@ void lv_group_send_data(lv_group_t * group, uint32_t c)
act->signal_func(act, LV_SIGNAL_CONTROLL, &c); 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 * 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 group pointer to a group
* @param style_cb the style modifier function pointer * @param style_mod_func the style modifier function pointer
*/ */
void lv_group_set_style_mod_cb(lv_group_t * group, void (*style_cb)(lv_style_t * style)) void lv_group_set_style_mod_cb(lv_group_t * group, lv_group_style_mod_func_t style_mod_func)
{ {
group->style_mod = style_cb; group->style_mod = style_mod_func;
if(group->obj_focus != NULL) lv_obj_invalidate(*group->obj_focus); if(group->obj_focus != NULL) lv_obj_invalidate(*group->obj_focus);
} }
/**
* Set a function for a group which will be called when a new object is focused
* @param group pointer to a group
* @param focus_cb the call back function or NULL if unused
*/
void lv_group_set_focus_cb(lv_group_t * group, lv_group_focus_cb_t focus_cb)
{
group->focus_cb = focus_cb;
}
/** /**
* Modify a style with the set 'style_mod' function. The input style remains unchanged. * Modify a style with the set 'style_mod' function. The input style remains unchanged.
* @param group pointer to group * @param group pointer to group
@ -243,6 +287,26 @@ lv_obj_t * lv_group_get_focused(lv_group_t * group)
return *group->obj_focus; return *group->obj_focus;
} }
/**
* Get a the style modifier function of a group
* @param group pointer to a group
* @return pointer to the style modifier function
*/
lv_group_style_mod_func_t lv_group_get_style_mod_cb(lv_group_t * group)
{
return group->style_mod ;
}
/**
* Get the focus callback function of a group
* @param group pointer to a group
* @return the call back function or NULL if not set
*/
lv_group_focus_cb_t lv_group_get_focus_cb(lv_group_t * group)
{
return group->focus_cb;
}
/********************** /**********************
* STATIC FUNCTIONS * STATIC FUNCTIONS
**********************/ **********************/
@ -253,6 +317,7 @@ lv_obj_t * lv_group_get_focused(lv_group_t * group)
*/ */
static void style_mod_def(lv_style_t * style) static void style_mod_def(lv_style_t * style)
{ {
#if LV_COLOR_DEPTH != 1
/*Make the style to be a little bit orange*/ /*Make the style to be a little bit orange*/
style->body.border.opa = LV_OPA_COVER; style->body.border.opa = LV_OPA_COVER;
style->body.border.color = LV_COLOR_ORANGE; style->body.border.color = LV_COLOR_ORANGE;
@ -265,6 +330,13 @@ static void style_mod_def(lv_style_t * style)
style->body.shadow.color = lv_color_mix(style->body.shadow.color, LV_COLOR_ORANGE, LV_OPA_60); 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); style->text.color = lv_color_mix(style->text.color, LV_COLOR_ORANGE, LV_OPA_70);
#else
style->body.border.opa = LV_OPA_COVER;
style->body.border.color = LV_COLOR_BLACK;
style->body.border.width = 3;
#endif
} }
#endif /*USE_LV_GROUP != 0*/ #endif /*USE_LV_GROUP != 0*/

View File

@ -25,23 +25,32 @@ extern "C" {
#define LV_GROUP_KEY_DOWN 18 /*0x12*/ #define LV_GROUP_KEY_DOWN 18 /*0x12*/
#define LV_GROUP_KEY_RIGHT 19 /*0x13*/ #define LV_GROUP_KEY_RIGHT 19 /*0x13*/
#define LV_GROUP_KEY_LEFT 20 /*0x14*/ #define LV_GROUP_KEY_LEFT 20 /*0x14*/
#define LV_GROUP_KEY_ESC 33 /*0x1B*/ #define LV_GROUP_KEY_ESC 27 /*0x1B*/
#define LV_GROUP_KEY_DEL 28 /*0x1C*/
#define LV_GROUP_KEY_ENTER 10 /*0x0A, '\n'*/ #define LV_GROUP_KEY_ENTER 10 /*0x0A, '\n'*/
#define LV_GROUP_KEY_NEXT 9 /*0x09, '\t'*/ #define LV_GROUP_KEY_NEXT 9 /*0x09, '\t'*/
#define LV_GROUP_KEY_PREV 11 /*0x0B, '*/ #define LV_GROUP_KEY_PREV 11 /*0x0B, '*/
#define LV_GROUP_KEY_ENTER_LONG 14 /*0x0E, Sent by the library if ENTER is long pressed*/
#if USE_LV_GROUP != 0 #if USE_LV_GROUP != 0
/********************** /**********************
* TYPEDEFS * TYPEDEFS
**********************/ **********************/
struct _lv_group_t;
typedef void (*lv_group_style_mod_func_t)(lv_style_t *);
typedef void (*lv_group_focus_cb_t)(struct _lv_group_t *);
typedef struct _lv_group_t typedef struct _lv_group_t
{ {
lv_ll_t obj_ll; lv_ll_t obj_ll; /*Linked list to store the objects in the group */
lv_obj_t ** obj_focus; lv_obj_t ** obj_focus; /*The object in focus*/
void (*style_mod)(lv_style_t * style); lv_group_style_mod_func_t style_mod; /*A function which modifies the style of the focused object*/
lv_style_t style_tmp; lv_group_focus_cb_t focus_cb; /*A function to call when a new object is focused (optional)*/
uint8_t frozen:1; lv_style_t style_tmp; /*Stores the modified style of the focused object */
}lv_group_t; uint8_t frozen:1; /*1: can't focus to new object*/
} lv_group_t;
/********************** /**********************
* GLOBAL PROTOTYPES * GLOBAL PROTOTYPES
@ -53,6 +62,12 @@ typedef struct _lv_group_t
*/ */
lv_group_t * lv_group_create(void); lv_group_t * lv_group_create(void);
/**
* Delete a group object
* @param group pointer to a group
*/
void lv_group_del(lv_group_t * group);
/** /**
* Add an object to a group * Add an object to a group
* @param group pointer to a group * @param group pointer to a group
@ -98,13 +113,19 @@ void lv_group_focus_freeze(lv_group_t * group, bool en);
*/ */
void lv_group_send_data(lv_group_t * group, uint32_t c); 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 * 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 group pointer to a group
* @param style_cb the style modifier function pointer * @param style_mod_func the style modifier function pointer
*/ */
void lv_group_set_style_mod_cb(lv_group_t * group, void (*style_cb)(lv_style_t * style)); void lv_group_set_style_mod_cb(lv_group_t * group,lv_group_style_mod_func_t style_mod_func);
/**
* Set a function for a group which will be called when a new object is focused
* @param group pointer to a group
* @param focus_cb the call back function or NULL if unused
*/
void lv_group_set_focus_cb(lv_group_t * group, lv_group_focus_cb_t focus_cb);
/** /**
* Modify a style with the set 'style_mod' function. The input style remains unchanged. * Modify a style with the set 'style_mod' function. The input style remains unchanged.
@ -121,6 +142,20 @@ lv_style_t * lv_group_mod_style(lv_group_t * group, const lv_style_t * style);
*/ */
lv_obj_t * lv_group_get_focused(lv_group_t * group); lv_obj_t * lv_group_get_focused(lv_group_t * group);
/**
* Get a the style modifier function of a group
* @param group pointer to a group
* @return pointer to the style modifier function
*/
lv_group_style_mod_func_t lv_group_get_style_mod_cb(lv_group_t * group);
/**
* Get the focus callback function of a group
* @param group pointer to a group
* @return the call back function or NULL if not set
*/
lv_group_focus_cb_t lv_group_get_focus_cb(lv_group_t * group);
/********************** /**********************
* MACROS * MACROS
**********************/ **********************/

View File

@ -11,6 +11,7 @@
#include "../lv_hal/lv_hal_tick.h" #include "../lv_hal/lv_hal_tick.h"
#include "../lv_core/lv_group.h" #include "../lv_core/lv_group.h"
#include "../lv_core/lv_refr.h"
#include "../lv_misc/lv_task.h" #include "../lv_misc/lv_task.h"
#include "../lv_misc/lv_math.h" #include "../lv_misc/lv_math.h"
#include "../lv_draw/lv_draw_rbasic.h" #include "../lv_draw/lv_draw_rbasic.h"
@ -27,19 +28,24 @@
/********************** /**********************
* STATIC PROTOTYPES * STATIC PROTOTYPES
**********************/ **********************/
#if LV_INDEV_READ_PERIOD != 0
static void indev_proc_task(void * param); static void indev_proc_task(void * param);
static void indev_proc_point(lv_indev_proc_t * indev); static void indev_pointer_proc(lv_indev_t * i, lv_indev_data_t * data);
static void indev_proc_press(lv_indev_proc_t * info); static void indev_keypad_proc(lv_indev_t * i, lv_indev_data_t * data);
static void indev_proc_release(lv_indev_proc_t * state); static void indev_button_proc(lv_indev_t * i, lv_indev_data_t * data);
static void indev_proc_press(lv_indev_proc_t * proc);
static void indev_proc_release(lv_indev_proc_t * proc);
static void indev_proc_reset_query_handler(lv_indev_t * indev);
static lv_obj_t * indev_search_obj(const lv_indev_proc_t * indev, lv_obj_t * obj); 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(lv_indev_proc_t * state);
static void indev_drag_throw(lv_indev_proc_t * state); static void indev_drag_throw(lv_indev_proc_t * state);
#endif
/********************** /**********************
* STATIC VARIABLES * STATIC VARIABLES
**********************/ **********************/
static lv_task_t *indev_proc_task_p; static lv_indev_t * indev_act;
static lv_indev_t *indev_act;
/********************** /**********************
* MACROS * MACROS
@ -55,9 +61,7 @@ static lv_indev_t *indev_act;
void lv_indev_init(void) void lv_indev_init(void)
{ {
#if LV_INDEV_READ_PERIOD != 0 #if LV_INDEV_READ_PERIOD != 0
indev_proc_task_p = lv_task_create(indev_proc_task, LV_INDEV_READ_PERIOD, LV_TASK_PRIO_MID, NULL); lv_task_create(indev_proc_task, LV_INDEV_READ_PERIOD, LV_TASK_PRIO_MID, NULL);
#else
indev_proc_task_p = lv_task_create(indev_proc_task, 1, LV_TASK_PRIO_OFF); /*Not use lv_indev_proc*/
#endif #endif
lv_indev_reset(NULL); /*Reset all input devices*/ lv_indev_reset(NULL); /*Reset all input devices*/
@ -106,22 +110,22 @@ void lv_indev_reset_lpr(lv_indev_t * indev)
*/ */
void lv_indev_enable(lv_hal_indev_type_t type, bool enable) void lv_indev_enable(lv_hal_indev_type_t type, bool enable)
{ {
lv_indev_t *i = lv_indev_next(NULL); lv_indev_t * i = lv_indev_next(NULL);
while (i) { while(i) {
if (i->driver.type == type) i->proc.disabled = enable == false ? 1 : 0; if(i->driver.type == type) i->proc.disabled = enable == false ? 1 : 0;
i = lv_indev_next(i); i = lv_indev_next(i);
} }
} }
/** /**
* Set a cursor for a pointer input device * Set a cursor for a pointer input device (for LV_INPUT_TYPE_POINTER and LV_INPUT_TYPE_BUTTON)
* @param indev pointer to an input device (type: 'LV_INDEV_TYPE_POINTER') * @param indev pointer to an input device
* @param cur_obj pointer to an object to be used as cursor * @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) void lv_indev_set_cursor(lv_indev_t * indev, lv_obj_t * cur_obj)
{ {
if(indev->driver.type != LV_INDEV_TYPE_POINTER) return; if(indev->driver.type != LV_INDEV_TYPE_POINTER && indev->driver.type != LV_INDEV_TYPE_BUTTON) return;
indev->cursor = cur_obj; indev->cursor = cur_obj;
lv_obj_set_parent(indev->cursor, lv_layer_sys()); lv_obj_set_parent(indev->cursor, lv_layer_sys());
@ -130,47 +134,69 @@ void lv_indev_set_cursor(lv_indev_t *indev, lv_obj_t *cur_obj)
#if USE_LV_GROUP #if USE_LV_GROUP
/** /**
* Set a destination group for a keypad input device * Set a destination group for a keypad input device (for LV_INDEV_TYPE_KEYPAD)
* @param indev pointer to an input device (type: 'LV_INDEV_TYPE_KEYPAD') * @param indev pointer to an input device
* @param group point to a group * @param group point to a group
*/ */
void lv_indev_set_group(lv_indev_t *indev, lv_group_t *group) void lv_indev_set_group(lv_indev_t * indev, lv_group_t * group)
{ {
indev->group = group; if(indev->driver.type == LV_INDEV_TYPE_KEYPAD) indev->group = group;
} }
#endif #endif
/** /**
* Get the last point of an input device * Set the an array of points for LV_INDEV_TYPE_BUTTON.
* These points will be assigned to the buttons to press a specific point on the screen
* @param indev pointer to an input device
* @param group point to a group
*/
void lv_indev_set_button_points(lv_indev_t * indev, lv_point_t * points)
{
if(indev->driver.type == LV_INDEV_TYPE_BUTTON) indev->btn_points = points;
}
/**
* Get the last point of an input device (for LV_INDEV_TYPE_POINTER and LV_INDEV_TYPE_BUTTON)
* @param indev pointer to an input device * @param indev pointer to an input device
* @param point pointer to a point to store the result * @param point pointer to a point to store the result
*/ */
void lv_indev_get_point(lv_indev_t * indev, lv_point_t * point) void lv_indev_get_point(lv_indev_t * indev, lv_point_t * point)
{ {
if(indev->driver.type != LV_INDEV_TYPE_POINTER && indev->driver.type != LV_INDEV_TYPE_BUTTON) {
point->x = 0;
point->y = 0;
} else {
point->x = indev->proc.act_point.x; point->x = indev->proc.act_point.x;
point->y = indev->proc.act_point.y; point->y = indev->proc.act_point.y;
}
} }
/** /**
* Check if there is dragging with an input device or not * Check if there is dragging with an input device or not (for LV_INDEV_TYPE_POINTER and LV_INDEV_TYPE_BUTTON)
* @param indev pointer to an input device * @param indev pointer to an input device
* @return true: drag is in progress * @return true: drag is in progress
*/ */
bool lv_indev_is_dragging(lv_indev_t * indev) bool lv_indev_is_dragging(lv_indev_t * indev)
{ {
if(indev == NULL) return false; if(indev == NULL) return false;
if(indev->driver.type != LV_INDEV_TYPE_POINTER && indev->driver.type != LV_INDEV_TYPE_BUTTON) return false;
return indev->proc.drag_in_prog == 0 ? false : true; return indev->proc.drag_in_prog == 0 ? false : true;
} }
/** /**
* Get the vector of dragging of an input device * Get the vector of dragging of an input device (for LV_INDEV_TYPE_POINTER and LV_INDEV_TYPE_BUTTON)
* @param indev pointer to an input device * @param indev pointer to an input device
* @param point pointer to a point to store the vector * @param point pointer to a point to store the vector
*/ */
void lv_indev_get_vect(lv_indev_t * indev, lv_point_t * point) void lv_indev_get_vect(lv_indev_t * indev, lv_point_t * point)
{ {
if(indev->driver.type != LV_INDEV_TYPE_POINTER && indev->driver.type != LV_INDEV_TYPE_BUTTON) {
point->x = 0;
point->y = 0;
} else {
point->x = indev->proc.vect.x; point->x = indev->proc.vect.x;
point->y = indev->proc.vect.y; point->y = indev->proc.vect.y;
}
} }
/** /**
@ -184,7 +210,7 @@ uint32_t lv_indev_get_inactive_time(lv_indev_t * indev)
if(indev) return t = lv_tick_elaps(indev->last_activity_time); if(indev) return t = lv_tick_elaps(indev->last_activity_time);
lv_indev_t *i; lv_indev_t * i;
t = UINT16_MAX; t = UINT16_MAX;
i = lv_indev_next(NULL); i = lv_indev_next(NULL);
while(i) { while(i) {
@ -208,6 +234,7 @@ void lv_indev_wait_release(lv_indev_t * indev)
* STATIC FUNCTIONS * STATIC FUNCTIONS
**********************/ **********************/
#if LV_INDEV_READ_PERIOD != 0
/** /**
* Called periodically to handle the input devices * Called periodically to handle the input devices
* @param param unused * @param param unused
@ -225,162 +252,211 @@ static void indev_proc_task(void * param)
indev_act = i; indev_act = i;
/*Handle reset query before processing the point*/ /*Handle reset query before processing the point*/
if(i->proc.reset_query) { indev_proc_reset_query_handler(i);
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) { if(i->proc.disabled == 0) {
bool more_to_read;
do {
/*Read the data*/ /*Read the data*/
lv_indev_read(i, &data); more_to_read = lv_indev_read(i, &data);
indev_proc_reset_query_handler(i); /*The active object might deleted even in the read function*/
i->proc.state = data.state; i->proc.state = data.state;
if(i->proc.state == LV_INDEV_STATE_PR) { if(i->proc.state == LV_INDEV_STATE_PR) {
i->last_activity_time = lv_tick_get(); i->last_activity_time = lv_tick_get();
} }
/*Move the cursor if set and moved*/ if(i->driver.type == LV_INDEV_TYPE_POINTER) {
if(i->driver.type == LV_INDEV_TYPE_POINTER && indev_pointer_proc(i, &data);
i->cursor != NULL && } else if(i->driver.type == LV_INDEV_TYPE_KEYPAD) {
(i->proc.last_point.x != data.point.x || indev_keypad_proc(i, &data);
i->proc.last_point.y != data.point.y)) } else if(i->driver.type == LV_INDEV_TYPE_BUTTON) {
{ indev_button_proc(i, &data);
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*/ /*Handle reset query if it happened in during processing*/
if(i->proc.reset_query) { indev_proc_reset_query_handler(i);
i->proc.act_obj = NULL; } while(more_to_read);
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*/ i = lv_indev_next(i); /*Go to the next indev*/
} }
indev_act = NULL; /*End of indev processing, so no act indev*/ indev_act = NULL; /*End of indev processing, so no act indev*/
} }
/**
* Process a new point from LV_INDEV_TYPE_POINTER input device
* @param i pointer to an input device
* @param data pointer to the data read from the input device
*/
static void indev_pointer_proc(lv_indev_t * i, lv_indev_data_t * data)
{
/*Move the cursor if set and moved*/
if(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);
}
i->proc.act_point.x = data->point.x;
i->proc.act_point.y = data->point.y;
if(i->proc.state == LV_INDEV_STATE_PR) {
#if LV_INDEV_POINT_MARKER != 0
lv_area_t area;
area.x1 = i->proc.act_point.x - (LV_INDEV_POINT_MARKER >> 1);
area.y1 = i->proc.act_point.y - (LV_INDEV_POINT_MARKER >> 1);
area.x2 = i->proc.act_point.x + ((LV_INDEV_POINT_MARKER >> 1) | 0x1);
area.y2 = i->proc.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(&i->proc);
} else {
indev_proc_release(&i->proc);
}
i->proc.last_point.x = i->proc.act_point.x;
i->proc.last_point.y = i->proc.act_point.y;
}
/**
* Process a new point from LV_INDEV_TYPE_KEYPAD input device
* @param i pointer to an input device
* @param data pointer to the data read from the input device
*/
static void indev_keypad_proc(lv_indev_t * i, lv_indev_data_t * data)
{
#if USE_LV_GROUP
if(i->group == NULL) return;
/*Key press happened*/
if(data->state == LV_INDEV_STATE_PR &&
i->proc.last_state == LV_INDEV_STATE_REL) {
i->proc.pr_timestamp = lv_tick_get();
}
/*Pressing*/
else if(data->state == LV_INDEV_STATE_PR && i->proc.last_state == LV_INDEV_STATE_PR) {
if(data->key == LV_GROUP_KEY_ENTER &&
i->proc.long_pr_sent == 0 &&
lv_tick_elaps(i->proc.pr_timestamp) > LV_INDEV_LONG_PRESS_TIME) {
lv_group_send_data(i->group, LV_GROUP_KEY_ENTER_LONG);
i->proc.long_pr_sent = 1;
}
}
/*Release happened*/
else if(data->state == LV_INDEV_STATE_REL && i->proc.last_state == LV_INDEV_STATE_PR) {
/*The user might clear the key it was released. Always release the pressed key*/
data->key = i->proc.last_key;
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 if(data->key == LV_GROUP_KEY_ENTER && i->proc.long_pr_sent) {
/*Do nothing. Don't send the ENTER if ENTER_LONG was sent*/
} else {
lv_group_send_data(i->group, data->key);
}
if(i->proc.reset_query) return; /*The object might be deleted in `focus_cb` or due to any other user event*/
i->proc.pr_timestamp = 0;
i->proc.long_pr_sent = 0;
}
i->proc.last_state = data->state;
i->proc.last_key = data->key;
#endif
}
/** /**
* Process new points from a input device. indev->state.pressed has to be set * Process new points from a input device. indev->state.pressed has to be set
* @param indev pointer to an input device state * @param indev pointer to an input device state
* @param x x coordinate of the next point * @param x x coordinate of the next point
* @param y y coordinate of the next point * @param y y coordinate of the next point
*/ */
static void indev_proc_point(lv_indev_proc_t * indev) static void indev_button_proc(lv_indev_t * i, lv_indev_data_t * data)
{ {
if(indev->state == LV_INDEV_STATE_PR){ i->proc.act_point.x = i->btn_points[data->btn].x;
i->proc.act_point.y = i->btn_points[data->btn].y;
/*Still the same point is pressed*/
if(i->proc.last_point.x == i->proc.act_point.x &&
i->proc.last_point.y == i->proc.act_point.y &&
data->state == LV_INDEV_STATE_PR) {
#if LV_INDEV_POINT_MARKER != 0 #if LV_INDEV_POINT_MARKER != 0
lv_area_t area; lv_area_t area;
area.x1 = indev->act_point.x - (LV_INDEV_POINT_MARKER >> 1); area.x1 = i->proc.act_point.x - (LV_INDEV_POINT_MARKER >> 1);
area.y1 = indev->act_point.y - (LV_INDEV_POINT_MARKER >> 1); area.y1 = i->proc.act_point.y - (LV_INDEV_POINT_MARKER >> 1);
area.x2 = indev->act_point.x + ((LV_INDEV_POINT_MARKER >> 1) | 0x1); area.x2 = i->proc.act_point.x + ((LV_INDEV_POINT_MARKER >> 1) | 0x1);
area.y2 = indev->act_point.y + ((LV_INDEV_POINT_MARKER >> 1) | 0x1); area.y2 = i->proc.act_point.y + ((LV_INDEV_POINT_MARKER >> 1) | 0x1);
lv_rfill(&area, NULL, LV_COLOR_MAKE(0xFF, 0, 0), LV_OPA_COVER); lv_rfill(&area, NULL, LV_COLOR_MAKE(0xFF, 0, 0), LV_OPA_COVER);
#endif #endif
indev_proc_press(indev); indev_proc_press(&i->proc);
} else { } else {
indev_proc_release(indev); /*If a new point comes always make a release*/
indev_proc_release(&i->proc);
} }
indev->last_point.x = indev->act_point.x; i->proc.last_point.x = i->proc.act_point.x;
indev->last_point.y = indev->act_point.y; i->proc.last_point.y = i->proc.act_point.y;
} }
/** /**
* Process the pressed state * Process the pressed state of LV_INDEV_TYPE_POINER input devices
* @param indev pointer to an input device state * @param indev pointer to an input device 'proc'
*/ */
static void indev_proc_press(lv_indev_proc_t * info) static void indev_proc_press(lv_indev_proc_t * proc)
{ {
lv_obj_t * pr_obj = info->act_obj; lv_obj_t * pr_obj = proc->act_obj;
if(info->wait_unil_release != 0) return; if(proc->wait_unil_release != 0) return;
/*If there is no last object then search*/ /*If there is no last object then search*/
if(info->act_obj == NULL) { if(proc->act_obj == NULL) {
pr_obj = indev_search_obj(info, lv_layer_top()); pr_obj = indev_search_obj(proc, lv_layer_top());
if(pr_obj == NULL) pr_obj = indev_search_obj(info, lv_scr_act()); if(pr_obj == NULL) pr_obj = indev_search_obj(proc, lv_scr_act());
} }
/*If there is last object but it is not dragged also search*/ /*If there is last object but it is not dragged and not protected also search*/
else if(info->drag_in_prog == 0) {/*Now act_obj != NULL*/ else if(proc->drag_in_prog == 0 &&
pr_obj = indev_search_obj(info, lv_layer_top()); lv_obj_is_protected(proc->act_obj, LV_PROTECT_PRESS_LOST) == false) {/*Now act_obj != NULL*/
if(pr_obj == NULL) pr_obj = indev_search_obj(info, lv_scr_act()); pr_obj = indev_search_obj(proc, lv_layer_top());
if(pr_obj == NULL) pr_obj = indev_search_obj(proc, lv_scr_act());
} }
/*If a dragable object was the last then keep it*/ /*If a dragable or a protected object was the last then keep it*/
else { else {
} }
/*If a new object was found reset some variables and send a pressed signal*/ /*If a new object was found reset some variables and send a pressed signal*/
if(pr_obj != info->act_obj) { if(pr_obj != proc->act_obj) {
info->last_point.x = info->act_point.x; proc->last_point.x = proc->act_point.x;
info->last_point.y = info->act_point.y; proc->last_point.y = proc->act_point.y;
/*If a new object found the previous was lost, so send a signal*/ /*If a new object found the previous was lost, so send a signal*/
if(info->act_obj != NULL) { if(proc->act_obj != NULL) {
info->act_obj->signal_func(info->act_obj, LV_SIGNAL_PRESS_LOST, indev_act); proc->act_obj->signal_func(proc->act_obj, LV_SIGNAL_PRESS_LOST, indev_act);
if(info->reset_query != 0) return; if(proc->reset_query != 0) return;
} }
if(pr_obj != NULL) { if(pr_obj != NULL) {
/* Save the time when the obj pressed. /* Save the time when the obj pressed.
* It is necessary to count the long press time.*/ * It is necessary to count the long press time.*/
info->pr_timestamp = lv_tick_get(); proc->pr_timestamp = lv_tick_get();
info->long_pr_sent = 0; proc->long_pr_sent = 0;
info->drag_range_out = 0; proc->drag_range_out = 0;
info->drag_in_prog = 0; proc->drag_in_prog = 0;
info->drag_sum.x = 0; proc->drag_sum.x = 0;
info->drag_sum.y = 0; proc->drag_sum.y = 0;
/*Search for 'top' attribute*/ /*Search for 'top' attribute*/
lv_obj_t * i = pr_obj; lv_obj_t * i = pr_obj;
lv_obj_t * last_top = NULL; lv_obj_t * last_top = NULL;
while(i != NULL){ while(i != NULL) {
if(i->top != 0) last_top = i; if(i->top != 0) last_top = i;
i = lv_obj_get_parent(i); i = lv_obj_get_parent(i);
} }
@ -395,46 +471,46 @@ static void indev_proc_press(lv_indev_proc_t * info)
/*Send a signal about the press*/ /*Send a signal about the press*/
pr_obj->signal_func(pr_obj, LV_SIGNAL_PRESSED, indev_act); pr_obj->signal_func(pr_obj, LV_SIGNAL_PRESSED, indev_act);
if(info->reset_query != 0) return; if(proc->reset_query != 0) return;
} }
} }
info->act_obj = pr_obj; /*Save the pressed object*/ proc->act_obj = pr_obj; /*Save the pressed object*/
info->last_obj = info->act_obj; /*Refresh the last_obj*/ proc->last_obj = proc->act_obj; /*Refresh the last_obj*/
/*Calculate the vector*/ /*Calculate the vector*/
info->vect.x = info->act_point.x - info->last_point.x; proc->vect.x = proc->act_point.x - proc->last_point.x;
info->vect.y = info->act_point.y - info->last_point.y; proc->vect.y = proc->act_point.y - proc->last_point.y;
/*If there is active object and it can be dragged run the drag*/ /*If there is active object and it can be dragged run the drag*/
if(info->act_obj != NULL) { if(proc->act_obj != NULL) {
info->act_obj->signal_func(info->act_obj, LV_SIGNAL_PRESSING, indev_act); proc->act_obj->signal_func(proc->act_obj, LV_SIGNAL_PRESSING, indev_act);
if(info->reset_query != 0) return; if(proc->reset_query != 0) return;
indev_drag(info); indev_drag(proc);
if(info->reset_query != 0) return; if(proc->reset_query != 0) return;
/*If there is no drag then check for long press time*/ /*If there is no drag then check for long press time*/
if(info->drag_in_prog == 0 && info->long_pr_sent == 0) { if(proc->drag_in_prog == 0 && proc->long_pr_sent == 0) {
/*Send a signal about the long press if enough time elapsed*/ /*Send a signal about the long press if enough time elapsed*/
if(lv_tick_elaps(info->pr_timestamp) > LV_INDEV_LONG_PRESS_TIME) { if(lv_tick_elaps(proc->pr_timestamp) > LV_INDEV_LONG_PRESS_TIME) {
pr_obj->signal_func(pr_obj, LV_SIGNAL_LONG_PRESS, indev_act); pr_obj->signal_func(pr_obj, LV_SIGNAL_LONG_PRESS, indev_act);
if(info->reset_query != 0) return; if(proc->reset_query != 0) return;
/*Mark the signal sending to do not send it again*/ /*Mark the signal sending to do not send it again*/
info->long_pr_sent = 1; proc->long_pr_sent = 1;
/*Save the long press time stamp for the long press repeat handler*/ /*Save the long press time stamp for the long press repeat handler*/
info->longpr_rep_timestamp = lv_tick_get(); proc->longpr_rep_timestamp = lv_tick_get();
} }
} }
/*Send long press repeated signal*/ /*Send long press repeated signal*/
if(info->drag_in_prog == 0 && info->long_pr_sent == 1) { if(proc->drag_in_prog == 0 && proc->long_pr_sent == 1) {
/*Send a signal about the long press repeate if enough time elapsed*/ /*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) { if(lv_tick_elaps(proc->longpr_rep_timestamp) > LV_INDEV_LONG_PRESS_REP_TIME) {
pr_obj->signal_func(pr_obj, LV_SIGNAL_LONG_PRESS_REP, indev_act); pr_obj->signal_func(pr_obj, LV_SIGNAL_LONG_PRESS_REP, indev_act);
if(info->reset_query != 0) return; if(proc->reset_query != 0) return;
info->longpr_rep_timestamp = lv_tick_get(); proc->longpr_rep_timestamp = lv_tick_get();
} }
} }
@ -442,36 +518,58 @@ static void indev_proc_press(lv_indev_proc_t * info)
} }
/** /**
* Process the released state * Process the released state of LV_INDEV_TYPE_POINER input devices
* @param indev_proc_p pointer to an input device state * @param proc pointer to an input device 'proc'
*/ */
static void indev_proc_release(lv_indev_proc_t * state) static void indev_proc_release(lv_indev_proc_t * proc)
{ {
if(state->wait_unil_release != 0) { if(proc->wait_unil_release != 0) {
state->act_obj = NULL; proc->act_obj = NULL;
state->last_obj = NULL; proc->last_obj = NULL;
state->pr_timestamp = 0; proc->pr_timestamp = 0;
state->longpr_rep_timestamp = 0; proc->longpr_rep_timestamp = 0;
state->wait_unil_release = 0; proc->wait_unil_release = 0;
} }
/*Forgot the act obj and send a released signal */ /*Forgot the act obj and send a released signal */
if(state->act_obj != NULL) { if(proc->act_obj != NULL) {
state->act_obj->signal_func(state->act_obj, LV_SIGNAL_RELEASED, indev_act); proc->act_obj->signal_func(proc->act_obj, LV_SIGNAL_RELEASED, indev_act);
if(state->reset_query != 0) return; if(proc->reset_query != 0) return;
state->act_obj = NULL; proc->act_obj = NULL;
state->pr_timestamp = 0; proc->pr_timestamp = 0;
state->longpr_rep_timestamp = 0; proc->longpr_rep_timestamp = 0;
} }
/*The reset can be set in the signal function. /*The reset can be set in the signal function.
* In case of reset query ignore the remaining parts.*/ * In case of reset query ignore the remaining parts.*/
if(state->last_obj != NULL && state->reset_query == 0) { if(proc->last_obj != NULL && proc->reset_query == 0) {
indev_drag_throw(state); indev_drag_throw(proc);
if(state->reset_query != 0) return; if(proc->reset_query != 0) return;
} }
} }
/**
* Process a new point from LV_INDEV_TYPE_BUTTON input device
* @param i pointer to an input device
* @param data pointer to the data read from the input device
* Reset input device if a reset query has been sent to it
* @param indev pointer to an input device
*/
static void indev_proc_reset_query_handler(lv_indev_t * indev)
{
if(indev->proc.reset_query) {
indev->proc.act_obj = NULL;
indev->proc.last_obj = NULL;
indev->proc.drag_range_out = 0;
indev->proc.drag_in_prog = 0;
indev->proc.long_pr_sent = 0;
indev->proc.pr_timestamp = 0;
indev->proc.longpr_rep_timestamp = 0;
indev->proc.drag_sum.x = 0;
indev->proc.drag_sum.y = 0;
indev->proc.reset_query = 0;
}
}
/** /**
* Search the most top, clickable object on the last point of an input device * Search the most top, clickable object on the last point of an input device
* @param indev pointer to an input device * @param indev pointer to an input device
@ -538,8 +636,7 @@ static void indev_drag(lv_indev_proc_t * state)
/*If a move is greater then LV_DRAG_LIMIT then begin the drag*/ /*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 || if(LV_MATH_ABS(state->drag_sum.x) >= LV_INDEV_DRAG_LIMIT ||
LV_MATH_ABS(state->drag_sum.y) >= LV_INDEV_DRAG_LIMIT) LV_MATH_ABS(state->drag_sum.y) >= LV_INDEV_DRAG_LIMIT) {
{
state->drag_range_out = 1; state->drag_range_out = 1;
} }
} }
@ -549,21 +646,30 @@ static void indev_drag(lv_indev_proc_t * state)
/*Set new position if the vector is not zero*/ /*Set new position if the vector is not zero*/
if(state->vect.x != 0 || if(state->vect.x != 0 ||
state->vect.y != 0) { state->vect.y != 0) {
/*Get the coordinates of the object end modify them*/ /*Get the coordinates of the object and modify them*/
lv_coord_t act_x = lv_obj_get_x(drag_obj); lv_coord_t act_x = lv_obj_get_x(drag_obj);
lv_coord_t act_y = lv_obj_get_y(drag_obj); lv_coord_t act_y = lv_obj_get_y(drag_obj);
uint16_t inv_buf_size = lv_refr_get_buf_size(); /*Get the number of currently invalidated areas*/
lv_coord_t prev_x = drag_obj->coords.x1;
lv_coord_t prev_y = drag_obj->coords.y1;
lv_obj_set_pos(drag_obj, act_x + state->vect.x, act_y + state->vect.y); 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*/ /*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(drag_obj->coords.x1 != prev_x || drag_obj->coords.y1 != prev_y) {
if(state->drag_range_out != 0) { /*Send the drag begin signal on first move*/ 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); drag_obj->signal_func(drag_obj, LV_SIGNAL_DRAG_BEGIN, indev_act);
if(state->reset_query != 0) return; if(state->reset_query != 0) return;
} }
state->drag_in_prog = 1; state->drag_in_prog = 1;
} }
/*If the object didn't moved then clear the invalidated areas*/
else {
uint16_t new_inv_buf_size = lv_refr_get_buf_size();
lv_refr_pop_from_buf(new_inv_buf_size - inv_buf_size);
}
} }
} }
} }
@ -588,19 +694,18 @@ static void indev_drag_throw(lv_indev_proc_t * state)
if(drag_obj == NULL) return; if(drag_obj == NULL) return;
/*Return if the drag throw is not enabled*/ /*Return if the drag throw is not enabled*/
if(lv_obj_get_drag_throw(drag_obj) == false ){ if(lv_obj_get_drag_throw(drag_obj) == false) {
state->drag_in_prog = 0; state->drag_in_prog = 0;
drag_obj->signal_func(drag_obj, LV_SIGNAL_DRAG_END, indev_act); drag_obj->signal_func(drag_obj, LV_SIGNAL_DRAG_END, indev_act);
return; return;
} }
/*Reduce the vectors*/ /*Reduce the vectors*/
state->vect.x = state->vect.x * (100 -LV_INDEV_DRAG_THROW) / 100; state->vect.x = state->vect.x * (100 - LV_INDEV_DRAG_THROW) / 100;
state->vect.y = state->vect.y * (100 -LV_INDEV_DRAG_THROW) / 100; state->vect.y = state->vect.y * (100 - LV_INDEV_DRAG_THROW) / 100;
if(state->vect.x != 0 || if(state->vect.x != 0 ||
state->vect.y != 0) state->vect.y != 0) {
{
/*Get the coordinates and modify them*/ /*Get the coordinates and modify them*/
lv_coord_t act_x = lv_obj_get_x(drag_obj) + state->vect.x; 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_coord_t act_y = lv_obj_get_y(drag_obj) + state->vect.y;
@ -622,3 +727,4 @@ static void indev_drag_throw(lv_indev_proc_t * state)
drag_obj->signal_func(drag_obj, LV_SIGNAL_DRAG_END, indev_act); drag_obj->signal_func(drag_obj, LV_SIGNAL_DRAG_END, indev_act);
} }
} }
#endif

View File

@ -60,40 +60,49 @@ void lv_indev_reset_lpr(lv_indev_t * indev);
void lv_indev_enable(lv_hal_indev_type_t type, bool enable); void lv_indev_enable(lv_hal_indev_type_t type, bool enable);
/** /**
* Set a cursor for a pointer input device * Set a cursor for a pointer input device (for LV_INPUT_TYPE_POINTER and LV_INPUT_TYPE_BUTTON)
* @param indev pointer to an input device (type: 'LV_INDEV_TYPE_POINTER') * @param indev pointer to an input device
* @param cur_obj pointer to an object to be used as cursor * @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); void lv_indev_set_cursor(lv_indev_t *indev, lv_obj_t *cur_obj);
#if USE_LV_GROUP #if USE_LV_GROUP
/** /**
* Set a destination group for a keypad input device * Set a destination group for a keypad input device (for LV_INDEV_TYPE_KEYPAD)
* @param indev pointer to an input device (type: 'LV_INDEV_TYPE_KEYPAD') * @param indev pointer to an input device
* @param group point to a group * @param group point to a group
*/ */
void lv_indev_set_group(lv_indev_t *indev, lv_group_t *group); void lv_indev_set_group(lv_indev_t *indev, lv_group_t *group);
#endif #endif
/** /**
* Get the last point of an input device * Set the an array of points for LV_INDEV_TYPE_BUTTON.
* These points will be assigned to the buttons to press a specific point on the screen
* @param indev pointer to an input device
* @param group point to a group
*/
void lv_indev_set_button_points(lv_indev_t *indev, lv_point_t *points);
/**
* Get the last point of an input device (for LV_INDEV_TYPE_POINTER and LV_INDEV_TYPE_BUTTON)
* @param indev pointer to an input device * @param indev pointer to an input device
* @param point pointer to a point to store the result * @param point pointer to a point to store the result
*/ */
void lv_indev_get_point(lv_indev_t * indev, lv_point_t * point); void lv_indev_get_point(lv_indev_t * indev, lv_point_t * point);
/** /**
* Check if there is dragging with an input device or not * Check if there is dragging with an input device or not (for LV_INDEV_TYPE_POINTER and LV_INDEV_TYPE_BUTTON)
* @param indev pointer to an input device * @param indev pointer to an input device
* @return true: drag is in progress * @return true: drag is in progress
*/ */
bool lv_indev_is_dragging(lv_indev_t * indev); bool lv_indev_is_dragging(lv_indev_t * indev);
/** /**
* Get the vector of dragging of an input device * Get the vector of dragging of an input device (for LV_INDEV_TYPE_POINTER and LV_INDEV_TYPE_BUTTON)
* @param indev pointer to an input device * @param indev pointer to an input device
* @param point pointer to a point to store the vector * @param point pointer to a point to store the vector
*/ */
void lv_indev_get_vect(lv_indev_t * indev, lv_point_t * point); void lv_indev_get_vect(lv_indev_t * indev, lv_point_t * point);
/** /**
* Get elapsed time since last press * Get elapsed time since last press
* @param indev pointer to an input device (NULL to get the overall smallest inactivity) * @param indev pointer to an input device (NULL to get the overall smallest inactivity)

View File

@ -132,7 +132,7 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent, lv_obj_t * copy)
new_obj->ext_size = 0; new_obj->ext_size = 0;
/*Set the default styles*/ /*Set the default styles*/
lv_theme_t *th = lv_theme_get_current(); lv_theme_t * th = lv_theme_get_current();
if(th) { if(th) {
new_obj->style_p = th->bg; new_obj->style_p = th->bg;
} else { } else {
@ -166,8 +166,7 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent, lv_obj_t * copy)
new_obj->ext_attr = NULL; new_obj->ext_attr = NULL;
} }
/*parent != NULL create normal obj. on a parent*/ /*parent != NULL create normal obj. on a parent*/
else else {
{
new_obj = lv_ll_ins_head(&(parent)->child_ll); new_obj = lv_ll_ins_head(&(parent)->child_ll);
new_obj->par = parent; /*Set the parent*/ new_obj->par = parent; /*Set the parent*/
@ -265,6 +264,16 @@ lv_res_t lv_obj_del(lv_obj_t * obj)
{ {
lv_obj_invalidate(obj); lv_obj_invalidate(obj);
/*Delete from the group*/
#if USE_LV_GROUP
if(obj->group_p != NULL) lv_group_remove_obj(obj);
#endif
/*Remove the animations from this object*/
#if USE_LV_ANIMATION
lv_anim_del(obj, NULL);
#endif
/*Recursively delete the children*/ /*Recursively delete the children*/
lv_obj_t * i; lv_obj_t * i;
lv_obj_t * i_next; lv_obj_t * i_next;
@ -279,28 +288,6 @@ lv_res_t lv_obj_del(lv_obj_t * obj)
/*Set i to the next node*/ /*Set i to the next node*/
i = i_next; i = i_next;
} }
#if USE_LV_ANIMATION
/*Remove the animations from this object*/
lv_anim_del(obj, NULL);
#endif
/* Reset all input devices if
* the currently pressed object is deleted*/
lv_indev_t * indev = lv_indev_next(NULL);
lv_obj_t * dpar;
while(indev) {
dpar = obj;
while(dpar != NULL) {
if(indev->proc.act_obj == dpar ||
indev->proc.last_obj == dpar) {
lv_indev_reset(indev);
break;
} else {
dpar = lv_obj_get_parent(dpar);
}
}
indev = lv_indev_next(indev);
}
/*Remove the object from parent's children list*/ /*Remove the object from parent's children list*/
lv_obj_t * par = lv_obj_get_parent(obj); lv_obj_t * par = lv_obj_get_parent(obj);
@ -310,6 +297,16 @@ lv_res_t lv_obj_del(lv_obj_t * obj)
lv_ll_rem(&(par->child_ll), obj); lv_ll_rem(&(par->child_ll), obj);
} }
/* Reset all input devices if
* the currently pressed object is deleted*/
lv_indev_t * indev = lv_indev_next(NULL);
while(indev) {
if(indev->proc.act_obj == obj || indev->proc.last_obj == obj) {
lv_indev_reset(indev);
}
indev = lv_indev_next(indev);
}
/* All children deleted. /* All children deleted.
* Now clean up the object specific data*/ * Now clean up the object specific data*/
obj->signal_func(obj, LV_SIGNAL_CLEANUP, NULL); obj->signal_func(obj, LV_SIGNAL_CLEANUP, NULL);
@ -330,9 +327,9 @@ lv_res_t lv_obj_del(lv_obj_t * obj)
* Delete all children of an object * Delete all children of an object
* @param obj pointer to an object * @param obj pointer to an object
*/ */
void lv_obj_clean(lv_obj_t *obj) void lv_obj_clean(lv_obj_t * obj)
{ {
lv_obj_t *child = lv_obj_get_child(obj, NULL); lv_obj_t * child = lv_obj_get_child(obj, NULL);
while(child) { while(child) {
lv_obj_del(child); lv_obj_del(child);
@ -346,6 +343,8 @@ void lv_obj_clean(lv_obj_t *obj)
*/ */
void lv_obj_invalidate(lv_obj_t * obj) void lv_obj_invalidate(lv_obj_t * obj)
{ {
if(lv_obj_get_hidden(obj)) return;
/*Invalidate the object only if it belongs to the 'act_scr'*/ /*Invalidate the object only if it belongs to the 'act_scr'*/
lv_obj_t * obj_scr = lv_obj_get_screen(obj); lv_obj_t * obj_scr = lv_obj_get_screen(obj);
if(obj_scr == lv_scr_act() || if(obj_scr == lv_scr_act() ||
@ -365,8 +364,9 @@ void lv_obj_invalidate(lv_obj_t * obj)
/*Check through all parents*/ /*Check through all parents*/
while(par != NULL) { while(par != NULL) {
union_ok = lv_area_union(&area_trunc, &area_trunc, &par->coords); union_ok = lv_area_intersect(&area_trunc, &area_trunc, &par->coords);
if(union_ok == false) break; /*If no common parts with parent break;*/ if(union_ok == false) break; /*If no common parts with parent break;*/
if(lv_obj_get_hidden(par)) return; /*If the parent is hidden then the child is hidden and won't be drawn*/
par = lv_obj_get_parent(par); par = lv_obj_get_parent(par);
} }
@ -567,7 +567,7 @@ void lv_obj_set_height(lv_obj_t * obj, lv_coord_t h)
* @param x_mod x coordinate shift after alignment * @param x_mod x coordinate shift after alignment
* @param y_mod y 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) 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)
{ {
lv_coord_t new_x = lv_obj_get_x(obj); lv_coord_t new_x = lv_obj_get_x(obj);
lv_coord_t new_y = lv_obj_get_y(obj); lv_coord_t new_y = lv_obj_get_y(obj);
@ -576,8 +576,7 @@ void lv_obj_align(lv_obj_t * obj,lv_obj_t * base, lv_align_t align, lv_coord_t x
base = lv_obj_get_parent(obj); base = lv_obj_get_parent(obj);
} }
switch(align) switch(align) {
{
case LV_ALIGN_CENTER: case LV_ALIGN_CENTER:
new_x = lv_obj_get_width(base) / 2 - lv_obj_get_width(obj) / 2; new_x = lv_obj_get_width(base) / 2 - lv_obj_get_width(obj) / 2;
new_y = lv_obj_get_height(base) / 2 - lv_obj_get_height(obj) / 2; new_y = lv_obj_get_height(base) / 2 - lv_obj_get_height(obj) / 2;
@ -753,12 +752,15 @@ void lv_obj_report_style_mod(lv_style_t * style)
*/ */
void lv_obj_set_hidden(lv_obj_t * obj, bool en) void lv_obj_set_hidden(lv_obj_t * obj, bool en)
{ {
if(!obj->hidden) lv_obj_invalidate(obj); /*Invalidate when not hidden (hidden objects are ignored) */
obj->hidden = en == false ? 0 : 1; obj->hidden = en == false ? 0 : 1;
if(!obj->hidden) lv_obj_invalidate(obj); /*Invalidate when not hidden (hidden objects are ignored) */
lv_obj_t * par = lv_obj_get_parent(obj); lv_obj_t * par = lv_obj_get_parent(obj);
par->signal_func(par, LV_SIGNAL_CHILD_CHG, obj); par->signal_func(par, LV_SIGNAL_CHILD_CHG, obj);
lv_obj_invalidate(obj);
} }
/** /**
@ -789,6 +791,7 @@ void lv_obj_set_top(lv_obj_t * obj, bool en)
*/ */
void lv_obj_set_drag(lv_obj_t * obj, bool en) void lv_obj_set_drag(lv_obj_t * obj, bool en)
{ {
if(en == true) lv_obj_set_click(obj, true); /*Drag is useless without enabled clicking*/
obj->drag = (en == true ? 1 : 0); obj->drag = (en == true ? 1 : 0);
} }
@ -869,7 +872,7 @@ void * lv_obj_allocate_ext_attr(lv_obj_t * obj, uint16_t ext_size)
{ {
obj->ext_attr = lv_mem_realloc(obj->ext_attr, ext_size); obj->ext_attr = lv_mem_realloc(obj->ext_attr, ext_size);
return (void*)obj->ext_attr; return (void *)obj->ext_attr;
} }
/** /**
@ -919,7 +922,7 @@ void lv_obj_set_free_ptr(lv_obj_t * obj, void * free_p)
* @param delay delay before the animation in milliseconds * @param delay delay before the animation in milliseconds
* @param cb a function to call when the animation is ready * @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 *)) void lv_obj_animate(lv_obj_t * obj, lv_anim_builtin_t type, uint16_t time, uint16_t delay, void (*cb)(lv_obj_t *))
{ {
lv_obj_t * par = lv_obj_get_parent(obj); lv_obj_t * par = lv_obj_get_parent(obj);
@ -930,8 +933,8 @@ void lv_obj_animate(lv_obj_t * obj, lv_anim_builtin_t type, uint16_t time, uint1
lv_anim_t a; lv_anim_t a;
a.var = obj; a.var = obj;
a.time = time; a.time = time;
a.act_time = (int32_t)-delay; a.act_time = (int32_t) - delay;
a.end_cb = (void(*)(void*))cb; a.end_cb = (void(*)(void *))cb;
a.path = lv_anim_path_linear; a.path = lv_anim_path_linear;
a.playback_pause = 0; a.playback_pause = 0;
a.repeat_pause = 0; a.repeat_pause = 0;
@ -951,22 +954,22 @@ void lv_obj_animate(lv_obj_t * obj, lv_anim_builtin_t type, uint16_t time, uint1
a.end = lv_obj_get_x(obj); a.end = lv_obj_get_x(obj);
break; break;
case LV_ANIM_FLOAT_TOP: case LV_ANIM_FLOAT_TOP:
a.fp = (void(*)(void * , int32_t))lv_obj_set_y; a.fp = (void(*)(void *, int32_t))lv_obj_set_y;
a.start = -lv_obj_get_height(obj); a.start = -lv_obj_get_height(obj);
a.end = lv_obj_get_y(obj); a.end = lv_obj_get_y(obj);
break; break;
case LV_ANIM_FLOAT_BOTTOM: case LV_ANIM_FLOAT_BOTTOM:
a.fp = (void(*)(void * , int32_t))lv_obj_set_y; a.fp = (void(*)(void *, int32_t))lv_obj_set_y;
a.start = lv_obj_get_height(par); a.start = lv_obj_get_height(par);
a.end = lv_obj_get_y(obj); a.end = lv_obj_get_y(obj);
break; break;
case LV_ANIM_GROW_H: case LV_ANIM_GROW_H:
a.fp = (void(*)(void * , int32_t))lv_obj_set_width; a.fp = (void(*)(void *, int32_t))lv_obj_set_width;
a.start = 0; a.start = 0;
a.end = lv_obj_get_width(obj); a.end = lv_obj_get_width(obj);
break; break;
case LV_ANIM_GROW_V: case LV_ANIM_GROW_V:
a.fp = (void(*)(void * , int32_t))lv_obj_set_height; a.fp = (void(*)(void *, int32_t))lv_obj_set_height;
a.start = 0; a.start = 0;
a.end = lv_obj_get_height(obj); a.end = lv_obj_get_height(obj);
break; break;
@ -1040,8 +1043,7 @@ lv_obj_t * lv_obj_get_screen(lv_obj_t * obj)
do { do {
act_p = par; act_p = par;
par = lv_obj_get_parent(act_p); par = lv_obj_get_parent(act_p);
} } while(par != NULL);
while(par != NULL);
return act_p; return act_p;
} }
@ -1202,7 +1204,17 @@ lv_style_t * lv_obj_get_style(lv_obj_t * obj)
while(par) { while(par) {
if(par->style_p) { if(par->style_p) {
if(par->style_p->glass == 0) { if(par->style_p->glass == 0) {
#if USE_LV_GROUP == 0
style_act = par->style_p; style_act = par->style_p;
#else
/*Is a parent is focused then use then focused style*/
lv_group_t * g = lv_obj_get_group(par);
if(lv_group_get_focused(g) == par) {
style_act = lv_group_mod_style(g, par->style_p);
} else {
style_act = par->style_p;
}
#endif
break; break;
} }
} }
@ -1342,6 +1354,34 @@ void * lv_obj_get_ext_attr(lv_obj_t * obj)
return obj->ext_attr; return obj->ext_attr;
} }
/**
* Get object's and its ancestors type. Put their name in `type_buf` starting with the current type.
* E.g. buf.type[0]="lv_btn", buf.type[1]="lv_cont", buf.type[2]="lv_obj"
* @param obj pointer to an object which type should be get
* @param buf pointer to an `lv_obj_type_t` buffer to store the types
*/
void lv_obj_get_type(lv_obj_t * obj, lv_obj_type_t * buf)
{
lv_obj_type_t tmp;
memset(buf, 0, sizeof(lv_obj_type_t));
memset(&tmp, 0, sizeof(lv_obj_type_t));
obj->signal_func(obj, LV_SIGNAL_GET_TYPE, &tmp);
uint8_t cnt;
for(cnt = 0; cnt < LV_MAX_ANCESTOR_NUM; cnt++) {
if(tmp.type[cnt] == NULL) break;
}
/*Swap the order. The real type comes first*/
uint8_t i;
for(i = 0; i < cnt; i++) {
buf->type[i] = tmp.type[cnt - 1 - i];
}
}
#ifdef LV_OBJ_FREE_NUM_TYPE #ifdef LV_OBJ_FREE_NUM_TYPE
/** /**
* Get the free number * Get the free number
@ -1366,6 +1406,7 @@ void * lv_obj_get_free_ptr(lv_obj_t * obj)
} }
#endif #endif
#if USE_LV_GROUP #if USE_LV_GROUP
/** /**
* Get the group of the object * Get the group of the object
@ -1440,19 +1481,16 @@ static lv_res_t lv_obj_signal(lv_obj_t * obj, lv_signal_t sign, void * param)
lv_res_t res = LV_RES_OK; lv_res_t res = LV_RES_OK;
lv_style_t * style = lv_obj_get_style(obj); lv_style_t * style = lv_obj_get_style(obj);
switch(sign) { if(sign == LV_SIGNAL_CHILD_CHG) {
case LV_SIGNAL_CHILD_CHG:
/*Return 'invalid' if the child change signal is not enabled*/ /*Return 'invalid' if the child change signal is not enabled*/
if(lv_obj_is_protected(obj, LV_PROTECT_CHILD_CHG) != false) res = LV_RES_INV; if(lv_obj_is_protected(obj, LV_PROTECT_CHILD_CHG) != false) res = LV_RES_INV;
break; } else if(sign == LV_SIGNAL_REFR_EXT_SIZE) {
case LV_SIGNAL_REFR_EXT_SIZE:
if(style->body.shadow.width > obj->ext_size) obj->ext_size = style->body.shadow.width; if(style->body.shadow.width > obj->ext_size) obj->ext_size = style->body.shadow.width;
break; } else if(sign == LV_SIGNAL_STYLE_CHG) {
case LV_SIGNAL_STYLE_CHG:
lv_obj_refresh_ext_size(obj); lv_obj_refresh_ext_size(obj);
break; } else if(sign == LV_SIGNAL_GET_TYPE) {
default: lv_obj_type_t * buf = param;
break; buf->type[0] = "lv_obj";
} }
return res; return res;
@ -1546,6 +1584,16 @@ static void delete_children(lv_obj_t * obj)
if(obj->group_p != NULL) lv_group_remove_obj(obj); if(obj->group_p != NULL) lv_group_remove_obj(obj);
#endif #endif
/* Reset the input devices if
* the currently pressed object is deleted*/
lv_indev_t * indev = lv_indev_next(NULL);
while(indev) {
if(indev->proc.act_obj == obj || indev->proc.last_obj == obj) {
lv_indev_reset(indev);
}
indev = lv_indev_next(indev);
}
/*Remove the object from parent's children list*/ /*Remove the object from parent's children list*/
lv_obj_t * par = lv_obj_get_parent(obj); lv_obj_t * par = lv_obj_get_parent(obj);
lv_ll_rem(&(par->child_ll), obj); lv_ll_rem(&(par->child_ll), obj);

View File

@ -28,29 +28,31 @@ extern "C" {
/*Error check of lv_conf.h*/ /*Error check of lv_conf.h*/
#if LV_HOR_RES == 0 || LV_VER_RES == 0 #if LV_HOR_RES == 0 || LV_VER_RES == 0
#error "LV: LV_HOR_RES and LV_VER_RES must be greater then 0" #error "LittlevGL: LV_HOR_RES and LV_VER_RES must be greater then 0"
#endif #endif
#if LV_ANTIALIAS != 0 && LV_ANTIALIAS != 1 #if LV_ANTIALIAS > 1
#error "LV: LV_ATIALIAS can be only 0 or 1" #error "LittlevGL: LV_ANTIALIAS can be only 0 or 1"
#endif #endif
#if LV_VDB_SIZE == 0 && LV_ANTIALIAS != 0 #if LV_VDB_SIZE == 0 && LV_ANTIALIAS != 0
#error "LV: If LV_VDB_SIZE == 0 the antialaissing must be disabled" #error "LittlevGL: If LV_VDB_SIZE == 0 the anti-aliasing must be disabled"
#endif #endif
#if LV_VDB_SIZE != 0 && LV_VDB_SIZE < LV_HOR_RES && LV_ANTIALIAS == 0 #if LV_VDB_SIZE > 0 && LV_VDB_SIZE < LV_HOR_RES
#error "LV: Small Virtual Display Buffer (lv_conf.h: LV_VDB_SIZE >= LV_HOR_RES)" #error "LittlevGL: Small Virtual Display Buffer (lv_conf.h: LV_VDB_SIZE >= LV_HOR_RES)"
#endif #endif
#if LV_VDB_SIZE != 0 && LV_VDB_SIZE < 2 *LV_HOR_RES && LV_ANTIALIAS != 0 #if LV_VDB_SIZE == 0 && USE_LV_REAL_DRAW == 0
#error "LV: Small Virtual Display Buffer (lv_conf.h: LV_VDB_SIZE >= (2 * LV_HOR_RES))" #error "LittlevGL: If LV_VDB_SIZE = 0 Real drawing function are required (lv_conf.h: USE_LV_REAL_DRAW 1)"
#endif #endif
#define LV_ANIM_IN 0x00 /*Animation to show an object. 'OR' it with lv_anim_builtin_t*/ #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_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*/ #define LV_ANIM_DIR_MASK 0x80 /*ANIM_IN/ANIM_OUT mask*/
#define LV_MAX_ANCESTOR_NUM 8
/********************** /**********************
* TYPEDEFS * TYPEDEFS
**********************/ **********************/
@ -62,7 +64,7 @@ typedef enum
LV_DESIGN_DRAW_MAIN, LV_DESIGN_DRAW_MAIN,
LV_DESIGN_DRAW_POST, LV_DESIGN_DRAW_POST,
LV_DESIGN_COVER_CHK, LV_DESIGN_COVER_CHK,
}lv_design_mode_t; } 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 bool (* lv_design_func_t) (struct _lv_obj_t * obj, const lv_area_t * mask_p, lv_design_mode_t mode);
@ -70,7 +72,7 @@ typedef enum
{ {
LV_RES_INV = 0, /*Typically indicates that the object is deleted (become invalid) in the action function*/ 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_OK, /*The object is valid (no deleted) after the action*/
}lv_res_t; } lv_res_t;
typedef enum typedef enum
{ {
@ -80,6 +82,7 @@ typedef enum
LV_SIGNAL_CORD_CHG, LV_SIGNAL_CORD_CHG,
LV_SIGNAL_STYLE_CHG, LV_SIGNAL_STYLE_CHG,
LV_SIGNAL_REFR_EXT_SIZE, LV_SIGNAL_REFR_EXT_SIZE,
LV_SIGNAL_GET_TYPE,
/*Input device related*/ /*Input device related*/
LV_SIGNAL_PRESSED, LV_SIGNAL_PRESSED,
@ -95,7 +98,7 @@ typedef enum
LV_SIGNAL_FOCUS, LV_SIGNAL_FOCUS,
LV_SIGNAL_DEFOCUS, LV_SIGNAL_DEFOCUS,
LV_SIGNAL_CONTROLL, LV_SIGNAL_CONTROLL,
}lv_signal_t; } lv_signal_t;
typedef lv_res_t (* lv_signal_func_t) (struct _lv_obj_t * obj, lv_signal_t sign, void * param); typedef lv_res_t (* lv_signal_func_t) (struct _lv_obj_t * obj, lv_signal_t sign, void * param);
@ -116,8 +119,9 @@ typedef struct _lv_obj_t
void * free_ptr; /*Application specific pointer (set it freely)*/ void * free_ptr; /*Application specific pointer (set it freely)*/
#endif #endif
#if USE_LV_GROUP != 0
void * group_p; /*Pointer to the group of the object*/ void * group_p; /*Pointer to the group of the object*/
#endif
/*Attributes and states*/ /*Attributes and states*/
uint8_t click :1; /*1: Can be pressed by an input device*/ uint8_t click :1; /*1: Can be pressed by an input device*/
uint8_t drag :1; /*1: Enable the dragging*/ uint8_t drag :1; /*1: Enable the dragging*/
@ -134,7 +138,7 @@ typedef struct _lv_obj_t
#ifdef LV_OBJ_FREE_NUM_TYPE #ifdef LV_OBJ_FREE_NUM_TYPE
LV_OBJ_FREE_NUM_TYPE free_num; /*Application specific identifier (set it freely)*/ LV_OBJ_FREE_NUM_TYPE free_num; /*Application specific identifier (set it freely)*/
#endif #endif
}lv_obj_t; } lv_obj_t;
typedef lv_res_t (*lv_action_t) (struct _lv_obj_t * obj); typedef lv_res_t (*lv_action_t) (struct _lv_obj_t * obj);
@ -146,7 +150,14 @@ typedef enum
LV_PROTECT_PARENT = 0x02, /*Prevent automatic parent change (e.g. in lv_page)*/ 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_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_FOLLOW = 0x08, /*Prevent the object be followed in automatic ordering (e.g. in lv_cont PRETTY layout)*/
}lv_protect_t; LV_PROTECT_PRESS_LOST= 0x10, /*TODO */
} lv_protect_t;
/*Used by `lv_obj_get_type()`. The object's and its ancestor types are stored here*/
typedef struct {
const char * type[LV_MAX_ANCESTOR_NUM]; /*[0]: the actual type, [1]: ancestor, [2] #1's ancestor ... [x]: "lv_obj" */
} lv_obj_type_t;
typedef enum typedef enum
{ {
@ -171,7 +182,7 @@ typedef enum
LV_ALIGN_OUT_RIGHT_TOP, LV_ALIGN_OUT_RIGHT_TOP,
LV_ALIGN_OUT_RIGHT_MID, LV_ALIGN_OUT_RIGHT_MID,
LV_ALIGN_OUT_RIGHT_BOTTOM, LV_ALIGN_OUT_RIGHT_BOTTOM,
}lv_align_t; } lv_align_t;
typedef enum typedef enum
{ {
@ -182,7 +193,7 @@ typedef enum
LV_ANIM_FLOAT_RIGHT, /*Float from/to the right*/ LV_ANIM_FLOAT_RIGHT, /*Float from/to the right*/
LV_ANIM_GROW_H, /*Grow/shrink horizontally*/ LV_ANIM_GROW_H, /*Grow/shrink horizontally*/
LV_ANIM_GROW_V, /*Grow/shrink vertically*/ LV_ANIM_GROW_V, /*Grow/shrink vertically*/
}lv_anim_builtin_t; } lv_anim_builtin_t;
/********************** /**********************
* GLOBAL PROTOTYPES * GLOBAL PROTOTYPES
@ -225,7 +236,6 @@ void lv_obj_clean(lv_obj_t *obj);
*/ */
void lv_obj_invalidate(lv_obj_t * obj); void lv_obj_invalidate(lv_obj_t * obj);
/*===================== /*=====================
* Setter functions * Setter functions
*====================*/ *====================*/
@ -419,7 +429,7 @@ void lv_obj_set_design_func(lv_obj_t * obj, lv_design_func_t fp);
* Allocate a new ext. data for an object * Allocate a new ext. data for an object
* @param obj pointer to an object * @param obj pointer to an object
* @param ext_size the size of the new ext. data * @param ext_size the size of the new ext. data
* @return Normal pointer to the allocated ext * @return pointer to the allocated ext
*/ */
void * lv_obj_allocate_ext_attr(lv_obj_t * obj, uint16_t ext_size); void * lv_obj_allocate_ext_attr(lv_obj_t * obj, uint16_t ext_size);
@ -675,6 +685,14 @@ lv_design_func_t lv_obj_get_design_func(lv_obj_t * obj);
*/ */
void * lv_obj_get_ext_attr(lv_obj_t * obj); void * lv_obj_get_ext_attr(lv_obj_t * obj);
/**
* Get object's and its ancestors type. Put their name in `type_buf` starting with the current type.
* E.g. buf.type[0]="lv_btn", buf.type[1]="lv_cont", buf.type[2]="lv_obj"
* @param obj pointer to an object which type should be get
* @param buf pointer to an `lv_obj_type_t` buffer to store the types
*/
void lv_obj_get_type(lv_obj_t * obj, lv_obj_type_t * buf);
#ifdef LV_OBJ_FREE_NUM_TYPE #ifdef LV_OBJ_FREE_NUM_TYPE
/** /**
* Get the free number * Get the free number

View File

@ -21,11 +21,10 @@
/********************** /**********************
* TYPEDEFS * TYPEDEFS
**********************/ **********************/
typedef struct typedef struct {
{
lv_area_t area; lv_area_t area;
uint8_t joined; uint8_t joined;
}lv_join_t; } lv_join_t;
/********************** /**********************
* STATIC PROTOTYPES * STATIC PROTOTYPES
@ -48,7 +47,8 @@ static void lv_refr_obj(lv_obj_t * obj, const lv_area_t * mask_ori_p);
**********************/ **********************/
static lv_join_t inv_buf[LV_INV_FIFO_SIZE]; static lv_join_t inv_buf[LV_INV_FIFO_SIZE];
static uint16_t inv_buf_p; static uint16_t inv_buf_p;
static void (*monitor_cb)(uint32_t, uint32_t); static void (*monitor_cb)(uint32_t, uint32_t); /*Monitor the rendering time*/
static void (*round_cb)(lv_area_t *); /*If set then called to modify invalidated areas for special display controllers*/
static uint32_t px_num; static uint32_t px_num;
/********************** /**********************
@ -67,9 +67,9 @@ void lv_refr_init(void)
inv_buf_p = 0; inv_buf_p = 0;
memset(inv_buf, 0, sizeof(inv_buf)); memset(inv_buf, 0, sizeof(inv_buf));
lv_task_t* task; lv_task_t * task;
task = lv_task_create(lv_refr_task, LV_REFR_PERIOD, LV_TASK_PRIO_MID, NULL); task = lv_task_create(lv_refr_task, LV_REFR_PERIOD, LV_TASK_PRIO_MID, NULL);
lv_mem_assert(task); lv_task_ready(task); /*Be sure the screen will be refreshed immediately on start up*/
} }
/** /**
@ -93,18 +93,11 @@ void lv_inv_area(const lv_area_t * area_p)
lv_area_t com_area; lv_area_t com_area;
bool suc; bool suc;
suc = lv_area_union(&com_area, area_p, &scr_area); suc = lv_area_intersect(&com_area, area_p, &scr_area);
/*The area is truncated to the screen*/ /*The area is truncated to the screen*/
if(suc != false) if(suc != false) {
{ if(round_cb) round_cb(&com_area);
#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*/ /*Save only if this area is not in one of the saved areas*/
uint16_t i; uint16_t i;
@ -112,13 +105,12 @@ void lv_inv_area(const lv_area_t * area_p)
if(lv_area_is_in(&com_area, &inv_buf[i].area) != false) return; if(lv_area_is_in(&com_area, &inv_buf[i].area) != false) return;
} }
/*Save the area*/ /*Save the area*/
if(inv_buf_p < LV_INV_FIFO_SIZE) { if(inv_buf_p < LV_INV_FIFO_SIZE) {
lv_area_copy(&inv_buf[inv_buf_p].area,&com_area); lv_area_copy(&inv_buf[inv_buf_p].area, &com_area);
} else {/*If no place for the area add the screen*/ } else {/*If no place for the area add the screen*/
inv_buf_p = 0; inv_buf_p = 0;
lv_area_copy(&inv_buf[inv_buf_p].area,&scr_area); lv_area_copy(&inv_buf[inv_buf_p].area, &scr_area);
} }
inv_buf_p ++; inv_buf_p ++;
} }
@ -136,6 +128,35 @@ void lv_refr_set_monitor_cb(void (*cb)(uint32_t, uint32_t))
monitor_cb = cb; monitor_cb = cb;
} }
/**
* Called when an area is invalidated to modify the coordinates of the area.
* Special display controllers may require special coordinate rounding
* @param cb pointer to the a function which will modify the area
*/
void lv_refr_set_round_cb(void(*cb)(lv_area_t *))
{
round_cb = cb;
}
/**
* Get the number of areas in the buffer
* @return number of invalid areas
*/
uint16_t lv_refr_get_buf_size(void)
{
return inv_buf_p;
}
/**
* Pop (delete) the last 'num' invalidated areas from the buffer
* @param num number of areas to delete
*/
void lv_refr_pop_from_buf(uint16_t num)
{
if(inv_buf_p < num) inv_buf_p = 0;
else inv_buf_p -= num;
}
/********************** /**********************
* STATIC FUNCTIONS * STATIC FUNCTIONS
**********************/ **********************/
@ -189,8 +210,7 @@ static void lv_refr_join_area(void)
/*Check if the areas are on each other*/ /*Check if the areas are on each other*/
if(lv_area_is_on(&inv_buf[join_in].area, if(lv_area_is_on(&inv_buf[join_in].area,
&inv_buf[join_from].area) == false) &inv_buf[join_from].area) == false) {
{
continue; continue;
} }
@ -262,10 +282,8 @@ static void lv_refr_area_with_vdb(const lv_area_t * area_p)
lv_coord_t h = lv_area_get_height(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; 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); uint32_t max_row = (uint32_t) LV_VDB_SIZE / w;
if(max_row > (h << LV_AA)) max_row = (h << LV_AA); if(max_row > h) max_row = h;
max_row = max_row >> LV_AA ;
/*Always use the full row*/ /*Always use the full row*/
uint32_t row; uint32_t row;
@ -310,14 +328,7 @@ static void lv_refr_area_part_vdb(const lv_area_t * area_p)
/*Get the new mask from the original area and the act. VDB /*Get the new mask from the original area and the act. VDB
It will be a part of 'area_p'*/ It will be a part of 'area_p'*/
lv_area_t start_mask; lv_area_t start_mask;
lv_area_union(&start_mask, area_p, &vdb_p->area); lv_area_intersect(&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*/ /*Get the most top object which is not covered by others*/
top_p = lv_refr_get_top_obj(&start_mask, lv_scr_act()); top_p = lv_refr_get_top_obj(&start_mask, lv_scr_act());
@ -347,8 +358,7 @@ static lv_obj_t * lv_refr_get_top_obj(const lv_area_t * area_p, lv_obj_t * obj)
lv_obj_t * found_p = NULL; lv_obj_t * found_p = NULL;
/*If this object is fully cover the draw area check the children too */ /*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) if(lv_area_is_in(area_p, &obj->coords) && obj->hidden == 0) {
{
LL_READ(obj->child_ll, i) { LL_READ(obj->child_ll, i) {
found_p = lv_refr_get_top_obj(area_p, i); found_p = lv_refr_get_top_obj(area_p, i);
@ -441,7 +451,7 @@ static void lv_refr_obj(lv_obj_t * obj, const lv_area_t * mask_ori_p)
obj_area.y1 -= ext_size; obj_area.y1 -= ext_size;
obj_area.x2 += ext_size; obj_area.x2 += ext_size;
obj_area.y2 += ext_size; obj_area.y2 += ext_size;
union_ok = lv_area_union(&obj_ext_mask, mask_ori_p, &obj_area); union_ok = lv_area_intersect(&obj_ext_mask, mask_ori_p, &obj_area);
/*Draw the parent and its children only if they ore on 'mask_parent'*/ /*Draw the parent and its children only if they ore on 'mask_parent'*/
if(union_ok != false) { if(union_ok != false) {
@ -455,13 +465,12 @@ static void lv_refr_obj(lv_obj_t * obj, const lv_area_t * mask_ori_p)
/*Create a new 'obj_mask' without 'ext_size' because the children can't be visible there*/ /*Create a new 'obj_mask' without 'ext_size' because the children can't be visible there*/
lv_obj_get_coords(obj, &obj_area); lv_obj_get_coords(obj, &obj_area);
union_ok = lv_area_union(&obj_mask, mask_ori_p, &obj_area); union_ok = lv_area_intersect(&obj_mask, mask_ori_p, &obj_area);
if(union_ok != false) { if(union_ok != false) {
lv_area_t mask_child; /*Mask from obj and its child*/ lv_area_t mask_child; /*Mask from obj and its child*/
lv_obj_t * child_p; lv_obj_t * child_p;
lv_area_t child_area; lv_area_t child_area;
LL_READ_BACK(obj->child_ll, child_p) LL_READ_BACK(obj->child_ll, child_p) {
{
lv_obj_get_coords(child_p, &child_area); lv_obj_get_coords(child_p, &child_area);
ext_size = child_p->ext_size; ext_size = child_p->ext_size;
child_area.x1 -= ext_size; child_area.x1 -= ext_size;
@ -470,7 +479,7 @@ static void lv_refr_obj(lv_obj_t * obj, const lv_area_t * mask_ori_p)
child_area.y2 += ext_size; child_area.y2 += ext_size;
/* Get the union (common parts) of original mask (from obj) /* Get the union (common parts) of original mask (from obj)
* and its child */ * and its child */
union_ok = lv_area_union(&mask_child, &obj_mask, &child_area); union_ok = lv_area_intersect(&mask_child, &obj_mask, &child_area);
/*If the parent and the child has common area then refresh the child */ /*If the parent and the child has common area then refresh the child */
if(union_ok) { if(union_ok) {

View File

@ -58,6 +58,24 @@ void lv_inv_area(const lv_area_t * area_p);
*/ */
void lv_refr_set_monitor_cb(void (*cb)(uint32_t, uint32_t)); void lv_refr_set_monitor_cb(void (*cb)(uint32_t, uint32_t));
/**
* Called when an area is invalidated to modify the coordinates of the area.
* Special display controllers may require special coordinate rounding
* @param cb pointer to the a function which will modify the area
*/
void lv_refr_set_round_cb(void(*cb)(lv_area_t*));
/**
* Get the number of areas in the buffer
* @return number of invalid areas
*/
uint16_t lv_refr_get_buf_size(void);
/**
* Pop (delete) the last 'num' invalidated areas from the buffer
* @param num number of areas to delete
*/
void lv_refr_pop_from_buf(uint16_t num);
/********************** /**********************
* STATIC FUNCTIONS * STATIC FUNCTIONS
**********************/ **********************/

View File

@ -29,9 +29,9 @@
typedef struct { 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_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_end;
lv_style_t *style_anim; lv_style_t * style_anim;
void (*end_cb)(void *); void (*end_cb)(void *);
}lv_style_anim_dsc_t; } lv_style_anim_dsc_t;
#endif #endif
/********************** /**********************
@ -39,7 +39,7 @@ typedef struct {
**********************/ **********************/
#if USE_LV_ANIMATION #if USE_LV_ANIMATION
static void style_animator(lv_style_anim_dsc_t * dsc, int32_t val); static void style_animator(lv_style_anim_dsc_t * dsc, int32_t val);
static void style_animation_common_end_cb(void *ptr); static void style_animation_common_end_cb(void * ptr);
#endif #endif
/********************** /**********************
@ -70,7 +70,7 @@ lv_style_t lv_style_btn_ina;
/** /**
* Init the basic styles * Init the basic styles
*/ */
void lv_style_init (void) void lv_style_init(void)
{ {
/* Not White/Black/Gray colors are created by HSV model with /* Not White/Black/Gray colors are created by HSV model with
* HUE = 210*/ * HUE = 210*/
@ -232,7 +232,7 @@ void lv_style_anim_create(lv_style_anim_t * anim)
lv_anim_t a; lv_anim_t a;
a.var = (void*)dsc; a.var = (void *)dsc;
a.start = 0; a.start = 0;
a.end = LV_STYLE_ANIM_RES; a.end = LV_STYLE_ANIM_RES;
a.fp = (lv_anim_fp_t)style_animator; a.fp = (lv_anim_fp_t)style_animator;
@ -272,8 +272,11 @@ static void style_animator(lv_style_anim_dsc_t * dsc, int32_t val)
STYLE_ATTR_ANIM(body.padding.inner, val); STYLE_ATTR_ANIM(body.padding.inner, val);
STYLE_ATTR_ANIM(text.line_space, val); STYLE_ATTR_ANIM(text.line_space, val);
STYLE_ATTR_ANIM(text.letter_space, val); STYLE_ATTR_ANIM(text.letter_space, val);
STYLE_ATTR_ANIM(text.opa, val);
STYLE_ATTR_ANIM(line.width, val); STYLE_ATTR_ANIM(line.width, val);
STYLE_ATTR_ANIM(line.opa, val);
STYLE_ATTR_ANIM(image.intense, val); STYLE_ATTR_ANIM(image.intense, val);
STYLE_ATTR_ANIM(image.opa, val);
lv_opa_t opa = val == LV_STYLE_ANIM_RES ? LV_OPA_COVER : val; lv_opa_t opa = val == LV_STYLE_ANIM_RES ? LV_OPA_COVER : val;
@ -307,9 +310,9 @@ static void style_animator(lv_style_anim_dsc_t * dsc, int32_t val)
* It called the user defined call back and free the allocated memories * It called the user defined call back and free the allocated memories
* @param ptr the 'animated variable' set by lv_style_anim_create() * @param ptr the 'animated variable' set by lv_style_anim_create()
*/ */
static void style_animation_common_end_cb(void *ptr) static void style_animation_common_end_cb(void * ptr)
{ {
lv_style_anim_dsc_t *dsc = ptr; /*To avoid casting*/ lv_style_anim_dsc_t * dsc = ptr; /*To avoid casting*/
if(dsc->end_cb) dsc->end_cb(dsc); if(dsc->end_cb) dsc->end_cb(dsc);

View File

@ -23,7 +23,6 @@ extern "C" {
* DEFINES * DEFINES
*********************/ *********************/
#define LV_RADIUS_CIRCLE (LV_COORD_MAX) /*A very big radius to always draw as circle*/ #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 * TYPEDEFS
@ -38,14 +37,14 @@ typedef enum
LV_BORDER_LEFT = 0x04, LV_BORDER_LEFT = 0x04,
LV_BORDER_RIGHT = 0x08, LV_BORDER_RIGHT = 0x08,
LV_BORDER_FULL = 0x0F, LV_BORDER_FULL = 0x0F,
}lv_border_part_t; } lv_border_part_t;
/*Shadow types*/ /*Shadow types*/
typedef enum typedef enum
{ {
LV_SHADOW_BOTTOM = 0, LV_SHADOW_BOTTOM = 0,
LV_SHADOW_FULL, LV_SHADOW_FULL,
}lv_shadow_type_t; } lv_shadow_type_t;
typedef struct typedef struct
{ {
@ -62,22 +61,22 @@ typedef struct
lv_coord_t width; lv_coord_t width;
lv_border_part_t part; lv_border_part_t part;
lv_opa_t opa; lv_opa_t opa;
}border; } border;
struct { struct {
lv_color_t color; lv_color_t color;
lv_coord_t width; lv_coord_t width;
uint8_t type; uint8_t type;
}shadow; } shadow;
struct { struct {
lv_coord_t ver; lv_coord_t ver;
lv_coord_t hor; lv_coord_t hor;
lv_coord_t inner; lv_coord_t inner;
}padding; } padding;
uint8_t empty :1; /*Transparent background (border still drawn)*/ uint8_t empty :1; /*Transparent background (border still drawn)*/
}body; } body;
struct { struct {
@ -86,20 +85,20 @@ typedef struct
lv_coord_t letter_space; lv_coord_t letter_space;
lv_coord_t line_space; lv_coord_t line_space;
lv_opa_t opa; lv_opa_t opa;
}text; } text;
struct { struct {
lv_color_t color; lv_color_t color;
lv_opa_t intense; lv_opa_t intense;
lv_opa_t opa; lv_opa_t opa;
}image; } image;
struct { struct {
lv_color_t color; lv_color_t color;
lv_coord_t width; lv_coord_t width;
lv_opa_t opa; lv_opa_t opa;
}line; } line;
}lv_style_t; } lv_style_t;
#if USE_LV_ANIMATION #if USE_LV_ANIMATION
typedef struct { typedef struct {
@ -113,7 +112,7 @@ typedef struct {
uint16_t repeat_pause; /*Wait before repeat*/ uint16_t repeat_pause; /*Wait before repeat*/
uint8_t playback :1; /*When the animation is ready play it back*/ uint8_t playback :1; /*When the animation is ready play it back*/
uint8_t repeat :1; /*Repeat the animation infinitely*/ uint8_t repeat :1; /*Repeat the animation infinitely*/
}lv_style_anim_t; } lv_style_anim_t;
/* Example initialization /* Example initialization
lv_style_anim_t a; lv_style_anim_t a;

View File

@ -36,27 +36,27 @@ typedef enum {
#if LV_VDB_DOUBLE == 0 #if LV_VDB_DOUBLE == 0
/*Simple VDB*/ /*Simple VDB*/
static volatile lv_vdb_state_t vdb_state = LV_VDB_STATE_ACTIVE; static volatile lv_vdb_state_t vdb_state = LV_VDB_STATE_ACTIVE;
# if LV_VDB_ADR == 0 # if LV_VDB_ADR == 0
/*If the buffer address is not specified simply allocate it*/ /*If the buffer address is not specified simply allocate it*/
static lv_color_t vdb_buf[LV_VDB_SIZE]; static lv_color_t vdb_buf[LV_VDB_SIZE];
static lv_vdb_t vdb = {.buf = vdb_buf}; static lv_vdb_t vdb = {.buf = vdb_buf};
# else # else
/*If the buffer address is specified use that address*/ /*If the buffer address is specified use that address*/
static lv_vdb_t vdb = {.buf = (lv_color_t *)LV_VDB_ADR}; static lv_vdb_t vdb = {.buf = (lv_color_t *)LV_VDB_ADR};
# endif # endif
#else #else
/*Double VDB*/ /*Double VDB*/
static volatile lv_vdb_state_t vdb_state[2] = {LV_VDB_STATE_FREE, LV_VDB_STATE_FREE}; static volatile lv_vdb_state_t vdb_state[2] = {LV_VDB_STATE_FREE, LV_VDB_STATE_FREE};
# if LV_VDB_ADR == 0 # if LV_VDB_ADR == 0
/*If the buffer address is not specified simply allocate it*/ /*If the buffer address is not specified simply allocate it*/
static lv_color_t vdb_buf1[LV_VDB_SIZE]; static lv_color_t vdb_buf1[LV_VDB_SIZE];
static lv_color_t vdb_buf2[LV_VDB_SIZE]; static lv_color_t vdb_buf2[LV_VDB_SIZE];
static lv_vdb_t vdb[2] = {{.buf = vdb_buf1}, {.buf = vdb_buf2}}; static lv_vdb_t vdb[2] = {{.buf = vdb_buf1}, {.buf = vdb_buf2}};
# else # else
/*If the buffer address is specified use that address*/ /*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}}; static lv_vdb_t vdb[2] = {{.buf = (lv_color_t *)LV_VDB_ADR}, {.buf = (lv_color_t *)LV_VDB2_ADR}};
# endif # endif
#endif #endif
@ -119,59 +119,9 @@ void lv_vdb_flush(void)
if(vdb_state[1] == LV_VDB_STATE_ACTIVE) vdb_state[1] = LV_VDB_STATE_FLUSH; if(vdb_state[1] == LV_VDB_STATE_ACTIVE) vdb_state[1] = LV_VDB_STATE_FLUSH;
#endif #endif
#if LV_ANTIALIAS == 0 /*Flush the rendered content to the display*/
lv_disp_flush(vdb_act->area.x1, vdb_act->area.y1, vdb_act->area.x2, vdb_act->area.y2, vdb_act->buf); 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
} }
/** /**

View File

@ -32,7 +32,7 @@ typedef struct
{ {
lv_area_t area; lv_area_t area;
lv_color_t *buf; lv_color_t *buf;
}lv_vdb_t; } lv_vdb_t;
/********************** /**********************
* GLOBAL PROTOTYPES * GLOBAL PROTOTYPES

File diff suppressed because it is too large Load Diff

View File

@ -19,6 +19,14 @@ extern "C" {
/********************* /*********************
* DEFINES * DEFINES
*********************/ *********************/
/*If image pixels contains alpha we need to know how much byte is a pixel*/
#if LV_COLOR_DEPTH == 1 || LV_COLOR_DEPTH == 8
# define LV_IMG_PX_SIZE_ALPHA_BYTE 2
#elif LV_COLOR_DEPTH == 16
# define LV_IMG_PX_SIZE_ALPHA_BYTE 3
#elif LV_COLOR_DEPTH == 24
# define LV_IMG_PX_SIZE_ALPHA_BYTE 4
#endif
/********************** /**********************
* TYPEDEFS * TYPEDEFS
@ -28,12 +36,39 @@ extern "C" {
* the result image converter utility*/ * the result image converter utility*/
typedef struct typedef struct
{ {
union {
struct {
uint32_t chroma_keyed:1; /*1: The image contains transparent pixels with LV_COLOR_TRANSP color*/
uint32_t alpha_byte :1; /*Every pixel is extended with a 8 bit alpha channel*/
uint32_t format :6; /*See: lv_img_px_format*/
uint32_t w:12; /*Width of the image map*/ uint32_t w:12; /*Width of the image map*/
uint32_t h:12; /*Height 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*/ } header;
uint32_t cd:3; /*Color depth (0: reserved, 1: 8 bit, 2: 16 bit or 3: 24 bit, 4-7: reserved)*/ uint8_t src_type;
uint32_t res :4; /*Reserved*/ };
}lv_img_raw_header_t;
union {
const uint8_t * pixel_map; /*For internal images (c arrays) pointer to the pixels array*/
uint8_t first_pixel; /*For external images (binary) the first byte of the pixels (just for convenient)*/
};
} lv_img_t;
typedef enum {
LV_IMG_FORMAT_UNKOWN = 0,
LV_IMG_FORMAT_INTERNAL_RAW, /*'lv_img_t' variable compiled with the code*/
LV_IMG_FORMAT_FILE_RAW_RGB332, /*8 bit*/
LV_IMG_FORMAT_FILE_RAW_RGB565, /*16 bit*/
LV_IMG_FORMAT_FILE_RAW_RGB888, /*24 bit (stored on 32 bit)*/
} lv_img_format_t;
typedef enum {
LV_IMG_SRC_VARIABLE,
LV_IMG_SRC_FILE,
LV_IMG_SRC_SYMBOL,
LV_IMG_SRC_UNKNOWN,
} lv_img_src_t;
/********************** /**********************
* GLOBAL PROTOTYPES * GLOBAL PROTOTYPES
@ -79,8 +114,8 @@ void lv_draw_label(const lv_area_t * cords_p,const lv_area_t * mask_p, const lv_
* @param mask_p the image will be drawn only in this area * @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 * @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, void lv_draw_img(const lv_area_t * coords, const lv_area_t * mask,
const lv_style_t * style_p, const char * fn); const lv_style_t * style, const void * src);
#endif #endif
/** /**

View File

@ -6,10 +6,12 @@
/********************* /*********************
* INCLUDES * INCLUDES
*********************/ *********************/
#include "../lv_hal/lv_hal_disp.h"
#include "lv_draw_rbasic.h" #include "lv_draw_rbasic.h"
#include "../../lv_conf.h" #if USE_LV_REAL_DRAW != 0
#include "../lv_hal/lv_hal_disp.h"
#include "../lv_misc/lv_font.h" #include "../lv_misc/lv_font.h"
#include "lv_draw.h"
/********************* /*********************
* DEFINES * DEFINES
@ -26,6 +28,7 @@
/********************** /**********************
* STATIC VARIABLES * STATIC VARIABLES
**********************/ **********************/
static lv_color_t letter_bg_color;
/********************** /**********************
* MACROS * MACROS
@ -73,14 +76,14 @@ void lv_rfill(const lv_area_t * cords_p, const lv_area_t * mask_p,
bool union_ok = true; bool union_ok = true;
if(mask_p != NULL) { if(mask_p != NULL) {
union_ok = lv_area_union(&masked_area, cords_p, mask_p); union_ok = lv_area_intersect(&masked_area, cords_p, mask_p);
} else { } else {
lv_area_t scr_area; lv_area_t scr_area;
lv_area_set(&scr_area, 0, 0, LV_HOR_RES - 1, LV_HOR_RES - 1); lv_area_set(&scr_area, 0, 0, LV_HOR_RES - 1, LV_VER_RES - 1);
union_ok = lv_area_union(&masked_area, cords_p, &scr_area); union_ok = lv_area_intersect(&masked_area, cords_p, &scr_area);
} }
if(union_ok != false){ if(union_ok != false) {
lv_disp_fill(masked_area.x1, masked_area.y1, masked_area.x2, masked_area.y2, color); lv_disp_fill(masked_area.x1, masked_area.y1, masked_area.x2, masked_area.y2, color);
} }
} }
@ -100,128 +103,161 @@ void lv_rletter(const lv_point_t * pos_p, const lv_area_t * mask_p,
{ {
(void)opa; /*Opa is used only for compatibility with lv_vletter*/ (void)opa; /*Opa is used only for compatibility with lv_vletter*/
uint8_t w = lv_font_get_width(font_p, letter); static uint8_t bpp1_opa_table[2] = {0, 255}; /*Opacity mapping with bpp = 1 (Just for compatibility)*/
static uint8_t bpp2_opa_table[4] = {0, 85, 170, 255}; /*Opacity mapping with bpp = 2*/
static uint8_t bpp4_opa_table[16] = {0, 17, 34, 51, /*Opacity mapping with bpp = 4*/
68, 85, 102, 119,
136, 153, 170, 187,
204, 221, 238, 255
};
if(letter == 'C') { if(font_p == NULL) return;
letter = 'C';
uint8_t letter_w = lv_font_get_width(font_p, letter);
uint8_t letter_h = lv_font_get_height(font_p);
uint8_t bpp = lv_font_get_bpp(font_p, letter); /*Bit per pixel (1,2, 4 or 8)*/
uint8_t * bpp_opa_table;
uint8_t mask_init;
uint8_t mask;
switch(bpp) {
case 1:
bpp_opa_table = bpp1_opa_table;
mask_init = 0x80;
break;
case 2:
bpp_opa_table = bpp2_opa_table;
mask_init = 0xC0;
break;
case 4:
bpp_opa_table = bpp4_opa_table;
mask_init = 0xF0;
break;
case 8:
bpp_opa_table = NULL;
mask_init = 0xFF;
break; /*No opa table, pixel value will be used directly*/
default:
return; /*Invalid bpp. Can't render the letter*/
} }
const uint8_t * bitmap_p = lv_font_get_bitmap(font_p, letter); const uint8_t * map_p = lv_font_get_bitmap(font_p, letter);
uint8_t col, col_sub, row; if(map_p == NULL) return;
#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) { /*If the letter is completely out of mask don't draw it */
bitmap_p++; if(pos_p->x + letter_w < mask_p->x1 || pos_p->x > mask_p->x2 ||
col_sub = 8; pos_p->y + letter_h < mask_p->y1 || pos_p->y > mask_p->y2) return;
}
} lv_coord_t col, row;
/*Go to the next row*/ uint8_t col_bit;
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; uint8_t col_byte_cnt;
for(row = 0; row < (font_p->height_row >> 1); row ++) { uint8_t width_byte_scr = letter_w >> 3; /*Width in bytes (on the screen finally) (e.g. w = 11 -> 2 bytes wide)*/
if(letter_w & 0x7) width_byte_scr++;
uint8_t width_byte_bpp = (letter_w * bpp) >> 3; /*Letter width in byte. Real width in the font*/
if((letter_w * bpp) & 0x7) width_byte_bpp++;
/* Calculate the col/row start/end on the map*/
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 <= mask_p->x2 ? letter_w : 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 <= mask_p->y2 ? letter_h : mask_p->y2 - pos_p->y + 1;
/*Move on the map too*/
map_p += (row_start * width_byte_bpp) + ((col_start * bpp) >> 3);
uint8_t letter_px;
for(row = row_start; row < row_end; row ++) {
col_byte_cnt = 0; col_byte_cnt = 0;
col_sub = 7; col_bit = (col_start * bpp) % 8;
for(col = 0; col < (w >> 1); col ++) { mask = mask_init >> col_bit;
for(col = col_start; col < col_end; col ++) {
letter_px = (*map_p & mask) >> (8 - col_bit - bpp);
if(letter_px != 0) {
lv_rpx(pos_p->x + col, pos_p->y + row, mask_p, lv_color_mix(color, letter_bg_color, bpp == 8 ? letter_px : bpp_opa_table[letter_px]), LV_OPA_COVER);
}
px_cnt = 0; if(col_bit < 8 - bpp) {
if((*map1_p & (1 << col_sub)) != 0) px_cnt++; col_bit += bpp;
if((*map2_p & (1 << col_sub)) != 0) px_cnt++; mask = mask >> bpp;
if(col_sub != 0) col_sub --; } else {
else { col_bit = 0;
col_sub = 7;
col_byte_cnt ++; col_byte_cnt ++;
map1_p ++; mask = mask_init;
map2_p ++; map_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; map_p += (width_byte_bpp) - col_byte_cnt;
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 * When the letter is ant-aliased it needs to know the background color
* @param bg_color the background color of the currently drawn letter
*/
void lv_rletter_set_background(lv_color_t color)
{
letter_bg_color = color;
}
/**
* Draw a color map to the display (image)
* @param cords_p coordinates the color map * @param cords_p coordinates the color map
* @param mask_p the map will drawn only on this area * @param mask_p the map will drawn only on this area
* @param map_p pointer to a lv_color_t array * @param map_p pointer to a lv_color_t array
* @param opa opacity of the map (ignored, only for compatibility with lv_vmap) * @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 chroma_keyed true: enable transparency of LV_IMG_LV_COLOR_TRANSP color pixels
* @param upscale true: upscale to double size (not supported) * @param alpha_byte true: extra alpha byte is inserted for every pixel (not supported, only l'v_vmap' can draw it)
* @param recolor mix the pixels with this color (not supported) * @param recolor mix the pixels with this color
* @param recolor_opa the intense of recoloring (not supported) * @param recolor_opa the intense of recoloring
*/ */
void lv_rmap(const lv_area_t * cords_p, const lv_area_t * mask_p, 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, const uint8_t * map_p, lv_opa_t opa, bool chroma_key, bool alpha_byte,
lv_color_t recolor, lv_opa_t recolor_opa) lv_color_t recolor, lv_opa_t recolor_opa)
{ {
(void)opa; /*opa is used only for compatibility with lv_vmap*/ if(alpha_byte) return; /*Pixel level opacity i not supported in real map drawing*/
(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*/
(void)opa; /*opa is used only for compatibility with lv_vmap*/
lv_area_t masked_a; lv_area_t masked_a;
bool union_ok; bool union_ok;
union_ok = lv_area_union(&masked_a, cords_p, mask_p); union_ok = lv_area_intersect(&masked_a, cords_p, mask_p);
/*If there are common part of the mask and map then draw the map*/ /*If there are common part of the mask and map then draw the map*/
if(union_ok == false) return; if(union_ok == false) return;
/*Go to the first pixel*/ /*Go to the first pixel*/
lv_coord_t map_width = lv_area_get_width(cords_p); 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.y1 - cords_p->y1) * map_width * sizeof(lv_color_t);
map_p += masked_a.x1 - cords_p->x1; map_p += (masked_a.x1 - cords_p->x1) * sizeof(lv_color_t);
if(transp == false) {
lv_coord_t row; lv_coord_t row;
if(recolor_opa == LV_OPA_TRANSP && chroma_key == false) {
lv_coord_t mask_w = lv_area_get_width(&masked_a) - 1; lv_coord_t mask_w = lv_area_get_width(&masked_a) - 1;
for(row = 0; row < lv_area_get_height(&masked_a); row++) { for(row = masked_a.y1; row <= masked_a.y2; row++) {
lv_disp_map(masked_a.x1, masked_a.y1 + row, masked_a.x1 + mask_w, masked_a.y1 + row, map_p); lv_disp_map(masked_a.x1, row, masked_a.x1 + mask_w, row, (lv_color_t *)map_p);
map_p += map_width * sizeof(lv_color_t); /*Next row on the map*/
map_p += map_width;
} }
}else { } else {
lv_color_t transp_color = LV_COLOR_TRANSP; lv_color_t chroma_key_color = LV_COLOR_TRANSP;
lv_coord_t row;
for(row = 0; row < lv_area_get_height(&masked_a); row++) {
lv_coord_t col; lv_coord_t col;
for(col = 0; col < lv_area_get_width(&masked_a); col ++) { for(row = masked_a.y1; row <= masked_a.y2; row++) {
if(map_p[col].full != transp_color.full) { for(col = masked_a.x1; col <= masked_a.x2; col++) {
lv_rpx(masked_a.x1 + col, masked_a.y1 + row, mask_p, map_p[col], opa); lv_color_t * px_color = (lv_color_t *) &map_p[(uint32_t)(col - masked_a.x1) * sizeof(lv_color_t)];
if(chroma_key && chroma_key_color.full == px_color->full) continue;
if(recolor_opa != LV_OPA_TRANSP) {
lv_color_t recolored_px = lv_color_mix(recolor, *px_color, recolor_opa);
lv_rpx(col, row, mask_p, recolored_px, LV_OPA_COVER);
} else {
lv_rpx(col, row, mask_p, *px_color, LV_OPA_COVER);
} }
} }
map_p += map_width; map_p += map_width * sizeof(lv_color_t); /*Next row on the map*/
} }
} }
} }
@ -229,3 +265,5 @@ void lv_rmap(const lv_area_t * cords_p, const lv_area_t * mask_p,
/********************** /**********************
* STATIC FUNCTIONS * STATIC FUNCTIONS
**********************/ **********************/
#endif /*USE_LV_REAL_DRAW*/

View File

@ -13,6 +13,9 @@ extern "C" {
/********************* /*********************
* INCLUDES * INCLUDES
*********************/ *********************/
#include "../../lv_conf.h"
#if USE_LV_REAL_DRAW != 0
#include "../lv_misc/lv_color.h" #include "../lv_misc/lv_color.h"
#include "../lv_misc/lv_area.h" #include "../lv_misc/lv_area.h"
#include "../lv_misc/lv_font.h" #include "../lv_misc/lv_font.h"
@ -55,23 +58,31 @@ void lv_rletter(const lv_point_t * pos_p, const lv_area_t * mask_p,
lv_color_t color, lv_opa_t opa); lv_color_t color, lv_opa_t opa);
/** /**
* Draw a color map to the display * When the letter is ant-aliased it needs to know the background color
* @param bg_color the background color of the currently drawn letter
*/
void lv_rletter_set_background(lv_color_t color);
/**
* Draw a color map to the display (image)
* @param cords_p coordinates the color map * @param cords_p coordinates the color map
* @param mask_p the map will drawn only on this area * @param mask_p the map will drawn only on this area
* @param map_p pointer to a lv_color_t array * @param map_p pointer to a lv_color_t array
* @param opa opacity of the map (ignored, only for compatibility with lv_vmap) * @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 chroma_keyed true: enable transparency of LV_IMG_LV_COLOR_TRANSP color pixels
* @param upscale true: upscale to double size (not supported) * @param alpha_byte true: extra alpha byte is inserted for every pixel (not supported, only l'v_vmap' can draw it)
* @param recolor mix the pixels with this color (not supported) * @param recolor mix the pixels with this color
* @param recolor_opa the intense of recoloring (not supported) * @param recolor_opa the intense of recoloring
*/ */
void lv_rmap(const lv_area_t * cords_p, const lv_area_t * mask_p, 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, const uint8_t * map_p, lv_opa_t opa, bool chroma_key, bool alpha_byte,
lv_color_t recolor, lv_opa_t recolor_opa); lv_color_t recolor, lv_opa_t recolor_opa);
/********************** /**********************
* MACROS * MACROS
**********************/ **********************/
#endif /*USE_LV_REAL_DRAW*/
#ifdef __cplusplus #ifdef __cplusplus
} /* extern "C" */ } /* extern "C" */

View File

@ -18,6 +18,7 @@
#include <stddef.h> #include <stddef.h>
#include "../lv_core/lv_vdb.h" #include "../lv_core/lv_vdb.h"
#include "lv_draw.h"
/********************* /*********************
* INCLUDES * INCLUDES
@ -71,14 +72,13 @@ void lv_vpx(lv_coord_t x, lv_coord_t y, const lv_area_t * mask_p, lv_color_t col
uint32_t vdb_width = lv_area_get_width(&vdb_p->area); uint32_t vdb_width = lv_area_get_width(&vdb_p->area);
/*Make the coordinates relative to VDB*/ /*Make the coordinates relative to VDB*/
x-=vdb_p->area.x1; x -= vdb_p->area.x1;
y-=vdb_p->area.y1; y -= vdb_p->area.y1;
lv_color_t * vdb_px_p = vdb_p->buf + y * vdb_width + x; lv_color_t * vdb_px_p = vdb_p->buf + y * vdb_width + x;
if(opa == LV_OPA_COVER) { if(opa == LV_OPA_COVER) {
*vdb_px_p = color; *vdb_px_p = color;
} } else {
else { *vdb_px_p = lv_color_mix(color, *vdb_px_p, opa);
*vdb_px_p = lv_color_mix(color,*vdb_px_p, opa);
} }
} }
@ -101,7 +101,7 @@ void lv_vfill(const lv_area_t * cords_p, const lv_area_t * mask_p,
/*Get the union of cord and mask*/ /*Get the union of cord and mask*/
/* The mask is already truncated to the vdb size /* The mask is already truncated to the vdb size
* in 'lv_refr_area_with_vdb' function */ * in 'lv_refr_area_with_vdb' function */
union_ok = lv_area_union(&res_a, cords_p, mask_p); union_ok = lv_area_intersect(&res_a, cords_p, mask_p);
/*If there are common part of the three area then draw to the vdb*/ /*If there are common part of the three area then draw to the vdb*/
if(union_ok == false) return; if(union_ok == false) return;
@ -119,7 +119,7 @@ void lv_vfill(const lv_area_t * cords_p, const lv_area_t * mask_p,
#if USE_LV_GPU #if USE_LV_GPU
static lv_color_t color_array_tmp[LV_HOR_RES << LV_ANTIALIAS]; /*Used by 'sw_color_fill'*/ static lv_color_t color_array_tmp[LV_HOR_RES]; /*Used by 'lv_disp_mem_blend'*/
static lv_coord_t last_width = -1; static lv_coord_t last_width = -1;
lv_coord_t w = lv_area_get_width(&vdb_rel_a); lv_coord_t w = lv_area_get_width(&vdb_rel_a);
@ -132,15 +132,15 @@ void lv_vfill(const lv_area_t * cords_p, const lv_area_t * mask_p,
/*Use hw fill if present*/ /*Use hw fill if present*/
if(lv_disp_is_mem_fill_supported()) { if(lv_disp_is_mem_fill_supported()) {
lv_coord_t row; lv_coord_t row;
for(row = vdb_rel_a.y1;row <= vdb_rel_a.y2; 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); lv_disp_mem_fill(&vdb_buf_tmp[vdb_rel_a.x1], w, color);
vdb_buf_tmp += vdb_width; vdb_buf_tmp += vdb_width;
} }
} }
/*Use hw blend if present and the area is not too small*/ /*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 && else if(lv_area_get_height(&vdb_rel_a) > VFILL_HW_ACC_SIZE_LIMIT &&
lv_disp_is_mem_blend_supported()) lv_disp_is_mem_blend_supported()) {
{ /*Fill a one line sized buffer with a color and blend this later*/
if(color_array_tmp[0].full != color.full || last_width != w) { if(color_array_tmp[0].full != color.full || last_width != w) {
uint16_t i; uint16_t i;
for(i = 0; i < w; i++) { for(i = 0; i < w; i++) {
@ -148,8 +148,10 @@ void lv_vfill(const lv_area_t * cords_p, const lv_area_t * mask_p,
} }
last_width = w; last_width = w;
} }
/*Blend the filled line to every line VDB line-by-line*/
lv_coord_t row; lv_coord_t row;
for(row = vdb_rel_a.y1;row <= vdb_rel_a.y2; 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); lv_disp_mem_blend(&vdb_buf_tmp[vdb_rel_a.x1], color_array_tmp, w, opa);
vdb_buf_tmp += vdb_width; vdb_buf_tmp += vdb_width;
} }
@ -174,7 +176,7 @@ void lv_vfill(const lv_area_t * cords_p, const lv_area_t * mask_p,
last_width = w; last_width = w;
} }
lv_coord_t row; lv_coord_t row;
for(row = vdb_rel_a.y1;row <= vdb_rel_a.y2; 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); lv_disp_mem_blend(&vdb_buf_tmp[vdb_rel_a.x1], color_array_tmp, w, opa);
vdb_buf_tmp += vdb_width; vdb_buf_tmp += vdb_width;
} }
@ -204,10 +206,44 @@ void lv_vletter(const lv_point_t * pos_p, const lv_area_t * mask_p,
const lv_font_t * font_p, uint32_t letter, const lv_font_t * font_p, uint32_t letter,
lv_color_t color, lv_opa_t opa) lv_color_t color, lv_opa_t opa)
{ {
static uint8_t bpp1_opa_table[2] = {0, 255}; /*Opacity mapping with bpp = 1 (Just for compatibility)*/
static uint8_t bpp2_opa_table[4] = {0, 85, 170, 255}; /*Opacity mapping with bpp = 2*/
static uint8_t bpp4_opa_table[16] = {0, 17, 34, 51, /*Opacity mapping with bpp = 4*/
68, 85, 102, 119,
136, 153, 170, 187,
204, 221, 238, 255
};
if(font_p == NULL) return; if(font_p == NULL) return;
uint8_t letter_w = lv_font_get_width(font_p, letter); uint8_t letter_w = lv_font_get_width(font_p, letter);
uint8_t letter_h = lv_font_get_height(font_p); uint8_t letter_h = lv_font_get_height(font_p);
uint8_t bpp = lv_font_get_bpp(font_p, letter); /*Bit per pixel (1,2, 4 or 8)*/
uint8_t * bpp_opa_table;
uint8_t mask_init;
uint8_t mask;
switch(bpp) {
case 1:
bpp_opa_table = bpp1_opa_table;
mask_init = 0x80;
break;
case 2:
bpp_opa_table = bpp2_opa_table;
mask_init = 0xC0;
break;
case 4:
bpp_opa_table = bpp4_opa_table;
mask_init = 0xF0;
break;
case 8:
bpp_opa_table = NULL;
mask_init = 0xFF;
break; /*No opa table, pixel value will be used directly*/
default:
return; /*Invalid bpp. Can't render the letter*/
}
const uint8_t * map_p = lv_font_get_bitmap(font_p, letter); const uint8_t * map_p = lv_font_get_bitmap(font_p, letter);
@ -223,15 +259,16 @@ void lv_vletter(const lv_point_t * pos_p, const lv_area_t * mask_p,
lv_coord_t col, row; lv_coord_t col, row;
uint8_t col_bit; uint8_t col_bit;
uint8_t col_byte_cnt; uint8_t col_byte_cnt;
uint8_t width_byte = letter_w >> 3; /*Width in bytes (e.g. w = 11 -> 2 bytes wide)*/ uint8_t width_byte_scr = letter_w >> 3; /*Width in bytes (on the screen finally) (e.g. w = 11 -> 2 bytes wide)*/
if(letter_w & 0x7) width_byte++; if(letter_w & 0x7) width_byte_scr++;
uint8_t width_byte_bpp = (letter_w * bpp) >> 3; /*Letter width in byte. Real width in the font*/
if((letter_w * bpp) & 0x7) width_byte_bpp++;
/* Calculate the col/row start/end on the map /* 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_start = pos_p->x > mask_p->x1 ? 0 : mask_p->x1 - pos_p->x; lv_coord_t col_end = pos_p->x + letter_w <= mask_p->x2 ? letter_w : mask_p->x2 - pos_p->x + 1;
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_start = pos_p->y > mask_p->y1 ? 0 : mask_p->y1 - pos_p->y; lv_coord_t row_end = pos_p->y + letter_h <= mask_p->y2 ? letter_h : mask_p->y2 - pos_p->y + 1;
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*/ /*Set a pointer on VDB to the first pixel of the letter*/
vdb_buf_tmp += ((pos_p->y - vdb_p->area.y1) * vdb_width) vdb_buf_tmp += ((pos_p->y - vdb_p->area.y1) * vdb_width)
@ -241,93 +278,56 @@ void lv_vletter(const lv_point_t * pos_p, const lv_area_t * mask_p,
vdb_buf_tmp += (row_start * vdb_width) + col_start; vdb_buf_tmp += (row_start * vdb_width) + col_start;
/*Move on the map too*/ /*Move on the map too*/
map_p += ((row_start << LV_FONT_ANTIALIAS) * width_byte) + ((col_start << LV_FONT_ANTIALIAS) >> 3); map_p += (row_start * width_byte_bpp) + ((col_start * bpp) >> 3);
#if LV_FONT_ANTIALIAS != 0 uint8_t letter_px;
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 ++) { for(row = row_start; row < row_end; row ++) {
col_byte_cnt = 0; col_byte_cnt = 0;
col_bit = 7 - ((col_start << LV_FONT_ANTIALIAS) % 8); col_bit = (col_start * bpp) % 8;
mask = mask_init >> col_bit;
for(col = col_start; col < col_end; col ++) { for(col = col_start; col < col_end; col ++) {
letter_px = (*map_p & mask) >> (8 - col_bit - bpp);
px_cnt = 0; if(letter_px != 0) {
if((*map1_p & (1 << col_bit)) != 0) px_cnt++; if(opa == LV_OPA_COVER) {
if((*map2_p & (1 << col_bit)) != 0) px_cnt++; *vdb_buf_tmp = lv_color_mix(color, *vdb_buf_tmp, bpp == 8 ? letter_px : bpp_opa_table[letter_px]);
if(col_bit != 0) col_bit --; } else {
else { *vdb_buf_tmp = lv_color_mix(color, *vdb_buf_tmp, bpp == 8 ?
col_bit = 7; (uint16_t)((uint16_t)letter_px * opa) >> 8 :
col_byte_cnt ++; (uint16_t)((uint16_t)bpp_opa_table[letter_px] * opa) >> 8);
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++; vdb_buf_tmp++;
if(col_bit != 0) col_bit --; if(col_bit < 8 - bpp) {
else { col_bit += bpp;
col_bit = 7; mask = mask >> bpp;
} else {
col_bit = 0;
col_byte_cnt ++; col_byte_cnt ++;
mask = mask_init;
map_p ++; map_p ++;
} }
} }
map_p += width_byte - col_byte_cnt; map_p += (width_byte_bpp) - col_byte_cnt;
vdb_buf_tmp += vdb_width - (col_end - col_start); /*Next row in VDB*/ vdb_buf_tmp += vdb_width - (col_end - col_start); /*Next row in VDB*/
} }
#endif
} }
/** /**
* Draw a color map to the display * Draw a color map to the display (image)
* @param cords_p coordinates the color map * @param cords_p coordinates the color map
* @param mask_p the map will drawn only on this area (truncated to VDB area) * @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 map_p pointer to a lv_color_t array
* @param opa opacity of the map (ignored, only for compatibility with lv_vmap) * @param opa opacity of the map
* @param transp true: enable transparency of LV_IMG_LV_COLOR_TRANSP color pixels * @param chroma_keyed true: enable transparency of LV_IMG_LV_COLOR_TRANSP color pixels
* @param upscale true: upscale to double size * @param alpha_byte true: extra alpha byte is inserted for every pixel
* @param recolor mix the pixels with this color * @param recolor mix the pixels with this color
* @param recolor_opa the intense of recoloring * @param recolor_opa the intense of recoloring
*/ */
void lv_vmap(const lv_area_t * cords_p, const lv_area_t * mask_p, 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, const uint8_t * map_p, lv_opa_t opa, bool chroma_key, bool alpha_byte,
lv_color_t recolor, lv_opa_t recolor_opa) lv_color_t recolor, lv_opa_t recolor_opa)
{ {
lv_area_t masked_a; lv_area_t masked_a;
@ -337,24 +337,24 @@ void lv_vmap(const lv_area_t * cords_p, const lv_area_t * mask_p,
/*Get the union of map size and mask*/ /*Get the union of map size and mask*/
/* The mask is already truncated to the vdb size /* The mask is already truncated to the vdb size
* in 'lv_refr_area_with_vdb' function */ * in 'lv_refr_area_with_vdb' function */
union_ok = lv_area_union(&masked_a, cords_p, mask_p); union_ok = lv_area_intersect(&masked_a, cords_p, mask_p);
/*If there are common part of the three area then draw to the vdb*/ /*If there are common part of the three area then draw to the vdb*/
if(union_ok == false) return; if(union_ok == false) return;
uint8_t ds_shift = 0; /*The pixel size in byte is different if an alpha byte is added too*/
if(upscale != false) ds_shift = 1; uint8_t px_size_byte = alpha_byte ? LV_IMG_PX_SIZE_ALPHA_BYTE : sizeof(lv_color_t);
/*If the map starts OUT of the masked area then calc. the first pixel*/ /*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; lv_coord_t map_width = lv_area_get_width(cords_p);
if(cords_p->y1 < masked_a.y1) { if(cords_p->y1 < masked_a.y1) {
map_p += (uint32_t) map_width * ((masked_a.y1 - cords_p->y1) >> ds_shift); map_p += (uint32_t) map_width * ((masked_a.y1 - cords_p->y1)) * px_size_byte;
} }
if(cords_p->x1 < masked_a.x1) { if(cords_p->x1 < masked_a.x1) {
map_p += (masked_a.x1 - cords_p->x1) >> ds_shift; map_p += (masked_a.x1 - cords_p->x1) * px_size_byte;
} }
/*Stores coordinates relative to the act vdb*/ /*Stores coordinates relative to the current VDB*/
masked_a.x1 = masked_a.x1 - vdb_p->area.x1; masked_a.x1 = masked_a.x1 - vdb_p->area.x1;
masked_a.y1 = masked_a.y1 - vdb_p->area.y1; masked_a.y1 = masked_a.y1 - vdb_p->area.y1;
masked_a.x2 = masked_a.x2 - vdb_p->area.x1; masked_a.x2 = masked_a.x2 - vdb_p->area.x1;
@ -363,157 +363,86 @@ void lv_vmap(const lv_area_t * cords_p, const lv_area_t * mask_p,
lv_coord_t vdb_width = lv_area_get_width(&vdb_p->area); lv_coord_t vdb_width = lv_area_get_width(&vdb_p->area);
lv_color_t * vdb_buf_tmp = vdb_p->buf; lv_color_t * vdb_buf_tmp = vdb_p->buf;
vdb_buf_tmp += (uint32_t) vdb_width * masked_a.y1; /*Move to the first row*/ vdb_buf_tmp += (uint32_t) vdb_width * masked_a.y1; /*Move to the first row*/
vdb_buf_tmp += (uint32_t) masked_a.x1; /*Move to the first col*/
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 row;
lv_coord_t map_useful_w = lv_area_get_width(&masked_a); lv_coord_t map_useful_w = lv_area_get_width(&masked_a);
/*The simplest case just copy the pixels into the VDB*/
if(chroma_key == false && alpha_byte == false && opa == LV_OPA_COVER && recolor_opa == LV_OPA_TRANSP) {
for(row = masked_a.y1; row <= masked_a.y2; row++) { for(row = masked_a.y1; row <= masked_a.y2; row++) {
#if USE_LV_GPU #if USE_LV_GPU
if(lv_disp_is_mem_blend_supported() == false) { 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); sw_mem_blend(vdb_buf_tmp, (lv_color_t *)map_p, map_useful_w, opa);
} else { } else {
lv_disp_mem_blend(&vdb_buf_tmp[masked_a.x1], &map_p[masked_a.x1], map_useful_w, opa); lv_disp_mem_blend(vdb_buf_tmp, (lv_color_t *)map_p, map_useful_w, opa);
} }
#else #else
sw_mem_blend(&vdb_buf_tmp[masked_a.x1], &map_p[masked_a.x1], map_useful_w, opa); sw_mem_blend(vdb_buf_tmp, (lv_color_t *)map_p, map_useful_w, opa);
#endif #endif
map_p += map_width; /*Next row on the map*/ map_p += map_width * px_size_byte; /*Next row on the map*/
vdb_buf_tmp += vdb_width; /*Next row on the VDB*/ vdb_buf_tmp += vdb_width; /*Next row on the VDB*/
} }
/*To recolor draw simply a rectangle above the image*/ }
/*In the other cases every pixel need to be checked one-by-one*/
else {
lv_color_t chroma_key_color = LV_COLOR_TRANSP;
lv_coord_t col;
lv_color_t last_img_px = LV_COLOR_BLACK;
lv_color_t recolored_px = lv_color_mix(recolor, last_img_px, recolor_opa);
for(row = masked_a.y1; row <= masked_a.y2; row++) {
for(col = 0; col < map_useful_w; col++) {
lv_opa_t opa_result = opa;
uint8_t * px_color_p = (uint8_t *) &map_p[(uint32_t)col * px_size_byte];
lv_color_t px_color;
/*Calculate with the pixel level alpha*/
if(alpha_byte) {
#if LV_COLOR_DEPTH == 8
px_color.full = px_color_p[0];
#elif LV_COLOR_DEPTH == 16
/*Because of Alpha byte 16 bit color can start on odd address which can cause crash*/
px_color.full = px_color_p[0] + (px_color_p[1] << 8);
#elif LV_COLOR_DEPTH == 24
px_color = *((lv_color_t *)px_color_p);
#endif
lv_opa_t px_opa = *(px_color_p + LV_IMG_PX_SIZE_ALPHA_BYTE - 1);
if(px_opa == LV_OPA_TRANSP) continue;
else if(px_opa != LV_OPA_COVER) opa_result = (uint32_t)((uint32_t)px_opa * opa_result) >> 8;
} else {
px_color = *((lv_color_t *)px_color_p);
}
/*Handle chroma key*/
if(chroma_key && px_color.full == chroma_key_color.full) continue;
/*Re-color the pixel if required*/
if(recolor_opa != LV_OPA_TRANSP) { 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(last_img_px.full != px_color.full) { /*Minor acceleration: calculate only for new colors (save the last)*/
if(opa == LV_OPA_COVER) { /*no opa */ last_img_px = px_color;
for(row = masked_a.y1; row <= masked_a.y2; row++) { recolored_px = lv_color_mix(recolor, last_img_px, recolor_opa);
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*/ if(opa_result == LV_OPA_COVER) vdb_buf_tmp[col].full = recolored_px.full;
else vdb_buf_tmp[col] = lv_color_mix(recolored_px, vdb_buf_tmp[col], opa_result);
} else {
if(opa_result == LV_OPA_COVER) vdb_buf_tmp[col] = px_color;
else vdb_buf_tmp[col] = lv_color_mix(px_color, vdb_buf_tmp[col], opa_result);
}
}
/*Next row on the map*/
map_p += map_width * px_size_byte;
vdb_buf_tmp += vdb_width; /*Next row on the VDB*/ 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*/
}
}
}
} }
/********************** /**********************

View File

@ -58,18 +58,18 @@ void lv_vletter(const lv_point_t * pos_p, const lv_area_t * mask_p,
lv_color_t color, lv_opa_t opa); lv_color_t color, lv_opa_t opa);
/** /**
* Draw a color map to the display * Draw a color map to the display (image)
* @param cords_p coordinates the color map * @param cords_p coordinates the color map
* @param mask_p the map will drawn only on this area * @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 map_p pointer to a lv_color_t array
* @param opa opacity of the map (ignored, only for compatibility with lv_vmap) * @param opa opacity of the map
* @param transp true: enable transparency of LV_IMG_LV_COLOR_TRANSP color pixels * @param chroma_keyed true: enable transparency of LV_IMG_LV_COLOR_TRANSP color pixels
* @param upscale true: upscale to double size * @param alpha_byte true: extra alpha byte is inserted for every pixel
* @param recolor mix the pixels with this color * @param recolor mix the pixels with this color
* @param recolor_opa the intense of recoloring * @param recolor_opa the intense of recoloring
*/ */
void lv_vmap(const lv_area_t * cords_p, const lv_area_t * mask_p, 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, const uint8_t * map_p, lv_opa_t opa, bool chroma_key, bool alpha_byte,
lv_color_t recolor, lv_opa_t recolor_opa); lv_color_t recolor, lv_opa_t recolor_opa);

View File

@ -30,8 +30,8 @@
/********************** /**********************
* STATIC VARIABLES * STATIC VARIABLES
**********************/ **********************/
static lv_disp_t *disp_list = NULL; static lv_disp_t * disp_list = NULL;
static lv_disp_t *active; static lv_disp_t * active;
/********************** /**********************
* MACROS * MACROS
@ -47,7 +47,7 @@ static lv_disp_t *active;
* After it you can set the fields. * After it you can set the fields.
* @param driver pointer to driver variable to initialize * @param driver pointer to driver variable to initialize
*/ */
void lv_disp_drv_init(lv_disp_drv_t *driver) void lv_disp_drv_init(lv_disp_drv_t * driver)
{ {
driver->disp_fill = NULL; driver->disp_fill = NULL;
driver->disp_map = NULL; driver->disp_map = NULL;
@ -65,23 +65,23 @@ void lv_disp_drv_init(lv_disp_drv_t *driver)
* @param driver pointer to an initialized 'lv_disp_drv_t' variable (can be local variable) * @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 * @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 * lv_disp_drv_register(lv_disp_drv_t * driver)
{ {
lv_disp_t *node; lv_disp_t * node;
node = lv_mem_alloc(sizeof(lv_disp_t)); node = lv_mem_alloc(sizeof(lv_disp_t));
if (!node) return NULL; if(!node) return NULL;
memcpy(&node->driver,driver, sizeof(lv_disp_drv_t)); memcpy(&node->driver, driver, sizeof(lv_disp_drv_t));
node->next = NULL; node->next = NULL;
/* Set first display as active by default */ /* Set first display as active by default */
if (disp_list == NULL) { if(disp_list == NULL) {
disp_list = node; disp_list = node;
active = node; active = node;
lv_obj_invalidate(lv_scr_act()); lv_obj_invalidate(lv_scr_act());
} else { } else {
node->next = disp_list; disp_list->next = node;
} }
return node; return node;
@ -144,7 +144,7 @@ void lv_disp_fill(int32_t x1, int32_t y1, int32_t x2, int32_t y2, lv_color_t col
* @param y2 bottom coordinate of the rectangle * @param y2 bottom coordinate of the rectangle
* @param color_p pointer to an array of colors * @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) 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 == NULL) return;
if(active->driver.disp_flush != NULL) active->driver.disp_flush(x1, y1, x2, y2, color_p); if(active->driver.disp_flush != NULL) active->driver.disp_flush(x1, y1, x2, y2, color_p);
@ -200,6 +200,7 @@ void lv_disp_mem_fill(lv_color_t * dest, uint32_t length, lv_color_t color)
*/ */
bool lv_disp_is_mem_blend_supported(void) bool lv_disp_is_mem_blend_supported(void)
{ {
if(active == NULL) return false;
if(active->driver.mem_blend) return true; if(active->driver.mem_blend) return true;
else return false; else return false;
} }
@ -210,6 +211,7 @@ bool lv_disp_is_mem_blend_supported(void)
*/ */
bool lv_disp_is_mem_fill_supported(void) bool lv_disp_is_mem_fill_supported(void)
{ {
if(active == NULL) return false;
if(active->driver.mem_fill) return true; if(active->driver.mem_fill) return true;
else return false; else return false;
} }

View File

@ -22,7 +22,7 @@
/********************** /**********************
* STATIC PROTOTYPES * STATIC PROTOTYPES
**********************/ **********************/
static lv_indev_t *indev_list = NULL; static lv_indev_t * indev_list = NULL;
/********************** /**********************
* STATIC VARIABLES * STATIC VARIABLES
@ -42,10 +42,11 @@ static lv_indev_t *indev_list = NULL;
* After it you can set the fields. * After it you can set the fields.
* @param driver pointer to driver variable to initialize * @param driver pointer to driver variable to initialize
*/ */
void lv_indev_drv_init(lv_indev_drv_t *driver) void lv_indev_drv_init(lv_indev_drv_t * driver)
{ {
driver->read = NULL; driver->read = NULL;
driver->type = LV_INDEV_TYPE_NONE; driver->type = LV_INDEV_TYPE_NONE;
driver->user_data = NULL;
} }
/** /**
@ -53,25 +54,27 @@ void lv_indev_drv_init(lv_indev_drv_t *driver)
* @param driver pointer to an initialized 'lv_indev_drv_t' variable (can be local variable) * @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 * @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 * lv_indev_drv_register(lv_indev_drv_t * driver)
{ {
lv_indev_t *node; lv_indev_t * node;
node = lv_mem_alloc(sizeof(lv_indev_t)); node = lv_mem_alloc(sizeof(lv_indev_t));
if (!node) return NULL; if(!node) return NULL;
memset(node, 0, sizeof(lv_indev_t));
memcpy(&node->driver, driver, sizeof(lv_indev_drv_t)); memcpy(&node->driver, driver, sizeof(lv_indev_drv_t));
node->next = NULL; node->next = NULL;
node->proc.reset_query = 1; node->proc.reset_query = 1;
node->cursor = NULL; node->cursor = NULL;
node->group = NULL; node->group = NULL;
node->btn_points = NULL;
if (indev_list == NULL) { if(indev_list == NULL) {
indev_list = node; indev_list = node;
} else { } else {
lv_indev_t *last = indev_list; lv_indev_t * last = indev_list;
while (last->next) while(last->next)
last = last->next; last = last->next;
last->next = node; last->next = node;
@ -102,11 +105,12 @@ lv_indev_t * lv_indev_next(lv_indev_t * indev)
* @param data input device will write its data here * @param data input device will write its data here
* @return false: no more data; true: there more data to read (buffered) * @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 lv_indev_read(lv_indev_t * indev, lv_indev_data_t * data)
{ {
bool cont = false; bool cont = false;
if(indev->driver.read) { if(indev->driver.read) {
data->user_data = indev->driver.user_data;
cont = indev->driver.read(data); cont = indev->driver.read(data);
} else { } else {
memset(data, 0, sizeof(lv_indev_data_t)); memset(data, 0, sizeof(lv_indev_data_t));

View File

@ -33,35 +33,40 @@ typedef enum {
LV_INDEV_TYPE_NONE, /*Show uninitialized state*/ LV_INDEV_TYPE_NONE, /*Show uninitialized state*/
LV_INDEV_TYPE_POINTER, /*Touch pad, mouse, external button*/ LV_INDEV_TYPE_POINTER, /*Touch pad, mouse, external button*/
LV_INDEV_TYPE_KEYPAD, /*Keypad or keyboard*/ LV_INDEV_TYPE_KEYPAD, /*Keypad or keyboard*/
LV_INDEV_TYPE_BUTTON, /*External (hardware button) which is assinged to a specific point of the screen*/
} lv_hal_indev_type_t; } lv_hal_indev_type_t;
/*States for input devices*/ /*States for input devices*/
typedef enum { typedef enum {
LV_INDEV_STATE_REL, LV_INDEV_STATE_REL = 0,
LV_INDEV_STATE_PR LV_INDEV_STATE_PR
}lv_indev_state_t; } lv_indev_state_t;
/*Data type when an input device is read */ /*Data type when an input device is read */
typedef struct { typedef struct {
union { union {
lv_point_t point; /*For INDEV_TYPE_POINTER*/ lv_point_t point; /*For LV_INDEV_TYPE_POINTER the currently pressed point*/
uint32_t key; /*For INDEV_TYPE_KEYPAD*/ uint32_t key; /*For LV_INDEV_TYPE_KEYPAD the currently pressed key*/
uint32_t btn; /*For LV_INDEV_TYPE_BUTTON the currently pressed button*/
}; };
lv_indev_state_t state; /*LV_INDEV_EVENT_REL or LV_INDEV_EVENT_PR*/ lv_indev_state_t state; /*LV_INDEV_EVENT_REL or LV_INDEV_EVENT_PR*/
}lv_indev_data_t; void *user_data; /*'lv_indev_drv_t.priv' for this driver*/
} lv_indev_data_t;
/*Initialized by the user and registered by 'lv_indev_add()'*/ /*Initialized by the user and registered by 'lv_indev_add()'*/
typedef struct { typedef struct {
lv_hal_indev_type_t type; /*Input device type*/ 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)*/ 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; void *user_data; /*Pointer to user defined data, passed in 'lv_indev_data_t' on read*/
} lv_indev_drv_t;
struct _lv_obj_t; struct _lv_obj_t;
typedef struct _lv_indev_state_t { /*Run time data of input devices*/
typedef struct _lv_indev_proc_t {
lv_indev_state_t state; lv_indev_state_t state;
union { union {
struct { /*Pointer data*/ struct { /*Pointer and button data*/
lv_point_t act_point; lv_point_t act_point;
lv_point_t last_point; lv_point_t last_point;
lv_point_t vect; lv_point_t vect;
@ -76,6 +81,7 @@ typedef struct _lv_indev_state_t {
}; };
struct { /*Keypad data*/ struct { /*Keypad data*/
lv_indev_state_t last_state; lv_indev_state_t last_state;
uint32_t last_key;
}; };
}; };
@ -86,19 +92,22 @@ typedef struct _lv_indev_state_t {
uint8_t long_pr_sent :1; uint8_t long_pr_sent :1;
uint8_t reset_query :1; uint8_t reset_query :1;
uint8_t disabled :1; uint8_t disabled :1;
}lv_indev_proc_t; } lv_indev_proc_t;
struct _lv_obj_t; struct _lv_obj_t;
struct _lv_group_t; struct _lv_group_t;
/*The main input device descriptor with driver, runtime data ('proc') and some additional information*/
typedef struct _lv_indev_t { typedef struct _lv_indev_t {
lv_indev_drv_t driver; lv_indev_drv_t driver;
lv_indev_proc_t proc; lv_indev_proc_t proc;
uint32_t last_activity_time; uint32_t last_activity_time;
union { union {
struct _lv_obj_t *cursor; struct _lv_obj_t *cursor; /*Cursor for LV_INPUT_TYPE_POINTER*/
struct _lv_group_t *group; /*Keypad destination group*/ struct _lv_group_t *group; /*Keypad destination group*/
lv_point_t * btn_points; /*Array points assigned to the button ()screen will be pressed here by the buttons*/
}; };
struct _lv_indev_t *next; struct _lv_indev_t *next;
} lv_indev_t; } lv_indev_t;

View File

@ -8,6 +8,7 @@
*********************/ *********************/
#include "lv_hal_tick.h" #include "lv_hal_tick.h"
#include <stddef.h> #include <stddef.h>
#include "../../lv_conf.h"
/********************* /*********************
* DEFINES * DEFINES
@ -39,7 +40,7 @@ static volatile uint8_t tick_irq_flag;
* You have to call this function periodically * You have to call this function periodically
* @param tick_period the call period of this function in milliseconds * @param tick_period the call period of this function in milliseconds
*/ */
void lv_tick_inc(uint32_t tick_period) LV_ATTRIBUTE_TICK_INC void lv_tick_inc(uint32_t tick_period)
{ {
tick_irq_flag = 0; tick_irq_flag = 0;
sys_time += tick_period; sys_time += tick_period;

View File

@ -19,6 +19,9 @@ extern "C" {
/********************* /*********************
* DEFINES * DEFINES
*********************/ *********************/
#ifndef LV_ATTRIBUTE_TICK_INC
#define LV_ATTRIBUTE_TICK_INC
#endif
/********************** /**********************
* TYPEDEFS * TYPEDEFS
@ -32,7 +35,7 @@ extern "C" {
* You have to call this function periodically * You have to call this function periodically
* @param tick_period the call period of this function in milliseconds * @param tick_period the call period of this function in milliseconds
*/ */
void lv_tick_inc(uint32_t tick_period); LV_ATTRIBUTE_TICK_INC void lv_tick_inc(uint32_t tick_period);
/** /**
* Get the elapsed milliseconds since start up * Get the elapsed milliseconds since start up

View File

@ -28,7 +28,7 @@
/********************** /**********************
* STATIC PROTOTYPES * STATIC PROTOTYPES
**********************/ **********************/
static void anim_task (void * param); static void anim_task(void * param);
static bool anim_ready_handler(lv_anim_t * a); static bool anim_ready_handler(lv_anim_t * a);
/********************** /**********************
@ -36,7 +36,6 @@ static bool anim_ready_handler(lv_anim_t * a);
**********************/ **********************/
static lv_ll_t anim_ll; static lv_ll_t anim_ll;
static uint32_t last_task_run; static uint32_t last_task_run;
static bool anim_del_global_flag = false;
/********************** /**********************
* MACROS * MACROS
@ -98,7 +97,6 @@ bool lv_anim_del(void * var, lv_anim_fp_t fp)
lv_ll_rem(&anim_ll, a); lv_ll_rem(&anim_ll, a);
lv_mem_free(a); lv_mem_free(a);
del = true; del = true;
anim_del_global_flag = true;
} }
a = a_next; a = a_next;
@ -117,7 +115,9 @@ bool lv_anim_del(void * var, lv_anim_fp_t fp)
uint16_t lv_anim_speed_to_time(uint16_t speed, int32_t start, int32_t end) 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); int32_t d = LV_MATH_ABS((int32_t) start - end);
uint16_t time = (int32_t)((int32_t)(d * 1000) / speed); uint32_t time = (int32_t)((int32_t)(d * 1000) / speed);
if(time > UINT16_MAX) time = UINT16_MAX;
if(time == 0) { if(time == 0) {
time++; time++;
@ -131,7 +131,7 @@ uint16_t lv_anim_speed_to_time(uint16_t speed, int32_t start, int32_t end)
* @param a pointer to an animation * @param a pointer to an animation
* @return the current value to set * @return the current value to set
*/ */
int32_t lv_anim_path_linear(const lv_anim_t *a) int32_t lv_anim_path_linear(const lv_anim_t * a)
{ {
/*Calculate the current step*/ /*Calculate the current step*/
@ -156,7 +156,7 @@ int32_t lv_anim_path_linear(const lv_anim_t *a)
* @param a pointer to an animation * @param a pointer to an animation
* @return the current value to set * @return the current value to set
*/ */
int32_t lv_anim_path_step(const lv_anim_t *a) int32_t lv_anim_path_step(const lv_anim_t * a)
{ {
if(a->act_time >= a->time) return a->end; if(a->act_time >= a->time) return a->end;
else return a->start; else return a->start;
@ -170,7 +170,7 @@ int32_t lv_anim_path_step(const lv_anim_t *a)
* Periodically handle the animations. * Periodically handle the animations.
* @param param unused * @param param unused
*/ */
static void anim_task (void * param) static void anim_task(void * param)
{ {
(void)param; (void)param;
@ -224,7 +224,7 @@ static bool anim_ready_handler(lv_anim_t * a)
* - no repeat, play back is enabled and play back is ready */ * - no repeat, play back is enabled and play back is ready */
if((a->repeat == 0 && a->playback == 0) || if((a->repeat == 0 && a->playback == 0) ||
(a->repeat == 0 && a->playback == 1 && a->playback_now == 1)) { (a->repeat == 0 && a->playback == 1 && a->playback_now == 1)) {
void (*cb) (void *) = a->end_cb; void (*cb)(void *) = a->end_cb;
void * p = a->var; void * p = a->var;
lv_ll_rem(&anim_ll, a); lv_ll_rem(&anim_ll, a);
lv_mem_free(a); lv_mem_free(a);
@ -232,9 +232,8 @@ static bool anim_ready_handler(lv_anim_t * a)
/*Call the callback function at the end*/ /*Call the callback function at the end*/
/* Check if an animation is deleted in the cb function /* Check if an animation is deleted in the cb function
* if yes then the caller function has to know this*/ * if yes then the caller function has to know this*/
anim_del_global_flag = false;
if(cb != NULL) cb(p); if(cb != NULL) cb(p);
invalid = anim_del_global_flag; invalid = true;
} }
/*If the animation is not deleted then restart it*/ /*If the animation is not deleted then restart it*/
else { else {
@ -245,7 +244,7 @@ static bool anim_ready_handler(lv_anim_t * a)
if(a->playback_now == 0) a->act_time = - a->playback_pause; if(a->playback_now == 0) a->act_time = - a->playback_pause;
/*Toggle the play back state*/ /*Toggle the play back state*/
a->playback_now = a->playback_now == 0 ? 1: 0; a->playback_now = a->playback_now == 0 ? 1 : 0;
/*Swap the start and end values*/ /*Swap the start and end values*/
int32_t tmp; int32_t tmp;
tmp = a->start; tmp = a->start;

View File

@ -43,7 +43,7 @@ typedef struct _lv_anim_t
lv_anim_path_t path; /*An array with the steps of animations*/ lv_anim_path_t path; /*An array with the steps of animations*/
int32_t start; /*Start value*/ int32_t start; /*Start value*/
int32_t end; /*End value*/ int32_t end; /*End value*/
int16_t time; /*Animation time in ms*/ uint16_t time; /*Animation time in ms*/
int16_t act_time; /*Current time in animation. Set to negative to make delay.*/ int16_t act_time; /*Current time in animation. Set to negative to make delay.*/
uint16_t playback_pause; /*Wait before play back*/ uint16_t playback_pause; /*Wait before play back*/
uint16_t repeat_pause; /*Wait before repeat*/ uint16_t repeat_pause; /*Wait before repeat*/
@ -51,7 +51,7 @@ typedef struct _lv_anim_t
uint8_t repeat :1; /*Repeat the animation infinitely*/ uint8_t repeat :1; /*Repeat the animation infinitely*/
/*Animation system use these - user shouldn't set*/ /*Animation system use these - user shouldn't set*/
uint8_t playback_now :1; /*Play back is in progress*/ uint8_t playback_now :1; /*Play back is in progress*/
}lv_anim_t; } lv_anim_t;
/*Example initialization /*Example initialization
lv_anim_t a; lv_anim_t a;
@ -119,7 +119,7 @@ int32_t lv_anim_path_step(const lv_anim_t *a);
* MACROS * MACROS
**********************/ **********************/
#endif /*LV_NO_ANIM == 0*/ #endif /*USE_LV_ANIMATION == 0*/
#ifdef __cplusplus #ifdef __cplusplus
} /* extern "C" */ } /* extern "C" */

View File

@ -102,12 +102,12 @@ uint32_t lv_area_get_size(const lv_area_t * area_p)
/** /**
* Get the common parts of two areas * Get the common parts of two areas
* @param res_p pointer to an area, the result will be stored her * @param res_p pointer to an area, the result will be stored here
* @param a1_p pointer to the first area * @param a1_p pointer to the first area
* @param a2_p pointer to the second area * @param a2_p pointer to the second area
* @return false: the two area has NO common parts, res_p is invalid * @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) bool lv_area_intersect(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' */ /* Get the smaller area from 'a1_p' and 'a2_p' */
res_p->x1 = LV_MATH_MAX(a1_p->x1, a2_p->x1); res_p->x1 = LV_MATH_MAX(a1_p->x1, a2_p->x1);
@ -118,8 +118,7 @@ bool lv_area_union(lv_area_t * res_p, const lv_area_t * a1_p, const lv_area_t *
/*If x1 or y1 greater then x2 or y2 then the areas union is empty*/ /*If x1 or y1 greater then x2 or y2 then the areas union is empty*/
bool union_ok = true; bool union_ok = true;
if((res_p->x1 > res_p->x2) || if((res_p->x1 > res_p->x2) ||
(res_p->y1 > res_p->y2)) (res_p->y1 > res_p->y2)) {
{
union_ok = false; union_ok = false;
} }
@ -150,8 +149,7 @@ bool lv_area_is_point_on(const lv_area_t * a_p, const lv_point_t * p_p)
bool is_on = false; bool is_on = false;
if((p_p->x >= a_p->x1 && p_p->x <= a_p->x2) && 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))) ((p_p->y >= a_p->y1 && p_p->y <= a_p->y2))) {
{
is_on = true; is_on = true;
} }
@ -166,45 +164,15 @@ bool lv_area_is_point_on(const lv_area_t * a_p, const lv_point_t * p_p)
*/ */
bool lv_area_is_on(const lv_area_t * a1_p, const lv_area_t * a2_p) bool lv_area_is_on(const lv_area_t * a1_p, const lv_area_t * a2_p)
{ {
/*Two area are on each other if... */ if((a1_p->x1 <= a2_p->x2) &&
(a1_p->x2 >= a2_p->x1) &&
lv_point_t p; (a1_p->y1 <= a2_p->y2) &&
/*a2 left-top corner is on a1*/ (a1_p->y2 >= a2_p->y1)) {
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; return true;
} else {
/*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; return false;
}
} }
/** /**
@ -220,8 +188,7 @@ bool lv_area_is_in(const lv_area_t * ain_p, const lv_area_t * aholder_p)
if(ain_p->x1 >= aholder_p->x1 && if(ain_p->x1 >= aholder_p->x1 &&
ain_p->y1 >= aholder_p->y1 && ain_p->y1 >= aholder_p->y1 &&
ain_p->x2 <= aholder_p->x2 && ain_p->x2 <= aholder_p->x2 &&
ain_p->y2 <= aholder_p->y2) ain_p->y2 <= aholder_p->y2) {
{
is_in = true; is_in = true;
} }

View File

@ -33,7 +33,7 @@ typedef struct
{ {
lv_coord_t x; lv_coord_t x;
lv_coord_t y; lv_coord_t y;
}lv_point_t; } lv_point_t;
typedef struct typedef struct
{ {
@ -41,7 +41,7 @@ typedef struct
lv_coord_t y1; lv_coord_t y1;
lv_coord_t x2; lv_coord_t x2;
lv_coord_t y2; lv_coord_t y2;
}lv_area_t; } lv_area_t;
/********************** /**********************
* GLOBAL PROTOTYPES * GLOBAL PROTOTYPES
@ -123,7 +123,7 @@ uint32_t lv_area_get_size(const lv_area_t * area_p);
* @param a2_p pointer to the second area * @param a2_p pointer to the second area
* @return false: the two area has NO common parts, res_p is invalid * @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); bool lv_area_intersect(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 * Join two areas into a third which involves the other two

View File

@ -66,7 +66,7 @@ void lv_circ_next(lv_point_t * c, lv_coord_t * tmp)
{ {
c->y++; c->y++;
if (*tmp <= 0) { if(*tmp <= 0) {
(*tmp) += 2 * c->y + 1; // Change in decision criterion for y -> y+1 (*tmp) += 2 * c->y + 1; // Change in decision criterion for y -> y+1
} else { } else {
c->x--; c->x--;

View File

@ -53,8 +53,7 @@ lv_color_t lv_color_hsv_to_rgb(uint16_t h, uint8_t s, uint8_t v)
uint8_t region, remainder, p, q, t; uint8_t region, remainder, p, q, t;
if (s == 0) if(s == 0) {
{
r = v; r = v;
g = v; g = v;
b = v; b = v;
@ -68,25 +67,36 @@ lv_color_t lv_color_hsv_to_rgb(uint16_t h, uint8_t s, uint8_t v)
q = (v * (255 - ((s * remainder) >> 8))) >> 8; q = (v * (255 - ((s * remainder) >> 8))) >> 8;
t = (v * (255 - ((s * (255 - remainder)) >> 8))) >> 8; t = (v * (255 - ((s * (255 - remainder)) >> 8))) >> 8;
switch (region) switch(region) {
{
case 0: case 0:
r = v; g = t; b = p; r = v;
g = t;
b = p;
break; break;
case 1: case 1:
r = q; g = v; b = p; r = q;
g = v;
b = p;
break; break;
case 2: case 2:
r = p; g = v; b = t; r = p;
g = v;
b = t;
break; break;
case 3: case 3:
r = p; g = q; b = v; r = p;
g = q;
b = v;
break; break;
case 4: case 4:
r = t; g = p; b = v; r = t;
g = p;
b = v;
break; break;
default: default:
r = v; g = p; b = q; r = v;
g = p;
b = q;
break; break;
} }
@ -110,23 +120,21 @@ lv_color_hsv_t lv_color_rgb_to_hsv(uint8_t r, uint8_t g, uint8_t b)
rgbMax = r > g ? (r > b ? r : b) : (g > b ? g : b); rgbMax = r > g ? (r > b ? r : b) : (g > b ? g : b);
hsv.v = rgbMax; hsv.v = rgbMax;
if (hsv.v == 0) if(hsv.v == 0) {
{
hsv.h = 0; hsv.h = 0;
hsv.s = 0; hsv.s = 0;
return hsv; return hsv;
} }
hsv.s = 255 * (long)(rgbMax - rgbMin) / hsv.v; hsv.s = 255 * (long)(rgbMax - rgbMin) / hsv.v;
if (hsv.s == 0) if(hsv.s == 0) {
{
hsv.h = 0; hsv.h = 0;
return hsv; return hsv;
} }
if (rgbMax == r) if(rgbMax == r)
hsv.h = 0 + 43 * (g - b) / (rgbMax - rgbMin); hsv.h = 0 + 43 * (g - b) / (rgbMax - rgbMin);
else if (rgbMax == g) else if(rgbMax == g)
hsv.h = 85 + 43 * (b - r) / (rgbMax - rgbMin); hsv.h = 85 + 43 * (b - r) / (rgbMax - rgbMin);
else else
hsv.h = 171 + 43 * (r - g) / (rgbMax - rgbMin); hsv.h = 171 + 43 * (r - g) / (rgbMax - rgbMin);

View File

@ -64,7 +64,7 @@ typedef union
uint8_t green :1; uint8_t green :1;
uint8_t red :1; uint8_t red :1;
uint8_t full :1; uint8_t full :1;
}lv_color1_t; } lv_color1_t;
typedef union typedef union
{ {
@ -75,7 +75,7 @@ typedef union
uint8_t red :3; uint8_t red :3;
}; };
uint8_t full; uint8_t full;
}lv_color8_t; } lv_color8_t;
typedef union typedef union
{ {
@ -86,7 +86,7 @@ typedef union
uint16_t red :5; uint16_t red :5;
}; };
uint16_t full; uint16_t full;
}lv_color16_t; } lv_color16_t;
typedef union typedef union
{ {
@ -95,9 +95,10 @@ typedef union
uint8_t blue; uint8_t blue;
uint8_t green; uint8_t green;
uint8_t red; uint8_t red;
uint8_t alpha;
}; };
uint32_t full; uint32_t full;
}lv_color24_t; } lv_color24_t;
#if LV_COLOR_DEPTH == 1 #if LV_COLOR_DEPTH == 1
typedef uint8_t lv_color_int_t; typedef uint8_t lv_color_int_t;
@ -147,17 +148,17 @@ static inline uint8_t lv_color_to1(lv_color_t color)
#if LV_COLOR_DEPTH == 1 #if LV_COLOR_DEPTH == 1
return color.full; return color.full;
#elif LV_COLOR_DEPTH == 8 #elif LV_COLOR_DEPTH == 8
if((color.red & 0b100) || if((color.red & 0x4) ||
(color.green & 0b100) || (color.green & 0x4) ||
(color.blue & 0b10)) { (color.blue & 0x2)) {
return 1; return 1;
} else { } else {
return 0; return 0;
} }
#elif LV_COLOR_DEPTH == 16 #elif LV_COLOR_DEPTH == 16
if((color.red & 0b10000) || if((color.red & 0x10) ||
(color.green & 0b100000) || (color.green & 0x20) ||
(color.blue & 0b10000)) { (color.blue & 0x10)) {
return 1; return 1;
} else { } else {
return 0; return 0;
@ -221,18 +222,20 @@ static inline uint32_t lv_color_to24(lv_color_t color)
{ {
#if LV_COLOR_DEPTH == 1 #if LV_COLOR_DEPTH == 1
if(color.full == 0) return 0; if(color.full == 0) return 0;
else return 0xFFFFFF; else return 0xFFFFFFFF;
#elif LV_COLOR_DEPTH == 8 #elif LV_COLOR_DEPTH == 8
lv_color24_t ret; lv_color24_t ret;
ret.red = color.red * 36; /*(2^8 - 1)/(2^3 - 1) = 255/7 = 36*/ 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.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.blue = color.blue * 85; /*(2^8 - 1)/(2^2 - 1) = 255/3 = 85*/
ret.alpha = 0xFF;
return ret.full; return ret.full;
#elif LV_COLOR_DEPTH == 16 #elif LV_COLOR_DEPTH == 16
lv_color24_t ret; lv_color24_t ret;
ret.red = color.red * 8; /*(2^8 - 1)/(2^5 - 1) = 255/31 = 8*/ 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.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.blue = color.blue * 8; /*(2^8 - 1)/(2^5 - 1) = 255/31 = 8*/
ret.alpha = 0xFF;
return ret.full; return ret.full;
#elif LV_COLOR_DEPTH == 24 #elif LV_COLOR_DEPTH == 24
return color.full; return color.full;
@ -242,9 +245,17 @@ static inline uint32_t lv_color_to24(lv_color_t color)
static inline lv_color_t lv_color_mix(lv_color_t c1, lv_color_t c2, uint8_t mix) static inline lv_color_t lv_color_mix(lv_color_t c1, lv_color_t c2, uint8_t mix)
{ {
lv_color_t ret; lv_color_t ret;
#if LV_COLOR_DEPTH != 1
ret.red = (uint16_t)((uint16_t) c1.red * mix + (c2.red * (255 - mix))) >> 8; 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.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; ret.blue = (uint16_t)((uint16_t) c1.blue * mix + (c2.blue * (255 - mix))) >> 8;
# if LV_COLOR_DEPTH == 24
ret.alpha = 0xFF;
# endif
#else
ret.full = mix > LV_OPA_50 ? c1.full : c2.full;
#endif
return ret; return ret;
} }
@ -261,6 +272,9 @@ static inline uint8_t lv_color_brightness(lv_color_t color)
return (uint16_t) bright >> 3; 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 #if LV_COLOR_DEPTH == 1
#define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){(b8 >> 7 | g8 >> 7 | r8 >> 7)}) #define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){(b8 >> 7 | g8 >> 7 | r8 >> 7)})
#elif LV_COLOR_DEPTH == 8 #elif LV_COLOR_DEPTH == 8
@ -268,7 +282,18 @@ static inline uint8_t lv_color_brightness(lv_color_t color)
#elif LV_COLOR_DEPTH == 16 #elif LV_COLOR_DEPTH == 16
#define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){{b8 >> 3, g8 >> 2, r8 >> 3}}) #define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){{b8 >> 3, g8 >> 2, r8 >> 3}})
#elif LV_COLOR_DEPTH == 24 #elif LV_COLOR_DEPTH == 24
#define LV_COLOR_MAKE(r8, g8, b8) ((lv_color_t){{b8, g8, r8}}) #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 #endif
#define LV_COLOR_HEX(c) LV_COLOR_MAKE(((uint32_t)((uint32_t)c >> 16) & 0xFF), \ #define LV_COLOR_HEX(c) LV_COLOR_MAKE(((uint32_t)((uint32_t)c >> 16) & 0xFF), \

View File

@ -18,6 +18,11 @@
/********************** /**********************
* TYPEDEFS * TYPEDEFS
**********************/ **********************/
typedef struct {
uint32_t glyph_index;
uint32_t unicode;
uint8_t w_px;
} asd_glyph_dsc_t;
/********************** /**********************
* STATIC PROTOTYPES * STATIC PROTOTYPES
@ -44,33 +49,16 @@
*/ */
void lv_font_init(void) void lv_font_init(void)
{ {
/*DEJAVU 10*/ /*DEJAVU 10*/
#if USE_LV_FONT_DEJAVU_10 != 0 #if USE_LV_FONT_DEJAVU_10 != 0
lv_font_add(&lv_font_dejavu_10, NULL); lv_font_add(&lv_font_dejavu_10, NULL);
#endif #endif
#if USE_LV_FONT_DEJAVU_10_SUP != 0 #if USE_LV_FONT_DEJAVU_10_LATIN_SUP != 0
#if USE_LV_FONT_DEJAVU_10 != 0 #if USE_LV_FONT_DEJAVU_10 != 0
lv_font_add(&lv_font_dejavu_10_sup, &lv_font_dejavu_10); lv_font_add(&lv_font_dejavu_10_latin_sup, &lv_font_dejavu_10);
#else #else
lv_font_add(&lv_font_dejavu_10_sup, NULL); lv_font_add(&lv_font_dejavu_10_latin_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
#endif #endif
@ -83,56 +71,25 @@ void lv_font_init(void)
#endif #endif
/*SYMBOL 10*/ /*SYMBOL 10*/
#if USE_LV_FONT_SYMBOL_10_BASIC != 0 #if USE_LV_FONT_SYMBOL_10 != 0
#if USE_LV_FONT_DEJAVU_10 != 0 #if USE_LV_FONT_DEJAVU_10 != 0
lv_font_add(&lv_font_symbol_10_basic, &lv_font_dejavu_10); lv_font_add(&lv_font_symbol_10, &lv_font_dejavu_10);
#else #else
lv_font_add(&lv_font_symbol_10_basic, NULL); lv_font_add(&lv_font_symbol_10, NULL);
#endif #endif
#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*/ /*DEJAVU 20*/
#if USE_LV_FONT_DEJAVU_20 != 0 #if USE_LV_FONT_DEJAVU_20 != 0
lv_font_add(&lv_font_dejavu_20, NULL); lv_font_add(&lv_font_dejavu_20, NULL);
#endif #endif
#if USE_LV_FONT_DEJAVU_20_SUP != 0 #if USE_LV_FONT_DEJAVU_20_LATIN_SUP != 0
#if USE_LV_FONT_DEJAVU_20 != 0 #if USE_LV_FONT_DEJAVU_20 != 0
lv_font_add(&lv_font_dejavu_20_sup, &lv_font_dejavu_20); lv_font_add(&lv_font_dejavu_20_latin_sup, &lv_font_dejavu_20);
#else #else
lv_font_add(&lv_font_symbol_20_sup, NULL); lv_font_add(&lv_font_symbol_20_latin_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
#endif #endif
@ -145,56 +102,25 @@ void lv_font_init(void)
#endif #endif
/*SYMBOL 20*/ /*SYMBOL 20*/
#if USE_LV_FONT_SYMBOL_20_BASIC != 0 #if USE_LV_FONT_SYMBOL_20 != 0
#if USE_LV_FONT_DEJAVU_20 != 0 #if USE_LV_FONT_DEJAVU_20 != 0
lv_font_add(&lv_font_symbol_20_basic, &lv_font_dejavu_20); lv_font_add(&lv_font_symbol_20, &lv_font_dejavu_20);
#else #else
lv_font_add(&lv_font_symbol_20_basic, NULL); lv_font_add(&lv_font_symbol_20, NULL);
#endif #endif
#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*/ /*DEJAVU 30*/
#if USE_LV_FONT_DEJAVU_30 != 0 #if USE_LV_FONT_DEJAVU_30 != 0
lv_font_add(&lv_font_dejavu_30, NULL); lv_font_add(&lv_font_dejavu_30, NULL);
#endif #endif
#if USE_LV_FONT_DEJAVU_30_SUP != 0 #if USE_LV_FONT_DEJAVU_30_LATIN_SUP != 0
#if USE_LV_FONT_DEJAVU_30 != 0 #if USE_LV_FONT_DEJAVU_30 != 0
lv_font_add(&lv_font_dejavu_30_sup, &lv_font_dejavu_30); lv_font_add(&lv_font_dejavu_30_latin_sup, &lv_font_dejavu_30);
#else #else
lv_font_add(&lv_font_dejavu_30_sup, NULL); lv_font_add(&lv_font_dejavu_30_latin_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
#endif #endif
@ -207,28 +133,12 @@ void lv_font_init(void)
#endif #endif
/*SYMBOL 30*/ /*SYMBOL 30*/
#if USE_LV_FONT_SYMBOL_30_BASIC != 0 #if USE_LV_FONT_SYMBOL_30 != 0
#if USE_LV_FONT_DEJAVU_30 != 0 #if USE_LV_FONT_DEJAVU_30 != 0
lv_font_add(&lv_font_symbol_30_basic, &lv_font_dejavu_30); lv_font_add(&lv_font_symbol_30, &lv_font_dejavu_30);
#else #else
lv_font_add(&lv_font_symbol_30_basic, NULL); lv_font_add(&lv_font_symbol_30_basic, NULL);
#endif #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 #endif
/*DEJAVU 40*/ /*DEJAVU 40*/
@ -236,27 +146,11 @@ void lv_font_init(void)
lv_font_add(&lv_font_dejavu_40, NULL); lv_font_add(&lv_font_dejavu_40, NULL);
#endif #endif
#if USE_LV_FONT_DEJAVU_40_SUP != 0 #if USE_LV_FONT_DEJAVU_40_LATIN_SUP != 0
#if USE_LV_FONT_DEJAVU_40 != 0 #if USE_LV_FONT_DEJAVU_40 != 0
lv_font_add(&lv_font_dejavu_40_sup, &lv_font_dejavu_40); lv_font_add(&lv_font_dejavu_40_latin_sup, &lv_font_dejavu_40);
#else #else
lv_font_add(&lv_font_dejavu_40_sup, NULL); lv_font_add(&lv_font_dejavu_40_latin_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
#endif #endif
@ -269,153 +163,14 @@ void lv_font_init(void)
#endif #endif
/*SYMBOL 40*/ /*SYMBOL 40*/
#if USE_LV_FONT_SYMBOL_40_BASIC != 0 #if USE_LV_FONT_SYMBOL_40 != 0
#if USE_LV_FONT_DEJAVU_40 != 0 #if USE_LV_FONT_DEJAVU_40 != 0
lv_font_add(&lv_font_symbol_40_basic, &lv_font_dejavu_40); lv_font_add(&lv_font_symbol_40, &lv_font_dejavu_40);
#else #else
lv_font_add(&lv_font_symbol_40_basic, NULL); lv_font_add(&lv_font_symbol_40, NULL);
#endif #endif
#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
} }
/** /**
@ -424,7 +179,7 @@ void lv_font_init(void)
* @param dsc_get_fp the font descriptor get function * @param dsc_get_fp the font descriptor get function
* @param parent add this font as charter set extension of 'parent' * @param parent add this font as charter set extension of 'parent'
*/ */
void lv_font_add(lv_font_t *child, lv_font_t *parent) void lv_font_add(lv_font_t * child, lv_font_t * parent)
{ {
if(parent == NULL) return; if(parent == NULL) return;
@ -446,10 +201,8 @@ const uint8_t * lv_font_get_bitmap(const lv_font_t * font_p, uint32_t letter)
{ {
const lv_font_t * font_i = font_p; const lv_font_t * font_i = font_p;
while(font_i != NULL) { while(font_i != NULL) {
if(letter >= font_i->first_ascii && letter <= font_i->last_ascii) { const uint8_t * bitmap = font_i->get_bitmap(font_i, letter);
uint32_t index = (letter - font_i->first_ascii); if(bitmap) return bitmap;
return &font_i->bitmap[font_i->map[index]];
}
font_i = font_i->next_page; font_i = font_i->next_page;
} }
@ -466,17 +219,111 @@ const uint8_t * lv_font_get_bitmap(const lv_font_t * font_p, uint32_t letter)
uint8_t lv_font_get_width(const lv_font_t * font_p, uint32_t letter) uint8_t lv_font_get_width(const lv_font_t * font_p, uint32_t letter)
{ {
const lv_font_t * font_i = font_p; const lv_font_t * font_i = font_p;
int16_t w;
while(font_i != NULL) { while(font_i != NULL) {
if(letter >= font_i->first_ascii && letter <= font_i->last_ascii) { w = font_i->get_width(font_i, letter);
uint32_t index = (letter - font_i->first_ascii); if(w >= 0) return w;
return font_i->width[index];
}
font_i = font_i->next_page; font_i = font_i->next_page;
} }
return 0; return 0;
} }
/**
* Get the bit-per-pixel of font
* @param font pointer to font
* @param letter a letter from font (font extensions can have different bpp)
* @return bpp of the font (or font extension)
*/
uint8_t lv_font_get_bpp(const lv_font_t * font, uint32_t letter)
{
const lv_font_t * font_i = font;
while(font_i != NULL) {
if(letter >= font_i->unicode_first && letter <= font_i->unicode_last) {
return font_i->bpp;
}
font_i = font_i->next_page;
}
return 0;
}
/**
* Generic bitmap get function used in 'font->get_bitmap' when the font contains all characters in the range
* @param font pointer to font
* @param unicode_letter an unicode letter which bitmap should be get
* @return pointer to the bitmap or NULL if not found
*/
const uint8_t * lv_font_get_bitmap_continuous(const lv_font_t * font, uint32_t unicode_letter)
{
/*Check the range*/
if(unicode_letter < font->unicode_first || unicode_letter > font->unicode_last) return NULL;
uint32_t index = (unicode_letter - font->unicode_first);
return &font->glyph_bitmap[font->glyph_dsc[index].glyph_index];
}
/**
* Generic bitmap get function used in 'font->get_bitmap' when the font NOT contains all characters in the range (sparse)
* @param font pointer to font
* @param unicode_letter an unicode letter which bitmap should be get
* @return pointer to the bitmap or NULL if not found
*/
const uint8_t * lv_font_get_bitmap_sparse(const lv_font_t * font, uint32_t unicode_letter)
{
/*Check the range*/
if(unicode_letter < font->unicode_first || unicode_letter > font->unicode_last) return NULL;
uint32_t i;
for(i = 0; font->unicode_list[i] != 0; i++) {
if(font->unicode_list[i] == unicode_letter) {
return &font->glyph_bitmap[font->glyph_dsc[i].glyph_index];
}
}
return NULL;
}
/**
* Generic glyph width get function used in 'font->get_width' when the font contains all characters in the range
* @param font pointer to font
* @param unicode_letter an unicode letter which width should be get
* @return width of the gylph or -1 if not found
*/
int16_t lv_font_get_width_continuous(const lv_font_t * font, uint32_t unicode_letter)
{
/*Check the range*/
if(unicode_letter < font->unicode_first || unicode_letter > font->unicode_last) {
return -1;
}
uint32_t index = (unicode_letter - font->unicode_first);
return font->glyph_dsc[index].w_px;
}
/**
* Generic glyph width get function used in 'font->get_bitmap' when the font NOT contains all characters in the range (sparse)
* @param font pointer to font
* @param unicode_letter an unicode letter which width should be get
* @return width of the glyph or -1 if not found
*/
int16_t lv_font_get_width_sparse(const lv_font_t * font, uint32_t unicode_letter)
{
/*Check the range*/
if(unicode_letter < font->unicode_first || unicode_letter > font->unicode_last) return -1;
uint32_t i;
for(i = 0; font->unicode_list[i] != 0; i++) {
if(font->unicode_list[i] == unicode_letter) {
return font->glyph_dsc[i].w_px;
}
}
return -1;
}
/********************** /**********************
* STATIC FUNCTIONS * STATIC FUNCTIONS
**********************/ **********************/

View File

@ -29,16 +29,31 @@ extern "C" {
* TYPEDEFS * TYPEDEFS
**********************/ **********************/
typedef struct
{
uint32_t w_px :8;
uint32_t glyph_index :24;
} lv_font_glyph_dsc_t;
typedef struct
{
uint32_t unicode :21;
uint32_t glyph_dsc_index :11;
} lv_font_unicode_map_t;
typedef struct _lv_font_struct typedef struct _lv_font_struct
{ {
uint32_t first_ascii; uint32_t unicode_first;
uint32_t last_ascii; uint32_t unicode_last;
uint8_t height_row; uint8_t h_px;
const uint8_t * bitmap; const uint8_t * glyph_bitmap;
const uint32_t * map; const lv_font_glyph_dsc_t * glyph_dsc;
const uint8_t * width; const uint32_t * unicode_list;
const uint8_t * (*get_bitmap)(const struct _lv_font_struct *,uint32_t); /*Get a glyph's bitmap from a font*/
int16_t (*get_width)(const struct _lv_font_struct *,uint32_t); /*Get a glyph's with with a given font*/
struct _lv_font_struct * next_page; /*Pointer to a font extension*/ struct _lv_font_struct * next_page; /*Pointer to a font extension*/
}lv_font_t; uint32_t bpp :4; /*Bit per pixel: 1, 2 or 4*/
} lv_font_t;
/********************** /**********************
* GLOBAL PROTOTYPES * GLOBAL PROTOTYPES
@ -71,20 +86,9 @@ const uint8_t * lv_font_get_bitmap(const lv_font_t * font_p, uint32_t letter);
*/ */
static inline uint8_t lv_font_get_height(const lv_font_t * font_p) static inline uint8_t lv_font_get_height(const lv_font_t * font_p)
{ {
return font_p->height_row; return font_p->h_px;
} }
/**
* 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 * Get the width of a letter in a font
* @param font_p pointer to a font * @param font_p pointer to a font
@ -94,78 +98,125 @@ static inline uint8_t lv_font_get_height_scale(const lv_font_t * font_p)
uint8_t lv_font_get_width(const lv_font_t * font_p, uint32_t 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) * Get the bit-per-pixel of font
* @param font_p pointer to a font * @param font pointer to font
* @param letter a letter * @param letter a letter from font (font extensions can have different bpp)
* @return the width of a letter * @return bpp of the font (or font extension)
*/ */
static inline uint8_t lv_font_get_width_scale(const lv_font_t * font_p, uint32_t letter) uint8_t lv_font_get_bpp(const lv_font_t * font, uint32_t letter);
{
return (lv_font_get_width(font_p, letter) >> LV_FONT_ANTIALIAS) >> LV_ANTIALIAS; /**
} * Generic bitmap get function used in 'font->get_bitmap' when the font contains all characters in the range
* @param font pointer to font
* @param unicode_letter an unicode letter which bitmap should be get
* @return pointer to the bitmap or NULL if not found
*/
const uint8_t * lv_font_get_bitmap_continuous(const lv_font_t * font, uint32_t unicode_letter);
/**
* Generic bitmap get function used in 'font->get_bitmap' when the font NOT contains all characters in the range (sparse)
* @param font pointer to font
* @param unicode_letter an unicode letter which bitmap should be get
* @return pointer to the bitmap or NULL if not found
*/
const uint8_t * lv_font_get_bitmap_sparse(const lv_font_t * font, uint32_t unicode_letter);
/**
* Generic glyph width get function used in 'font->get_width' when the font contains all characters in the range
* @param font pointer to font
* @param unicode_letter an unicode letter which width should be get
* @return width of the gylph or -1 if not found
*/
int16_t lv_font_get_width_continuous(const lv_font_t * font, uint32_t unicode_letter);
/**
* Generic glyph width get function used in 'font->get_bitmap' when the font NOT contains all characters in the range (sparse)
* @param font pointer to font
* @param unicode_letter an unicode letter which width should be get
* @return width of the glyph or -1 if not found
*/
int16_t lv_font_get_width_sparse(const lv_font_t * font, uint32_t unicode_letter);
/********************** /**********************
* MACROS * MACROS
**********************/ **********************/
#define LV_FONT_DECLARE(font_name) extern lv_font_t font_name;
/*********************** /**********************
* POST INCLUDES * FONT DECLARATION
***********************/ **********************/
/*Add built-in fonts*/
#include "lv_fonts/dejavu_10.h" /*10 px */
#include "lv_fonts/dejavu_10_sup.h" #if USE_LV_FONT_DEJAVU_10
#include "lv_fonts/dejavu_10_latin_ext_a.h" LV_FONT_DECLARE(lv_font_dejavu_10);
#include "lv_fonts/dejavu_10_latin_ext_b.h" #endif
#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" #if USE_LV_FONT_DEJAVU_10_LATIN_SUP
#include "lv_fonts/dejavu_20_sup.h" LV_FONT_DECLARE(lv_font_dejavu_10_latin_sup);
#include "lv_fonts/dejavu_20_latin_ext_a.h" #endif
#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" #if USE_LV_FONT_DEJAVU_10_CYRILLIC
#include "lv_fonts/dejavu_30_sup.h" LV_FONT_DECLARE(lv_font_dejavu_10_cyrillic);
#include "lv_fonts/dejavu_30_latin_ext_a.h" #endif
#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" #if USE_LV_FONT_SYMBOL_10
#include "lv_fonts/dejavu_40_sup.h" LV_FONT_DECLARE(lv_font_symbol_10);
#include "lv_fonts/dejavu_40_latin_ext_a.h" #endif
#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" /*20 px */
#include "lv_fonts/dejavu_60_sup.h" #if USE_LV_FONT_DEJAVU_20
#include "lv_fonts/dejavu_60_latin_ext_a.h" LV_FONT_DECLARE(lv_font_dejavu_20);
#include "lv_fonts/dejavu_60_latin_ext_b.h" #endif
#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" #if USE_LV_FONT_DEJAVU_20_LATIN_SUP
#include "lv_fonts/dejavu_80_sup.h" LV_FONT_DECLARE(lv_font_dejavu_20_latin_sup);
#include "lv_fonts/dejavu_80_latin_ext_a.h" #endif
#include "lv_fonts/dejavu_80_latin_ext_b.h"
#include "lv_fonts/dejavu_80_cyrillic.h" #if USE_LV_FONT_DEJAVU_20_CYRILLIC
#include "lv_fonts/symbol_80_basic.h" LV_FONT_DECLARE(lv_font_dejavu_20_cyrillic);
#include "lv_fonts/symbol_80_file.h" #endif
#include "lv_fonts/symbol_80_feedback.h"
#if USE_LV_FONT_SYMBOL_20
LV_FONT_DECLARE(lv_font_symbol_20);
#endif
/*30 px */
#if USE_LV_FONT_DEJAVU_30
LV_FONT_DECLARE(lv_font_dejavu_30);
#endif
#if USE_LV_FONT_DEJAVU_30_LATIN_SUP
LV_FONT_DECLARE(lv_font_dejavu_30_latin_sup);
#endif
#if USE_LV_FONT_DEJAVU_30_CYRILLIC
LV_FONT_DECLARE(lv_font_dejavu_30_cyrillic);
#endif
#if USE_LV_FONT_SYMBOL_30
LV_FONT_DECLARE(lv_font_symbol_30);
#endif
/*40 px */
#if USE_LV_FONT_DEJAVU_40
LV_FONT_DECLARE(lv_font_dejavu_40);
#endif
#if USE_LV_FONT_DEJAVU_40_LATIN_SUP
LV_FONT_DECLARE(lv_font_dejavu_40_latin_sup);
#endif
#if USE_LV_FONT_DEJAVU_40_CYRILLIC
LV_FONT_DECLARE(lv_font_dejavu_40_cyrillic);
#endif
#if USE_LV_FONT_SYMBOL_40
LV_FONT_DECLARE(lv_font_symbol_40);
#endif
/*Declare the custom (user defined) fonts*/
#ifdef LV_FONT_CUSTOM_DECLARE
LV_FONT_CUSTOM_DECLARE
#endif
#ifdef __cplusplus #ifdef __cplusplus
} /* extern "C" */ } /* extern "C" */

File diff suppressed because it is too large Load Diff

View File

@ -1,15 +0,0 @@
#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

@ -1,15 +0,0 @@
#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

@ -1,15 +0,0 @@
#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

@ -1,15 +0,0 @@
#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

@ -1,15 +0,0 @@
#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

@ -1,15 +0,0 @@
#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

@ -1,15 +0,0 @@
#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

@ -1,15 +0,0 @@
#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

@ -1,15 +0,0 @@
#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

@ -1,15 +0,0 @@
#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

@ -1,15 +0,0 @@
#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

@ -1,15 +0,0 @@
#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

@ -1,15 +0,0 @@
#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

@ -1,15 +0,0 @@
#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

@ -1,15 +0,0 @@
#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

@ -1,15 +0,0 @@
#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

@ -1,15 +0,0 @@
#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

@ -1,15 +0,0 @@
#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

@ -1,15 +0,0 @@
#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

@ -1,15 +0,0 @@
#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

@ -1,15 +0,0 @@
#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

@ -1,15 +0,0 @@
#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

@ -1,15 +0,0 @@
#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

@ -1,15 +0,0 @@
#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

@ -1,15 +0,0 @@
#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

@ -1,15 +0,0 @@
#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*/

File diff suppressed because it is too large Load Diff

View File

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

File diff suppressed because it is too large Load Diff

View File

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

File diff suppressed because it is too large Load Diff

View File

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

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