Merge branch 'main' into beta

This commit is contained in:
David Capello 2024-11-06 18:01:44 -03:00
commit a9d795b6df
25 changed files with 202 additions and 54 deletions

3
.gitmodules vendored
View File

@ -81,3 +81,6 @@
[submodule "third_party/tinyxml2"]
path = third_party/tinyxml2
url = https://github.com/aseprite/tinyxml2.git
[submodule "third_party/TinyEXIF"]
path = third_party/TinyEXIF
url = https://github.com/aseprite/TinyEXIF.git

View File

@ -1050,6 +1050,7 @@
<param name="preview" value="true" />
<param name="checkedIfZero" value="true" />
</item>
<item command="ShowBrushPreviewInPreview" text="@.view_preview_brush_preview"/>
</menu>
<item command="AdvancedMode" text="@.view_advanced_mode" />
<item command="FullscreenMode" text="@.view_full_screen_mode" />

View File

@ -614,6 +614,7 @@
<option id="grid" type="bool" default="false" />
<option id="pixel_grid" type="bool" default="false" />
<option id="brush_preview" type="bool" default="true" />
<option id="brush_preview_in_preview" type="bool" default="false" />
<option id="slices" type="bool" default="true" />
<option id="auto_guides" type="bool" default="true" />
<option id="tile_numbers" type="bool" default="true" />

View File

@ -441,6 +441,7 @@ SetPlaybackSpeed = Playback Speed {0}x
SetSameInk = Same Ink in All Tools
ShowAutoGuides = Show Auto Guides
ShowBrushPreview = Show Brush Preview
ShowBrushPreviewInPreview = Show Brush Preview in Preview
ShowBrushes = Show Brushes
ShowDynamics = Show Dynamics
ShowExtras = Show Extras
@ -1172,6 +1173,7 @@ view_show_onion_skin = Show &Onion Skin
view_timeline = &Timeline
view_preview = Previe&w
view_preview_hide_other_layers = &Hide Other Layers
view_preview_brush_preview = &Brush Preview
view_advanced_mode = &Advanced Mode
view_full_screen_mode = &Full Screen Mode
view_full_screen_preview = F&ull Screen Preview
@ -1430,6 +1432,7 @@ brush_preview_edges = Edges Only
brush_preview_full = Full Preview
brush_preview_fullall = Full Preview with All Tools
brush_preview_fullnedges = Full Preview and Edges
brush_preview_in_preview = Brush Preview in Preview
cursor_color_type = Crosshair && Brush Edges Color:
cursor_neg_bw = Negative Black and White
cursor_specific_color = Specific Color

View File

@ -1129,6 +1129,33 @@ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
```
# [TinyEXIF](https://github.com/cdcseacave/TinyEXIF)
```
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS "AS IS" AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FREEBSD PROJECT OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
```
# [tinyexpr](https://github.com/codeplea/tinyexpr)
```

2
laf

@ -1 +1 @@
Subproject commit acb17f472a29e2bfb3fe04e16e12cdc08c41047b
Subproject commit 1ddaf36637e9eb27bf6f08608de6d01b3d3b3932

View File

@ -19,12 +19,9 @@ if(MSVC)
if(LAF_BACKEND STREQUAL "skia")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /LTCG")
endif()
add_definitions(-D_SCL_SECURE_NO_WARNINGS)
add_definitions(-wd4267) # disable warnings about signed/unsigned comparison
add_definitions(-wd4244) # disable warnings about possible loss of data
else()
# disable warnings about signed/unsigned comparison
# Disable warnings about signed/unsigned comparison.
# TODO we should remove this (or move it to laf-base)
add_definitions(-Wno-sign-compare)
endif()

View File

@ -759,6 +759,7 @@ target_link_libraries(app-lib
archive_static
fmt
tinyexpr
TinyEXIFstatic
qoi)
if(ENABLE_WEBP AND WEBP_FOUND)

View File

@ -33,11 +33,6 @@ namespace app {
using namespace ui;
using namespace app::skin;
// Disable warning about usage of "this" in initializer list.
#ifdef _MSC_VER
#pragma warning(disable:4355)
#endif
struct CanvasSizeParams : public NewParams {
Param<bool> ui { this, true, "ui" };
Param<int> left { this, 0, "left" };

View File

@ -148,6 +148,24 @@ protected:
}
};
class ShowBrushPreviewInPreviewCommand : public Command {
public:
ShowBrushPreviewInPreviewCommand()
: Command(CommandId::ShowBrushPreviewInPreview(), CmdUIOnlyFlag) {
}
protected:
bool onChecked(Context* ctx) override {
DocumentPreferences& docPref = Preferences::instance().document(ctx->activeDocument());
return docPref.show.brushPreviewInPreview();
}
void onExecute(Context* ctx) override {
DocumentPreferences& docPref = Preferences::instance().document(ctx->activeDocument());
docPref.show.brushPreviewInPreview(!docPref.show.brushPreviewInPreview());
}
};
class ShowAutoGuidesCommand : public Command {
public:
ShowAutoGuidesCommand()
@ -232,6 +250,11 @@ Command* CommandFactory::createShowBrushPreviewCommand()
return new ShowBrushPreviewCommand;
}
Command* CommandFactory::createShowBrushPreviewInPreviewCommand()
{
return new ShowBrushPreviewInPreviewCommand;
}
Command* CommandFactory::createShowAutoGuidesCommand()
{
return new ShowAutoGuidesCommand;

View File

@ -145,6 +145,7 @@ FOR_EACH_COMMAND(SetPlaybackSpeed)
FOR_EACH_COMMAND(SetSameInk)
FOR_EACH_COMMAND(ShowAutoGuides)
FOR_EACH_COMMAND(ShowBrushPreview)
FOR_EACH_COMMAND(ShowBrushPreviewInPreview)
FOR_EACH_COMMAND(ShowExtras)
FOR_EACH_COMMAND(ShowGrid)
FOR_EACH_COMMAND(ShowLayerEdges)

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2023 Igara Studio S.A.
// Copyright (C) 2023-2024 Igara Studio S.A.
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.
@ -87,7 +87,10 @@ void ToggleOtherLayersOpacityCommand::onExecute(Context* ctx)
if (params().preview()) {
PreviewEditorWindow* previewWin =
App::instance()->mainWindow()->getPreviewEditor();
previewWin->previewEditor()->invalidate();
if (previewWin &&
previewWin->previewEditor()) {
previewWin->previewEditor()->invalidate();
}
}
else {
app_refresh_screen();

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2020 Igara Studio S.A.
// Copyright (C) 2020-2024 Igara Studio S.A.
// Copyright (C) 2001-2016 David Capello
//
// This program is distributed under the terms of
@ -16,12 +16,14 @@
namespace app {
ExtraCel::ExtraCel()
: m_type(render::ExtraType::NONE)
: m_purpose(Purpose::Unknown)
, m_type(render::ExtraType::NONE)
, m_blendMode(doc::BlendMode::NORMAL)
{
}
void ExtraCel::create(const TilemapMode tilemapMode,
void ExtraCel::create(Purpose purpose,
const TilemapMode tilemapMode,
doc::Sprite* sprite,
const gfx::Rect& bounds,
const gfx::Size& imageSize,
@ -30,6 +32,8 @@ void ExtraCel::create(const TilemapMode tilemapMode,
{
ASSERT(sprite);
m_purpose = purpose;
doc::PixelFormat pixelFormat;
if (tilemapMode == TilemapMode::Tiles)
pixelFormat = doc::IMAGE_TILEMAP;
@ -60,6 +64,7 @@ void ExtraCel::create(const TilemapMode tilemapMode,
void ExtraCel::reset()
{
m_purpose = Purpose::Unknown;
m_type = render::ExtraType::NONE;
m_image.reset();
m_cel.reset();

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2019-2020 Igara Studio S.A.
// Copyright (C) 2019-2024 Igara Studio S.A.
// Copyright (C) 2001-2018 David Capello
//
// This program is distributed under the terms of
@ -29,9 +29,16 @@ namespace app {
class ExtraCel {
public:
enum class Purpose {
Unknown,
BrushPreview,
TransformationPreview,
};
ExtraCel();
void create(const TilemapMode tilemapMode,
void create(Purpose purpose,
const TilemapMode tilemapMode,
doc::Sprite* sprite,
const gfx::Rect& bounds,
const gfx::Size& imageSize,
@ -39,6 +46,8 @@ namespace app {
const int opacity);
void reset();
Purpose purpose() const { return m_purpose; }
render::ExtraType type() const { return m_type; }
void setType(render::ExtraType type) { m_type = type; }
@ -49,6 +58,7 @@ namespace app {
void setBlendMode(doc::BlendMode mode) { m_blendMode = mode; }
private:
Purpose m_purpose;
render::ExtraType m_type;
std::unique_ptr<doc::Cel> m_cel;
doc::ImageRef m_image;

View File

@ -1,5 +1,5 @@
// Aseprite
// Copyright (C) 2018-2023 Igara Studio S.A.
// Copyright (C) 2018-2024 Igara Studio S.A.
// Copyright (C) 2001-2018 David Capello
//
// This program is distributed under the terms of
@ -27,10 +27,12 @@
#include <csetjmp>
#include <cstdio>
#include <cstdlib>
#include <fstream>
#include "jpeg_options.xml.h"
#include "jpeglib.h"
#include "TinyEXIF.h"
namespace app {
@ -177,12 +179,24 @@ bool JpegFormat::onLoad(FileOp* fop)
// Start decompressor.
jpeg_start_decompress(&dinfo);
// Get orientation:
TinyEXIF::EXIFInfo info;
int orientation = 0;
{
std::ifstream istream(fop->filename(), std::ifstream::in | std::ifstream::binary);
// Get EXIF information:
TinyEXIF::EXIFInfo info(istream);
if (info.Fields != 0)
orientation = info.Orientation;
}
const int outputW = (orientation < 5 ? dinfo.output_width : dinfo.output_height);
const int outputH = (orientation < 5 ? dinfo.output_height : dinfo.output_width);
// Create the image.
ImageRef image = fop->sequenceImageToLoad(
(dinfo.out_color_space == JCS_RGB ? IMAGE_RGB:
IMAGE_GRAYSCALE),
dinfo.output_width,
dinfo.output_height);
outputW,
outputH);
if (!image) {
jpeg_destroy_decompress(&dinfo);
return false;
@ -217,6 +231,61 @@ bool JpegFormat::onLoad(FileOp* fop)
while (dinfo.output_scanline < dinfo.output_height) {
num_scanlines = jpeg_read_scanlines(&dinfo, buffer, buffer_height);
// Orientation function/variables adjust
std::function<int(int)> start_dst_x;
std::function<int(int)> start_dst_y;
int next_addr_increment = 1;
switch (orientation) {
case 2:
start_dst_x = [image](int) { return image->width() - 1; };
start_dst_y = [dinfo](int y) {
return dinfo.output_scanline - 1 + y; };
next_addr_increment = -1;
break;
case 3:
start_dst_x = [image](int) { return image->width() - 1; };
start_dst_y = [image, dinfo](int y) {
return image->height() - dinfo.output_scanline + y; };
next_addr_increment = -1;
break;
case 4:
start_dst_x = [](int) { return 0; };
start_dst_y = [image, dinfo](int y) {
return image->height() - dinfo.output_scanline - y; };
next_addr_increment = 1;
break;
case 5:
start_dst_x = [dinfo](int y) {
return dinfo.output_scanline - 1 + y; };
start_dst_y = [](int) { return 0; };
next_addr_increment = image->width();
break;
case 6:
start_dst_x = [image, dinfo](int y) {
return image->width() - dinfo.output_scanline - y; };
start_dst_y = [](int) { return 0; };
next_addr_increment = image->width();
break;
case 7:
start_dst_x = [image, dinfo](int y) {
return image->width() - dinfo.output_scanline - y; };
start_dst_y = [image](int) { return image->height() - 1; };
next_addr_increment = -image->width();
break;
case 8:
start_dst_x = [dinfo](int y) {
return dinfo.output_scanline - 1 + y; };
start_dst_y = [image](int) { return image->height() - 1; };
next_addr_increment = -image->width();
break;
default:
start_dst_x = [](int) { return 0; };
start_dst_y = [dinfo](int y) {
return dinfo.output_scanline - 1 + y; };
next_addr_increment = 1;
break;
}
// RGB
if (image->pixelFormat() == IMAGE_RGB) {
uint8_t* src_address;
@ -225,13 +294,14 @@ bool JpegFormat::onLoad(FileOp* fop)
for (y=0; y<(int)num_scanlines; y++) {
src_address = ((uint8_t**)buffer)[y];
dst_address = (uint32_t*)image->getPixelAddress(0, dinfo.output_scanline-1+y);
dst_address = (uint32_t*)image->getPixelAddress(start_dst_x(y), start_dst_y(y));
for (x=0; x<image->width(); x++) {
for (x=0; x<dinfo.output_width; x++) {
r = *(src_address++);
g = *(src_address++);
b = *(src_address++);
*(dst_address++) = rgba(r, g, b, 255);
*dst_address = rgba(r, g, b, 255);
dst_address += next_addr_increment;
}
}
}
@ -243,10 +313,12 @@ bool JpegFormat::onLoad(FileOp* fop)
for (y=0; y<(int)num_scanlines; y++) {
src_address = ((uint8_t**)buffer)[y];
dst_address = (uint16_t*)image->getPixelAddress(0, dinfo.output_scanline-1+y);
dst_address = (uint16_t*)image->getPixelAddress(start_dst_x(y), start_dst_y(y));
for (x=0; x<image->width(); x++)
*(dst_address++) = graya(*(src_address++), 255);
for (x=0; x<dinfo.output_width; x++) {
*dst_address = graya(*(src_address++), 255);
dst_address += next_addr_increment;
}
}
}

View File

@ -80,6 +80,11 @@ public:
: m_brushes(App::instance()->brushes())
, m_brush(brush)
, m_slot(slot) {
initTheme();
}
void onInitTheme(InitThemeEvent& ev) override {
ButtonSet::Item::onInitTheme(ev);
if (m_brush.hasBrush()) {
SkinPartPtr icon(new SkinPart);
icon->setBitmap(0, BrushPopup::createSurfaceForBrush(

View File

@ -220,6 +220,7 @@ protected:
void onInitTheme(InitThemeEvent& ev) override {
ButtonSet::onInitTheme(ev);
m_popupWindow.initTheme();
updateBrush();
}
private:

View File

@ -351,6 +351,7 @@ void BrushPreview::show(const gfx::Point& screenPos)
m_extraCel.reset(new ExtraCel);
m_extraCel->create(
ExtraCel::Purpose::BrushPreview,
tilemapMode,
document->sprite(),
extraCelBoundsInCanvas,

View File

@ -705,13 +705,23 @@ void Editor::drawOneSpriteUnclippedRect(ui::Graphics* g, const gfx::Rect& sprite
ExtraCelRef extraCel = m_document->extraCel();
if (extraCel &&
extraCel->type() != render::ExtraType::NONE) {
m_renderEngine->setExtraImage(
extraCel->type(),
extraCel->cel(),
extraCel->image(),
extraCel->blendMode(),
m_layer, m_frame);
extraCel->type() != render::ExtraType::NONE &&
// We render the extra cel if:
(// 1) it doesn't contains the brush preview (e.g. the user
// is transforming the selection),
extraCel->purpose() != ExtraCel::Purpose::BrushPreview
// 2) we are drawing the brush preview in a regular editor,
|| !m_docView->isPreview()
// 3) we are drawing the brush preview in a preview editor
// and preferences (brushPreviewInPreview) says that we
// should do that.
|| m_docPref.show.brushPreviewInPreview())) {
m_renderEngine->setExtraImage(extraCel->type(),
extraCel->cel(),
extraCel->image(),
extraCel->blendMode(),
m_layer,
m_frame);
}
// Render background first (e.g. new ShaderRenderer will paint the

View File

@ -1156,6 +1156,7 @@ void PixelsMovement::redrawExtraImage(Transformation* transformation)
}
m_extraCel->create(
ExtraCel::Purpose::TransformationPreview,
m_site.tilemapMode(),
m_document->sprite(),
bounds,

View File

@ -79,10 +79,6 @@ namespace app {
using namespace ui;
#ifdef _MSC_VER
#pragma warning(disable:4355) // warning C4355: 'this' : used in base member initializer list
#endif
StandbyState::StandbyState()
: m_decorator(new Decorator(this))
, m_transformSelectionHandlesAreVisible(false)

View File

@ -11,21 +11,6 @@
#define ASEPRITE_CONFIG_H_INCLUDED
// In MSVC
#ifdef _MSC_VER
// Avoid warnings about insecure standard C++ functions
#ifndef _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS
#endif
// Disable warning C4355 in MSVC: 'this' used in base member initializer list
#pragma warning(disable:4355)
// Disable warning C4710 in MSVC: function not inlined (generated by MSVC header files)
// https://docs.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-4-c4710
#pragma warning(disable:4710)
#endif
#include "base/base.h"
#include "base/debug.h"
#include "base/log.h"

View File

@ -54,6 +54,12 @@ if(NOT USE_SHARED_TINYXML)
add_subdirectory(tinyxml2)
endif()
set(BUILD_SHARED_LIBS OFF CACHE BOOL "build as shared library")
set(BUILD_STATIC_LIBS ON CACHE BOOL "build as static library")
set(LINK_CRT_STATIC_LIBS OFF CACHE BOOL "link CRT static library")
set(BUILD_DEMO OFF CACHE BOOL "build demo binary")
add_subdirectory(TinyEXIF)
if(REQUIRE_CURL AND NOT USE_SHARED_CURL)
set(BUILD_RELEASE_DEBUG_DIRS ON BOOL)
set(BUILD_CURL_EXE OFF CACHE BOOL "Set to ON to build curl executable.")

1
third_party/TinyEXIF vendored Submodule

@ -0,0 +1 @@
Subproject commit 2283d8094e42e6b6cef00d1d31ecadfe0d9e1f29

2
third_party/json11 vendored

@ -1 +1 @@
Subproject commit 92ba6ce0fa1f1c8fd8783b6930b52539b3861888
Subproject commit f1ff45a7cd3781ab2d6bfaa8552a74172b5e6a73