mirror of
https://github.com/aseprite/aseprite.git
synced 2025-03-30 04:20:23 +00:00
Use ui::Graphics instead of Allegro in Editor's brush preview routines
* Remove color_utils::color_for_allegro() * Rename editor_draw/move/clear_cursor() -> draw/move/clearBrushPreview() * Rename Editor::get_raw_cursor_color() and Editor::is_cursor_mask() * Add Graphics::get/putPixel() and Graphics::width/height() * Add SetClip class
This commit is contained in:
parent
0b8d88d6ee
commit
7ebc90678f
@ -111,48 +111,6 @@ ui::Color color_utils::color_for_ui(const app::Color& color)
|
||||
return c;
|
||||
}
|
||||
|
||||
int color_utils::color_for_allegro(const app::Color& color, int depth)
|
||||
{
|
||||
int c = -1;
|
||||
|
||||
switch (color.getType()) {
|
||||
|
||||
case app::Color::MaskType:
|
||||
c = get_mask_for_bitmap(depth);
|
||||
break;
|
||||
|
||||
case app::Color::RgbType:
|
||||
case app::Color::HsvType:
|
||||
c = makeacol_depth(depth,
|
||||
color.getRed(),
|
||||
color.getGreen(),
|
||||
color.getBlue(), 255);
|
||||
break;
|
||||
|
||||
case app::Color::GrayType:
|
||||
c = color.getGray();
|
||||
if (depth != 8)
|
||||
c = makeacol_depth(depth, c, c, c, 255);
|
||||
break;
|
||||
|
||||
case app::Color::IndexType:
|
||||
c = color.getIndex();
|
||||
if (depth != 8) {
|
||||
ASSERT(c >= 0 && c < (int)get_current_palette()->size());
|
||||
|
||||
uint32_t _c = get_current_palette()->getEntry(c);
|
||||
c = makeacol_depth(depth,
|
||||
rgba_getr(_c),
|
||||
rgba_getg(_c),
|
||||
rgba_getb(_c), 255);
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
raster::color_t color_utils::color_for_image(const app::Color& color, PixelFormat format)
|
||||
{
|
||||
if (color.getType() == app::Color::MaskType)
|
||||
|
@ -37,7 +37,6 @@ namespace app {
|
||||
ui::Color blackandwhite_neg(ui::Color color);
|
||||
|
||||
ui::Color color_for_ui(const app::Color& color);
|
||||
int color_for_allegro(const app::Color& color, int depth);
|
||||
raster::color_t color_for_image(const app::Color& color, raster::PixelFormat format);
|
||||
raster::color_t color_for_layer(const app::Color& color, raster::Layer* layer);
|
||||
raster::color_t color_for_target(const app::Color& color, const ColorTarget& colorTarget);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Aseprite
|
||||
* Copyright (C) 2001-2013 David Capello
|
||||
* Copyright (C) 2001-2014 David Capello
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -20,6 +20,8 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "app/ui/editor/editor.h"
|
||||
|
||||
#include "app/app.h"
|
||||
#include "app/color.h"
|
||||
#include "app/color_utils.h"
|
||||
@ -28,10 +30,10 @@
|
||||
#include "app/settings/settings.h"
|
||||
#include "app/tools/ink.h"
|
||||
#include "app/tools/tool.h"
|
||||
#include "app/ui/editor/editor.h"
|
||||
#include "app/ui_context.h"
|
||||
#include "app/util/boundary.h"
|
||||
#include "base/memory.h"
|
||||
#include "raster/algo.h"
|
||||
#include "raster/brush.h"
|
||||
#include "raster/image.h"
|
||||
#include "raster/layer.h"
|
||||
@ -42,7 +44,6 @@
|
||||
#include "ui/widget.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <allegro.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#undef max
|
||||
@ -53,18 +54,10 @@ namespace app {
|
||||
|
||||
using namespace ui;
|
||||
|
||||
/**********************************************************************/
|
||||
/* drawing-cursor routines */
|
||||
/**********************************************************************/
|
||||
|
||||
/**
|
||||
* Returns true if the cursor of the editor needs subpixel movement.
|
||||
*/
|
||||
// Returns true if the cursor of the editor needs subpixel movement.
|
||||
#define IS_SUBPIXEL(editor) ((editor)->m_zoom >= 2)
|
||||
|
||||
/**
|
||||
* Maximum quantity of colors to save pixels overlapped by the cursor.
|
||||
*/
|
||||
// Maximum quantity of colors to save pixels overlapped by the cursor.
|
||||
#define MAX_SAVED 4096
|
||||
|
||||
static struct {
|
||||
@ -72,19 +65,19 @@ static struct {
|
||||
int brush_size;
|
||||
int brush_angle;
|
||||
int nseg;
|
||||
BoundSeg *seg;
|
||||
BoundSeg* seg;
|
||||
} cursor_bound = { 0, 0, 0, 0, NULL };
|
||||
|
||||
enum {
|
||||
CURSOR_BRUSH = 1, // New cursor style (with preview)
|
||||
CURSOR_CROSS_ONE = 2, // Old cursor style (deprecated)
|
||||
CURSOR_BOUNDS = 4 // Old cursor boundaries (deprecated)
|
||||
CURSOR_THINCROSS = 1,
|
||||
CURSOR_THICKCROSS = 2,
|
||||
CURSOR_BRUSHBOUNDS = 4
|
||||
};
|
||||
|
||||
static int cursor_type = CURSOR_BRUSH;
|
||||
static int cursor_type = CURSOR_THINCROSS;
|
||||
static int cursor_negative;
|
||||
|
||||
static int saved_pixel[MAX_SAVED];
|
||||
static ui::Color saved_pixel[MAX_SAVED];
|
||||
static int saved_pixel_n;
|
||||
|
||||
// These clipping regions are shared between all editors, so we cannot
|
||||
@ -94,13 +87,13 @@ static gfx::Region old_clipping_region;
|
||||
|
||||
static void generate_cursor_boundaries();
|
||||
|
||||
static void editor_cursor_brush(Editor *editor, int x, int y, int color, int thickness, void (*pixel)(BITMAP *bmp, int x, int y, int color));
|
||||
static void editor_cursor_cross(Editor *editor, int x, int y, int color, int thickness, void (*pixel)(BITMAP *bmp, int x, int y, int color));
|
||||
static void editor_cursor_bounds(Editor *editor, int x, int y, int color, void (*pixel)(BITMAP *bmp, int x, int y, int color));
|
||||
static void trace_thincross_pixels(ui::Graphics* g, Editor* editor, int x, int y, ui::Color color, Editor::PixelDelegate pixel);
|
||||
static void trace_thickcross_pixels(ui::Graphics* g, Editor* editor, int x, int y, ui::Color color, int thickness, Editor::PixelDelegate pixel);
|
||||
static void trace_brush_bounds(ui::Graphics* g, Editor* editor, int x, int y, ui::Color color, Editor::PixelDelegate pixel);
|
||||
|
||||
static void savepixel(BITMAP *bmp, int x, int y, int color);
|
||||
static void drawpixel(BITMAP *bmp, int x, int y, int color);
|
||||
static void cleanpixel(BITMAP *bmp, int x, int y, int color);
|
||||
static void savepixel(ui::Graphics* g, int x, int y, ui::Color color);
|
||||
static void drawpixel(ui::Graphics* g, int x, int y, ui::Color color);
|
||||
static void clearpixel(ui::Graphics* g, int x, int y, ui::Color color);
|
||||
|
||||
static color_t get_brush_color(Sprite* sprite, Layer* layer);
|
||||
|
||||
@ -109,27 +102,17 @@ static color_t get_brush_color(Sprite* sprite, Layer* layer);
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
static app::Color cursor_color;
|
||||
static int _cursor_color;
|
||||
static bool _cursor_mask;
|
||||
static ui::Color ui_cursor_color;
|
||||
static bool is_cursor_mask;
|
||||
|
||||
static void update_cursor_color()
|
||||
{
|
||||
if (ji_screen)
|
||||
_cursor_color = color_utils::color_for_allegro(cursor_color, bitmap_color_depth(ji_screen));
|
||||
ui_cursor_color = color_utils::color_for_ui(cursor_color);
|
||||
else
|
||||
_cursor_color = 0;
|
||||
ui_cursor_color = 0;
|
||||
|
||||
_cursor_mask = (cursor_color.getType() == app::Color::MaskType);
|
||||
}
|
||||
|
||||
int Editor::get_raw_cursor_color()
|
||||
{
|
||||
return _cursor_color;
|
||||
}
|
||||
|
||||
bool Editor::is_cursor_mask()
|
||||
{
|
||||
return _cursor_mask;
|
||||
is_cursor_mask = (cursor_color.getType() == app::Color::MaskType);
|
||||
}
|
||||
|
||||
app::Color Editor::get_cursor_color()
|
||||
@ -228,19 +211,12 @@ void Editor::editor_cursor_exit()
|
||||
current_brush = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws the brush cursor inside the specified editor.
|
||||
*
|
||||
* @warning You should clean the cursor before to use
|
||||
* this routine with other editor.
|
||||
*
|
||||
* @param widget The editor widget
|
||||
* @param x Absolute position in X axis of the mouse.
|
||||
* @param y Absolute position in Y axis of the mouse.
|
||||
*
|
||||
* @see editor_clean_cursor
|
||||
*/
|
||||
void Editor::editor_draw_cursor(int x, int y, bool refresh)
|
||||
// Draws the brush cursor inside the specified editor.
|
||||
// Warning: You should clean the cursor before to use
|
||||
// this routine with other editor.
|
||||
//
|
||||
// Note: x and y params are absolute positions of the mouse.
|
||||
void Editor::drawBrushPreview(int x, int y, bool refresh)
|
||||
{
|
||||
ASSERT(m_cursor_thick == 0);
|
||||
ASSERT(m_sprite != NULL);
|
||||
@ -248,15 +224,14 @@ void Editor::editor_draw_cursor(int x, int y, bool refresh)
|
||||
// Get drawable region
|
||||
getDrawableRegion(clipping_region, kCutTopWindows);
|
||||
|
||||
/* get cursor color */
|
||||
cursor_negative = is_cursor_mask();
|
||||
int color = get_raw_cursor_color();
|
||||
// Get cursor color
|
||||
cursor_negative = is_cursor_mask;
|
||||
|
||||
/* cursor in the screen (view) */
|
||||
// Cursor in the screen (view)
|
||||
m_cursor_screen_x = x;
|
||||
m_cursor_screen_y = y;
|
||||
|
||||
/* get cursor position in the editor */
|
||||
// Get cursor position in the editor
|
||||
screenToEditor(x, y, &x, &y);
|
||||
|
||||
// Get the current tool
|
||||
@ -271,7 +246,7 @@ void Editor::editor_draw_cursor(int x, int y, bool refresh)
|
||||
|
||||
if (current_tool->getInk(0)->isSelection() ||
|
||||
current_tool->getInk(0)->isSlice()) {
|
||||
cursor_type = CURSOR_CROSS_ONE;
|
||||
cursor_type = CURSOR_THICKCROSS;
|
||||
}
|
||||
else if (
|
||||
// Use cursor bounds for inks that are effects (eraser, blur, etc.)
|
||||
@ -279,18 +254,18 @@ void Editor::editor_draw_cursor(int x, int y, bool refresh)
|
||||
// or when the brush color is transparent and we are not in the background layer
|
||||
(m_layer && !m_layer->isBackground() &&
|
||||
brush_color == mask_color)) {
|
||||
cursor_type = CURSOR_BOUNDS;
|
||||
cursor_type = CURSOR_BRUSHBOUNDS;
|
||||
}
|
||||
else {
|
||||
cursor_type = CURSOR_BRUSH;
|
||||
cursor_type = CURSOR_THINCROSS;
|
||||
}
|
||||
|
||||
// For cursor type 'bounds' we have to generate cursor boundaries
|
||||
if (cursor_type & CURSOR_BOUNDS)
|
||||
if (cursor_type & CURSOR_BRUSHBOUNDS)
|
||||
generate_cursor_boundaries();
|
||||
|
||||
// draw pixel/brush preview
|
||||
if (cursor_type & CURSOR_BRUSH && m_state->requireBrushPreview()) {
|
||||
// Draw pixel/brush preview
|
||||
if (cursor_type & CURSOR_THINCROSS && m_state->requireBrushPreview()) {
|
||||
IToolSettings* tool_settings = UIContext::instance()
|
||||
->getSettings()
|
||||
->getToolSettings(current_tool);
|
||||
@ -324,18 +299,17 @@ void Editor::editor_draw_cursor(int x, int y, bool refresh)
|
||||
|
||||
// Save area and draw the cursor
|
||||
if (refresh) {
|
||||
acquire_bitmap(ji_screen);
|
||||
ji_screen->clip = false;
|
||||
forEachBrushPixel(m_cursor_screen_x, m_cursor_screen_y, x, y, color, savepixel);
|
||||
forEachBrushPixel(m_cursor_screen_x, m_cursor_screen_y, x, y, color, drawpixel);
|
||||
ji_screen->clip = true;
|
||||
release_bitmap(ji_screen);
|
||||
ScreenGraphics g;
|
||||
SetClip clip(&g, gfx::Rect(0, 0, g.width(), g.height()));
|
||||
|
||||
forEachBrushPixel(&g, m_cursor_screen_x, m_cursor_screen_y, x, y, ui_cursor_color, savepixel);
|
||||
forEachBrushPixel(&g, m_cursor_screen_x, m_cursor_screen_y, x, y, ui_cursor_color, drawpixel);
|
||||
}
|
||||
|
||||
// cursor thickness
|
||||
m_cursor_thick = 1; // get_thickness_for_cursor();
|
||||
// Cursor thickness
|
||||
m_cursor_thick = 1;
|
||||
|
||||
// cursor in the editor (model)
|
||||
// Cursor in the editor (model)
|
||||
m_cursor_editor_x = x;
|
||||
m_cursor_editor_y = y;
|
||||
|
||||
@ -343,7 +317,7 @@ void Editor::editor_draw_cursor(int x, int y, bool refresh)
|
||||
old_clipping_region = clipping_region;
|
||||
}
|
||||
|
||||
void Editor::editor_move_cursor(int x, int y, bool refresh)
|
||||
void Editor::moveBrushPreview(int x, int y, bool refresh)
|
||||
{
|
||||
ASSERT(m_sprite != NULL);
|
||||
|
||||
@ -352,21 +326,22 @@ void Editor::editor_move_cursor(int x, int y, bool refresh)
|
||||
int old_x = m_cursor_editor_x;
|
||||
int old_y = m_cursor_editor_y;
|
||||
|
||||
editor_clean_cursor(false);
|
||||
editor_draw_cursor(x, y, false);
|
||||
clearBrushPreview(false);
|
||||
drawBrushPreview(x, y, false);
|
||||
|
||||
int new_x = m_cursor_editor_x;
|
||||
int new_y = m_cursor_editor_y;
|
||||
|
||||
if (refresh) {
|
||||
/* restore points */
|
||||
acquire_bitmap(ji_screen);
|
||||
ji_screen->clip = FALSE;
|
||||
forEachBrushPixel(old_screen_x, old_screen_y, old_x, old_y, 0, cleanpixel);
|
||||
ji_screen->clip = TRUE;
|
||||
release_bitmap(ji_screen);
|
||||
// Restore pixels
|
||||
{
|
||||
ScreenGraphics g;
|
||||
SetClip clip(&g, gfx::Rect(0, 0, g.width(), g.height()));
|
||||
|
||||
if (cursor_type & CURSOR_BRUSH && m_state->requireBrushPreview()) {
|
||||
forEachBrushPixel(&g, old_screen_x, old_screen_y, old_x, old_y, ui::ColorNone, clearpixel);
|
||||
}
|
||||
|
||||
if (cursor_type & CURSOR_THINCROSS && m_state->requireBrushPreview()) {
|
||||
Brush* brush = editor_get_current_brush();
|
||||
gfx::Rect brushBounds = brush->getBounds();
|
||||
gfx::Rect rc1(old_x+brushBounds.x, old_y+brushBounds.y, brushBounds.w, brushBounds.h);
|
||||
@ -375,14 +350,10 @@ void Editor::editor_move_cursor(int x, int y, bool refresh)
|
||||
(m_sprite, gfx::Region(rc1.createUnion(rc2)));
|
||||
}
|
||||
|
||||
/* save area and draw the cursor */
|
||||
int color = get_raw_cursor_color();
|
||||
acquire_bitmap(ji_screen);
|
||||
ji_screen->clip = false;
|
||||
forEachBrushPixel(m_cursor_screen_x, m_cursor_screen_y, new_x, new_y, color, savepixel);
|
||||
forEachBrushPixel(m_cursor_screen_x, m_cursor_screen_y, new_x, new_y, color, drawpixel);
|
||||
ji_screen->clip = true;
|
||||
release_bitmap(ji_screen);
|
||||
// Save area and draw the cursor
|
||||
ScreenGraphics g;
|
||||
forEachBrushPixel(&g, m_cursor_screen_x, m_cursor_screen_y, new_x, new_y, ui_cursor_color, savepixel);
|
||||
forEachBrushPixel(&g, m_cursor_screen_x, m_cursor_screen_y, new_x, new_y, ui_cursor_color, drawpixel);
|
||||
}
|
||||
}
|
||||
|
||||
@ -390,16 +361,16 @@ void Editor::editor_move_cursor(int x, int y, bool refresh)
|
||||
* Cleans the brush cursor from the specified editor.
|
||||
*
|
||||
* The mouse position is got from the last
|
||||
* call to @c editor_draw_cursor. So you must
|
||||
* call to @c drawBrushPreview. So you must
|
||||
* to use this routine only if you called
|
||||
* @c editor_draw_cursor before with the specified
|
||||
* @c drawBrushPreview before with the specified
|
||||
* editor @a widget.
|
||||
*
|
||||
* @param widget The editor widget
|
||||
*
|
||||
* @see editor_draw_cursor
|
||||
* @see drawBrushPreview
|
||||
*/
|
||||
void Editor::editor_clean_cursor(bool refresh)
|
||||
void Editor::clearBrushPreview(bool refresh)
|
||||
{
|
||||
int x, y;
|
||||
|
||||
@ -412,16 +383,15 @@ void Editor::editor_clean_cursor(bool refresh)
|
||||
y = m_cursor_editor_y;
|
||||
|
||||
if (refresh) {
|
||||
/* restore points */
|
||||
acquire_bitmap(ji_screen);
|
||||
ji_screen->clip = FALSE;
|
||||
forEachBrushPixel(m_cursor_screen_x, m_cursor_screen_y, x, y, 0, cleanpixel);
|
||||
ji_screen->clip = TRUE;
|
||||
release_bitmap(ji_screen);
|
||||
// Restore pixels
|
||||
ScreenGraphics g;
|
||||
SetClip clip(&g, gfx::Rect(0, 0, g.width(), g.height()));
|
||||
|
||||
forEachBrushPixel(&g, m_cursor_screen_x, m_cursor_screen_y, x, y, ui::ColorNone, clearpixel);
|
||||
}
|
||||
|
||||
// clean pixel/brush preview
|
||||
if (cursor_type & CURSOR_BRUSH && m_state->requireBrushPreview()) {
|
||||
// Clean pixel/brush preview
|
||||
if (cursor_type & CURSOR_THINCROSS && m_state->requireBrushPreview()) {
|
||||
Brush* brush = editor_get_current_brush();
|
||||
gfx::Rect brushBounds = brush->getBounds();
|
||||
|
||||
@ -444,12 +414,10 @@ void Editor::editor_clean_cursor(bool refresh)
|
||||
old_clipping_region.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the cursor to draw in the editor has subpixel
|
||||
* movement (a little pixel of the screen that indicates where is the
|
||||
* mouse inside the pixel of the sprite).
|
||||
*/
|
||||
bool Editor::editor_cursor_is_subpixel()
|
||||
// Returns true if the cursor to draw in the editor has subpixel
|
||||
// movement (a little pixel of the screen that indicates where is the
|
||||
// mouse inside the pixel of the sprite).
|
||||
bool Editor::doesBrushPreviewNeedSubpixel()
|
||||
{
|
||||
return IS_SUBPIXEL(this);
|
||||
}
|
||||
@ -498,33 +466,33 @@ static void generate_cursor_boundaries()
|
||||
}
|
||||
|
||||
void Editor::forEachBrushPixel(
|
||||
ui::Graphics* g,
|
||||
int screen_x, int screen_y,
|
||||
int sprite_x, int sprite_y, int color,
|
||||
void (*pixel)(BITMAP *bmp, int x, int y, int color))
|
||||
int sprite_x, int sprite_y,
|
||||
ui::Color color,
|
||||
Editor::PixelDelegate pixelDelegate)
|
||||
{
|
||||
saved_pixel_n = 0;
|
||||
|
||||
if (cursor_type & CURSOR_BRUSH) {
|
||||
editor_cursor_brush(this, screen_x, screen_y, color, 1, pixel);
|
||||
}
|
||||
if (cursor_type & CURSOR_THINCROSS)
|
||||
trace_thincross_pixels(g, this, screen_x, screen_y, color, pixelDelegate);
|
||||
|
||||
if (cursor_type & CURSOR_CROSS_ONE) {
|
||||
editor_cursor_cross(this, sprite_x, sprite_y, color, 1, pixel);
|
||||
}
|
||||
if (cursor_type & CURSOR_THICKCROSS)
|
||||
trace_thickcross_pixels(g, this, sprite_x, sprite_y, color, 1, pixelDelegate);
|
||||
|
||||
if (cursor_type & CURSOR_BOUNDS) {
|
||||
editor_cursor_bounds(this, sprite_x, sprite_y, color, pixel);
|
||||
}
|
||||
if (cursor_type & CURSOR_BRUSHBOUNDS)
|
||||
trace_brush_bounds(g, this, sprite_x, sprite_y, color, pixelDelegate);
|
||||
|
||||
if (IS_SUBPIXEL(this)) {
|
||||
(*pixel)(ji_screen, screen_x, screen_y, color);
|
||||
pixelDelegate(g, screen_x, screen_y, color);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// New cross
|
||||
// New Thin Cross
|
||||
|
||||
static void editor_cursor_brush(Editor *editor, int x, int y, int color, int thickness, void (*pixel)(BITMAP *bmp, int x, int y, int color))
|
||||
static void trace_thincross_pixels(ui::Graphics* g, Editor* editor,
|
||||
int x, int y, ui::Color color, Editor::PixelDelegate pixelDelegate)
|
||||
{
|
||||
static int cursor_cross[7*7] = {
|
||||
0, 0, 0, 1, 0, 0, 0,
|
||||
@ -542,17 +510,17 @@ static void editor_cursor_brush(Editor *editor, int x, int y, int color, int thi
|
||||
if (cursor_cross[v*7+u]) {
|
||||
xout = x-3+u;
|
||||
yout = y-3+v;
|
||||
(*pixel)(ji_screen, xout, yout, color);
|
||||
pixelDelegate(g, xout, yout, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Old cross
|
||||
// Old Thick Cross
|
||||
|
||||
static void editor_cursor_cross(Editor* editor, int x, int y, int color, int thickness,
|
||||
void (*pixel)(BITMAP *bmp, int x, int y, int color))
|
||||
static void trace_thickcross_pixels(ui::Graphics* g, Editor* editor,
|
||||
int x, int y, ui::Color color, int thickness, Editor::PixelDelegate pixelDelegate)
|
||||
{
|
||||
static int cursor_cross[6*6] = {
|
||||
0, 0, 1, 1, 0, 0,
|
||||
@ -578,19 +546,33 @@ static void editor_cursor_cross(Editor* editor, int x, int y, int color, int thi
|
||||
v-((thickness>>1)<<zoom)-3:
|
||||
v-((thickness>>1)<<zoom)-3+(thickness<<zoom));
|
||||
|
||||
(*pixel)(ji_screen, xout, yout, color);
|
||||
pixelDelegate(g, xout, yout, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Cursor Bounds
|
||||
// Current Brush Bounds
|
||||
|
||||
static void editor_cursor_bounds(Editor *editor, int x, int y, int color, void (*pixel) (BITMAP *bmp, int x, int y, int color))
|
||||
struct Data {
|
||||
ui::Graphics* g;
|
||||
ui::Color color;
|
||||
Editor::PixelDelegate pixelDelegate;
|
||||
};
|
||||
|
||||
static void algo_line_proxy(int x, int y, void* _data)
|
||||
{
|
||||
Data* data = (Data*)_data;
|
||||
data->pixelDelegate(data->g, x, y, data->color);
|
||||
}
|
||||
|
||||
static void trace_brush_bounds(ui::Graphics* g, Editor* editor,
|
||||
int x, int y, ui::Color color, Editor::PixelDelegate pixelDelegate)
|
||||
{
|
||||
Data data = { g, color, pixelDelegate };
|
||||
int c, x1, y1, x2, y2;
|
||||
BoundSeg *seg;
|
||||
BoundSeg* seg;
|
||||
|
||||
for (c=0; c<cursor_bound.nseg; c++) {
|
||||
seg = cursor_bound.seg+c;
|
||||
@ -624,42 +606,41 @@ static void editor_cursor_bounds(Editor *editor, int x, int y, int color, void (
|
||||
}
|
||||
}
|
||||
|
||||
do_line(ji_screen, x1, y1, x2, y2, color, pixel);
|
||||
raster::algo_line(x1, y1, x2, y2, (void*)&data, algo_line_proxy);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Helpers
|
||||
|
||||
static void savepixel(BITMAP *bmp, int x, int y, int color)
|
||||
static void savepixel(ui::Graphics* g, int x, int y, ui::Color color)
|
||||
{
|
||||
if (saved_pixel_n < MAX_SAVED && clipping_region.contains(gfx::Point(x, y)))
|
||||
saved_pixel[saved_pixel_n++] = getpixel(bmp, x, y);
|
||||
saved_pixel[saved_pixel_n++] = g->getPixel(x, y);
|
||||
}
|
||||
|
||||
static void drawpixel(BITMAP *bmp, int x, int y, int color)
|
||||
static void drawpixel(ui::Graphics* graphics, int x, int y, ui::Color color)
|
||||
{
|
||||
if (saved_pixel_n < MAX_SAVED && clipping_region.contains(gfx::Point(x, y))) {
|
||||
if (cursor_negative) {
|
||||
int r, g, b, c = saved_pixel[saved_pixel_n++];
|
||||
int c = saved_pixel[saved_pixel_n++];
|
||||
int r = getr(c);
|
||||
int g = getg(c);
|
||||
int b = getb(c);
|
||||
|
||||
r = getr(c);
|
||||
g = getg(c);
|
||||
b = getb(c);
|
||||
|
||||
putpixel(bmp, x, y, ui::to_system(color_utils::blackandwhite_neg(ui::rgba(r, g, b))));
|
||||
graphics->putPixel(color_utils::blackandwhite_neg(ui::rgba(r, g, b)), x, y);
|
||||
}
|
||||
else {
|
||||
putpixel(bmp, x, y, color);
|
||||
graphics->putPixel(color, x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void cleanpixel(BITMAP *bmp, int x, int y, int color)
|
||||
static void clearpixel(ui::Graphics* g, int x, int y, ui::Color color)
|
||||
{
|
||||
if (saved_pixel_n < MAX_SAVED) {
|
||||
if (clipping_region.contains(gfx::Point(x, y)))
|
||||
putpixel(bmp, x, y, saved_pixel[saved_pixel_n++]);
|
||||
g->putPixel(saved_pixel[saved_pixel_n++], x, y);
|
||||
else if (!old_clipping_region.isEmpty() &&
|
||||
old_clipping_region.contains(gfx::Point(x, y)))
|
||||
saved_pixel_n++;
|
||||
|
@ -299,7 +299,7 @@ void Editor::setEditorScroll(int x, int y, int use_refresh_region)
|
||||
int thick = m_cursor_thick;
|
||||
|
||||
if (thick)
|
||||
editor_clean_cursor();
|
||||
clearBrushPreview();
|
||||
|
||||
if (use_refresh_region) {
|
||||
getDrawableRegion(region, kCutTopWindows);
|
||||
@ -317,7 +317,7 @@ void Editor::setEditorScroll(int x, int y, int use_refresh_region)
|
||||
}
|
||||
|
||||
if (thick)
|
||||
editor_draw_cursor(m_cursor_screen_x, m_cursor_screen_y);
|
||||
drawBrushPreview(m_cursor_screen_x, m_cursor_screen_y);
|
||||
}
|
||||
|
||||
void Editor::updateEditor()
|
||||
@ -587,7 +587,7 @@ void Editor::drawMaskSafe()
|
||||
region.offset(-getBounds().getOrigin());
|
||||
|
||||
if (thick)
|
||||
editor_clean_cursor();
|
||||
clearBrushPreview();
|
||||
else
|
||||
jmouse_hide();
|
||||
|
||||
@ -602,7 +602,7 @@ void Editor::drawMaskSafe()
|
||||
|
||||
// Draw the cursor
|
||||
if (thick)
|
||||
editor_draw_cursor(m_cursor_screen_x, m_cursor_screen_y);
|
||||
drawBrushPreview(m_cursor_screen_x, m_cursor_screen_y);
|
||||
else
|
||||
jmouse_show();
|
||||
}
|
||||
@ -776,7 +776,7 @@ void Editor::showDrawingCursor()
|
||||
|
||||
if (!m_cursor_thick && canDraw()) {
|
||||
jmouse_hide();
|
||||
editor_draw_cursor(jmouse_x(0), jmouse_y(0));
|
||||
drawBrushPreview(jmouse_x(0), jmouse_y(0));
|
||||
jmouse_show();
|
||||
}
|
||||
}
|
||||
@ -785,7 +785,7 @@ void Editor::hideDrawingCursor()
|
||||
{
|
||||
if (m_cursor_thick) {
|
||||
jmouse_hide();
|
||||
editor_clean_cursor();
|
||||
clearBrushPreview();
|
||||
jmouse_show();
|
||||
}
|
||||
}
|
||||
@ -803,7 +803,7 @@ void Editor::moveDrawingCursor()
|
||||
// when the mouse moves only).
|
||||
if ((m_cursor_screen_x != x) || (m_cursor_screen_y != y)) {
|
||||
jmouse_hide();
|
||||
editor_move_cursor(x, y);
|
||||
moveBrushPreview(x, y);
|
||||
jmouse_show();
|
||||
}
|
||||
}
|
||||
@ -1025,7 +1025,7 @@ void Editor::onPaint(ui::PaintEvent& ev)
|
||||
|
||||
int old_cursor_thick = m_cursor_thick;
|
||||
if (m_cursor_thick)
|
||||
editor_clean_cursor();
|
||||
clearBrushPreview();
|
||||
|
||||
// Editor without sprite
|
||||
if (!m_sprite) {
|
||||
@ -1051,7 +1051,7 @@ void Editor::onPaint(ui::PaintEvent& ev)
|
||||
|
||||
// Draw the cursor again
|
||||
if (old_cursor_thick != 0) {
|
||||
editor_draw_cursor(jmouse_x(0), jmouse_y(0));
|
||||
drawBrushPreview(jmouse_x(0), jmouse_y(0));
|
||||
}
|
||||
}
|
||||
catch (const LockedDocumentException&) {
|
||||
|
@ -65,6 +65,8 @@ namespace app {
|
||||
class Editor : public ui::Widget,
|
||||
public DocumentSettingsObserver {
|
||||
public:
|
||||
typedef void (*PixelDelegate)(ui::Graphics* g, int x, int y, ui::Color color);
|
||||
|
||||
enum EditorFlags {
|
||||
kNoneFlag = 0,
|
||||
kShowGridFlag = 1,
|
||||
@ -178,8 +180,6 @@ namespace app {
|
||||
|
||||
// in cursor.cpp
|
||||
|
||||
static int get_raw_cursor_color();
|
||||
static bool is_cursor_mask();
|
||||
static app::Color get_cursor_color();
|
||||
static void set_cursor_color(const app::Color& color);
|
||||
|
||||
@ -201,10 +201,10 @@ namespace app {
|
||||
private:
|
||||
void setStateInternal(const EditorStatePtr& newState);
|
||||
void editor_update_quicktool();
|
||||
void editor_draw_cursor(int x, int y, bool refresh = true);
|
||||
void editor_move_cursor(int x, int y, bool refresh = true);
|
||||
void editor_clean_cursor(bool refresh = true);
|
||||
bool editor_cursor_is_subpixel();
|
||||
void drawBrushPreview(int x, int y, bool refresh = true);
|
||||
void moveBrushPreview(int x, int y, bool refresh = true);
|
||||
void clearBrushPreview(bool refresh = true);
|
||||
bool doesBrushPreviewNeedSubpixel();
|
||||
|
||||
void drawMaskSafe();
|
||||
void drawMask(ui::Graphics* g);
|
||||
@ -213,9 +213,11 @@ namespace app {
|
||||
void editor_setcursor();
|
||||
|
||||
void forEachBrushPixel(
|
||||
ui::Graphics* g,
|
||||
int screen_x, int screen_y,
|
||||
int sprite_x, int sprite_y, int color,
|
||||
void (*pixel)(BITMAP* bmp, int x, int y, int color));
|
||||
int sprite_x, int sprite_y,
|
||||
ui::Color color,
|
||||
PixelDelegate pixelDelegate);
|
||||
|
||||
// Draws the specified portion of sprite in the editor. Warning:
|
||||
// You should setup the clip of the screen before calling this
|
||||
|
@ -27,6 +27,13 @@ namespace she {
|
||||
return makecol(getr(color), getg(color), getb(color));
|
||||
}
|
||||
|
||||
inline Color from_allegro(int color_depth, int color) {
|
||||
return she::rgba(
|
||||
getr_depth(color_depth, color),
|
||||
getg_depth(color_depth, color),
|
||||
getb_depth(color_depth, color));
|
||||
}
|
||||
|
||||
class Alleg4Surface : public Surface
|
||||
, public LockedSurface {
|
||||
public:
|
||||
@ -212,6 +219,16 @@ namespace she {
|
||||
}
|
||||
}
|
||||
|
||||
she::Color getPixel(int x, int y) OVERRIDE {
|
||||
return from_allegro(
|
||||
bitmap_color_depth(m_bmp),
|
||||
getpixel(m_bmp, x, y));
|
||||
}
|
||||
|
||||
void putPixel(she::Color color, int x, int y) OVERRIDE {
|
||||
putpixel(m_bmp, x, y, to_allegro(color));
|
||||
}
|
||||
|
||||
void drawHLine(she::Color color, int x, int y, int w) OVERRIDE {
|
||||
hline(m_bmp, x, y, x+w-1, to_allegro(color));
|
||||
}
|
||||
|
@ -27,6 +27,9 @@ namespace she {
|
||||
virtual uint8_t* getData(int x, int y) = 0;
|
||||
virtual void getFormat(SurfaceFormatData* formatData) = 0;
|
||||
|
||||
virtual she::Color getPixel(int x, int y) = 0;
|
||||
virtual void putPixel(she::Color color, int x, int y) = 0;
|
||||
|
||||
virtual void drawHLine(she::Color color, int x, int y, int w) = 0;
|
||||
virtual void drawVLine(she::Color color, int x, int y, int h) = 0;
|
||||
virtual void drawLine(she::Color color, const gfx::Point& a, const gfx::Point& b) = 0;
|
||||
|
@ -28,6 +28,10 @@ namespace {
|
||||
return (she::Color)color;
|
||||
}
|
||||
|
||||
inline ui::Color from_she(she::Color color) {
|
||||
return (ui::Color)color;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace ui {
|
||||
@ -43,6 +47,16 @@ Graphics::~Graphics()
|
||||
{
|
||||
}
|
||||
|
||||
int Graphics::width() const
|
||||
{
|
||||
return m_surface->width();
|
||||
}
|
||||
|
||||
int Graphics::height() const
|
||||
{
|
||||
return m_surface->height();
|
||||
}
|
||||
|
||||
gfx::Rect Graphics::getClipBounds() const
|
||||
{
|
||||
return m_surface->getClipBounds().offset(-m_dx, -m_dy);
|
||||
@ -58,6 +72,18 @@ bool Graphics::intersectClipRect(const gfx::Rect& rc)
|
||||
return m_surface->intersectClipRect(gfx::Rect(rc).offset(m_dx, m_dy));
|
||||
}
|
||||
|
||||
ui::Color Graphics::getPixel(int x, int y)
|
||||
{
|
||||
she::ScopedSurfaceLock dst(m_surface);
|
||||
return from_she(dst->getPixel(m_dx+x, m_dy+y));
|
||||
}
|
||||
|
||||
void Graphics::putPixel(ui::Color color, int x, int y)
|
||||
{
|
||||
she::ScopedSurfaceLock dst(m_surface);
|
||||
dst->putPixel(to_she(color), m_dx+x, m_dy+y);
|
||||
}
|
||||
|
||||
void Graphics::drawHLine(ui::Color color, int x, int y, int w)
|
||||
{
|
||||
she::ScopedSurfaceLock dst(m_surface);
|
||||
|
@ -34,6 +34,9 @@ namespace ui {
|
||||
Graphics(she::Surface* surface, int dx, int dy);
|
||||
~Graphics();
|
||||
|
||||
int width() const;
|
||||
int height() const;
|
||||
|
||||
she::Surface* getInternalSurface() { return m_surface; }
|
||||
int getInternalDeltaX() { return m_dx; }
|
||||
int getInternalDeltaY() { return m_dy; }
|
||||
@ -42,6 +45,9 @@ namespace ui {
|
||||
void setClipBounds(const gfx::Rect& rc);
|
||||
bool intersectClipRect(const gfx::Rect& rc);
|
||||
|
||||
ui::Color getPixel(int x, int y);
|
||||
void putPixel(ui::Color color, int x, int y);
|
||||
|
||||
void drawHLine(ui::Color color, int x, int y, int w);
|
||||
void drawVLine(ui::Color color, int x, int y, int h);
|
||||
void drawLine(ui::Color color, const gfx::Point& a, const gfx::Point& b);
|
||||
@ -91,6 +97,29 @@ namespace ui {
|
||||
virtual ~ScreenGraphics();
|
||||
};
|
||||
|
||||
// Class to temporary set the Graphics' clip region (in the
|
||||
// life-time of the SetClip instance).
|
||||
class SetClip {
|
||||
public:
|
||||
SetClip(Graphics* g, const gfx::Rect& rc)
|
||||
: m_graphics(g)
|
||||
, m_oldClip(g->getClipBounds())
|
||||
{
|
||||
m_graphics->setClipBounds(rc);
|
||||
}
|
||||
|
||||
~SetClip()
|
||||
{
|
||||
m_graphics->setClipBounds(m_oldClip);
|
||||
}
|
||||
|
||||
private:
|
||||
Graphics* m_graphics;
|
||||
gfx::Rect m_oldClip;
|
||||
|
||||
DISABLE_COPYING(SetClip);
|
||||
};
|
||||
|
||||
// Class to temporary set the Graphics' clip region to a sub-rectangle
|
||||
// (in the life-time of the IntersectClip instance).
|
||||
class IntersectClip {
|
||||
|
Loading…
x
Reference in New Issue
Block a user