Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
M
magicseteditor
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Packages
Packages
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issues
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
MyCard
magicseteditor
Commits
3a201da9
Commit
3a201da9
authored
Oct 29, 2006
by
twanvl
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
implemented more image related functions
parent
3cbbe729
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
377 additions
and
33 deletions
+377
-33
src/data/set.cpp
src/data/set.cpp
+4
-5
src/gfx/blend_image.cpp
src/gfx/blend_image.cpp
+88
-0
src/gfx/combine_image.cpp
src/gfx/combine_image.cpp
+2
-3
src/gfx/gfx.hpp
src/gfx/gfx.hpp
+13
-18
src/gfx/image_effects.cpp
src/gfx/image_effects.cpp
+31
-0
src/gfx/resample_image.cpp
src/gfx/resample_image.cpp
+166
-0
src/gfx/rotate_image.cpp
src/gfx/rotate_image.cpp
+1
-2
src/mse.vcproj
src/mse.vcproj
+9
-0
src/script/image.cpp
src/script/image.cpp
+56
-1
src/util/age.hpp
src/util/age.hpp
+3
-0
src/util/dynamic_arg.hpp
src/util/dynamic_arg.hpp
+4
-4
No files found.
src/data/set.cpp
View file @
3a201da9
...
@@ -46,11 +46,10 @@ IMPLEMENT_REFLECTION(Set) {
...
@@ -46,11 +46,10 @@ IMPLEMENT_REFLECTION(Set) {
if
(
tag
.
reading
())
{
if
(
tag
.
reading
())
{
data
.
init
(
game
->
set_fields
);
data
.
init
(
game
->
set_fields
);
}
}
WITH_DYNAMIC_ARG
(
game_for_reading
,
game
.
get
())
{
WITH_DYNAMIC_ARG
(
game_for_reading
,
game
.
get
());
REFLECT
(
stylesheet
);
REFLECT
(
stylesheet
);
REFLECT_N
(
"set_info"
,
data
);
REFLECT_N
(
"set_info"
,
data
);
REFLECT
(
cards
);
REFLECT
(
cards
);
}
}
}
REFLECT
(
apprentice_code
);
REFLECT
(
apprentice_code
);
}
}
...
...
src/gfx/blend_image.cpp
0 → 100644
View file @
3a201da9
//+----------------------------------------------------------------------------+
//| Description: Magic Set Editor - Program to make Magic (tm) cards |
//| Copyright: (C) 2001 - 2006 Twan van Laarhoven |
//| License: GNU General Public License 2 or later (see file COPYING) |
//+----------------------------------------------------------------------------+
// ----------------------------------------------------------------------------- : Includes
#include <gfx/gfx.hpp>
#include <util/error.hpp>
// ----------------------------------------------------------------------------- : Linear Blend
// sqr(x) = x^2
template
<
typename
T
>
inline
T
sqr
(
T
x
)
{
return
x
*
x
;
}
void
linear_blend
(
Image
&
img1
,
const
Image
&
img2
,
double
x1
,
double
y1
,
double
x2
,
double
y2
)
{
int
width
=
img1
.
GetWidth
(),
height
=
img1
.
GetHeight
();
if
(
img2
.
GetWidth
()
!=
width
||
img2
.
GetHeight
()
!=
height
)
{
throw
Error
(
_
(
"Images used for blending must have the same size"
));
}
const
int
fixed
=
1
<<
16
;
// fixed point multiplier
// equation:
// x * xm + y * ym + d == fixed * f(x,y)
// xm and ym are multiples of delta x/y:
// xm = a w (x2-x1); ym = a h (y2-y1)
// known values
// f(x1*w, y1*h) = 0
// f(x2*w, y2*h) = 1
// filling in:
// x1 * w * a * w * (x2-x1) + y1 * h * a * h * (y2-y1) + d == 0
// x2 * w * a * w * (x2-x1) + y2 * h * a * h * (y2-y1) + d == fixed
// solving for a and d:
// (using dx = x1-x2, dy = y1-y2)
// a = fixed / (w^2 dx^2 + h^2 dy^2)
// d = a * (w^2 x1 dx + h^2 y1 dy)
if
(
x1
==
x2
&&
y1
==
y2
)
throw
Error
(
_
(
"Coordinates for blending overlap"
));
double
a
=
fixed
/
(
sqr
(
width
)
*
sqr
(
x1
-
x2
)
+
sqr
(
height
)
*
sqr
(
y1
-
y2
));
int
xm
=
(
x2
-
x1
)
*
width
*
a
;
int
ym
=
(
y2
-
y1
)
*
height
*
a
;
int
d
=
-
(
x1
*
width
*
xm
+
y1
*
width
*
ym
);
Byte
*
data1
=
img1
.
GetData
(),
*
data2
=
img2
.
GetData
();
// blend pixels
for
(
int
y
=
0
;
y
<
height
;
++
y
)
{
for
(
int
x
=
0
;
x
<
width
;
++
x
)
{
int
mult
=
x
*
xm
+
y
*
ym
+
d
;
if
(
mult
<
0
)
mult
=
0
;
if
(
mult
>
fixed
)
mult
=
fixed
;
data1
[
0
]
=
data1
[
0
]
+
mult
*
(
data2
[
0
]
-
data1
[
0
])
/
fixed
;
data1
[
1
]
=
data1
[
1
]
+
mult
*
(
data2
[
1
]
-
data1
[
1
])
/
fixed
;
data1
[
2
]
=
data1
[
2
]
+
mult
*
(
data2
[
2
]
-
data1
[
2
])
/
fixed
;
data1
+=
3
;
data2
+=
3
;
}
}
}
// ----------------------------------------------------------------------------- : Mask Blend
void
mask_blend
(
Image
&
img1
,
const
Image
&
img2
,
const
Image
&
mask
)
{
if
(
img2
.
GetWidth
()
!=
img1
.
GetWidth
()
||
img2
.
GetHeight
()
!=
img1
.
GetHeight
()
||
mask
.
GetWidth
()
!=
img1
.
GetWidth
()
||
mask
.
GetHeight
()
!=
img1
.
GetHeight
())
{
throw
Error
(
_
(
"Images used for blending must have the same size"
));
}
UInt
size
=
img1
.
GetWidth
()
*
img1
.
GetHeight
()
*
3
;
Byte
*
data1
=
img1
.
GetData
(),
*
data2
=
img2
.
GetData
(),
*
dataM
=
mask
.
GetData
();
// for each subpixel...
for
(
UInt
i
=
0
;
i
<
size
;
++
i
)
{
data1
[
i
]
=
(
data1
[
i
]
*
dataM
[
i
]
+
data2
[
i
]
*
(
255
-
dataM
[
i
]))
/
255
;
}
}
// ----------------------------------------------------------------------------- : Alpha
void
set_alpha
(
Image
&
img
,
const
Image
&
img_alpha
)
{
if
(
img
.
GetWidth
()
!=
img_alpha
.
GetWidth
()
||
img
.
GetHeight
()
!=
img_alpha
.
GetHeight
())
{
throw
InternalError
(
_
(
"Image used with maks must have same size as mask"
));
}
if
(
!
img
.
HasAlpha
())
img
.
InitAlpha
();
Byte
*
im
=
img
.
GetAlpha
(),
*
al
=
img_alpha
.
GetData
();
UInt
size
=
img
.
GetWidth
()
*
img
.
GetHeight
();
for
(
UInt
i
=
0
;
i
<
size
;
++
i
)
{
im
[
i
]
=
(
im
[
i
]
*
al
[
i
*
3
])
/
255
;
}
}
src/gfx/combine_image.cpp
View file @
3a201da9
...
@@ -6,9 +6,8 @@
...
@@ -6,9 +6,8 @@
// ----------------------------------------------------------------------------- : Includes
// ----------------------------------------------------------------------------- : Includes
#include "../util/prec.hpp"
#include <gfx/gfx.hpp>
#include "../util/reflect.hpp"
#include <util/reflect.hpp>
#include "gfx.hpp"
#include <algorithm>
#include <algorithm>
using
namespace
std
;
using
namespace
std
;
...
...
src/gfx/gfx.hpp
View file @
3a201da9
...
@@ -19,23 +19,11 @@
...
@@ -19,23 +19,11 @@
// ----------------------------------------------------------------------------- : Resampling
// ----------------------------------------------------------------------------- : Resampling
/// Resample (resize) an image, uses bilenear filtering
/// Resample (resize) an image, uses bilenear filtering
/** The algorithm first resizes in horizontally, then vertically,
void
resample
(
const
Image
&
img_in
,
Image
&
img_out
);
* the two passes are essentially the same:
* - for each row:
* - each input pixel becomes a fixed amount of output (in 1<<shift fixed point math)
* - for each output pixel:
* - 'eat' input pixels until the total is 1<<shift
* - write the total to the output pixel
* - to ensure the sum of all the pixel amounts is exacly width<<shift an extra rest amount
* is 'eaten' from the first pixel
*
* Uses fixed point numbers internally
*/
void
resample
(
const
Image
&
imgIn
,
Image
&
imgOut
);
/// Resamples an image, first clips the input image to a specified rectangle
,
/// Resamples an image, first clips the input image to a specified rectangle
/
// that rectangle is resampledinto the entire output image
/
** The selected rectangle is resampled into the entire output image */
void
resample_and_clip
(
const
Image
&
img
In
,
Image
&
imgO
ut
,
wxRect
rect
);
void
resample_and_clip
(
const
Image
&
img
_in
,
Image
&
img_o
ut
,
wxRect
rect
);
/// How to preserve the aspect ratio of an image when rescaling
/// How to preserve the aspect ratio of an image when rescaling
enum
PreserveAspect
enum
PreserveAspect
...
@@ -44,6 +32,8 @@ enum PreserveAspect
...
@@ -44,6 +32,8 @@ enum PreserveAspect
,
ASPECT_FIT
///< generate a smaller image if needed
,
ASPECT_FIT
///< generate a smaller image if needed
};
};
/// Resample an image, but preserve the aspect ratio by adding a transparent border around the output if needed.
void
resample_preserve_aspect
(
const
Image
&
img_in
,
Image
&
img_out
);
// ----------------------------------------------------------------------------- : Image rotation
// ----------------------------------------------------------------------------- : Image rotation
...
@@ -67,8 +57,13 @@ void linear_blend(Image& img1, const Image& img2, double x1,double y1, double x2
...
@@ -67,8 +57,13 @@ void linear_blend(Image& img1, const Image& img2, double x1,double y1, double x2
*/
*/
void
mask_blend
(
Image
&
img1
,
const
Image
&
img2
,
const
Image
&
mask
);
void
mask_blend
(
Image
&
img1
,
const
Image
&
img2
,
const
Image
&
mask
);
/// Use the red channel of img2 as alpha channel for img1
/// Use the red channel of img_alpha as alpha channel for img
void
set_alpha
(
Image
&
img1
,
const
Image
&
img2
);
void
set_alpha
(
Image
&
img
,
const
Image
&
img_alpha
);
// ----------------------------------------------------------------------------- : Effects
/// Saturate an image, amount should be in range [0...100]
void
saturate
(
Image
&
image
,
int
amount
);
// ----------------------------------------------------------------------------- : Combining
// ----------------------------------------------------------------------------- : Combining
...
...
src/gfx/image_effects.cpp
0 → 100644
View file @
3a201da9
//+----------------------------------------------------------------------------+
//| Description: Magic Set Editor - Program to make Magic (tm) cards |
//| Copyright: (C) 2001 - 2006 Twan van Laarhoven |
//| License: GNU General Public License 2 or later (see file COPYING) |
//+----------------------------------------------------------------------------+
// ----------------------------------------------------------------------------- : Includes
#include <gfx/gfx.hpp>
#include <util/error.hpp>
// ----------------------------------------------------------------------------- : Saturation
void
saturate
(
Image
&
image
,
int
amount
)
{
if
(
amount
==
0
)
return
;
// nothing to do
int
factor
=
300
/
amount
;
int
div
=
factor
-
2
;
// for each pixel...
Byte
*
pix
=
image
.
GetData
();
Byte
*
end
=
pix
+
image
.
GetWidth
()
*
image
.
GetHeight
()
*
3
;
while
(
pix
!=
end
)
{
int
r
=
pix
[
0
],
g
=
pix
[
1
],
b
=
pix
[
2
];
int
r2
=
(
factor
*
r
-
g
-
b
)
/
div
;
int
g2
=
(
factor
*
g
-
r
-
b
)
/
div
;
int
b2
=
(
factor
*
b
-
r
-
g
)
/
div
;
pix
[
0
]
=
col
(
r2
);
pix
[
1
]
=
col
(
g2
);
pix
[
2
]
=
col
(
b2
);
pix
+=
3
;
}
}
src/gfx/resample_image.cpp
0 → 100644
View file @
3a201da9
//+----------------------------------------------------------------------------+
//| Description: Magic Set Editor - Program to make Magic (tm) cards |
//| Copyright: (C) 2001 - 2006 Twan van Laarhoven |
//| License: GNU General Public License 2 or later (see file COPYING) |
//+----------------------------------------------------------------------------+
// ----------------------------------------------------------------------------- : Includes
#include <gfx/gfx.hpp>
#include <util/error.hpp>
// ----------------------------------------------------------------------------- : Resample passes
// bitshift for fixed point numbers
// higher is less error
// we will get errors if 2^shift * imagesize becomes too large
const
int
shift
=
32
-
10
-
8
;
// => max size = 1024, max alpha = 255
// Resample an image only in a single direction, either horizontally or vertically
/* Terms are based on x resampling (keeping the same number of lines):
* offset = number of elements to skip at the start
* length = length of a line
* delta = number of elements between pixels in a lines
* lines = number of lines
* line_delta = number of elements between the the first pixel of two lines
* 1 element = 3 bytes in data, 1 byte in alpha
*/
void
resample_pass
(
const
Image
&
img_in
,
Image
&
img_out
,
int
offset_in
,
int
offset_out
,
int
length_in
,
int
delta_in
,
int
length_out
,
int
delta_out
,
int
lines
,
int
line_delta_in
,
int
line_delta_out
)
{
bool
alpha
=
img_in
.
HasAlpha
();
if
(
alpha
)
img_out
.
InitAlpha
();
int
out_fact
=
(
length_out
<<
shift
)
/
length_in
;
// how much to output for 256 input = 1 pixel
int
out_rest
=
(
length_out
<<
shift
)
%
length_in
;
// for each line
for
(
int
l
=
0
;
l
<
lines
;
++
l
)
{
Byte
*
in
=
img_in
.
GetData
()
+
3
*
(
offset_in
+
line_delta_in
);
Byte
*
out
=
img_out
.
GetData
()
+
3
*
(
offset_out
+
line_delta_out
);
UInt
in_rem
=
out_fact
+
out_rest
;
// remaining to input from the current input pixel
if
(
alpha
)
{
Byte
*
in_a
=
img_in
.
GetAlpha
()
+
(
offset_in
+
line_delta_in
);
Byte
*
out_a
=
img_out
.
GetAlpha
()
+
(
offset_out
+
line_delta_out
);
for
(
int
x
=
0
;
x
<
length_out
;
++
x
)
{
UInt
out_rem
=
1
<<
shift
;
UInt
totR
=
0
,
totG
=
0
,
totB
=
0
,
totA
=
0
;
while
(
out_rem
>=
in_rem
)
{
// eat a whole input pixel
totR
+=
in
[
0
]
*
in_rem
*
in_a
[
0
];
// multiply by alpha
totG
+=
in
[
1
]
*
in_rem
*
in_a
[
0
];
totB
+=
in
[
2
]
*
in_rem
*
in_a
[
0
];
totA
+=
in_a
[
0
]
*
in_rem
;
out_rem
-=
in_rem
;
in_rem
=
out_fact
;
in
+=
3
*
delta_in
;
in_a
+=
delta_in
;
}
if
(
out_rem
>
0
)
{
// eat a partial input pixel
totR
+=
in
[
0
]
*
out_rem
*
in_a
[
0
];
totG
+=
in
[
1
]
*
out_rem
*
in_a
[
0
];
totB
+=
in
[
2
]
*
out_rem
*
in_a
[
0
];
totA
+=
in_a
[
0
]
*
out_rem
;
in_rem
-=
out_rem
;
}
// store
if
(
totA
)
{
out
[
0
]
=
totR
/
totA
;
out
[
1
]
=
totG
/
totA
;
out
[
2
]
=
totB
/
totA
;
out_a
[
0
]
=
totA
>>
shift
;
}
else
{
out
[
0
]
=
out
[
1
]
=
out
[
2
]
=
out_a
[
0
]
=
0
;
// div by 0 is bad
}
out
+=
3
*
delta_out
;
out_a
+=
delta_out
;
}
}
else
{
// no alpha
for
(
int
x
=
0
;
x
<
length_out
;
++
x
)
{
UInt
out_rem
=
1
<<
shift
;
UInt
totR
=
0
,
totG
=
0
,
totB
=
0
;
while
(
out_rem
>=
in_rem
)
{
// eat a whole input pixel
totR
+=
in
[
0
]
*
in_rem
;
totG
+=
in
[
1
]
*
in_rem
;
totB
+=
in
[
2
]
*
in_rem
;
out_rem
-=
in_rem
;
in_rem
=
out_fact
;
in
+=
3
*
delta_in
;
}
if
(
out_rem
>
0
)
{
// eat a partial input pixel
totR
+=
in
[
0
]
*
out_rem
;
totR
+=
in
[
1
]
*
out_rem
;
totR
+=
in
[
2
]
*
out_rem
;
in_rem
-=
out_rem
;
}
// store
out
[
0
]
=
totR
>>
shift
;
out
[
1
]
=
totG
>>
shift
;
out
[
2
]
=
totB
>>
shift
;
out
+=
3
*
delta_out
;
}
}
}
}
// ----------------------------------------------------------------------------- : Resample
/* The algorithm first resizes in horizontally, then vertically,
* the two passes are essentially the same:
* - for each row:
* - each input pixel becomes a fixed amount of output (in 1<<shift fixed point math)
* - for each output pixel:
* - _('eat') input pixels until the total is 1<<shift
* - write the total to the output pixel
* - to ensure the sum of all the pixel amounts is exacly width<<shift an extra rest amount
* is _('eaten') from the first pixel;
*
* Uses fixed point numbers
*/
void
resample
(
const
Image
&
img_in
,
Image
&
img_out
)
{
resample_and_clip
(
img_in
,
img_out
,
wxRect
(
0
,
0
,
img_in
.
GetWidth
(),
img_in
.
GetHeight
()));
}
void
resample_and_clip
(
const
Image
&
img_in
,
Image
&
img_out
,
wxRect
rect
)
{
// starting position in data
int
offset_in
=
(
rect
.
x
+
img_in
.
GetWidth
()
*
rect
.
y
);
if
(
img_out
.
GetHeight
()
==
rect
.
height
)
{
// no resizing vertically
resample_pass
(
img_in
,
img_out
,
offset_in
,
0
,
rect
.
width
,
1
,
img_out
.
GetWidth
(),
1
,
rect
.
GetHeight
(),
img_in
.
GetWidth
(),
img_out
.
GetWidth
());
}
else
{
Image
img_temp
(
img_out
.
GetWidth
(),
rect
.
height
,
false
);
resample_pass
(
img_in
,
img_temp
,
offset_in
,
0
,
rect
.
width
,
1
,
img_temp
.
GetWidth
(),
1
,
rect
.
GetHeight
(),
img_in
.
GetWidth
(),
img_temp
.
GetWidth
());
resample_pass
(
img_temp
,
img_out
,
0
,
0
,
rect
.
height
,
img_temp
.
GetWidth
(),
img_out
.
GetHeight
(),
img_temp
.
GetWidth
(),
img_temp
.
GetWidth
(),
1
,
1
);
}
}
// ----------------------------------------------------------------------------- : Aspect ratio preserving
// fill an image with 100% transparent
void
fill_transparent
(
Image
&
img
)
{
if
(
!
img
.
HasAlpha
())
img
.
InitAlpha
();
memset
(
img
.
GetAlpha
(),
0
,
img
.
GetWidth
()
*
img
.
GetHeight
());
}
void
resample_preserve_aspect
(
const
Image
&
img_in
,
Image
&
img_out
)
{
int
rheight
=
img_in
.
GetHeight
()
*
img_out
.
GetWidth
()
/
img_in
.
GetWidth
();
int
rwidth
=
img_in
.
GetWidth
()
*
img_out
.
GetHeight
()
/
img_in
.
GetHeight
();
// actual size of output
if
(
rheight
<
img_out
.
GetHeight
())
rwidth
=
img_out
.
GetWidth
();
else
if
(
rwidth
<
img_out
.
GetWidth
())
rheight
=
img_out
.
GetHeight
();
else
{
rwidth
=
img_out
.
GetWidth
();
rheight
=
img_out
.
GetHeight
();}
int
dx
=
(
img_out
.
GetWidth
()
-
rwidth
)
/
2
;
int
dy
=
(
img_out
.
GetHeight
()
-
rheight
)
/
2
;
// transparent background
fill_transparent
(
img_out
);
// resample
int
offset_out
=
dx
+
img_out
.
GetWidth
()
*
dy
;
Image
img_temp
(
rwidth
,
img_in
.
GetHeight
(),
false
);
resample_pass
(
img_in
,
img_temp
,
0
,
0
,
img_in
.
GetWidth
(),
1
,
rwidth
,
1
,
img_in
.
GetHeight
(),
img_in
.
GetWidth
(),
img_temp
.
GetWidth
());
resample_pass
(
img_temp
,
img_out
,
0
,
offset_out
,
img_in
.
GetHeight
(),
img_temp
.
GetWidth
(),
rheight
,
img_out
.
GetWidth
(),
rwidth
,
1
,
1
);
}
src/gfx/rotate_image.cpp
View file @
3a201da9
...
@@ -6,8 +6,7 @@
...
@@ -6,8 +6,7 @@
// ----------------------------------------------------------------------------- : Includes
// ----------------------------------------------------------------------------- : Includes
#include "../util/prec.hpp"
#include <gfx/gfx.hpp>
#include "gfx.hpp"
// ----------------------------------------------------------------------------- : Implementation
// ----------------------------------------------------------------------------- : Implementation
...
...
src/mse.vcproj
View file @
3a201da9
...
@@ -1052,6 +1052,9 @@
...
@@ -1052,6 +1052,9 @@
<File
<File
RelativePath=
".\gfx\bezier.hpp"
>
RelativePath=
".\gfx\bezier.hpp"
>
</File>
</File>
<File
RelativePath=
".\gfx\blend_image.cpp"
>
</File>
<File
<File
RelativePath=
".\gfx\combine_image.cpp"
>
RelativePath=
".\gfx\combine_image.cpp"
>
<FileConfiguration
<FileConfiguration
...
@@ -1070,12 +1073,18 @@
...
@@ -1070,12 +1073,18 @@
<File
<File
RelativePath=
".\gfx\gfx.hpp"
>
RelativePath=
".\gfx\gfx.hpp"
>
</File>
</File>
<File
RelativePath=
".\gfx\image_effects.cpp"
>
</File>
<File
<File
RelativePath=
".\gfx\polynomial.cpp"
>
RelativePath=
".\gfx\polynomial.cpp"
>
</File>
</File>
<File
<File
RelativePath=
".\gfx\polynomial.hpp"
>
RelativePath=
".\gfx\polynomial.hpp"
>
</File>
</File>
<File
RelativePath=
".\gfx\resample_image.cpp"
>
</File>
<File
<File
RelativePath=
".\gfx\resample_text.cpp"
>
RelativePath=
".\gfx\resample_text.cpp"
>
<FileConfiguration
<FileConfiguration
...
...
src/script/image.cpp
View file @
3a201da9
...
@@ -56,11 +56,62 @@ bool script_image_up_to_date(const ScriptValueP& value) {
...
@@ -56,11 +56,62 @@ bool script_image_up_to_date(const ScriptValueP& value) {
}
}
}
}
// ----------------------------------------------------------------------------- : ScriptableImage
// ----------------------------------------------------------------------------- : ScriptableImage
ScriptImageP
ScriptableImage
::
generate
(
Context
&
ctx
)
const
{
try
{
ScriptImageP
img
=
to_script_image
(
script
.
invoke
(
ctx
));
return
img
;
}
catch
(
Error
e
)
{
// loading images can fail
// it is likely we are inside a paint function or outside the main thread, handle error later
handle_error
(
e
,
false
,
false
);
return
new_intrusive1
<
ScriptImage
>
(
Image
(
1
,
1
));
}
}
ScriptImageP
ScriptableImage
::
generate
(
Context
&
ctx
,
UInt
width
,
UInt
height
,
PreserveAspect
preserve_aspect
,
bool
saturate
)
const
{
ScriptImageP
image
=
generate
(
ctx
);
if
(
!
image
->
image
.
Ok
())
{
// return an image so we don't fail
image
->
image
=
Image
(
1
,
1
);
}
UInt
iw
=
image
->
image
.
GetWidth
(),
ih
=
image
->
image
.
GetHeight
();
if
((
iw
==
width
&&
ih
==
height
)
||
width
==
0
)
{
// already the right size
}
else
if
(
preserve_aspect
==
ASPECT_FIT
)
{
// determine actual size of resulting image
UInt
w
,
h
;
if
(
iw
*
height
>
ih
*
width
)
{
// too much height requested
w
=
width
;
h
=
width
*
ih
/
iw
;
}
else
{
w
=
height
*
iw
/
ih
;
h
=
height
;
}
Image
resampled_image
(
w
,
h
,
false
);
resample
(
image
->
image
,
resampled_image
);
image
->
image
=
resampled_image
;
}
else
{
Image
resampled_image
(
width
,
height
,
false
);
if
(
preserve_aspect
==
ASPECT_BORDER
&&
(
width
<
height
*
3
)
&&
(
height
<
width
*
3
))
{
// preserve the aspect ratio if there is not too much difference
resample_preserve_aspect
(
image
->
image
,
resampled_image
);
}
else
{
resample
(
image
->
image
,
resampled_image
);
}
image
->
image
=
resampled_image
;
}
if
(
saturate
)
{
::
saturate
(
image
->
image
,
40
);
}
return
image
;
}
ScriptImageP
ScriptableImage
::
update
(
Context
&
ctx
,
UInt
width
,
UInt
height
,
PreserveAspect
preserve_aspect
,
bool
saturate
)
{
ScriptImageP
ScriptableImage
::
update
(
Context
&
ctx
,
UInt
width
,
UInt
height
,
PreserveAspect
preserve_aspect
,
bool
saturate
)
{
// up to date?
// up to date?
if
(
!
cache
||
(
UInt
)
cache
->
image
.
GetWidth
()
!=
width
||
(
UInt
)
cache
->
image
.
GetHeight
()
==
height
)
{
if
(
!
cache
||
(
UInt
)
cache
->
image
.
GetWidth
()
!=
width
||
(
UInt
)
cache
->
image
.
GetHeight
()
==
height
||
!
upToDate
(
ctx
,
last_update
)
)
{
// cache must be updated
// cache must be updated
cache
=
generate
(
ctx
,
width
,
height
,
preserve_aspect
,
saturate
);
cache
=
generate
(
ctx
,
width
,
height
,
preserve_aspect
,
saturate
);
last_update
.
update
();
last_update
.
update
();
...
@@ -68,6 +119,10 @@ ScriptImageP ScriptableImage::update(Context& ctx, UInt width, UInt height, Pres
...
@@ -68,6 +119,10 @@ ScriptImageP ScriptableImage::update(Context& ctx, UInt width, UInt height, Pres
return
cache
;
return
cache
;
}
}
bool
ScriptableImage
::
upToDate
(
Context
&
ctx
,
Age
age
)
const
{
WITH_DYNAMIC_ARG
(
last_update_age
,
age
.
get
());
return
(
int
)
*
script
.
invoke
(
ctx
);
}
// ----------------------------------------------------------------------------- : Reflection
// ----------------------------------------------------------------------------- : Reflection
...
...
src/util/age.hpp
View file @
3a201da9
...
@@ -41,6 +41,9 @@ class Age {
...
@@ -41,6 +41,9 @@ class Age {
/// Compare two ages, smaller means earlier
/// Compare two ages, smaller means earlier
inline
bool
operator
<
(
Age
a
)
const
{
return
age
<
a
.
age
;
}
inline
bool
operator
<
(
Age
a
)
const
{
return
age
<
a
.
age
;
}
/// A number corresponding to the age
inline
LONG
get
()
const
{
return
age
;
}
private:
private:
/// This age
/// This age
LONG
age
;
LONG
age
;
...
...
src/util/dynamic_arg.hpp
View file @
3a201da9
...
@@ -27,7 +27,7 @@
...
@@ -27,7 +27,7 @@
/// Declare a dynamic argument.
/// Declare a dynamic argument.
/** The value of the argument can be got with: name()
/** The value of the argument can be got with: name()
* To change the value use WITH_DYNAMIC_ARG(name, newValue)
{ ... }
* To change the value use WITH_DYNAMIC_ARG(name, newValue)
* To be used in a header file. Use IMPLEMENT_DYN_ARG in a source file
* To be used in a header file. Use IMPLEMENT_DYN_ARG in a source file
*/
*/
#define DECLARE_DYNAMIC_ARG(Type, name) \
#define DECLARE_DYNAMIC_ARG(Type, name) \
...
@@ -42,7 +42,6 @@
...
@@ -42,7 +42,6 @@
inline
~
name
##
_changer
()
{
\
inline
~
name
##
_changer
()
{
\
name
##
_private
=
oldValue
;
\
name
##
_private
=
oldValue
;
\
}
\
}
\
inline
operator
bool
()
{
return
true
;
}
\
private:
\
private:
\
Type
oldValue
;
\
Type
oldValue
;
\
}
}
...
@@ -55,14 +54,15 @@
...
@@ -55,14 +54,15 @@
/** Usage:
/** Usage:
* @code
* @code
* // here name() == old value
* // here name() == old value
* WITH_DYNAMIC_ARG(name, newValue) {
* {
* WITH_DYNAMIC_ARG(name, newValue);
* // here name() == newValue
* // here name() == newValue
* }
* }
* // here name() == old value
* // here name() == old value
* @endcode
* @endcode
*/
*/
#define WITH_DYNAMIC_ARG(name, value) \
#define WITH_DYNAMIC_ARG(name, value) \
if
(
name
##
_changer
name
##
_dummmy
=
value
)
// hack: variable in if guard scopes over the following block
name
##
_changer
name
##
_dummmy
(
value
)
// ----------------------------------------------------------------------------- : EOF
// ----------------------------------------------------------------------------- : EOF
#endif
#endif
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment