mirror of
https://github.com/gnustep/libs-back.git
synced 2025-04-22 23:42:16 +00:00
Small cairo fixes plus NET WM icon setting.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/back/trunk@21964 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
22e9233bd6
commit
5de50d17fd
4 changed files with 221 additions and 59 deletions
12
ChangeLog
12
ChangeLog
|
@ -1,3 +1,15 @@
|
|||
2005-11-07 Fred Kiefer <FredKiefer@gmx.de>
|
||||
|
||||
* Source/x11/XGServerWindow.m (_createNetIcon, _setNetWMIconFor:):
|
||||
New methods to create and set NET WM icon for window.
|
||||
* Source/x11/XGServerWindow.m (-window::::): Use this methods to
|
||||
set window icon.
|
||||
|
||||
* Source/cairo/CairoGState.m (-DPSImage::::::::): Try to deal with
|
||||
flipped views.
|
||||
* Source/cairo/CairoFontInfo.m: Reduced the amount of unexported cairo
|
||||
functions we use.
|
||||
|
||||
2005-10-30 Richard Frith-Macdonald <rfm@gnu.org>
|
||||
|
||||
* Source/win32/WIN33Server.m: synchronize defaults so settings are
|
||||
|
|
|
@ -154,7 +154,7 @@
|
|||
return YES;
|
||||
}
|
||||
|
||||
// FIXME: This function is not exported by Cairo
|
||||
// FIXME: This function is not exported by Cairo. The parameters have changed in recent cairo!!!
|
||||
extern
|
||||
cairo_status_t
|
||||
_cairo_scaled_font_text_to_glyphs (cairo_scaled_font_t *scaled_font,
|
||||
|
@ -163,31 +163,41 @@ _cairo_scaled_font_text_to_glyphs (cairo_scaled_font_t *scaled_font,
|
|||
int *num_glyphs);
|
||||
|
||||
static
|
||||
cairo_glyph_t _cairo_glyph_for_NSGlyph(cairo_scaled_font_t *scaled_font, NSGlyph glyph)
|
||||
BOOL _cairo_extents_for_text(cairo_scaled_font_t *scaled_font, const char *utf8,
|
||||
cairo_text_extents_t *ctext)
|
||||
{
|
||||
cairo_glyph_t cglyph;
|
||||
char str[2];
|
||||
cairo_glyph_t *glyphs = NULL;
|
||||
int num_glyphs;
|
||||
cairo_status_t status;
|
||||
|
||||
str[0] = glyph;
|
||||
str[1] = 0;
|
||||
|
||||
status = _cairo_scaled_font_text_to_glyphs(scaled_font, str,
|
||||
status = _cairo_scaled_font_text_to_glyphs(scaled_font, utf8,
|
||||
&glyphs, &num_glyphs);
|
||||
if (glyphs)
|
||||
{
|
||||
cglyph = glyphs[0];
|
||||
cairo_scaled_font_glyph_extents(scaled_font, glyphs, num_glyphs, ctext);
|
||||
free(glyphs);
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
return cglyph;
|
||||
return NO;
|
||||
}
|
||||
|
||||
static
|
||||
BOOL _cairo_extents_for_NSGlyph(cairo_scaled_font_t *scaled_font, NSGlyph glyph,
|
||||
cairo_text_extents_t *ctext)
|
||||
{
|
||||
char str[3];
|
||||
|
||||
// FIXME: This is wrong for none ASCII characters!
|
||||
str[0] = glyph;
|
||||
str[1] = 0;
|
||||
|
||||
return _cairo_extents_for_text(scaled_font, str, ctext);
|
||||
}
|
||||
|
||||
- (NSSize) advancementForGlyph: (NSGlyph)glyph
|
||||
{
|
||||
cairo_glyph_t cglyph;
|
||||
cairo_text_extents_t ctext;
|
||||
int entry;
|
||||
|
||||
|
@ -198,39 +208,40 @@ cairo_glyph_t _cairo_glyph_for_NSGlyph(cairo_scaled_font_t *scaled_font, NSGlyph
|
|||
return _cachedSizes[entry];
|
||||
}
|
||||
|
||||
cglyph = _cairo_glyph_for_NSGlyph(_scaled, glyph);
|
||||
cairo_scaled_font_glyph_extents(_scaled, &cglyph, 1, &ctext);
|
||||
_cachedGlyphs[entry] = glyph;
|
||||
_cachedSizes[entry] = NSMakeSize(ctext.x_advance, ctext.y_advance);
|
||||
if (_cairo_extents_for_NSGlyph(_scaled, glyph, &ctext))
|
||||
{
|
||||
_cachedGlyphs[entry] = glyph;
|
||||
_cachedSizes[entry] = NSMakeSize(ctext.x_advance, ctext.y_advance);
|
||||
|
||||
return _cachedSizes[entry];
|
||||
return _cachedSizes[entry];
|
||||
}
|
||||
|
||||
return NSZeroSize;
|
||||
}
|
||||
|
||||
- (NSRect) boundingRectForGlyph: (NSGlyph)glyph
|
||||
{
|
||||
cairo_glyph_t cglyph;
|
||||
cairo_text_extents_t ctext;
|
||||
|
||||
cglyph = _cairo_glyph_for_NSGlyph(_scaled, glyph);
|
||||
cairo_scaled_font_glyph_extents(_scaled, &cglyph, 1, &ctext);
|
||||
if (_cairo_extents_for_NSGlyph(_scaled, glyph, &ctext))
|
||||
{
|
||||
return NSMakeRect(ctext.x_bearing, ctext.y_bearing,
|
||||
ctext.width, ctext.height);
|
||||
}
|
||||
|
||||
return NSMakeRect(ctext.x_bearing, ctext.y_bearing,
|
||||
ctext.width, ctext.height);
|
||||
return NSZeroRect;
|
||||
}
|
||||
|
||||
- (float) widthOfString: (NSString *)string
|
||||
{
|
||||
cairo_text_extents_t ctext;
|
||||
cairo_status_t status;
|
||||
cairo_glyph_t *glyphs = NULL;
|
||||
int num_glyphs;
|
||||
|
||||
status = _cairo_scaled_font_text_to_glyphs(_scaled, [string UTF8String],
|
||||
&glyphs, &num_glyphs);
|
||||
cairo_scaled_font_glyph_extents(_scaled, glyphs, num_glyphs, &ctext);
|
||||
free(glyphs);
|
||||
if (_cairo_extents_for_text(_scaled, [string UTF8String], &ctext))
|
||||
{
|
||||
return ctext.width;
|
||||
}
|
||||
|
||||
return ctext.width;
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
-(NSGlyph) glyphWithName: (NSString *) glyphName
|
||||
|
@ -265,39 +276,24 @@ cairo_glyph_t _cairo_glyph_for_NSGlyph(cairo_scaled_font_t *scaled_font, NSGlyph
|
|||
length: (int)length
|
||||
on: (cairo_t*)ct
|
||||
{
|
||||
static cairo_glyph_t *cglyphs = NULL;
|
||||
static int maxlength = 0;
|
||||
size_t i;
|
||||
cairo_text_extents_t gext;
|
||||
cairo_matrix_t font_matrix;
|
||||
double dx, dy;
|
||||
char str[length+1];
|
||||
int i;
|
||||
|
||||
cairo_get_current_point(ct, &dx, &dy);
|
||||
// FIXME: Need some adjustment here
|
||||
dy -= 5;
|
||||
|
||||
if (length > maxlength)
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
maxlength = length;
|
||||
cglyphs = realloc(cglyphs, sizeof(cairo_glyph_t) * maxlength);
|
||||
str[i] = glyphs[i];
|
||||
}
|
||||
str[length] = 0;
|
||||
|
||||
cairo_matrix_init(&font_matrix, matrix[0], matrix[1], matrix[2],
|
||||
-matrix[3], matrix[4], matrix[5]);
|
||||
cairo_set_font_face(ct, [_faceInfo fontFace]);
|
||||
cairo_set_font_matrix(ct, &font_matrix);
|
||||
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
cglyphs[i] = _cairo_glyph_for_NSGlyph(_scaled, glyphs[i]);
|
||||
cglyphs[i].x = dx;
|
||||
cglyphs[i].y = dy;
|
||||
cairo_glyph_extents(ct, cglyphs + i, 1, &gext);
|
||||
dx += gext.x_advance;
|
||||
dy += gext.y_advance;
|
||||
}
|
||||
|
||||
cairo_show_glyphs(ct, cglyphs, length);
|
||||
// FIXME: Need some adjustment here
|
||||
cairo_rel_move_to(ct, 0.0, -5.0);
|
||||
cairo_show_text(ct, str);
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -619,9 +619,25 @@ _log_matrix(cairo_t * ct)
|
|||
{
|
||||
NSAffineTransform *transform;
|
||||
NSAffineTransformStruct tstruct;
|
||||
cairo_matrix_t flip_matrix;
|
||||
|
||||
transform = [NSAffineTransform transform];
|
||||
cairo_get_matrix(_ct, &local_matrix);
|
||||
/*
|
||||
NSLog(@"Before flip %f %f, %f, %f, %f, %f", local_matrix.xx, local_matrix.yx,
|
||||
local_matrix.xy, local_matrix.yy, local_matrix.x0, local_matrix.y0);
|
||||
*/
|
||||
if (_surface)
|
||||
{
|
||||
cairo_matrix_init_translate(&flip_matrix, 0, -[_surface size].height);
|
||||
cairo_matrix_multiply(&local_matrix, &local_matrix, &flip_matrix);
|
||||
}
|
||||
cairo_matrix_init_scale(&flip_matrix, 1, -1);
|
||||
cairo_matrix_multiply(&local_matrix, &local_matrix, &flip_matrix);
|
||||
/*
|
||||
NSLog(@"After flip %f %f, %f, %f, %f, %f", local_matrix.xx, local_matrix.yx,
|
||||
local_matrix.xy, local_matrix.yy, local_matrix.x0, local_matrix.y0);
|
||||
*/
|
||||
tstruct.m11 = local_matrix.xx;
|
||||
tstruct.m12 = local_matrix.yx;
|
||||
tstruct.m21 = local_matrix.xy;
|
||||
|
@ -642,7 +658,6 @@ _log_matrix(cairo_t * ct)
|
|||
tstruct.m11, tstruct.m12,
|
||||
tstruct.m21, tstruct.m22,
|
||||
tstruct.tX, tstruct.tY);
|
||||
//cairo_set_matrix(_ct, &local_matrix);
|
||||
cairo_transform(_ct, &local_matrix);
|
||||
}
|
||||
|
||||
|
@ -1094,7 +1109,14 @@ _set_op(cairo_t * ct, NSCompositingOperation op)
|
|||
}
|
||||
|
||||
cairo_set_source_surface(_ct, surface, 0, 0);
|
||||
cairo_rectangle(_ct, 0, 0, pixelsWide, pixelsHigh);
|
||||
if (_viewIsFlipped)
|
||||
{
|
||||
cairo_rectangle(_ct, 0, -pixelsHigh, pixelsWide, pixelsHigh);
|
||||
}
|
||||
else
|
||||
{
|
||||
cairo_rectangle(_ct, 0, 0, pixelsWide, pixelsHigh);
|
||||
}
|
||||
cairo_fill(_ct);
|
||||
cairo_surface_destroy(surface);
|
||||
cairo_restore(_ct);
|
||||
|
@ -1120,6 +1142,7 @@ _set_op(cairo_t * ct, NSCompositingOperation op)
|
|||
|
||||
/*
|
||||
NSLog(NSStringFromRect(aRect));
|
||||
NSLog(NSStringFromPoint(aPoint));
|
||||
NSLog(@"src %p(%p,%@) des %p(%p,%@)",
|
||||
source,cairo_get_target(source->_ct),NSStringFromSize([source->_surface size]),
|
||||
self,cairo_get_target(_ct),NSStringFromSize([_surface size]));
|
||||
|
@ -1135,8 +1158,8 @@ _set_op(cairo_t * ct, NSCompositingOperation op)
|
|||
height = NSHeight(aRect);
|
||||
/*
|
||||
cairo_user_to_device(source->_ct, &minx, &miny);
|
||||
cairo_device_to_user(_ct, &minx, &miny);
|
||||
cairo_user_to_device_distance(source->_ct, &width, &height);
|
||||
cairo_device_to_user(_ct, &minx, &miny);
|
||||
cairo_device_to_user_distance(_ct, &width, &height);
|
||||
NSLog(@"Rect %@ = %f, %f, %f, %f", NSStringFromRect(aRect), minx, miny, width, height);
|
||||
*/
|
||||
|
|
|
@ -893,10 +893,6 @@ NSDebugLLog(@"Frame", @"X2O %d, %@, %@", win->number,
|
|||
pid_atom, XA_CARDINAL,
|
||||
32, PropModeReplace,
|
||||
(unsigned char*)&pid, 1);
|
||||
|
||||
// We should store the GNUStepMenuImage in the root window
|
||||
// and use that as our title bar icon
|
||||
// pid_atom = XInternAtom(dpy, "_NET_WM_ICON", False);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -956,6 +952,136 @@ NSDebugLLog(@"Frame", @"X2O %d, %@, %@", win->number,
|
|||
NSHeight(window->xframe));
|
||||
}
|
||||
|
||||
/*
|
||||
Code to build up a NET WM icon from our application icon
|
||||
*/
|
||||
static long *iconPropertyData;
|
||||
static int iconSize;
|
||||
static BOOL didCreateNetIcon;
|
||||
|
||||
-(int) _createNetIcon
|
||||
{
|
||||
NSImage *image;
|
||||
NSBitmapImageRep *rep;
|
||||
int i, j, w, h, samples;
|
||||
unsigned char *data;
|
||||
int index;
|
||||
|
||||
NSAssert(!didCreateNetIcon, @"called _createNetIcon twice");
|
||||
|
||||
image = [NSApp applicationIconImage];
|
||||
if (image == nil)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
didCreateNetIcon = YES;
|
||||
|
||||
rep = (NSBitmapImageRep *)[image bestRepresentationForDevice:nil];
|
||||
if (![rep isKindOfClass: [NSBitmapImageRep class]])
|
||||
{
|
||||
NSLog(@"Wrong bitmap class for WM icon %@ %@", rep, image);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ([rep bitsPerSample] != 8
|
||||
|| (![[rep colorSpaceName] isEqual: NSDeviceRGBColorSpace]
|
||||
&& ![[rep colorSpaceName] isEqual: NSCalibratedRGBColorSpace])
|
||||
|| [rep isPlanar])
|
||||
{
|
||||
NSLog(@"Wrong image type for WM icon");
|
||||
return 0;
|
||||
}
|
||||
|
||||
h = [rep pixelsHigh];
|
||||
w = [rep pixelsWide];
|
||||
samples = [rep samplesPerPixel];
|
||||
data = [rep bitmapData];
|
||||
|
||||
iconSize = 2 + w * h;
|
||||
iconPropertyData = (long *)objc_malloc(sizeof(long) * iconSize);
|
||||
if (iconPropertyData == NULL)
|
||||
{
|
||||
NSLog(@"No memory for WM icon");
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(iconPropertyData, 0, sizeof(long)*iconSize);
|
||||
index = 0;
|
||||
iconPropertyData[index++] = w;
|
||||
iconPropertyData[index++] = h;
|
||||
|
||||
for (i = 0; i < h; i++)
|
||||
{
|
||||
unsigned char *d = data;
|
||||
|
||||
for (j = 0; j < w; j++)
|
||||
{
|
||||
unsigned char A, R, G, B;
|
||||
|
||||
// red
|
||||
R = d[0];
|
||||
// green
|
||||
G = d[1];
|
||||
// blue
|
||||
B = d[2];
|
||||
// alpha
|
||||
#if 0
|
||||
/*
|
||||
For unclear reasons the alpha handling does not work, so we simulate it.
|
||||
*/
|
||||
if (samples == 4)
|
||||
{
|
||||
A = d[4];
|
||||
}
|
||||
else
|
||||
{
|
||||
A = 255;
|
||||
}
|
||||
#else
|
||||
if (R || G || B)
|
||||
{
|
||||
A = 255;
|
||||
}
|
||||
else
|
||||
{
|
||||
A = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
iconPropertyData[index++] = A << 24 | R << 16 | G << 8 | B;
|
||||
d += samples;
|
||||
}
|
||||
data += [rep bytesPerRow];
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
- (void) _setNetWMIconFor: (Window) window
|
||||
{
|
||||
// We store the GNUStepMenuImage in the window
|
||||
// and use that as our title bar icon
|
||||
static Atom icon_atom = None;
|
||||
|
||||
/* Initialize the atom if needed */
|
||||
if (icon_atom == None)
|
||||
icon_atom = XInternAtom(dpy, "_NET_WM_ICON", False);
|
||||
|
||||
if (!didCreateNetIcon)
|
||||
{
|
||||
[self _createNetIcon];
|
||||
}
|
||||
|
||||
if (iconPropertyData)
|
||||
{
|
||||
XChangeProperty(dpy, window,
|
||||
icon_atom, XA_CARDINAL,
|
||||
32, PropModeReplace,
|
||||
(unsigned char *)iconPropertyData, iconSize);
|
||||
}
|
||||
}
|
||||
|
||||
- (int) window: (NSRect)frame : (NSBackingStoreType)type : (unsigned int)style
|
||||
: (int)screen
|
||||
{
|
||||
|
@ -1071,6 +1197,11 @@ NSDebugLLog(@"Frame", @"X2O %d, %@, %@", win->number,
|
|||
setWindowHintsForStyle (dpy, window->ident, style);
|
||||
}
|
||||
|
||||
if ((generic.wm & XGWM_EWMH) != 0)
|
||||
{
|
||||
[self _setNetWMIconFor: window->ident];
|
||||
}
|
||||
|
||||
// Use the globally active input mode
|
||||
window->gen_hints.flags = InputHint;
|
||||
window->gen_hints.input = False;
|
||||
|
|
Loading…
Reference in a new issue