mirror of
https://github.com/amyinspace/MagicSetEditor2.git
synced 2026-06-10 04:57:00 -04:00
b79f52db84
Major changes: - when rotating, the top left corner of the rectangle stays in place. - ValueViewers get a dc that is pre-rotated/translated for them, i.e. (0,0) is the top-left of the viewer (with ValueViewer::getRotation). - moved 'angle' from individual Styles to the Style base class. - any rotation angle is now possible. angle is still an int for now. This warrants a version bump git-svn-id: svn://svn.code.sf.net/p/magicseteditor/code/trunk@782 0fc631ac-6414-0410-93d0-97cfa31319b6
222 lines
8.1 KiB
C++
222 lines
8.1 KiB
C++
//+----------------------------------------------------------------------------+
|
|
//| Description: Magic Set Editor - Program to make Magic (tm) cards |
|
|
//| Copyright: (C) 2001 - 2007 Twan van Laarhoven |
|
|
//| License: GNU General Public License 2 or later (see file COPYING) |
|
|
//+----------------------------------------------------------------------------+
|
|
|
|
#ifndef HEADER_GFX_GFX
|
|
#define HEADER_GFX_GFX
|
|
|
|
/** @file gfx/gfx.hpp
|
|
*
|
|
* Graphics/image processing functions.
|
|
*/
|
|
|
|
// ----------------------------------------------------------------------------- : Includes
|
|
|
|
#include <util/prec.hpp>
|
|
#include <util/real_point.hpp>
|
|
|
|
// ----------------------------------------------------------------------------- : Resampling
|
|
|
|
/// Resample (resize) an image, uses bilenear filtering
|
|
void resample(const Image& img_in, Image& img_out);
|
|
|
|
/// Resamples an image, first clips the input image to a specified rectangle
|
|
/** The selected rectangle is resampled into the entire output image */
|
|
void resample_and_clip(const Image& img_in, Image& img_out, wxRect rect);
|
|
|
|
/// How to preserve the aspect ratio of an image when rescaling
|
|
enum PreserveAspect
|
|
{ ASPECT_STRETCH ///< don't preserve
|
|
, ASPECT_BORDER ///< put borders around the image to make it the right shape
|
|
, 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);
|
|
|
|
/// Resample an image to create a sharp result by applying a sharpening filter
|
|
/** Amount must be between 0 and 100 */
|
|
void sharp_resample(const Image& img_in, Image& img_out, int amount);
|
|
|
|
/// Sharpening version of of resample_and_clip
|
|
void sharp_resample_and_clip(const Image& img_in, Image& img_out, wxRect rect, int amount);
|
|
|
|
/// Draw text by first drawing it using a larger font and then downsampling it
|
|
/** optionally rotated by an angle.
|
|
* pos = the position to draw
|
|
* rect = rectangle to draw in (a rectangle somewhere around pos)
|
|
* stretch = amount to stretch in the direction of the text after drawing
|
|
*/
|
|
void draw_resampled_text(DC& dc, const RealPoint& pos, const RealRect& rect, double stretch, int angle, const String& text, int blur_radius = 0, int repeat = 1);
|
|
|
|
// scaling factor to use when drawing resampled text
|
|
extern const int text_scaling;
|
|
|
|
// ----------------------------------------------------------------------------- : Image rotation
|
|
|
|
/// Is an angle a {0,90,180,270}?
|
|
inline bool straight(int angle) { return angle % 90 == 0; }
|
|
|
|
/// Is an angle sideways (90 or 270 degrees)?
|
|
inline bool sideways(int angle) {
|
|
int a = (angle + 3600) % 180;
|
|
return (a > 45 && a < 135);
|
|
}
|
|
|
|
/// Convert radians to degrees
|
|
inline double rad_to_deg(double rad) { return rad * (180.0 / M_PI); }
|
|
/// Convert degrees to radians
|
|
inline double deg_to_rad(double deg) { return deg * (M_PI / 180.0); }
|
|
|
|
/// Rotates an image counter clockwise
|
|
/// angle must be a multiple of 90, i.e. {0,90,180,270}
|
|
Image rotate_image(const Image& image, int angle);
|
|
|
|
// ----------------------------------------------------------------------------- : Blending
|
|
|
|
/// Blends two images together using some linear gradient
|
|
/** The result is stored in img1
|
|
* The two coordinates give the two points between which the images are blended
|
|
* Coordinates are given in the range [0..1);
|
|
*/
|
|
void linear_blend(Image& img1, const Image& img2, double x1,double y1, double x2,double y2);
|
|
|
|
/// Blends two images together, using a third image as a mask
|
|
/** The result is stored in img1
|
|
* mask is used as a mask, white pixels are taken from img1, black pixels from img2
|
|
* color channels are blended separatly
|
|
*/
|
|
void mask_blend(Image& img1, const Image& img2, const Image& mask);
|
|
|
|
// ----------------------------------------------------------------------------- : Effects
|
|
|
|
/// Saturate an image, amount should be in range [0...100]
|
|
void saturate(Image& image, int amount);
|
|
|
|
// ----------------------------------------------------------------------------- : Combining
|
|
|
|
/// Ways in which images can be combined, similair to what Photoshop supports
|
|
enum ImageCombine
|
|
{ COMBINE_DEFAULT // normal combine, but with a low priority, i.e. "apply default instead of add" == "add"
|
|
// it is not representable in scripting/files, so should only be used internally
|
|
, COMBINE_NORMAL
|
|
, COMBINE_ADD
|
|
, COMBINE_SUBTRACT
|
|
, COMBINE_STAMP
|
|
, COMBINE_DIFFERENCE
|
|
, COMBINE_NEGATION
|
|
, COMBINE_MULTIPLY
|
|
, COMBINE_DARKEN
|
|
, COMBINE_LIGHTEN
|
|
, COMBINE_COLOR_DODGE
|
|
, COMBINE_COLOR_BURN
|
|
, COMBINE_SCREEN
|
|
, COMBINE_OVERLAY
|
|
, COMBINE_HARD_LIGHT
|
|
, COMBINE_SOFT_LIGHT
|
|
, COMBINE_REFLECT
|
|
, COMBINE_GLOW
|
|
, COMBINE_FREEZE
|
|
, COMBINE_HEAT
|
|
, COMBINE_AND
|
|
, COMBINE_OR
|
|
, COMBINE_XOR
|
|
, COMBINE_SHADOW
|
|
, COMBINE_SYMMETRIC_OVERLAY
|
|
};
|
|
|
|
/// Combine image b onto image a using some combining function.
|
|
/// The results are stored in the image A.
|
|
/// This image gets the alpha channel from B, it should then be
|
|
/// drawn onto the area where A originated.
|
|
void combine_image(Image& a, const Image& b, ImageCombine combine);
|
|
|
|
/// Draw an image to a DC using a combining function
|
|
void draw_combine_image(DC& dc, UInt x, UInt y, const Image& img, ImageCombine combine);
|
|
|
|
// ----------------------------------------------------------------------------- : Masks
|
|
|
|
/// Use the red channel of img_alpha as alpha channel for img
|
|
void set_alpha(Image& img, const Image& img_alpha);
|
|
/// Use the given bytes as alpha channel for img
|
|
void set_alpha(Image& img, Byte* alphas, const wxSize& alphas_size);
|
|
/// Set the transparency of img
|
|
void set_alpha(Image& img, double alpha);
|
|
|
|
/// An alpha mask is an alpha channel that can be copied to another image
|
|
/** It is created by treating black in the source image as transparent and white (red) as opaque
|
|
*/
|
|
class AlphaMask : public IntrusivePtrBase<AlphaMask> {
|
|
public:
|
|
AlphaMask(const Image& mask);
|
|
~AlphaMask();
|
|
|
|
/// Apply the alpha mask to an image
|
|
void setAlpha(Image& i) const;
|
|
/// Apply the alpha mask to a bitmap
|
|
void setAlpha(Bitmap& b) const;
|
|
|
|
/// Is the given location fully transparent?
|
|
bool isTransparent(int x, int y) const;
|
|
|
|
/// Determine a convex hull polygon *around* the mask
|
|
void convexHull(vector<wxPoint>& points) const;
|
|
|
|
/// Size of the mask
|
|
wxSize size;
|
|
private:
|
|
Byte* alpha;
|
|
};
|
|
|
|
/// A contour mask stores the size and position of each line in the image
|
|
/** It is created by treating black in the source image as transparent and white (red) as opaque
|
|
* The left is the first non-transparent pixel, the right is the last non-transparent pixel
|
|
*/
|
|
class ContourMask {
|
|
public:
|
|
ContourMask();
|
|
~ContourMask();
|
|
|
|
/// Load a contour mask
|
|
void load(const Image& image);
|
|
/// Unload the mask
|
|
void unload();
|
|
/// Is a mask loaded?
|
|
inline bool ok() const { return width > 0 && height > 0; }
|
|
|
|
/// Returns the start of a row, when the mask were stretched to size
|
|
double rowLeft (double y, RealSize size) const;
|
|
/// Returns the end of a row, when the mask were stretched to size
|
|
double rowRight(double y, RealSize size) const;
|
|
|
|
private:
|
|
int width, height;
|
|
int *lefts, *rights;
|
|
};
|
|
|
|
// ----------------------------------------------------------------------------- : Color utility functions
|
|
|
|
inline int bot(int x) { return max(0, x); } ///< bottom range check for color values
|
|
inline int top(int x) { return min(255, x); } ///< top range check for color values
|
|
inline int col(int x) { return top(bot(x)); } ///< top and bottom range check for color values
|
|
|
|
/// Linear interpolation between colors
|
|
Color lerp(const Color& a, const Color& b, double t);
|
|
|
|
/// convert HSL to RGB, h,s,l must be in range [0...1)
|
|
Color hsl2rgb(double h, double s, double l);
|
|
|
|
/// A darker version of a color
|
|
Color darken(const Color& c);
|
|
|
|
/// A saturated version of a color
|
|
Color saturate(const Color& c, double amount);
|
|
|
|
/// Fills an image with the specified color
|
|
void fill_image(Image& image, const Color& color);
|
|
|
|
// ----------------------------------------------------------------------------- : EOF
|
|
#endif
|