forked from old/legacy-imlib2
write text at any angle............... :) patches form willem again :)
SVN revision: 2583
This commit is contained in:
parent
714e25d1d5
commit
2676818732
1
AUTHORS
1
AUTHORS
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
97
src/api.c
97
src/api.c
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
107
src/font.c
107
src/font.c
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
179
src/rotate.c
179
src/rotate.c
|
@ -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,
|
||||
|
|
20
src/rotate.h
20
src/rotate.h
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue