mirror of
https://github.com/gnustep/libs-back.git
synced 2025-04-22 07:21:02 +00:00
Add XIM Input Method, UPdate to wraster 0.80.2
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/back/trunk@17286 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
123b8ffd38
commit
eb1cd51d37
14 changed files with 1097 additions and 278 deletions
20
ChangeLog
20
ChangeLog
|
@ -1,3 +1,23 @@
|
|||
2003-07-21 Adam Fedor <fedor@gnu.org>
|
||||
|
||||
* Documentation/Back/DefaultsSummary.gsdoc: Add new
|
||||
GSXIMInputMethodStyle deafult (Adam Fedor).
|
||||
|
||||
* Source/x11/context.c, StdCmp.c, convert.c, raster.c, scale.c:
|
||||
Updated to 0.80.2 version
|
||||
|
||||
2003-07-13 Kazunobu Kuriyama <kazunobu.kuriyama@nifty.com>
|
||||
|
||||
* Header/x11/XGInputServer.h: Add the new category InputMethod.
|
||||
* Header/x11/XGServer.h: Add the new category InputMethod.
|
||||
* Source/x11/XIMInputServer.m:
|
||||
([XIMInputServer (XIMPrivate) -ximStyleInit]): Cover the input
|
||||
method styles RootWindow, OffTheSpot, OverTheSpot, and OnTheSpot.
|
||||
([XIMInputServer (XIMPrivate) -ximCreateIC:]): Implement OffTheSpot
|
||||
and OverTheSpot. Implement the category InputMethod.
|
||||
* Source/x11/XGServer.m: Implement the category InputMethod. Add
|
||||
overriding methods to NSTextView (NSView (InputMethod)).
|
||||
|
||||
2003-07-27 Richard Frith-Macdonald <rfm@gnu.org>
|
||||
|
||||
* Tools/gpbs.m: Use protocols
|
||||
|
|
|
@ -83,6 +83,14 @@
|
|||
problem with the X-Server.
|
||||
</p>
|
||||
</desc>
|
||||
<term>GSXIMInputMethodStyle</term>
|
||||
<desc>
|
||||
<p> A string value used to specify the XIM input method for
|
||||
entering characters. Valid values are
|
||||
<code>RootWindow</code>, <code>OffTheSpot</code>, or
|
||||
<code>OverTheSpot</code>.
|
||||
</p>
|
||||
</desc>
|
||||
<term>GraphicCompositing</term>
|
||||
<desc>
|
||||
<p> [Xlib backend only]
|
||||
|
@ -90,7 +98,7 @@
|
|||
<code>YES</code>, then the application uses various tricks
|
||||
to get alpha colors to work when compositing images. This
|
||||
may slow down drawing of images, but it is generally
|
||||
recommended anyway, particularly on fast systems
|
||||
recommended anyway, particularly on fast systems.
|
||||
</p>
|
||||
</desc>
|
||||
<term>Keyboard Modifiers</term>
|
||||
|
|
|
@ -59,6 +59,22 @@
|
|||
name: (NSString *)name;
|
||||
- (void) ximFocusICWindow: (gswindow_device_t *)windev;
|
||||
- (void) ximCloseIC: (XIC)xic;
|
||||
|
||||
@end
|
||||
|
||||
// Public interface for the input methods
|
||||
@interface XIMInputServer (InputMethod)
|
||||
- (NSString *) inputMethodStyle;
|
||||
- (NSString *) fontSize: (int *)size;
|
||||
- (BOOL) clientWindowRect: (NSRect *)rect;
|
||||
|
||||
- (BOOL) statusArea: (NSRect *)rect;
|
||||
- (BOOL) preeditArea: (NSRect *)rect;
|
||||
- (BOOL) preeditSpot: (NSPoint *)p;
|
||||
|
||||
- (BOOL) setStatusArea: (NSRect *)rect;
|
||||
- (BOOL) setPreeditArea: (NSRect *)rect;
|
||||
- (BOOL) setPreeditSpot: (NSPoint *)p;
|
||||
@end // XIMInputServer (InputMethod)
|
||||
|
||||
#endif
|
||||
|
|
|
@ -81,4 +81,19 @@ typedef enum {
|
|||
- (NSRect) _XFrameToOSFrame: (NSRect)x for: (void*)window;
|
||||
@end
|
||||
|
||||
// Public interface for the input methods.
|
||||
@interface XGServer (InputMethod)
|
||||
- (NSString *) inputMethodStyle;
|
||||
- (NSString *) fontSize: (int *)size;
|
||||
- (BOOL) clientWindowRect: (NSRect *)rect;
|
||||
|
||||
- (BOOL) statusArea: (NSRect *)rect;
|
||||
- (BOOL) preeditArea: (NSRect *)rect;
|
||||
- (BOOL) preeditSpot: (NSPoint *)p;
|
||||
|
||||
- (BOOL) setStatusArea: (NSRect *)rect;
|
||||
- (BOOL) setPreeditArea: (NSRect *)rect;
|
||||
- (BOOL) setPreeditSpot: (NSPoint *)p;
|
||||
@end
|
||||
|
||||
#endif /* _XGServer_h_INCLUDE */
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Raster graphics library
|
||||
*
|
||||
* Copyright (c) 1997 ~ 2000 Alfredo K. Kojima
|
||||
* Copyright (c) 1997-2002 Alfredo K. Kojima
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
|
@ -39,8 +39,8 @@
|
|||
#define RLRASTER_H_
|
||||
|
||||
|
||||
/* version of the header for the library: 0.20 */
|
||||
#define WRASTER_HEADER_VERSION 20
|
||||
/* version of the header for the library: 0.21 */
|
||||
#define WRASTER_HEADER_VERSION 21
|
||||
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
|
@ -148,6 +148,8 @@ typedef struct RContext {
|
|||
unsigned int use_shared_pixmap:1;
|
||||
unsigned int optimize_for_speed:1;
|
||||
} flags;
|
||||
|
||||
struct RHermesData *hermes_data; /* handle for Hermes stuff */
|
||||
} RContext;
|
||||
|
||||
|
||||
|
@ -189,10 +191,11 @@ enum RImageFormat {
|
|||
* internal 24bit+alpha image representation
|
||||
*/
|
||||
typedef struct RImage {
|
||||
unsigned char *data; /* image data RGBA or RGB */
|
||||
unsigned width, height; /* size of the image */
|
||||
unsigned char *data; /* image data RGBA or RGB */
|
||||
int width, height; /* size of the image */
|
||||
enum RImageFormat format;
|
||||
RColor background; /* background color */
|
||||
RColor background; /* background color */
|
||||
int refCount;
|
||||
} RImage;
|
||||
|
||||
|
||||
|
@ -320,7 +323,18 @@ RImage *RCreateImageFromDrawable(RContext *context, Drawable drawable,
|
|||
|
||||
RImage *RLoadImage(RContext *context, char *file, int index);
|
||||
|
||||
RImage* RRetainImage(RImage *image);
|
||||
|
||||
void RReleaseImage(RImage *image);
|
||||
|
||||
/* Obsoleted function. Use RReleaseImage() instead. This was kept only to
|
||||
* allow a smoother transition and to avoid breaking existing programs, but
|
||||
* it will be removed in a future release. Right now is just an alias to
|
||||
* RReleaseImage(). Do _NOT_ use RDestroyImage() anymore in your programs.
|
||||
* Being an alias to RReleaseImage() this function no longer actually
|
||||
* destroys the image, unless the image is no longer retained in some other
|
||||
* place.
|
||||
*/
|
||||
void RDestroyImage(RImage *image);
|
||||
|
||||
RImage *RGetImageFromXPMData(RContext *context, char **xpmData);
|
||||
|
@ -418,6 +432,10 @@ RImage *RRenderMultiGradient(unsigned width, unsigned height, RColor **colors,
|
|||
int style);
|
||||
|
||||
|
||||
RImage *RRenderInterwovenGradient(unsigned width, unsigned height,
|
||||
RColor colors1[2], int thickness1,
|
||||
RColor colors2[2], int thickness2);
|
||||
|
||||
|
||||
/*
|
||||
* Convertion into X Pixmaps
|
||||
|
|
|
@ -35,7 +35,7 @@ in this Software without prior written authorization from the X Consortium.
|
|||
#include <X11/Xlib.h>
|
||||
#include <X11/Xatom.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/Xmu/StdCmap.h>
|
||||
#include "x11/StdCmap.h"
|
||||
|
||||
#define lowbit(x) ((x) & (~(x) + 1))
|
||||
|
||||
|
|
|
@ -575,3 +575,187 @@ _parse_display_name(NSString *name, int *dn, int *sn)
|
|||
|
||||
|
||||
@end
|
||||
|
||||
@implementation XGServer (InputMethod)
|
||||
- (NSString *) inputMethodStyle
|
||||
{
|
||||
return inputServer ? [(XIMInputServer *)inputServer inputMethodStyle] : nil;
|
||||
}
|
||||
|
||||
- (NSString *) fontSize: (int *)size
|
||||
{
|
||||
return inputServer ? [(XIMInputServer *)inputServer fontSize: size] : nil;
|
||||
}
|
||||
|
||||
- (BOOL) clientWindowRect: (NSRect *)rect
|
||||
{
|
||||
return inputServer
|
||||
? [(XIMInputServer *)inputServer clientWindowRect: rect] : NO;
|
||||
}
|
||||
|
||||
- (BOOL) statusArea: (NSRect *)rect
|
||||
{
|
||||
return inputServer ? [(XIMInputServer *)inputServer statusArea: rect] : NO;
|
||||
}
|
||||
|
||||
- (BOOL) preeditArea: (NSRect *)rect
|
||||
{
|
||||
return inputServer ? [(XIMInputServer *)inputServer preeditArea: rect] : NO;
|
||||
}
|
||||
|
||||
- (BOOL) preeditSpot: (NSPoint *)p
|
||||
{
|
||||
return inputServer ? [(XIMInputServer *)inputServer preeditSpot: p] : NO;
|
||||
}
|
||||
|
||||
- (BOOL) setStatusArea: (NSRect *)rect
|
||||
{
|
||||
return inputServer
|
||||
? [(XIMInputServer *)inputServer setStatusArea: rect] : NO;
|
||||
}
|
||||
|
||||
- (BOOL) setPreeditArea: (NSRect *)rect
|
||||
{
|
||||
return inputServer
|
||||
? [(XIMInputServer *)inputServer setPreeditArea: rect] : NO;
|
||||
}
|
||||
|
||||
- (BOOL) setPreeditSpot: (NSPoint *)p
|
||||
{
|
||||
return inputServer
|
||||
? [(XIMInputServer *)inputServer setPreeditSpot: p] : NO;
|
||||
}
|
||||
|
||||
@end // XGServer (InputMethod)
|
||||
|
||||
|
||||
//==== Additional code for NSTextView =========================================
|
||||
//
|
||||
// WARNING This section is not genuine part of the XGServer implementation.
|
||||
// -------
|
||||
//
|
||||
// The methods implemented in this section override some of the internal
|
||||
// methods defined in NSTextView so that the class can support input methods
|
||||
// (XIM) in cooperation with XGServer.
|
||||
//
|
||||
// Note that the orverriding is done by defining the methods in a category,
|
||||
// the name of which is not explicitly mentioned in NSTextView.h; the
|
||||
// category is called 'InputMethod'.
|
||||
//
|
||||
|
||||
#include <AppKit/NSClipView.h>
|
||||
#include <AppKit/NSTextView.h>
|
||||
|
||||
@implementation NSTextView (InputMethod)
|
||||
|
||||
- (void) _updateInputMethodState
|
||||
{
|
||||
NSRect frame;
|
||||
int font_size;
|
||||
NSRect status_area;
|
||||
NSRect preedit_area;
|
||||
id displayServer = (XGServer *)GSCurrentServer();
|
||||
|
||||
if (![displayServer respondsToSelector: @selector(inputMethodStyle)])
|
||||
return;
|
||||
|
||||
if (![displayServer fontSize: &font_size])
|
||||
return;
|
||||
|
||||
if ([[self superview] isKindOfClass: [NSClipView class]])
|
||||
frame = [[self superview] frame];
|
||||
else
|
||||
frame = [self frame];
|
||||
|
||||
status_area.size.width = 2 * font_size;
|
||||
status_area.size.height = font_size + 2;
|
||||
status_area.origin.x = 0;
|
||||
status_area.origin.y = frame.size.height - status_area.size.height;
|
||||
|
||||
if ([[displayServer inputMethodStyle] isEqual: @"OverTheSpot"])
|
||||
{
|
||||
preedit_area.origin.x = 0;
|
||||
preedit_area.origin.y = 0;
|
||||
preedit_area.size.width = frame.size.width;
|
||||
preedit_area.size.height = status_area.size.height;
|
||||
|
||||
[displayServer setStatusArea: &status_area];
|
||||
[displayServer setPreeditArea: &preedit_area];
|
||||
}
|
||||
else if ([[displayServer inputMethodStyle] isEqual: @"OffTheSpot"])
|
||||
{
|
||||
preedit_area.origin.x = status_area.size.width + 2;
|
||||
preedit_area.origin.y = status_area.origin.y;
|
||||
preedit_area.size.width = frame.origin.x + frame.size.width
|
||||
- preedit_area.origin.x;
|
||||
preedit_area.size.height = status_area.size.height;
|
||||
|
||||
[displayServer setStatusArea: &status_area];
|
||||
[displayServer setPreeditArea: &preedit_area];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Do nothing for the RootWindow style.
|
||||
}
|
||||
}
|
||||
|
||||
- (void) _updateInputMethodWithInsertionPoint: (NSPoint)insertionPoint
|
||||
{
|
||||
id displayServer = (XGServer *)GSCurrentServer();
|
||||
|
||||
if (![displayServer respondsToSelector: @selector(inputMethodStyle)])
|
||||
return;
|
||||
|
||||
if ([[displayServer inputMethodStyle] isEqual: @"OverTheSpot"])
|
||||
{
|
||||
id view;
|
||||
NSRect frame;
|
||||
NSPoint p;
|
||||
NSRect client_win_rect;
|
||||
NSPoint screenXY_of_frame;
|
||||
double x_offset;
|
||||
double y_offset;
|
||||
int font_size;
|
||||
NSRect doc_rect;
|
||||
NSRect doc_visible_rect;
|
||||
BOOL cond;
|
||||
float x = insertionPoint.x;
|
||||
float y = insertionPoint.y;
|
||||
|
||||
[displayServer clientWindowRect: &client_win_rect];
|
||||
[displayServer fontSize: &font_size];
|
||||
|
||||
cond = [[self superview] isKindOfClass: [NSClipView class]];
|
||||
if (cond)
|
||||
view = [self superview];
|
||||
else
|
||||
view = self;
|
||||
|
||||
frame = [view frame];
|
||||
screenXY_of_frame = [[view window] convertBaseToScreen: frame.origin];
|
||||
|
||||
// N.B. The window of NSTextView isn't necessarily the same as the input
|
||||
// method's client window.
|
||||
x_offset = screenXY_of_frame.x - client_win_rect.origin.x;
|
||||
y_offset = (client_win_rect.origin.y + client_win_rect.size.height)
|
||||
- (screenXY_of_frame.y + frame.size.height) + font_size;
|
||||
|
||||
x += x_offset;
|
||||
y += y_offset;
|
||||
if (cond) // If 'view' is of NSClipView, then
|
||||
{
|
||||
// N.B. Remember, (x, y) are the values with respect to NSTextView.
|
||||
// We need to know the corresponding insertion position with respect
|
||||
// to NSClipView.
|
||||
doc_rect = [(NSClipView *)view documentRect];
|
||||
doc_visible_rect = [view documentVisibleRect];
|
||||
y -= doc_visible_rect.origin.y - doc_rect.origin.y;
|
||||
}
|
||||
|
||||
p = NSMakePoint(x, y);
|
||||
[displayServer setPreeditSpot: &p];
|
||||
}
|
||||
}
|
||||
|
||||
@end // NSTextView
|
||||
//==== End: Additional Code for NSTextView ====================================
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
|
||||
#include "config.h"
|
||||
|
||||
#include <Foundation/NSUserDefaults.h>
|
||||
#include <Foundation/NSData.h>
|
||||
#include <Foundation/NSDebug.h>
|
||||
#include <Foundation/NSException.h>
|
||||
|
@ -37,6 +38,11 @@
|
|||
#include "x11/XGInputServer.h"
|
||||
#include <X11/Xlocale.h>
|
||||
|
||||
#define RootWindowStyle (XIMPreeditNothing | XIMStatusNothing)
|
||||
#define OffTheSpotStyle (XIMPreeditArea | XIMStatusArea)
|
||||
#define OverTheSpotStyle (XIMPreeditPosition | XIMStatusArea)
|
||||
#define OnTheSpotStyle (XIMPreeditCallbacks| XIMStatusCallbacks)
|
||||
|
||||
|
||||
@interface XIMInputServer (XIMPrivate)
|
||||
- (BOOL) ximInit: (Display *)dpy;
|
||||
|
@ -240,31 +246,59 @@
|
|||
|
||||
- (int) ximStyleInit
|
||||
{
|
||||
/* FIXME: Right now we only support this style *but*
|
||||
this is only temporary */
|
||||
XIMStyle xim_supported_style=XIMPreeditNothing|XIMStatusNothing;
|
||||
XIMStyles *styles;
|
||||
char *failed_arg;
|
||||
int i;
|
||||
NSUserDefaults *uds;
|
||||
NSString *request;
|
||||
XIMStyle xim_requested_style;
|
||||
XIMStyles *styles;
|
||||
char *failed_arg;
|
||||
int i;
|
||||
|
||||
uds = [NSUserDefaults standardUserDefaults];
|
||||
if ((request = [uds stringForKey: @"GSXIMInputMethodStyle"]) == nil)
|
||||
{
|
||||
xim_requested_style = RootWindowStyle;
|
||||
}
|
||||
else if ([request isEqual: @"RootWindow"])
|
||||
{
|
||||
xim_requested_style = RootWindowStyle;
|
||||
}
|
||||
else if ([request isEqual: @"OffTheSpot"])
|
||||
{
|
||||
xim_requested_style = OffTheSpotStyle;
|
||||
}
|
||||
else if ([request isEqual: @"OverTheSpot"])
|
||||
{
|
||||
xim_requested_style = OverTheSpotStyle;
|
||||
}
|
||||
else if ([request isEqual: @"OnTheSpot"])
|
||||
{
|
||||
xim_requested_style = OnTheSpotStyle;
|
||||
}
|
||||
else
|
||||
{
|
||||
NSLog(@"XIM: Unknown style '%s'.\n"
|
||||
@"Fallback to RootWindow style.", [request cString]);
|
||||
xim_requested_style = RootWindowStyle;
|
||||
}
|
||||
|
||||
failed_arg = XGetIMValues(xim,XNQueryInputStyle,&styles,NULL);
|
||||
if (failed_arg!=NULL)
|
||||
failed_arg = XGetIMValues(xim, XNQueryInputStyle, &styles, NULL);
|
||||
if (failed_arg != NULL)
|
||||
{
|
||||
NSDebugLLog(@"XIM", @"Can't getting the following IM value :%s",
|
||||
failed_arg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i=0;i<styles->count_styles;i++)
|
||||
for (i = 0; i < styles->count_styles; i++)
|
||||
{
|
||||
if (styles->supported_styles[i]==xim_supported_style)
|
||||
if (styles->supported_styles[i] == xim_requested_style)
|
||||
{
|
||||
xim_style=xim_supported_style;
|
||||
xim_style = xim_requested_style;
|
||||
XFree(styles);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
NSLog(@"XIM: '%s' is not supported", request);
|
||||
XFree(styles);
|
||||
return 0;
|
||||
}
|
||||
|
@ -315,10 +349,111 @@
|
|||
|
||||
- (XIC) ximCreateIC: (Window)w
|
||||
{
|
||||
XIC xic;
|
||||
xic = XCreateIC(xim, XNClientWindow, w, XNInputStyle,
|
||||
xim_style, NULL);
|
||||
if (xic==NULL)
|
||||
XIC xic = NULL;
|
||||
|
||||
if (xim_style == RootWindowStyle)
|
||||
{
|
||||
xic = XCreateIC(xim,
|
||||
XNInputStyle, xim_style,
|
||||
XNClientWindow, w,
|
||||
NULL);
|
||||
}
|
||||
else if (xim_style == OffTheSpotStyle || xim_style == OverTheSpotStyle)
|
||||
{
|
||||
Display *dpy = [XGServer currentXDisplay];
|
||||
XFontSet font_set;
|
||||
char **missing_charset;
|
||||
int num_missing_charset;
|
||||
int dummy = 0;
|
||||
XVaNestedList preedit_args = NULL;
|
||||
XVaNestedList status_args = NULL;
|
||||
XRectangle status_area;
|
||||
XRectangle preedit_area;
|
||||
XPoint preedit_spot;
|
||||
NSString *ns_font_size;
|
||||
int font_size;
|
||||
char base_font_name[64];
|
||||
|
||||
//
|
||||
// Create a FontSet
|
||||
//
|
||||
|
||||
// N.B. Because some input methods fail to provide a default font set,
|
||||
// we have to do it by ourselves.
|
||||
ns_font_size = [self fontSize: &font_size];
|
||||
sprintf(base_font_name, "*medium-r-normal--%s*", [ns_font_size cString]);
|
||||
font_set = XCreateFontSet(dpy,
|
||||
base_font_name,
|
||||
&missing_charset,
|
||||
&num_missing_charset,
|
||||
NULL);
|
||||
if (!font_set)
|
||||
{
|
||||
goto finish;
|
||||
}
|
||||
if (missing_charset)
|
||||
{
|
||||
int i;
|
||||
NSLog(@"XIM: missing charset: ");
|
||||
for (i = 0; i < num_missing_charset; ++i)
|
||||
NSLog(@"%s", missing_charset[i]);
|
||||
XFreeStringList(missing_charset);
|
||||
}
|
||||
|
||||
//
|
||||
// Create XIC.
|
||||
//
|
||||
// At least, XNFontSet and XNPreeditSpotLocation must be specified
|
||||
// at initialization time.
|
||||
//
|
||||
status_area.width = font_size * 2;
|
||||
status_area.height = font_size + 2;
|
||||
status_area.x = 0;
|
||||
status_area.y = 0;
|
||||
|
||||
status_args = XVaCreateNestedList(dummy,
|
||||
XNArea, &status_area,
|
||||
XNFontSet, font_set,
|
||||
NULL);
|
||||
|
||||
preedit_area.width = 120;
|
||||
preedit_area.height = status_area.height;
|
||||
preedit_area.x = 0;
|
||||
preedit_area.y = 0;
|
||||
|
||||
preedit_spot.x = 0;
|
||||
preedit_spot.y = 0;
|
||||
|
||||
preedit_args = XVaCreateNestedList(dummy,
|
||||
XNArea, &preedit_area,
|
||||
XNSpotLocation, &preedit_spot,
|
||||
XNFontSet, font_set,
|
||||
NULL);
|
||||
|
||||
xic = XCreateIC(xim,
|
||||
XNInputStyle, xim_style,
|
||||
XNClientWindow, w,
|
||||
XNPreeditAttributes, preedit_args,
|
||||
XNStatusAttributes, status_args,
|
||||
NULL);
|
||||
|
||||
if (preedit_args) { XFree(preedit_args); preedit_args = NULL; }
|
||||
if (status_args) { XFree(status_args); status_args = NULL; }
|
||||
if (font_set) XFreeFontSet(dpy, font_set);
|
||||
}
|
||||
else if (xim_style == OnTheSpotStyle)
|
||||
{
|
||||
NSLog(@"XIM: GNUstep doesn't support 'OnTheSpot'.\n"
|
||||
@"Fallback to RootWindow style.");
|
||||
xim_style = RootWindowStyle;
|
||||
xic = XCreateIC(xim,
|
||||
XNInputStyle, xim_style,
|
||||
XNClientWindow, w,
|
||||
NULL);
|
||||
}
|
||||
|
||||
finish:
|
||||
if (xic == NULL)
|
||||
NSDebugLLog(@"XIM", @"Can't create the input context.\n");
|
||||
|
||||
xics = realloc(xics, sizeof(XIC) * (num_xics + 1));
|
||||
|
@ -356,3 +491,218 @@
|
|||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation XIMInputServer (InputMethod)
|
||||
- (NSString *) inputMethodStyle
|
||||
{
|
||||
if (num_xics > 0)
|
||||
{
|
||||
if (xim_style == RootWindowStyle)
|
||||
return @"RootWindow";
|
||||
else if (xim_style == OffTheSpotStyle)
|
||||
return @"OffTheSpot";
|
||||
else if (xim_style == OverTheSpotStyle)
|
||||
return @"OverTheSpot";
|
||||
else if (xim_style == OnTheSpotStyle)
|
||||
return @"OnTheSpot";
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (NSString *) fontSize: (int *)size
|
||||
{
|
||||
NSString *str;
|
||||
|
||||
str = [[NSUserDefaults standardUserDefaults] stringForKey: @"NSFontSize"];
|
||||
if (!str)
|
||||
str = @"12";
|
||||
*size = (int)strtol([str cString], NULL, 10);
|
||||
return str;
|
||||
}
|
||||
|
||||
- (BOOL) clientWindowRect: (NSRect *)rect
|
||||
{
|
||||
Window win;
|
||||
Window dummy;
|
||||
Display *dpy;
|
||||
int abs_x, abs_y;
|
||||
int x, y;
|
||||
unsigned int w, h;
|
||||
unsigned int bw, d;
|
||||
|
||||
if (num_xics <= 0 || !rect) return NO;
|
||||
|
||||
*rect = NSMakeRect(0, 0, 0, 0);
|
||||
|
||||
if (XGetICValues(xics[num_xics - 1], XNClientWindow, &win, NULL))
|
||||
return NO;
|
||||
dpy = [XGServer currentXDisplay];
|
||||
if (XTranslateCoordinates(dpy, win, DefaultRootWindow(dpy), 0, 0,
|
||||
&abs_x, &abs_y, &dummy) == 0)
|
||||
return NO;
|
||||
XGetGeometry(dpy, win, &dummy, &x, &y, &w, &h, &bw, &d);
|
||||
|
||||
// X Window Coordinates to GNUstep Coordinates
|
||||
x = abs_x;
|
||||
y = XDisplayHeight(dpy, 0) - (abs_y + h);
|
||||
|
||||
*rect = NSMakeRect((float)x, (float)y, (float)w, (float)h);
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL) statusArea: (NSRect *)rect
|
||||
{
|
||||
if (num_xics > 0 && (xim_style & XIMStatusArea))
|
||||
{
|
||||
XRectangle area;
|
||||
int dummy = 0;
|
||||
XVaNestedList arglist = NULL;
|
||||
|
||||
if (!(arglist = XVaCreateNestedList(dummy, XNArea, &area, NULL)))
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
XGetICValues(xics[num_xics - 1], XNStatusAttributes, arglist, NULL);
|
||||
|
||||
rect->origin.x = area.x;
|
||||
rect->origin.y = area.y;
|
||||
rect->size.width = area.width;
|
||||
rect->size.height = area.height;
|
||||
|
||||
if (arglist) { XFree(arglist); arglist = NULL; }
|
||||
|
||||
return YES;
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL) preeditArea: (NSRect *)rect
|
||||
{
|
||||
if (num_xics > 0
|
||||
&& ((xim_style & XIMPreeditArea) || (xim_style & XIMPreeditPosition)))
|
||||
{
|
||||
XRectangle area;
|
||||
int dummy = 0;
|
||||
XVaNestedList arglist = NULL;
|
||||
|
||||
if (!(arglist = XVaCreateNestedList(dummy, XNArea, &area, NULL)))
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
XGetICValues(xics[num_xics - 1], XNPreeditAttributes, arglist, NULL);
|
||||
|
||||
rect->origin.x = area.x;
|
||||
rect->origin.y = area.y;
|
||||
rect->size.width = area.width;
|
||||
rect->size.height = area.height;
|
||||
|
||||
if (arglist) { XFree(arglist); arglist = NULL; }
|
||||
|
||||
return YES;
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL) preeditSpot: (NSPoint *)p
|
||||
{
|
||||
if (num_xics > 0 && (xim_style & XIMPreeditPosition))
|
||||
{
|
||||
XPoint spot;
|
||||
int dummy = 0;
|
||||
XVaNestedList arglist = NULL;
|
||||
|
||||
if (!(arglist = XVaCreateNestedList(dummy, XNSpotLocation, &spot, NULL)))
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
XGetICValues(xics[num_xics - 1], XNPreeditAttributes, arglist, NULL);
|
||||
|
||||
p->x = spot.x;
|
||||
p->y = spot.y;
|
||||
|
||||
if (arglist) { XFree(arglist); arglist = NULL; }
|
||||
|
||||
return YES;
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL) setStatusArea: (NSRect *)rect
|
||||
{
|
||||
if (num_xics > 0 && (xim_style & XIMStatusArea))
|
||||
{
|
||||
XRectangle area;
|
||||
int dummy = 0;
|
||||
XVaNestedList arglist = NULL;
|
||||
|
||||
area.x = rect->origin.x;
|
||||
area.y = rect->origin.y;
|
||||
area.width = rect->size.width;
|
||||
area.height = rect->size.height;
|
||||
|
||||
if (!(arglist = XVaCreateNestedList(dummy, XNArea, &area, NULL)))
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
XSetICValues(xics[num_xics - 1], XNStatusAttributes, arglist, NULL);
|
||||
|
||||
if (arglist) { XFree(arglist); arglist = NULL; }
|
||||
|
||||
return YES;
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL) setPreeditArea: (NSRect *)rect
|
||||
{
|
||||
if (num_xics > 0
|
||||
&& ((xim_style & XIMPreeditArea) || (xim_style & XIMPreeditPosition)))
|
||||
{
|
||||
XRectangle area;
|
||||
int dummy = 0;
|
||||
XVaNestedList arglist = NULL;
|
||||
|
||||
area.x = rect->origin.x;
|
||||
area.y = rect->origin.y;
|
||||
area.width = rect->size.width;
|
||||
area.height = rect->size.height;
|
||||
|
||||
if (!(arglist = XVaCreateNestedList(dummy, XNArea, &area, NULL)))
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
XSetICValues(xics[num_xics - 1], XNPreeditAttributes, arglist, NULL);
|
||||
|
||||
if (arglist) { XFree(arglist); arglist = NULL; }
|
||||
|
||||
return YES;
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL) setPreeditSpot: (NSPoint *)p
|
||||
{
|
||||
if (num_xics > 0 && (xim_style & XIMPreeditPosition))
|
||||
{
|
||||
XPoint spot;
|
||||
int dummy = 0;
|
||||
XVaNestedList arglist = NULL;
|
||||
|
||||
spot.x = p->x;
|
||||
spot.y = p->y;
|
||||
|
||||
if (!(arglist = XVaCreateNestedList(dummy, XNSpotLocation, &spot, NULL)))
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
XSetICValues(xics[num_xics - 1], XNPreeditAttributes, arglist, NULL);
|
||||
|
||||
if (arglist) { XFree(arglist); arglist = NULL; }
|
||||
|
||||
return YES;
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
@end // XIMInputServer (InputMethod)
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
*
|
||||
* Raster graphics library
|
||||
*
|
||||
* Copyright (c) 1997, 1998, 1999 Alfredo K. Kojima
|
||||
* Copyright (c) 1997-2002 Alfredo K. Kojima
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
|
@ -32,9 +32,17 @@
|
|||
|
||||
#include <math.h>
|
||||
|
||||
#include "x11/wraster.h"
|
||||
#include "wrasterP.h"
|
||||
|
||||
#ifdef HAVE_HERMES
|
||||
#include <Hermes/Hermes.h>
|
||||
#endif
|
||||
|
||||
#include "x11/StdCmap.h"
|
||||
|
||||
#include "x11/wraster.h"
|
||||
|
||||
|
||||
extern void _wraster_change_filter(int type);
|
||||
|
||||
|
||||
|
@ -53,7 +61,13 @@ static RContextAttributes DEFAULT_CONTEXT_ATTRIBS = {
|
|||
RUseStdColormap
|
||||
};
|
||||
|
||||
|
||||
char**
|
||||
RSupportedFileFormats(void)
|
||||
{
|
||||
static char *tmp[2];
|
||||
tmp[0] = NULL;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
|
@ -558,7 +572,6 @@ getColormap(RContext *context, int screen_number)
|
|||
&cmaps, &ncmaps, XA_RGB_DEFAULT_MAP)) {
|
||||
for (i=0; i<ncmaps; ++i) {
|
||||
if (cmaps[i].visualid == context->visual->visualid) {
|
||||
puts("ACHOU");
|
||||
cmap = cmaps[i].colormap;
|
||||
break;
|
||||
}
|
||||
|
@ -632,6 +645,11 @@ RCreateContext(Display *dpy, int screen_number, RContextAttributes *attribs)
|
|||
context->attribs->standard_colormap_mode = RUseStdColormap;
|
||||
}
|
||||
|
||||
if (!(context->attribs->flags & RC_ScalingFilter)) {
|
||||
context->attribs->flags |= RC_ScalingFilter;
|
||||
context->attribs->scaling_filter = RMitchellFilter;
|
||||
}
|
||||
|
||||
/* get configuration from environment variables */
|
||||
gatherconfig(context, screen_number);
|
||||
#ifndef BENCH
|
||||
|
@ -694,17 +712,66 @@ RCreateContext(Display *dpy, int screen_number, RContextAttributes *attribs)
|
|||
context->copy_gc = XCreateGC(dpy, context->drawable, GCFunction
|
||||
|GCGraphicsExposures, &gcv);
|
||||
|
||||
if (context->vclass == PseudoColor || context->vclass == StaticColor) {
|
||||
#ifdef HAVE_HERMES
|
||||
context->hermes_data = malloc(sizeof(RHermesData));
|
||||
if (!context->hermes_data) {
|
||||
RErrorCode = RERR_NOMEMORY;
|
||||
free(context);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Hermes_Init();
|
||||
|
||||
context->hermes_data->palette = Hermes_PaletteInstance();
|
||||
{
|
||||
unsigned long flags = 0;
|
||||
|
||||
if (context->attribs->render_mode == RDitheredRendering) {
|
||||
flags |= HERMES_CONVERT_DITHER;
|
||||
}
|
||||
context->hermes_data->converter = Hermes_ConverterInstance(flags);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (context->vclass == PseudoColor || context->vclass == StaticColor) {
|
||||
if (!setupPseudoColorColormap(context)) {
|
||||
free(context);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef HAVE_HERMES
|
||||
{
|
||||
int32 palette[256];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < context->ncolors; i++) {
|
||||
palette[i] = ((context->colors[i].red >> 8) << 16) ||
|
||||
((context->colors[i].green >> 8) << 8) ||
|
||||
((context->colors[i].blue >> 8));
|
||||
}
|
||||
|
||||
Hermes_PaletteSet(context->hermes_data->palette, palette);
|
||||
}
|
||||
#endif
|
||||
} else if (context->vclass == GrayScale || context->vclass == StaticGray) {
|
||||
context->colors = allocateGrayScale(context);
|
||||
if (!context->colors) {
|
||||
free(context);
|
||||
return NULL;
|
||||
}
|
||||
#ifdef HAVE_HERMES
|
||||
{
|
||||
int32 palette[256];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < context->ncolors; i++) {
|
||||
palette[i] = ((context->colors[i].red >> 8) << 16) ||
|
||||
((context->colors[i].green >> 8) << 8) ||
|
||||
((context->colors[i].blue >> 8));
|
||||
}
|
||||
|
||||
Hermes_PaletteSet(context->hermes_data->palette, palette);
|
||||
}
|
||||
#endif
|
||||
} else if (context->vclass == TrueColor) {
|
||||
/* calc offsets to create a TrueColor pixel */
|
||||
context->red_offset = count_offset(context->visual->red_mask);
|
||||
|
@ -714,6 +781,10 @@ RCreateContext(Display *dpy, int screen_number, RContextAttributes *attribs)
|
|||
if (context->depth >= 24)
|
||||
context->attribs->render_mode = RBestMatchRendering;
|
||||
}
|
||||
|
||||
#ifdef HAVE_HERMES
|
||||
|
||||
#endif
|
||||
|
||||
/* check avaiability of MIT-SHM */
|
||||
#ifdef XSHM
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
*
|
||||
* Raster graphics library
|
||||
*
|
||||
* Copyright (c) 1997-2000 Alfredo K. Kojima
|
||||
* Copyright (c) 1997-2002 Alfredo K. Kojima
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
|
@ -18,6 +18,12 @@
|
|||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/* Problems:
|
||||
* 1. Using Grayscale visual with Dithering crashes wmaker
|
||||
* 2. Ghost dock/appicon is wrong in Pseudocolor, Staticgray, Grayscale
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
|
||||
|
@ -29,11 +35,12 @@
|
|||
|
||||
#include <assert.h>
|
||||
|
||||
|
||||
#ifdef BENCH
|
||||
#include "bench.h"
|
||||
#endif
|
||||
|
||||
#include "x11/wraster.h"
|
||||
#include "wrasterP.h"
|
||||
|
||||
#ifdef XSHM
|
||||
extern Pixmap R_CreateXImageMappedPixmap(RContext *context, RXImage *ximage);
|
||||
|
@ -41,39 +48,7 @@ extern Pixmap R_CreateXImageMappedPixmap(RContext *context, RXImage *ximage);
|
|||
#endif
|
||||
|
||||
|
||||
#ifdef ASM_X86
|
||||
extern void x86_PseudoColor_32_to_8(unsigned char *image,
|
||||
unsigned char *ximage,
|
||||
char *err, char *nerr,
|
||||
short *ctable,
|
||||
int dr, int dg, int db,
|
||||
unsigned long *pixels,
|
||||
int cpc,
|
||||
int width, int height,
|
||||
int bytesPerPixel,
|
||||
int line_offset);
|
||||
#endif /* ASM_X86 */
|
||||
|
||||
#ifdef ASM_X86_MMX
|
||||
|
||||
extern int x86_check_mmx();
|
||||
|
||||
extern void x86_mmx_TrueColor_32_to_16(unsigned char *image,
|
||||
unsigned short *ximage,
|
||||
short *err, short *nerr,
|
||||
short *rtable, short *gtable,
|
||||
short *btable,
|
||||
int dr, int dg, int db,
|
||||
unsigned int roffs,
|
||||
unsigned int goffs,
|
||||
unsigned int boffs,
|
||||
int width, int height,
|
||||
int line_offset);
|
||||
|
||||
|
||||
|
||||
#endif /* ASM_X86_MMX */
|
||||
|
||||
#define HAS_ALPHA(I) ((I)->format == RRGBAFormat)
|
||||
|
||||
|
||||
typedef struct RConversionTable {
|
||||
|
@ -164,7 +139,7 @@ computeStdTable(unsigned int mult, unsigned int max)
|
|||
|
||||
static void
|
||||
convertTrueColor_generic(RXImage *ximg, RImage *image,
|
||||
char *err, char *nerr,
|
||||
signed char *err, signed char *nerr,
|
||||
const short *rtable,
|
||||
const short *gtable,
|
||||
const short *btable,
|
||||
|
@ -173,13 +148,13 @@ convertTrueColor_generic(RXImage *ximg, RImage *image,
|
|||
const unsigned short goffs,
|
||||
const unsigned short boffs)
|
||||
{
|
||||
char *terr;
|
||||
signed char *terr;
|
||||
int x, y, r, g, b;
|
||||
int pixel;
|
||||
int rer, ger, ber;
|
||||
unsigned char *ptr = image->data;
|
||||
int channels = image->format == RRGBAFormat ? 4 : 3;
|
||||
|
||||
int channels = (image->format == RRGBAFormat ? 4 : 3);
|
||||
|
||||
/* convert and dither the image to XImage */
|
||||
for (y=0; y<image->height; y++) {
|
||||
nerr[0] = 0;
|
||||
|
@ -234,6 +209,57 @@ convertTrueColor_generic(RXImage *ximg, RImage *image,
|
|||
err = nerr;
|
||||
nerr = terr;
|
||||
}
|
||||
|
||||
/* redither the 1st line to distribute error better */
|
||||
ptr=image->data;
|
||||
y=0;
|
||||
nerr[0] = 0;
|
||||
nerr[1] = 0;
|
||||
nerr[2] = 0;
|
||||
for (x=0; x<image->width; x++, ptr+=channels) {
|
||||
|
||||
/* reduce pixel */
|
||||
pixel = *ptr + err[x];
|
||||
if (pixel<0) pixel=0; else if (pixel>0xff) pixel=0xff;
|
||||
r = rtable[pixel];
|
||||
/* calc error */
|
||||
rer = pixel - r*dr;
|
||||
|
||||
/* reduce pixel */
|
||||
pixel = *(ptr+1) + err[x+1];
|
||||
if (pixel<0) pixel=0; else if (pixel>0xff) pixel=0xff;
|
||||
g = gtable[pixel];
|
||||
/* calc error */
|
||||
ger = pixel - g*dg;
|
||||
|
||||
/* reduce pixel */
|
||||
pixel = *(ptr+2) + err[x+2];
|
||||
if (pixel<0) pixel=0; else if (pixel>0xff) pixel=0xff;
|
||||
b = btable[pixel];
|
||||
/* calc error */
|
||||
ber = pixel - b*db;
|
||||
|
||||
|
||||
pixel = (r<<roffs) | (g<<goffs) | (b<<boffs);
|
||||
XPutPixel(ximg->image, x, y, pixel);
|
||||
|
||||
/* distribute error */
|
||||
r = (rer*3)/8;
|
||||
g = (ger*3)/8;
|
||||
b = (ber*3)/8;
|
||||
/* x+1, y */
|
||||
err[x+3*1]+=r;
|
||||
err[x+1+3*1]+=g;
|
||||
err[x+2+3*1]+=b;
|
||||
/* x, y+1 */
|
||||
nerr[x]+=r;
|
||||
nerr[x+1]+=g;
|
||||
nerr[x+2]+=b;
|
||||
/* x+1, y+1 */
|
||||
nerr[x+3*1]=rer-2*r;
|
||||
nerr[x+1+3*1]=ger-2*g;
|
||||
nerr[x+2+3*1]=ber-2*b;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -283,64 +309,42 @@ image2TrueColor(RContext *ctx, RImage *image)
|
|||
unsigned char *ptr = image->data;
|
||||
|
||||
/* fake match */
|
||||
#ifdef DEBUG
|
||||
#ifdef WR_DEBUG
|
||||
puts("true color match");
|
||||
#endif
|
||||
for (y=0, ofs=0; y < image->height; y++) {
|
||||
for (x=0; x < image->width; x++, ofs+=channels-3) {
|
||||
/* reduce pixel */
|
||||
r = rtable[ptr[ofs++]];
|
||||
g = gtable[ptr[ofs++]];
|
||||
b = btable[ptr[ofs++]];
|
||||
pixel = (r<<roffs) | (g<<goffs) | (b<<boffs);
|
||||
XPutPixel(ximg->image, x, y, pixel);
|
||||
}
|
||||
}
|
||||
if (rmask==0xff && gmask==0xff && bmask==0xff) {
|
||||
for (y=0; y < image->height; y++) {
|
||||
for (x=0; x < image->width; x++, ptr+=channels) {
|
||||
/* reduce pixel */
|
||||
pixel = (*(ptr)<<roffs) | (*(ptr+1)<<goffs) | (*(ptr+2)<<boffs);
|
||||
XPutPixel(ximg->image, x, y, pixel);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (y=0, ofs=0; y < image->height; y++) {
|
||||
for (x=0; x < image->width; x++, ofs+=channels-3) {
|
||||
/* reduce pixel */
|
||||
r = rtable[ptr[ofs++]];
|
||||
g = gtable[ptr[ofs++]];
|
||||
b = btable[ptr[ofs++]];
|
||||
pixel = (r<<roffs) | (g<<goffs) | (b<<boffs);
|
||||
XPutPixel(ximg->image, x, y, pixel);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* dither */
|
||||
const int dr=0xff/rmask;
|
||||
const int dg=0xff/gmask;
|
||||
const int db=0xff/bmask;
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifdef WR_DEBUG
|
||||
puts("true color dither");
|
||||
#endif
|
||||
|
||||
#ifdef ASM_X86_MMX
|
||||
if (ctx->depth == 16 && image->format == RRGBAFormat
|
||||
&& x86_check_mmx()) {
|
||||
short *err;
|
||||
short *nerr;
|
||||
|
||||
err = malloc(8*(image->width+3));
|
||||
nerr = malloc(8*(image->width+3));
|
||||
if (!err || !nerr) {
|
||||
if (nerr)
|
||||
free(nerr);
|
||||
RErrorCode = RERR_NOMEMORY;
|
||||
RDestroyXImage(ctx, ximg);
|
||||
return NULL;
|
||||
}
|
||||
memset(err, 0, 8*(image->width+3));
|
||||
memset(nerr, 0, 8*(image->width+3));
|
||||
|
||||
x86_mmx_TrueColor_32_to_16(image->data,
|
||||
(unsigned short*)ximg->image->data,
|
||||
err+8, nerr+8,
|
||||
rtable, gtable, btable,
|
||||
dr, dg, db,
|
||||
roffs, goffs, boffs,
|
||||
image->width, image->height,
|
||||
ximg->image->bytes_per_line - 2*image->width);
|
||||
|
||||
free(err);
|
||||
free(nerr);
|
||||
} else
|
||||
#endif /* ASM_X86_MMX */
|
||||
#endif
|
||||
{
|
||||
char *err;
|
||||
char *nerr;
|
||||
int ch = image->format == RRGBAFormat ? 4 : 3;
|
||||
int ch = (image->format == RRGBAFormat ? 4 : 3);
|
||||
|
||||
err = malloc(ch*(image->width+2));
|
||||
nerr = malloc(ch*(image->width+2));
|
||||
|
@ -376,7 +380,7 @@ image2TrueColor(RContext *ctx, RImage *image)
|
|||
|
||||
static void
|
||||
convertPseudoColor_to_8(RXImage *ximg, RImage *image,
|
||||
char *err, char *nerr,
|
||||
signed char *err, signed char *nerr,
|
||||
const short *rtable,
|
||||
const short *gtable,
|
||||
const short *btable,
|
||||
|
@ -384,13 +388,13 @@ convertPseudoColor_to_8(RXImage *ximg, RImage *image,
|
|||
unsigned long *pixels,
|
||||
int cpc)
|
||||
{
|
||||
char *terr;
|
||||
signed char *terr;
|
||||
int x, y, r, g, b;
|
||||
int pixel;
|
||||
int rer, ger, ber;
|
||||
unsigned char *ptr = image->data;
|
||||
unsigned char *optr = ximg->image->data;
|
||||
int channels = image->format == RRGBAFormat ? 4 : 3;
|
||||
int channels = (image->format == RRGBAFormat ? 4 : 3);
|
||||
int cpcpc = cpc*cpc;
|
||||
|
||||
/* convert and dither the image to XImage */
|
||||
|
@ -465,7 +469,7 @@ image2PseudoColor(RContext *ctx, RImage *image)
|
|||
const unsigned short bmask = rmask;
|
||||
unsigned short *rtable, *gtable, *btable;
|
||||
const int cpccpc = cpc*cpc;
|
||||
int channels = image->format == RRGBAFormat ? 4 : 3;
|
||||
int channels = (image->format == RRGBAFormat ? 4 : 3);
|
||||
|
||||
ximg = RCreateXImage(ctx, ctx->depth, image->width, image->height);
|
||||
if (!ximg) {
|
||||
|
@ -487,11 +491,11 @@ image2PseudoColor(RContext *ctx, RImage *image)
|
|||
|
||||
if (ctx->attribs->render_mode == RBestMatchRendering) {
|
||||
/* fake match */
|
||||
#ifdef DEBUG
|
||||
#ifdef WR_DEBUG
|
||||
printf("pseudo color match with %d colors per channel\n", cpc);
|
||||
#endif
|
||||
for (y=0; y<image->height; y++) {
|
||||
for (x=0; x<image->width; x++, ptr+=channels-1) {
|
||||
for (x=0; x<image->width; x++, ptr+=channels-3) {
|
||||
/* reduce pixel */
|
||||
r = rtable[*ptr++];
|
||||
g = gtable[*ptr++];
|
||||
|
@ -510,7 +514,7 @@ image2PseudoColor(RContext *ctx, RImage *image)
|
|||
const int db=0xff/bmask;
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifdef WR_DEBUG
|
||||
printf("pseudo color dithering with %d colors per channel\n", cpc);
|
||||
#endif
|
||||
err = malloc(4*(image->width+3));
|
||||
|
@ -525,19 +529,9 @@ image2PseudoColor(RContext *ctx, RImage *image)
|
|||
memset(err, 0, 4*(image->width+3));
|
||||
memset(nerr, 0, 4*(image->width+3));
|
||||
|
||||
#ifdef ASM_X86
|
||||
x86_PseudoColor_32_to_8(image->data, ximg->image->data,
|
||||
err+4, nerr+4,
|
||||
rtable,
|
||||
dr, dg, db, ctx->pixels, cpc,
|
||||
image->width, image->height,
|
||||
channels,
|
||||
ximg->image->bytes_per_line - image->width);
|
||||
#else
|
||||
convertPseudoColor_to_8(ximg, image, err+4, nerr+4,
|
||||
rtable, gtable, btable,
|
||||
dr, dg, db, ctx->pixels, cpc);
|
||||
#endif
|
||||
|
||||
free(err);
|
||||
free(nerr);
|
||||
|
@ -560,8 +554,8 @@ image2StandardPseudoColor(RContext *ctx, RImage *image)
|
|||
unsigned char *data;
|
||||
unsigned int *rtable, *gtable, *btable;
|
||||
unsigned int base_pixel = ctx->std_rgb_map->base_pixel;
|
||||
int channels = image->format == RRGBAFormat ? 4 : 3;
|
||||
/*register unsigned char maxrgb = 0xff;*/
|
||||
int channels = (image->format == RRGBAFormat ? 4 : 3);
|
||||
|
||||
|
||||
ximg = RCreateXImage(ctx, ctx->depth, image->width, image->height);
|
||||
if (!ximg) {
|
||||
|
@ -591,24 +585,29 @@ image2StandardPseudoColor(RContext *ctx, RImage *image)
|
|||
|
||||
if (ctx->attribs->render_mode == RBestMatchRendering) {
|
||||
for (y=0; y<image->height; y++) {
|
||||
for (x=0; x<image->width; x++, ptr+=channels-3) {
|
||||
for (x=0; x<image->width; x++, ptr+=channels) {
|
||||
/* reduce pixel */
|
||||
pixel = (rtable[*ptr++] + gtable[*ptr++]
|
||||
+ btable[*ptr++] + base_pixel) & 0xffffffff;
|
||||
pixel = (rtable[*ptr] + gtable[*(ptr+1)]
|
||||
+ btable[*(ptr+2)] + base_pixel) & 0xffffffff;
|
||||
|
||||
XPutPixel(ximg->image, x, y, pixel);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* dither */
|
||||
short *err, *nerr;
|
||||
short *terr;
|
||||
signed short *err, *nerr;
|
||||
signed short *terr;
|
||||
int rer, ger, ber;
|
||||
int x1, ofs;
|
||||
|
||||
#ifdef WR_DEBUG
|
||||
printf("pseudo color dithering with %d colors per channel\n", channels);
|
||||
#endif
|
||||
err = (short*)malloc(3*(image->width+2)*sizeof(short));
|
||||
nerr = (short*)malloc(3*(image->width+2)*sizeof(short));
|
||||
if (!err || !nerr) {
|
||||
if (err)
|
||||
free(err);
|
||||
if (nerr)
|
||||
free(nerr);
|
||||
RErrorCode = RERR_NOMEMORY;
|
||||
|
@ -620,7 +619,7 @@ image2StandardPseudoColor(RContext *ctx, RImage *image)
|
|||
err[x++] = ptr[x1++];
|
||||
err[x++] = ptr[x1++];
|
||||
}
|
||||
err[x++] = err[x++] = err[x++] = 0;
|
||||
err[x] = err[x+1] = err[x+2] = 0;
|
||||
/* convert and dither the image to XImage */
|
||||
for (y=0, ofs=0; y<image->height; y++) {
|
||||
if (y<image->height-1) {
|
||||
|
@ -703,9 +702,8 @@ image2GrayScale(RContext *ctx, RImage *image)
|
|||
unsigned short gmask;
|
||||
unsigned short *table;
|
||||
unsigned char *data;
|
||||
int channels = image->format == RRGBAFormat ? 4 : 3;
|
||||
int channels = (image->format == RRGBAFormat ? 4 : 3);
|
||||
|
||||
/*register unsigned char maxrgb = 0xff;*/
|
||||
|
||||
ximg = RCreateXImage(ctx, ctx->depth, image->width, image->height);
|
||||
if (!ximg) {
|
||||
|
@ -731,14 +729,14 @@ image2GrayScale(RContext *ctx, RImage *image)
|
|||
|
||||
if (ctx->attribs->render_mode == RBestMatchRendering) {
|
||||
/* fake match */
|
||||
#ifdef DEBUG
|
||||
#ifdef WR_DEBUG
|
||||
printf("grayscale match with %d colors per channel\n", cpc);
|
||||
#endif
|
||||
for (y=0; y<image->height; y++) {
|
||||
for (x=0; x<image->width; x++) {
|
||||
/* reduce pixel */
|
||||
g = table[(*ptr++ * 30 + *ptr++ * 59 + *ptr++ * 11)/100];
|
||||
|
||||
g = table[(*ptr * 30 + *(ptr+1) * 59 + *(ptr+2) * 11)/100];
|
||||
ptr += channels;
|
||||
/*data[ofs] = ctx->colors[g].pixel;*/
|
||||
XPutPixel(ximg->image, x, y, ctx->colors[g].pixel);
|
||||
}
|
||||
|
@ -751,7 +749,7 @@ image2GrayScale(RContext *ctx, RImage *image)
|
|||
int ger;
|
||||
const int dg=0xff/gmask;
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifdef WR_DEBUG
|
||||
printf("grayscale dither with %d colors per channel\n", cpc);
|
||||
#endif
|
||||
gerr = (short*)malloc((image->width+2)*sizeof(short));
|
||||
|
@ -763,22 +761,20 @@ image2GrayScale(RContext *ctx, RImage *image)
|
|||
RDestroyXImage(ctx, ximg);
|
||||
return NULL;
|
||||
}
|
||||
for (x=0; x<image->width; x++) {
|
||||
gerr[x] = (ptr[x*3]*30 + ptr[x*3+1]*59 + ptr[x*3+2]*11)/100;
|
||||
for (x=0, y=0; x<image->width; x++, y+=channels) {
|
||||
gerr[x] = (ptr[y]*30 + ptr[y+1]*59 + ptr[y+2]*11)/100;
|
||||
}
|
||||
gerr[x] = 0;
|
||||
/* convert and dither the image to XImage */
|
||||
for (y=0; y<image->height; y++) {
|
||||
if (y<image->height-1) {
|
||||
int x1;
|
||||
for (x=0, x1=(y+1)*image->width*3;
|
||||
x<image->width;
|
||||
x1+=channels-3) {
|
||||
ngerr[x] = (ptr[x1++]*30 + ptr[x1++]*59 + ptr[x1++]*11)/100;
|
||||
for (x=0, x1=(y+1)*image->width*channels; x<image->width; x++, x1+=channels) {
|
||||
ngerr[x] = (ptr[x1]*30 + ptr[x1+1]*59 + ptr[x1+2]*11)/100;
|
||||
}
|
||||
/* last column */
|
||||
x1-=channels;
|
||||
ngerr[x] = (ptr[x1++]*30 + ptr[x1++]*59 + ptr[x1++]*11)/100;
|
||||
ngerr[x] = (ptr[x1]*30 + ptr[x1+1]*59 + ptr[x1+2]*11)/100;
|
||||
}
|
||||
for (x=0; x<image->width; x++) {
|
||||
/* reduce pixel */
|
||||
|
@ -838,6 +834,88 @@ image2Bitmap(RContext *ctx, RImage *image, int threshold)
|
|||
}
|
||||
|
||||
|
||||
#ifdef HAVE_HERMES
|
||||
|
||||
static RXImage*
|
||||
hermesConvert(RContext *context, RImage *image)
|
||||
{
|
||||
HermesFormat source;
|
||||
HermesFormat dest;
|
||||
RXImage *ximage;
|
||||
|
||||
|
||||
ximage = RCreateXImage(context, context->depth,
|
||||
image->width, image->height);
|
||||
if (!ximage) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* The masks look weird for images with alpha. but they work this way.
|
||||
* wth does hermes do internally?
|
||||
*/
|
||||
source.bits = (HAS_ALPHA(image) ? 32 : 24);
|
||||
if (ximage->image->byte_order==LSBFirst) {
|
||||
source.r = 0xff0000;
|
||||
source.g = 0x00ff00;
|
||||
source.b = 0x0000ff;
|
||||
} else {
|
||||
if (source.bits == 32) {
|
||||
source.r = 0xff000000;
|
||||
source.g = 0x00ff0000;
|
||||
source.b = 0x0000ff00;
|
||||
} else {
|
||||
source.r = 0xff0000;
|
||||
source.g = 0x00ff00;
|
||||
source.b = 0x0000ff;
|
||||
}
|
||||
}
|
||||
source.a = 0; /* Don't care about alpha */
|
||||
source.indexed = 0;
|
||||
source.has_colorkey = 0;
|
||||
|
||||
/* This is a hack and certainly looks weird, but it works :P
|
||||
* it assumes though that green is inbetween red and blue (the mask) */
|
||||
if (ximage->image->byte_order==LSBFirst) {
|
||||
dest.r = context->visual->blue_mask;
|
||||
dest.g = context->visual->green_mask;
|
||||
dest.b = context->visual->red_mask;
|
||||
} else {
|
||||
dest.r = context->visual->red_mask;
|
||||
dest.g = context->visual->green_mask;
|
||||
dest.b = context->visual->blue_mask;
|
||||
}
|
||||
dest.a = 0;
|
||||
dest.bits = ximage->image->bits_per_pixel;
|
||||
if (context->vclass == TrueColor)
|
||||
dest.indexed = 0;
|
||||
else
|
||||
dest.indexed = 1;
|
||||
dest.has_colorkey = 0;
|
||||
|
||||
/*printf("source r=0x%x, g=0x%x, b=0x%x, a=0x%x, b=%d, i=%d, c=%d\n",
|
||||
source.r, source.g, source.b, source.a,
|
||||
source.bits, source.indexed, source.has_colorkey);
|
||||
printf("dest r=0x%x, g=0x%x, b=0x%x, a=0x%x, b=%d, i=%d, c=%d\n",
|
||||
dest.r, dest.g, dest.b, dest.a,
|
||||
dest.bits, dest.indexed, dest.has_colorkey);
|
||||
*/
|
||||
|
||||
Hermes_ConverterRequest(context->hermes_data->converter, &source, &dest);
|
||||
|
||||
Hermes_ConverterPalette(context->hermes_data->converter,
|
||||
context->hermes_data->palette, 0);
|
||||
|
||||
Hermes_ConverterCopy(context->hermes_data->converter,
|
||||
image->data, 0, 0, image->width, image->height,
|
||||
image->width * (image->format == RRGBFormat ? 3 : 4),
|
||||
ximage->image->data, 0, 0,
|
||||
image->width, image->height,
|
||||
ximage->image->bytes_per_line);
|
||||
|
||||
return ximage;
|
||||
}
|
||||
#endif /* HAVE_HERMES */
|
||||
|
||||
|
||||
int
|
||||
RConvertImage(RContext *context, RImage *image, Pixmap *pixmap)
|
||||
|
@ -851,14 +929,22 @@ RConvertImage(RContext *context, RImage *image, Pixmap *pixmap)
|
|||
assert(image!=NULL);
|
||||
assert(pixmap!=NULL);
|
||||
|
||||
/* clear error message */
|
||||
if (context->vclass == TrueColor) {
|
||||
|
||||
ximg = image2TrueColor(context, image);
|
||||
|
||||
} else if (context->vclass == PseudoColor
|
||||
|| context->vclass == StaticColor) {
|
||||
switch (context->vclass) {
|
||||
case TrueColor:
|
||||
#ifdef HAVE_HERMES
|
||||
if (context->attribs->render_mode == RBestMatchRendering) {
|
||||
ximg = hermesConvert(context, image);
|
||||
} else {
|
||||
ximg = image2TrueColor(context, image);
|
||||
}
|
||||
#else /* !HAVE_HERMES */
|
||||
ximg = image2TrueColor(context, image);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case PseudoColor:
|
||||
case StaticColor:
|
||||
/* For StaticColor we can also use hermes, but it doesn't dither */
|
||||
#ifdef BENCH
|
||||
cycle_bench(1);
|
||||
#endif
|
||||
|
@ -869,16 +955,19 @@ RConvertImage(RContext *context, RImage *image, Pixmap *pixmap)
|
|||
#ifdef BENCH
|
||||
cycle_bench(0);
|
||||
#endif
|
||||
} else if (context->vclass == GrayScale || context->vclass == StaticGray) {
|
||||
break;
|
||||
|
||||
case GrayScale:
|
||||
case StaticGray:
|
||||
ximg = image2GrayScale(context, image);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (!ximg) {
|
||||
return False;
|
||||
}
|
||||
|
||||
|
||||
*pixmap = XCreatePixmap(context->dpy, context->drawable, image->width,
|
||||
image->height, context->depth);
|
||||
|
||||
|
@ -952,6 +1041,7 @@ RConvertImageMask(RContext *context, RImage *image, Pixmap *pixmap,
|
|||
RPutXImage(context, *mask, gc, ximg, 0, 0, 0, 0,
|
||||
image->width, image->height);
|
||||
RDestroyXImage(context, ximg);
|
||||
XFreeGC(context->dpy, gc);
|
||||
|
||||
return True;
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
*
|
||||
* Raster graphics library
|
||||
*
|
||||
* Copyright (c) 1997-2000 Alfredo K. Kojima
|
||||
* Copyright (c) 1997-2002 Alfredo K. Kojima
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
|
@ -24,6 +24,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include "x11/wraster.h"
|
||||
|
||||
|
@ -37,14 +38,26 @@ int RErrorCode=RERR_NONE;
|
|||
|
||||
#define HAS_ALPHA(I) ((I)->format == RRGBAFormat)
|
||||
|
||||
#define MAX_WIDTH 20000
|
||||
#define MAX_HEIGHT 20000
|
||||
/* 20000^2*4 < 2G */
|
||||
|
||||
|
||||
RImage*
|
||||
RCreateImage(unsigned width, unsigned height, int alpha)
|
||||
{
|
||||
RImage *image=NULL;
|
||||
unsigned bla1, bla2;
|
||||
|
||||
assert(width>0 && height>0);
|
||||
|
||||
/* check for bogus image sizes (and avoid overflow as a bonus) */
|
||||
if (width > MAX_WIDTH || height > MAX_HEIGHT) {
|
||||
RErrorCode = RERR_NOMEMORY;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
image = malloc(sizeof(RImage));
|
||||
if (!image) {
|
||||
RErrorCode = RERR_NOMEMORY;
|
||||
|
@ -54,11 +67,9 @@ RCreateImage(unsigned width, unsigned height, int alpha)
|
|||
memset(image, 0, sizeof(RImage));
|
||||
image->width = width;
|
||||
image->height = height;
|
||||
if (alpha) {
|
||||
image->format = RRGBAFormat;
|
||||
} else {
|
||||
image->format = RRGBFormat;
|
||||
}
|
||||
image->format = alpha ? RRGBAFormat : RRGBFormat;
|
||||
image->refCount = 1;
|
||||
|
||||
/* the +4 is to give extra bytes at the end of the buffer,
|
||||
* so that we can optimize image conversion for MMX(tm).. see convert.c
|
||||
*/
|
||||
|
@ -73,6 +84,44 @@ RCreateImage(unsigned width, unsigned height, int alpha)
|
|||
}
|
||||
|
||||
|
||||
RImage*
|
||||
RRetainImage(RImage *image)
|
||||
{
|
||||
if (image)
|
||||
image->refCount++;
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
RReleaseImage(RImage *image)
|
||||
{
|
||||
assert(image!=NULL);
|
||||
|
||||
image->refCount--;
|
||||
|
||||
if (image->refCount < 1) {
|
||||
free(image->data);
|
||||
free(image);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Obsoleted function. Use RReleaseImage() instead. This was kept only to
|
||||
* allow a smoother transition and to avoid breaking existing programs, but
|
||||
* it will be removed in a future release. Right now is just an alias to
|
||||
* RReleaseImage(). Do _NOT_ use RDestroyImage() anymore in your programs.
|
||||
* Being an alias to RReleaseImage() this function no longer actually
|
||||
* destroys the image, unless the image is no longer retained in some other
|
||||
* place.
|
||||
*/
|
||||
void
|
||||
RDestroyImage(RImage *image)
|
||||
{
|
||||
RReleaseImage(image);
|
||||
}
|
||||
|
||||
|
||||
RImage*
|
||||
RCloneImage(RImage *image)
|
||||
|
@ -129,16 +178,6 @@ RGetSubImage(RImage *image, int x, int y, unsigned width, unsigned height)
|
|||
}
|
||||
|
||||
|
||||
void
|
||||
RDestroyImage(RImage *image)
|
||||
{
|
||||
assert(image!=NULL);
|
||||
|
||||
free(image->data);
|
||||
free(image);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
* RCombineImages-
|
||||
|
@ -183,24 +222,18 @@ RCombineImages(RImage *image, RImage *src)
|
|||
for (i=0; i<image->height*image->width; i++) {
|
||||
alpha = *(s+3);
|
||||
calpha = 255 - alpha;
|
||||
*d = (((int)*d * calpha) + ((int)*s * alpha))/256;
|
||||
d++; s++;
|
||||
*d = (((int)*d * calpha) + ((int)*s * alpha))/256;
|
||||
d++; s++;
|
||||
*d = (((int)*d * calpha) + ((int)*s * alpha))/256;
|
||||
d++; s++;
|
||||
*d = (((int)*d * calpha) + ((int)*s * alpha))/256; d++; s++;
|
||||
*d = (((int)*d * calpha) + ((int)*s * alpha))/256; d++; s++;
|
||||
*d = (((int)*d * calpha) + ((int)*s * alpha))/256; d++; s++;
|
||||
s++;
|
||||
}
|
||||
} else {
|
||||
for (i=0; i<image->height*image->width; i++) {
|
||||
alpha = *(s+3);
|
||||
calpha = 255 - alpha;
|
||||
*d = (((int)*d * calpha) + ((int)*s * alpha))/256;
|
||||
d++; s++;
|
||||
*d = (((int)*d * calpha) + ((int)*s * alpha))/256;
|
||||
d++; s++;
|
||||
*d = (((int)*d * calpha) + ((int)*s * alpha))/256;
|
||||
d++; s++;
|
||||
*d = (((int)*d * calpha) + ((int)*s * alpha))/256; d++; s++;
|
||||
*d = (((int)*d * calpha) + ((int)*s * alpha))/256; d++; s++;
|
||||
*d = (((int)*d * calpha) + ((int)*s * alpha))/256; d++; s++;
|
||||
*d++ |= *s++;
|
||||
}
|
||||
}
|
||||
|
@ -225,53 +258,74 @@ RCombineImagesWithOpaqueness(RImage *image, RImage *src, int opaqueness)
|
|||
s = src->data;
|
||||
|
||||
c_opaqueness = 255 - opaqueness;
|
||||
|
||||
#define OP opaqueness
|
||||
#define COP c_opaqueness
|
||||
|
||||
if (!HAS_ALPHA(src)) {
|
||||
int dalpha = HAS_ALPHA(image);
|
||||
#define COP c_opaqueness
|
||||
for (i=0; i < image->width*image->height; i++) {
|
||||
*d = (((int)*d *(int)COP) + ((int)*s *(int)OP))/256;
|
||||
d++; s++;
|
||||
*d = (((int)*d *(int)COP) + ((int)*s *(int)OP))/256;
|
||||
d++; s++;
|
||||
*d = (((int)*d *(int)COP) + ((int)*s *(int)OP))/256;
|
||||
d++; s++;
|
||||
*d = (((int)*d *(int)COP) + ((int)*s *(int)OP))/256; d++; s++;
|
||||
*d = (((int)*d *(int)COP) + ((int)*s *(int)OP))/256; d++; s++;
|
||||
*d = (((int)*d *(int)COP) + ((int)*s *(int)OP))/256; d++; s++;
|
||||
if (dalpha) {
|
||||
d++;
|
||||
}
|
||||
}
|
||||
#undef COP
|
||||
} else {
|
||||
int tmp;
|
||||
|
||||
if (!HAS_ALPHA(image)) {
|
||||
for (i=0; i<image->width*image->height; i++) {
|
||||
tmp = (*(s+3) * opaqueness)/256;
|
||||
*d = (((int)*d * (255-tmp)) + ((int)*s * tmp))/256;
|
||||
d++; s++;
|
||||
*d = (((int)*d * (255-tmp)) + ((int)*s * tmp))/256;
|
||||
d++; s++;
|
||||
*d = (((int)*d * (255-tmp)) + ((int)*s * tmp))/256;
|
||||
d++; s++;
|
||||
*d = (((int)*d * (255-tmp)) + ((int)*s * tmp))/256; d++; s++;
|
||||
*d = (((int)*d * (255-tmp)) + ((int)*s * tmp))/256; d++; s++;
|
||||
*d = (((int)*d * (255-tmp)) + ((int)*s * tmp))/256; d++; s++;
|
||||
s++;
|
||||
}
|
||||
} else {
|
||||
for (i=0; i<image->width*image->height; i++) {
|
||||
tmp = (*(s+3) * opaqueness)/256;
|
||||
*d = (((int)*d * (255-tmp)) + ((int)*s * tmp))/256;
|
||||
d++; s++;
|
||||
*d = (((int)*d * (255-tmp)) + ((int)*s * tmp))/256;
|
||||
d++; s++;
|
||||
*d = (((int)*d * (255-tmp)) + ((int)*s * tmp))/256;
|
||||
d++; s++;
|
||||
*d = (((int)*d * (255-tmp)) + ((int)*s * tmp))/256; d++; s++;
|
||||
*d = (((int)*d * (255-tmp)) + ((int)*s * tmp))/256; d++; s++;
|
||||
*d = (((int)*d * (255-tmp)) + ((int)*s * tmp))/256; d++; s++;
|
||||
*d |= tmp;
|
||||
d++; s++;
|
||||
}
|
||||
}
|
||||
}
|
||||
#undef OP
|
||||
#undef COP
|
||||
}
|
||||
|
||||
int
|
||||
calculateCombineArea(RImage *des, RImage *src, int *sx, int *sy,
|
||||
int *swidth, int *sheight, int *dx, int *dy)
|
||||
{
|
||||
if (*dx < 0) {
|
||||
*sx = -*dx;
|
||||
*swidth = *swidth + *dx;
|
||||
*dx = 0;
|
||||
}
|
||||
|
||||
if (*dx + *swidth > des->width) {
|
||||
*swidth = des->width - *dx;
|
||||
}
|
||||
|
||||
if (*dy < 0) {
|
||||
*sy = -*dy;
|
||||
*sheight = *sheight + *dy;
|
||||
*dy = 0;
|
||||
}
|
||||
|
||||
if (*dy + *sheight > des->height) {
|
||||
*sheight = des->height - *dy;
|
||||
}
|
||||
|
||||
if (*sheight > 0 && *swidth > 0) {
|
||||
return True;
|
||||
} else return False;
|
||||
}
|
||||
|
||||
void
|
||||
RCombineArea(RImage *image, RImage *src, int sx, int sy, unsigned width,
|
||||
|
@ -282,18 +336,8 @@ RCombineArea(RImage *image, RImage *src, int sx, int sy, unsigned width,
|
|||
unsigned char *s;
|
||||
int alpha, calpha;
|
||||
|
||||
|
||||
assert(dy < image->height);
|
||||
assert(dx < image->width);
|
||||
|
||||
assert(sy + height <= src->height);
|
||||
assert(sx + width <= src->width);
|
||||
|
||||
if (width > image->width - dx)
|
||||
width = image->width - dx;
|
||||
|
||||
if (height > image->height - dy)
|
||||
height = image->height - dy;
|
||||
if(!calculateCombineArea(image, src, &sx, &sy, &width, &height, &dx, &dy))
|
||||
return;
|
||||
|
||||
if (!HAS_ALPHA(src)) {
|
||||
if (!HAS_ALPHA(image)) {
|
||||
|
@ -343,12 +387,9 @@ RCombineArea(RImage *image, RImage *src, int sx, int sy, unsigned width,
|
|||
for (x=0; x < width; x++) {
|
||||
alpha = *(s+3);
|
||||
calpha = 255 - alpha;
|
||||
*d = (((int)*d * calpha) + ((int)*s * alpha))/256;
|
||||
s++; d++;
|
||||
*d = (((int)*d * calpha) + ((int)*s * alpha))/256;
|
||||
s++; d++;
|
||||
*d = (((int)*d * calpha) + ((int)*s * alpha))/256;
|
||||
s++; d++;
|
||||
*d = (((int)*d * calpha) + ((int)*s * alpha))/256; s++; d++;
|
||||
*d = (((int)*d * calpha) + ((int)*s * alpha))/256; s++; d++;
|
||||
*d = (((int)*d * calpha) + ((int)*s * alpha))/256; s++; d++;
|
||||
s++;
|
||||
if (dalpha)
|
||||
d++;
|
||||
|
@ -367,65 +408,48 @@ RCombineAreaWithOpaqueness(RImage *image, RImage *src, int sx, int sy,
|
|||
{
|
||||
int x, y, dwi, swi;
|
||||
int c_opaqueness;
|
||||
unsigned char *d;
|
||||
unsigned char *s;
|
||||
unsigned char *s, *d;
|
||||
int dalpha = HAS_ALPHA(image);
|
||||
int dch = (dalpha ? 4 : 3);
|
||||
|
||||
assert(dy <= image->height);
|
||||
assert(dx <= image->width);
|
||||
if(!calculateCombineArea(image, src, &sx, &sy, &width, &height, &dx, &dy))
|
||||
return;
|
||||
|
||||
assert(sy <= height);
|
||||
assert(sx <= width);
|
||||
|
||||
|
||||
/* clip */
|
||||
width -= sx;
|
||||
height -= sy;
|
||||
|
||||
if (height > image->height - dy)
|
||||
height = image->height - dy;
|
||||
|
||||
d = image->data + dy*image->width*dch + dx;
|
||||
d = image->data + (dy*image->width + dx) * dch;
|
||||
dwi = (image->width - width)*dch;
|
||||
|
||||
c_opaqueness = 255 - opaqueness;
|
||||
|
||||
#define OP opaqueness
|
||||
if (!HAS_ALPHA(src)) {
|
||||
#define COP c_opaqueness
|
||||
|
||||
s = src->data + sy*src->width*3;
|
||||
if (!HAS_ALPHA(src)) {
|
||||
|
||||
s = src->data + (sy*src->width + sx)*3;
|
||||
swi = (src->width - width) * 3;
|
||||
|
||||
for (y=0; y < height; y++) {
|
||||
for (x=0; x < width; x++) {
|
||||
*d = (((int)*d *(int)COP) + ((int)*s *(int)OP))/256;
|
||||
s++; d++;
|
||||
*d = (((int)*d *(int)COP) + ((int)*s *(int)OP))/256;
|
||||
s++; d++;
|
||||
*d = (((int)*d *(int)COP) + ((int)*s *(int)OP))/256;
|
||||
s++; d++;
|
||||
*d = (((int)*d *(int)COP) + ((int)*s *(int)OP))/256; s++; d++;
|
||||
*d = (((int)*d *(int)COP) + ((int)*s *(int)OP))/256; s++; d++;
|
||||
*d = (((int)*d *(int)COP) + ((int)*s *(int)OP))/256; s++; d++;
|
||||
if (dalpha)
|
||||
d++;
|
||||
}
|
||||
d += dwi; s += swi;
|
||||
}
|
||||
#undef COP
|
||||
} else {
|
||||
int tmp;
|
||||
|
||||
s = src->data + sy*src->width*4;
|
||||
s = src->data + (sy*src->width + sx)*4;
|
||||
swi = (src->width - width) * 4;
|
||||
|
||||
for (y=0; y < height; y++) {
|
||||
for (x=0; x < width; x++) {
|
||||
tmp= (*(s+3) * opaqueness)/256;
|
||||
*d = (((int)*d *(int)(255-tmp)) + ((int)*s *(int)tmp))/256;
|
||||
d++; s++;
|
||||
*d = (((int)*d *(int)(255-tmp)) + ((int)*s *(int)tmp))/256;
|
||||
d++; s++;
|
||||
*d = (((int)*d *(int)(255-tmp)) + ((int)*s *(int)tmp))/256;
|
||||
d++; s++;
|
||||
tmp = (*(s+3) * opaqueness)/256;
|
||||
*d = (((int)*d * (255-tmp)) + ((int)*s * tmp))/256; d++; s++;
|
||||
*d = (((int)*d * (255-tmp)) + ((int)*s * tmp))/256; d++; s++;
|
||||
*d = (((int)*d * (255-tmp)) + ((int)*s * tmp))/256; d++; s++;
|
||||
s++;
|
||||
if (dalpha)
|
||||
d++;
|
||||
|
@ -434,6 +458,7 @@ RCombineAreaWithOpaqueness(RImage *image, RImage *src, int sx, int sy,
|
|||
}
|
||||
}
|
||||
#undef OP
|
||||
#undef COP
|
||||
}
|
||||
|
||||
|
||||
|
@ -460,12 +485,9 @@ RCombineImageWithColor(RImage *image, RColor *color)
|
|||
alpha = *(d+3);
|
||||
nalpha = 255 - alpha;
|
||||
|
||||
*d = (((int)*d * alpha) + (r * nalpha))/256;
|
||||
d++;
|
||||
*d = (((int)*d * alpha) + (g * nalpha))/256;
|
||||
d++;
|
||||
*d = (((int)*d * alpha) + (b * nalpha))/256;
|
||||
d++;
|
||||
*d = (((int)*d * alpha) + (r * nalpha))/256; d++;
|
||||
*d = (((int)*d * alpha) + (g * nalpha))/256; d++;
|
||||
*d = (((int)*d * alpha) + (b * nalpha))/256; d++;
|
||||
d++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
*
|
||||
* Raster graphics library
|
||||
*
|
||||
* Copyright (c) 1997, 1988, 1999 Alfredo K. Kojima
|
||||
* Copyright (c) 1997-2002 Alfredo K. Kojima
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
|
@ -29,7 +29,7 @@
|
|||
#include <math.h>
|
||||
|
||||
#ifndef PI
|
||||
#define PI 3.141592
|
||||
#define PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
|
@ -412,6 +412,7 @@ CLIST *contrib; /* array of contribution lists */
|
|||
#define CLAMP(v,l,h) ((v)<(l) ? (l) : (v) > (h) ? (h) : v)
|
||||
|
||||
|
||||
/* return of calloc is not checked if NULL in the function below! */
|
||||
RImage*
|
||||
RSmoothScaleImage(RImage *src, unsigned new_width, unsigned new_height)
|
||||
{
|
||||
|
@ -616,7 +617,7 @@ RSmoothScaleImage(RImage *src, unsigned new_width, unsigned new_height)
|
|||
}
|
||||
free(contrib);
|
||||
|
||||
RDestroyImage(tmp);
|
||||
RReleaseImage(tmp);
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
|
24
Source/x11/wrasterP.h
Normal file
24
Source/x11/wrasterP.h
Normal file
|
@ -0,0 +1,24 @@
|
|||
|
||||
|
||||
#ifndef WRASTERP_H_
|
||||
#define WRASTERP_H_
|
||||
|
||||
#include <config.h>
|
||||
|
||||
|
||||
#include "x11/wraster.h"
|
||||
|
||||
|
||||
#ifdef HAVE_HERMES
|
||||
|
||||
# include <Hermes/Hermes.h>
|
||||
|
||||
typedef struct RHermesData {
|
||||
HermesHandle palette;
|
||||
HermesHandle converter;
|
||||
} RHermesData;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
|
@ -2,7 +2,7 @@
|
|||
*
|
||||
* Raster graphics library
|
||||
*
|
||||
* Copyright (c) 1997 Alfredo K. Kojima
|
||||
* Copyright (c) 1997-2002 Alfredo K. Kojima
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
|
@ -120,7 +120,7 @@ RCreateXImage(RContext *context, int depth, unsigned width, unsigned height)
|
|||
IPC_CREAT|0777);
|
||||
if (rximg->info.shmid < 0) {
|
||||
context->attribs->use_shared_memory = 0;
|
||||
perror("wrlib:could not allocate shared memory segment");
|
||||
perror("wrlib: could not allocate shared memory segment");
|
||||
XDestroyImage(rximg->image);
|
||||
goto retry_without_shm;
|
||||
}
|
||||
|
@ -129,8 +129,8 @@ RCreateXImage(RContext *context, int depth, unsigned width, unsigned height)
|
|||
if (rximg->info.shmaddr == (void*)-1) {
|
||||
context->attribs->use_shared_memory = 0;
|
||||
if (shmctl(rximg->info.shmid, IPC_RMID, 0) < 0)
|
||||
perror("wrlib:shmctl");
|
||||
perror("wrlib:could not allocate shared memory");
|
||||
perror("wrlib: shmctl");
|
||||
perror("wrlib: could not allocate shared memory");
|
||||
XDestroyImage(rximg->image);
|
||||
goto retry_without_shm;
|
||||
}
|
||||
|
@ -149,9 +149,9 @@ RCreateXImage(RContext *context, int depth, unsigned width, unsigned height)
|
|||
context->attribs->use_shared_memory = 0;
|
||||
XDestroyImage(rximg->image);
|
||||
if (shmdt(rximg->info.shmaddr) < 0)
|
||||
perror("wrlib:shmdt");
|
||||
perror("wrlib: shmdt");
|
||||
if (shmctl(rximg->info.shmid, IPC_RMID, 0) < 0)
|
||||
perror("wrlib:shmctl");
|
||||
perror("wrlib: shmctl");
|
||||
/* printf("wrlib:error attaching shared memory segment to XImage\n");
|
||||
*/
|
||||
goto retry_without_shm;
|
||||
|
@ -174,9 +174,9 @@ RDestroyXImage(RContext *context, RXImage *rximage)
|
|||
XShmDetach(context->dpy, &rximage->info);
|
||||
XDestroyImage(rximage->image);
|
||||
if (shmdt(rximage->info.shmaddr) < 0)
|
||||
perror("wrlib:shmdt");
|
||||
perror("wrlib: shmdt");
|
||||
if (shmctl(rximage->info.shmid, IPC_RMID, 0) < 0)
|
||||
perror("wrlib:shmctl");
|
||||
perror("wrlib: shmctl");
|
||||
} else {
|
||||
XDestroyImage(rximage->image);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue