mirror of
https://github.com/lvgl/lvgl.git
synced 2025-01-14 06:42:58 +08:00
Merge branch 'master' into feat/test-unity
This commit is contained in:
commit
ad04307d3f
1
.gitignore
vendored
1
.gitignore
vendored
@ -10,6 +10,7 @@ scripts/cppcheck_res.txt
|
||||
scripts/built_in_font/lv_font_*
|
||||
docs/doxygen_html
|
||||
docs/xml
|
||||
docs/examples.md
|
||||
docs/out_latex
|
||||
docs/_static/built_lv_examples
|
||||
docs/LVGL.pdf
|
||||
|
2
Kconfig
2
Kconfig
@ -166,7 +166,7 @@ menu "LVGL configuration"
|
||||
1: Add default bare metal and FreeRTOS interrupt handling
|
||||
routines for PXP (lv_gpu_nxp_pxp_osa.c) and call
|
||||
lv_gpu_nxp_pxp_init() automatically during lv_init().
|
||||
Note that symbol FSL_RTOS_FREE_RTOS has to be defined in order
|
||||
Note that symbol SDK_OS_FREE_RTOS has to be defined in order
|
||||
to use FreeRTOS OSA, otherwise bare-metal implementation is
|
||||
selected.
|
||||
0: lv_gpu_nxp_pxp_init() has to be called manually before
|
||||
|
@ -1,5 +1,5 @@
|
||||
MIT licence
|
||||
Copyright (c) 2020 LVGL LLC
|
||||
Copyright (c) 2021 LVGL Kft
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
|
12
README.md
12
README.md
@ -115,14 +115,14 @@ LVGL is also avaiable as:
|
||||
This list shows the recommended way of learning the library:
|
||||
1. Check the [Online demos](https://lvgl.io/demos) to see LVGL in action (3 minutes)
|
||||
2. Read the [Introduction](https://docs.lvgl.io/master/intro/index.html) page of the documentation (5 minutes)
|
||||
3. Get familiar with the basics on the [Quick overview](https://docs.lvgl.io/master/html/get-started/quick-overview.html) page (15 minutes)
|
||||
4. Set up a [Simulator](https://docs.lvgl.io/latest/master/get-started/pc-simulator.html) (10 minutes)
|
||||
3. Get familiar with the basics on the [Quick overview](https://docs.lvgl.io/master/get-started/quick-overview.html) page (15 minutes)
|
||||
4. Set up a [Simulator](https://docs.lvgl.io/master/get-started/pc-simulator.html) (10 minutes)
|
||||
5. Try out some [Examples](https://github.com/lvgl/lvgl/tree/master/examples)
|
||||
6. Port LVGL to a board. See the [Porting](https://docs.lvgl.io/master/porting/index.html) guide or check the ready to use [Projects](https://github.com/lvgl?q=lv_port_&type=&language=)
|
||||
6. Port LVGL to a board. See the [Porting](https://docs.lvgl.io/master/porting/index.html) guide or check the ready to use [Projects](https://github.com/lvgl?q=lv_port_)
|
||||
7. Read the [Overview](https://docs.lvgl.io/master/overview/index.html) page to get a better understanding of the library (2-3 hours)
|
||||
8. Check the documentation of the [Widgets](https://docs.lvgl.io/master/html/widgets/index.html) to see their features and usage
|
||||
8. Check the documentation of the [Widgets](https://docs.lvgl.io/master/widgets/index.html) to see their features and usage
|
||||
9. If you have questions go to the [Forum](http://forum.lvgl.io/)
|
||||
10. Read the [Contributing](https://docs.lvgl.io/master/contributing/index.html) guide to see how you can help to improve LVGL (15 minutes)
|
||||
10. Read the [Contributing](https://docs.lvgl.io/master/CONTRIBUTING.html) guide to see how you can help to improve LVGL (15 minutes)
|
||||
|
||||
## Examples
|
||||
|
||||
@ -177,5 +177,5 @@ Feel free to contact us if you have any questions.
|
||||
## Contributing
|
||||
LVGL is an open project and contribution is very welcome. There are many ways to contribute from simply speaking about your project, through writing examples, improving the documentation, fixing bugs to hosing your own project under the LVGL organization.
|
||||
|
||||
For a detailed description of contribution opportunities visit the [Contributing](https://docs.lvgl.io/master/CONTRIBUTING.htmll) section of the documentation.
|
||||
For a detailed description of contribution opportunities visit the [Contributing](https://docs.lvgl.io/master/CONTRIBUTING.html) section of the documentation.
|
||||
|
||||
|
@ -16,7 +16,8 @@ class LvExample(Directive):
|
||||
required_arguments = 1
|
||||
option_spec = {
|
||||
'excluded_languages': excluded_list,
|
||||
'language': directives.unchanged
|
||||
'language': directives.unchanged,
|
||||
'description': directives.unchanged
|
||||
}
|
||||
def get_example_code_path(self, example_path, language):
|
||||
return os.path.abspath("../examples/" + example_path + "." + language)
|
||||
@ -27,8 +28,10 @@ class LvExample(Directive):
|
||||
return 'C'
|
||||
else:
|
||||
return language
|
||||
def embed_code(self, example_file, example_path, language):
|
||||
def github_path(self, example_path, language):
|
||||
env = self.state.document.settings.env
|
||||
return f"https://github.com/lvgl/lvgl/blob/{env.config.repo_commit_hash}/examples/{example_path}.{language}"
|
||||
def embed_code(self, example_file, example_path, language, buttons={}):
|
||||
toggle = nodes.container('', literal_block=False, classes=['toggle'])
|
||||
header = nodes.container('', literal_block=False, classes=['header'])
|
||||
toggle.append(header)
|
||||
@ -40,7 +43,10 @@ class LvExample(Directive):
|
||||
literal_list = nodes.literal_block(contents, contents)
|
||||
literal_list['language'] = language
|
||||
toggle.append(literal_list)
|
||||
header.append(nodes.raw(text=f"<p>{self.human_language_name(language)} code <a onclick=\"event.stopPropagation();\" class='fa fa-github' href='https://github.com/lvgl/lvgl/blob/{env.config.repo_commit_hash}/examples/{example_path}.{language}'> view on GitHub</a></p>", format='html'))
|
||||
paragraph_node = nodes.raw(text=f"<p>{self.human_language_name(language)} code </p>", format='html')
|
||||
for text, url in buttons.items():
|
||||
paragraph_node.append(nodes.raw(text=f"<a class='lv-example-link-button' onclick=\"event.stopPropagation();\" href='{url}'>{text}</a>", format='html'))
|
||||
header.append(paragraph_node)
|
||||
return toggle
|
||||
def run(self):
|
||||
example_path = self.arguments[0]
|
||||
@ -50,20 +56,27 @@ class LvExample(Directive):
|
||||
|
||||
env = self.state.document.settings.env
|
||||
|
||||
iframe_node = nodes.raw(text=f"<iframe loading='lazy' class='lv-example' src='/{env.config.version}/_static/built_lv_examples?example={example_name}&w=320&h=240'></iframe>", format='html')
|
||||
micropython_node = nodes.raw(text=f"<a style='display: inline-block; margin-bottom: 1rem;' target='_blank' href='https://sim.lvgl.io/v{env.config.version}/micropython/ports/javascript/index.html?script_startup=https://raw.githubusercontent.com/lvgl/lvgl/{env.config.repo_commit_hash}/examples/header.py&script=https://raw.githubusercontent.com/lvgl/lvgl/{env.config.repo_commit_hash}/examples/{example_path}.py'>Click to try in the MicroPython simulator!</a>", format='html')
|
||||
|
||||
iframe_html = ""
|
||||
|
||||
c_path = self.get_example_code_path(example_path, 'c')
|
||||
py_path = self.get_example_code_path(example_path, 'py')
|
||||
|
||||
c_code = self.embed_code(c_path, example_path, 'c')
|
||||
py_code = self.embed_code(py_path, example_path, 'py')
|
||||
c_code = self.embed_code(c_path, example_path, 'c', buttons={
|
||||
'<i class="fa fa-github"></i> GitHub': self.github_path(example_path, 'c')
|
||||
})
|
||||
py_code = self.embed_code(py_path, example_path, 'py', buttons={
|
||||
'<i class="fa fa-github"></i> GitHub': self.github_path(example_path, 'py'),
|
||||
'<i class="fa fa-play"></i> Simulator': f"https://sim.lvgl.io/v{env.config.version}/micropython/ports/javascript/index.html?script_startup=https://raw.githubusercontent.com/lvgl/lvgl/{env.config.repo_commit_hash}/examples/header.py&script=https://raw.githubusercontent.com/lvgl/lvgl/{env.config.repo_commit_hash}/examples/{example_path}.py"
|
||||
})
|
||||
|
||||
if not 'c' in excluded_languages:
|
||||
if env.app.tags.has('html'):
|
||||
node_list.append(iframe_node)
|
||||
if not 'py' in excluded_languages:
|
||||
node_list.append(micropython_node)
|
||||
iframe_html = f"<div class='lv-example' data-real-src='/{env.config.version}/_static/built_lv_examples?example={example_name}&w=320&h=240'></div>"
|
||||
|
||||
description_html = f"<div class='lv-example-description'>{self.options.get('description', '')}</div>"
|
||||
layout_node = nodes.raw(text=f"<div class='lv-example-container'>{iframe_html}{description_html}</div>", format='html')
|
||||
|
||||
node_list.append(layout_node)
|
||||
if not 'c' in excluded_languages:
|
||||
node_list.append(c_code)
|
||||
if not 'py' in excluded_languages:
|
||||
|
36
docs/_static/css/custom.css
vendored
36
docs/_static/css/custom.css
vendored
@ -19,7 +19,7 @@ span.pre:first-child
|
||||
|
||||
code.sig-name
|
||||
{
|
||||
//margin-left:8px;
|
||||
/*margin-left:8px;*/
|
||||
}
|
||||
|
||||
.toggle .header {
|
||||
@ -64,11 +64,43 @@ code.sig-name
|
||||
transform: translate(0, -10px);
|
||||
}
|
||||
|
||||
.lv-example {
|
||||
.lv-example, .lv-example > iframe {
|
||||
border: none;
|
||||
outline: none;
|
||||
padding: none;
|
||||
display: block;
|
||||
width: 320px;
|
||||
height: 240px;
|
||||
flex: none;
|
||||
position: relative;
|
||||
}
|
||||
.lv-example > iframe {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.lv-example-container {
|
||||
display: flex;
|
||||
}
|
||||
.lv-example-description {
|
||||
flex: 1 1 auto;
|
||||
margin-left: 1rem;
|
||||
}
|
||||
|
||||
.lv-example-link-button {
|
||||
display: inline-block;
|
||||
padding: 4px 8px;
|
||||
border-radius: 4px;
|
||||
background-color: #2980b9;
|
||||
color: white;
|
||||
margin: 0 4px;
|
||||
}
|
||||
.lv-example-link-button:hover {
|
||||
color: white;
|
||||
filter: brightness(120%);
|
||||
}
|
||||
|
||||
.lv-example-link-button:visited {
|
||||
color: white;
|
||||
}
|
||||
|
27
docs/_templates/page.html
vendored
27
docs/_templates/page.html
vendored
@ -51,5 +51,32 @@ document.addEventListener('DOMContentLoaded', (event) => {
|
||||
});
|
||||
|
||||
})
|
||||
document.addEventListener('DOMContentLoaded', (event) => {
|
||||
function onIntersection(entries) {
|
||||
entries.forEach(entry => {
|
||||
let currentlyLoaded = entry.target.getAttribute("data-is-loaded") == "true";
|
||||
let shouldBeLoaded = entry.intersectionRatio > 0;
|
||||
if(currentlyLoaded != shouldBeLoaded) {
|
||||
entry.target.setAttribute("data-is-loaded", shouldBeLoaded);
|
||||
if(shouldBeLoaded) {
|
||||
let iframe = document.createElement("iframe");
|
||||
iframe.src = entry.target.getAttribute("data-real-src");
|
||||
entry.target.appendChild(iframe);
|
||||
} else {
|
||||
let iframe = entry.target.querySelector("iframe");
|
||||
iframe.parentNode.removeChild(iframe);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
const config = {
|
||||
rootMargin: '600px 0px',
|
||||
threshold: 0.01
|
||||
};
|
||||
let observer = new IntersectionObserver(onIntersection, config);
|
||||
document.querySelectorAll(".lv-example").forEach(iframe => {
|
||||
observer.observe(iframe);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
@ -1,5 +1,7 @@
|
||||
#!/usr/bin/env python3
|
||||
import os
|
||||
|
||||
|
||||
|
||||
def process_index_rst(path):
|
||||
# print(path)
|
||||
with open(path) as fp:
|
||||
@ -73,10 +75,11 @@ layouts = {
|
||||
def print_item(path, lvl, d, fout):
|
||||
for k in d:
|
||||
v = d[k]
|
||||
b = os.path.basename(k)
|
||||
if k.startswith(path + "/lv_example_"):
|
||||
fout.write("#"*lvl + " " + v + "\n")
|
||||
fout.write('<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=' + b +'&w=320&h=240"></iframe>\n')
|
||||
fout.write('```eval_rst\n')
|
||||
fout.write(f".. lv_example:: {k}\n")
|
||||
fout.write('```\n')
|
||||
fout.write("\n")
|
||||
|
||||
def exec():
|
||||
|
364
docs/examples.md
364
docs/examples.md
@ -1,364 +0,0 @@
|
||||
```eval_rst
|
||||
.. include:: /header.rst
|
||||
:github_url: |github_link_base|/examples.md
|
||||
```
|
||||
|
||||
# Examples
|
||||
## Get started
|
||||
### A button with a label and react on click event
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_get_started_1&w=320&h=240"></iframe>
|
||||
|
||||
### Create styles from scratch for buttons
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_get_started_2&w=320&h=240"></iframe>
|
||||
|
||||
### Create a slider and write its value on a label
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_get_started_3&w=320&h=240"></iframe>
|
||||
|
||||
## Styles
|
||||
### Size styles
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_style_1&w=320&h=240"></iframe>
|
||||
|
||||
### Background styles
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_style_2&w=320&h=240"></iframe>
|
||||
|
||||
### Border styles
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_style_3&w=320&h=240"></iframe>
|
||||
|
||||
### Outline styles
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_style_4&w=320&h=240"></iframe>
|
||||
|
||||
### Shadow styles
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_style_5&w=320&h=240"></iframe>
|
||||
|
||||
### Image styles
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_style_6&w=320&h=240"></iframe>
|
||||
|
||||
### Text styles
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_style_8&w=320&h=240"></iframe>
|
||||
|
||||
### Line styles
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_style_9&w=320&h=240"></iframe>
|
||||
|
||||
### Transition
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_style_10&w=320&h=240"></iframe>
|
||||
|
||||
### Using multiple styles
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_style_11&w=320&h=240"></iframe>
|
||||
|
||||
### Local styles
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_style_12&w=320&h=240"></iframe>
|
||||
|
||||
### Add styles to parts and states
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_style_13&w=320&h=240"></iframe>
|
||||
|
||||
### Extending the current theme
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_style_14&w=320&h=240"></iframe>
|
||||
|
||||
## Animations
|
||||
### Start animation on an event
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_anim_1&w=320&h=240"></iframe>
|
||||
|
||||
### Playback animation
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_anim_2&w=320&h=240"></iframe>
|
||||
|
||||
## Events
|
||||
### Button click event
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_event_1&w=320&h=240"></iframe>
|
||||
|
||||
### Handle multiple events
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_event_2&w=320&h=240"></iframe>
|
||||
|
||||
### Event bubbling
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_event_3&w=320&h=240"></iframe>
|
||||
|
||||
## Layouts
|
||||
### Flex
|
||||
#### A simple row and a column layout with flexbox
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_flex_1&w=320&h=240"></iframe>
|
||||
|
||||
#### Arrange items in rows with wrap and even spacing
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_flex_2&w=320&h=240"></iframe>
|
||||
|
||||
#### Demonstrate flex grow
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_flex_3&w=320&h=240"></iframe>
|
||||
|
||||
#### Demonstrate flex grow.
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_flex_4&w=320&h=240"></iframe>
|
||||
|
||||
#### Demonstrate column and row gap style properties
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_flex_5&w=320&h=240"></iframe>
|
||||
|
||||
#### RTL base direction changes order of the items
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_flex_6&w=320&h=240"></iframe>
|
||||
|
||||
### Grid
|
||||
#### A simple grid
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_grid_1&w=320&h=240"></iframe>
|
||||
|
||||
#### Demonstrate cell placement and span
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_grid_2&w=320&h=240"></iframe>
|
||||
|
||||
#### Demonstrate grid's "free unit"
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_grid_3&w=320&h=240"></iframe>
|
||||
|
||||
#### Demonstrate track placement
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_grid_4&w=320&h=240"></iframe>
|
||||
|
||||
#### Demonstrate column and row gap
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_grid_5&w=320&h=240"></iframe>
|
||||
|
||||
#### Demonstrate RTL direction on grid
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_grid_6&w=320&h=240"></iframe>
|
||||
|
||||
## Scrolling
|
||||
### Nested scrolling
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_scroll_1&w=320&h=240"></iframe>
|
||||
|
||||
### Snapping
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_scroll_2&w=320&h=240"></iframe>
|
||||
|
||||
### Floating button
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_scroll_3&w=320&h=240"></iframe>
|
||||
|
||||
### Styling the scrollbars
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_scroll_4&w=320&h=240"></iframe>
|
||||
|
||||
### Right to left scrolling
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_scroll_5&w=320&h=240"></iframe>
|
||||
|
||||
### Translate on scroll
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_scroll_6&w=320&h=240"></iframe>
|
||||
|
||||
## Widgets
|
||||
### Base object
|
||||
#### Base objects with custom styles
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_obj_1&w=320&h=240"></iframe>
|
||||
|
||||
#### Make an object draggable
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_obj_2&w=320&h=240"></iframe>
|
||||
|
||||
### Arc
|
||||
#### Simple Arc
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_arc_1&w=320&h=240"></iframe>
|
||||
|
||||
#### Loader with Arc
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_arc_2&w=320&h=240"></iframe>
|
||||
|
||||
### Bar
|
||||
#### Simple Bar
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_bar_1&w=320&h=240"></iframe>
|
||||
|
||||
#### Styling a bar
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_bar_2&w=320&h=240"></iframe>
|
||||
|
||||
#### Temperature meter
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_bar_3&w=320&h=240"></iframe>
|
||||
|
||||
#### Stripe pattern and range value
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_bar_4&w=320&h=240"></iframe>
|
||||
|
||||
#### Bar with RTL and RTL base direction
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_bar_5&w=320&h=240"></iframe>
|
||||
|
||||
#### Custom drawr to show the current value
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_bar_6&w=320&h=240"></iframe>
|
||||
|
||||
### Button
|
||||
#### Simple Buttons
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_btn_1&w=320&h=240"></iframe>
|
||||
|
||||
#### Styling buttons
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_btn_2&w=320&h=240"></iframe>
|
||||
|
||||
#### Gummy button
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_btn_3&w=320&h=240"></iframe>
|
||||
|
||||
### Button matrix
|
||||
#### Simple Button matrix
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_btnmatrix_1&w=320&h=240"></iframe>
|
||||
|
||||
#### Custom buttons
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_btnmatrix_2&w=320&h=240"></iframe>
|
||||
|
||||
#### Pagination
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_btnmatrix_3&w=320&h=240"></iframe>
|
||||
|
||||
### Calendar
|
||||
#### Calendar with header
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_calendar_1&w=320&h=240"></iframe>
|
||||
|
||||
### Canvas
|
||||
#### Drawing on the Canvas and rotate
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_canvas_1&w=320&h=240"></iframe>
|
||||
|
||||
#### Transparent Canvas with chroma keying
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_canvas_2&w=320&h=240"></iframe>
|
||||
|
||||
### Chart
|
||||
#### Line Chart
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_chart_1&w=320&h=240"></iframe>
|
||||
|
||||
#### Faded area line chart with custom division lines
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_chart_2&w=320&h=240"></iframe>
|
||||
|
||||
#### Axis ticks and labels with scrolling
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_chart_3&w=320&h=240"></iframe>
|
||||
|
||||
#### Show the value of the pressed points
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_chart_4&w=320&h=240"></iframe>
|
||||
|
||||
#### Display 1000 data points with zooming and scrolling
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_chart_5&w=320&h=240"></iframe>
|
||||
|
||||
#### Show cursor on the clicked point
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_chart_6&w=320&h=240"></iframe>
|
||||
|
||||
#### Scatter chart
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_chart_7&w=320&h=240"></iframe>
|
||||
|
||||
### Checkbox
|
||||
#### Simple Checkboxes
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_checkbox_1&w=320&h=240"></iframe>
|
||||
|
||||
### Colorwheel
|
||||
#### Simple Colorwheel
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_colorwheel_1&w=320&h=240"></iframe>
|
||||
|
||||
### Dropdown
|
||||
#### Simple Drop down list
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_dropdown_1&w=320&h=240"></iframe>
|
||||
|
||||
#### Drop down in four directions
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_dropdown_2&w=320&h=240"></iframe>
|
||||
|
||||
#### Menu
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_dropdown_3&w=320&h=240"></iframe>
|
||||
|
||||
### Image
|
||||
#### Image from variable and symbol
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_img_1&w=320&h=240"></iframe>
|
||||
|
||||
#### Image recoloring
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_img_2&w=320&h=240"></iframe>
|
||||
|
||||
#### Rotate and zoom
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_img_3&w=320&h=240"></iframe>
|
||||
|
||||
#### Image offset and styling
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_img_4&w=320&h=240"></iframe>
|
||||
|
||||
### Image button
|
||||
#### Simple Image button
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_imgbtn_1&w=320&h=240"></iframe>
|
||||
|
||||
### Keyboard
|
||||
#### Keyboard with text area
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_keyboard_1&w=320&h=240"></iframe>
|
||||
|
||||
### Label
|
||||
#### Line wrap, recoloring and scrolling
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_label_1&w=320&h=240"></iframe>
|
||||
|
||||
#### Text shadow
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_label_2&w=320&h=240"></iframe>
|
||||
|
||||
#### Show LTR, RTL and Chinese texts
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_label_3&w=320&h=240"></iframe>
|
||||
|
||||
### LED
|
||||
#### LED with custom style
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_led_1&w=320&h=240"></iframe>
|
||||
|
||||
### Line
|
||||
#### Simple Line
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_line_1&w=320&h=240"></iframe>
|
||||
|
||||
### List
|
||||
#### Simple List
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_list_1&w=320&h=240"></iframe>
|
||||
|
||||
### Meter
|
||||
#### Simple meter
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_meter_1&w=320&h=240"></iframe>
|
||||
|
||||
#### A meter with multiple arcs
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_meter_2&w=320&h=240"></iframe>
|
||||
|
||||
#### A clock from a meter
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_meter_3&w=320&h=240"></iframe>
|
||||
|
||||
#### Pie chart
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_meter_4&w=320&h=240"></iframe>
|
||||
|
||||
### Message box
|
||||
#### Simple Message box
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_msgbox_1&w=320&h=240"></iframe>
|
||||
|
||||
### Roller
|
||||
#### Simple Roller
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_roller_1&w=320&h=240"></iframe>
|
||||
|
||||
#### Styling the roller
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_roller_2&w=320&h=240"></iframe>
|
||||
|
||||
#### add fade mask to roller
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_roller_3&w=320&h=240"></iframe>
|
||||
|
||||
### Slider
|
||||
#### Simple Slider
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_slider_1&w=320&h=240"></iframe>
|
||||
|
||||
#### Slider with custom style
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_slider_2&w=320&h=240"></iframe>
|
||||
|
||||
#### Slider with extended drawer
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_slider_3&w=320&h=240"></iframe>
|
||||
|
||||
### Span
|
||||
#### Span with custom styles
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_span_1&w=320&h=240"></iframe>
|
||||
|
||||
### Spinbox
|
||||
#### Simple Spinbox
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_spinbox_1&w=320&h=240"></iframe>
|
||||
|
||||
### Spinner
|
||||
#### Simple spinner
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_spinner_1&w=320&h=240"></iframe>
|
||||
|
||||
### Switch
|
||||
#### Simple Switch
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_switch_1&w=320&h=240"></iframe>
|
||||
|
||||
### Table
|
||||
#### Simple table
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_table_1&w=320&h=240"></iframe>
|
||||
|
||||
#### Lightweighted list from table
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_table_2&w=320&h=240"></iframe>
|
||||
|
||||
### Tabview
|
||||
#### Simple Tabview
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_tabview_1&w=320&h=240"></iframe>
|
||||
|
||||
#### Tabs on the left, styling and no scrolling
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_tabview_2&w=320&h=240"></iframe>
|
||||
|
||||
### Textarea
|
||||
#### Simple Text area
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_textarea_1&w=320&h=240"></iframe>
|
||||
|
||||
#### Text area with password field
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_textarea_2&w=320&h=240"></iframe>
|
||||
|
||||
#### Text auto-formatting
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_textarea_3&w=320&h=240"></iframe>
|
||||
|
||||
### Tabview
|
||||
#### Tileview with content
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_tileview_1&w=320&h=240"></iframe>
|
||||
|
||||
### Window
|
||||
#### Simple window
|
||||
<iframe loading="lazy" class="lv-example" src="_static/built_lv_examples?example=lv_example_win_1&w=320&h=240"></iframe>
|
||||
|
@ -20,6 +20,8 @@ The parts of the Spinbox are identical to the [Text area](/widgets/core/textarea
|
||||
|
||||
`lv_spinbox_set_step(spinbox, 100)` sets which digits to change on increment/decrement. Only multiples of ten can be set, and not for example 3.
|
||||
|
||||
`lv_spinbox_set_pos(spinbox, 1)` sets the cursor to a specific digit to change on increment/decrement. For example position '0' sets the cursor to the least significant digit.
|
||||
|
||||
### Format
|
||||
|
||||
`lv_spinbox_set_digit_format(spinbox, digit_count, separator_position)` sets the number format. `digit_count` is the number of digits excluding the decimal separator and the sign.
|
||||
|
@ -4,6 +4,7 @@ Simple Arc
|
||||
|
||||
.. lv_example:: widgets/arc/lv_example_arc_1
|
||||
:language: c
|
||||
:description: A simple example to demonstrate the use of an arc.
|
||||
|
||||
Loader with Arc
|
||||
""""""""""""""""
|
||||
|
@ -39,5 +39,5 @@ img.header.cf = lv.img.CF.TRUE_COLOR
|
||||
img.header.w = _CANVAS_WIDTH
|
||||
img.header.h = _CANVAS_HEIGHT
|
||||
|
||||
canvas.fill_bg(lv_palette_lighten(LV_PALETTE_GREY, 3), LV_OPA_COVER)
|
||||
canvas.fill_bg(lv.palette_lighten(lv.PALETTE.GREY, 3), lv.OPA.COVER)
|
||||
canvas.transform(img, 30, LV_IMG_ZOOM_NONE, 0, 0, _CANVAS_WIDTH // 2, _CANVAS_HEIGHT // 2, True);
|
||||
|
@ -122,7 +122,7 @@ e.g. "stm32f769xx.h" or "stm32f429xx.h"*/
|
||||
#define LV_USE_GPU_NXP_PXP 0
|
||||
#if LV_USE_GPU_NXP_PXP
|
||||
/*1: Add default bare metal and FreeRTOS interrupt handling routines for PXP (lv_gpu_nxp_pxp_osa.c)
|
||||
* and call lv_gpu_nxp_pxp_init() automatically during lv_init(). Note that symbol FSL_RTOS_FREE_RTOS
|
||||
* and call lv_gpu_nxp_pxp_init() automatically during lv_init(). Note that symbol SDK_OS_FREE_RTOS
|
||||
* has to be defined in order to use FreeRTOS OSA, otherwise bare-metal implementation is selected.
|
||||
*0: lv_gpu_nxp_pxp_init() has to be called manually before lv_init()
|
||||
*/
|
||||
|
@ -30,6 +30,11 @@
|
||||
#include "../gpu/lv_gpu_stm32_dma2d.h"
|
||||
#endif
|
||||
|
||||
#if LV_USE_GPU_NXP_PXP && LV_USE_GPU_NXP_PXP_AUTO_INIT
|
||||
#include "../gpu/lv_gpu_nxp_pxp.h"
|
||||
#include "../gpu/lv_gpu_nxp_pxp_osa.h"
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
@ -105,6 +110,13 @@ void lv_init(void)
|
||||
lv_gpu_stm32_dma2d_init();
|
||||
#endif
|
||||
|
||||
#if LV_USE_GPU_NXP_PXP && LV_USE_GPU_NXP_PXP_AUTO_INIT
|
||||
if(lv_gpu_nxp_pxp_init(&pxp_default_cfg) != LV_RES_OK) {
|
||||
LV_LOG_ERROR("PXP init error. STOP.\n");
|
||||
for(; ;) ;
|
||||
}
|
||||
#endif
|
||||
|
||||
_lv_obj_style_init();
|
||||
_lv_ll_init(&LV_GC_ROOT(_lv_disp_ll), sizeof(lv_disp_t));
|
||||
_lv_ll_init(&LV_GC_ROOT(_lv_indev_ll), sizeof(lv_indev_t));
|
||||
@ -472,8 +484,18 @@ static void lv_obj_draw(lv_event_t * e)
|
||||
coords.y1 -= h;
|
||||
coords.y2 += h;
|
||||
|
||||
|
||||
lv_obj_draw_part_dsc_t part_dsc;
|
||||
lv_obj_draw_dsc_init(&part_dsc, clip_area);
|
||||
part_dsc.rect_dsc = &draw_dsc;
|
||||
part_dsc.draw_area = &coords;
|
||||
part_dsc.part = LV_PART_MAIN;
|
||||
lv_event_send(obj, LV_EVENT_DRAW_PART_BEGIN, &part_dsc);
|
||||
|
||||
lv_draw_rect(&coords, clip_area, &draw_dsc);
|
||||
|
||||
lv_event_send(obj, LV_EVENT_DRAW_PART_END, &part_dsc);
|
||||
|
||||
#if LV_DRAW_COMPLEX
|
||||
if(lv_obj_get_style_clip_corner(obj, LV_PART_MAIN)) {
|
||||
lv_draw_mask_radius_param_t * mp = lv_mem_buf_get(sizeof(lv_draw_mask_radius_param_t));
|
||||
@ -530,8 +552,23 @@ static void draw_scrollbar(lv_obj_t * obj, const lv_area_t * clip_area)
|
||||
lv_res_t sb_res = scrollbar_init_draw_dsc(obj, &draw_dsc);
|
||||
if(sb_res != LV_RES_OK) return;
|
||||
|
||||
if(lv_area_get_size(&hor_area) > 0) lv_draw_rect(&hor_area, clip_area, &draw_dsc);
|
||||
if(lv_area_get_size(&ver_area) > 0) lv_draw_rect(&ver_area, clip_area, &draw_dsc);
|
||||
lv_obj_draw_part_dsc_t part_dsc;
|
||||
lv_obj_draw_dsc_init(&part_dsc, clip_area);
|
||||
part_dsc.rect_dsc = &draw_dsc;
|
||||
part_dsc.part = LV_PART_SCROLLBAR;
|
||||
|
||||
if(lv_area_get_size(&hor_area) > 0) {
|
||||
part_dsc.draw_area = &hor_area;
|
||||
lv_event_send(obj, LV_EVENT_DRAW_PART_BEGIN, &part_dsc);
|
||||
lv_draw_rect(&hor_area, clip_area, &draw_dsc);
|
||||
lv_event_send(obj, LV_EVENT_DRAW_PART_END, &part_dsc);
|
||||
}
|
||||
if(lv_area_get_size(&ver_area) > 0) {
|
||||
part_dsc.draw_area = &ver_area;
|
||||
lv_event_send(obj, LV_EVENT_DRAW_PART_BEGIN, &part_dsc);
|
||||
lv_draw_rect(&ver_area, clip_area, &draw_dsc);
|
||||
lv_event_send(obj, LV_EVENT_DRAW_PART_END, &part_dsc);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -622,8 +659,12 @@ static void lv_obj_event(const lv_obj_class_t * class_p, lv_event_t * e)
|
||||
else if(c == LV_KEY_LEFT || c == LV_KEY_DOWN) {
|
||||
lv_obj_clear_state(obj, LV_STATE_CHECKED);
|
||||
}
|
||||
lv_res_t res = lv_event_send(obj, LV_EVENT_VALUE_CHANGED, NULL);
|
||||
if(res != LV_RES_OK) return;
|
||||
|
||||
/*With Enter LV_EVENT_RELEASED will send VALUE_CHANGE event*/
|
||||
if(c != LV_KEY_ENTER) {
|
||||
lv_res_t res = lv_event_send(obj, LV_EVENT_VALUE_CHANGED, NULL);
|
||||
if(res != LV_RES_OK) return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(code == LV_EVENT_FOCUSED) {
|
||||
|
@ -408,75 +408,75 @@ static void lv_refr_area(const lv_area_t * area_p)
|
||||
draw_buf->area.y2 = lv_disp_get_ver_res(disp_refr) - 1;
|
||||
disp_refr->driver->draw_buf->last_part = 1;
|
||||
lv_refr_area_part(area_p);
|
||||
return;
|
||||
}
|
||||
|
||||
/*Normal refresh: draw the area in parts*/
|
||||
else {
|
||||
lv_disp_draw_buf_t * draw_buf = lv_disp_get_draw_buf(disp_refr);
|
||||
/*Calculate the max row num*/
|
||||
lv_coord_t w = lv_area_get_width(area_p);
|
||||
lv_coord_t h = lv_area_get_height(area_p);
|
||||
lv_coord_t y2 =
|
||||
area_p->y2 >= lv_disp_get_ver_res(disp_refr) ? lv_disp_get_ver_res(disp_refr) - 1 : area_p->y2;
|
||||
lv_disp_draw_buf_t * draw_buf = lv_disp_get_draw_buf(disp_refr);
|
||||
/*Calculate the max row num*/
|
||||
lv_coord_t w = lv_area_get_width(area_p);
|
||||
lv_coord_t h = lv_area_get_height(area_p);
|
||||
lv_coord_t y2 = area_p->y2 >= lv_disp_get_ver_res(disp_refr) ?
|
||||
lv_disp_get_ver_res(disp_refr) - 1 : area_p->y2;
|
||||
|
||||
int32_t max_row = (uint32_t)draw_buf->size / w;
|
||||
int32_t max_row = (uint32_t)draw_buf->size / w;
|
||||
|
||||
if(max_row > h) max_row = h;
|
||||
if(max_row > h) max_row = h;
|
||||
|
||||
/*Round down the lines of draw_buf if rounding is added*/
|
||||
if(disp_refr->driver->rounder_cb) {
|
||||
lv_area_t tmp;
|
||||
tmp.x1 = 0;
|
||||
tmp.x2 = 0;
|
||||
tmp.y1 = 0;
|
||||
/*Round down the lines of draw_buf if rounding is added*/
|
||||
if(disp_refr->driver->rounder_cb) {
|
||||
lv_area_t tmp;
|
||||
tmp.x1 = 0;
|
||||
tmp.x2 = 0;
|
||||
tmp.y1 = 0;
|
||||
|
||||
lv_coord_t h_tmp = max_row;
|
||||
do {
|
||||
tmp.y2 = h_tmp - 1;
|
||||
disp_refr->driver->rounder_cb(disp_refr->driver, &tmp);
|
||||
lv_coord_t h_tmp = max_row;
|
||||
do {
|
||||
tmp.y2 = h_tmp - 1;
|
||||
disp_refr->driver->rounder_cb(disp_refr->driver, &tmp);
|
||||
|
||||
/*If this height fits into `max_row` then fine*/
|
||||
if(lv_area_get_height(&tmp) <= max_row) break;
|
||||
/*If this height fits into `max_row` then fine*/
|
||||
if(lv_area_get_height(&tmp) <= max_row) break;
|
||||
|
||||
/*Decrement the height of the area until it fits into `max_row` after rounding*/
|
||||
h_tmp--;
|
||||
} while(h_tmp > 0);
|
||||
/*Decrement the height of the area until it fits into `max_row` after rounding*/
|
||||
h_tmp--;
|
||||
} while(h_tmp > 0);
|
||||
|
||||
if(h_tmp <= 0) {
|
||||
LV_LOG_WARN("Can't set draw_buf height using the round function. (Wrong round_cb or to "
|
||||
"small draw_buf)");
|
||||
return;
|
||||
}
|
||||
else {
|
||||
max_row = tmp.y2 + 1;
|
||||
}
|
||||
if(h_tmp <= 0) {
|
||||
LV_LOG_WARN("Can't set draw_buf height using the round function. (Wrong round_cb or to "
|
||||
"small draw_buf)");
|
||||
return;
|
||||
}
|
||||
|
||||
/*Always use the full row*/
|
||||
lv_coord_t row;
|
||||
lv_coord_t row_last = 0;
|
||||
for(row = area_p->y1; row + max_row - 1 <= y2; row += max_row) {
|
||||
/*Calc. the next y coordinates of draw_buf*/
|
||||
draw_buf->area.x1 = area_p->x1;
|
||||
draw_buf->area.x2 = area_p->x2;
|
||||
draw_buf->area.y1 = row;
|
||||
draw_buf->area.y2 = row + max_row - 1;
|
||||
if(draw_buf->area.y2 > y2) draw_buf->area.y2 = y2;
|
||||
row_last = draw_buf->area.y2;
|
||||
if(y2 == row_last) disp_refr->driver->draw_buf->last_part = 1;
|
||||
lv_refr_area_part(area_p);
|
||||
else {
|
||||
max_row = tmp.y2 + 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*If the last y coordinates are not handled yet ...*/
|
||||
if(y2 != row_last) {
|
||||
/*Calc. the next y coordinates of draw_buf*/
|
||||
draw_buf->area.x1 = area_p->x1;
|
||||
draw_buf->area.x2 = area_p->x2;
|
||||
draw_buf->area.y1 = row;
|
||||
draw_buf->area.y2 = y2;
|
||||
/*Always use the full row*/
|
||||
lv_coord_t row;
|
||||
lv_coord_t row_last = 0;
|
||||
for(row = area_p->y1; row + max_row - 1 <= y2; row += max_row) {
|
||||
/*Calc. the next y coordinates of draw_buf*/
|
||||
draw_buf->area.x1 = area_p->x1;
|
||||
draw_buf->area.x2 = area_p->x2;
|
||||
draw_buf->area.y1 = row;
|
||||
draw_buf->area.y2 = row + max_row - 1;
|
||||
if(draw_buf->area.y2 > y2) draw_buf->area.y2 = y2;
|
||||
row_last = draw_buf->area.y2;
|
||||
if(y2 == row_last) disp_refr->driver->draw_buf->last_part = 1;
|
||||
lv_refr_area_part(area_p);
|
||||
}
|
||||
|
||||
disp_refr->driver->draw_buf->last_part = 1;
|
||||
lv_refr_area_part(area_p);
|
||||
}
|
||||
/*If the last y coordinates are not handled yet ...*/
|
||||
if(y2 != row_last) {
|
||||
/*Calc. the next y coordinates of draw_buf*/
|
||||
draw_buf->area.x1 = area_p->x1;
|
||||
draw_buf->area.x2 = area_p->x2;
|
||||
draw_buf->area.y1 = row;
|
||||
draw_buf->area.y2 = y2;
|
||||
|
||||
disp_refr->driver->draw_buf->last_part = 1;
|
||||
lv_refr_area_part(area_p);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -701,8 +701,8 @@ LV_ATTRIBUTE_FAST_MEM static void map_normal(const lv_area_t * disp_area, lv_col
|
||||
blit.src_stride = lv_area_get_width(map_area) * sizeof(lv_color_t);
|
||||
blit.src_area.x1 = (draw_area->x1 - (map_area->x1 - disp_area->x1));
|
||||
blit.src_area.y1 = (draw_area->y1 - (map_area->y1 - disp_area->y1));
|
||||
blit.src_area.x2 = blit.src_area.x1 + draw_area_w;
|
||||
blit.src_area.y2 = blit.src_area.y1 + draw_area_h;
|
||||
blit.src_area.x2 = blit.src_area.x1 + draw_area_w - 1;
|
||||
blit.src_area.y2 = blit.src_area.y1 + draw_area_h - 1;
|
||||
|
||||
blit.dst = disp_buf;
|
||||
blit.dst_width = lv_area_get_width(disp_area);
|
||||
@ -710,8 +710,8 @@ LV_ATTRIBUTE_FAST_MEM static void map_normal(const lv_area_t * disp_area, lv_col
|
||||
blit.dst_stride = lv_area_get_width(disp_area) * sizeof(lv_color_t);
|
||||
blit.dst_area.x1 = draw_area->x1;
|
||||
blit.dst_area.y1 = draw_area->y1;
|
||||
blit.dst_area.x2 = blit.dst_area.x1 + draw_area_w;
|
||||
blit.dst_area.y2 = blit.dst_area.y1 + draw_area_h;
|
||||
blit.dst_area.x2 = blit.dst_area.x1 + draw_area_w - 1;
|
||||
blit.dst_area.y2 = blit.dst_area.y1 + draw_area_h - 1;
|
||||
|
||||
blit.opa = opa;
|
||||
|
||||
@ -751,8 +751,8 @@ LV_ATTRIBUTE_FAST_MEM static void map_normal(const lv_area_t * disp_area, lv_col
|
||||
blit.src_stride = lv_area_get_width(map_area) * sizeof(lv_color_t);
|
||||
blit.src_area.x1 = (draw_area->x1 - (map_area->x1 - disp_area->x1));
|
||||
blit.src_area.y1 = (draw_area->y1 - (map_area->y1 - disp_area->y1));
|
||||
blit.src_area.x2 = blit.src_area.x1 + draw_area_w;
|
||||
blit.src_area.y2 = blit.src_area.y1 + draw_area_h;
|
||||
blit.src_area.x2 = blit.src_area.x1 + draw_area_w - 1;
|
||||
blit.src_area.y2 = blit.src_area.y1 + draw_area_h - 1;
|
||||
|
||||
blit.dst = disp_buf;
|
||||
blit.dst_width = lv_area_get_width(disp_area);
|
||||
@ -760,8 +760,8 @@ LV_ATTRIBUTE_FAST_MEM static void map_normal(const lv_area_t * disp_area, lv_col
|
||||
blit.dst_stride = lv_area_get_width(disp_area) * sizeof(lv_color_t);
|
||||
blit.dst_area.x1 = draw_area->x1;
|
||||
blit.dst_area.y1 = draw_area->y1;
|
||||
blit.dst_area.x2 = blit.dst_area.x1 + draw_area_w;
|
||||
blit.dst_area.y2 = blit.dst_area.y1 + draw_area_h;
|
||||
blit.dst_area.x2 = blit.dst_area.x1 + draw_area_w - 1;
|
||||
blit.dst_area.y2 = blit.dst_area.y1 + draw_area_h - 1;
|
||||
|
||||
blit.opa = opa;
|
||||
|
||||
|
@ -113,6 +113,7 @@ void lv_obj_set_flex_align(lv_obj_t * obj, lv_flex_align_t main_place, lv_flex_a
|
||||
void lv_obj_set_flex_grow(lv_obj_t * obj, uint8_t grow)
|
||||
{
|
||||
lv_obj_set_style_flex_grow(obj, grow, 0);
|
||||
lv_obj_mark_layout_as_dirty(lv_obj_get_parent(obj));
|
||||
}
|
||||
|
||||
|
||||
@ -342,8 +343,10 @@ static int32_t find_track_end(lv_obj_t * cont, flex_t * f, int32_t item_start_id
|
||||
LV_ASSERT_MALLOC(new_dsc);
|
||||
if(new_dsc == NULL) return item_id;
|
||||
|
||||
lv_memcpy(new_dsc, t->grow_dsc, sizeof(grow_dsc_t) * (t->grow_item_cnt - 1));
|
||||
lv_mem_buf_release(t->grow_dsc);
|
||||
if(t->grow_dsc) {
|
||||
lv_memcpy(new_dsc, t->grow_dsc, sizeof(grow_dsc_t) * (t->grow_item_cnt - 1));
|
||||
lv_mem_buf_release(t->grow_dsc);
|
||||
}
|
||||
new_dsc[t->grow_item_cnt - 1].item = item;
|
||||
new_dsc[t->grow_item_cnt - 1].min_size = f->row ? lv_obj_get_style_min_width(item, LV_PART_MAIN) : lv_obj_get_style_min_height(item, LV_PART_MAIN);
|
||||
new_dsc[t->grow_item_cnt - 1].max_size = f->row ? lv_obj_get_style_max_width(item, LV_PART_MAIN) : lv_obj_get_style_max_height(item, LV_PART_MAIN);
|
||||
@ -453,16 +456,16 @@ static void children_repos(lv_obj_t * cont, flex_t * f, int32_t item_first_id, i
|
||||
break;
|
||||
}
|
||||
}
|
||||
lv_area_t old_coords;
|
||||
lv_area_copy(&old_coords, &item->coords);
|
||||
|
||||
area_set_main_size(&item->coords, s);
|
||||
|
||||
if(f->row) item->w_layout = 1;
|
||||
else item->h_layout = 1;
|
||||
|
||||
if(area_get_main_size(&old_coords) != area_get_main_size(&item->coords)) {
|
||||
if(s != area_get_main_size(&item->coords)) {
|
||||
lv_obj_invalidate(item);
|
||||
|
||||
lv_area_t old_coords;
|
||||
lv_area_copy(&old_coords, &item->coords);
|
||||
area_set_main_size(&item->coords, s);
|
||||
lv_event_send(item, LV_EVENT_SIZE_CHANGED, &old_coords);
|
||||
lv_event_send(lv_obj_get_parent(item), LV_EVENT_CHILD_CHANGED, item);
|
||||
lv_obj_invalidate(item);
|
||||
|
@ -50,7 +50,6 @@ static lv_opa_t lv_span_get_style_text_blend_mode(lv_obj_t * par, lv_span_t * sp
|
||||
static int32_t lv_span_get_style_text_decor(lv_obj_t * par, lv_span_t * span);
|
||||
|
||||
static inline void span_text_check(const char ** text);
|
||||
static inline bool is_break_char(uint32_t letter);
|
||||
static void get_txt_coords(const lv_obj_t * span, lv_area_t * area);
|
||||
static void lv_draw_span(lv_obj_t * spans, const lv_area_t * coords, const lv_area_t * mask);
|
||||
static bool lv_txt_get_snippet(const char * txt, const lv_font_t * font, lv_coord_t letter_space,
|
||||
@ -442,9 +441,9 @@ lv_coord_t lv_spangroup_get_expand_height(lv_obj_t * obj, lv_coord_t width)
|
||||
/* break word deal width */
|
||||
if(isfill && next_ofs > 0 && snippet_cnt > 0) {
|
||||
uint32_t letter = (uint32_t)cur_txt[cur_txt_ofs + next_ofs - 1];
|
||||
if(!(letter == '\0' || letter == '\n' || letter == '\r' || is_break_char(letter))) {
|
||||
if(!(letter == '\0' || letter == '\n' || letter == '\r' || _lv_txt_is_break_char(letter))) {
|
||||
letter = (uint32_t)cur_txt[cur_txt_ofs + next_ofs];
|
||||
if(!(letter == '\0' || letter == '\n' || letter == '\r' || is_break_char(letter))) {
|
||||
if(!(letter == '\0' || letter == '\n' || letter == '\r' || _lv_txt_is_break_char(letter))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -694,22 +693,6 @@ static inline void span_text_check(const char ** text)
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool is_break_char(uint32_t letter)
|
||||
{
|
||||
uint8_t i;
|
||||
bool ret = false;
|
||||
|
||||
/*Compare the letter to TXT_BREAK_CHARS*/
|
||||
for(i = 0; LV_TXT_BREAK_CHARS[i] != '\0'; i++) {
|
||||
if(letter == (uint32_t)LV_TXT_BREAK_CHARS[i]) {
|
||||
ret = true; /*If match then it is break char*/
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* draw span group
|
||||
* @param spans obj handle
|
||||
@ -788,9 +771,9 @@ static void lv_draw_span(lv_obj_t * obj, const lv_area_t * coords, const lv_area
|
||||
/* break word deal width */
|
||||
if(isfill && next_ofs > 0 && lv_get_snippet_cnt() > 0) {
|
||||
uint32_t letter = (uint32_t)cur_txt[cur_txt_ofs + next_ofs - 1];
|
||||
if(!(letter == '\0' || letter == '\n' || letter == '\r' || is_break_char(letter))) {
|
||||
if(!(letter == '\0' || letter == '\n' || letter == '\r' || _lv_txt_is_break_char(letter))) {
|
||||
letter = (uint32_t)cur_txt[cur_txt_ofs + next_ofs];
|
||||
if(!(letter == '\0' || letter == '\n' || letter == '\r' || is_break_char(letter))) {
|
||||
if(!(letter == '\0' || letter == '\n' || letter == '\r' || _lv_txt_is_break_char(letter))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -145,6 +145,23 @@ void lv_spinbox_set_range(lv_obj_t * obj, int32_t range_min, int32_t range_max)
|
||||
lv_spinbox_updatevalue(obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set cursor position to a specific digit for edition
|
||||
* @param spinbox pointer to spinbox
|
||||
* @param pos selected position in spinbox
|
||||
*/
|
||||
void lv_spinbox_set_pos(lv_obj_t * obj, uint8_t pos)
|
||||
{
|
||||
|
||||
lv_spinbox_t * spinbox = (lv_spinbox_t *)obj;
|
||||
int32_t step_limit;
|
||||
step_limit = LV_MAX(spinbox->range_max, (spinbox->range_min < 0 ? (-spinbox->range_min) : spinbox->range_min));
|
||||
int32_t new_step = spinbox->step * lv_pow(10, pos);
|
||||
if(pos <= 0) spinbox->step = 1;
|
||||
else if(new_step <= step_limit) spinbox->step = new_step;
|
||||
|
||||
lv_spinbox_updatevalue(obj);
|
||||
}
|
||||
/*=====================
|
||||
* Getter functions
|
||||
*====================*/
|
||||
|
@ -99,6 +99,12 @@ void lv_spinbox_set_step(lv_obj_t * obj, uint32_t step);
|
||||
*/
|
||||
void lv_spinbox_set_range(lv_obj_t * obj, int32_t range_min, int32_t range_max);
|
||||
|
||||
/**
|
||||
* Set cursor position to a specific digit for edition
|
||||
* @param spinbox pointer to spinbox
|
||||
* @param pos selected position in spinbox
|
||||
*/
|
||||
void lv_spinbox_set_pos(lv_obj_t * obj, uint8_t pos);
|
||||
/*=====================
|
||||
* Getter functions
|
||||
*====================*/
|
||||
|
@ -71,8 +71,6 @@ static void lv_gpu_nxp_pxp_run(void);
|
||||
static void lv_gpu_nxp_pxp_blit_recolor(lv_color_t * dest, lv_coord_t dest_width, const lv_color_t * src,
|
||||
lv_coord_t src_width,
|
||||
lv_coord_t copy_width, lv_coord_t copy_height, lv_opa_t opa, lv_color_t recolor, lv_opa_t recolorOpa);
|
||||
static void lv_gpu_nxp_invalidate_cache(uint32_t address, uint32_t width, uint32_t height, uint32_t stride,
|
||||
uint32_t pxSize);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
@ -160,8 +158,7 @@ void lv_gpu_nxp_pxp_fill(lv_color_t * dest_buf, lv_coord_t dest_width, const lv_
|
||||
.width = fill_area->x2 - fill_area->x1 + 1,
|
||||
.height = fill_area->y2 - fill_area->y1 + 1,
|
||||
};
|
||||
lv_gpu_nxp_invalidate_cache(outputConfig.buffer0Addr, outputConfig.width, outputConfig.height, outputConfig.pitchBytes,
|
||||
sizeof(lv_color_t));
|
||||
|
||||
PXP_SetOutputBufferConfig(LV_GPU_NXP_PXP_ID, &outputConfig);
|
||||
|
||||
if(opa > LV_OPA_MAX) {
|
||||
@ -272,9 +269,6 @@ void lv_gpu_nxp_pxp_blit(lv_color_t * dest, lv_coord_t dest_width, const lv_colo
|
||||
PXP_SetAlphaSurfacePosition(LV_GPU_NXP_PXP_ID, 0U, 0U, copy_width - 1U, copy_height - 1U);
|
||||
PXP_SetAlphaSurfaceBlendConfig(LV_GPU_NXP_PXP_ID, &asBlendConfig);
|
||||
|
||||
lv_gpu_nxp_invalidate_cache(asBufferConfig.bufferAddr, copy_width, copy_height, asBufferConfig.pitchBytes,
|
||||
sizeof(lv_color_t));
|
||||
|
||||
if(colorKeyEnabled) {
|
||||
PXP_SetAlphaSurfaceOverlayColorKey(LV_GPU_NXP_PXP_ID, colorKey, colorKey);
|
||||
}
|
||||
@ -290,10 +284,7 @@ void lv_gpu_nxp_pxp_blit(lv_color_t * dest, lv_coord_t dest_width, const lv_colo
|
||||
outputBufferConfig.height = copy_height;
|
||||
PXP_SetOutputBufferConfig(LV_GPU_NXP_PXP_ID, &outputBufferConfig);
|
||||
|
||||
lv_gpu_nxp_invalidate_cache(outputBufferConfig.buffer0Addr, outputBufferConfig.width, outputBufferConfig.height,
|
||||
outputBufferConfig.pitchBytes, sizeof(lv_color_t));
|
||||
|
||||
lv_gpu_nxp_pxp_run(); /*Start PXP task*/
|
||||
lv_gpu_nxp_pxp_run(); /* Start PXP task */
|
||||
}
|
||||
|
||||
/**
|
||||
@ -349,6 +340,12 @@ void lv_gpu_nxp_pxp_disable_recolor(void)
|
||||
*/
|
||||
static void lv_gpu_nxp_pxp_run(void)
|
||||
{
|
||||
lv_disp_t * disp = _lv_refr_get_disp_refreshing();
|
||||
|
||||
if(disp && disp->driver->clean_dcache_cb) { /* Clean & invalidate cache */
|
||||
disp->driver->clean_dcache_cb(disp->driver);
|
||||
}
|
||||
|
||||
pxp_cfg.pxp_run();
|
||||
}
|
||||
|
||||
@ -396,9 +393,6 @@ static void lv_gpu_nxp_pxp_blit_recolor(lv_color_t * dest, lv_coord_t dest_width
|
||||
PXP_SetAlphaSurfaceBufferConfig(LV_GPU_NXP_PXP_ID, &asBufferConfig);
|
||||
PXP_SetAlphaSurfacePosition(LV_GPU_NXP_PXP_ID, 0U, 0U, copy_width - 1U, copy_height - 1U);
|
||||
|
||||
lv_gpu_nxp_invalidate_cache(asBufferConfig.bufferAddr, copy_width, copy_height, asBufferConfig.pitchBytes,
|
||||
sizeof(lv_color_t));
|
||||
|
||||
/*Disable PS buffer, use as color generator*/
|
||||
PXP_SetProcessSurfacePosition(LV_GPU_NXP_PXP_ID, 0xFFFFU, 0xFFFFU, 0U, 0U);
|
||||
PXP_SetProcessSurfaceBackGroundColor(LV_GPU_NXP_PXP_ID, lv_color_to32(recolor));
|
||||
@ -413,9 +407,6 @@ static void lv_gpu_nxp_pxp_blit_recolor(lv_color_t * dest, lv_coord_t dest_width
|
||||
outputBufferConfig.height = copy_height;
|
||||
PXP_SetOutputBufferConfig(LV_GPU_NXP_PXP_ID, &outputBufferConfig);
|
||||
|
||||
lv_gpu_nxp_invalidate_cache(outputBufferConfig.buffer0Addr, outputBufferConfig.width, outputBufferConfig.height,
|
||||
outputBufferConfig.pitchBytes, sizeof(lv_color_t));
|
||||
|
||||
pxp_porter_duff_config_t pdConfig;
|
||||
|
||||
/*Configure Porter-Duff blending - For RGB 565 only!*/
|
||||
@ -454,23 +445,4 @@ static void lv_gpu_nxp_pxp_blit_recolor(lv_color_t * dest, lv_coord_t dest_width
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Invalidate cache for rectangular area of memory
|
||||
*
|
||||
* @param[in] address starting address of area
|
||||
* @param[in] width width of area in pixels
|
||||
* @param[in] height height of area in pixels
|
||||
* @param[in] stride stride in bytes
|
||||
* @param[in] pxSize pixel size in bytes
|
||||
*/
|
||||
static void lv_gpu_nxp_invalidate_cache(uint32_t address, uint32_t width, uint32_t height, uint32_t stride,
|
||||
uint32_t pxSize)
|
||||
{
|
||||
int y;
|
||||
|
||||
for(y = 0; y < height; y++) {
|
||||
DCACHE_CleanInvalidateByRange(address, width * pxSize);
|
||||
address += stride;
|
||||
}
|
||||
}
|
||||
#endif /*LV_USE_GPU && LV_USE_GPU_NXP_PXP*/
|
||||
#endif /* LV_USE_GPU_NXP_PXP */
|
||||
|
@ -61,6 +61,11 @@ extern "C" {
|
||||
#define LV_GPU_NXP_PXP_BLIT_OPA_SIZE_LIMIT 16
|
||||
#endif
|
||||
|
||||
#ifndef LV_GPU_NXP_PXP_BUFF_SYNC_BLIT_SIZE_LIMIT
|
||||
/** Minimum invalidated area (in pixels) to be synchronized by PXP during buffer sync */
|
||||
#define LV_GPU_NXP_PXP_BUFF_SYNC_BLIT_SIZE_LIMIT 32
|
||||
#endif
|
||||
|
||||
#ifndef LV_GPU_NXP_PXP_FILL_SIZE_LIMIT
|
||||
/** Minimum area (in pixels) to be filled by PXP with 100% opacity*/
|
||||
#define LV_GPU_NXP_PXP_FILL_SIZE_LIMIT 64
|
||||
|
@ -32,13 +32,14 @@
|
||||
*********************/
|
||||
|
||||
#include "../lv_conf_internal.h"
|
||||
#include "../misc/lv_log.h"
|
||||
|
||||
#if LV_USE_GPU_NXP_PXP && LV_USE_GPU_NXP_PXP_AUTO_INIT
|
||||
|
||||
#include "lv_gpu_nxp_pxp.h"
|
||||
#include "fsl_pxp.h"
|
||||
|
||||
#if defined(FSL_RTOS_FREE_RTOS)
|
||||
#if defined(SDK_OS_FREE_RTOS)
|
||||
#include "FreeRTOS.h"
|
||||
#include "semphr.h"
|
||||
#endif
|
||||
@ -62,7 +63,7 @@ static void _lv_gpu_nxp_pxp_run(void);
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
#if defined(FSL_RTOS_FREE_RTOS)
|
||||
#if defined(SDK_OS_FREE_RTOS)
|
||||
static SemaphoreHandle_t s_pxpIdle;
|
||||
#else
|
||||
static volatile bool s_pxpIdle;
|
||||
@ -81,13 +82,13 @@ static void _lv_gpu_nxp_pxp_run(void);
|
||||
*/
|
||||
void PXP_IRQHandler(void)
|
||||
{
|
||||
#if defined(FSL_RTOS_FREE_RTOS)
|
||||
#if defined(SDK_OS_FREE_RTOS)
|
||||
BaseType_t taskAwake = pdFALSE;
|
||||
#endif
|
||||
|
||||
if(kPXP_CompleteFlag & PXP_GetStatusFlags(LV_GPU_NXP_PXP_ID)) {
|
||||
PXP_ClearStatusFlags(LV_GPU_NXP_PXP_ID, kPXP_CompleteFlag);
|
||||
#if defined(FSL_RTOS_FREE_RTOS)
|
||||
#if defined(SDK_OS_FREE_RTOS)
|
||||
xSemaphoreGiveFromISR(s_pxpIdle, &taskAwake);
|
||||
portYIELD_FROM_ISR(taskAwake);
|
||||
#else
|
||||
@ -106,7 +107,7 @@ void PXP_IRQHandler(void)
|
||||
*/
|
||||
static lv_res_t _lv_gpu_nxp_pxp_interrupt_init(void)
|
||||
{
|
||||
#if defined(FSL_RTOS_FREE_RTOS)
|
||||
#if defined(SDK_OS_FREE_RTOS)
|
||||
s_pxpIdle = xSemaphoreCreateBinary();
|
||||
if(s_pxpIdle == NULL) {
|
||||
return LV_RES_INV;
|
||||
@ -128,7 +129,7 @@ static lv_res_t _lv_gpu_nxp_pxp_interrupt_init(void)
|
||||
static void _lv_gpu_nxp_pxp_interrupt_deinit(void)
|
||||
{
|
||||
NVIC_DisableIRQ(LV_GPU_NXP_PXP_IRQ_ID);
|
||||
#if defined(FSL_RTOS_FREE_RTOS)
|
||||
#if defined(SDK_OS_FREE_RTOS)
|
||||
vSemaphoreDelete(s_pxpIdle);
|
||||
#endif
|
||||
}
|
||||
@ -138,14 +139,14 @@ static void _lv_gpu_nxp_pxp_interrupt_deinit(void)
|
||||
*/
|
||||
static void _lv_gpu_nxp_pxp_run(void)
|
||||
{
|
||||
#if !defined(FSL_RTOS_FREE_RTOS)
|
||||
#if !defined(SDK_OS_FREE_RTOS)
|
||||
s_pxpIdle = false;
|
||||
#endif
|
||||
|
||||
PXP_EnableInterrupts(LV_GPU_NXP_PXP_ID, kPXP_CompleteInterruptEnable);
|
||||
PXP_Start(LV_GPU_NXP_PXP_ID);
|
||||
|
||||
#if defined(FSL_RTOS_FREE_RTOS)
|
||||
#if defined(SDK_OS_FREE_RTOS)
|
||||
if(xSemaphoreTake(s_pxpIdle, portMAX_DELAY) != pdTRUE) {
|
||||
LV_LOG_ERROR("xSemaphoreTake error. Task halted.");
|
||||
for(; ;) ;
|
||||
|
@ -40,27 +40,78 @@
|
||||
#include "../misc/lv_log.h"
|
||||
#include "fsl_cache.h"
|
||||
#include "vg_lite.h"
|
||||
#include "fsl_debug_console.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
#if LV_COLOR_DEPTH==16
|
||||
#define VGLITE_PX_FMT VG_LITE_RGB565
|
||||
#else
|
||||
#error Only 16bit color depth is supported. Set LV_COLOR_DEPTH to 16.
|
||||
#endif
|
||||
|
||||
/* Enable BLIT quality degradation workaround for RT595 */
|
||||
#define RT595_BLIT_WRKRND_ENABLED 1
|
||||
|
||||
/* If LV_HOR_RES_MAX/LV_VER_RES_MAX is higher than this value, workaround will be enabled */
|
||||
#define RT595_BLIT_WRKRND_THR 352
|
||||
|
||||
/* Print detailed info to SDK console (NOT to LVGL log system) */
|
||||
#define BLIT_DBG_VERBOSE 0
|
||||
|
||||
/* Draw rectangles around BLIT tiles */
|
||||
#define BLIT_DBG_AREAS 0
|
||||
|
||||
/* Redirect PRINT to SDK PRINTF */
|
||||
#define PRINT PRINTF
|
||||
|
||||
/* Verbose debug print */
|
||||
#if BLIT_DBG_VERBOSE
|
||||
#define PRINT_BLT PRINTF
|
||||
#else
|
||||
#define PRINT_BLT(...)
|
||||
#endif
|
||||
|
||||
/* Internal compound symbol */
|
||||
#if (defined(CPU_MIMXRT595SFFOB) || defined(CPU_MIMXRT595SFFOB_cm33) || \
|
||||
defined(CPU_MIMXRT595SFFOC) || defined(CPU_MIMXRT595SFFOC_cm33)) && \
|
||||
((LV_HOR_RES_MAX > RT595_BLIT_WRKRND_THR) || (LV_VER_RES_MAX > RT595_BLIT_WRKRND_THR)) && \
|
||||
RT595_BLIT_WRKRND_ENABLED
|
||||
#define _BLIT_SPLIT_ENABLED 1
|
||||
#else
|
||||
#define _BLIT_SPLIT_ENABLED 0
|
||||
#endif
|
||||
|
||||
/* BLIT split threshold - BLITs with width or height higher than this value will be done
|
||||
* in multiple steps. Value must be 16-aligned. Don't change.
|
||||
* */
|
||||
#define LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR 352
|
||||
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
static lv_res_t init_vg_buf(vg_lite_buffer_t * dst, uint32_t width, uint32_t height, uint32_t stride,
|
||||
const lv_color_t * ptr);
|
||||
static lv_res_t _init_vg_buf(vg_lite_buffer_t * dst, uint32_t width, uint32_t height, uint32_t stride,
|
||||
const lv_color_t * ptr, bool source);
|
||||
|
||||
static lv_res_t _lv_gpu_nxp_vglite_blit_single(lv_gpu_nxp_vglite_blit_info_t * blit);
|
||||
#if _BLIT_SPLIT_ENABLED
|
||||
static void _align_x(lv_area_t * area, lv_color_t ** buf);
|
||||
static void _align_y(lv_area_t * area, lv_color_t ** buf, uint32_t stridePx);
|
||||
static void _sw_blit(lv_gpu_nxp_vglite_blit_info_t * blit);
|
||||
#if BLIT_DBG_AREAS
|
||||
static void _draw_rectangle(lv_color_t * dest_buf, lv_coord_t dest_width, lv_coord_t dest_height,
|
||||
lv_area_t * fill_area, lv_color_t color);
|
||||
#endif
|
||||
static lv_res_t _lv_gpu_nxp_vglite_check_blit(lv_gpu_nxp_vglite_blit_info_t * blit);
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
@ -70,6 +121,14 @@ static lv_res_t init_vg_buf(vg_lite_buffer_t * dst, uint32_t width, uint32_t hei
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#define CHECK(cond, txt) \
|
||||
do { \
|
||||
if (cond) { \
|
||||
PRINT("%s. STOP!\n", txt); \
|
||||
for ( ; ; ); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
@ -94,25 +153,37 @@ lv_res_t lv_gpu_nxp_vglite_fill(lv_color_t * dest_buf, lv_coord_t dest_width, lv
|
||||
lv_color32_t col32 = {.full = lv_color_to32(color)}; /*Convert color to RGBA8888*/
|
||||
lv_disp_t * disp = _lv_refr_get_disp_refreshing();
|
||||
|
||||
if(init_vg_buf(&rt, dest_width, dest_height, dest_width * sizeof(lv_color_t), dest_buf) != LV_RES_OK) {
|
||||
if(_init_vg_buf(&rt, (uint32_t) dest_width, (uint32_t) dest_height, (uint32_t) dest_width * sizeof(lv_color_t), (const lv_color_t *) dest_buf, false) != LV_RES_OK) {
|
||||
#if LV_GPU_NXP_VG_LITE_LOG_ERRORS
|
||||
LV_LOG_ERROR("init_vg_buf reported error. Fill failed.");
|
||||
#endif
|
||||
return LV_RES_INV;
|
||||
}
|
||||
|
||||
if(opa >= LV_OPA_MAX) { /*Opaque fill*/
|
||||
if(opa >= (lv_opa_t) LV_OPA_MAX) { /*Opaque fill*/
|
||||
rect.x = fill_area->x1;
|
||||
rect.y = fill_area->y1;
|
||||
rect.width = (fill_area->x2 - fill_area->x1) + 1;
|
||||
rect.height = (fill_area->y2 - fill_area->y1) + 1;
|
||||
rect.width = (int32_t) fill_area->x2 - (int32_t) fill_area->x1 + 1;
|
||||
rect.height = (int32_t) fill_area->y2 - (int32_t) fill_area->y1 + 1;
|
||||
|
||||
if(disp && disp->driver->clean_dcache_cb) { /*Clean & invalidate cache*/
|
||||
if(disp != NULL && disp->driver->clean_dcache_cb != NULL) { /*Clean & invalidate cache*/
|
||||
disp->driver->clean_dcache_cb(disp->driver);
|
||||
}
|
||||
|
||||
err |= vg_lite_clear(&rt, &rect, col32.full);
|
||||
err |= vg_lite_finish();
|
||||
err = vg_lite_clear(&rt, &rect, col32.full);
|
||||
if (err != VG_LITE_SUCCESS) {
|
||||
#if LV_GPU_NXP_VG_LITE_LOG_ERRORS
|
||||
LV_LOG_ERROR("vg_lite_clear reported error. Fill failed.");
|
||||
#endif
|
||||
return LV_RES_INV;
|
||||
}
|
||||
err = vg_lite_finish();
|
||||
if (err != VG_LITE_SUCCESS) {
|
||||
#if LV_GPU_NXP_VG_LITE_LOG_ERRORS
|
||||
LV_LOG_ERROR("vg_lite_finish reported error. Fill failed.");
|
||||
#endif
|
||||
return LV_RES_INV;
|
||||
}
|
||||
}
|
||||
else { /*fill with transparency*/
|
||||
|
||||
@ -127,8 +198,8 @@ lv_res_t lv_gpu_nxp_vglite_fill(lv_color_t * dest_buf, lv_coord_t dest_width, lv
|
||||
VLC_OP_END
|
||||
};
|
||||
|
||||
err |= vg_lite_init_path(&path, VG_LITE_S16, VG_LITE_LOW, sizeof(path_data), path_data,
|
||||
fill_area->x1, fill_area->y1, fill_area->x2 + 1, fill_area->y2 + 1);
|
||||
err = vg_lite_init_path(&path, VG_LITE_S16, VG_LITE_LOW, sizeof(path_data), path_data,
|
||||
(vg_lite_float_t) fill_area->x1, (vg_lite_float_t) fill_area->y1, ((vg_lite_float_t) fill_area->x2) + 1.0f, ((vg_lite_float_t) fill_area->y2) + 1.0f);
|
||||
if(err != VG_LITE_SUCCESS) {
|
||||
#if LV_GPU_NXP_VG_LITE_LOG_ERRORS
|
||||
LV_LOG_ERROR("vg_lite_init_path() failed.");
|
||||
@ -136,12 +207,12 @@ lv_res_t lv_gpu_nxp_vglite_fill(lv_color_t * dest_buf, lv_coord_t dest_width, lv
|
||||
return LV_RES_INV;
|
||||
}
|
||||
|
||||
colMix.ch.red = ((uint16_t)col32.ch.red * opa) >> 8; /*Pre-multiply color*/
|
||||
colMix.ch.green = ((uint16_t)col32.ch.green * opa) >> 8;
|
||||
colMix.ch.blue = ((uint16_t)col32.ch.blue * opa) >> 8;
|
||||
colMix.ch.red = (uint8_t)(((uint16_t)col32.ch.red * opa) >> 8); /*Pre-multiply color*/
|
||||
colMix.ch.green = (uint8_t)(((uint16_t)col32.ch.green * opa) >> 8);
|
||||
colMix.ch.blue = (uint8_t)(((uint16_t)col32.ch.blue * opa) >> 8);
|
||||
colMix.ch.alpha = opa;
|
||||
|
||||
if(disp && disp->driver->clean_dcache_cb) { /*Clean & invalidate cache*/
|
||||
if((disp != NULL) && (disp->driver->clean_dcache_cb != NULL)) { /*Clean & invalidate cache*/
|
||||
disp->driver->clean_dcache_cb(disp->driver);
|
||||
}
|
||||
|
||||
@ -149,8 +220,8 @@ lv_res_t lv_gpu_nxp_vglite_fill(lv_color_t * dest_buf, lv_coord_t dest_width, lv
|
||||
vg_lite_identity(&matrix);
|
||||
|
||||
/*Draw rectangle*/
|
||||
err |= vg_lite_draw(&rt, &path, VG_LITE_FILL_EVEN_ODD, &matrix, VG_LITE_BLEND_SRC_OVER, colMix.full);
|
||||
if(err) {
|
||||
err = vg_lite_draw(&rt, &path, VG_LITE_FILL_EVEN_ODD, &matrix, VG_LITE_BLEND_SRC_OVER, colMix.full);
|
||||
if(err != VG_LITE_SUCCESS) {
|
||||
#if LV_GPU_NXP_VG_LITE_LOG_ERRORS
|
||||
LV_LOG_ERROR("vg_lite_draw() failed.");
|
||||
#endif
|
||||
@ -158,8 +229,21 @@ lv_res_t lv_gpu_nxp_vglite_fill(lv_color_t * dest_buf, lv_coord_t dest_width, lv
|
||||
return LV_RES_INV;
|
||||
}
|
||||
|
||||
err |= vg_lite_finish();
|
||||
err |= vg_lite_clear_path(&path);
|
||||
err = vg_lite_finish();
|
||||
if(err != VG_LITE_SUCCESS) {
|
||||
#if LV_GPU_NXP_VG_LITE_LOG_ERRORS
|
||||
LV_LOG_ERROR("vg_lite_finish() failed.");
|
||||
#endif
|
||||
return LV_RES_INV;
|
||||
}
|
||||
|
||||
err = vg_lite_clear_path(&path);
|
||||
if(err != VG_LITE_SUCCESS) {
|
||||
#if LV_GPU_NXP_VG_LITE_LOG_ERRORS
|
||||
LV_LOG_ERROR("vg_lite_clear_path() failed.");
|
||||
#endif
|
||||
return LV_RES_INV;
|
||||
}
|
||||
}
|
||||
|
||||
if(err == VG_LITE_SUCCESS) {
|
||||
@ -180,63 +264,255 @@ lv_res_t lv_gpu_nxp_vglite_fill(lv_color_t * dest_buf, lv_coord_t dest_width, lv
|
||||
* @retval LV_RES_INV Error occurred (\see LV_GPU_NXP_VG_LITE_LOG_ERRORS)
|
||||
*/
|
||||
lv_res_t lv_gpu_nxp_vglite_blit(lv_gpu_nxp_vglite_blit_info_t * blit)
|
||||
{
|
||||
#if _BLIT_SPLIT_ENABLED
|
||||
|
||||
lv_res_t rv = LV_RES_INV;
|
||||
|
||||
if(_lv_gpu_nxp_vglite_check_blit(blit) != LV_RES_OK) {
|
||||
PRINT_BLT("Blit check failed\n");
|
||||
return LV_RES_INV;
|
||||
}
|
||||
|
||||
PRINT_BLT("BLIT from: "
|
||||
"Area: %03d,%03d - %03d,%03d "
|
||||
"Addr: %d\n\n",
|
||||
blit->src_area.x1, blit->src_area.y1,
|
||||
blit->src_area.x2, blit->src_area.y2,
|
||||
(uintptr_t) blit->src);
|
||||
|
||||
PRINT_BLT("BLIT to: "
|
||||
"Area: %03d,%03d - %03d,%03d "
|
||||
"Addr: %d\n\n",
|
||||
blit->dst_area.x1, blit->dst_area.y1,
|
||||
blit->dst_area.x2, blit->dst_area.y2,
|
||||
(uintptr_t) blit->src);
|
||||
|
||||
/* Stage 1: Move starting pointers as close as possible to [x1, y1], so coordinates are as small as possible. */
|
||||
_align_x(&blit->src_area, (lv_color_t **)&blit->src);
|
||||
_align_y(&blit->src_area, (lv_color_t **)&blit->src, blit->src_stride / sizeof(lv_color_t));
|
||||
_align_x(&blit->dst_area, (lv_color_t **)&blit->dst);
|
||||
_align_y(&blit->dst_area, (lv_color_t **)&blit->dst, blit->dst_stride / sizeof(lv_color_t));
|
||||
|
||||
/* Stage 2: If we're in limit, do a single BLIT */
|
||||
if((blit->src_area.x2 < LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR) &&
|
||||
(blit->src_area.y2 < LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR)) {
|
||||
PRINT_BLT("Simple blit!\n");
|
||||
return _lv_gpu_nxp_vglite_blit_single(blit);
|
||||
};
|
||||
|
||||
/* Stage 3: Split the BLIT into multiple tiles */
|
||||
PRINT_BLT("Split blit!\n");
|
||||
|
||||
PRINT_BLT("Blit "
|
||||
"([%03d,%03d], [%03d,%03d]) -> "
|
||||
"([%03d,%03d], [%03d,%03d]) | "
|
||||
"([%03dx%03d] -> [%03dx%03d]) | "
|
||||
"A:(%d -> %d)\n",
|
||||
blit->src_area.x1, blit->src_area.y1, blit->src_area.x2, blit->src_area.y2,
|
||||
blit->dst_area.x1, blit->dst_area.y1, blit->dst_area.x2, blit->dst_area.y2,
|
||||
lv_area_get_width(&blit->src_area), lv_area_get_height(&blit->src_area),
|
||||
lv_area_get_width(&blit->dst_area), lv_area_get_height(&blit->dst_area),
|
||||
(uintptr_t) blit->src, (uintptr_t) blit->dst);
|
||||
|
||||
|
||||
uint32_t totalWidth = lv_area_get_width(&blit->src_area);
|
||||
uint32_t totalHeight = lv_area_get_height(&blit->src_area);
|
||||
|
||||
lv_gpu_nxp_vglite_blit_info_t tileBlit;
|
||||
|
||||
/* Number of tiles needed */
|
||||
int totalTilesX = (blit->src_area.x1 + totalWidth + LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR - 1) /
|
||||
LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR;
|
||||
int totalTilesY = (blit->src_area.y1 + totalHeight + LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR - 1) /
|
||||
LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR;
|
||||
|
||||
/* src and dst buffer shift against each other. Src buffer real data [0,0] may start actually at [3,0] in buffer, as
|
||||
* the buffer pointer has to be aligned, while dst buffer real data [0,0] may start at [1,0] in buffer. alignment may be
|
||||
* different */
|
||||
int shiftSrcX = (blit->src_area.x1 > blit->dst_area.x1) ? (blit->src_area.x1 - blit->dst_area.x1) : 0;
|
||||
int shiftDstX = (blit->src_area.x1 < blit->dst_area.x1) ? (blit->dst_area.x1 - blit->src_area.x1) : 0;
|
||||
|
||||
PRINT_BLT("\n");
|
||||
PRINT_BLT("Align shift: src: %d, dst: %d\n", shiftSrcX, shiftDstX);
|
||||
|
||||
tileBlit = *blit;
|
||||
|
||||
for(int tileY = 0; tileY < totalTilesY; tileY++) {
|
||||
|
||||
tileBlit.src_area.y1 = 0; /* no vertical alignment, always start from 0 */
|
||||
tileBlit.src_area.y2 = totalHeight - tileY * LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR - 1;
|
||||
if(tileBlit.src_area.y2 >= LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR) {
|
||||
tileBlit.src_area.y2 = LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR - 1; /* Should never happen */
|
||||
}
|
||||
tileBlit.src = blit->src + tileY * LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR * blit->src_stride / sizeof(
|
||||
lv_color_t); /* stride in px! */
|
||||
|
||||
tileBlit.dst_area.y1 = tileBlit.src_area.y1; /* y has no alignment, always in sync with src */
|
||||
tileBlit.dst_area.y2 = tileBlit.src_area.y2;
|
||||
|
||||
tileBlit.dst = blit->dst + tileY * LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR * blit->dst_stride / sizeof(
|
||||
lv_color_t); /* stride in px! */
|
||||
|
||||
for(int tileX = 0; tileX < totalTilesX; tileX++) {
|
||||
|
||||
if(tileX == 0) {
|
||||
/* 1st tile is special - there may be a gap between buffer start pointer
|
||||
* and area.x1 value, as the pointer has to be aligned.
|
||||
* tileBlit.src pointer - keep init value from Y-loop.
|
||||
* Also, 1st tile start is not shifted! shift is applied from 2nd tile */
|
||||
tileBlit.src_area.x1 = blit->src_area.x1;
|
||||
tileBlit.dst_area.x1 = blit->dst_area.x1;
|
||||
}
|
||||
else {
|
||||
/* subsequent tiles always starts from 0, but shifted*/
|
||||
tileBlit.src_area.x1 = 0 + shiftSrcX;
|
||||
tileBlit.dst_area.x1 = 0 + shiftDstX;
|
||||
/* and advance start pointer + 1 tile size */
|
||||
tileBlit.src += LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR;
|
||||
tileBlit.dst += LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR;
|
||||
}
|
||||
|
||||
/* Clip tile end coordinates */
|
||||
tileBlit.src_area.x2 = totalWidth + blit->src_area.x1 - tileX * LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR - 1;
|
||||
if(tileBlit.src_area.x2 >= LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR) {
|
||||
tileBlit.src_area.x2 = LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR - 1;
|
||||
}
|
||||
|
||||
tileBlit.dst_area.x2 = totalWidth + blit->dst_area.x1 - tileX * LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR - 1;
|
||||
if(tileBlit.dst_area.x2 >= LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR) {
|
||||
tileBlit.dst_area.x2 = LV_GPU_NXP_VG_LITE_BLIT_SPLIT_THR - 1;
|
||||
}
|
||||
|
||||
if(tileX < (totalTilesX - 1)) {
|
||||
/* And adjust end coords if shifted, but not for last tile! */
|
||||
tileBlit.src_area.x2 += shiftSrcX;
|
||||
tileBlit.dst_area.x2 += shiftDstX;
|
||||
}
|
||||
|
||||
rv = _lv_gpu_nxp_vglite_blit_single(&tileBlit);
|
||||
|
||||
#if BLIT_DBG_AREAS
|
||||
_draw_rectangle((lv_color_t *) tileBlit.dst, tileBlit.dst_width, tileBlit.dst_height, &tileBlit.dst_area, LV_COLOR_RED);
|
||||
_draw_rectangle((lv_color_t *) tileBlit.src, tileBlit.src_width, tileBlit.src_height, &tileBlit.src_area,
|
||||
LV_COLOR_GREEN);
|
||||
#endif
|
||||
|
||||
PRINT_BLT("Tile [%d, %d]: "
|
||||
"([%d,%d], [%d,%d]) -> "
|
||||
"([%d,%d], [%d,%d]) | "
|
||||
"([%dx%d] -> [%dx%d]) | "
|
||||
"A:(0x%8X -> 0x%8X) %s\n",
|
||||
tileX, tileY,
|
||||
tileBlit.src_area.x1, tileBlit.src_area.y1, tileBlit.src_area.x2, tileBlit.src_area.y2,
|
||||
tileBlit.dst_area.x1, tileBlit.dst_area.y1, tileBlit.dst_area.x2, tileBlit.dst_area.y2,
|
||||
lv_area_get_width(&tileBlit.src_area), lv_area_get_height(&tileBlit.src_area),
|
||||
lv_area_get_width(&tileBlit.dst_area), lv_area_get_height(&tileBlit.dst_area),
|
||||
(uintptr_t) tileBlit.src, (uintptr_t) tileBlit.dst,
|
||||
rv == LV_RES_OK ? "OK!" : "!!! FAILED !!!");
|
||||
|
||||
if(rv != LV_RES_OK) { /* if anything goes wrong... */
|
||||
#if LV_GPU_NXP_VG_LITE_LOG_ERRORS
|
||||
LV_LOG_ERROR("Split BLIT failed. Trying SW BLIT instead.");
|
||||
#endif
|
||||
_sw_blit(&tileBlit);
|
||||
rv = LV_RES_OK; /* Don't report error, as SW BLIT was performed */
|
||||
}
|
||||
|
||||
}
|
||||
PRINT_BLT(" \n");
|
||||
}
|
||||
|
||||
return rv; /* should never fail */
|
||||
|
||||
#else /* non RT595 */
|
||||
/* Just pass down */
|
||||
return _lv_gpu_nxp_vglite_blit_single(blit);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/***
|
||||
* BLock Image Transfer - single direct BLIT.
|
||||
* @param[in] blit Description of the transfer
|
||||
* @retval LV_RES_OK Transfer complete
|
||||
* @retval LV_RES_INV Error occurred (\see LV_GPU_NXP_VG_LITE_LOG_ERRORS)
|
||||
*/
|
||||
static lv_res_t _lv_gpu_nxp_vglite_blit_single(lv_gpu_nxp_vglite_blit_info_t * blit)
|
||||
{
|
||||
vg_lite_buffer_t src_vgbuf, dst_vgbuf;
|
||||
vg_lite_error_t err = VG_LITE_SUCCESS;
|
||||
uint32_t rect[4];
|
||||
lv_disp_t * disp = _lv_refr_get_disp_refreshing();
|
||||
|
||||
if(blit->opa < LV_OPA_MIN) {
|
||||
if(blit == NULL) {
|
||||
/*Wrong parameter*/
|
||||
return LV_RES_INV;
|
||||
}
|
||||
|
||||
if(blit->opa < (lv_opa_t) LV_OPA_MIN) {
|
||||
return LV_RES_OK; /*Nothing to BLIT*/
|
||||
}
|
||||
|
||||
if(!blit) {
|
||||
/*Wrong parameter*/
|
||||
return LV_RES_INV;
|
||||
}
|
||||
|
||||
/*Wrap src/dst buffer into VG-Lite buffer*/
|
||||
if(init_vg_buf(&src_vgbuf, blit->src_width, blit->src_height, blit->src_stride, blit->src) != LV_RES_OK) {
|
||||
if(_init_vg_buf(&src_vgbuf, (uint32_t) blit->src_width, (uint32_t) blit->src_height, (uint32_t) blit->src_stride, blit->src, true) != LV_RES_OK) {
|
||||
#if LV_GPU_NXP_VG_LITE_LOG_ERRORS
|
||||
LV_LOG_ERROR("init_vg_buf reported error. BLIT failed.");
|
||||
#endif
|
||||
return LV_RES_INV;
|
||||
}
|
||||
|
||||
if(init_vg_buf(&dst_vgbuf, blit->dst_width, blit->dst_height, blit->dst_stride, blit->dst) != LV_RES_OK) {
|
||||
if(_init_vg_buf(&dst_vgbuf, (uint32_t) blit->dst_width, (uint32_t) blit->dst_height, (uint32_t) blit->dst_stride, blit->dst, false) != LV_RES_OK) {
|
||||
#if LV_GPU_NXP_VG_LITE_LOG_ERRORS
|
||||
LV_LOG_ERROR("init_vg_buf reported error. BLIT failed.");
|
||||
#endif
|
||||
return LV_RES_INV;
|
||||
}
|
||||
|
||||
rect[0] = 0; /*Crop*/
|
||||
rect[1] = 0;
|
||||
rect[2] = blit->src_width;
|
||||
rect[3] = blit->src_height;
|
||||
rect[0] = (uint32_t) blit->src_area.x1; /* start x */
|
||||
rect[1] = (uint32_t) blit->src_area.y1; /* start y */
|
||||
rect[2] = (uint32_t) blit->src_area.x2 - (uint32_t) blit->src_area.x1 + 1U; /* width */
|
||||
rect[3] = (uint32_t) blit->src_area.y2 - (uint32_t) blit->src_area.y1 + 1U; /* height */
|
||||
|
||||
vg_lite_matrix_t matrix;
|
||||
vg_lite_identity(&matrix);
|
||||
vg_lite_translate(blit->dst_area.x1, blit->dst_area.y1, &matrix);
|
||||
vg_lite_translate((vg_lite_float_t)blit->dst_area.x1, (vg_lite_float_t)blit->dst_area.y1, &matrix);
|
||||
|
||||
if(disp && disp->driver->clean_dcache_cb) { /*Clean & invalidate cache*/
|
||||
if((disp != NULL) && (disp->driver->clean_dcache_cb != NULL)) { /*Clean & invalidate cache*/
|
||||
disp->driver->clean_dcache_cb(disp->driver);
|
||||
}
|
||||
|
||||
uint32_t color;
|
||||
vg_lite_blend_t blend;
|
||||
if(blit->opa >= LV_OPA_MAX) {
|
||||
if(blit->opa >= (uint8_t) LV_OPA_MAX) {
|
||||
color = 0x0;
|
||||
blend = VG_LITE_BLEND_NONE;
|
||||
}
|
||||
else {
|
||||
color = ((blit->opa) << 24) | ((blit->opa) << 16) | ((blit->opa) << 8) | (blit->opa);
|
||||
uint32_t opa = (uint32_t) blit->opa;
|
||||
color = (opa << 24) | (opa << 16) | (opa << 8) | opa;
|
||||
blend = VG_LITE_BLEND_SRC_OVER;
|
||||
src_vgbuf.image_mode = VG_LITE_MULTIPLY_IMAGE_MODE;
|
||||
}
|
||||
err |= vg_lite_blit_rect(&dst_vgbuf, &src_vgbuf, rect, &matrix, blend, color, VG_LITE_FILTER_POINT);
|
||||
|
||||
err |= vg_lite_finish();
|
||||
err = vg_lite_blit_rect(&dst_vgbuf, &src_vgbuf, rect, &matrix, blend, color, VG_LITE_FILTER_POINT);
|
||||
if(err != VG_LITE_SUCCESS) {
|
||||
#if LV_GPU_NXP_VG_LITE_LOG_ERRORS
|
||||
LV_LOG_ERROR("vg_lite_blit_rect() failed.");
|
||||
#endif
|
||||
return LV_RES_INV;
|
||||
}
|
||||
|
||||
err = vg_lite_finish();
|
||||
if(err != VG_LITE_SUCCESS) {
|
||||
#if LV_GPU_NXP_VG_LITE_LOG_ERRORS
|
||||
LV_LOG_ERROR("vg_lite_finish() failed.");
|
||||
#endif
|
||||
return LV_RES_INV;
|
||||
}
|
||||
|
||||
if(err == VG_LITE_SUCCESS) {
|
||||
return LV_RES_OK;
|
||||
@ -249,10 +525,6 @@ lv_res_t lv_gpu_nxp_vglite_blit(lv_gpu_nxp_vglite_blit_info_t * blit)
|
||||
}
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/***
|
||||
* Fills vg_lite_buffer_t structure according given parameters.
|
||||
* @param[out] dst Buffer structure to be filled
|
||||
@ -261,19 +533,19 @@ lv_res_t lv_gpu_nxp_vglite_blit(lv_gpu_nxp_vglite_blit_info_t * blit)
|
||||
* @param[in] stride Stride of the buffer in bytes
|
||||
* @param[in] ptr Pointer to the buffer (must be aligned according VG-Lite requirements)
|
||||
*/
|
||||
static lv_res_t init_vg_buf(vg_lite_buffer_t * dst, uint32_t width, uint32_t height, uint32_t stride,
|
||||
const lv_color_t * ptr)
|
||||
static lv_res_t _init_vg_buf(vg_lite_buffer_t * dst, uint32_t width, uint32_t height, uint32_t stride,
|
||||
const lv_color_t * ptr, bool source)
|
||||
{
|
||||
if((((uintptr_t)ptr) % LV_ATTRIBUTE_MEM_ALIGN_SIZE) != 0x0) { /*Test for alignment*/
|
||||
if((((uintptr_t)ptr) % (uintptr_t)LV_ATTRIBUTE_MEM_ALIGN_SIZE) != 0x0U) { /*Test for alignment*/
|
||||
#if LV_GPU_NXP_VG_LITE_LOG_ERRORS
|
||||
LV_LOG_ERROR("ptr (0x%X) not aligned to %d.", (size_t) ptr, LV_ATTRIBUTE_MEM_ALIGN_SIZE);
|
||||
#endif
|
||||
return LV_RES_INV;
|
||||
}
|
||||
|
||||
if((stride % LV_GPU_NXP_VG_LITE_STRIDE_ALIGN_PX) != 0x0) { /*Test for stride alignment*/
|
||||
if(source && (stride % (LV_GPU_NXP_VG_LITE_STRIDE_ALIGN_PX * sizeof(lv_color_t))) != 0x0U) { /*Test for stride alignment*/
|
||||
#if LV_GPU_NXP_VG_LITE_LOG_ERRORS
|
||||
LV_LOG_ERROR("Buffer stride (%d px) not aligned to %d px.", stride, LV_GPU_NXP_VG_LITE_STRIDE_ALIGN_PX);
|
||||
LV_LOG_ERROR("Buffer stride (%d px) not aligned to %d bytes.", stride, LV_GPU_NXP_VG_LITE_STRIDE_ALIGN_PX * sizeof(lv_color_t));
|
||||
#endif
|
||||
return LV_RES_INV;
|
||||
}
|
||||
@ -283,17 +555,205 @@ static lv_res_t init_vg_buf(vg_lite_buffer_t * dst, uint32_t width, uint32_t hei
|
||||
dst->image_mode = VG_LITE_NORMAL_IMAGE_MODE;
|
||||
dst->transparency_mode = VG_LITE_IMAGE_OPAQUE;
|
||||
|
||||
dst->width = width;
|
||||
dst->height = height;
|
||||
dst->stride = stride;
|
||||
dst->width = (int32_t) width;
|
||||
dst->height = (int32_t) height;
|
||||
dst->stride = (int32_t) stride;
|
||||
|
||||
memset(&dst->yuv, 0, sizeof(dst->yuv));
|
||||
void *r_ptr = memset(&dst->yuv, 0, sizeof(dst->yuv));
|
||||
if (r_ptr == NULL) {
|
||||
return LV_RES_INV;
|
||||
}
|
||||
|
||||
dst->memory = (void *)ptr;
|
||||
dst->address = (uint32_t) dst->memory;
|
||||
dst->handle = 0x0;
|
||||
dst->handle = NULL;
|
||||
|
||||
return LV_RES_OK;
|
||||
}
|
||||
|
||||
#if _BLIT_SPLIT_ENABLED
|
||||
|
||||
/**
|
||||
* Software BLIT as a fall-back scenario
|
||||
* @param[in] blit BLIT configuration
|
||||
*/
|
||||
static void _sw_blit(lv_gpu_nxp_vglite_blit_info_t * blit)
|
||||
{
|
||||
int x, y;
|
||||
|
||||
lv_coord_t w = lv_area_get_width(&blit->src_area);
|
||||
lv_coord_t h = lv_area_get_height(&blit->src_area);
|
||||
|
||||
uint32_t srcStridePx = blit->src_stride / sizeof(lv_color_t);
|
||||
uint32_t dstStridePx = blit->dst_stride / sizeof(lv_color_t);
|
||||
|
||||
lv_color_t * src = (lv_color_t *)blit->src + blit->src_area.y1 * srcStridePx + blit->src_area.x1;
|
||||
lv_color_t * dst = (lv_color_t *)blit->dst + blit->dst_area.y1 * dstStridePx + blit->dst_area.x1;
|
||||
|
||||
if(blit->opa >= LV_OPA_MAX) {
|
||||
/* simple copy */
|
||||
for(y = 0; y < h; y++) {
|
||||
_lv_memcpy(dst, src, w * sizeof(lv_color_t));
|
||||
src += srcStridePx;
|
||||
dst += dstStridePx;
|
||||
}
|
||||
}
|
||||
else if(blit->opa >= LV_OPA_MIN) {
|
||||
/* alpha blending */
|
||||
for(y = 0; y < h; y++) {
|
||||
for(x = 0; x < w; x++) {
|
||||
dst[x] = lv_color_mix(src[x], dst[x], blit->opa);
|
||||
}
|
||||
src += srcStridePx;
|
||||
dst += dstStridePx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify BLIT structure - widths, stride, pointer alignment
|
||||
* @param[in] blit
|
||||
* @return
|
||||
*/
|
||||
static lv_res_t _lv_gpu_nxp_vglite_check_blit(lv_gpu_nxp_vglite_blit_info_t * blit)
|
||||
{
|
||||
|
||||
if(lv_area_get_width(&blit->src_area) < LV_GPU_NXP_VG_LITE_STRIDE_ALIGN_PX) { /* Test for minimal width */
|
||||
#if LV_GPU_NXP_VG_LITE_LOG_ERRORS
|
||||
LV_LOG_ERROR("source area width (%d) is smaller than required (%d).", lv_area_get_width(&blit->src_area),
|
||||
LV_GPU_NXP_VG_LITE_STRIDE_ALIGN_PX);
|
||||
#endif
|
||||
return LV_RES_INV;
|
||||
}
|
||||
|
||||
if(lv_area_get_width(&blit->dst_area) < LV_GPU_NXP_VG_LITE_STRIDE_ALIGN_PX) { /* Test for minimal width */
|
||||
#if LV_GPU_NXP_VG_LITE_LOG_ERRORS
|
||||
LV_LOG_ERROR("destination area width (%d) is smaller than required (%d).", lv_area_get_width(&blit->dst_area),
|
||||
LV_GPU_NXP_VG_LITE_STRIDE_ALIGN_PX);
|
||||
#endif
|
||||
return LV_RES_INV;
|
||||
}
|
||||
|
||||
if((((uintptr_t) blit->src) % LV_ATTRIBUTE_MEM_ALIGN_SIZE) != 0x0) { /* Test for pointer alignment */
|
||||
#if LV_GPU_NXP_VG_LITE_LOG_ERRORS
|
||||
LV_LOG_ERROR("source buffer ptr (0x%X) not aligned to %d.", (size_t) blit->src, LV_ATTRIBUTE_MEM_ALIGN_SIZE);
|
||||
#endif
|
||||
return LV_RES_INV;
|
||||
}
|
||||
/* No alignment requirement for destination pixel buffer when using mode VG_LITE_LINEAR */
|
||||
|
||||
if((blit->src_stride % (LV_GPU_NXP_VG_LITE_STRIDE_ALIGN_PX * LV_COLOR_DEPTH / 8)) != 0x0) { /* Test for stride alignment */
|
||||
#if LV_GPU_NXP_VG_LITE_LOG_ERRORS
|
||||
LV_LOG_ERROR("source buffer stride (%d px) not aligned to %d px.", blit->src_stride, LV_GPU_NXP_VG_LITE_STRIDE_ALIGN_PX);
|
||||
#endif
|
||||
return LV_RES_INV;
|
||||
}
|
||||
|
||||
if((blit->dst_stride % (LV_GPU_NXP_VG_LITE_STRIDE_ALIGN_PX * LV_COLOR_DEPTH / 8)) != 0x0) { /* Test for stride alignment */
|
||||
#if LV_GPU_NXP_VG_LITE_LOG_ERRORS
|
||||
LV_LOG_ERROR("destination buffer stride (%d px) not aligned to %d px.", blit->dst_stride, LV_GPU_NXP_VG_LITE_STRIDE_ALIGN_PX);
|
||||
#endif
|
||||
return LV_RES_INV;
|
||||
}
|
||||
|
||||
if((lv_area_get_width(&blit->src_area) != lv_area_get_width(&blit->dst_area)) ||
|
||||
(lv_area_get_height(&blit->src_area) != lv_area_get_height(&blit->dst_area))) {
|
||||
#if LV_GPU_NXP_VG_LITE_LOG_ERRORS
|
||||
LV_LOG_ERROR("source and destination buffer areas are not equal.");
|
||||
#endif
|
||||
return LV_RES_INV;
|
||||
}
|
||||
|
||||
return LV_RES_OK;
|
||||
}
|
||||
|
||||
/***
|
||||
* Move buffer pointer as close as possible to area, but with respect to alignment requirements. X-axis only.
|
||||
* @param[in,out] area Area to be updated
|
||||
* @param[in,out] buf Pointer to be updated
|
||||
*/
|
||||
static void _align_x(lv_area_t * area, lv_color_t ** buf)
|
||||
{
|
||||
|
||||
int alignedAreaStartPx = area->x1 - (area->x1 % (LV_ATTRIBUTE_MEM_ALIGN_SIZE * 8 / LV_COLOR_DEPTH) );
|
||||
CHECK(alignedAreaStartPx < 0, "Should never happen.");
|
||||
|
||||
area->x1 -= alignedAreaStartPx;
|
||||
area->x2 -= alignedAreaStartPx;
|
||||
*buf += alignedAreaStartPx;
|
||||
}
|
||||
|
||||
/***
|
||||
* Move buffer pointer to the area start and update variables, Y-axis only.
|
||||
* @param[in,out] area Area to be updated
|
||||
* @param[in,out] buf Pointer to be updated
|
||||
* @param[in] stridePx Buffer stride in pixels
|
||||
*/
|
||||
static void _align_y(lv_area_t * area, lv_color_t ** buf, uint32_t stridePx)
|
||||
{
|
||||
int LineToAlignMem;
|
||||
int alignedAreaStartPy;
|
||||
/* find how many lines of pixels will respect memory alignment requirement */
|
||||
if(stridePx % LV_ATTRIBUTE_MEM_ALIGN_SIZE == 0) {
|
||||
alignedAreaStartPy = area->y1;
|
||||
} else {
|
||||
LineToAlignMem = LV_ATTRIBUTE_MEM_ALIGN_SIZE / (sizeof(lv_color_t) * LV_GPU_NXP_VG_LITE_STRIDE_ALIGN_PX);
|
||||
CHECK(LV_ATTRIBUTE_MEM_ALIGN_SIZE % (sizeof(lv_color_t) * LV_GPU_NXP_VG_LITE_STRIDE_ALIGN_PX) != 0, "Complex case: need gcd function.");
|
||||
alignedAreaStartPy = area->y1 - (area->y1 % LineToAlignMem);
|
||||
CHECK(alignedAreaStartPy < 0, "Should never happen.");
|
||||
}
|
||||
|
||||
area->y1 -= alignedAreaStartPy;
|
||||
area->y2 -= alignedAreaStartPy;
|
||||
*buf += alignedAreaStartPy * stridePx;
|
||||
}
|
||||
|
||||
#if BLIT_DBG_AREAS
|
||||
/***
|
||||
* Draws a simple rectangle, 1 px line width.
|
||||
* @param dest_buf Destination buffer
|
||||
* @param dest_width Destination buffer width (must be aligned on 16px)
|
||||
* @param dest_height Destination buffer height
|
||||
* @param fill_area Rectangle coordinates
|
||||
* @param color Rectangle color
|
||||
*/
|
||||
static void _draw_rectangle(lv_color_t * dest_buf, lv_coord_t dest_width, lv_coord_t dest_height,
|
||||
lv_area_t * fill_area, lv_color_t color)
|
||||
{
|
||||
|
||||
lv_area_t a;
|
||||
|
||||
/* top line */
|
||||
a.x1 = fill_area->x1;
|
||||
a.x2 = fill_area->x2;
|
||||
a.y1 = fill_area->y1;
|
||||
a.y2 = fill_area->y1;
|
||||
lv_gpu_nxp_vglite_fill(dest_buf, dest_width, dest_height, &a, color, LV_OPA_COVER);
|
||||
|
||||
|
||||
/* bottom line */
|
||||
a.x1 = fill_area->x1;
|
||||
a.x2 = fill_area->x2;
|
||||
a.y1 = fill_area->y2;
|
||||
a.y2 = fill_area->y2;
|
||||
lv_gpu_nxp_vglite_fill(dest_buf, dest_width, dest_height, &a, color, LV_OPA_COVER);
|
||||
|
||||
/* left line */
|
||||
a.x1 = fill_area->x1;
|
||||
a.x2 = fill_area->x1;
|
||||
a.y1 = fill_area->y1;
|
||||
a.y2 = fill_area->y2;
|
||||
lv_gpu_nxp_vglite_fill(dest_buf, dest_width, dest_height, &a, color, LV_OPA_COVER);
|
||||
|
||||
/* right line */
|
||||
a.x1 = fill_area->x2;
|
||||
a.x2 = fill_area->x2;
|
||||
a.y1 = fill_area->y1;
|
||||
a.y2 = fill_area->y2;
|
||||
lv_gpu_nxp_vglite_fill(dest_buf, dest_width, dest_height, &a, color, LV_OPA_COVER);
|
||||
}
|
||||
#endif /* BLIT_DBG_AREAS */
|
||||
|
||||
#endif /* _BLIT_SPLIT_ENABLED */
|
||||
|
||||
#endif /*LV_USE_GPU_NXP_VG_LITE*/
|
||||
|
@ -43,8 +43,11 @@ extern "C" {
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/** Stride in px required by VG-Lite HW. Don't change this.*/
|
||||
#define LV_GPU_NXP_VG_LITE_STRIDE_ALIGN_PX 16
|
||||
/** Use this symbol as limit to disable feature (value has to be larger than supported resolution) */
|
||||
#define LV_GPU_NXP_VG_LITE_FEATURE_DISABLED (1920*1080+1)
|
||||
|
||||
/** Stride in px required by VG-Lite HW. Don't change this. */
|
||||
#define LV_GPU_NXP_VG_LITE_STRIDE_ALIGN_PX 16U
|
||||
|
||||
#ifndef LV_GPU_NXP_VG_LITE_FILL_SIZE_LIMIT
|
||||
/** Minimum area (in pixels) to be filled by VG-Lite with 100% opacity*/
|
||||
@ -61,6 +64,11 @@ extern "C" {
|
||||
#define LV_GPU_NXP_VG_LITE_BLIT_SIZE_LIMIT 32
|
||||
#endif
|
||||
|
||||
#ifndef LV_GPU_NXP_VG_LITE_BUFF_SYNC_BLIT_SIZE_LIMIT
|
||||
/** Minimum invalidated area (in pixels) to be synchronized by VG-Lite during buffer sync */
|
||||
#define LV_GPU_NXP_VG_LITE_BUFF_SYNC_BLIT_SIZE_LIMIT 32
|
||||
#endif
|
||||
|
||||
#ifndef LV_GPU_NXP_VG_LITE_BLIT_OPA_SIZE_LIMIT
|
||||
/** Minimum area (in pixels) for image copy with transparency to be handled by VG-Lite*/
|
||||
#define LV_GPU_NXP_VG_LITE_BLIT_OPA_SIZE_LIMIT 32
|
||||
|
@ -307,7 +307,7 @@ e.g. "stm32f769xx.h" or "stm32f429xx.h"*/
|
||||
#endif
|
||||
#if LV_USE_GPU_NXP_PXP
|
||||
/*1: Add default bare metal and FreeRTOS interrupt handling routines for PXP (lv_gpu_nxp_pxp_osa.c)
|
||||
* and call lv_gpu_nxp_pxp_init() automatically during lv_init(). Note that symbol FSL_RTOS_FREE_RTOS
|
||||
* and call lv_gpu_nxp_pxp_init() automatically during lv_init(). Note that symbol SDK_OS_FREE_RTOS
|
||||
* has to be defined in order to use FreeRTOS OSA, otherwise bare-metal implementation is selected.
|
||||
*0: lv_gpu_nxp_pxp_init() has to be called manually before lv_init()
|
||||
*/
|
||||
|
@ -43,7 +43,7 @@ LV_ATTRIBUTE_FAST_MEM void lv_color_fill(lv_color_t * buf, lv_color_t color, uin
|
||||
px_num--;
|
||||
}
|
||||
|
||||
uint32_t c32 = color.full + (color.full << 16);
|
||||
uint32_t c32 = (uint32_t)color.full + ((uint32_t)color.full << 16);
|
||||
uint32_t * buf32 = (uint32_t *)buf;
|
||||
|
||||
while(px_num > 16) {
|
||||
|
@ -26,7 +26,6 @@
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static inline bool is_break_char(uint32_t letter);
|
||||
|
||||
#if LV_TXT_ENC == LV_TXT_ENC_UTF8
|
||||
static uint8_t lv_txt_utf8_size(const char * str);
|
||||
@ -224,7 +223,7 @@ static uint32_t lv_txt_get_next_word(const char * txt, const lv_font_t * font,
|
||||
}
|
||||
|
||||
/*Check for new line chars and breakchars*/
|
||||
if(letter == '\n' || letter == '\r' || is_break_char(letter)) {
|
||||
if(letter == '\n' || letter == '\r' || _lv_txt_is_break_char(letter)) {
|
||||
/*Update the output width on the first character if it fits.
|
||||
*Must do this here in case first letter is a break character.*/
|
||||
if(i == 0 && break_index == NO_BREAK_FOUND && word_w_ptr != NULL) *word_w_ptr = cur_w;
|
||||
@ -895,28 +894,3 @@ static uint32_t lv_txt_iso8859_1_get_length(const char * txt)
|
||||
#error "Invalid character encoding. See `LV_TXT_ENC` in `lv_conf.h`"
|
||||
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Test if char is break char or not (a text can broken here or not)
|
||||
* @param letter a letter
|
||||
* @return false: 'letter' is not break char
|
||||
*/
|
||||
static inline bool is_break_char(uint32_t letter)
|
||||
{
|
||||
uint8_t i;
|
||||
bool ret = false;
|
||||
|
||||
/*Compare the letter to TXT_BREAK_CHARS*/
|
||||
for(i = 0; LV_TXT_BREAK_CHARS[i] != '\0'; i++) {
|
||||
if(letter == (uint32_t)LV_TXT_BREAK_CHARS[i]) {
|
||||
ret = true; /*If match then it is break char*/
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -154,6 +154,32 @@ char * _lv_txt_set_text_vfmt(const char * fmt, va_list ap);
|
||||
*/
|
||||
void _lv_txt_encoded_letter_next_2(const char * txt, uint32_t * letter, uint32_t * letter_next, uint32_t *ofs);
|
||||
|
||||
/**
|
||||
* Test if char is break char or not (a text can broken here or not)
|
||||
* @param letter a letter
|
||||
* @return false: 'letter' is not break char
|
||||
*/
|
||||
static inline bool _lv_txt_is_break_char(uint32_t letter)
|
||||
{
|
||||
uint8_t i;
|
||||
bool ret = false;
|
||||
|
||||
/* each chinese character can be break */
|
||||
if (letter >= 0x4E00 && letter <= 0x9FA5) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/*Compare the letter to TXT_BREAK_CHARS*/
|
||||
for(i = 0; LV_TXT_BREAK_CHARS[i] != '\0'; i++) {
|
||||
if(letter == (uint32_t)LV_TXT_BREAK_CHARS[i]) {
|
||||
ret = true; /*If match then it is break char*/
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***************************************************************
|
||||
* GLOBAL FUNCTION POINTERS FOR CHARACTER ENCODING INTERFACE
|
||||
***************************************************************/
|
||||
|
@ -112,10 +112,6 @@ static void lv_switch_event(const lv_obj_class_t * class_p, lv_event_t * e)
|
||||
*s = LV_MAX(*s, lv_obj_calculate_ext_draw_size(obj, LV_PART_INDICATOR));
|
||||
}
|
||||
else if(code == LV_EVENT_CLICKED) {
|
||||
uint32_t v = lv_obj_get_state(obj) & LV_STATE_CHECKED ? 1 : 0;
|
||||
res = lv_event_send(obj, LV_EVENT_VALUE_CHANGED, &v);
|
||||
if(res != LV_RES_OK) return;
|
||||
|
||||
lv_obj_invalidate(obj);
|
||||
}
|
||||
else if(code == LV_EVENT_DRAW_MAIN) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user