mirror of
https://github.com/aseprite/aseprite.git
synced 2025-03-14 04:19:12 +00:00
Merge branch '1.0'
Conflicts: src/app/color_utils.cpp src/app/tools/ink_processing.h
This commit is contained in:
commit
7615c22827
@ -275,12 +275,14 @@ DDRAW_SURFACE *gfx_directx_create_surface(int w, int h, LPDDPIXELFORMAT pixel_fo
|
||||
return NULL;
|
||||
|
||||
/* create the surface with the specified characteristics */
|
||||
surf->id = create_directdraw2_surface(w, h, pixel_format,type, 0);
|
||||
surf->id = create_directdraw2_surface(w, h, pixel_format, type, 0);
|
||||
if (!surf->id) {
|
||||
_AL_FREE(surf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
surf->w = w;
|
||||
surf->h = h;
|
||||
surf->flags = type;
|
||||
surf->lock_nesting = 0;
|
||||
|
||||
@ -303,6 +305,40 @@ void gfx_directx_destroy_surface(DDRAW_SURFACE *surf)
|
||||
|
||||
|
||||
|
||||
int gfx_directx_restore_surface(DDRAW_SURFACE *surf)
|
||||
{
|
||||
int type = (surf->flags & DDRAW_SURFACE_TYPE_MASK);
|
||||
HRESULT hr;
|
||||
|
||||
hr = IDirectDrawSurface2_Restore(surf->id);
|
||||
if (FAILED(hr)) {
|
||||
LPDIRECTDRAWSURFACE2 new_id;
|
||||
|
||||
hr = IDirectDrawSurface2_Release(surf->id);
|
||||
if (FAILED(hr))
|
||||
return -1;
|
||||
|
||||
new_id = create_directdraw2_surface(
|
||||
surf->w, surf->h, ddpixel_format, type, 0);
|
||||
if (!new_id) {
|
||||
surf->id = 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
surf->id = new_id;
|
||||
|
||||
if (type == DDRAW_SURFACE_PRIMARY) {
|
||||
hr = IDirectDrawSurface_SetClipper(surf->id, ddclipper);
|
||||
if (FAILED(hr))
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* gfx_directx_make_bitmap_from_surface:
|
||||
* Connects a DirectDraw surface with an Allegro bitmap.
|
||||
*/
|
||||
@ -315,7 +351,7 @@ BITMAP *gfx_directx_make_bitmap_from_surface(DDRAW_SURFACE *surf, int w, int h,
|
||||
if (!bmp)
|
||||
return NULL;
|
||||
|
||||
bmp->w =w;
|
||||
bmp->w = w;
|
||||
bmp->cr = w;
|
||||
bmp->h = h;
|
||||
bmp->cb = h;
|
||||
|
@ -114,17 +114,14 @@ void unregister_all_ddraw_surfaces(void)
|
||||
int restore_all_ddraw_surfaces(void)
|
||||
{
|
||||
DDRAW_SURFACE *item = ddraw_surface_list;
|
||||
HRESULT hr;
|
||||
|
||||
_enter_gfx_critical();
|
||||
|
||||
while (item) {
|
||||
hr = IDirectDrawSurface2_Restore(item->id);
|
||||
if (FAILED(hr)) {
|
||||
if (gfx_directx_restore_surface(item) != 0) {
|
||||
_exit_gfx_critical();
|
||||
return -1;
|
||||
}
|
||||
|
||||
item = item->next;
|
||||
}
|
||||
|
||||
|
@ -41,6 +41,7 @@
|
||||
/* wrapper for DirectDraw surfaces */
|
||||
typedef struct DDRAW_SURFACE {
|
||||
LPDIRECTDRAWSURFACE2 id;
|
||||
int w, h;
|
||||
int flags;
|
||||
int lock_nesting;
|
||||
BITMAP *parent_bmp; /* only used by the flipping chain */
|
||||
@ -138,6 +139,7 @@ AL_FUNCPTR(void, _al_wd_update_window, (RECT *rect));
|
||||
/* bitmap creation (from wddbmp.c) */
|
||||
AL_FUNC(DDRAW_SURFACE *, gfx_directx_create_surface, (int w, int h, LPDDPIXELFORMAT pixel_format, int type));
|
||||
AL_FUNC(void, gfx_directx_destroy_surface, (DDRAW_SURFACE *surf));
|
||||
AL_FUNC(int, gfx_directx_restore_surface, (DDRAW_SURFACE *surf));
|
||||
AL_FUNC(BITMAP *, gfx_directx_make_bitmap_from_surface, (DDRAW_SURFACE *surf, int w, int h, int id));
|
||||
|
||||
|
||||
|
@ -133,6 +133,8 @@ static void get_working_area(RECT *working_area)
|
||||
*/
|
||||
static void switch_in_win(void)
|
||||
{
|
||||
gfx_directx_compare_color_depth(desktop_color_depth());
|
||||
|
||||
restore_all_ddraw_surfaces();
|
||||
get_working_area(&working_area);
|
||||
}
|
||||
|
@ -119,31 +119,44 @@ doc::color_t color_utils::color_for_layer(const app::Color& color, Layer* layer)
|
||||
|
||||
doc::color_t color_utils::color_for_target(const app::Color& color, const ColorTarget& colorTarget)
|
||||
{
|
||||
if (color.getType() == app::Color::MaskType)
|
||||
return colorTarget.maskColor();
|
||||
|
||||
doc::color_t c = -1;
|
||||
|
||||
if (color.getType() == app::Color::MaskType) {
|
||||
c = colorTarget.maskColor();
|
||||
}
|
||||
else {
|
||||
switch (colorTarget.pixelFormat()) {
|
||||
case IMAGE_RGB:
|
||||
c = doc::rgba(color.getRed(), color.getGreen(), color.getBlue(), 255);
|
||||
break;
|
||||
case IMAGE_GRAYSCALE:
|
||||
c = doc::graya(color.getGray(), 255);
|
||||
break;
|
||||
case IMAGE_INDEXED:
|
||||
if (color.getType() == app::Color::IndexType) {
|
||||
c = color.getIndex();
|
||||
}
|
||||
else {
|
||||
c = get_current_palette()->findBestfit(
|
||||
color.getRed(),
|
||||
color.getGreen(),
|
||||
color.getBlue(),
|
||||
colorTarget.isTransparent() ?
|
||||
colorTarget.maskColor(): // Don't return the mask color
|
||||
-1); // Return any color, we are in a background layer.
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (colorTarget.pixelFormat()) {
|
||||
case IMAGE_RGB:
|
||||
c = doc::rgba(color.getRed(), color.getGreen(), color.getBlue(), 255);
|
||||
if (colorTarget.isBackground())
|
||||
c |= doc::rgba(0, 0, 0, 255);
|
||||
break;
|
||||
case IMAGE_GRAYSCALE:
|
||||
c = doc::graya(color.getGray(), 255);
|
||||
break;
|
||||
case IMAGE_INDEXED:
|
||||
if (color.getType() == app::Color::IndexType) {
|
||||
c = color.getIndex();
|
||||
}
|
||||
else {
|
||||
c = get_current_palette()->findBestfit(
|
||||
color.getRed(),
|
||||
color.getGreen(),
|
||||
color.getBlue(),
|
||||
colorTarget.isTransparent() ?
|
||||
colorTarget.maskColor(): // Don't return the mask color
|
||||
-1); // Return any color, we are in a background layer.
|
||||
}
|
||||
if (colorTarget.isBackground())
|
||||
c |= doc::graya(0, 255);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -20,10 +20,10 @@
|
||||
#include "app/settings/document_settings.h"
|
||||
#include "app/tools/shade_table.h"
|
||||
#include "app/tools/shading_options.h"
|
||||
#include "filters/neighboring_pixels.h"
|
||||
#include "doc/palette.h"
|
||||
#include "doc/rgbmap.h"
|
||||
#include "doc/sprite.h"
|
||||
#include "filters/neighboring_pixels.h"
|
||||
|
||||
namespace app {
|
||||
namespace tools {
|
||||
@ -475,14 +475,27 @@ private:
|
||||
|
||||
template<>
|
||||
void ReplaceInkProcessing<RgbTraits>::processPixel(int x, int y) {
|
||||
if (*m_srcAddress == m_color1)
|
||||
*m_dstAddress = rgba_blend_normal(*m_srcAddress, m_color2, m_opacity);
|
||||
color_t src = (*m_srcAddress);
|
||||
|
||||
// Colors (m_srcAddress and m_color1) match if:
|
||||
// * They are both completelly transparent (alpha == 0)
|
||||
// * Or they are not transparent and the RGB values are the same
|
||||
if ((rgba_geta(src) == 0 && rgba_geta(m_color1) == 0) ||
|
||||
(rgba_geta(src) > 0 && rgba_geta(m_color1) > 0 &&
|
||||
((src & rgba_rgb_mask) == (m_color1 & rgba_rgb_mask)))) {
|
||||
*m_dstAddress = rgba_blend_merge(src, m_color2, m_opacity);
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
void ReplaceInkProcessing<GrayscaleTraits>::processPixel(int x, int y) {
|
||||
if (*m_srcAddress == m_color1)
|
||||
*m_dstAddress = graya_blend_normal(*m_srcAddress, m_color2, m_opacity);
|
||||
color_t src = (*m_srcAddress);
|
||||
|
||||
if ((graya_geta(src) == 0 && graya_geta(m_color1) == 0) ||
|
||||
(graya_geta(src) > 0 && graya_geta(m_color1) > 0 &&
|
||||
((src & graya_v_mask) == (m_color1 & graya_v_mask)))) {
|
||||
*m_dstAddress = graya_blend_merge(src, m_color2, m_opacity);
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
|
@ -177,13 +177,23 @@ bool MovingPixelsState::onMouseDown(Editor* editor, MouseMessage* msg)
|
||||
{
|
||||
ASSERT(m_pixelsMovement != NULL);
|
||||
|
||||
Decorator* decorator = static_cast<Decorator*>(editor->decorator());
|
||||
Document* document = editor->document();
|
||||
// Set this editor as the active one and setup the ContextBar for
|
||||
// moving pixels. This is needed in case that the user is working
|
||||
// with a couple of Editors, in one is moving pixels and the other
|
||||
// one not.
|
||||
UIContext* ctx = UIContext::instance();
|
||||
ctx->setActiveView(editor->getDocumentView());
|
||||
|
||||
ContextBar* contextBar = App::instance()->getMainWindow()->getContextBar();
|
||||
contextBar->updateForMovingPixels();
|
||||
|
||||
// Start scroll loop
|
||||
if (checkForScroll(editor, msg))
|
||||
return true;
|
||||
|
||||
Decorator* decorator = static_cast<Decorator*>(editor->decorator());
|
||||
Document* document = editor->document();
|
||||
|
||||
// Transform selected pixels
|
||||
if (document->isMaskVisible() &&
|
||||
decorator->getTransformHandles(editor)) {
|
||||
@ -406,6 +416,10 @@ bool MovingPixelsState::onUpdateStatusBar(Editor* editor)
|
||||
// Before executing any command, we drop the pixels (go back to standby).
|
||||
void MovingPixelsState::onBeforeCommandExecution(Command* command)
|
||||
{
|
||||
// If the command is for other editor, we don't drop pixels.
|
||||
if (!isActiveEditor())
|
||||
return;
|
||||
|
||||
// We don't need to drop the pixels if a MoveMaskCommand of Content is executed.
|
||||
if (MoveMaskCommand* moveMaskCmd = dynamic_cast<MoveMaskCommand*>(command)) {
|
||||
if (moveMaskCmd->getTarget() == MoveMaskCommand::Content)
|
||||
@ -422,12 +436,18 @@ void MovingPixelsState::onBeforeCommandExecution(Command* command)
|
||||
|
||||
void MovingPixelsState::onBeforeFrameChanged(Editor* editor)
|
||||
{
|
||||
if (!isActiveDocument())
|
||||
return;
|
||||
|
||||
if (m_pixelsMovement)
|
||||
dropPixels(m_editor);
|
||||
}
|
||||
|
||||
void MovingPixelsState::onBeforeLayerChanged(Editor* editor)
|
||||
{
|
||||
if (!isActiveDocument())
|
||||
return;
|
||||
|
||||
if (m_pixelsMovement)
|
||||
dropPixels(m_editor);
|
||||
}
|
||||
@ -440,6 +460,9 @@ void MovingPixelsState::onSetMoveTransparentColor(app::Color newColor)
|
||||
|
||||
void MovingPixelsState::onDropPixels(ContextBarObserver::DropAction action)
|
||||
{
|
||||
if (!isActiveEditor())
|
||||
return;
|
||||
|
||||
switch (action) {
|
||||
|
||||
case ContextBarObserver::DropPixels:
|
||||
@ -478,4 +501,16 @@ gfx::Transformation MovingPixelsState::getTransformation(Editor* editor)
|
||||
return m_pixelsMovement->getTransformation();
|
||||
}
|
||||
|
||||
bool MovingPixelsState::isActiveDocument() const
|
||||
{
|
||||
Document* doc = UIContext::instance()->activeDocument();
|
||||
return (m_editor->document() == doc);
|
||||
}
|
||||
|
||||
bool MovingPixelsState::isActiveEditor() const
|
||||
{
|
||||
Editor* targetEditor = UIContext::instance()->activeEditor();
|
||||
return (targetEditor == m_editor);
|
||||
}
|
||||
|
||||
} // namespace app
|
||||
|
@ -78,6 +78,9 @@ namespace app {
|
||||
void setTransparentColor(const app::Color& color);
|
||||
void dropPixels(Editor* editor);
|
||||
|
||||
bool isActiveDocument() const;
|
||||
bool isActiveEditor() const;
|
||||
|
||||
// Helper member to move/translate selection and pixels.
|
||||
PixelsMovementPtr m_pixelsMovement;
|
||||
Editor* m_editor;
|
||||
|
@ -555,6 +555,8 @@ void StandbyState::transformSelection(Editor* editor, MouseMessage* msg, HandleT
|
||||
// Other editor is locking the document.
|
||||
|
||||
// TODO steal the PixelsMovement of the other editor and use it for this one.
|
||||
StatusBar::instance()->showTip(1000, "The sprite is locked in other editor");
|
||||
jmouse_set_cursor(kForbiddenCursor);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -97,6 +97,7 @@ int rgba_blend_merge(int back, int front, int opacity)
|
||||
int B_r, B_g, B_b, B_a;
|
||||
int F_r, F_g, F_b, F_a;
|
||||
int D_r, D_g, D_b, D_a;
|
||||
int t;
|
||||
|
||||
B_r = rgba_getr(back);
|
||||
B_g = rgba_getg(back);
|
||||
@ -119,11 +120,13 @@ int rgba_blend_merge(int back, int front, int opacity)
|
||||
D_b = B_b;
|
||||
}
|
||||
else {
|
||||
D_r = B_r + (F_r-B_r) * opacity / 255;
|
||||
D_g = B_g + (F_g-B_g) * opacity / 255;
|
||||
D_b = B_b + (F_b-B_b) * opacity / 255;
|
||||
D_r = B_r + INT_MULT((F_r - B_r), opacity, t);
|
||||
D_g = B_g + INT_MULT((F_g - B_g), opacity, t);
|
||||
D_b = B_b + INT_MULT((F_b - B_b), opacity, t);
|
||||
}
|
||||
D_a = B_a + (F_a-B_a) * opacity / 255;
|
||||
D_a = B_a + INT_MULT((F_a - B_a), opacity, t);
|
||||
if (D_a == 0)
|
||||
D_r = D_g = D_b = 0;
|
||||
|
||||
return rgba(D_r, D_g, D_b, D_a);
|
||||
}
|
||||
@ -262,6 +265,7 @@ int graya_blend_merge(int back, int front, int opacity)
|
||||
int B_k, B_a;
|
||||
int F_k, F_a;
|
||||
int D_k, D_a;
|
||||
int t;
|
||||
|
||||
B_k = graya_getv(back);
|
||||
B_a = graya_geta(back);
|
||||
@ -276,9 +280,11 @@ int graya_blend_merge(int back, int front, int opacity)
|
||||
D_k = B_k;
|
||||
}
|
||||
else {
|
||||
D_k = B_k + (F_k-B_k) * opacity / 255;
|
||||
D_k = B_k + INT_MULT((F_k-B_k), opacity, t);
|
||||
}
|
||||
D_a = B_a + (F_a-B_a) * opacity / 255;
|
||||
D_a = B_a + INT_MULT((F_a-B_a), opacity, t);
|
||||
if (D_a == 0)
|
||||
D_k = 0;
|
||||
|
||||
return graya(D_k, D_a);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user