mirror of
https://github.com/amyinspace/MagicSetEditor2.git
synced 2026-06-11 05:07:00 -04:00
New rotation system (see forum thread).
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
This commit is contained in:
@@ -75,6 +75,8 @@ Image conform_image(const Image& img, const GeneratedImage::Options& options) {
|
||||
if (options.saturate) {
|
||||
saturate(image, 40);
|
||||
}
|
||||
options.width = image.GetWidth();
|
||||
options.height = image.GetHeight();
|
||||
// rotate?
|
||||
if (options.angle != 0) {
|
||||
image = rotate_image(image, options.angle);
|
||||
|
||||
@@ -33,7 +33,8 @@ class GeneratedImage : public ScriptValue {
|
||||
, package(package), local_package(local_package)
|
||||
{}
|
||||
|
||||
int width, height; ///< Width to force the image to, or 0 to keep the width of the input
|
||||
mutable int width, height; ///< Width to force the image to, or 0 to keep the width of the input
|
||||
///< In that case, width and height will be later set to the actual size
|
||||
double zoom; ///< Zoom factor to use, when witdth=height=0
|
||||
int angle; ///< Angle to rotate image by afterwards
|
||||
PreserveAspect preserve_aspect;
|
||||
|
||||
+15
-5
@@ -45,20 +45,30 @@ void sharp_resample_and_clip(const Image& img_in, Image& img_out, wxRect rect, i
|
||||
|
||||
/// Draw text by first drawing it using a larger font and then downsampling it
|
||||
/** optionally rotated by an angle.
|
||||
* rect = rectangle to draw in
|
||||
* 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
|
||||
* (wc,hc) = the corner where drawing should begin, (0,0) for top-left, (1,1) for bottom-right
|
||||
*/
|
||||
void draw_resampled_text(DC& dc, const RealRect& rect, double stretch, int wc, int hc, int angle, const String& text, int blur_radius = 0, int repeat = 1);
|
||||
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)?
|
||||
// Note: angle & 2 == 0 for angle in {0, 180} and != 0 for angle in {90, 270)
|
||||
inline bool sideways(int angle) { return (angle & 2) != 0; }
|
||||
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}
|
||||
|
||||
@@ -145,14 +145,14 @@ void blur_image_alpha(Image& img) {
|
||||
|
||||
// Draw text by first drawing it using a larger font and then downsampling it
|
||||
// optionally rotated by an angle
|
||||
// (w2,h2) = size of text
|
||||
// (wc,hc) = the corner where drawing should begin, (0,0) for top-left, (1,1) for bottom-right
|
||||
void draw_resampled_text(DC& dc, const RealRect& rect, double stretch, int wc, int hc, int angle, const String& text, int blur_radius, int repeat) {
|
||||
void draw_resampled_text(DC& dc, const RealPoint& pos, const RealRect& rect, double stretch, int angle, const String& text, int blur_radius, int repeat) {
|
||||
// enlarge slightly; some fonts are larger then the GetTextExtent tells us (especially italic fonts)
|
||||
int w = static_cast<int>(rect.width) + 3 + 2 * blur_radius, h = static_cast<int>(rect.height) + 1 + 2 * blur_radius;
|
||||
// determine sub-pixel position
|
||||
int xi = static_cast<int>(rect.x), yi = static_cast<int>(rect.y);
|
||||
int xsub = static_cast<int>(text_scaling * (rect.x - xi)), ysub = static_cast<int>(text_scaling * (rect.y - yi));
|
||||
int xi = static_cast<int>(rect.x) - blur_radius / text_scaling,
|
||||
yi = static_cast<int>(rect.y) - blur_radius / text_scaling;
|
||||
int xsub = static_cast<int>(text_scaling * (pos.x - xi)),
|
||||
ysub = static_cast<int>(text_scaling * (pos.y - yi));
|
||||
// draw text
|
||||
Bitmap buffer(w * text_scaling, h * text_scaling, 24); // should be initialized to black
|
||||
wxMemoryDC mdc;
|
||||
@@ -161,7 +161,7 @@ void draw_resampled_text(DC& dc, const RealRect& rect, double stretch, int wc, i
|
||||
// now draw the text
|
||||
mdc.SetFont(dc.GetFont());
|
||||
mdc.SetTextForeground(*wxWHITE);
|
||||
mdc.DrawRotatedText(text, (wc * w + blur_radius) * text_scaling + xsub, (hc * h + blur_radius) * text_scaling + ysub, angle);
|
||||
mdc.DrawRotatedText(text, xsub, ysub, angle);
|
||||
// get image
|
||||
mdc.SelectObject(wxNullBitmap);
|
||||
Image img_large = buffer.ConvertToImage();
|
||||
@@ -177,8 +177,7 @@ void draw_resampled_text(DC& dc, const RealRect& rect, double stretch, int wc, i
|
||||
}
|
||||
// step 3. draw to dc
|
||||
for (int i = 0 ; i < repeat ; ++i) {
|
||||
dc.DrawBitmap(img_small, xi + static_cast<int>(wc * (rect.width - w)) - blur_radius,
|
||||
yi + static_cast<int>(hc * (rect.height - h)) - blur_radius);
|
||||
dc.DrawBitmap(img_small, xi, yi);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -84,10 +84,13 @@ struct Rotate270 {
|
||||
|
||||
Image rotate_image(const Image& image, int angle) {
|
||||
switch (angle % 360) {
|
||||
case 0: return image;
|
||||
case 90: return rotate_image_impl<Rotate90> (image);
|
||||
case 180: return rotate_image_impl<Rotate180>(image);
|
||||
case 270: return rotate_image_impl<Rotate270>(image);
|
||||
default: return image;
|
||||
default:
|
||||
if (!image.HasAlpha()) const_cast<Image&>(image).InitAlpha();
|
||||
return image.Rotate(angle * M_PI / 180, wxPoint(0,0));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user