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:
FredKiefer 2005-11-07 00:11:09 +00:00
parent 01029229be
commit 80d261fff9
4 changed files with 221 additions and 59 deletions

View file

@ -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

View file

@ -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

View file

@ -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);
*/

View file

@ -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;