mirror of
https://github.com/aseprite/aseprite.git
synced 2025-01-28 00:35:30 +00:00
Merge branch 'main' into beta
This commit is contained in:
commit
801ea7ab6c
81
.github/workflows/build.yml
vendored
81
.github/workflows/build.yml
vendored
@ -8,35 +8,50 @@ jobs:
|
||||
matrix:
|
||||
os: [windows-latest, macos-latest, ubuntu-latest]
|
||||
build_type: [RelWithDebInfo, Debug]
|
||||
enable_ui: [off]
|
||||
include:
|
||||
- os: ubuntu-latest
|
||||
build_type: Debug
|
||||
enable_ui: on
|
||||
ui: [gui, cli]
|
||||
scripting: [lua, noscripts]
|
||||
exclude:
|
||||
- build_type: Debug
|
||||
ui: gui
|
||||
- build_type: RelWithDebInfo
|
||||
ui: cli
|
||||
- build_type: RelWithDebInfo
|
||||
scripting: noscripts
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: 'recursive'
|
||||
- name: Install Dependencies
|
||||
if: runner.os == 'Linux'
|
||||
shell: bash
|
||||
run: |
|
||||
sudo apt-get update -qq
|
||||
sudo apt-get install -y \
|
||||
libpixman-1-dev libfreetype6-dev libharfbuzz-dev zlib1g-dev \
|
||||
libx11-dev libxcursor-dev libxi-dev libgl1-mesa-dev
|
||||
- name: Install Skia
|
||||
if: ${{ matrix.ui == 'gui' }}
|
||||
shell: bash
|
||||
run: |
|
||||
if [[ "${{ runner.os }}" == "Windows" ]] ; then
|
||||
choco install wget -y --no-progress
|
||||
wget https://github.com/aseprite/skia/releases/download/m124-08a5439a6b/Skia-Windows-Release-x64.zip
|
||||
unzip Skia-Windows-Release-x64.zip -d skia
|
||||
elif [[ "${{ runner.os }}" == "macOS" ]] ; then
|
||||
wget https://github.com/aseprite/skia/releases/download/m124-08a5439a6b/Skia-macOS-Release-arm64.zip
|
||||
unzip Skia-macOS-Release-arm64.zip -d skia
|
||||
else
|
||||
wget https://github.com/aseprite/skia/releases/download/m124-08a5439a6b/Skia-Linux-Release-x64.zip
|
||||
unzip Skia-Linux-Release-x64.zip -d skia
|
||||
fi
|
||||
- name: ccache
|
||||
uses: hendrikmuhs/ccache-action@v1
|
||||
if: ${{ runner.os == 'Linux' || runner.os == 'macOS' }}
|
||||
with:
|
||||
key: ${{ matrix.os }}-${{ matrix.enable_ui }}-${{ matrix.build_type }}
|
||||
key: ${{ matrix.os }}-${{ matrix.ui }}-${{ matrix.scripting }}-${{ matrix.build_type }}
|
||||
- uses: aseprite/get-ninja@main
|
||||
- uses: ilammy/msvc-dev-cmd@v1
|
||||
if: runner.os == 'Windows'
|
||||
- name: Workaround for windows-2022 and cmake 3.25.0
|
||||
if: runner.os == 'Windows'
|
||||
shell: bash
|
||||
run: rm -rf C:/Strawberry/
|
||||
- name: Install Dependencies
|
||||
shell: bash
|
||||
run: |
|
||||
if [[ "${{ runner.os }}" == "Linux" ]] ; then
|
||||
sudo apt-get update -qq
|
||||
sudo apt-get install -y \
|
||||
libx11-dev libxcursor-dev libxi-dev
|
||||
fi
|
||||
- name: Generating Makefiles
|
||||
shell: bash
|
||||
run: |
|
||||
@ -45,12 +60,37 @@ jobs:
|
||||
else
|
||||
export enable_ccache=on
|
||||
fi
|
||||
|
||||
if [[ "${{ matrix.ui }}" == "gui" ]] ; then
|
||||
export enable_ui=on
|
||||
export laf_backend=skia
|
||||
else
|
||||
export enable_ui=off
|
||||
export laf_backend=none
|
||||
fi
|
||||
|
||||
if [[ "${{ matrix.scripting }}" == "lua" ]] ; then
|
||||
export enable_scripting=on
|
||||
else
|
||||
export enable_scripting=off
|
||||
fi
|
||||
|
||||
if [[ "${{ runner.os }}" == "macOS" ]] ; then
|
||||
export skia_arch=arm64
|
||||
else
|
||||
export skia_arch=x64
|
||||
fi
|
||||
|
||||
cmake -S . -B build -G Ninja \
|
||||
-DCMAKE_BUILD_TYPE=${{ matrix.build_type }} \
|
||||
-DCMAKE_OSX_DEPLOYMENT_TARGET=10.9 \
|
||||
-DENABLE_TESTS=ON \
|
||||
-DENABLE_UI=${{ matrix.enable_ui }} \
|
||||
-DENABLE_CCACHE=$enable_ccache
|
||||
-DENABLE_UI=$enable_ui \
|
||||
-DENABLE_SCRIPTING=$enable_scripting \
|
||||
-DENABLE_CCACHE=$enable_ccache \
|
||||
-DLAF_BACKEND=$laf_backend \
|
||||
-DSKIA_DIR=$(realpath skia) \
|
||||
-DSKIA_LIBRARY_DIR=$(realpath skia/out/Release-$skia_arch)
|
||||
- name: Compiling
|
||||
shell: bash
|
||||
run: |
|
||||
@ -63,6 +103,7 @@ jobs:
|
||||
fi
|
||||
cd build && $XVFB ctest --output-on-failure
|
||||
- name: Running CLI Tests
|
||||
if: ${{ matrix.scripting == 'lua' }}
|
||||
shell: bash
|
||||
run: |
|
||||
if [[ "${{ runner.os }}" == "Linux" ]] ; then
|
||||
|
72
.github/workflows/lint_commit.yml
vendored
Normal file
72
.github/workflows/lint_commit.yml
vendored
Normal file
@ -0,0 +1,72 @@
|
||||
# Based on SerenityOS commit linter:
|
||||
# https://github.com/SerenityOS/serenity/blob/master/.github/workflows/lintcommits.yml
|
||||
|
||||
name: Commit linter
|
||||
on: [pull_request_target]
|
||||
jobs:
|
||||
lint_commits:
|
||||
runs-on: ubuntu-22.04
|
||||
if: always() && github.repository == 'aseprite/aseprite'
|
||||
steps:
|
||||
- name: Lint PR commits
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
const rules = [
|
||||
{
|
||||
pattern: /^[^\r]*$/,
|
||||
error: "Commit message contains CRLF line breaks (only unix-style LF linebreaks are allowed)",
|
||||
},
|
||||
{
|
||||
pattern: /^.+(\r?\n(\r?\n.*)*)?$/,
|
||||
error: "Empty line between commit title and body is missing",
|
||||
},
|
||||
{
|
||||
pattern: /^.{0,72}(?:\r?\n(?:(.{0,72})|(.*?([a-z]+:\/\/)?(([a-zA-Z0-9_]|-)+\.)+[a-z]{2,}(:\d+)?([a-zA-Z_0-9@:%\+.~\?&/=]|-)+).*?))*$/,
|
||||
error: "Commit message lines are too long (maximum allowed is 72 characters, except for URLs)",
|
||||
},
|
||||
{
|
||||
pattern: /^.+[^.\n](\r?\n.*)*$/,
|
||||
error: "Commit title ends in a period",
|
||||
},
|
||||
{
|
||||
pattern: /^((?!Signed-off-by: )[\s\S])*$/,
|
||||
error: "Commit body contains a Signed-off-by tag",
|
||||
},
|
||||
];
|
||||
|
||||
const { repository, pull_request } = context.payload;
|
||||
|
||||
// NOTE: This maxes out at 250 commits. If this becomes a problem, see:
|
||||
// https://octokit.github.io/rest.js/v18#pulls-list-commits
|
||||
const opts = github.rest.pulls.listCommits.endpoint.merge({
|
||||
owner: repository.owner.login,
|
||||
repo: repository.name,
|
||||
pull_number: pull_request.number,
|
||||
});
|
||||
const commits = await github.paginate(opts);
|
||||
|
||||
const errors = [];
|
||||
for (const { sha, commit: { message } } of commits) {
|
||||
const commitErrors = [];
|
||||
for (const { pattern, error } of rules) {
|
||||
if (!pattern.test(message)) {
|
||||
commitErrors.push(error);
|
||||
}
|
||||
}
|
||||
if (commitErrors.length > 0) {
|
||||
const title = message.split("\n")[0];
|
||||
errors.push([`${title} (${sha}):`, ...commitErrors].join("\n "));
|
||||
}
|
||||
}
|
||||
|
||||
if (errors.length > 0) {
|
||||
core.setFailed(`One or more of the commits in this PR do not match the code submission policy:\n\n${errors.join("\n")}`);
|
||||
}
|
||||
- name: Comment on PR
|
||||
if: ${{ failure() && !github.event.pull_request.draft }}
|
||||
uses: IdanHo/comment-on-pr@63ea2bf352997c66e524b8b5be7a79163fb3a88a
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.LINT_COMMIT_TOKEN }}
|
||||
with:
|
||||
msg: "Hi there!\n\nOne or more of the commit messages in this PR do not match our [code submission policy](https://github.com/aseprite/aseprite/blob/main/CONTRIBUTING.md), please check the `lint_commits` CI job for more details on which commits were flagged and why.\nPlease do not close this PR and open another, instead modify your commit message(s) with [git commit --amend](https://docs.github.com/en/pull-requests/committing-changes-to-your-project/creating-and-editing-commits/changing-a-commit-message) and force push those changes to update this PR."
|
117
CONTRIBUTING.md
117
CONTRIBUTING.md
@ -1,7 +1,7 @@
|
||||
# Code of Conduct
|
||||
|
||||
We have a [code of conduct](CODE_OF_CONDUCT.md) that we all must
|
||||
read. Be polite to everyone. If you are not in your best day, take a
|
||||
follow. Be polite to everyone. If you are not in your best day, take a
|
||||
deep breath and try again. Smile :smile:
|
||||
|
||||
# New Issues
|
||||
@ -24,31 +24,33 @@ check the following items:
|
||||
* See how to get the source code correctly in the [INSTALL](INSTALL.md) guide.
|
||||
* Check if you are using the latest repository clone.
|
||||
* Remember that we use submodules, so you need to initialize and update them.
|
||||
* Search in the [GitHub issues about compilation](https://github.com/aseprite/aseprite/issues?q=is%3Aissue+label%3Acompilation)
|
||||
if someone else had the same problem.
|
||||
* Remember that might be some [pull requests](https://github.com/aseprite/aseprite/pulls)
|
||||
being reviewed to fix your same problem.
|
||||
being reviewed to fix your same issue.
|
||||
|
||||
If you have a compilation problem, you can ask in the
|
||||
[Development category](https://community.aseprite.org/c/development)
|
||||
in the [Community site](https://community.aseprite.org/) for help
|
||||
or creating a [GitHub issue](https://github.com/aseprite/aseprite/issues/new).
|
||||
or create a [new GitHub issue](https://github.com/aseprite/aseprite/issues/new).
|
||||
|
||||
# Contributing
|
||||
|
||||
One of the easiest ways to contribute is writing articles,
|
||||
[Steam reviews](https://steamcommunity.com/app/431730/reviews/),
|
||||
blog posts, recording video tutorials,
|
||||
[creating pixel art](https://aseprite.deviantart.com/), or showing your love
|
||||
to Aseprite e.g. naming Aseprite in your website and linking it to
|
||||
https://www.aseprite.org/, following
|
||||
[@aseprite](https://twitter.com/aseprite) twitter account, or
|
||||
[buying an extra Aseprite copy to your friend](https://www.aseprite.org/download/).
|
||||
One of the easiest ways to contribute is writing articles, [Steam
|
||||
reviews](https://steamcommunity.com/app/431730/reviews/), blog posts,
|
||||
recording video tutorials, creating pixel art in social media with
|
||||
[#aseprite](https://twitter.com/search?q=%23aseprite), or showing your
|
||||
love to Aseprite, e.g. naming Aseprite in your website and linking it
|
||||
to https://www.aseprite.org/, following [@aseprite](https://twitter.com/aseprite),
|
||||
or [buying an extra Aseprite copy to your friends](https://www.aseprite.org/download/).
|
||||
|
||||
Other ways to contribute require direct contact with us. For example:
|
||||
|
||||
* [Writing documentation](https://github.com/aseprite/docs).
|
||||
* Making art with Aseprite and for Aseprite (logos, skins, mockups).
|
||||
* Making art (and fan art) with Aseprite and for Aseprite (logos, skins, mockups).
|
||||
* Sending patches for features or bug fixes.
|
||||
* Reviewing issues in the [issue tracker](https://github.com/aseprite/aseprite/issues) and making comments.
|
||||
* Reviewing issues in the [issue tracker](https://github.com/aseprite/aseprite/issues)
|
||||
and making comments.
|
||||
* Helping other users in the [Community](https://community.aseprite.org/) site.
|
||||
|
||||
## Documentation
|
||||
@ -56,15 +58,16 @@ Other ways to contribute require direct contact with us. For example:
|
||||
You can start seeing the
|
||||
[documentation](https://www.aseprite.org/docs/), and
|
||||
[contact us](mailto:support@aseprite.org) if you want to help
|
||||
writting documentation
|
||||
or recording [tutorials](https://www.aseprite.org/docs/tutorial/).
|
||||
writing documentation or recording [tutorials](https://www.aseprite.org/docs/tutorial/).
|
||||
|
||||
If you are going to write documentation, we recommend you to take
|
||||
screenshots or record a GIF animations to show steps:
|
||||
If you are going to write some docs, we recommend you to take
|
||||
screenshots or record a GIF animations to showcase the feature your
|
||||
are documenting or the steps to follow:
|
||||
|
||||
* As screen recording software, on Windows you can generate GIF files
|
||||
using [LICEcap](http://www.cockos.com/licecap/).
|
||||
* You can upload the PNG/GIF images to [Imgur](http://imgur.com/).
|
||||
* PNG/GIF images can be uploaded in the same docs repository
|
||||
[with a pull request](https://github.com/aseprite/docs/pulls)
|
||||
|
||||
## Reviewing Issues
|
||||
|
||||
@ -74,54 +77,54 @@ new [features](https://community.aseprite.org/c/features),
|
||||
[bug reports](https://community.aseprite.org/c/bugs), etc. You are
|
||||
encouraged to create mockups for any issue you see and attach them.
|
||||
|
||||
## Hacking
|
||||
## Code submission policy
|
||||
|
||||
The first thing to keep in mind if you want to modify the source code:
|
||||
checkout the **main** branch. It is the branch that we use to
|
||||
develop new features and fix issues that are planned for the next big
|
||||
release. See the [INSTALL](INSTALL.md) guide to know how to compile.
|
||||
We have some rules for the changes and commits that are contributed:
|
||||
|
||||
To start looking the source code, see how it is organized in
|
||||
[src/README.md](https://github.com/aseprite/aseprite/tree/main/src/#aseprite-source-code)
|
||||
file.
|
||||
* First of all you will need to sign our
|
||||
[Contributor License Agreement](https://github.com/igarastudio/cla) (CLA)
|
||||
to submit your code.
|
||||
* Split your changes in the most atomic commits possible: one commit
|
||||
for feature, or fix.
|
||||
* Rebase your commits to the `main` branch (or `beta` if you are
|
||||
targeting the beta version).
|
||||
* Wrap your commit messages at 72 characters.
|
||||
* The first line of the commit message is the subject line.
|
||||
* Write the subject line in the imperative mood, e.g. "Fix something",
|
||||
not "Fixed something".
|
||||
* For platform-specific commits start the subject line using
|
||||
`[win]`, `[osx]`, or `[x11]` prefixes.
|
||||
* For CLI related commits you can use the `[cli]` prefix in the
|
||||
subject line.
|
||||
* For Lua scripting related commits can use the `[lua]` prefix in
|
||||
the subject line.
|
||||
* Check the spelling of your code, comments and commit messages.
|
||||
* Follow our [coding style guide](docs/CODING_STYLE.md). We're using
|
||||
some C++17 features, targeting macOS 10.9 mainly as the oldest
|
||||
platform (and the one limiting us to newer C++ standards),
|
||||
|
||||
## Forking & Pull Requests
|
||||
You can also take a look at the [src/README.md](https://github.com/aseprite/aseprite/tree/main/src/#aseprite-source-code)
|
||||
guide which contains some information about how the code is structured.
|
||||
|
||||
You can fork the GitHub repository using the Fork button at
|
||||
[https://github.com/aseprite/aseprite](https://github.com/aseprite/aseprite).
|
||||
|
||||
The Pull Requests (PR) systems works in this way:
|
||||
|
||||
1. First of all you will need to sign our
|
||||
[Contributor License Agreement](https://github.com/igarastudio/cla) (CLA).
|
||||
1. Then you can start working on Aseprite. Create a new branch from `main`, e.g. `fix-8` to fix the issue 8.
|
||||
Check this guide about [how to name your branch](https://github.com/agis/git-style-guide#branches).
|
||||
1. Start working on that new branch, and push your commits to your fork.
|
||||
1. Create a new PR to merge your `fix-8` branch to the official `main`.
|
||||
1. If the PR is accepted (does not require review/comments/modifications),
|
||||
your branch is merged into `main`.
|
||||
1. You will need to pull changes from the official `main` branch, and
|
||||
merge them in your own `main` branch. Finally you can discard your
|
||||
own `fix-8` branch (because those changes should be already merged
|
||||
into `main` if the PR was accepted).
|
||||
1. Continue working from the new `main` head.
|
||||
|
||||
To keep in mind: **always** start working from the `main` head, if you
|
||||
want to fix three different issues, create three different branches
|
||||
from `main` and then send three different PR. Do not chain all the
|
||||
fixes in one single branch. E.g. `fix-issues-3-and-8-and-25`.
|
||||
|
||||
## Community
|
||||
# Community
|
||||
|
||||
You can use the [Development category](https://community.aseprite.org/c/development)
|
||||
to ask question about the code, how to compile, etc.
|
||||
If you want to start working in something
|
||||
to ask questions about the code, how to compile, etc.
|
||||
If you want to start working on something
|
||||
([issue](https://github.com/aseprite/aseprite/issues),
|
||||
[bug](https://community.aseprite.org/c/bugs),
|
||||
or [feature](https://community.aseprite.org/c/features)),
|
||||
post a comment asking if somebody is already working on that,
|
||||
in that way you can avoid start programming in something that is already
|
||||
in that way you can avoid starting programming in something that is already
|
||||
done for the next release or which someone else is working on.
|
||||
|
||||
And always remember to take a look at our
|
||||
[roadmap](http://www.aseprite.org/roadmap/).
|
||||
# Future
|
||||
|
||||
If you want to contribute a new feature, I highly recommend trying to
|
||||
contribute a couple of pull requests to fix some bugs first. After
|
||||
that you can check what are the features we're planning for the
|
||||
future:
|
||||
|
||||
* Our [roadmap](http://www.aseprite.org/roadmap/) and our [planning](https://github.com/orgs/aseprite/projects/10).
|
||||
* The most liked [issues on GitHub](https://github.com/aseprite/aseprite/issues?q=is%3Aissue+is%3Aopen+sort%3Areactions-%2B1-desc).
|
||||
* [Features on the forum](https://community.aseprite.org/c/features/7/l/latest?order=votes) with the most votes.
|
||||
|
2
laf
2
laf
@ -1 +1 @@
|
||||
Subproject commit c90b81aec001293bdf7d19eb7feb22509716705e
|
||||
Subproject commit 10caee2455d07676d79a69a102399080f5eba4a9
|
@ -74,6 +74,7 @@ AppOptions::AppOptions(int argc, const char* argv[])
|
||||
, m_scriptParam(m_po.add("script-param").requiresValue("name=value").description("Parameter for a script executed from the\nCLI that you can access with app.params"))
|
||||
#endif
|
||||
, m_listLayers(m_po.add("list-layers").description("List layers of the next given sprite\nor include layers in JSON data"))
|
||||
, m_listLayerHierarchy(m_po.add("list-layer-hierarchy").description("List layers with groups of the next given sprite\nor include layers hierarchy in JSON data"))
|
||||
, m_listTags(m_po.add("list-tags").description("List tags of the next given sprite\nor include frame tags in JSON data"))
|
||||
, m_listSlices(m_po.add("list-slices").description("List slices of the next given sprite\nor include slices in JSON data"))
|
||||
, m_oneFrame(m_po.add("oneframe").description("Load just the first frame"))
|
||||
|
@ -90,6 +90,7 @@ public:
|
||||
const Option& scriptParam() const { return m_scriptParam; }
|
||||
#endif
|
||||
const Option& listLayers() const { return m_listLayers; }
|
||||
const Option& listLayerHierarchy() const { return m_listLayerHierarchy; }
|
||||
const Option& listTags() const { return m_listTags; }
|
||||
const Option& listSlices() const { return m_listSlices; }
|
||||
const Option& oneFrame() const { return m_oneFrame; }
|
||||
@ -164,6 +165,7 @@ private:
|
||||
Option& m_scriptParam;
|
||||
#endif
|
||||
Option& m_listLayers;
|
||||
Option& m_listLayerHierarchy;
|
||||
Option& m_listTags;
|
||||
Option& m_listSlices;
|
||||
Option& m_oneFrame;
|
||||
|
@ -37,6 +37,7 @@ namespace app {
|
||||
bool splitGrid = false;
|
||||
bool allLayers = false;
|
||||
bool listLayers = false;
|
||||
bool listLayerHierarchy = false;
|
||||
bool listTags = false;
|
||||
bool listSlices = false;
|
||||
bool ignoreEmpty = false;
|
||||
|
@ -587,6 +587,13 @@ int CliProcessor::process(Context* ctx)
|
||||
else
|
||||
cof.listLayers = true;
|
||||
}
|
||||
// --list-layer-hierarchy
|
||||
else if (opt == &m_options.listLayerHierarchy()) {
|
||||
if (m_exporter)
|
||||
m_exporter->setListLayerHierarchy(true);
|
||||
else
|
||||
cof.listLayerHierarchy = true;
|
||||
}
|
||||
// --list-tags
|
||||
else if (opt == &m_options.listTags()) {
|
||||
if (m_exporter)
|
||||
|
@ -67,6 +67,10 @@ void DefaultCliDelegate::afterOpenFile(const CliOpenFile& cof)
|
||||
std::cout << layer->name() << "\n";
|
||||
}
|
||||
|
||||
if (cof.listLayerHierarchy) {
|
||||
std::cout << cof.document->sprite()->visibleLayerHierarchyAsString() << "\n";
|
||||
}
|
||||
|
||||
if (cof.listTags) {
|
||||
for (doc::Tag* tag : cof.document->sprite()->tags())
|
||||
std::cout << tag->name() << "\n";
|
||||
|
@ -67,6 +67,9 @@ void PreviewCliDelegate::afterOpenFile(const CliOpenFile& cof)
|
||||
if (cof.listLayers)
|
||||
std::cout << " - List layers\n";
|
||||
|
||||
if (cof.listLayerHierarchy)
|
||||
std::cout << " - List layer hierarchy\n";
|
||||
|
||||
if (cof.listTags)
|
||||
std::cout << " - List tags\n";
|
||||
|
||||
|
@ -623,6 +623,7 @@ void DocExporter::reset()
|
||||
m_splitTags = false;
|
||||
m_listTags = false;
|
||||
m_listLayers = false;
|
||||
m_listLayerHierarchy = false;
|
||||
m_listSlices = false;
|
||||
m_documents.clear();
|
||||
}
|
||||
@ -1487,7 +1488,7 @@ void DocExporter::createDataFile(const Samples& samples,
|
||||
}
|
||||
|
||||
// meta.layers
|
||||
if (m_listLayers) {
|
||||
if (m_listLayers || m_listLayerHierarchy) {
|
||||
LayerList metaLayers;
|
||||
for (auto& item : m_documents) {
|
||||
if (item.isOneImageOnly())
|
||||
|
@ -77,6 +77,7 @@ namespace app {
|
||||
void setSplitTags(bool splitTags) { m_splitTags = splitTags; }
|
||||
void setListTags(bool value) { m_listTags = value; }
|
||||
void setListLayers(bool value) { m_listLayers = value; }
|
||||
void setListLayerHierarchy(bool value) { m_listLayerHierarchy = value; }
|
||||
void setListSlices(bool value) { m_listSlices = value; }
|
||||
|
||||
void addImage(
|
||||
@ -180,6 +181,7 @@ namespace app {
|
||||
bool m_splitTags;
|
||||
bool m_listTags;
|
||||
bool m_listLayers;
|
||||
bool m_listLayerHierarchy;
|
||||
bool m_listSlices;
|
||||
Items m_documents;
|
||||
|
||||
|
@ -50,6 +50,13 @@ FILE* lua_user_fopen(const char* fname,
|
||||
return base::open_file_raw(fname, mode);
|
||||
}
|
||||
|
||||
FILE* lua_user_freopen(const char* fname,
|
||||
const char* mode,
|
||||
FILE* stream)
|
||||
{
|
||||
return base::reopen_file_raw(fname, mode, stream);
|
||||
}
|
||||
|
||||
namespace app {
|
||||
namespace script {
|
||||
|
||||
|
@ -540,6 +540,20 @@ void LayerGroup::allTilemaps(LayerList& list) const
|
||||
}
|
||||
}
|
||||
|
||||
std::string LayerGroup::visibleLayerHierarchyAsString(const std::string& indent) const
|
||||
{
|
||||
std::string str;
|
||||
for (Layer* child : m_layers) {
|
||||
if (!child->isVisible())
|
||||
continue;
|
||||
|
||||
str += indent + child->name() + (child->isGroup() ? "/" : "") + "\n";
|
||||
if (child->isGroup())
|
||||
str += static_cast<LayerGroup*>(child)->visibleLayerHierarchyAsString(indent+" ");
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
void LayerGroup::getCels(CelList& cels) const
|
||||
{
|
||||
for (const Layer* layer : m_layers)
|
||||
|
@ -215,6 +215,7 @@ namespace doc {
|
||||
void allVisibleReferenceLayers(LayerList& list) const;
|
||||
void allBrowsableLayers(LayerList& list) const;
|
||||
void allTilemaps(LayerList& list) const;
|
||||
std::string visibleLayerHierarchyAsString(const std::string& indent) const;
|
||||
|
||||
void getCels(CelList& cels) const override;
|
||||
void displaceFrames(frame_t fromThis, frame_t delta) override;
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite Document Library
|
||||
// Copyright (c) 2020-2022 Igara Studio S.A.
|
||||
// Copyright (c) 2020-2024 Igara Studio S.A.
|
||||
// Copyright (c) 2001-2016 David Capello
|
||||
//
|
||||
// This file is released under the terms of the MIT license.
|
||||
@ -11,6 +11,7 @@
|
||||
|
||||
#include "base/debug.h"
|
||||
#include "base/disable_copying.h"
|
||||
#include "base/ints.h"
|
||||
#include "doc/object.h"
|
||||
#include "doc/rgbmap.h"
|
||||
|
||||
@ -23,7 +24,7 @@ namespace doc {
|
||||
// It acts like a cache for Palette:findBestfit() calls.
|
||||
class RgbMapRGB5A3 : public RgbMap {
|
||||
// Bit activated on m_map entries that aren't yet calculated.
|
||||
const int INVALID = 256;
|
||||
const uint16_t INVALID = 256;
|
||||
|
||||
public:
|
||||
RgbMapRGB5A3();
|
||||
@ -31,13 +32,13 @@ namespace doc {
|
||||
// RgbMap impl
|
||||
void regenerateMap(const Palette* palette, int maskIndex) override;
|
||||
int mapColor(const color_t rgba) const override {
|
||||
const int r = rgba_getr(rgba);
|
||||
const int g = rgba_getg(rgba);
|
||||
const int b = rgba_getb(rgba);
|
||||
const int a = rgba_geta(rgba);
|
||||
const uint8_t r = rgba_getr(rgba);
|
||||
const uint8_t g = rgba_getg(rgba);
|
||||
const uint8_t b = rgba_getb(rgba);
|
||||
const uint8_t a = rgba_geta(rgba);
|
||||
// bits -> bbbbbgggggrrrrraaa
|
||||
const int i = (a>>5) | ((b>>3) << 3) | ((g>>3) << 8) | ((r>>3) << 13);
|
||||
const int v = m_map[i];
|
||||
const uint32_t i = (a>>5) | ((b>>3) << 3) | ((g>>3) << 8) | ((r>>3) << 13);
|
||||
const uint16_t v = m_map[i];
|
||||
return (v & INVALID) ? generateEntry(i, r, g, b, a): v;
|
||||
}
|
||||
|
||||
|
@ -773,6 +773,11 @@ LayerList Sprite::allTilemaps() const
|
||||
return list;
|
||||
}
|
||||
|
||||
std::string Sprite::visibleLayerHierarchyAsString() const
|
||||
{
|
||||
return m_root->visibleLayerHierarchyAsString("");
|
||||
}
|
||||
|
||||
CelsRange Sprite::cels() const
|
||||
{
|
||||
SelectedFrames selFrames;
|
||||
|
@ -219,6 +219,7 @@ namespace doc {
|
||||
LayerList allVisibleReferenceLayers() const;
|
||||
LayerList allBrowsableLayers() const;
|
||||
LayerList allTilemaps() const;
|
||||
std::string visibleLayerHierarchyAsString() const;
|
||||
|
||||
CelsRange cels() const;
|
||||
CelsRange cels(frame_t frame) const;
|
||||
|
@ -8,3 +8,9 @@ assert(100 == math.min(100, 200, 300))
|
||||
assert(300 == math.max(100, 200, 300))
|
||||
assert(50 == math.fmod(250, 100))
|
||||
assert(3141 == math.floor(1000*math.pi))
|
||||
|
||||
-- Add tests for integer <-> number comparisons
|
||||
assert(math.floor(0.5) == 0)
|
||||
assert(math.floor(0.5) == 0.0)
|
||||
assert(math.floor(0.5) ~= 0.5)
|
||||
assert(math.floor(0.5)+0.1-0.1 ~= 0.5)
|
||||
|
@ -133,8 +133,8 @@ for _,cm in ipairs{ ColorMode.RGB,
|
||||
app.sprite = spr
|
||||
app.command.SaveFileCopyAs{ filename=fn, slice="small_slice", scale=scale }
|
||||
local c = app.open(fn)
|
||||
assert(c.width == slice.bounds.width*scale)
|
||||
assert(c.height == slice.bounds.height*scale)
|
||||
assert(c.width == math.floor(slice.bounds.width*scale))
|
||||
assert(c.height == math.floor(slice.bounds.height*scale))
|
||||
|
||||
local testImg = Image(spr.cels[1].image, spr.slices[1].bounds)
|
||||
fix_images(testImg, scale, fileExt, c, cm, c1)
|
||||
|
@ -21,8 +21,8 @@ do
|
||||
a:resize(6, 8)
|
||||
assert(a.width == 6)
|
||||
assert(a.height == 8)
|
||||
assert(a.cels[1].image.width == 32 * 6 / 4) -- Check that the image was resized (not only the canvas)
|
||||
assert(a.cels[1].image.height == 64 * 8 / 5)
|
||||
assert(a.cels[1].image.width == math.floor(32 * 6 / 4)) -- Check that the image was resized (not only the canvas)
|
||||
assert(a.cels[1].image.height == math.floor(64 * 8 / 5))
|
||||
a:crop{x=-1, y=-1, width=20, height=30}
|
||||
assert(a.width == 20)
|
||||
assert(a.height == 30)
|
||||
|
2
third_party/lua
vendored
2
third_party/lua
vendored
@ -1 +1 @@
|
||||
Subproject commit 04abf20c9e8c973c62b30d0b98f6884ff665b1ba
|
||||
Subproject commit 2a00e6b0013f54ce80b6e3cefe6514e13229987a
|
Loading…
x
Reference in New Issue
Block a user