write text at any angle............... :) patches form willem again :)

SVN revision: 2583
This commit is contained in:
Carsten Haitzler 2000-04-30 19:15:12 +00:00
parent 714e25d1d5
commit 2676818732
10 changed files with 316 additions and 151 deletions

View File

@ -6,3 +6,4 @@ KainX (Michael Jennings) <mej@eterm.org>
Eric Dorland <dorland@lords.com>
Chutt (Isaac Richards) <ijr@po.cwru.edu>
gilbertt (Tom Gilbert) <gilbertt@btinternet.com>
Takis <takis@lumumba.luc.ac.be>

View File

@ -1,6 +1,6 @@
# Note that this is NOT a relocatable package
%define ver 0.0.2
%define rel SNAP
%define ver 0.0.4
%define rel 1
%define prefix /usr
Summary: Powerful image loading and rendering library for X11R6

View File

@ -32,7 +32,8 @@ enum _imlib_text_direction
IMLIB_TEXT_TO_RIGHT = 0,
IMLIB_TEXT_TO_LEFT = 1,
IMLIB_TEXT_TO_DOWN = 2,
IMLIB_TEXT_TO_UP = 3
IMLIB_TEXT_TO_UP = 3,
IMLIB_TEXT_TO_ANGLE = 4
};
enum _imlib_load_error
@ -95,6 +96,7 @@ void imlib_context_set_color_modifier(Imlib_Color_Modifier color_modifier);
void imlib_context_set_operation(Imlib_Operation operation);
void imlib_context_set_font(Imlib_Font font);
void imlib_context_set_direction(Imlib_Text_Direction direction);
void imlib_context_set_angle(double angle);
void imlib_context_set_color(int red, int green, int blue, int alpha);
void imlib_context_set_color_range(Imlib_Color_Range color_range);
void imlib_context_set_progress_function(Imlib_Progress_Function progress_function);
@ -230,7 +232,8 @@ void imlib_save_image_with_error_return(const char *filename, Imlib_Load_Error *
/* need to add arbitary rotation routines */
Imlib_Image imlib_create_rotated_image(double angle);
void imlib_blend_image_onto_image_at_angle(Imlib_Image source_image, char merge_alpha, int source_x, int source_y, int source_width, int source_height, int destination_x1, int destination_y1, int destination_x2, int destination_y2);
void imlib_blend_image_onto_image_at_angle(Imlib_Image source_image, char merge_alpha, int source_x, int source_y, int source_width, int source_height, int destination_x, int destination_y, int angle_x, int angle_y);
void imlib_blend_image_onto_image_skewed(Imlib_Image source_image, char merge_alpha, int source_x, int source_y, int source_width, int source_height, int destination_x, int destination_y, int h_angle_x, int h_angle_y, int v_angle_x, int v_angle_y);
void imlib_image_filter(void);
Imlib_Filter imlib_create_filter(int initsize);

View File

@ -75,6 +75,7 @@ static Imlib_Color_Modifier ctxt_color_modifier = NULL;
static Imlib_Operation ctxt_operation = IMLIB_OP_COPY;
static Imlib_Font ctxt_font = NULL;
static Imlib_Text_Direction ctxt_direction = IMLIB_TEXT_TO_RIGHT;
static double ctxt_angle = 0.0;
static Imlib_Color ctxt_color = {255, 255, 255, 255};
static Imlib_Color_Range ctxt_color_range = NULL;
static Imlib_Image ctxt_image = NULL;
@ -235,6 +236,12 @@ imlib_context_set_direction(Imlib_Text_Direction direction)
ctxt_direction = direction;
}
void
imlib_context_set_angle(double angle)
{
ctxt_angle = angle;
}
Imlib_Text_Direction
imlib_context_get_direction(void)
{
@ -1488,7 +1495,7 @@ imlib_text_draw(int x, int y, const char *text)
__imlib_render_str(im, ctxt_font, x, y, text, (DATA8)ctxt_color.red,
(DATA8)ctxt_color.green, (DATA8)ctxt_color.blue,
(DATA8)ctxt_color.alpha, (char)ctxt_direction,
NULL, NULL, 0, NULL, NULL,
ctxt_angle, NULL, NULL, 0, NULL, NULL,
ctxt_operation);
}
@ -1515,7 +1522,7 @@ imlib_text_draw_with_return_metrics(int x, int y, const char *text,
__imlib_render_str(im, fn, x, y, text, (DATA8)ctxt_color.red,
(DATA8)ctxt_color.green, (DATA8)ctxt_color.blue,
(DATA8)ctxt_color.alpha, (char)ctxt_direction,
width_return, height_return, 0,
ctxt_angle, width_return, height_return, 0,
horizontal_advance_return, vertical_advance_return,
ctxt_operation);
}
@ -1546,6 +1553,43 @@ imlib_get_text_size(const char *text, int *width_return, int *height_return)
if (height_return)
*height_return = w;
break;
case IMLIB_TEXT_TO_ANGLE:
if (width_return || height_return)
{
double sa, ca;
sa = sin(ctxt_angle);
ca = cos(ctxt_angle);
if (width_return) {
double x1, x2, xt;
x1 = x2 = 0.0;
xt = ca * w;
if (xt < x1) x1 = xt;
if (xt > x2) x2 = xt;
xt = -(sa * h);
if (xt < x1) x1 = xt;
if (xt > x2) x2 = xt;
xt = ca * w - sa * h;
if (xt < x1) x1 = xt;
if (xt > x2) x2 = xt;
*width_return = (int)(x2 - x1);
}
if (height_return) {
double y1, y2, yt;
y1 = y2 = 0.0;
yt = sa * w;
if (yt < y1) y1 = yt;
if (yt > y2) y2 = yt;
yt = ca * h;
if (yt < y1) y1 = yt;
if (yt > y2) y2 = yt;
yt = sa * w + ca * h;
if (yt < y1) y1 = yt;
if (yt > y2) y2 = yt;
*height_return = (int)(y2 - y1);
}
}
break;
default:
break;
}
@ -2213,15 +2257,18 @@ imlib_create_rotated_image(double angle)
#ifdef DO_MMX_ASM
if (__imlib_get_cpuid() & CPUID_MMX)
__imlib_mmx_RotateAA(im_old->data, im->data, im_old->w,
im_old->w, im_old->h, im->w, sz, sz, x, y, dx, dy);
im_old->w, im_old->h, im->w, sz, sz, x, y,
dx, dy, -dy, dx);
else
#endif
__imlib_RotateAA(im_old->data, im->data, im_old->w,
im_old->w, im_old->h, im->w, sz, sz, x, y, dx, dy);
im_old->w, im_old->h, im->w, sz, sz, x, y,
dx, dy, -dy, dx);
} else
{
__imlib_RotateSample(im_old->data, im->data, im_old->w,
im_old->w, im_old->h, im->w, sz, sz, x, y, dx, dy);
im_old->w, im_old->h, im->w, sz, sz, x, y,
dx, dy, -dy, dx);
}
SET_FLAG(im->flags, F_HAS_ALPHA);
@ -2233,8 +2280,8 @@ imlib_blend_image_onto_image_at_angle(Imlib_Image source_image,
char merge_alpha,
int source_x, int source_y,
int source_width, int source_height,
int destination_x1, int destination_y1,
int destination_x2, int destination_y2)
int destination_x, int destination_y,
int angle_x, int angle_y)
{
ImlibImage *im_src, *im_dst;
@ -2244,11 +2291,37 @@ imlib_blend_image_onto_image_at_angle(Imlib_Image source_image,
CAST_IMAGE(im_dst, ctxt_image);
__imlib_DirtyImage(im_dst);
__imlib_DirtyPixmapsForImage(im_dst);
__imlib_BlendImageToImageAtAngle(im_src, im_dst, ctxt_anti_alias,
ctxt_blend, merge_alpha, source_x, source_y,
source_width, source_height, destination_x1,
destination_y1, destination_x2, destination_y2,
ctxt_color_modifier, ctxt_operation);
__imlib_BlendImageToImageSkewed(im_src, im_dst, ctxt_anti_alias,
ctxt_blend, merge_alpha, source_x, source_y,
source_width, source_height,
destination_x, destination_y,
angle_x, angle_y, 0, 0,
ctxt_color_modifier, ctxt_operation);
}
void
imlib_blend_image_onto_image_skewed(Imlib_Image source_image,
char merge_alpha,
int source_x, int source_y,
int source_width, int source_height,
int destination_x, int destination_y,
int h_angle_x, int h_angle_y,
int v_angle_x, int v_angle_y)
{
ImlibImage *im_src, *im_dst;
CHECK_PARAM_POINTER("imlib_blend_image_onto_image_skewed", "source_image", source_image);
CHECK_PARAM_POINTER("imlib_blend_image_onto_image_skewed", "image", ctxt_image);
CAST_IMAGE(im_src, source_image);
CAST_IMAGE(im_dst, ctxt_image);
__imlib_DirtyImage(im_dst);
__imlib_DirtyPixmapsForImage(im_dst);
__imlib_BlendImageToImageSkewed(im_src, im_dst, ctxt_anti_alias,
ctxt_blend, merge_alpha, source_x, source_y,
source_width, source_height,
destination_x, destination_y,
h_angle_x, h_angle_y, v_angle_x, v_angle_y,
ctxt_color_modifier, ctxt_operation);
}
void

View File

@ -15,7 +15,8 @@
.align 8
/*\ Prototype: __imlib_mmx_RotateAA(DATA32 *src, DATA32 *dest, int sow, int sw,
|*| int sh, int dow, int dw, int dh, int x, int y, int dx, int dy)
|*| int sh, int dow, int dw, int dh, int x, int y,
|*| int dxh, int dyh, int dxv, int dyv)
\*/
#define src 8(%ebp)
@ -28,8 +29,10 @@
#define dh 36(%ebp)
#define x 40(%ebp)
#define y 44(%ebp)
#define dx 48(%ebp)
#define dy 52(%ebp)
#define dxh 48(%ebp)
#define dyh 52(%ebp)
#define dxv 56(%ebp)
#define dyv 60(%ebp)
/*\ Local variables \*/
#define j -4(%ebp)
@ -74,18 +77,18 @@ __imlib_mmx_RotateAA:
movl dw, %eax
leal (%edi, %eax, 4), %edi
/*\ dlx = -dy - dw * dx \*/
/*\ dlx = dxv - dw * dxh \*/
movl dw, %eax
imull dx, %eax
imull dxh, %eax
negl %eax
subl dy, %eax
addl dxv, %eax
movl %eax, dlx
/*\ dly = dx - dw * dy \*/
/*\ dly = dyv - dw * dyh \*/
movl dw, %eax
imull dy, %eax
imull dyh, %eax
negl %eax
addl dx, %eax
addl dyv, %eax
movl %eax, dly
/*\ j = dh \*/
@ -98,19 +101,19 @@ __imlib_mmx_RotateAA:
movl x, %ecx
cmpl %edx, %ecx
jae .rotate_outside
/*\ x + dx * dw < sw \*/
movl dx, %ebx
/*\ x + dxh * dw < sw \*/
movl dxh, %ebx
imull dw, %ebx
addl %ebx, %ecx
cmpl %edx, %ecx
jae .rotate_outside
/*\ x + dx * dw - dy * dh < sw \*/
movl dy, %eax
/*\ x + dxh * dw + dxv * dh < sw \*/
movl dxv, %eax
imull dh, %eax
subl %eax, %ecx
cmpl %edx, %ecx
jae .rotate_outside
/*\ x - dy * dh < sw \*/
/*\ x + dxv * dh < sw \*/
subl %ebx, %ecx
cmpl %edx, %ecx
jae .rotate_outside
@ -120,19 +123,19 @@ __imlib_mmx_RotateAA:
movl y, %ecx
cmpl %edx, %ecx
jae .rotate_outside
/*\ y + dy * dw < sh \*/
movl dx, %ebx
/*\ y + dyh * dw < sh \*/
movl dyh, %ebx
imull dw, %ebx
addl %ebx, %ecx
cmpl %edx, %ecx
jae .rotate_outside
/*\ y + dy * dw + dx * dh < sh \*/
movl dy, %eax
/*\ y + dyh * dw + dyv * dh < sh \*/
movl dyv, %eax
imull dh, %eax
addl %eax, %ecx
cmpl %edx, %ecx
jae .rotate_outside
/*\ y + dx * dh < sh \*/
/*\ y + dyv * dh < sh \*/
subl %ebx, %ecx
cmpl %edx, %ecx
jae .rotate_outside
@ -196,7 +199,7 @@ __imlib_mmx_RotateAA:
packuswb %mm5, %mm5
movd %mm5, (%edi, %ecx, 4)
paddd dx, %mm6
paddd dxh, %mm6
incl %ecx
jnz .inside_loop_x
@ -421,7 +424,7 @@ __imlib_mmx_RotateAA:
movl %eax, (%edi, %ecx, 4)
.outside_il_end:
paddd dx, %mm6
paddd dxh, %mm6
incl %ecx
jnz .outside_loop_x

View File

@ -12,9 +12,11 @@
#include "font.h"
#include <sys/types.h>
#include <string.h>
#include <math.h>
#include "file.h"
#include "updates.h"
#include "rgbadraw.h"
#include "rotate.h"
#define TT_VALID( handle ) ( ( handle ).z != NULL )
@ -382,13 +384,13 @@ __imlib_calc_size(ImlibFont *f, int *width, int *height, const char *text)
void
__imlib_render_str(ImlibImage *im, ImlibFont *fn, int drx, int dry, const char *text,
DATA8 r, DATA8 g, DATA8 b, DATA8 a,
char dir, int *retw, int *reth, int blur,
char dir, double angle, int *retw, int *reth, int blur,
int *nextx, int *nexty, ImlibOp op)
{
DATA32 lut[9], *p, *tmp;
TT_Glyph_Metrics metrics;
TT_F26Dot6 x, y, xmin, ymin, xmax, ymax;
int w, h, i, ioff, iread, xor, yor;
int w, h, i, ioff, iread, tw, th;
char *off, *read, *_off, *_read;
int x_offset, y_offset;
unsigned char j;
@ -424,14 +426,15 @@ __imlib_render_str(ImlibImage *im, ImlibFont *fn, int drx, int dry, const char *
/* figure out the size this text string is going to be */
__imlib_calc_size(fn, &w, &h, text);
tw = w; th = w;
switch(dir)
{
case 0:
case 1:
if (retw)
*retw = w;
*retw = tw;
if (reth)
*reth = h;
*reth = th;
if (nexty)
*nexty = fn->ascent + fn->descent;
if (nextx)
@ -444,10 +447,11 @@ __imlib_render_str(ImlibImage *im, ImlibFont *fn, int drx, int dry, const char *
break;
case 2:
case 3:
tw = h; th = w;
if (retw)
*retw = h;
*retw = tw;
if (reth)
*reth = w;
*reth = th;
if (nextx)
*nextx = fn->ascent + fn->descent;
if (nexty)
@ -458,11 +462,57 @@ __imlib_render_str(ImlibImage *im, ImlibFont *fn, int drx, int dry, const char *
(metrics.bbox.xMax / 64);
}
break;
case 4:
{
double sa, ca;
double x1, x2, xt;
double y1, y2, yt;
sa = sin(angle);
ca = cos(angle);
x1 = x2 = 0.0;
xt = ca * w;
if (xt < x1) x1 = xt;
if (xt > x2) x2 = xt;
xt = -(sa * h);
if (xt < x1) x1 = xt;
if (xt > x2) x2 = xt;
xt = ca * w - sa * h;
if (xt < x1) x1 = xt;
if (xt > x2) x2 = xt;
tw = (int)(x2 - x1);
y1 = y2 = 0.0;
yt = sa * w;
if (yt < y1) y1 = yt;
if (yt > y2) y2 = yt;
yt = ca * h;
if (yt < y1) y1 = yt;
if (yt > y2) y2 = yt;
yt = sa * w + ca * h;
if (yt < y1) y1 = yt;
if (yt > y2) y2 = yt;
th = (int)(y2 - y1);
}
if (retw)
*retw = tw;
if (reth)
*reth = th;
if (nexty)
*nexty = fn->ascent + fn->descent;
if (nextx)
{
j = text[strlen(text) - 1];
TT_Get_Glyph_Metrics(fn->glyphs[j], &metrics);
*nextx = w - x_offset + (metrics.advance / 64) -
(metrics.bbox.xMax / 64);
}
break;
default:
break;
}
/* if the text is completely outside the image - give up */
if (((drx + w) <= 0) || ((dry + h) <= 0))
if (((drx + tw) <= 0) || ((dry + th) <= 0))
return;
/* create a scratch pad for it */
rmap = __imlib_create_font_raster(w, h);
@ -588,27 +638,50 @@ __imlib_render_str(ImlibImage *im, ImlibFont *fn, int drx, int dry, const char *
switch(dir)
{
case 0: /* to right */
angle = 0.0;
break;
case 1: /* to left */
__imlib_FlipImageHoriz(&im2);
__imlib_FlipImageVert(&im2);
angle = 0.0;
__imlib_FlipImageBoth(&im2);
break;
case 2: /* to down */
__imlib_FlipImageDiagonal(&im2, 0);
angle = 0.0;
__imlib_FlipImageDiagonal(&im2, 1);
break;
case 3: /* to up */
__imlib_FlipImageDiagonal(&im2, 0);
__imlib_FlipImageHoriz(&im2);
__imlib_FlipImageVert(&im2);
angle = 0.0;
__imlib_FlipImageDiagonal(&im2, 2);
break;
default:
break;
}
tmp = im2.data;
__imlib_BlendRGBAToData(tmp, im2.w, im2.h,
im->data, im->w, im->h,
0, 0, drx, dry, im2.w, im2.h,
1, IMAGE_HAS_ALPHA(im), NULL, op, 0);
if (angle == 0.0) {
__imlib_BlendRGBAToData(tmp, im2.w, im2.h,
im->data, im->w, im->h,
0, 0, drx, dry, im2.w, im2.h,
1, IMAGE_HAS_ALPHA(im), NULL, op, 0);
} else {
int xx, yy;
double sa, ca;
sa = sin(angle);
ca = cos(angle);
xx = drx;
yy = dry;
if (sa > 0.0)
xx += sa * im2.h;
else
yy -= sa * im2.w;
if (ca < 0.0) {
xx -= ca * im2.w;
yy -= ca * im2.h;
}
__imlib_BlendImageToImageSkewed(&im2, im, 1, 1,
IMAGE_HAS_ALPHA(im),
0, 0, im2.w, im2.h,
xx, yy, (w * ca), (w * sa), 0, 0,
NULL, op);
}
free(tmp);
}
__imlib_destroy_font_raster(rmap);

View File

@ -36,7 +36,7 @@ void __imlib_calc_size(ImlibFont *f, int *width, int *height,
void __imlib_render_str(ImlibImage *im, ImlibFont *fn, int drx,
int dry, const char *text,
DATA8 r, DATA8 g, DATA8 b, DATA8 a,
char dir, int *retw, int *reth, int blur,
char dir, double angle, int *retw, int *reth, int blur,
int *nextx, int *nexty, ImlibOp op);
int __imlib_char_pos(ImlibFont *fn, const char *text, int x, int y,
int *cx, int *cy, int *cw, int *ch);

View File

@ -51,7 +51,8 @@
/*\ Rotate by pixel sampling only, target inside source \*/
static void
__imlib_RotateSampleInside(DATA32 *src, DATA32 *dest, int sow, int dow,
int dw, int dh, int x, int y, int dx, int dy)
int dw, int dh, int x, int y,
int dxh, int dyh, int dxv, int dyv)
{
int i;
@ -62,14 +63,14 @@ __imlib_RotateSampleInside(DATA32 *src, DATA32 *dest, int sow, int dow,
do {
*dest = src[(x >> _ROTATE_PREC) + ((y >> _ROTATE_PREC) * sow)];
/*\ RIGHT; \*/
x += dx;
y += dy;
x += dxh;
y += dyh;
dest++;
} while (--i >= 0);
if (--dh <= 0) break;
/*\ DOWN/LEFT; \*/
x += -dy - dw * dx;
y += dx - dw * dy;
x += dxv - dw * dxh;
y += dyv - dw * dyh;
dest += (dow - dw);
}
}
@ -77,7 +78,8 @@ __imlib_RotateSampleInside(DATA32 *src, DATA32 *dest, int sow, int dow,
/*\ Same as last function, but with antialiasing \*/
static void
__imlib_RotateAAInside(DATA32 *src, DATA32 *dest, int sow, int dow,
int dw, int dh, int x, int y, int dx, int dy)
int dw, int dh, int x, int y,
int dxh, int dyh, int dxv, int dyv)
{
int i;
@ -90,14 +92,14 @@ __imlib_RotateAAInside(DATA32 *src, DATA32 *dest, int sow, int dow,
((y >> _ROTATE_PREC) * sow));
INTERP_ARGB(dest, src_x_y, sow, x, y);
/*\ RIGHT; \*/
x += dx;
y += dy;
x += dxh;
y += dyh;
dest++;
} while (--i >= 0);
if (--dh <= 0) break;
/*\ DOWN/LEFT; \*/
x += -dy - dw * dx;
y += dx - dw * dy;
x += dxv - dw * dxh;
y += dyv - dw * dyh;
dest += (dow - dw);
}
}
@ -110,7 +112,7 @@ __imlib_RotateAAInside(DATA32 *src, DATA32 *dest, int sow, int dow,
|*| v in [-t .. 0) is also special, as its the same as ~v in [0 .. t)
\*/
static int
__check_inside_coords(int x, int y, int dx, int dy,
__check_inside_coords(int x, int y, int dxh, int dyh, int dxv, int dyv,
int dw, int dh, int sw, int sh)
{
sw <<= _ROTATE_PREC;
@ -118,13 +120,13 @@ __check_inside_coords(int x, int y, int dx, int dy,
if (((unsigned)x >= sw) || ((unsigned)y >= sh))
return 0;
x += dx * dw; y += dy * dw;
x += dxh * dw; y += dyh * dw;
if (((unsigned)x >= sw) || ((unsigned)y >= sh))
return 0;
x -= dy * dh; y += dx * dh;
x += dxv * dh; y += dyv * dh;
if (((unsigned)x >= sw) || ((unsigned)y >= sh))
return 0;
x -= dx * dw; y -= dy * dw;
x -= dxh * dw; y -= dyh * dw;
if (((unsigned)x >= sw) || ((unsigned)y >= sh))
return 0;
@ -134,14 +136,16 @@ __check_inside_coords(int x, int y, int dx, int dy,
/*\ These ones don't need the target to be inside the source \*/
void
__imlib_RotateSample(DATA32 *src, DATA32 *dest, int sow, int sw, int sh,
int dow, int dw, int dh, int x, int y, int dx, int dy)
int dow, int dw, int dh, int x, int y,
int dxh, int dyh, int dxv, int dyv)
{
int i;
if ((dw < 1) || (dh < 1)) return;
if (__check_inside_coords(x, y, dx, dy, dw, dh, sw, sh)) {
__imlib_RotateSampleInside(src, dest, sow, dow, dw, dh, x, y, dx, dy);
if (__check_inside_coords(x, y, dxh, dyh, dxv, dyv, dw, dh, sw, sh)) {
__imlib_RotateSampleInside(src, dest, sow, dow, dw, dh, x, y,
dxh, dyh, dxv, dyv);
return;
}
@ -155,15 +159,15 @@ __imlib_RotateSample(DATA32 *src, DATA32 *dest, int sow, int sw, int sh,
*dest = src[(x >> _ROTATE_PREC) + ((y >> _ROTATE_PREC) * sow)];
else *dest = 0;
/*\ RIGHT; \*/
x += dx;
y += dy;
x += dxh;
y += dyh;
dest++;
} while (--i >= 0);
if (--dh <= 0) break;
/*\ DOWN/LEFT; \*/
x += -dy - dw * dx;
y += dx - dw * dy;
x += dxv - dw * dxh;
y += dyv - dw * dyh;
dest += (dow - dw);
}
@ -177,14 +181,16 @@ __imlib_RotateSample(DATA32 *src, DATA32 *dest, int sow, int sw, int sh,
\*/
void
__imlib_RotateAA(DATA32 *src, DATA32 *dest, int sow, int sw, int sh,
int dow, int dw, int dh, int x, int y, int dx, int dy)
int dow, int dw, int dh, int x, int y,
int dxh, int dyh, int dxv, int dyv)
{
int i;
if ((dw < 1) || (dh < 1)) return;
if (__check_inside_coords(x, y, dx, dy, dw, dh, sw - 1, sh - 1)) {
__imlib_RotateAAInside(src, dest, sow, dow, dw, dh, x, y, dx, dy);
if (__check_inside_coords(x, y, dxh, dyh, dxv, dyv, dw, dh, sw-1, sh-1)) {
__imlib_RotateAAInside(src, dest, sow, dow, dw, dh, x, y,
dxh, dyh, dxv, dyv);
return;
}
@ -250,15 +256,15 @@ __imlib_RotateAA(DATA32 *src, DATA32 *dest, int sow, int sw, int sh,
} else *dest = 0;
} else *dest = 0;
/*\ RIGHT; \*/
x += dx;
y += dy;
x += dxh;
y += dyh;
dest++;
} while (--i >= 0);
if (--dh <= 0) break;
/*\ DOWN/LEFT; \*/
x += -dy - dw * dx;
y += dx - dw * dy;
x += dxv - dw * dxh;
y += dyv - dw * dyh;
dest += (dow - dw);
}
@ -269,17 +275,18 @@ __imlib_RotateAA(DATA32 *src, DATA32 *dest, int sow, int sw, int sh,
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define MAX(a, b) ((a) > (b) ? (a) : (b))
void
__imlib_BlendImageToImageAtAngle(ImlibImage *im_src, ImlibImage *im_dst,
char aa, char blend, char merge_alpha,
int ssx, int ssy, int ssw, int ssh,
int ddx1, int ddy1, int ddx2, int ddy2,
ImlibColorModifier *cm, ImlibOp op)
__imlib_BlendImageToImageSkewed(ImlibImage *im_src, ImlibImage *im_dst,
char aa, char blend, char merge_alpha,
int ssx, int ssy, int ssw, int ssh,
int ddx, int ddy,
int hsx, int hsy, int vsx, int vsy,
ImlibColorModifier *cm, ImlibOp op)
{
int ddw, ddh, x, y, dx, dy, i;
int x, y, dxh, dyh, dxv, dyv, i;
double xy2;
DATA32 *data, *src;
int do_mmx;
if ((ssw < 0) || (ssh < 0))
return;
@ -292,31 +299,27 @@ __imlib_BlendImageToImageAtAngle(ImlibImage *im_src, ImlibImage *im_dst,
if (!im_dst->data)
return;
ddw = ddx2 - ddx1;
ddh = ddy2 - ddy1;
if ((ssw == ddw) & (ssh == ddh)) {
if (!IMAGE_HAS_ALPHA(im_src))
blend = 0;
if (!IMAGE_HAS_ALPHA(im_dst))
merge_alpha = 0;
__imlib_BlendRGBAToData(im_src->data, im_src->w, im_src->h,
im_dst->data, im_dst->w, im_dst->h,
ssx, ssy, ddx1, ddy1,
ssw, ssh, blend, merge_alpha, cm, op, 0);
return;
}
/*\ Complicated gonio. Works on paper..
|*| Too bad it doesn't all fit into integer math..
\*/
xy2 = (double)(ddh * ddh + ddw * ddw);
if (xy2 == 0) return;
dx = (((double)((ssh * ddh) + (ssw * ddw)) * _ROTATE_PREC_MAX) / xy2);
dy = (((double)((ssh * ddw) - (ssw * ddh)) * _ROTATE_PREC_MAX) / xy2);
x = ddy1 * dy - ddx1 * dx;
y = -ddx1 * dy - ddy1 * dx;
if (vsx | vsy) {
xy2 = (double)(hsx * vsy - vsx * hsy) / _ROTATE_PREC_MAX;
if (xy2 == 0.0) return;
dxh = (double)(ssw * vsy) / xy2;
dxv = (double)-(ssw * vsx) / xy2;
dyh = (double)-(ssh * hsy) / xy2;
dyv = (double)(ssh * hsx) / xy2;
} else {
xy2 = (double)(hsx * hsx + hsy * hsy) / _ROTATE_PREC_MAX;
if (xy2 == 0.0) return;
dxh = (double)(ssw * hsx) / xy2;
dyh = (double)-(ssw * hsy) / xy2;
dxv = -dyh;
dyv = dxh;
}
x = - (ddx * dxh + ddy * dxv);
y = - (ddx * dyh + ddy * dyv);
if (ssx < 0) {
x += ssx * _ROTATE_PREC_MAX;
ssw += ssx;
@ -349,8 +352,8 @@ __imlib_BlendImageToImageAtAngle(ImlibImage *im_src, ImlibImage *im_dst,
h = MIN(LINESIZE, im_dst->h - i);
x2 = x - h * dy;
y2 = y + h * dx;
x2 = x + h * dxv;
y2 = y + h * dyv;
w = ssw << _ROTATE_PREC;
h = ssh << _ROTATE_PREC;
@ -360,43 +363,43 @@ __imlib_BlendImageToImageAtAngle(ImlibImage *im_src, ImlibImage *im_dst,
h += 2 << _ROTATE_PREC;
}
/*\ Pretty similar code \*/
if (dx > 0) {
if (dy > 0) {
l = MAX(-y2 / dy, -x / dx);
r = MIN((h - y) / dy, (w - x2) / dx);
if (dxh > 0) {
if (dyh > 0) {
l = MAX(-MAX(y, y2) / dyh, -MAX(x, x2) / dxh);
r = MIN((h - MIN(y, y2)) / dyh, (w - MIN(x, x2)) / dxh);
} else if (dy < 0) {
l = MAX(-x2 / dx, (h - y) / dy);
r = MIN(-y2 / dy, (w - x) / dx);
} else if (dyh < 0) {
l = MAX(-MAX(x, x2) / dxh, (h - MIN(y, y2)) / dyh);
r = MIN(-MAX(y, y2) / dyh, (w - MIN(x, x2)) / dxh);
} else {
l = -x / dx;
r = (w - x) / dx;
l = -MAX(x, x2) / dxh;
r = (w - MIN(x, x2)) / dxh;
}
} else if (dx < 0) {
if (dy > 0) {
l = MAX(-y / dy, (w - x2) / dx);
r = MIN(-x / dx, (h - y2) / dy);
} else if (dxh < 0) {
if (dyh > 0) {
l = MAX(-MAX(y, y2) / dyh, (w - MIN(x, x2)) / dxh);
r = MIN(-MAX(x, x2) / dxh, (h - MIN(y, y2)) / dyh);
} else if (dy < 0) {
l = MAX((h - y2) / dy, (w - x) / dx);
r = MIN(-y / dy, -x2 / dx);
} else if (dyh < 0) {
l = MAX((h - MIN(y, y2)) / dyh, (w - MIN(x, x2)) / dxh);
r = MIN(-MAX(y, y2) / dyh, -MAX(x, x2) / dxh);
} else {
l = (w - x) / dx;
r = -x / dx;
l = (w - MIN(x, x2)) / dxh;
r = -MAX(x, x2) / dxh;
}
} else {
if (dy > 0) {
l = -y / dy;
r = (h - y) / dy;
if (dyh > 0) {
l = -MAX(y, y2) / dyh;
r = (h - MIN(y, y2)) / dyh;
} else if (dy < 0) {
l = (h - y) / dy;
r = -y / dy;
} else if (dyh < 0) {
l = (h - MIN(y, y2)) / dyh;
r = -MAX(y, y2) / dyh;
} else {
l = 0;
@ -416,22 +419,22 @@ __imlib_BlendImageToImageAtAngle(ImlibImage *im_src, ImlibImage *im_dst,
w = r - l;
h = MIN(LINESIZE, im_dst->h - i);
x += l * dx;
y += l * dy;
x += l * dxh;
y += l * dyh;
if (aa) {
x -= _ROTATE_PREC_MAX; y -= _ROTATE_PREC_MAX;
#ifdef DO_MMX_ASM
if (do_mmx)
__imlib_mmx_RotateAA(src, data, im_src->w, ssw, ssh, w, w, h,
x, y, dx, dy);
x, y, dxh, dyh, dxv, dyv);
else
#endif
__imlib_RotateAA(src, data, im_src->w, ssw, ssh, w, w, h,
x, y, dx, dy);
x, y, dxh, dyh, dxv, dyv);
} else {
__imlib_RotateSample(src, data, im_src->w, ssw, ssh, w, w, h,
x, y, dx, dy);
x, y, dxh, dyh, dxv, dyv);
}
__imlib_BlendRGBAToData(data, w, h, im_dst->data,

View File

@ -12,17 +12,21 @@
#define _ROTATE_PREC_BITS (_ROTATE_PREC_MAX - 1)
void __imlib_RotateSample(DATA32 *src, DATA32 *dest, int sow, int sw, int sh,
int dow, int dw, int dh, int x, int y, int dx, int dy);
int dow, int dw, int dh, int x, int y,
int dxh, int dyh, int dxv, int dyv);
void __imlib_RotateAA(DATA32 *src, DATA32 *dest, int sow, int sw, int sh,
int dow, int dw, int dh, int x, int y, int dx, int dy);
void __imlib_BlendImageToImageAtAngle(ImlibImage *im_src, ImlibImage *im_dst,
char aa, char blend, char merge_alpha,
int ssx, int ssy, int ssw, int ssh,
int ddx, int ddy, int ddw, int ddh,
ImlibColorModifier *cm, ImlibOp op);
int dow, int dw, int dh, int x, int y,
int dx, int dy, int dxv, int dyv);
void __imlib_BlendImageToImageSkewed(ImlibImage *im_src, ImlibImage *im_dst,
char aa, char blend, char merge_alpha,
int ssx, int ssy, int ssw, int ssh,
int ddx, int ddy,
int hsx, int hsy, int vsx, int vsy,
ImlibColorModifier *cm, ImlibOp op);
#ifdef DO_MMX_ASM
void __imlib_mmx_RotateAA(DATA32 *src, DATA32 *dest, int sow, int sw, int sh,
int dow, int dw, int dh, int x, int y, int dx, int dy);
int dow, int dw, int dh, int x, int y,
int dx, int dy, int dxv, int dyv);
#endif
#endif

View File

@ -738,6 +738,10 @@ int main (int argc, char **argv)
for (i = 0; i < 16; i++)
{
int al;
double an = (double)i / 10.0;
imlib_context_set_direction(IMLIB_TEXT_TO_ANGLE);
imlib_context_set_angle(an);
al = (15 - i) * 16;
if (al > 255)
@ -749,6 +753,7 @@ int main (int argc, char **argv)
up = imlib_update_append_rect(up, 50, ty, retw, reth);
ty += ny;
}
imlib_context_set_direction(IMLIB_TEXT_TO_RIGHT);
cp = imlib_text_get_index_and_location(str, x - 50, y - 50,
&cx, &cy, &cw, &ch);
if (cp >= 0)