cairo drawing problem

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

cairo drawing problem

GNUstep - General mailing list

Hi all,

I have just found some time to continue testing my app(s) on GNUstep and realised that drawing OSM maps fails under GNUstep when using the cairo backend while it works if using libart.

My code draws something in a NSView subclass and then uses

         [mapView display];
         [mapView lockFocus];
         NSBitmapImageRep *rep = [[NSBitmapImageRep alloc] initWithFocusedViewRect:[mapView bounds]];
         data = [[[rep representationUsingType:NSPNGFileType properties:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:1] forKey:@"NSImageInterlaced"]] retain] autorelease];         
         if ([data length] == 0) // try TIFF instead
           {
            data = [[[rep representationUsingType:NSTIFFFileType properties:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:1] forKey:@"NSImageInterlaced"]] retain] autorelease];
            if ([data length] == 0) NSLog(@"Damn! TIFF failed as well!");
           }
         [mapView unlockFocus];

to produce a PNG from the view content. This works great with libart

art:
============================================================================

2020-06-08 19:37:18.526 ESMMapServer[10165:10165] draw way inlays... 359 _drawPrimaryInLays 1 _drawOtherInLays 1
2020-06-08 19:37:18.527 ESMMapServer[10165:10165] BUMM
2020-06-08 19:37:18.545 ESMMapServer[10165:10165] Draw 7 mapShields ...
2020-06-08 19:37:18.548 ESMMapServer[10165:10165] Draw 1 mapLocs ...
2020-06-08 19:37:18.549 ESMMapServer[10165:10165] Draw 2 mapLines ...
2020-06-08 19:37:18.549 ESMMapServer[10165:10165] <ESMMapLine: 0x2ed0550> drawLine _colorName (null) _color 0 0 1
2020-06-08 19:37:18.549 ESMMapServer[10165:10165] <ESMMapLine: 0x2ed4610> drawLine _colorName (null) _color 0 1 0
2020-06-08 19:37:18.557 ESMMapServer[10165:10165]  h=--- v=--- <ESMMapView: 0x2302ca0> f={x = 0; y = 0; width = 542; height = 620} b={x = 0; y = 0; width = 542; height = 620} locking Focus ...
2020-06-08 19:37:18.557 ESMMapServer[10165:10165] getting rep ...
2020-06-08 19:37:18.563 ESMMapServer[10165:10165] rep <NSBitmapImageRep: 0x2f15450 size: {width = 542; height = 620} pixelsWide: 542 pixelsHigh: 620 colorSpaceName: NSDeviceRGBColorSpace bps: 8>
2020-06-08 19:37:18.665 ESMMapServer[10165:10165]  h=--- v=--- <ESMMapView: 0x2302ca0> f={x = 0; y = 0; width = 542; height = 620} b={x = 0; y = 0; width = 542; height = 620} unocked Focus!
2020-06-08 19:37:18.665 ESMMapServer[10165:10165] data 248529

but fails with cairo

cairo:
=======================================================================================
2020-06-08 19:31:52.783 ESMMapServer[9982:9982] draw way inlays... 359 _drawPrimaryInLays 1 _drawOtherInLays 1
2020-06-08 19:31:52.783 ESMMapServer[9982:9982] BUMM
2020-06-08 19:31:52.798 ESMMapServer[9982:9982] Draw 8 mapShields ...
2020-06-08 19:31:52.801 ESMMapServer[9982:9982] Draw 1 mapLocs ...
2020-06-08 19:31:52.802 ESMMapServer[9982:9982] Draw 2 mapLines ...
2020-06-08 19:31:52.802 ESMMapServer[9982:9982] <ESMMapLine: 0x33b52c0> drawLine _colorName (null) _color 0 0 1
2020-06-08 19:31:52.802 ESMMapServer[9982:9982] <ESMMapLine: 0x33c3d30> drawLine _colorName (null) _color 0 1 0
2020-06-08 19:31:52.811 ESMMapServer[9982:9982]  h=--- v=--- <ESMMapView: 0x28e0fe0> f={x = 0; y = 0; width = 542; height = 620} b={x = 0; y = 0; width = 542; height = 620} locking Focus ...
2020-06-08 19:31:52.812 ESMMapServer[9982:9982] getting rep ...
2020-06-08 19:31:52.815 ESMMapServer[9982:9982] rep <NSBitmapImageRep: 0x3698ef0 size: {width = 542; height = 620} pixelsWide: 542 pixelsHigh: 620 colorSpaceName: NSDeviceRGBColorSpace bps: 8>
2020-06-08 19:31:52.882 ESMMapServer[9982:9982]  h=--- v=--- <ESMMapView: 0x28e0fe0> f={x = 0; y = 0; width = 542; height = 620} b={x = 0; y = 0; width = 542; height = 620} unocked Focus!
2020-06-08 19:31:52.883 ESMMapServer[9982:9982] data 1383
2020-06-08 19:31:52.921 ESMMapServer[9982:9982] X-Windows error - RenderBadPicture (invalid Picture parameter)
          on display: :0
                type: 0
       serial number: 1169
        request code: 139


data contains nothing reasonable after this X-WIndows error. I have attached the complete implementation of

- (NSDictionary *)PNGForMapRequestDic:(NSDictionary *)dic;

for reference below (contains the lockFocus ... unlockFocus magic). Any idea what might be causing this X-Windows error with cairo? I am stuck when it gets to backend issues. I might have to add that this error occurs in a tool (no gui app) named ESMMapServer which is supposed to produce maps (PNGs) from OSM data in the background. 

Thanks a lot,

 Andreas







- (NSDictionary *)PNGForMapRequestDic:(NSDictionary *)dic
{
   NSNumber *pixelWidth = [dic objectForKey:@"pixelWidth"];
   NSNumber *pixelHeight = [dic objectForKey:@"pixelHeight"];
   NSNumber *x = [dic objectForKey:@"x"];
   NSNumber *y = [dic objectForKey:@"y"];
   NSNumber *width = [dic objectForKey:@"width"];
   NSNumber *height = [dic objectForKey:@"height"];
   NSArray *locations = [dic objectForKey:@"locations"];
   NSArray *hintPaths = [dic objectForKey:@"hintPaths"];
   BOOL drawTextMarks = [[dic objectForKey:@"drawTextMarks"] intValue];
   NSLog(@"PNGForMapRequestDic hintPaths %d %@ %@ %@ %@ pixelWidth %@ pixelHeight %@", [hintPaths count], x, y, width, height, pixelWidth, pixelHeight);
   NSLog(@"locations %@", [locations description]);
   
   [_shields removeAllObjects];
   
   if ((pixelWidth) && (pixelHeight) && (x) && (y) && (width) && (height))
     {
      _visibleMapSection = NSMakeRect ([x floatValue], [y floatValue], [width floatValue], [height floatValue]);      
      if (_visibleMapSection.size.height > MAXESMMAPHEIGHT) // reducing map size to avoid OSMMapServer break down <-----------
        {
         NSLog(@"reducing map size to avoid OSMMapServer break down %f -> %f", _visibleMapSection.size.height, MAXESMMAPHEIGHT);
         float margin = (_visibleMapSection.size.height - MAXESMMAPHEIGHT) / 2;
         _visibleMapSection.origin.y += margin;
         _visibleMapSection.size.height = MAXESMMAPHEIGHT;
        }
      _imageSize = NSMakeSize([pixelWidth floatValue], [pixelHeight floatValue]);
      NSLog(@"_imageSize %@", NSStringFromSize(_imageSize));
      if (_imageSize.width / _imageSize.height > (_visibleMapSection.size.width * cos ((_visibleMapSection.origin.y + _visibleMapSection.size.height / 2.0) / 180.0 * 3.14)) / _visibleMapSection.size.height)
        {
         float correctedWidth = _visibleMapSection.size.height * _imageSize.width / (_imageSize.height * cos ((_visibleMapSection.origin.y + _visibleMapSection.size.height / 2.0) / 180.0 * 3.14));
         //         NSLog(@"requested width %f correctedWidth %f", _visibleMapSection.size.width, correctedWidth);
         _visibleMapSection.origin.x -= (correctedWidth - _visibleMapSection.size.width) / 2.0;
         _visibleMapSection.size.width = correctedWidth;
        }
      else
        {
         float correctedHeight = (_visibleMapSection.size.width * _imageSize.height * cos ((_visibleMapSection.origin.y + _visibleMapSection.size.height / 2.0) / 180.0 * 3.14) / _imageSize.width);
         //         NSLog(@"requested height %f correctedHeight %f", _visibleMapSection.size.height, correctedHeight);
         _visibleMapSection.origin.y -= (correctedHeight - _visibleMapSection.size.height) / 2.0;
         _visibleMapSection.size.height = correctedHeight;
        }
      NSLog(@"_visibleMapSection %@", NSStringFromRect(_visibleMapSection));
      
      NSArray *presentations = [self suitablePresentationsForRect:_visibleMapSection]; 
      //      NSLog(@"presentations %@", [presentations description]);
      NSEnumerator *enumerator = [presentations objectEnumerator];
      ESMMapPresentation *presentation;
      NSArray *highways = nil;
      NSArray *ways = nil;
      NSArray *namedNodes = nil;
      ESMMapView *mapView = nil;
      NSWindow *window = nil;                 
      
      NSLog(@"_sharedMapView %@", _sharedMapView);
      if (_sharedMapView)
        {
         mapView = (ESMMapView *)[_sharedMapView retain];
         [mapView removeAllPathsAndMapLabels];
        }
      else
        {
         window = [[NSWindow alloc] initWithContentRect:NSMakeRect(0,0, _imageSize.width, _imageSize.height) styleMask:NSBorderlessWindowMask backing:NSBackingStoreNonretained defer:NO];
         mapView = [[ESMMapView alloc] initWithFrame:NSMakeRect(0, 0, _imageSize.width, _imageSize.height)];                  
//         NSLog(@"window %@", window);                  
         //         [window setContentView:mapView];
         [[window contentView] addSubview:mapView];
         //         [window setContentSize:NSMakeSize(_imageSize.width * 0.5, _imageSize.height *0.5)];  // <--- superfluous
//         NSLog(@"mapView %@ bounds %@", NSStringFromRect([mapView frame]), NSStringFromRect([mapView bounds]));
//         NSView *clipView = [mapView superview];
//         NSLog(@"clipView %@ bounds %@", NSStringFromRect([clipView frame]), NSStringFromRect([clipView bounds]));                  
        }
      [mapView prepareOSMDrawing];
      [mapView setVisibleMapSection:_visibleMapSection]; // used to determine zoom level / how to render streets, draw labels etc.
      //      NSSize unitSize = {1.0, 1.0};
      //      [mapView scaleUnitSquareToSize:[mapView convertSize:unitSize fromView:nil]];
      
#ifdef LOADCOSTLINES      
      if (_visibleMapSection.size.height > 8.0)
        {
         if (!_roughShapeFile)
           {
            //         NSString *path = [NSBundle pathForResource:@"germany" ofType:@"shp"];
            NSString *path = [NSBundle pathForResource:@"worldland-low" ofType:@"shp"];
            NSLog(@"_roughShapeFile path %@", path);
            if (path)
              {
               _roughShapeFile = [[ESMShapeFile alloc] initWithPath:path];   
               [_roughShapeFile loadShapeFile];
              }
           }
         NSLog(@"_roughShapeFile %@ --> calcing bezierPathsForVisibleMapSectionc ...", _roughShapeFile);
         [mapView setBezierPathsForLand:[_roughShapeFile bezierPathsForVisibleMapSection:_visibleMapSection imageSize:_imageSize]];
         NSLog(@"Done");
        }
      else
        {
         if (!_fineShapeFile)
           {
            //         NSString *path = [NSBundle pathForResource:@"germany" ofType:@"shp"];
            NSString *path = [NSBundle pathForResource:@"worldland-high" ofType:@"shp"];
            NSLog(@"_fineShapeFile path %@", path);
            if (path)
              {
               _fineShapeFile = [[ESMShapeFile alloc] initWithPath:path];   
               [_fineShapeFile loadShapeFile];
              }
           }
         NSLog(@"_fineShapeFile %@ --> calcing bezierPathsForVisibleMapSectionc ...", _fineShapeFile);
         [mapView setBezierPathsForLand:[_fineShapeFile bezierPathsForVisibleMapSection:_visibleMapSection imageSize:_imageSize]];
         NSLog(@"Done");
        }
      #endif
      
      //      [mapView setDrawlInLays:[mapView heightOfVisibleMapInKm] < 5.0];      
      
      //      NSLog(@"Iterating through %d presentations ...", [presentations count]);
      while (presentation = [enumerator nextObject])
        {
         //         [mapView setDrawlInLays:[presentation shouldDrawInlays]];      
         
         // presentation returns only those ways and highways that should be drawn respecting the detail level of the presentation
         NSLog(@"Getting mapTiles ...");
         NSArray *mapTiles = [presentation mapTilesForVisibleMapSection:_visibleMapSection highways:&highways ways:&ways namedNodes:&namedNodes];
         NSLog(@"We are utilizing %d mapTiles ...", [mapTiles count]);
         
         /* *** add ESMMapLabels to mapView *** */
           {
            NSEnumerator *enumerator = [namedNodes objectEnumerator];
            KindNode *node;
            while (node = [enumerator nextObject])
              {
//               NSLog(@"Creating mapLabel for %@ %@ %@ %@", node, [node valueForKey:@"name"], [node valueForKey:@"x"], [node valueForKey:@"y"]);
               NSPoint point = [self pixelFromGPS:NSMakePoint([[node valueForKey:@"x"] floatValue], [[node valueForKey:@"y"] floatValue])];
               //               ESMMapLabel *mapLabel = [[ESMMapLabel alloc] initWithPoint:point name:[node valueForKey:@"name"] kind:[ESMMapLabel nodekindForString:[node valueForKey:@"kind"]]];
               ESMMapLabel *mapLabel = [[ESMMapLabel alloc] initWithPoint:point name:[node valueForKey:@"name"] kind:node->_kind];
               //               [mapView addMapLabel:mapLabel];
               [mapView->_mapLabels addObject:mapLabel];
               [mapLabel release];
              }
           }
         
         #ifndef BLENDAHIGHWAY                  
         
         /* *** add ESMMapPaths for the highways *** */
           {
            NSLog(@"Iterating through %d highways ...", [highways count]);
            NSEnumerator *enumerator = [highways objectEnumerator];
            Highway *highway;
            int currentKind = -1;
            NSString *currentName = nil;
            ESMMapPath *currentPath = nil;
            NSBezierPath *currentBezier = nil;
            unsigned pathCounter = 0;
            BOOL tooBigForSmallStreets = (_visibleMapSection.size.height > MAXHEIGHTFORSMALLSTREET);
            BOOL tooBigForTrunkStreets = (_visibleMapSection.size.height > MAXHEIGHTFORTRUNKSTREET);
            BOOL tooBigForSmallMotorways = (_visibleMapSection.size.height > MAXHEIGHTFORSMALLMOTORWAYS);
            //            NSLog(@"add ESMMapPaths for the highways ...");
            
            while (highway = [enumerator nextObject])
              {
               //               BOOL debug = ([highway integerForKey:@"publicID"] < 0);
               //               BOOL debug = NO;// [[highway valueForKey:@"name"] isEqualToString:@"Muellerweg"];               
               //               int kind = [ESMMapPath waykindForString:[highway valueForKey:@"highway"]];
               int kind = highway->_kind; 
               //               BOOL debug = (kind == ESMWK_MOTORWAY);               
//               NSLog(@"highway %@ kind %d", highway, kind);
               if (kind == -1 || kind == NSNotFound) continue;
               if (kind == ESMWK_UNCLASSIFIED)
                 {
                  //                  NSLog(@"ESMWK_UNCLASSIFIED highway %@", [highway valueForKey:@"publicID"]);
                 }
               if (tooBigForSmallStreets && kind > ESMWK_TERTIARY) continue;
               if (tooBigForTrunkStreets && kind > ESMWK_MOTORWAY) continue;
               NSString *ref = [highway valueForKey:@"ref"]; // <--- ???
//               BOOL debug = [ref isEqualToString:@"L 71"];
               if (tooBigForSmallMotorways && kind == ESMWK_MOTORWAY && [[(NSString *)[highway valueForKey:@"ref"] substringFromIndex:1] intValue] > 24) continue;
               if (tooBigForSmallStreets && kind == ESMWK_MOTORWAYLINK)
                 {
                  if ((highway->_rect.top - highway->_rect.bottom) / _visibleMapSection.size.height < 0.05 && (highway->_rect.right - highway->_rect.left) / _visibleMapSection.size.width < 0.05) continue;
                 }
               
               NSArray *nodesArray = [highway nodesArray];
               int i, count = [nodesArray count];
               //               NSLog(@"nodesArray count %d", count);
               if (count < 2) continue;
               
//               if (ref) NSLog(@"doll highway %@ count %d kind %d name %@ ref %@", highway, count, kind, [highway valueForKey:@"name"], ref);               
               
               NSString *name = [highway valueForKey:@"name"];
               BOOL currentPathIsClosedPath;
               NSPoint pixelStartPoint;
                             
               if (currentKind != kind || [currentName isEqualToString:highway->_sortName] == NO)
                 {
                  currentPath = [[ESMMapPath alloc] initWithKind:kind name:name];
                  //                  if (debug) NSLog(@"currentPath %@ name %@ ref %@ new currentBezier", currentPath, name, ref);
                  // [mapView addMapPath:currentPath];
                  [mapView->_mapPaths addObject:currentPath];
                  currentKind = kind;
                  //                  currentName = name;
                  currentName = highway->_sortName;
                  pathCounter++;
                  [currentPath release];
                  currentBezier = [currentPath bezierPath];
                 }
               currentPathIsClosedPath = [currentPath isClosedPath];
               
               // create label
               if (name != nil && [name length] > 0) // create MapLabel for the street name
                 {
                  BOOL drawLabel = NO;
                  
                  switch (kind) // suppress street label for very small highways
                    {
                     case ESMWK_MOTORWAY:
                     case ESMWK_TRUNK:
                     drawLabel = YES;
                     break;
                     
                     case ESMWK_PRIMARY:
                     case ESMWK_SECONDARY:
                       {
                        drawLabel = (_visibleMapSection.size.height < MAXHEIGHTFORPRIMARYLABELS);
                       }
                     break;
                     
                     default:
                     drawLabel = (_visibleMapSection.size.height < MAXHEIGHTFORSTREETLABELS);
                     break;
                    }
                  
                  if (drawLabel)
                    {
                     NSPoint firstPoint, secondPoint;
                     BOOL success = [ESMMapLabel firstPoint:&firstPoint secondPoint:&secondPoint nodes:nodesArray];
                     if (success)
                       {
                        NSPoint anchor;
                        float angle;
                        NSRect labelRect = [ESMMapLabel labelRectForString:name firstPoint:[self pixelFromGPS:firstPoint] lastPoint:[self pixelFromGPS:secondPoint] anchor:&anchor angle:&angle];
                        if (labelRect.size.width > 0)
                          {
                           ESMMapLabel *mapLabel = [[ESMMapLabel alloc] initWithPoint:anchor name:name kind:-1]; // -1 means street label
                           [mapLabel setAngle:angle];
                           [mapLabel setLabelRect:labelRect];
                           // [mapView addMapLabel:mapLabel];
                           [mapView->_mapLabels addObject:mapLabel];
                           [mapLabel release];
                          }
                        //                  else NSLog(@"%@ suppressed!", name);
                       }
                    }
                 }
               
               BOOL gotStarted = NO;
               for (i = 0 ; i < count; i++)
                 {
                  ESMNode *node = [nodesArray objectAtIndex:i]; 
                  NSPoint gpsPoint = node->_point;                  
                  NSPoint point = [self pixelFromGPS:gpsPoint];
                  
                  if (gotStarted == NO)
                    {
                     pixelStartPoint = point;
                    }
                  
                  #ifndef BLENDAWAY                  
                  if (gotStarted && ref != nil && i > 0 && ((i-1) % 5) == 0) // shield generation
                    {
                     NSEnumerator *enumerator = [_shields objectEnumerator];
                     NSDictionary *dic;
                     BOOL accept = YES;
                     
//                     if (debug) NSLog(@"check if an existingShield is too close ...");
                     // check if an existingShield is too close
                     while (dic = [enumerator nextObject])
                       {
                        NSPoint extPoint = NSPointFromString([dic objectForKey:@"point"]);
                        float dx = point.x - extPoint.x;
                        float dy = point.y - extPoint.y;
                        float r = sqrt (dx * dx + dy * dy);
                        if (r < PIXELDISTANCEBETWEENSHIELDS)
                          {
                           //                           NSLog(@"ref %@ i %d shield too close r %f / %f", ref, i, r, PIXELDISTANCEBETWEENSHIELDS);
                           accept = NO;
                           break;
                          }
                       }
//                     if (debug) NSLog(@"accept %d kind %@", accept, [ESMMapPath stringForWaykind:kind]);
                     if (accept)
                       {
                        NSColor *bezierColor = nil;
                        switch (kind)
                          {
                           case ESMWK_MOTORWAY:
                           case ESMWK_MOTORWAYLINK:
                           bezierColor = [ESMMapView motorWayColor];
                           break;
                           
                           case ESMWK_PRIMARY:
                           case ESMWK_PRIMARYLINK:
                           bezierColor = [ESMMapView primaryColor];
                           break;
                           
                           case ESMWK_TRUNK:
                           case ESMWK_TRUNKLINK:
                           bezierColor = [ESMMapView trunkColor];                                                      
                           break;
                           
                           case ESMWK_SECONDARY:
                           bezierColor = [ESMMapView secondaryShieldColor];                                                      
                           break;

                           default:
                           break;
                          }
                        //                     NSLog(@"ref %@ kind %@ %d bezierColor %@", ref, [ESMMapPath stringForWaykind:kind], kind, bezierColor);
                        #ifndef SUPPRESSSHIELDS                        
                        if (bezierColor)
                          {
                           ESMMapShield *mapShield = [[ESMMapShield alloc] initWithPoint:point ref:[ref stringAfterRemovingAllOccurencesOfString:@" "] color:bezierColor];
                           //                           NSLog(@"Adding mapShield for ref %@ at %@", ref, NSStringFromPoint(point));
                           //                           [mapView addMapShield:mapShield];
                           [mapView->_mapShields addObject:mapShield];
                           [mapShield release];                           
                           
                           NSDictionary *someDic = [[NSDictionary alloc] initWithObjectsAndKeys:NSStringFromPoint(point), @"point", ref, @"ref", nil];
                           [_shields addObject:someDic]; 
                           [someDic release];
                          }
                        #endif                        
                       }
                    }
                  #endif                  
                  
                  if (gotStarted == NO)
                    {
                     //                     if (debug) NSLog(@"moveToPoint: %@", NSStringFromPoint(point));
                     [currentBezier moveToPoint:point];               
                     gotStarted = YES;
                    }
                  else if (currentPathIsClosedPath && i == count -1)
                    {
                     //                     if (debug) NSLog(@"lineToPoint: %@", NSStringFromPoint(pixelStartPoint));
                     //                                          [currentBezier lineToPoint:pixelStartPoint]; // return to exact start point
                     [currentBezier closePath];
                    }
                  else
                    {
                     //                     if (debug) NSLog(@"lineToPoint: %@", NSStringFromPoint(point));
                     /*                     if (pixelLastPoint.x == point.x && pixelLastPoint.y == point.y)
                       {
                        //                        NSLog(@"Suppress line to same point %@ i: %d", NSStringFromPoint(point), i);
                       }
                     else*/ [currentBezier lineToPoint:point];                     
                    }
                 }
              }
           }
         #endif
         
         #ifndef BLENDAWAY         
         /* *** add ESMMapPaths for the ways (buildings ...) *** */
           {
            NSLog(@"Iterating through %d ways ...", [ways count]);
            NSEnumerator *enumerator = [ways objectEnumerator];
            Way *way;
            int currentKind = -1;
            ESMMapPath *currentPath = nil;
            NSBezierPath *currentBezier = nil;
            unsigned pathCounter = 0;
            
            while (way = [enumerator nextObject])
              {
               NSArray *nodesArray = [way nodesArray];
               NSString *name = [way valueForKey:@"name"];
//               if (name) NSLog(@"hit named way %@", name);
               int i, count = [nodesArray count];
               //               NSString *kindString = [way valueForKey:@"kind"];
               //               if (kindString == nil) { NSLog(@"way %@ has no kind!??", [way keyValueDic]); continue; }
               //               int kind = [ESMMapPath waykindForString:kindString];
               int kind = way->_kind; 
               //               NSLog(@"way %@ kind %d count %d string %@", way, kind, count, [ESMMapPath stringForWaykind:kind]);
               BOOL debug = NO;//(kind == ESMWK_BUILDING);
               //               if (debug) NSLog(@"Bumahh, encountered ESMWK_BUILDING");               
               BOOL currentPathIsClosedPath;
               NSPoint pixelStartPoint;
               
               if (kind == -1 || kind == NSNotFound) continue;
               //               if (kind == ESMWK_UNCLASSIFIED) NSLog(@"way %@", [way valueForKey:@"publicID"]);               
               
               /*#ifndef __APPLE__               
               switch (kind)
                 {
                  case ESMWK_RAILWAYCONSTRUCTION:
                  case ESMWK_RAILWAYRAIL:
                  case ESMWK_RAILWAYABANDONEDTRAM:
                  case ESMWK_RAILWAYTRAM:
                  case ESMWK_RAILWAYABANDONED:
                  case ESMWK_RAILWAYPLATFORM:
                  continue;
                  default:
                  break;
                 }
               //               if ([[kindString uppercaseString] rangeOfString:@"RAIL"].length > 0) continue;  // railways cause noise problems on GNUstep with libart             
               #endif              
               */
               
               if (currentKind != kind)
                 {
                  currentPath = [[ESMMapPath alloc] initWithKind:kind name:nil];
                  //                  if (isCoastline) NSLog(@"created currentPath %@", currentPath);
                  //                  [mapView addMapPath:currentPath];
                  [mapView->_mapPaths addObject:currentPath];
                  if (debug) NSLog(@"Added currentPath to mapPaths ...");
                  currentKind = kind;
                  pathCounter++;
                  [currentPath release];
                  currentBezier = [currentPath bezierPath];
                 }
               currentPathIsClosedPath = [currentPath isClosedPath];
               
               // handle nodes
               BOOL gotStarted = NO;
               for (i = 0 ; i < count; i++)
                 {
                  ESMNode *node = [nodesArray objectAtIndex:i];                   
                  NSPoint gpsPoint = node->_point;
                  BOOL pointVisible = NSPointInRect(gpsPoint, _visibleMapSection);
                  if (!pointVisible) // gpsPoint liegt ausserhalb von _visibleMapSection
                    {                     
                     //                     continue;
                    }
                  NSPoint point = [self pixelFromGPS:gpsPoint];                  
                  if (gotStarted == NO)
                    {
                     pixelStartPoint = point;
                    }
                  
                  if (gotStarted == NO)
                    {
                     //                     NSLog(@"moveToPoint: %@", NSStringFromPoint(point));
                     [currentBezier moveToPoint:point];               
                     gotStarted = YES;
                    }
                  else if (currentPathIsClosedPath && i == count -1)
                    {
                     //                     NSLog(@"lineToPoint: %@", NSStringFromPoint(point));
                     //                     [currentBezier lineToPoint:pixelStartPoint]; // return to exact start point
                     [currentBezier closePath];
                    }
                  else
                    {
                     //                     NSLog(@"lineToPoint: %@", NSStringFromPoint(point));
                     [currentBezier lineToPoint:point];
                    }
                 }
               
               
               
               
               // create label
               if (name != nil && [name length] > 0) // create MapLabel for the street name
                 {
                  //                  BOOL drawLabel = (_visibleMapSection.size.height < MAXHEIGHTFORPRIMARYLABELS);                  
                  BOOL drawLabel = (_visibleMapSection.size.height < MAXHEIGHTFORWAYLABELS);
//                  NSLog(@"drawLabel %d", drawLabel);
                  if (drawLabel)
                    {
                     NSPoint center = [ESMMapLabel centerPointForNodes:nodesArray];
                     ESMMapLabel *mapLabel = [[ESMMapLabel alloc] initWithPoint:[self pixelFromGPS:center] name:name kind:NODEKIND_VILLAGE]; // -1 means street label
                     NSSize size = [name sizeWithAttributes:[mapLabel attributes]];
                     [mapLabel movePointBy:NSMakePoint(-size.width / 3, 0)];                     
                     [mapLabel setAngle:0]; // angle
                     [mapView->_mapLabels addObject:mapLabel];
                     [mapLabel release];
                    }
                 }
               
               
               
               
              }                        
           }
         
         
         /* *** add ESMMapLocs to mapView *** */
           {
            NSEnumerator *enumerator = [locations objectEnumerator];
            NSDictionary *dic;
            while (dic = [enumerator nextObject])
              {
               NSString *mark = [dic objectForKey:@"mark"];              
               NSString *bitmap = [dic objectForKey:@"bitmap"];
               NSLog(@"mark %@ bitmap %@", mark, bitmap);
               NSNumber *x = [dic objectForKey:@"x"];
               NSNumber *y = [dic objectForKey:@"y"];
               NSNumber *direction = [dic objectForKey:@"direction"];
               NSLog(@"mark %@ direction %@", mark, direction);
               if ((x) && (y) && (bitmap))
                 {
                  NSPoint point = [self pixelFromGPS:NSMakePoint([x floatValue], [y floatValue])];
                  ESMMapLoc *mapLoc = [[ESMMapLoc alloc] initWithPoint:point mark:((mark) && drawTextMarks ? mark : @"P")  bitmap:bitmap];
                  //                  [mapView addMapLoc:mapLoc];
                  [mapView->_mapLocs addObject:mapLoc];
                  [mapLoc release];
                 }
              }
           }
         
         /* *** add hint paths to mapView *** */
           {
            NSEnumerator *enumerator = [hintPaths objectEnumerator];
            NSDictionary *dic;
            //            NSLog(@"add hint paths to mapView %d", [hintPaths count]);
            while (dic = [enumerator nextObject])
              {
               NSColor *color = [SRHintPath colorFromColorString:[dic objectForKey:@"colorString"]];
               BOOL drawArrows = [[dic objectForKey:@"drawArrows"] isEqualToString:@"YES"];
               NSLog(@"colorString %@ color %@ drawArrows %d", [dic objectForKey:@"colorString"], color, drawArrows);
               ESMMapLine *mapLine = ((color) ? [[ESMMapLine alloc] initWithColor:color] : [[ESMMapLine alloc] initWithColorName:[dic objectForKey:@"dominantColorName"]]);
               NSArray *nodes = [dic objectForKey:@"nodes"];
               NSEnumerator *enumerator = [nodes objectEnumerator];
               NSDictionary *dic;
               int count = [nodes count];
               int counter = 0;
               int margin = count / 10;
               if (margin == 0) margin = 1;
               while (dic = [enumerator nextObject])
                 {
                  NSNumber *x = [dic objectForKey:@"x"];
                  NSNumber *y = [dic objectForKey:@"y"];
                  if ((x) && (y))
                    {
                     NSPoint point = [self pixelFromGPS:NSMakePoint([x floatValue], [y floatValue])];
                     [mapLine addPoint:point];
                    }
                  counter++;
                  if (drawArrows && counter > margin)
                    {                  
                     [mapLine addArrow];
                     counter = 0;
                    }
                 }
               [mapView->_mapLines addObject:mapLine];
               [mapLine release];
              }
           }
         #endif          
         
        }
      if ([presentations count])
        {
         [mapView sortMapPaths];
         [mapView sortMapLabels];
        }            
      
      //      NSLog(@"going to display ...");      
      //      if (_sharedMapView) [mapView setImage:nil];
      //      NSLog(@"going to lockFocus ...");            
      //      NSLog(@"convertSize %@", NSStringFromSize([mapView convertSize:unitSize toView:nil]));
      NSData *data = nil;
      
      if (_sharedMapView)
        {
         [mapView prepareOSMDrawing];
         NSLog(@"%@ calling display ..", mapView);      
         [mapView display];
         NSLog(@"%@ display done", mapView);      
        }
      else
        {
         [mapView display];
         NS_DURING
         NSLog(@"%@ locking Focus ...", mapView);      
         [mapView lockFocus];
         NSLog(@"getting rep ...");      
         //      NSLog(@"window frame %@", NSStringFromRect([[mapView window] frame]));
         //      NSLog(@"contentView frame %@", NSStringFromRect([[[mapView window] contentView] frame]));
         //      NSLog(@"frame %@", NSStringFromRect([mapView frame]));
         //      NSLog(@"bounds %@", NSStringFromRect([mapView bounds]));
         NSBitmapImageRep *rep = [[NSBitmapImageRep alloc] initWithFocusedViewRect:[mapView bounds]];
         NSLog(@"rep %@", rep);
         data = [[[rep representationUsingType:NSPNGFileType properties:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:1] forKey:@"NSImageInterlaced"]] retain] autorelease];         
/*           {
            NSString *path = @"/home/ahoesch/A.tiff";
            NSData *data = [[[rep representationUsingType:NSTIFFFileType properties:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:1] forKey:@"NSImageInterlaced"]] retain] autorelease];
            [data writeToFile:path atomically:YES];
           }
  */       
         if ([data length] == 0) // try TIFF instead
           {
            NSLog(@"Getting PNG data failed! We try TIFF instead ...");
            //      NSData *data = [[[rep TIFFRepresentation] retain] autorelease];
            data = [[[rep representationUsingType:NSTIFFFileType properties:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:1] forKey:@"NSImageInterlaced"]] retain] autorelease];
            if ([data length] == 0) NSLog(@"Damn! TIFF failed as well!");
           }
         [mapView unlockFocus];
         NSLog(@"%@ unocked Focus!", mapView);      
         [rep release];
         NS_HANDLER
         NSLog(@"Something went terribly wrong: %@", [localException description]);
         //      NSView *clipView = [mapView superview];
         //      NSLog(@"clipView %@ bounds %@", NSStringFromRect([clipView frame]), NSStringFromRect([clipView bounds]));
         NS_ENDHANDLER
        }
      
      NSLog(@"data %d", [data length]);
      [window release];         
      [mapView release];
      return [NSDictionary dictionaryWithObjectsAndKeys:
      [NSNumber numberWithFloat:_visibleMapSection.origin.x], @"visibleMapSection.origin.x",
      [NSNumber numberWithFloat:_visibleMapSection.origin.y], @"visibleMapSection.origin.y",
      [NSNumber numberWithFloat:_visibleMapSection.size.width], @"visibleMapSection.size.width",
      [NSNumber numberWithFloat:_visibleMapSection.size.height], @"visibleMapSection.size.height",
      data, @"imageData",
      nil];
     }
   else return nil;
}




Mit freundlichen Grüßen,
 
Andreas Höschler
Managing Director
 
Smartsoft GmbH
Birkenweg 11a
D-21483 Gülzow
 
Phone  040 22820930-0
Fax      040 22820930-9
Web    http://www.smartsoft.de
Email: [hidden email]
 
Steuernummer: 44/759/00826
Amtsgericht Hamburg, HRB 117172
Geschäftsführer: Andreas Höschler

Reply | Threaded
Open this post in threaded view
|

Re: cairo drawing problem

Josh Freeman
Hi Andreas,

    Try initializing your window as NSBackingStoreBuffered?  
(NSBackingStoreNonretained tells the window to draw directly to the  
screen without buffering, so the pixel data is probably unavailable  
for reading back).

Cheers,

Josh


On Jun 8, 2020, at 1:52 PM, Andreas Höschler via Discussion list for  
the GNUstep programming environment wrote:

>
> Hi all,
>
> I have just found some time to continue testing my app(s) on GNUstep  
> and realised that drawing OSM maps fails under GNUstep when using  
> the cairo backend while it works if using libart.
>
> My code draws something in a NSView subclass and then uses
>
>          [mapView display];
>          [mapView lockFocus];
>          NSBitmapImageRep *rep = [[NSBitmapImageRep alloc]  
> initWithFocusedViewRect:[mapView bounds]];
>          data = [[[rep representationUsingType:NSPNGFileType  
> properties:[NSDictionary dictionaryWithObject:[NSNumber  
> numberWithInt:1] forKey:@"NSImageInterlaced"]] retain] autorelease];
>          if ([data length] == 0) // try TIFF instead
>            {
>             data = [[[rep representationUsingType:NSTIFFFileType  
> properties:[NSDictionary dictionaryWithObject:[NSNumber  
> numberWithInt:1] forKey:@"NSImageInterlaced"]] retain] autorelease];
>             if ([data length] == 0) NSLog(@"Damn! TIFF failed as  
> well!");
>            }
>          [mapView unlockFocus];
>
> to produce a PNG from the view content. This works great with libart
>
> art:
> =
> =
> =
> =
> =
> =
> ======================================================================
>
> 2020-06-08 19:37:18.526 ESMMapServer[10165:10165] draw way inlays...  
> 359 _drawPrimaryInLays 1 _drawOtherInLays 1
> 2020-06-08 19:37:18.527 ESMMapServer[10165:10165] BUMM
> 2020-06-08 19:37:18.545 ESMMapServer[10165:10165] Draw 7  
> mapShields ...
> 2020-06-08 19:37:18.548 ESMMapServer[10165:10165] Draw 1 mapLocs ...
> 2020-06-08 19:37:18.549 ESMMapServer[10165:10165] Draw 2 mapLines ...
> 2020-06-08 19:37:18.549 ESMMapServer[10165:10165] <ESMMapLine:  
> 0x2ed0550> drawLine _colorName (null) _color 0 0 1
> 2020-06-08 19:37:18.549 ESMMapServer[10165:10165] <ESMMapLine:  
> 0x2ed4610> drawLine _colorName (null) _color 0 1 0
> 2020-06-08 19:37:18.557 ESMMapServer[10165:10165]  h=--- v=---  
> <ESMMapView: 0x2302ca0> f={x = 0; y = 0; width = 542; height = 620}  
> b={x = 0; y = 0; width = 542; height = 620} locking Focus ...
> 2020-06-08 19:37:18.557 ESMMapServer[10165:10165] getting rep ...
> 2020-06-08 19:37:18.563 ESMMapServer[10165:10165] rep  
> <NSBitmapImageRep: 0x2f15450 size: {width = 542; height = 620}  
> pixelsWide: 542 pixelsHigh: 620 colorSpaceName:  
> NSDeviceRGBColorSpace bps: 8>
> 2020-06-08 19:37:18.665 ESMMapServer[10165:10165]  h=--- v=---  
> <ESMMapView: 0x2302ca0> f={x = 0; y = 0; width = 542; height = 620}  
> b={x = 0; y = 0; width = 542; height = 620} unocked Focus!
> 2020-06-08 19:37:18.665 ESMMapServer[10165:10165] data 248529
>
> but fails with cairo
>
> cairo:
> =
> =
> =
> =
> =
> =
> =
> =
> =
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> 2020-06-08 19:31:52.783 ESMMapServer[9982:9982] draw way inlays...  
> 359 _drawPrimaryInLays 1 _drawOtherInLays 1
> 2020-06-08 19:31:52.783 ESMMapServer[9982:9982] BUMM
> 2020-06-08 19:31:52.798 ESMMapServer[9982:9982] Draw 8 mapShields ...
> 2020-06-08 19:31:52.801 ESMMapServer[9982:9982] Draw 1 mapLocs ...
> 2020-06-08 19:31:52.802 ESMMapServer[9982:9982] Draw 2 mapLines ...
> 2020-06-08 19:31:52.802 ESMMapServer[9982:9982] <ESMMapLine:  
> 0x33b52c0> drawLine _colorName (null) _color 0 0 1
> 2020-06-08 19:31:52.802 ESMMapServer[9982:9982] <ESMMapLine:  
> 0x33c3d30> drawLine _colorName (null) _color 0 1 0
> 2020-06-08 19:31:52.811 ESMMapServer[9982:9982]  h=--- v=---  
> <ESMMapView: 0x28e0fe0> f={x = 0; y = 0; width = 542; height = 620}  
> b={x = 0; y = 0; width = 542; height = 620} locking Focus ...
> 2020-06-08 19:31:52.812 ESMMapServer[9982:9982] getting rep ...
> 2020-06-08 19:31:52.815 ESMMapServer[9982:9982] rep  
> <NSBitmapImageRep: 0x3698ef0 size: {width = 542; height = 620}  
> pixelsWide: 542 pixelsHigh: 620 colorSpaceName:  
> NSDeviceRGBColorSpace bps: 8>
> 2020-06-08 19:31:52.882 ESMMapServer[9982:9982]  h=--- v=---  
> <ESMMapView: 0x28e0fe0> f={x = 0; y = 0; width = 542; height = 620}  
> b={x = 0; y = 0; width = 542; height = 620} unocked Focus!
> 2020-06-08 19:31:52.883 ESMMapServer[9982:9982] data 1383
> 2020-06-08 19:31:52.921 ESMMapServer[9982:9982] X-Windows error -  
> RenderBadPicture (invalid Picture parameter)
>           on display: :0
>                 type: 0
>        serial number: 1169
>         request code: 139
>
>
> data contains nothing reasonable after this X-WIndows error. I have  
> attached the complete implementation of
>
> - (NSDictionary *)PNGForMapRequestDic:(NSDictionary *)dic;
>
> for reference below (contains the lockFocus ... unlockFocus magic).  
> Any idea what might be causing this X-Windows error with cairo? I am  
> stuck when it gets to backend issues. I might have to add that this  
> error occurs in a tool (no gui app) named ESMMapServer which is  
> supposed to produce maps (PNGs) from OSM data in the background.
>
> Thanks a lot,
>
>  Andreas
>
>
>
>
>
>
>
> - (NSDictionary *)PNGForMapRequestDic:(NSDictionary *)dic
> {
>    NSNumber *pixelWidth = [dic objectForKey:@"pixelWidth"];
>    NSNumber *pixelHeight = [dic objectForKey:@"pixelHeight"];
>    NSNumber *x = [dic objectForKey:@"x"];
>    NSNumber *y = [dic objectForKey:@"y"];
>    NSNumber *width = [dic objectForKey:@"width"];
>    NSNumber *height = [dic objectForKey:@"height"];
>    NSArray *locations = [dic objectForKey:@"locations"];
>    NSArray *hintPaths = [dic objectForKey:@"hintPaths"];
>    BOOL drawTextMarks = [[dic objectForKey:@"drawTextMarks"]  
> intValue];
>    NSLog(@"PNGForMapRequestDic hintPaths %d %@ %@ %@ %@ pixelWidth  
> %@ pixelHeight %@", [hintPaths count], x, y, width, height,  
> pixelWidth, pixelHeight);
>    NSLog(@"locations %@", [locations description]);
>
>    [_shields removeAllObjects];
>
>    if ((pixelWidth) && (pixelHeight) && (x) && (y) && (width) &&  
> (height))
>      {
>       _visibleMapSection = NSMakeRect ([x floatValue], [y  
> floatValue], [width floatValue], [height floatValue]);
>       if (_visibleMapSection.size.height > MAXESMMAPHEIGHT) //  
> reducing map size to avoid OSMMapServer break down <-----------
>         {
>          NSLog(@"reducing map size to avoid OSMMapServer break down  
> %f -> %f", _visibleMapSection.size.height, MAXESMMAPHEIGHT);
>          float margin = (_visibleMapSection.size.height -  
> MAXESMMAPHEIGHT) / 2;
>          _visibleMapSection.origin.y += margin;
>          _visibleMapSection.size.height = MAXESMMAPHEIGHT;
>         }
>       _imageSize = NSMakeSize([pixelWidth floatValue], [pixelHeight  
> floatValue]);
>       NSLog(@"_imageSize %@", NSStringFromSize(_imageSize));
>       if (_imageSize.width / _imageSize.height >  
> (_visibleMapSection.size.width * cos ((_visibleMapSection.origin.y +  
> _visibleMapSection.size.height / 2.0) / 180.0 * 3.14)) /  
> _visibleMapSection.size.height)
>         {
>          float correctedWidth = _visibleMapSection.size.height *  
> _imageSize.width / (_imageSize.height * cos  
> ((_visibleMapSection.origin.y + _visibleMapSection.size.height /  
> 2.0) / 180.0 * 3.14));
>          //         NSLog(@"requested width %f correctedWidth %f",  
> _visibleMapSection.size.width, correctedWidth);
>          _visibleMapSection.origin.x -= (correctedWidth -  
> _visibleMapSection.size.width) / 2.0;
>          _visibleMapSection.size.width = correctedWidth;
>         }
>       else
>         {
>          float correctedHeight = (_visibleMapSection.size.width *  
> _imageSize.height * cos ((_visibleMapSection.origin.y +  
> _visibleMapSection.size.height / 2.0) / 180.0 * 3.14) /  
> _imageSize.width);
>          //         NSLog(@"requested height %f correctedHeight %f",  
> _visibleMapSection.size.height, correctedHeight);
>          _visibleMapSection.origin.y -= (correctedHeight -  
> _visibleMapSection.size.height) / 2.0;
>          _visibleMapSection.size.height = correctedHeight;
>         }
>       NSLog(@"_visibleMapSection %@",  
> NSStringFromRect(_visibleMapSection));
>
>       NSArray *presentations = [self  
> suitablePresentationsForRect:_visibleMapSection];
>       //      NSLog(@"presentations %@", [presentations description]);
>       NSEnumerator *enumerator = [presentations objectEnumerator];
>       ESMMapPresentation *presentation;
>       NSArray *highways = nil;
>       NSArray *ways = nil;
>       NSArray *namedNodes = nil;
>       ESMMapView *mapView = nil;
>       NSWindow *window = nil;
>
>       NSLog(@"_sharedMapView %@", _sharedMapView);
>       if (_sharedMapView)
>         {
>          mapView = (ESMMapView *)[_sharedMapView retain];
>          [mapView removeAllPathsAndMapLabels];
>         }
>       else
>         {
>          window = [[NSWindow alloc]  
> initWithContentRect:NSMakeRect(0,0, _imageSize.width,  
> _imageSize.height) styleMask:NSBorderlessWindowMask  
> backing:NSBackingStoreNonretained defer:NO];
>          mapView = [[ESMMapView alloc] initWithFrame:NSMakeRect(0,  
> 0, _imageSize.width, _imageSize.height)];
> //         NSLog(@"window %@", window);
>          //         [window setContentView:mapView];
>          [[window contentView] addSubview:mapView];
>          //         [window  
> setContentSize:NSMakeSize(_imageSize.width * 0.5, _imageSize.height  
> *0.5)];  // <--- superfluous
> //         NSLog(@"mapView %@ bounds %@", NSStringFromRect([mapView  
> frame]), NSStringFromRect([mapView bounds]));
> //         NSView *clipView = [mapView superview];
> //         NSLog(@"clipView %@ bounds %@",  
> NSStringFromRect([clipView frame]), NSStringFromRect([clipView  
> bounds]));
>         }
>       [mapView prepareOSMDrawing];
>       [mapView setVisibleMapSection:_visibleMapSection]; // used to  
> determine zoom level / how to render streets, draw labels etc.
>       //      NSSize unitSize = {1.0, 1.0};
>       //      [mapView scaleUnitSquareToSize:[mapView  
> convertSize:unitSize fromView:nil]];
>
> #ifdef LOADCOSTLINES
>       if (_visibleMapSection.size.height > 8.0)
>         {
>          if (!_roughShapeFile)
>            {
>             //         NSString *path = [NSBundle  
> pathForResource:@"germany" ofType:@"shp"];
>             NSString *path = [NSBundle pathForResource:@"worldland-
> low" ofType:@"shp"];
>             NSLog(@"_roughShapeFile path %@", path);
>             if (path)
>               {
>                _roughShapeFile = [[ESMShapeFile alloc]  
> initWithPath:path];
>                [_roughShapeFile loadShapeFile];
>               }
>            }
>          NSLog(@"_roughShapeFile %@ --> calcing  
> bezierPathsForVisibleMapSectionc ...", _roughShapeFile);
>          [mapView setBezierPathsForLand:[_roughShapeFile  
> bezierPathsForVisibleMapSection:_visibleMapSection  
> imageSize:_imageSize]];
>          NSLog(@"Done");
>         }
>       else
>         {
>          if (!_fineShapeFile)
>            {
>             //         NSString *path = [NSBundle  
> pathForResource:@"germany" ofType:@"shp"];
>             NSString *path = [NSBundle pathForResource:@"worldland-
> high" ofType:@"shp"];
>             NSLog(@"_fineShapeFile path %@", path);
>             if (path)
>               {
>                _fineShapeFile = [[ESMShapeFile alloc]  
> initWithPath:path];
>                [_fineShapeFile loadShapeFile];
>               }
>            }
>          NSLog(@"_fineShapeFile %@ --> calcing  
> bezierPathsForVisibleMapSectionc ...", _fineShapeFile);
>          [mapView setBezierPathsForLand:[_fineShapeFile  
> bezierPathsForVisibleMapSection:_visibleMapSection  
> imageSize:_imageSize]];
>          NSLog(@"Done");
>         }
>       #endif
>
>       //      [mapView setDrawlInLays:[mapView  
> heightOfVisibleMapInKm] < 5.0];
>
>       //      NSLog(@"Iterating through %d presentations ...",  
> [presentations count]);
>       while (presentation = [enumerator nextObject])
>         {
>          //         [mapView setDrawlInLays:[presentation  
> shouldDrawInlays]];
>
>          // presentation returns only those ways and highways that  
> should be drawn respecting the detail level of the presentation
>          NSLog(@"Getting mapTiles ...");
>          NSArray *mapTiles = [presentation  
> mapTilesForVisibleMapSection:_visibleMapSection highways:&highways  
> ways:&ways namedNodes:&namedNodes];
>          NSLog(@"We are utilizing %d mapTiles ...", [mapTiles count]);
>
>          /* *** add ESMMapLabels to mapView *** */
>            {
>             NSEnumerator *enumerator = [namedNodes objectEnumerator];
>             KindNode *node;
>             while (node = [enumerator nextObject])
>               {
> //               NSLog(@"Creating mapLabel for %@ %@ %@ %@", node,  
> [node valueForKey:@"name"], [node valueForKey:@"x"], [node  
> valueForKey:@"y"]);
>                NSPoint point = [self pixelFromGPS:NSMakePoint([[node  
> valueForKey:@"x"] floatValue], [[node valueForKey:@"y"] floatValue])];
>                //               ESMMapLabel *mapLabel =  
> [[ESMMapLabel alloc] initWithPoint:point name:[node  
> valueForKey:@"name"] kind:[ESMMapLabel nodekindForString:[node  
> valueForKey:@"kind"]]];
>                ESMMapLabel *mapLabel = [[ESMMapLabel alloc]  
> initWithPoint:point name:[node valueForKey:@"name"] kind:node->_kind];
>                //               [mapView addMapLabel:mapLabel];
>                [mapView->_mapLabels addObject:mapLabel];
>                [mapLabel release];
>               }
>            }
>
>          #ifndef BLENDAHIGHWAY
>
>          /* *** add ESMMapPaths for the highways *** */
>            {
>             NSLog(@"Iterating through %d highways ...", [highways  
> count]);
>             NSEnumerator *enumerator = [highways objectEnumerator];
>             Highway *highway;
>             int currentKind = -1;
>             NSString *currentName = nil;
>             ESMMapPath *currentPath = nil;
>             NSBezierPath *currentBezier = nil;
>             unsigned pathCounter = 0;
>             BOOL tooBigForSmallStreets =  
> (_visibleMapSection.size.height > MAXHEIGHTFORSMALLSTREET);
>             BOOL tooBigForTrunkStreets =  
> (_visibleMapSection.size.height > MAXHEIGHTFORTRUNKSTREET);
>             BOOL tooBigForSmallMotorways =  
> (_visibleMapSection.size.height > MAXHEIGHTFORSMALLMOTORWAYS);
>             //            NSLog(@"add ESMMapPaths for the  
> highways ...");
>
>             while (highway = [enumerator nextObject])
>               {
>                //               BOOL debug = ([highway  
> integerForKey:@"publicID"] < 0);
>                //               BOOL debug = NO;// [[highway  
> valueForKey:@"name"] isEqualToString:@"Muellerweg"];
>                //               int kind = [ESMMapPath  
> waykindForString:[highway valueForKey:@"highway"]];
>                int kind = highway->_kind;
>                //               BOOL debug = (kind == ESMWK_MOTORWAY);
> //               NSLog(@"highway %@ kind %d", highway, kind);
>                if (kind == -1 || kind == NSNotFound) continue;
>                if (kind == ESMWK_UNCLASSIFIED)
>                  {
>                   //                  NSLog(@"ESMWK_UNCLASSIFIED  
> highway %@", [highway valueForKey:@"publicID"]);
>                  }
>                if (tooBigForSmallStreets && kind > ESMWK_TERTIARY)  
> continue;
>                if (tooBigForTrunkStreets && kind > ESMWK_MOTORWAY)  
> continue;
>                NSString *ref = [highway valueForKey:@"ref"]; //  
> <--- ???
> //               BOOL debug = [ref isEqualToString:@"L 71"];
>                if (tooBigForSmallMotorways && kind == ESMWK_MOTORWAY  
> && [[(NSString *)[highway valueForKey:@"ref"] substringFromIndex:1]  
> intValue] > 24) continue;
>                if (tooBigForSmallStreets && kind ==  
> ESMWK_MOTORWAYLINK)
>                  {
>                   if ((highway->_rect.top - highway->_rect.bottom) /  
> _visibleMapSection.size.height < 0.05 && (highway->_rect.right -  
> highway->_rect.left) / _visibleMapSection.size.width < 0.05) continue;
>                  }
>
>                NSArray *nodesArray = [highway nodesArray];
>                int i, count = [nodesArray count];
>                //               NSLog(@"nodesArray count %d", count);
>                if (count < 2) continue;
>
> //               if (ref) NSLog(@"doll highway %@ count %d kind %d  
> name %@ ref %@", highway, count, kind, [highway  
> valueForKey:@"name"], ref);
>
>                NSString *name = [highway valueForKey:@"name"];
>                BOOL currentPathIsClosedPath;
>                NSPoint pixelStartPoint;
>
>                if (currentKind != kind || [currentName  
> isEqualToString:highway->_sortName] == NO)
>                  {
>                   currentPath = [[ESMMapPath alloc]  
> initWithKind:kind name:name];
>                   //                  if (debug) NSLog(@"currentPath  
> %@ name %@ ref %@ new currentBezier", currentPath, name, ref);
>                   // [mapView addMapPath:currentPath];
>                   [mapView->_mapPaths addObject:currentPath];
>                   currentKind = kind;
>                   //                  currentName = name;
>                   currentName = highway->_sortName;
>                   pathCounter++;
>                   [currentPath release];
>                   currentBezier = [currentPath bezierPath];
>                  }
>                currentPathIsClosedPath = [currentPath isClosedPath];
>
>                // create label
>                if (name != nil && [name length] > 0) // create  
> MapLabel for the street name
>                  {
>                   BOOL drawLabel = NO;
>
>                   switch (kind) // suppress street label for very  
> small highways
>                     {
>                      case ESMWK_MOTORWAY:
>                      case ESMWK_TRUNK:
>                      drawLabel = YES;
>                      break;
>
>                      case ESMWK_PRIMARY:
>                      case ESMWK_SECONDARY:
>                        {
>                         drawLabel = (_visibleMapSection.size.height  
> < MAXHEIGHTFORPRIMARYLABELS);
>                        }
>                      break;
>
>                      default:
>                      drawLabel = (_visibleMapSection.size.height <  
> MAXHEIGHTFORSTREETLABELS);
>                      break;
>                     }
>
>                   if (drawLabel)
>                     {
>                      NSPoint firstPoint, secondPoint;
>                      BOOL success = [ESMMapLabel  
> firstPoint:&firstPoint secondPoint:&secondPoint nodes:nodesArray];
>                      if (success)
>                        {
>                         NSPoint anchor;
>                         float angle;
>                         NSRect labelRect = [ESMMapLabel  
> labelRectForString:name firstPoint:[self pixelFromGPS:firstPoint]  
> lastPoint:[self pixelFromGPS:secondPoint] anchor:&anchor  
> angle:&angle];
>                         if (labelRect.size.width > 0)
>                           {
>                            ESMMapLabel *mapLabel = [[ESMMapLabel  
> alloc] initWithPoint:anchor name:name kind:-1]; // -1 means street  
> label
>                            [mapLabel setAngle:angle];
>                            [mapLabel setLabelRect:labelRect];
>                            // [mapView addMapLabel:mapLabel];
>                            [mapView->_mapLabels addObject:mapLabel];
>                            [mapLabel release];
>                           }
>                         //                  else NSLog(@"%@  
> suppressed!", name);
>                        }
>                     }
>                  }
>
>                BOOL gotStarted = NO;
>                for (i = 0 ; i < count; i++)
>                  {
>                   ESMNode *node = [nodesArray objectAtIndex:i];
>                   NSPoint gpsPoint = node->_point;
>                   NSPoint point = [self pixelFromGPS:gpsPoint];
>
>                   if (gotStarted == NO)
>                     {
>                      pixelStartPoint = point;
>                     }
>
>                   #ifndef BLENDAWAY
>                   if (gotStarted && ref != nil && i > 0 && ((i-1) %  
> 5) == 0) // shield generation
>                     {
>                      NSEnumerator *enumerator = [_shields  
> objectEnumerator];
>                      NSDictionary *dic;
>                      BOOL accept = YES;
>
> //                     if (debug) NSLog(@"check if an existingShield  
> is too close ...");
>                      // check if an existingShield is too close
>                      while (dic = [enumerator nextObject])
>                        {
>                         NSPoint extPoint = NSPointFromString([dic  
> objectForKey:@"point"]);
>                         float dx = point.x - extPoint.x;
>                         float dy = point.y - extPoint.y;
>                         float r = sqrt (dx * dx + dy * dy);
>                         if (r < PIXELDISTANCEBETWEENSHIELDS)
>                           {
>                            //                           NSLog(@"ref  
> %@ i %d shield too close r %f / %f", ref, i, r,  
> PIXELDISTANCEBETWEENSHIELDS);
>                            accept = NO;
>                            break;
>                           }
>                        }
> //                     if (debug) NSLog(@"accept %d kind %@",  
> accept, [ESMMapPath stringForWaykind:kind]);
>                      if (accept)
>                        {
>                         NSColor *bezierColor = nil;
>                         switch (kind)
>                           {
>                            case ESMWK_MOTORWAY:
>                            case ESMWK_MOTORWAYLINK:
>                            bezierColor = [ESMMapView motorWayColor];
>                            break;
>
>                            case ESMWK_PRIMARY:
>                            case ESMWK_PRIMARYLINK:
>                            bezierColor = [ESMMapView primaryColor];
>                            break;
>
>                            case ESMWK_TRUNK:
>                            case ESMWK_TRUNKLINK:
>                            bezierColor = [ESMMapView trunkColor];
>                            break;
>
>                            case ESMWK_SECONDARY:
>                            bezierColor = [ESMMapView  
> secondaryShieldColor];
>                            break;
>
>                            default:
>                            break;
>                           }
>                         //                     NSLog(@"ref %@ kind  
> %@ %d bezierColor %@", ref, [ESMMapPath stringForWaykind:kind],  
> kind, bezierColor);
>                         #ifndef SUPPRESSSHIELDS
>                         if (bezierColor)
>                           {
>                            ESMMapShield *mapShield = [[ESMMapShield  
> alloc] initWithPoint:point ref:[ref  
> stringAfterRemovingAllOccurencesOfString:@" "] color:bezierColor];
>                            //                            
> NSLog(@"Adding mapShield for ref %@ at %@", ref,  
> NSStringFromPoint(point));
>                            //                           [mapView  
> addMapShield:mapShield];
>                            [mapView->_mapShields addObject:mapShield];
>                            [mapShield release];
>
>                            NSDictionary *someDic = [[NSDictionary  
> alloc] initWithObjectsAndKeys:NSStringFromPoint(point), @"point",  
> ref, @"ref", nil];
>                            [_shields addObject:someDic];
>                            [someDic release];
>                           }
>                         #endif
>                        }
>                     }
>                   #endif
>
>                   if (gotStarted == NO)
>                     {
>                      //                     if (debug)  
> NSLog(@"moveToPoint: %@", NSStringFromPoint(point));
>                      [currentBezier moveToPoint:point];
>                      gotStarted = YES;
>                     }
>                   else if (currentPathIsClosedPath && i == count -1)
>                     {
>                      //                     if (debug)  
> NSLog(@"lineToPoint: %@", NSStringFromPoint(pixelStartPoint));
>                      //                                          
> [currentBezier lineToPoint:pixelStartPoint]; // return to exact  
> start point
>                      [currentBezier closePath];
>                     }
>                   else
>                     {
>                      //                     if (debug)  
> NSLog(@"lineToPoint: %@", NSStringFromPoint(point));
>                      /*                     if (pixelLastPoint.x ==  
> point.x && pixelLastPoint.y == point.y)
>                        {
>                         //                        NSLog(@"Suppress  
> line to same point %@ i: %d", NSStringFromPoint(point), i);
>                        }
>                      else*/ [currentBezier lineToPoint:point];
>                     }
>                  }
>               }
>            }
>          #endif
>
>          #ifndef BLENDAWAY
>          /* *** add ESMMapPaths for the ways (buildings ...) *** */
>            {
>             NSLog(@"Iterating through %d ways ...", [ways count]);
>             NSEnumerator *enumerator = [ways objectEnumerator];
>             Way *way;
>             int currentKind = -1;
>             ESMMapPath *currentPath = nil;
>             NSBezierPath *currentBezier = nil;
>             unsigned pathCounter = 0;
>
>             while (way = [enumerator nextObject])
>               {
>                NSArray *nodesArray = [way nodesArray];
>                NSString *name = [way valueForKey:@"name"];
> //               if (name) NSLog(@"hit named way %@", name);
>                int i, count = [nodesArray count];
>                //               NSString *kindString = [way  
> valueForKey:@"kind"];
>                //               if (kindString == nil) { NSLog(@"way  
> %@ has no kind!??", [way keyValueDic]); continue; }
>                //               int kind = [ESMMapPath  
> waykindForString:kindString];
>                int kind = way->_kind;
>                //               NSLog(@"way %@ kind %d count %d  
> string %@", way, kind, count, [ESMMapPath stringForWaykind:kind]);
>                BOOL debug = NO;//(kind == ESMWK_BUILDING);
>                //               if (debug) NSLog(@"Bumahh,  
> encountered ESMWK_BUILDING");
>                BOOL currentPathIsClosedPath;
>                NSPoint pixelStartPoint;
>
>                if (kind == -1 || kind == NSNotFound) continue;
>                //               if (kind == ESMWK_UNCLASSIFIED)  
> NSLog(@"way %@", [way valueForKey:@"publicID"]);
>
>                /*#ifndef __APPLE__
>                switch (kind)
>                  {
>                   case ESMWK_RAILWAYCONSTRUCTION:
>                   case ESMWK_RAILWAYRAIL:
>                   case ESMWK_RAILWAYABANDONEDTRAM:
>                   case ESMWK_RAILWAYTRAM:
>                   case ESMWK_RAILWAYABANDONED:
>                   case ESMWK_RAILWAYPLATFORM:
>                   continue;
>                   default:
>                   break;
>                  }
>                //               if ([[kindString uppercaseString]  
> rangeOfString:@"RAIL"].length > 0) continue;  // railways cause  
> noise problems on GNUstep with libart
>                #endif
>                */
>
>                if (currentKind != kind)
>                  {
>                   currentPath = [[ESMMapPath alloc]  
> initWithKind:kind name:nil];
>                   //                  if (isCoastline)  
> NSLog(@"created currentPath %@", currentPath);
>                   //                  [mapView  
> addMapPath:currentPath];
>                   [mapView->_mapPaths addObject:currentPath];
>                   if (debug) NSLog(@"Added currentPath to  
> mapPaths ...");
>                   currentKind = kind;
>                   pathCounter++;
>                   [currentPath release];
>                   currentBezier = [currentPath bezierPath];
>                  }
>                currentPathIsClosedPath = [currentPath isClosedPath];
>
>                // handle nodes
>                BOOL gotStarted = NO;
>                for (i = 0 ; i < count; i++)
>                  {
>                   ESMNode *node = [nodesArray objectAtIndex:i];
>                   NSPoint gpsPoint = node->_point;
>                   BOOL pointVisible = NSPointInRect(gpsPoint,  
> _visibleMapSection);
>                   if (!pointVisible) // gpsPoint liegt ausserhalb  
> von _visibleMapSection
>                     {
>                      //                     continue;
>                     }
>                   NSPoint point = [self pixelFromGPS:gpsPoint];
>                   if (gotStarted == NO)
>                     {
>                      pixelStartPoint = point;
>                     }
>
>                   if (gotStarted == NO)
>                     {
>                      //                     NSLog(@"moveToPoint:  
> %@", NSStringFromPoint(point));
>                      [currentBezier moveToPoint:point];
>                      gotStarted = YES;
>                     }
>                   else if (currentPathIsClosedPath && i == count -1)
>                     {
>                      //                     NSLog(@"lineToPoint:  
> %@", NSStringFromPoint(point));
>                      //                     [currentBezier  
> lineToPoint:pixelStartPoint]; // return to exact start point
>                      [currentBezier closePath];
>                     }
>                   else
>                     {
>                      //                     NSLog(@"lineToPoint:  
> %@", NSStringFromPoint(point));
>                      [currentBezier lineToPoint:point];
>                     }
>                  }
>
>
>
>
>                // create label
>                if (name != nil && [name length] > 0) // create  
> MapLabel for the street name
>                  {
>                   //                  BOOL drawLabel =  
> (_visibleMapSection.size.height < MAXHEIGHTFORPRIMARYLABELS);
>                   BOOL drawLabel = (_visibleMapSection.size.height <  
> MAXHEIGHTFORWAYLABELS);
> //                  NSLog(@"drawLabel %d", drawLabel);
>                   if (drawLabel)
>                     {
>                      NSPoint center = [ESMMapLabel  
> centerPointForNodes:nodesArray];
>                      ESMMapLabel *mapLabel = [[ESMMapLabel alloc]  
> initWithPoint:[self pixelFromGPS:center] name:name  
> kind:NODEKIND_VILLAGE]; // -1 means street label
>                      NSSize size = [name sizeWithAttributes:
> [mapLabel attributes]];
>                      [mapLabel movePointBy:NSMakePoint(-size.width /  
> 3, 0)];
>                      [mapLabel setAngle:0]; // angle
>                      [mapView->_mapLabels addObject:mapLabel];
>                      [mapLabel release];
>                     }
>                  }
>
>
>
>
>               }
>            }
>
>
>          /* *** add ESMMapLocs to mapView *** */
>            {
>             NSEnumerator *enumerator = [locations objectEnumerator];
>             NSDictionary *dic;
>             while (dic = [enumerator nextObject])
>               {
>                NSString *mark = [dic objectForKey:@"mark"];
>                NSString *bitmap = [dic objectForKey:@"bitmap"];
>                NSLog(@"mark %@ bitmap %@", mark, bitmap);
>                NSNumber *x = [dic objectForKey:@"x"];
>                NSNumber *y = [dic objectForKey:@"y"];
>                NSNumber *direction = [dic objectForKey:@"direction"];
>                NSLog(@"mark %@ direction %@", mark, direction);
>                if ((x) && (y) && (bitmap))
>                  {
>                   NSPoint point = [self pixelFromGPS:NSMakePoint([x  
> floatValue], [y floatValue])];
>                   ESMMapLoc *mapLoc = [[ESMMapLoc alloc]  
> initWithPoint:point mark:((mark) && drawTextMarks ? mark : @"P")  
> bitmap:bitmap];
>                   //                  [mapView addMapLoc:mapLoc];
>                   [mapView->_mapLocs addObject:mapLoc];
>                   [mapLoc release];
>                  }
>               }
>            }
>
>          /* *** add hint paths to mapView *** */
>            {
>             NSEnumerator *enumerator = [hintPaths objectEnumerator];
>             NSDictionary *dic;
>             //            NSLog(@"add hint paths to mapView %d",  
> [hintPaths count]);
>             while (dic = [enumerator nextObject])
>               {
>                NSColor *color = [SRHintPath colorFromColorString:
> [dic objectForKey:@"colorString"]];
>                BOOL drawArrows = [[dic objectForKey:@"drawArrows"]  
> isEqualToString:@"YES"];
>                NSLog(@"colorString %@ color %@ drawArrows %d", [dic  
> objectForKey:@"colorString"], color, drawArrows);
>                ESMMapLine *mapLine = ((color) ? [[ESMMapLine alloc]  
> initWithColor:color] : [[ESMMapLine alloc] initWithColorName:[dic  
> objectForKey:@"dominantColorName"]]);
>                NSArray *nodes = [dic objectForKey:@"nodes"];
>                NSEnumerator *enumerator = [nodes objectEnumerator];
>                NSDictionary *dic;
>                int count = [nodes count];
>                int counter = 0;
>                int margin = count / 10;
>                if (margin == 0) margin = 1;
>                while (dic = [enumerator nextObject])
>                  {
>                   NSNumber *x = [dic objectForKey:@"x"];
>                   NSNumber *y = [dic objectForKey:@"y"];
>                   if ((x) && (y))
>                     {
>                      NSPoint point = [self  
> pixelFromGPS:NSMakePoint([x floatValue], [y floatValue])];
>                      [mapLine addPoint:point];
>                     }
>                   counter++;
>                   if (drawArrows && counter > margin)
>                     {
>                      [mapLine addArrow];
>                      counter = 0;
>                     }
>                  }
>                [mapView->_mapLines addObject:mapLine];
>                [mapLine release];
>               }
>            }
>          #endif
>
>         }
>       if ([presentations count])
>         {
>          [mapView sortMapPaths];
>          [mapView sortMapLabels];
>         }
>
>       //      NSLog(@"going to display ...");
>       //      if (_sharedMapView) [mapView setImage:nil];
>       //      NSLog(@"going to lockFocus ...");
>       //      NSLog(@"convertSize %@", NSStringFromSize([mapView  
> convertSize:unitSize toView:nil]));
>       NSData *data = nil;
>
>       if (_sharedMapView)
>         {
>          [mapView prepareOSMDrawing];
>          NSLog(@"%@ calling display ..", mapView);
>          [mapView display];
>          NSLog(@"%@ display done", mapView);
>         }
>       else
>         {
>          [mapView display];
>          NS_DURING
>          NSLog(@"%@ locking Focus ...", mapView);
>          [mapView lockFocus];
>          NSLog(@"getting rep ...");
>          //      NSLog(@"window frame %@",  
> NSStringFromRect([[mapView window] frame]));
>          //      NSLog(@"contentView frame %@",  
> NSStringFromRect([[[mapView window] contentView] frame]));
>          //      NSLog(@"frame %@", NSStringFromRect([mapView  
> frame]));
>          //      NSLog(@"bounds %@", NSStringFromRect([mapView  
> bounds]));
>          NSBitmapImageRep *rep = [[NSBitmapImageRep alloc]  
> initWithFocusedViewRect:[mapView bounds]];
>          NSLog(@"rep %@", rep);
>          data = [[[rep representationUsingType:NSPNGFileType  
> properties:[NSDictionary dictionaryWithObject:[NSNumber  
> numberWithInt:1] forKey:@"NSImageInterlaced"]] retain] autorelease];
> /*           {
>             NSString *path = @"/home/ahoesch/A.tiff";
>             NSData *data = [[[rep  
> representationUsingType:NSTIFFFileType properties:[NSDictionary  
> dictionaryWithObject:[NSNumber numberWithInt:1]  
> forKey:@"NSImageInterlaced"]] retain] autorelease];
>             [data writeToFile:path atomically:YES];
>            }
>   */
>          if ([data length] == 0) // try TIFF instead
>            {
>             NSLog(@"Getting PNG data failed! We try TIFF  
> instead ...");
>             //      NSData *data = [[[rep TIFFRepresentation]  
> retain] autorelease];
>             data = [[[rep representationUsingType:NSTIFFFileType  
> properties:[NSDictionary dictionaryWithObject:[NSNumber  
> numberWithInt:1] forKey:@"NSImageInterlaced"]] retain] autorelease];
>             if ([data length] == 0) NSLog(@"Damn! TIFF failed as  
> well!");
>            }
>          [mapView unlockFocus];
>          NSLog(@"%@ unocked Focus!", mapView);
>          [rep release];
>          NS_HANDLER
>          NSLog(@"Something went terribly wrong: %@", [localException  
> description]);
>          //      NSView *clipView = [mapView superview];
>          //      NSLog(@"clipView %@ bounds %@",  
> NSStringFromRect([clipView frame]), NSStringFromRect([clipView  
> bounds]));
>          NS_ENDHANDLER
>         }
>
>       NSLog(@"data %d", [data length]);
>       [window release];
>       [mapView release];
>       return [NSDictionary dictionaryWithObjectsAndKeys:
>       [NSNumber numberWithFloat:_visibleMapSection.origin.x],  
> @"visibleMapSection.origin.x",
>       [NSNumber numberWithFloat:_visibleMapSection.origin.y],  
> @"visibleMapSection.origin.y",
>       [NSNumber numberWithFloat:_visibleMapSection.size.width],  
> @"visibleMapSection.size.width",
>       [NSNumber numberWithFloat:_visibleMapSection.size.height],  
> @"visibleMapSection.size.height",
>       data, @"imageData",
>       nil];
>      }
>    else return nil;
> }
>
>
>
>
> Mit freundlichen Grüßen,
>
> Andreas Höschler
> Managing Director
>
> Smartsoft GmbH
> Birkenweg 11a
> D-21483 Gülzow
>
> Phone  040 22820930-0
> Fax      040 22820930-9
> Web    http://www.smartsoft.de
> Email: [hidden email]
>
> Steuernummer: 44/759/00826
> Amtsgericht Hamburg, HRB 117172
> Geschäftsführer: Andreas Höschler
>


Reply | Threaded
Open this post in threaded view
|

Re: cairo drawing problem

Fred Kiefer
Hi Andreas,

I did not get your original mail and it isn’t even in my spam folder where your previous mails.

> Am 11.06.2020 um 00:05 schrieb Josh Freeman <[hidden email]>:
>
>   Try initializing your window as NSBackingStoreBuffered? (NSBackingStoreNonretained tells the window to draw directly to the screen without buffering, so the pixel data is probably unavailable for reading back).

This might help but I really would like to understand where the issue comes from in the first place.

Looking at the code and the output below the first thing I notice is that the X error happens after the extraction of the view data into the bitmap image was finished. The most likely scenario is that the data we extracted is somehow invalid. That would fit in wit your suggested work around.

But all of this is just blind guessing, what we need here is example code that allows to reproduce this issue with GNUstep classes only.

Andreas, could you please strip down your application to pure GNUstep and if that still displays the error send out that code?

Cheers,
Fred

> On Jun 8, 2020, at 1:52 PM, Andreas Höschler via Discussion list for the GNUstep programming environment wrote:
>
>>
>> Hi all,
>>
>> I have just found some time to continue testing my app(s) on GNUstep and realised that drawing OSM maps fails under GNUstep when using the cairo backend while it works if using libart.
>>
>> My code draws something in a NSView subclass and then uses
>>
>>         [mapView display];
>>         [mapView lockFocus];
>>         NSBitmapImageRep *rep = [[NSBitmapImageRep alloc] initWithFocusedViewRect:[mapView bounds]];
>>         data = [[[rep representationUsingType:NSPNGFileType properties:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:1] forKey:@"NSImageInterlaced"]] retain] autorelease];
>>         if ([data length] == 0) // try TIFF instead
>>           {
>>            data = [[[rep representationUsingType:NSTIFFFileType properties:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:1] forKey:@"NSImageInterlaced"]] retain] autorelease];
>>            if ([data length] == 0) NSLog(@"Damn! TIFF failed as well!");
>>           }
>>         [mapView unlockFocus];
>>
>> to produce a PNG from the view content. This works great with libart
>>
>> art:
>> ============================================================================
>>
>> 2020-06-08 19:37:18.526 ESMMapServer[10165:10165] draw way inlays... 359 _drawPrimaryInLays 1 _drawOtherInLays 1
>> 2020-06-08 19:37:18.527 ESMMapServer[10165:10165] BUMM
>> 2020-06-08 19:37:18.545 ESMMapServer[10165:10165] Draw 7 mapShields ...
>> 2020-06-08 19:37:18.548 ESMMapServer[10165:10165] Draw 1 mapLocs ...
>> 2020-06-08 19:37:18.549 ESMMapServer[10165:10165] Draw 2 mapLines ...
>> 2020-06-08 19:37:18.549 ESMMapServer[10165:10165] <ESMMapLine: 0x2ed0550> drawLine _colorName (null) _color 0 0 1
>> 2020-06-08 19:37:18.549 ESMMapServer[10165:10165] <ESMMapLine: 0x2ed4610> drawLine _colorName (null) _color 0 1 0
>> 2020-06-08 19:37:18.557 ESMMapServer[10165:10165]  h=--- v=--- <ESMMapView: 0x2302ca0> f={x = 0; y = 0; width = 542; height = 620} b={x = 0; y = 0; width = 542; height = 620} locking Focus ...
>> 2020-06-08 19:37:18.557 ESMMapServer[10165:10165] getting rep ...
>> 2020-06-08 19:37:18.563 ESMMapServer[10165:10165] rep <NSBitmapImageRep: 0x2f15450 size: {width = 542; height = 620} pixelsWide: 542 pixelsHigh: 620 colorSpaceName: NSDeviceRGBColorSpace bps: 8>
>> 2020-06-08 19:37:18.665 ESMMapServer[10165:10165]  h=--- v=--- <ESMMapView: 0x2302ca0> f={x = 0; y = 0; width = 542; height = 620} b={x = 0; y = 0; width = 542; height = 620} unocked Focus!
>> 2020-06-08 19:37:18.665 ESMMapServer[10165:10165] data 248529
>>
>> but fails with cairo
>>
>> cairo:
>> =======================================================================================
>> 2020-06-08 19:31:52.783 ESMMapServer[9982:9982] draw way inlays... 359 _drawPrimaryInLays 1 _drawOtherInLays 1
>> 2020-06-08 19:31:52.783 ESMMapServer[9982:9982] BUMM
>> 2020-06-08 19:31:52.798 ESMMapServer[9982:9982] Draw 8 mapShields ...
>> 2020-06-08 19:31:52.801 ESMMapServer[9982:9982] Draw 1 mapLocs ...
>> 2020-06-08 19:31:52.802 ESMMapServer[9982:9982] Draw 2 mapLines ...
>> 2020-06-08 19:31:52.802 ESMMapServer[9982:9982] <ESMMapLine: 0x33b52c0> drawLine _colorName (null) _color 0 0 1
>> 2020-06-08 19:31:52.802 ESMMapServer[9982:9982] <ESMMapLine: 0x33c3d30> drawLine _colorName (null) _color 0 1 0
>> 2020-06-08 19:31:52.811 ESMMapServer[9982:9982]  h=--- v=--- <ESMMapView: 0x28e0fe0> f={x = 0; y = 0; width = 542; height = 620} b={x = 0; y = 0; width = 542; height = 620} locking Focus ...
>> 2020-06-08 19:31:52.812 ESMMapServer[9982:9982] getting rep ...
>> 2020-06-08 19:31:52.815 ESMMapServer[9982:9982] rep <NSBitmapImageRep: 0x3698ef0 size: {width = 542; height = 620} pixelsWide: 542 pixelsHigh: 620 colorSpaceName: NSDeviceRGBColorSpace bps: 8>
>> 2020-06-08 19:31:52.882 ESMMapServer[9982:9982]  h=--- v=--- <ESMMapView: 0x28e0fe0> f={x = 0; y = 0; width = 542; height = 620} b={x = 0; y = 0; width = 542; height = 620} unocked Focus!
>> 2020-06-08 19:31:52.883 ESMMapServer[9982:9982] data 1383
>> 2020-06-08 19:31:52.921 ESMMapServer[9982:9982] X-Windows error - RenderBadPicture (invalid Picture parameter)
>>          on display: :0
>>                type: 0
>>       serial number: 1169
>>        request code: 139
>>
>>
>> data contains nothing reasonable after this X-WIndows error. I have attached the complete implementation of
>>
>> - (NSDictionary *)PNGForMapRequestDic:(NSDictionary *)dic;
>>
>> for reference below (contains the lockFocus ... unlockFocus magic). Any idea what might be causing this X-Windows error with cairo? I am stuck when it gets to backend issues. I might have to add that this error occurs in a tool (no gui app) named ESMMapServer which is supposed to produce maps (PNGs) from OSM data in the background.
>>
>> Thanks a lot,
>>
>> Andreas
>>
>>
>>
>>
>>
>>
>>
>> - (NSDictionary *)PNGForMapRequestDic:(NSDictionary *)dic
>> {
>>   NSNumber *pixelWidth = [dic objectForKey:@"pixelWidth"];
>>   NSNumber *pixelHeight = [dic objectForKey:@"pixelHeight"];
>>   NSNumber *x = [dic objectForKey:@"x"];
>>   NSNumber *y = [dic objectForKey:@"y"];
>>   NSNumber *width = [dic objectForKey:@"width"];
>>   NSNumber *height = [dic objectForKey:@"height"];
>>   NSArray *locations = [dic objectForKey:@"locations"];
>>   NSArray *hintPaths = [dic objectForKey:@"hintPaths"];
>>   BOOL drawTextMarks = [[dic objectForKey:@"drawTextMarks"] intValue];
>>   NSLog(@"PNGForMapRequestDic hintPaths %d %@ %@ %@ %@ pixelWidth %@ pixelHeight %@", [hintPaths count], x, y, width, height, pixelWidth, pixelHeight);
>>   NSLog(@"locations %@", [locations description]);
>>
>>   [_shields removeAllObjects];
>>
>>   if ((pixelWidth) && (pixelHeight) && (x) && (y) && (width) && (height))
>>     {
>>      _visibleMapSection = NSMakeRect ([x floatValue], [y floatValue], [width floatValue], [height floatValue]);
>>      if (_visibleMapSection.size.height > MAXESMMAPHEIGHT) // reducing map size to avoid OSMMapServer break down <-----------
>>        {
>>         NSLog(@"reducing map size to avoid OSMMapServer break down %f -> %f", _visibleMapSection.size.height, MAXESMMAPHEIGHT);
>>         float margin = (_visibleMapSection.size.height - MAXESMMAPHEIGHT) / 2;
>>         _visibleMapSection.origin.y += margin;
>>         _visibleMapSection.size.height = MAXESMMAPHEIGHT;
>>        }
>>      _imageSize = NSMakeSize([pixelWidth floatValue], [pixelHeight floatValue]);
>>      NSLog(@"_imageSize %@", NSStringFromSize(_imageSize));
>>      if (_imageSize.width / _imageSize.height > (_visibleMapSection.size.width * cos ((_visibleMapSection.origin.y + _visibleMapSection.size.height / 2.0) / 180.0 * 3.14)) / _visibleMapSection.size.height)
>>        {
>>         float correctedWidth = _visibleMapSection.size.height * _imageSize.width / (_imageSize.height * cos ((_visibleMapSection.origin.y + _visibleMapSection.size.height / 2.0) / 180.0 * 3.14));
>>         //         NSLog(@"requested width %f correctedWidth %f", _visibleMapSection.size.width, correctedWidth);
>>         _visibleMapSection.origin.x -= (correctedWidth - _visibleMapSection.size.width) / 2.0;
>>         _visibleMapSection.size.width = correctedWidth;
>>        }
>>      else
>>        {
>>         float correctedHeight = (_visibleMapSection.size.width * _imageSize.height * cos ((_visibleMapSection.origin.y + _visibleMapSection.size.height / 2.0) / 180.0 * 3.14) / _imageSize.width);
>>         //         NSLog(@"requested height %f correctedHeight %f", _visibleMapSection.size.height, correctedHeight);
>>         _visibleMapSection.origin.y -= (correctedHeight - _visibleMapSection.size.height) / 2.0;
>>         _visibleMapSection.size.height = correctedHeight;
>>        }
>>      NSLog(@"_visibleMapSection %@", NSStringFromRect(_visibleMapSection));
>>
>>      NSArray *presentations = [self suitablePresentationsForRect:_visibleMapSection];
>>      //      NSLog(@"presentations %@", [presentations description]);
>>      NSEnumerator *enumerator = [presentations objectEnumerator];
>>      ESMMapPresentation *presentation;
>>      NSArray *highways = nil;
>>      NSArray *ways = nil;
>>      NSArray *namedNodes = nil;
>>      ESMMapView *mapView = nil;
>>      NSWindow *window = nil;
>>
>>      NSLog(@"_sharedMapView %@", _sharedMapView);
>>      if (_sharedMapView)
>>        {
>>         mapView = (ESMMapView *)[_sharedMapView retain];
>>         [mapView removeAllPathsAndMapLabels];
>>        }
>>      else
>>        {
>>         window = [[NSWindow alloc] initWithContentRect:NSMakeRect(0,0, _imageSize.width, _imageSize.height) styleMask:NSBorderlessWindowMask backing:NSBackingStoreNonretained defer:NO];
>>         mapView = [[ESMMapView alloc] initWithFrame:NSMakeRect(0, 0, _imageSize.width, _imageSize.height)];

<a lot of unrelated code removed>

>>      NSData *data = nil;
>>
>>      if (_sharedMapView)
>>        {
>>         [mapView prepareOSMDrawing];
>>         NSLog(@"%@ calling display ..", mapView);
>>         [mapView display];
>>         NSLog(@"%@ display done", mapView);
>>        }
>>      else
>>        {
>>         [mapView display];
>>         NS_DURING
>>         NSLog(@"%@ locking Focus ...", mapView);
>>         [mapView lockFocus];
>>         NSLog(@"getting rep ...");
>>         //      NSLog(@"window frame %@", NSStringFromRect([[mapView window] frame]));
>>         //      NSLog(@"contentView frame %@", NSStringFromRect([[[mapView window] contentView] frame]));
>>         //      NSLog(@"frame %@", NSStringFromRect([mapView frame]));
>>         //      NSLog(@"bounds %@", NSStringFromRect([mapView bounds]));
>>         NSBitmapImageRep *rep = [[NSBitmapImageRep alloc] initWithFocusedViewRect:[mapView bounds]];
>>         NSLog(@"rep %@", rep);
>>         data = [[[rep representationUsingType:NSPNGFileType properties:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:1] forKey:@"NSImageInterlaced"]] retain] autorelease];
>> /*           {
>>            NSString *path = @"/home/ahoesch/A.tiff";
>>            NSData *data = [[[rep representationUsingType:NSTIFFFileType properties:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:1] forKey:@"NSImageInterlaced"]] retain] autorelease];
>>            [data writeToFile:path atomically:YES];
>>           }
>>  */
>>         if ([data length] == 0) // try TIFF instead
>>           {
>>            NSLog(@"Getting PNG data failed! We try TIFF instead ...");
>>            //      NSData *data = [[[rep TIFFRepresentation] retain] autorelease];
>>            data = [[[rep representationUsingType:NSTIFFFileType properties:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:1] forKey:@"NSImageInterlaced"]] retain] autorelease];
>>            if ([data length] == 0) NSLog(@"Damn! TIFF failed as well!");
>>           }
>>         [mapView unlockFocus];
>>         NSLog(@"%@ unocked Focus!", mapView);
>>         [rep release];
>>         NS_HANDLER
>>         NSLog(@"Something went terribly wrong: %@", [localException description]);
>>         //      NSView *clipView = [mapView superview];
>>         //      NSLog(@"clipView %@ bounds %@", NSStringFromRect([clipView frame]), NSStringFromRect([clipView bounds]));
>>         NS_ENDHANDLER
>>        }
>>
>>      NSLog(@"data %d", [data length]);
>>      [window release];
>>      [mapView release];
>>      return [NSDictionary dictionaryWithObjectsAndKeys:
>>      [NSNumber numberWithFloat:_visibleMapSection.origin.x], @"visibleMapSection.origin.x",
>>      [NSNumber numberWithFloat:_visibleMapSection.origin.y], @"visibleMapSection.origin.y",
>>      [NSNumber numberWithFloat:_visibleMapSection.size.width], @"visibleMapSection.size.width",
>>      [NSNumber numberWithFloat:_visibleMapSection.size.height], @"visibleMapSection.size.height",
>>      data, @"imageData",
>>      nil];
>>     }
>>   else return nil;
>> }
>>

Reply | Threaded
Open this post in threaded view
|

RE: cairo drawing problem

Ivan Vučica

Hi Andreas,

 

My first instinct is ‘are you releasing some internal object loaned to you, which you never retained’.

 

My cleanup didn’t reveal anything particular, but:

 

NSBitmapImageRep *rep = [[NSBitmapImageRep alloc] initWithFocusedViewRect:[mapView bounds]];

NSDictionary * props = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:1]

                                                   forKey:@"NSImageInterlaced"];

NSData * repData = [rep representationUsingType:NSPNGFileType

                                    properties:props]

NSData * data = [[repData retain] autorelease];

 

Note that the autoreleased repData is retained and then autoreleased (meaning the same object is put onto the autorelease queue twice)

 

Then I saw the rest of the code you attached. My thought goes in the direction of ‘_sharedMapView’-related code. Even though you’re allocating a whole new window only when the map view is not shared, you seem to be releasing window unconditionally.

 

Based on the output, I’m concluding you are running with _sharedMapView==NO and thus releasing the mapview and window incorrectly which possibly results in an X drawable being destroyed while still in use.

 

Some suggestions:

- start the program with GDB and put a breakpoint on the lines mentioning “X-Window error” in libs-back?

  - In the current code, I found these in only one file: https://github.com/gnustep/libs-back/blob/2a0e305a4f3ec93c00a96a13838877c9543449a9/Source/x11/XGServerEvent.m line 206 and 216. Based on the output, I’d expect it’s enough to put it on line 206 (the NSLog instead of the NSException).

- split up the function: while there may be valid reasons to have really long functions, this is not one of them and it’s hard to read and understand what’s going on

  - if you had a “draw into view” function (which should really be implemented inside the mapview class itself), separate from window allocation and release (or use of shared window and mapview), you’d have spotted that the alloc/new/retain/release don’t match

- provide a truly minimal example

  - if you would cut out everything that actually does the drawing, create a new project, and slowly move in the drawing code into this PNG export function, you’d more easily notice the problems

 

Ivan Vučica

 

From: [hidden email]
Sent: Thursday 11 June 2020 22:57
To: [hidden email]
Cc: [hidden email]
Subject: Re: cairo drawing problem

 

Hi Andreas,

 

I did not get your original mail and it isn’t even in my spam folder where your previous mails.

 

> Am 11.06.2020 um 00:05 schrieb Josh Freeman <[hidden email]>:

>

>   Try initializing your window as NSBackingStoreBuffered? (NSBackingStoreNonretained tells the window to draw directly to the screen without buffering, so the pixel data is probably unavailable for reading back).

 

This might help but I really would like to understand where the issue comes from in the first place.

 

Looking at the code and the output below the first thing I notice is that the X error happens after the extraction of the view data into the bitmap image was finished. The most likely scenario is that the data we extracted is somehow invalid. That would fit in wit your suggested work around.

 

But all of this is just blind guessing, what we need here is example code that allows to reproduce this issue with GNUstep classes only.

 

Andreas, could you please strip down your application to pure GNUstep and if that still displays the error send out that code?

 

Cheers,

Fred

 

> On Jun 8, 2020, at 1:52 PM, Andreas Höschler via Discussion list for the GNUstep programming environment wrote:

>

>>

>> Hi all,

>>

>> I have just found some time to continue testing my app(s) on GNUstep and realised that drawing OSM maps fails under GNUstep when using the cairo backend while it works if using libart.

>>

>> My code draws something in a NSView subclass and then uses

>>

>>         [mapView display];

>>         [mapView lockFocus];

>>         NSBitmapImageRep *rep = [[NSBitmapImageRep alloc] initWithFocusedViewRect:[mapView bounds]];

>>         data = [[[rep representationUsingType:NSPNGFileType properties:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:1] forKey:@"NSImageInterlaced"]] retain] autorelease];

>>         if ([data length] == 0) // try TIFF instead

>>           {

>>            data = [[[rep representationUsingType:NSTIFFFileType properties:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:1] forKey:@"NSImageInterlaced"]] retain] autorelease];

>>            if ([data length] == 0) NSLog(@"Damn! TIFF failed as well!");

>>           }

>>         [mapView unlockFocus];

>>

>> to produce a PNG from the view content. This works great with libart

>>

>> art:

>> ============================================================================

>>

>> 2020-06-08 19:37:18.526 ESMMapServer[10165:10165] draw way inlays... 359 _drawPrimaryInLays 1 _drawOtherInLays 1

>> 2020-06-08 19:37:18.527 ESMMapServer[10165:10165] BUMM

>> 2020-06-08 19:37:18.545 ESMMapServer[10165:10165] Draw 7 mapShields ...

>> 2020-06-08 19:37:18.548 ESMMapServer[10165:10165] Draw 1 mapLocs ...

>> 2020-06-08 19:37:18.549 ESMMapServer[10165:10165] Draw 2 mapLines ...

>> 2020-06-08 19:37:18.549 ESMMapServer[10165:10165] <ESMMapLine: 0x2ed0550> drawLine _colorName (null) _color 0 0 1

>> 2020-06-08 19:37:18.549 ESMMapServer[10165:10165] <ESMMapLine: 0x2ed4610> drawLine _colorName (null) _color 0 1 0

>> 2020-06-08 19:37:18.557 ESMMapServer[10165:10165]  h=--- v=--- <ESMMapView: 0x2302ca0> f={x = 0; y = 0; width = 542; height = 620} b={x = 0; y = 0; width = 542; height = 620} locking Focus ..

>> 2020-06-08 19:37:18.557 ESMMapServer[10165:10165] getting rep ...

>> 2020-06-08 19:37:18.563 ESMMapServer[10165:10165] rep <NSBitmapImageRep: 0x2f15450 size: {width = 542; height = 620} pixelsWide: 542 pixelsHigh: 620 colorSpaceName: NSDeviceRGBColorSpace bps: 8>

>> 2020-06-08 19:37:18.665 ESMMapServer[10165:10165]  h=--- v=--- <ESMMapView: 0x2302ca0> f={x = 0; y = 0; width = 542; height = 620} b={x = 0; y = 0; width = 542; height = 620} unocked Focus!

>> 2020-06-08 19:37:18.665 ESMMapServer[10165:10165] data 248529

>>

>> but fails with cairo

>>

>> cairo:

>> =======================================================================================

>> 2020-06-08 19:31:52.783 ESMMapServer[9982:9982] draw way inlays... 359 _drawPrimaryInLays 1 _drawOtherInLays 1

>> 2020-06-08 19:31:52.783 ESMMapServer[9982:9982] BUMM

>> 2020-06-08 19:31:52.798 ESMMapServer[9982:9982] Draw 8 mapShields ...

>> 2020-06-08 19:31:52.801 ESMMapServer[9982:9982] Draw 1 mapLocs ...

>> 2020-06-08 19:31:52.802 ESMMapServer[9982:9982] Draw 2 mapLines ...

>> 2020-06-08 19:31:52.802 ESMMapServer[9982:9982] <ESMMapLine: 0x33b52c0> drawLine _colorName (null) _color 0 0 1

>> 2020-06-08 19:31:52.802 ESMMapServer[9982:9982] <ESMMapLine: 0x33c3d30> drawLine _colorName (null) _color 0 1 0

>> 2020-06-08 19:31:52.811 ESMMapServer[9982:9982]  h=--- v=--- <ESMMapView: 0x28e0fe0> f={x = 0; y = 0; width = 542; height = 620} b={x = 0; y = 0; width = 542; height = 620} locking Focus ...

>> 2020-06-08 19:31:52.812 ESMMapServer[9982:9982] getting rep ...

>> 2020-06-08 19:31:52.815 ESMMapServer[9982:9982] rep <NSBitmapImageRep: 0x3698ef0 size: {width = 542; height = 620} pixelsWide: 542 pixelsHigh: 620 colorSpaceName: NSDeviceRGBColorSpace bps: 8>

>> 2020-06-08 19:31:52.882 ESMMapServer[9982:9982]  h=--- v=--- <ESMMapView: 0x28e0fe0> f={x = 0; y = 0; width = 542; height = 620} b={x = 0; y = 0; width = 542; height = 620} unocked Focus!

>> 2020-06-08 19:31:52.883 ESMMapServer[9982:9982] data 1383

>> 2020-06-08 19:31:52.921 ESMMapServer[9982:9982] X-Windows error - RenderBadPicture (invalid Picture parameter)

>>          on display: :0

>>                type: 0

>>       serial number: 1169

>>        request code: 139

>>

>>

>> data contains nothing reasonable after this X-WIndows error. I have attached the complete implementation of

>>

>> - (NSDictionary *)PNGForMapRequestDic:(NSDictionary *)dic;

>>

>> for reference below (contains the lockFocus ... unlockFocus magic). Any idea what might be causing this X-Windows error with cairo? I am stuck when it gets to backend issues. I might have to add that this error occurs in a tool (no gui app) named ESMMapServer which is supposed to produce maps (PNGs) from OSM data in the background.

>>

>> Thanks a lot,

>>

>> Andreas

>>

>>

>>

>>

>>

>>

>>

>> - (NSDictionary *)PNGForMapRequestDic:(NSDictionary *)dic

>> {

>>   NSNumber *pixelWidth = [dic objectForKey:@"pixelWidth"];

>>   NSNumber *pixelHeight = [dic objectForKey:@"pixelHeight"];

>>   NSNumber *x = [dic objectForKey:@"x"];

>>   NSNumber *y = [dic objectForKey:@"y"];

>>   NSNumber *width = [dic objectForKey:@"width"];

>>   NSNumber *height = [dic objectForKey:@"height"];

>>   NSArray *locations = [dic objectForKey:@"locations"];

>>   NSArray *hintPaths = [dic objectForKey:@"hintPaths"];

>>   BOOL drawTextMarks = [[dic objectForKey:@"drawTextMarks"] intValue];

>>   NSLog(@"PNGForMapRequestDic hintPaths %d %@ %@ %@ %@ pixelWidth %@ pixelHeight %@", [hintPaths count], x, y, width, height, pixelWidth, pixelHeight);

>>   NSLog(@"locations %@", [locations description]);

>>

>>   [_shields removeAllObjects];

>>

>>   if ((pixelWidth) && (pixelHeight) && (x) && (y) && (width) && (height))

>>     {

>>      _visibleMapSection = NSMakeRect ([x floatValue], [y floatValue], [width floatValue], [height floatValue]);

>>      if (_visibleMapSection.size.height > MAXESMMAPHEIGHT) // reducing map size to avoid OSMMapServer break down <-----------

>>        {

>>         NSLog(@"reducing map size to avoid OSMMapServer break down %f -> %f", _visibleMapSection.size.height, MAXESMMAPHEIGHT);

>>         float margin = (_visibleMapSection.size.height - MAXESMMAPHEIGHT) / 2;

>>         _visibleMapSection.origin.y += margin;

>>         _visibleMapSection.size.height = MAXESMMAPHEIGHT;

>>        }

>>      _imageSize = NSMakeSize([pixelWidth floatValue], [pixelHeight floatValue]);

>>      NSLog(@"_imageSize %@", NSStringFromSize(_imageSize));

>>      if (_imageSize.width / _imageSize.height > (_visibleMapSection.size.width * cos ((_visibleMapSection.origin.y + _visibleMapSection.size.height / 2.0) / 180.0 * 3.14)) / _visibleMapSection.size.height)

>>        {

>>         float correctedWidth = _visibleMapSection.size.height * _imageSize.width / (_imageSize.height * cos ((_visibleMapSection.origin.y + _visibleMapSection.size.height / 2.0) / 180.0 * 3.14));

>>         //         NSLog(@"requested width %f correctedWidth %f", _visibleMapSection.size.width, correctedWidth);

>>         _visibleMapSection.origin.x -= (correctedWidth - _visibleMapSection.size.width) / 2.0;

>>         _visibleMapSection.size.width = correctedWidth;

>>        }

>>      else

>>        {

>>         float correctedHeight = (_visibleMapSection.size.width * _imageSize.height * cos ((_visibleMapSection.origin.y + _visibleMapSection.size.height / 2.0) / 180.0 * 3.14) / _imageSize.width);

>>         //         NSLog(@"requested height %f correctedHeight %f", _visibleMapSection.size.height, correctedHeight);

>>         _visibleMapSection.origin.y -= (correctedHeight - _visibleMapSection.size.height) / 2.0;

>>         _visibleMapSection.size.height = correctedHeight;

>>        }

>>      NSLog(@"_visibleMapSection %@", NSStringFromRect(_visibleMapSection));

>>

>>      NSArray *presentations = [self suitablePresentationsForRect:_visibleMapSection];

>>      //      NSLog(@"presentations %@", [presentations description]);

>>      NSEnumerator *enumerator = [presentations objectEnumerator];

>>      ESMMapPresentation *presentation;

>>      NSArray *highways = nil;

>>      NSArray *ways = nil;

>>      NSArray *namedNodes = nil;

>>      ESMMapView *mapView = nil;

>>      NSWindow *window = nil;

>>

>>      NSLog(@"_sharedMapView %@", _sharedMapView);

>>      if (_sharedMapView)

>>        {

>>         mapView = (ESMMapView *)[_sharedMapView retain];

>>         [mapView removeAllPathsAndMapLabels];

>>        }

>>      else

>>        {

>>         window = [[NSWindow alloc] initWithContentRect:NSMakeRect(0,0, _imageSize.width, _imageSize.height) styleMask:NSBorderlessWindowMask backing:NSBackingStoreNonretained defer:NO];

>>         mapView = [[ESMMapView alloc] initWithFrame:NSMakeRect(0, 0, _imageSize.width, _imageSize.height)];

 

<a lot of unrelated code removed>

 

>>      NSData *data = nil;

>>

>>      if (_sharedMapView)

>>        {

>>         [mapView prepareOSMDrawing];

>>         NSLog(@"%@ calling display ..", mapView);

>>         [mapView display];

>>         NSLog(@"%@ display done", mapView);

>>        }

>>      else

>>        {

>>         [mapView display];

>>         NS_DURING

>>         NSLog(@"%@ locking Focus ...", mapView);

>>         [mapView lockFocus];

>>         NSLog(@"getting rep ...");

>>         //      NSLog(@"window frame %@", NSStringFromRect([[mapView window] frame]));

>>         //      NSLog(@"contentView frame %@", NSStringFromRect([[[mapView window] contentView] frame]));

>>         //      NSLog(@"frame %@", NSStringFromRect([mapView frame]));

>>         //      NSLog(@"bounds %@", NSStringFromRect([mapView bounds]));

>>         NSBitmapImageRep *rep = [[NSBitmapImageRep alloc] initWithFocusedViewRect:[mapView bounds]];

>>         NSLog(@"rep %@", rep);

>>         data = [[[rep representationUsingType:NSPNGFileType properties:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:1] forKey:@"NSImageInterlaced"]] retain] autorelease];

>> /*           {

>>            NSString *path = @"/home/ahoesch/A.tiff";

>>            NSData *data = [[[rep representationUsingType:NSTIFFFileType properties:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:1] forKey:@"NSImageInterlaced"]] retain] autorelease];

>>            [data writeToFile:path atomically:YES];

>>           }

>>  */

>>         if ([data length] == 0) // try TIFF instead

>>           {

>>            NSLog(@"Getting PNG data failed! We try TIFF instead ...");

>>            //      NSData *data = [[[rep TIFFRepresentation] retain] autorelease];

>>            data = [[[rep representationUsingType:NSTIFFFileType properties:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:1] forKey:@"NSImageInterlaced"]] retain] autorelease];

>>            if ([data length] == 0) NSLog(@"Damn! TIFF failed as well!");

>>           }

>>         [mapView unlockFocus];

>>         NSLog(@"%@ unocked Focus!", mapView);

>>         [rep release];

>>         NS_HANDLER

>>         NSLog(@"Something went terribly wrong: %@", [localException description]);

>>         //      NSView *clipView = [mapView superview];

>>         //      NSLog(@"clipView %@ bounds %@", NSStringFromRect([clipView frame]), NSStringFromRect([clipView bounds]));

>>         NS_ENDHANDLER

>>        }

>>

>>      NSLog(@"data %d", [data length]);

>>      [window release];

>>      [mapView release];

>>      return [NSDictionary dictionaryWithObjectsAndKeys:

>>      [NSNumber numberWithFloat:_visibleMapSection.origin.x], @"visibleMapSection.origin.x",

>>      [NSNumber numberWithFloat:_visibleMapSection.origin.y], @"visibleMapSection.origin.y",

>>      [NSNumber numberWithFloat:_visibleMapSection.size.width], @"visibleMapSection.size.width",

>>      [NSNumber numberWithFloat:_visibleMapSection.size.height], @"visibleMapSection.size.height",

>>      data, @"imageData",

>>      nil];

>>     }

>>   else return nil;

>> }

>>

 

 

Reply | Threaded
Open this post in threaded view
|

Re: cairo drawing problem

GNUstep - General mailing list
In reply to this post by Josh Freeman
Hi Josh, Fred and Ivan,

thanks a lot for your responses!!

On 11 Jun 2020, at 00:05, Josh Freeman <[hidden email]> wrote:
 Try initializing your window as NSBackingStoreBuffered? (NSBackingStoreNonretained tells the window to draw directly to the screen without buffering, so the pixel data is probably unavailable for reading back).

This actually fixed the problem. I get PNGs now even with cairo!! :-)

On 11 Jun 2020, at 23:56, Fred Kiefer <[hidden email]> wrote:

 Try initializing your window as NSBackingStoreBuffered? (NSBackingStoreNonretained tells the window to draw directly to the screen without buffering, so the pixel data is probably unavailable for reading back).

This might help but I really would like to understand where the issue comes from in the first place.

Looking at the code and the output below the first thing I notice is that the X error happens after the extraction of the view data into the bitmap image was finished.

         [mapView lockFocus];
         NSBitmapImageRep *rep = [[NSBitmapImageRep alloc] initWithFocusedViewRect:[mapView bounds]];
         NSLog(@"rep %@", rep);
         data = [[[rep representationUsingType:NSPNGFileType properties:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:1] forKey:@"NSImageInterlaced"]] retain] autorelease];         
         [mapView unlockFocus]; // <--- the error happens here
         NSLog(@"%@ unocked Focus!", mapView);      
         [rep release];


On 12 Jun 2020, at 19:43, Ivan Vučica <[hidden email]> wrote:

 

My first instinct is ‘are you releasing some internal object loaned to you, which you never retained’. 
My cleanup didn’t reveal anything particular, but:

 

NSBitmapImageRep *rep = [[NSBitmapImageRep alloc] initWithFocusedViewRect:[mapView bounds]];
NSDictionary * props = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:1]
                                                   forKey:@"NSImageInterlaced"];
NSData * repData = [rep representationUsingType:NSPNGFileType
                                    properties:props]
NSData * data = [[repData retain] autorelease];
 
Note that the autoreleased repData is retained and then autoreleased (meaning the same object is put onto the autorelease queue twice)

I don't remember why I thought this was necessary. I removed the additional retain autorelease, but this did not change anything. I doubt it hurts.
 
Then I saw the rest of the code you attached. My thought goes in the direction of ‘_sharedMapView’-related code. Even though you’re allocating a whole new window only when the map view is not shared, you seem to be releasing window unconditionally.

The ivar window is either nil (in case of _sharedMapView != nil) or initialised with window = [[NSWindow alloc] init...] (in case of _sharedMapView == nil), so the [window release] should be fine!? 

 Based on the output, I’m concluding you are running with _sharedMapView==NO

Yes!

and thus releasing the mapview and window incorrectly which possibly results in an X drawable being destroyed while still in use.
   
   window = [[NSWindow alloc] initWithContentRect:NSMakeRect(0,0, _imageSize.width, _imageSize.height) styleMask:NSBorderlessWindowMask backing:NSBackingStoreNonretained defer:NO];    // NSBackingStoreBuffered  NSBackingStoreNonretained
   mapView = [[ESMMapView alloc] initWithFrame:NSMakeRect(0, 0, _imageSize.width, _imageSize.height)];                  

...
   [mapView lockFocus];

   NSBitmapImageRep *rep = [[NSBitmapImageRep alloc] initWithFocusedViewRect:[mapView bounds]];
   data = [rep representationUsingType:NSPNGFileType properties:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:1] forKey:@"NSImageInterlaced"]];   
   [rep release];

   [mapView unlockFocus];
   [mapView release];
   [window release];         

This looks good to me (though I had the release of mapView and window exchanged)!? But that does not seem to be the problem. The error occurs in unlockFocus!

 Some suggestions:
- start the program with GDB and put a breakpoint on the lines mentioning “X-Window error” in libs-back? 
  - In the current code, I found these in only one file: https://github.com/gnustep/libs-back/blob/2a0e305a4f3ec93c00a96a13838877c9543449a9/Source/x11/XGServerEvent.m line 206 and 216. Based on the output, I’d expect it’s enough to put it on line 206 (the NSLog instead of the NSException).

I inserted an exception raiser 


  XGetErrorText(display, err->error_code, buffer, length);
  if (err->type == 0
      && GSDebugSet(@"XSynchronize") == NO)
    {

        

      NSLog(@"X-Windows error - %s\n\
          on display: %s\n\
                type: %d\n\
       serial number: %lu\n\
        request code: %d\n",
        buffer,
        XDisplayName(DisplayString(display)),
        err->type, err->serial, err->request_code);


        [NSException raise:NSInternalInconsistencyException format:@"asas"]; // <---


      return 0;
    }
  [NSException raise: NSWindowServerCommunicationException
    format: @"X-Windows error - %s\n\
          on display: %s\n\
                type: %d\n\
       serial number: %lu\n\
        request code: %d\n",
        buffer,
        XDisplayName(DisplayString(display)),
        err->type, err->serial, err->request_code];
  return 0;
}

and yes, there it went.

#0  -[NSException raise] (self=0x2dd0590, _cmd=0x7f3ca8aa74e0 <_OBJC_SELECTOR_TABLE+480>) at NSException.m:1574
#1  0x00007f3ca8546bba in +[NSException raise:format:arguments:] (self=0x7f3ca8aa7020 <_OBJC_Class_NSException>, 
    _cmd=0x7f3ca8aa74b0 <_OBJC_SELECTOR_TABLE+432>, name=0x7f3ca8aa69e0 <_OBJC_INSTANCE_4>, format=0x7f3c9fde0110 <_OBJC_INSTANCE_2>, 
    argList=0x7ffd6fbc8810) at NSException.m:1465
#2  0x00007f3ca8546b01 in +[NSException raise:format:] (self=0x7f3ca8aa7020 <_OBJC_Class_NSException>, 
    _cmd=0x7f3c9fde1350 <_OBJC_SELECTOR_TABLE+112>, name=0x7f3ca8aa69e0 <_OBJC_INSTANCE_4>, format=0x7f3c9fde0110 <_OBJC_INSTANCE_2>)
    at NSException.m:1450
#3  0x00007f3c9fb8bd66 in -[XGServer(EventOps) XGErrorHandler::] (self=0x194ed80, _cmd=0x7f3c9fde1340 <_OBJC_SELECTOR_TABLE+96>, 
    display=0x1953af0, err=0x7ffd6fbc8e00) at XGServerEvent.m:217
#4  0x00007f3c9fb8bb17 in XGErrorHandler (display=0x1953af0, err=0x7ffd6fbc8e00) at XGServerEvent.m:141
#5  0x00007f3c9f074ced in _XError () from /usr/lib/x86_64-linux-gnu/libX11.so.6
#6  0x00007f3c9f071b77 in ?? () from /usr/lib/x86_64-linux-gnu/libX11.so.6
#7  0x00007f3c9f071c35 in ?? () from /usr/lib/x86_64-linux-gnu/libX11.so.6
#8  0x00007f3c9f0725f5 in _XEventsQueued () from /usr/lib/x86_64-linux-gnu/libX11.so.6
#9  0x00007f3c9f063fd7 in XPending () from /usr/lib/x86_64-linux-gnu/libX11.so.6
#10 0x00007f3c9fb8c05b in -[XGServer(EventOps) receivedEvent:type:extra:forMode:] (self=0x194ed80, 
    _cmd=0x7f3ca8b85d30 <_OBJC_SELECTOR_TABLE+304>, data=0x9, type=ET_RDESC, extra=0x9, mode=0x7f3ca8b053c0 <_OBJC_INSTANCE_2>)
    at XGServerEvent.m:318
#11 0x00007f3ca86ee504 in -[GSRunLoopCtxt pollUntil:within:] (self=0x19b5b40, _cmd=0x7f3ca8b065c0 <_OBJC_SELECTOR_TABLE+1184>, 
    milliseconds=0, contexts=0x19abf30) at GSRunLoopCtxt.m:455
#12 0x00007f3ca85fae90 in -[NSRunLoop acceptInputForMode:beforeDate:] (self=0x19aa810, _cmd=0x7f3ca8b065f0 <_OBJC_SELECTOR_TABLE+1232>, 
    mode=0x7f3ca8b053c0 <_OBJC_INSTANCE_2>, limit_date=0x11717c0) at NSRunLoop.m:1238
#13 0x00007f3ca85fb368 in -[NSRunLoop runMode:beforeDate:] (self=0x19aa810, _cmd=0x7f3ca8b06620 <_OBJC_SELECTOR_TABLE+1280>, 

This stack trace does not look very helpful (at least to me). :-(

- provide a truly minimal example
Andreas, could you please strip down your application to pure GNUstep and if that still displays the error send out that code?

Will try to put something together ...

Best wishes,

 Andreas




Hi all,

I have just found some time to continue testing my app(s) on GNUstep and realised that drawing OSM maps fails under GNUstep when using the cairo backend while it works if using libart.

My code draws something in a NSView subclass and then uses

        [mapView display];
        [mapView lockFocus];
        NSBitmapImageRep *rep = [[NSBitmapImageRep alloc] initWithFocusedViewRect:[mapView bounds]];
        data = [[[rep representationUsingType:NSPNGFileType properties:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:1] forKey:@"NSImageInterlaced"]] retain] autorelease];
        if ([data length] == 0) // try TIFF instead
          {
           data = [[[rep representationUsingType:NSTIFFFileType properties:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:1] forKey:@"NSImageInterlaced"]] retain] autorelease];
           if ([data length] == 0) NSLog(@"Damn! TIFF failed as well!");
          }
        [mapView unlockFocus];

to produce a PNG from the view content. This works great with libart

art:
============================================================================

2020-06-08 19:37:18.526 ESMMapServer[10165:10165] draw way inlays... 359 _drawPrimaryInLays 1 _drawOtherInLays 1
2020-06-08 19:37:18.527 ESMMapServer[10165:10165] BUMM
2020-06-08 19:37:18.545 ESMMapServer[10165:10165] Draw 7 mapShields ...
2020-06-08 19:37:18.548 ESMMapServer[10165:10165] Draw 1 mapLocs ...
2020-06-08 19:37:18.549 ESMMapServer[10165:10165] Draw 2 mapLines ...
2020-06-08 19:37:18.549 ESMMapServer[10165:10165] <ESMMapLine: 0x2ed0550> drawLine _colorName (null) _color 0 0 1
2020-06-08 19:37:18.549 ESMMapServer[10165:10165] <ESMMapLine: 0x2ed4610> drawLine _colorName (null) _color 0 1 0
2020-06-08 19:37:18.557 ESMMapServer[10165:10165]  h=--- v=--- <ESMMapView: 0x2302ca0> f={x = 0; y = 0; width = 542; height = 620} b={x = 0; y = 0; width = 542; height = 620} locking Focus ...
2020-06-08 19:37:18.557 ESMMapServer[10165:10165] getting rep ...
2020-06-08 19:37:18.563 ESMMapServer[10165:10165] rep <NSBitmapImageRep: 0x2f15450 size: {width = 542; height = 620} pixelsWide: 542 pixelsHigh: 620 colorSpaceName: NSDeviceRGBColorSpace bps: 8>
2020-06-08 19:37:18.665 ESMMapServer[10165:10165]  h=--- v=--- <ESMMapView: 0x2302ca0> f={x = 0; y = 0; width = 542; height = 620} b={x = 0; y = 0; width = 542; height = 620} unocked Focus!
2020-06-08 19:37:18.665 ESMMapServer[10165:10165] data 248529

but fails with cairo

cairo:
=======================================================================================
2020-06-08 19:31:52.783 ESMMapServer[9982:9982] draw way inlays... 359 _drawPrimaryInLays 1 _drawOtherInLays 1
2020-06-08 19:31:52.783 ESMMapServer[9982:9982] BUMM
2020-06-08 19:31:52.798 ESMMapServer[9982:9982] Draw 8 mapShields ...
2020-06-08 19:31:52.801 ESMMapServer[9982:9982] Draw 1 mapLocs ...
2020-06-08 19:31:52.802 ESMMapServer[9982:9982] Draw 2 mapLines ...
2020-06-08 19:31:52.802 ESMMapServer[9982:9982] <ESMMapLine: 0x33b52c0> drawLine _colorName (null) _color 0 0 1
2020-06-08 19:31:52.802 ESMMapServer[9982:9982] <ESMMapLine: 0x33c3d30> drawLine _colorName (null) _color 0 1 0
2020-06-08 19:31:52.811 ESMMapServer[9982:9982]  h=--- v=--- <ESMMapView: 0x28e0fe0> f={x = 0; y = 0; width = 542; height = 620} b={x = 0; y = 0; width = 542; height = 620} locking Focus ...
2020-06-08 19:31:52.812 ESMMapServer[9982:9982] getting rep ...
2020-06-08 19:31:52.815 ESMMapServer[9982:9982] rep <NSBitmapImageRep: 0x3698ef0 size: {width = 542; height = 620} pixelsWide: 542 pixelsHigh: 620 colorSpaceName: NSDeviceRGBColorSpace bps: 8>
2020-06-08 19:31:52.882 ESMMapServer[9982:9982]  h=--- v=--- <ESMMapView: 0x28e0fe0> f={x = 0; y = 0; width = 542; height = 620} b={x = 0; y = 0; width = 542; height = 620} unocked Focus!
2020-06-08 19:31:52.883 ESMMapServer[9982:9982] data 1383
2020-06-08 19:31:52.921 ESMMapServer[9982:9982] X-Windows error - RenderBadPicture (invalid Picture parameter)
         on display: :0
               type: 0
      serial number: 1169
       request code: 139


data contains nothing reasonable after this X-WIndows error. I have attached the complete implementation of

- (NSDictionary *)PNGForMapRequestDic:(NSDictionary *)dic;

for reference below (contains the lockFocus ... unlockFocus magic). Any idea what might be causing this X-Windows error with cairo? I am stuck when it gets to backend issues. I might have to add that this error occurs in a tool (no gui app) named ESMMapServer which is supposed to produce maps (PNGs) from OSM data in the background.

Thanks a lot,

Andreas







- (NSDictionary *)PNGForMapRequestDic:(NSDictionary *)dic
{
  NSNumber *pixelWidth = [dic objectForKey:@"pixelWidth"];
  NSNumber *pixelHeight = [dic objectForKey:@"pixelHeight"];
  NSNumber *x = [dic objectForKey:@"x"];
  NSNumber *y = [dic objectForKey:@"y"];
  NSNumber *width = [dic objectForKey:@"width"];
  NSNumber *height = [dic objectForKey:@"height"];
  NSArray *locations = [dic objectForKey:@"locations"];
  NSArray *hintPaths = [dic objectForKey:@"hintPaths"];
  BOOL drawTextMarks = [[dic objectForKey:@"drawTextMarks"] intValue];
  NSLog(@"PNGForMapRequestDic hintPaths %d %@ %@ %@ %@ pixelWidth %@ pixelHeight %@", [hintPaths count], x, y, width, height, pixelWidth, pixelHeight);
  NSLog(@"locations %@", [locations description]);

  [_shields removeAllObjects];

  if ((pixelWidth) && (pixelHeight) && (x) && (y) && (width) && (height))
    {
     _visibleMapSection = NSMakeRect ([x floatValue], [y floatValue], [width floatValue], [height floatValue]);
     if (_visibleMapSection.size.height > MAXESMMAPHEIGHT) // reducing map size to avoid OSMMapServer break down <-----------
       {
        NSLog(@"reducing map size to avoid OSMMapServer break down %f -> %f", _visibleMapSection.size.height, MAXESMMAPHEIGHT);
        float margin = (_visibleMapSection.size.height - MAXESMMAPHEIGHT) / 2;
        _visibleMapSection.origin.y += margin;
        _visibleMapSection.size.height = MAXESMMAPHEIGHT;
       }
     _imageSize = NSMakeSize([pixelWidth floatValue], [pixelHeight floatValue]);
     NSLog(@"_imageSize %@", NSStringFromSize(_imageSize));
     if (_imageSize.width / _imageSize.height > (_visibleMapSection.size.width * cos ((_visibleMapSection.origin.y + _visibleMapSection.size.height / 2.0) / 180.0 * 3.14)) / _visibleMapSection.size.height)
       {
        float correctedWidth = _visibleMapSection.size.height * _imageSize.width / (_imageSize.height * cos ((_visibleMapSection.origin.y + _visibleMapSection.size.height / 2.0) / 180.0 * 3.14));
        //         NSLog(@"requested width %f correctedWidth %f", _visibleMapSection.size.width, correctedWidth);
        _visibleMapSection.origin.x -= (correctedWidth - _visibleMapSection.size.width) / 2.0;
        _visibleMapSection.size.width = correctedWidth;
       }
     else
       {
        float correctedHeight = (_visibleMapSection.size.width * _imageSize.height * cos ((_visibleMapSection.origin.y + _visibleMapSection.size.height / 2.0) / 180.0 * 3.14) / _imageSize.width);
        //         NSLog(@"requested height %f correctedHeight %f", _visibleMapSection.size.height, correctedHeight);
        _visibleMapSection.origin.y -= (correctedHeight - _visibleMapSection.size.height) / 2.0;
        _visibleMapSection.size.height = correctedHeight;
       }
     NSLog(@"_visibleMapSection %@", NSStringFromRect(_visibleMapSection));

     NSArray *presentations = [self suitablePresentationsForRect:_visibleMapSection];
     //      NSLog(@"presentations %@", [presentations description]);
     NSEnumerator *enumerator = [presentations objectEnumerator];
     ESMMapPresentation *presentation;
     NSArray *highways = nil;
     NSArray *ways = nil;
     NSArray *namedNodes = nil;
     ESMMapView *mapView = nil;
     NSWindow *window = nil;

     NSLog(@"_sharedMapView %@", _sharedMapView);
     if (_sharedMapView)
       {
        mapView = (ESMMapView *)[_sharedMapView retain];
        [mapView removeAllPathsAndMapLabels];
       }
     else
       {
        window = [[NSWindow alloc] initWithContentRect:NSMakeRect(0,0, _imageSize.width, _imageSize.height) styleMask:NSBorderlessWindowMask backing:NSBackingStoreNonretained defer:NO];
        mapView = [[ESMMapView alloc] initWithFrame:NSMakeRect(0, 0, _imageSize.width, _imageSize.height)];
//         NSLog(@"window %@", window);
        //         [window setContentView:mapView];
        [[window contentView] addSubview:mapView];
        //         [window setContentSize:NSMakeSize(_imageSize.width * 0.5, _imageSize.height *0.5)];  // <--- superfluous
//         NSLog(@"mapView %@ bounds %@", NSStringFromRect([mapView frame]), NSStringFromRect([mapView bounds]));
//         NSView *clipView = [mapView superview];
//         NSLog(@"clipView %@ bounds %@", NSStringFromRect([clipView frame]), NSStringFromRect([clipView bounds]));
       }
     [mapView prepareOSMDrawing];
     [mapView setVisibleMapSection:_visibleMapSection]; // used to determine zoom level / how to render streets, draw labels etc.
     //      NSSize unitSize = {1.0, 1.0};
     //      [mapView scaleUnitSquareToSize:[mapView convertSize:unitSize fromView:nil]];

#ifdef LOADCOSTLINES
     if (_visibleMapSection.size.height > 8.0)
       {
        if (!_roughShapeFile)
          {
           //         NSString *path = [NSBundle pathForResource:@"germany" ofType:@"shp"];
           NSString *path = [NSBundle pathForResource:@"worldland-low" ofType:@"shp"];
           NSLog(@"_roughShapeFile path %@", path);
           if (path)
             {
              _roughShapeFile = [[ESMShapeFile alloc] initWithPath:path];
              [_roughShapeFile loadShapeFile];
             }
          }
        NSLog(@"_roughShapeFile %@ --> calcing bezierPathsForVisibleMapSectionc ...", _roughShapeFile);
        [mapView setBezierPathsForLand:[_roughShapeFile bezierPathsForVisibleMapSection:_visibleMapSection imageSize:_imageSize]];
        NSLog(@"Done");
       }
     else
       {
        if (!_fineShapeFile)
          {
           //         NSString *path = [NSBundle pathForResource:@"germany" ofType:@"shp"];
           NSString *path = [NSBundle pathForResource:@"worldland-high" ofType:@"shp"];
           NSLog(@"_fineShapeFile path %@", path);
           if (path)
             {
              _fineShapeFile = [[ESMShapeFile alloc] initWithPath:path];
              [_fineShapeFile loadShapeFile];
             }
          }
        NSLog(@"_fineShapeFile %@ --> calcing bezierPathsForVisibleMapSectionc ...", _fineShapeFile);
        [mapView setBezierPathsForLand:[_fineShapeFile bezierPathsForVisibleMapSection:_visibleMapSection imageSize:_imageSize]];
        NSLog(@"Done");
       }
     #endif

     //      [mapView setDrawlInLays:[mapView heightOfVisibleMapInKm] < 5.0];

     //      NSLog(@"Iterating through %d presentations ...", [presentations count]);
     while (presentation = [enumerator nextObject])
       {
        //         [mapView setDrawlInLays:[presentation shouldDrawInlays]];

        // presentation returns only those ways and highways that should be drawn respecting the detail level of the presentation
        NSLog(@"Getting mapTiles ...");
        NSArray *mapTiles = [presentation mapTilesForVisibleMapSection:_visibleMapSection highways:&highways ways:&ways namedNodes:&namedNodes];
        NSLog(@"We are utilizing %d mapTiles ...", [mapTiles count]);

        /* *** add ESMMapLabels to mapView *** */
          {
           NSEnumerator *enumerator = [namedNodes objectEnumerator];
           KindNode *node;
           while (node = [enumerator nextObject])
             {
//               NSLog(@"Creating mapLabel for %@ %@ %@ %@", node, [node valueForKey:@"name"], [node valueForKey:@"x"], [node valueForKey:@"y"]);
              NSPoint point = [self pixelFromGPS:NSMakePoint([[node valueForKey:@"x"] floatValue], [[node valueForKey:@"y"] floatValue])];
              //               ESMMapLabel *mapLabel = [[ESMMapLabel alloc] initWithPoint:point name:[node valueForKey:@"name"] kind:[ESMMapLabel nodekindForString:[node valueForKey:@"kind"]]];
              ESMMapLabel *mapLabel = [[ESMMapLabel alloc] initWithPoint:point name:[node valueForKey:@"name"] kind:node->_kind];
              //               [mapView addMapLabel:mapLabel];
              [mapView->_mapLabels addObject:mapLabel];
              [mapLabel release];
             }
          }

        #ifndef BLENDAHIGHWAY

        /* *** add ESMMapPaths for the highways *** */
          {
           NSLog(@"Iterating through %d highways ...", [highways count]);
           NSEnumerator *enumerator = [highways objectEnumerator];
           Highway *highway;
           int currentKind = -1;
           NSString *currentName = nil;
           ESMMapPath *currentPath = nil;
           NSBezierPath *currentBezier = nil;
           unsigned pathCounter = 0;
           BOOL tooBigForSmallStreets = (_visibleMapSection.size.height > MAXHEIGHTFORSMALLSTREET);
           BOOL tooBigForTrunkStreets = (_visibleMapSection.size.height > MAXHEIGHTFORTRUNKSTREET);
           BOOL tooBigForSmallMotorways = (_visibleMapSection.size.height > MAXHEIGHTFORSMALLMOTORWAYS);
           //            NSLog(@"add ESMMapPaths for the highways ...");

           while (highway = [enumerator nextObject])
             {
              //               BOOL debug = ([highway integerForKey:@"publicID"] < 0);
              //               BOOL debug = NO;// [[highway valueForKey:@"name"] isEqualToString:@"Muellerweg"];
              //               int kind = [ESMMapPath waykindForString:[highway valueForKey:@"highway"]];
              int kind = highway->_kind;
              //               BOOL debug = (kind == ESMWK_MOTORWAY);
//               NSLog(@"highway %@ kind %d", highway, kind);
              if (kind == -1 || kind == NSNotFound) continue;
              if (kind == ESMWK_UNCLASSIFIED)
                {
                 //                  NSLog(@"ESMWK_UNCLASSIFIED highway %@", [highway valueForKey:@"publicID"]);
                }
              if (tooBigForSmallStreets && kind > ESMWK_TERTIARY) continue;
              if (tooBigForTrunkStreets && kind > ESMWK_MOTORWAY) continue;
              NSString *ref = [highway valueForKey:@"ref"]; // <--- ???
//               BOOL debug = [ref isEqualToString:@"L 71"];
              if (tooBigForSmallMotorways && kind == ESMWK_MOTORWAY && [[(NSString *)[highway valueForKey:@"ref"] substringFromIndex:1] intValue] > 24) continue;
              if (tooBigForSmallStreets && kind == ESMWK_MOTORWAYLINK)
                {
                 if ((highway->_rect.top - highway->_rect.bottom) / _visibleMapSection.size.height < 0.05 && (highway->_rect.right - highway->_rect.left) / _visibleMapSection.size.width < 0.05) continue;
                }

              NSArray *nodesArray = [highway nodesArray];
              int i, count = [nodesArray count];
              //               NSLog(@"nodesArray count %d", count);
              if (count < 2) continue;

//               if (ref) NSLog(@"doll highway %@ count %d kind %d name %@ ref %@", highway, count, kind, [highway valueForKey:@"name"], ref);

              NSString *name = [highway valueForKey:@"name"];
              BOOL currentPathIsClosedPath;
              NSPoint pixelStartPoint;

              if (currentKind != kind || [currentName isEqualToString:highway->_sortName] == NO)
                {
                 currentPath = [[ESMMapPath alloc] initWithKind:kind name:name];
                 //                  if (debug) NSLog(@"currentPath %@ name %@ ref %@ new currentBezier", currentPath, name, ref);
                 // [mapView addMapPath:currentPath];
                 [mapView->_mapPaths addObject:currentPath];
                 currentKind = kind;
                 //                  currentName = name;
                 currentName = highway->_sortName;
                 pathCounter++;
                 [currentPath release];
                 currentBezier = [currentPath bezierPath];
                }
              currentPathIsClosedPath = [currentPath isClosedPath];

              // create label
              if (name != nil && [name length] > 0) // create MapLabel for the street name
                {
                 BOOL drawLabel = NO;

                 switch (kind) // suppress street label for very small highways
                   {
                    case ESMWK_MOTORWAY:
                    case ESMWK_TRUNK:
                    drawLabel = YES;
                    break;

                    case ESMWK_PRIMARY:
                    case ESMWK_SECONDARY:
                      {
                       drawLabel = (_visibleMapSection.size.height < MAXHEIGHTFORPRIMARYLABELS);
                      }
                    break;

                    default:
                    drawLabel = (_visibleMapSection.size.height < MAXHEIGHTFORSTREETLABELS);
                    break;
                   }

                 if (drawLabel)
                   {
                    NSPoint firstPoint, secondPoint;
                    BOOL success = [ESMMapLabel firstPoint:&firstPoint secondPoint:&secondPoint nodes:nodesArray];
                    if (success)
                      {
                       NSPoint anchor;
                       float angle;
                       NSRect labelRect = [ESMMapLabel labelRectForString:name firstPoint:[self pixelFromGPS:firstPoint] lastPoint:[self pixelFromGPS:secondPoint] anchor:&anchor angle:&angle];
                       if (labelRect.size.width > 0)
                         {
                          ESMMapLabel *mapLabel = [[ESMMapLabel alloc] initWithPoint:anchor name:name kind:-1]; // -1 means street label
                          [mapLabel setAngle:angle];
                          [mapLabel setLabelRect:labelRect];
                          // [mapView addMapLabel:mapLabel];
                          [mapView->_mapLabels addObject:mapLabel];
                          [mapLabel release];
                         }
                       //                  else NSLog(@"%@ suppressed!", name);
                      }
                   }
                }

              BOOL gotStarted = NO;
              for (i = 0 ; i < count; i++)
                {
                 ESMNode *node = [nodesArray objectAtIndex:i];
                 NSPoint gpsPoint = node->_point;
                 NSPoint point = [self pixelFromGPS:gpsPoint];

                 if (gotStarted == NO)
                   {
                    pixelStartPoint = point;
                   }

                 #ifndef BLENDAWAY
                 if (gotStarted && ref != nil && i > 0 && ((i-1) % 5) == 0) // shield generation
                   {
                    NSEnumerator *enumerator = [_shields objectEnumerator];
                    NSDictionary *dic;
                    BOOL accept = YES;

//                     if (debug) NSLog(@"check if an existingShield is too close ...");
                    // check if an existingShield is too close
                    while (dic = [enumerator nextObject])
                      {
                       NSPoint extPoint = NSPointFromString([dic objectForKey:@"point"]);
                       float dx = point.x - extPoint.x;
                       float dy = point.y - extPoint.y;
                       float r = sqrt (dx * dx + dy * dy);
                       if (r < PIXELDISTANCEBETWEENSHIELDS)
                         {
                          //                           NSLog(@"ref %@ i %d shield too close r %f / %f", ref, i, r, PIXELDISTANCEBETWEENSHIELDS);
                          accept = NO;
                          break;
                         }
                      }
//                     if (debug) NSLog(@"accept %d kind %@", accept, [ESMMapPath stringForWaykind:kind]);
                    if (accept)
                      {
                       NSColor *bezierColor = nil;
                       switch (kind)
                         {
                          case ESMWK_MOTORWAY:
                          case ESMWK_MOTORWAYLINK:
                          bezierColor = [ESMMapView motorWayColor];
                          break;

                          case ESMWK_PRIMARY:
                          case ESMWK_PRIMARYLINK:
                          bezierColor = [ESMMapView primaryColor];
                          break;

                          case ESMWK_TRUNK:
                          case ESMWK_TRUNKLINK:
                          bezierColor = [ESMMapView trunkColor];
                          break;

                          case ESMWK_SECONDARY:
                          bezierColor = [ESMMapView secondaryShieldColor];
                          break;

                          default:
                          break;
                         }
                       //                     NSLog(@"ref %@ kind %@ %d bezierColor %@", ref, [ESMMapPath stringForWaykind:kind], kind, bezierColor);
                       #ifndef SUPPRESSSHIELDS
                       if (bezierColor)
                         {
                          ESMMapShield *mapShield = [[ESMMapShield alloc] initWithPoint:point ref:[ref stringAfterRemovingAllOccurencesOfString:@" "] color:bezierColor];
                          //                           NSLog(@"Adding mapShield for ref %@ at %@", ref, NSStringFromPoint(point));
                          //                           [mapView addMapShield:mapShield];
                          [mapView->_mapShields addObject:mapShield];
                          [mapShield release];

                          NSDictionary *someDic = [[NSDictionary alloc] initWithObjectsAndKeys:NSStringFromPoint(point), @"point", ref, @"ref", nil];
                          [_shields addObject:someDic];
                          [someDic release];
                         }
                       #endif
                      }
                   }
                 #endif

                 if (gotStarted == NO)
                   {
                    //                     if (debug) NSLog(@"moveToPoint: %@", NSStringFromPoint(point));
                    [currentBezier moveToPoint:point];
                    gotStarted = YES;
                   }
                 else if (currentPathIsClosedPath && i == count -1)
                   {
                    //                     if (debug) NSLog(@"lineToPoint: %@", NSStringFromPoint(pixelStartPoint));
                    //                                          [currentBezier lineToPoint:pixelStartPoint]; // return to exact start point
                    [currentBezier closePath];
                   }
                 else
                   {
                    //                     if (debug) NSLog(@"lineToPoint: %@", NSStringFromPoint(point));
                    /*                     if (pixelLastPoint.x == point.x && pixelLastPoint.y == point.y)
                      {
                       //                        NSLog(@"Suppress line to same point %@ i: %d", NSStringFromPoint(point), i);
                      }
                    else*/ [currentBezier lineToPoint:point];
                   }
                }
             }
          }
        #endif

        #ifndef BLENDAWAY
        /* *** add ESMMapPaths for the ways (buildings ...) *** */
          {
           NSLog(@"Iterating through %d ways ...", [ways count]);
           NSEnumerator *enumerator = [ways objectEnumerator];
           Way *way;
           int currentKind = -1;
           ESMMapPath *currentPath = nil;
           NSBezierPath *currentBezier = nil;
           unsigned pathCounter = 0;

           while (way = [enumerator nextObject])
             {
              NSArray *nodesArray = [way nodesArray];
              NSString *name = [way valueForKey:@"name"];
//               if (name) NSLog(@"hit named way %@", name);
              int i, count = [nodesArray count];
              //               NSString *kindString = [way valueForKey:@"kind"];
              //               if (kindString == nil) { NSLog(@"way %@ has no kind!??", [way keyValueDic]); continue; }
              //               int kind = [ESMMapPath waykindForString:kindString];
              int kind = way->_kind;
              //               NSLog(@"way %@ kind %d count %d string %@", way, kind, count, [ESMMapPath stringForWaykind:kind]);
              BOOL debug = NO;//(kind == ESMWK_BUILDING);
              //               if (debug) NSLog(@"Bumahh, encountered ESMWK_BUILDING");
              BOOL currentPathIsClosedPath;
              NSPoint pixelStartPoint;

              if (kind == -1 || kind == NSNotFound) continue;
              //               if (kind == ESMWK_UNCLASSIFIED) NSLog(@"way %@", [way valueForKey:@"publicID"]);

              /*#ifndef __APPLE__
              switch (kind)
                {
                 case ESMWK_RAILWAYCONSTRUCTION:
                 case ESMWK_RAILWAYRAIL:
                 case ESMWK_RAILWAYABANDONEDTRAM:
                 case ESMWK_RAILWAYTRAM:
                 case ESMWK_RAILWAYABANDONED:
                 case ESMWK_RAILWAYPLATFORM:
                 continue;
                 default:
                 break;
                }
              //               if ([[kindString uppercaseString] rangeOfString:@"RAIL"].length > 0) continue;  // railways cause noise problems on GNUstep with libart
              #endif
              */

              if (currentKind != kind)
                {
                 currentPath = [[ESMMapPath alloc] initWithKind:kind name:nil];
                 //                  if (isCoastline) NSLog(@"created currentPath %@", currentPath);
                 //                  [mapView addMapPath:currentPath];
                 [mapView->_mapPaths addObject:currentPath];
                 if (debug) NSLog(@"Added currentPath to mapPaths ...");
                 currentKind = kind;
                 pathCounter++;
                 [currentPath release];
                 currentBezier = [currentPath bezierPath];
                }
              currentPathIsClosedPath = [currentPath isClosedPath];

              // handle nodes
              BOOL gotStarted = NO;
              for (i = 0 ; i < count; i++)
                {
                 ESMNode *node = [nodesArray objectAtIndex:i];
                 NSPoint gpsPoint = node->_point;
                 BOOL pointVisible = NSPointInRect(gpsPoint, _visibleMapSection);
                 if (!pointVisible) // gpsPoint liegt ausserhalb von _visibleMapSection
                   {
                    //                     continue;
                   }
                 NSPoint point = [self pixelFromGPS:gpsPoint];
                 if (gotStarted == NO)
                   {
                    pixelStartPoint = point;
                   }

                 if (gotStarted == NO)
                   {
                    //                     NSLog(@"moveToPoint: %@", NSStringFromPoint(point));
                    [currentBezier moveToPoint:point];
                    gotStarted = YES;
                   }
                 else if (currentPathIsClosedPath && i == count -1)
                   {
                    //                     NSLog(@"lineToPoint: %@", NSStringFromPoint(point));
                    //                     [currentBezier lineToPoint:pixelStartPoint]; // return to exact start point
                    [currentBezier closePath];
                   }
                 else
                   {
                    //                     NSLog(@"lineToPoint: %@", NSStringFromPoint(point));
                    [currentBezier lineToPoint:point];
                   }
                }




              // create label
              if (name != nil && [name length] > 0) // create MapLabel for the street name
                {
                 //                  BOOL drawLabel = (_visibleMapSection.size.height < MAXHEIGHTFORPRIMARYLABELS);
                 BOOL drawLabel = (_visibleMapSection.size.height < MAXHEIGHTFORWAYLABELS);
//                  NSLog(@"drawLabel %d", drawLabel);
                 if (drawLabel)
                   {
                    NSPoint center = [ESMMapLabel centerPointForNodes:nodesArray];
                    ESMMapLabel *mapLabel = [[ESMMapLabel alloc] initWithPoint:[self pixelFromGPS:center] name:name kind:NODEKIND_VILLAGE]; // -1 means street label
                    NSSize size = [name sizeWithAttributes:[mapLabel attributes]];
                    [mapLabel movePointBy:NSMakePoint(-size.width / 3, 0)];
                    [mapLabel setAngle:0]; // angle
                    [mapView->_mapLabels addObject:mapLabel];
                    [mapLabel release];
                   }
                }




             }
          }


        /* *** add ESMMapLocs to mapView *** */
          {
           NSEnumerator *enumerator = [locations objectEnumerator];
           NSDictionary *dic;
           while (dic = [enumerator nextObject])
             {
              NSString *mark = [dic objectForKey:@"mark"];
              NSString *bitmap = [dic objectForKey:@"bitmap"];
              NSLog(@"mark %@ bitmap %@", mark, bitmap);
              NSNumber *x = [dic objectForKey:@"x"];
              NSNumber *y = [dic objectForKey:@"y"];
              NSNumber *direction = [dic objectForKey:@"direction"];
              NSLog(@"mark %@ direction %@", mark, direction);
              if ((x) && (y) && (bitmap))
                {
                 NSPoint point = [self pixelFromGPS:NSMakePoint([x floatValue], [y floatValue])];
                 ESMMapLoc *mapLoc = [[ESMMapLoc alloc] initWithPoint:point mark:((mark) && drawTextMarks ? mark : @"P")  bitmap:bitmap];
                 //                  [mapView addMapLoc:mapLoc];
                 [mapView->_mapLocs addObject:mapLoc];
                 [mapLoc release];
                }
             }
          }

        /* *** add hint paths to mapView *** */
          {
           NSEnumerator *enumerator = [hintPaths objectEnumerator];
           NSDictionary *dic;
           //            NSLog(@"add hint paths to mapView %d", [hintPaths count]);
           while (dic = [enumerator nextObject])
             {
              NSColor *color = [SRHintPath colorFromColorString:[dic objectForKey:@"colorString"]];
              BOOL drawArrows = [[dic objectForKey:@"drawArrows"] isEqualToString:@"YES"];
              NSLog(@"colorString %@ color %@ drawArrows %d", [dic objectForKey:@"colorString"], color, drawArrows);
              ESMMapLine *mapLine = ((color) ? [[ESMMapLine alloc] initWithColor:color] : [[ESMMapLine alloc] initWithColorName:[dic objectForKey:@"dominantColorName"]]);
              NSArray *nodes = [dic objectForKey:@"nodes"];
              NSEnumerator *enumerator = [nodes objectEnumerator];
              NSDictionary *dic;
              int count = [nodes count];
              int counter = 0;
              int margin = count / 10;
              if (margin == 0) margin = 1;
              while (dic = [enumerator nextObject])
                {
                 NSNumber *x = [dic objectForKey:@"x"];
                 NSNumber *y = [dic objectForKey:@"y"];
                 if ((x) && (y))
                   {
                    NSPoint point = [self pixelFromGPS:NSMakePoint([x floatValue], [y floatValue])];
                    [mapLine addPoint:point];
                   }
                 counter++;
                 if (drawArrows && counter > margin)
                   {
                    [mapLine addArrow];
                    counter = 0;
                   }
                }
              [mapView->_mapLines addObject:mapLine];
              [mapLine release];
             }
          }
        #endif

       }
     if ([presentations count])
       {
        [mapView sortMapPaths];
        [mapView sortMapLabels];
       }

     //      NSLog(@"going to display ...");
     //      if (_sharedMapView) [mapView setImage:nil];
     //      NSLog(@"going to lockFocus ...");
     //      NSLog(@"convertSize %@", NSStringFromSize([mapView convertSize:unitSize toView:nil]));
     NSData *data = nil;

     if (_sharedMapView)
       {
        [mapView prepareOSMDrawing];
        NSLog(@"%@ calling display ..", mapView);
        [mapView display];
        NSLog(@"%@ display done", mapView);
       }
     else
       {
        [mapView display];
        NS_DURING
        NSLog(@"%@ locking Focus ...", mapView);
        [mapView lockFocus];
        NSLog(@"getting rep ...");
        //      NSLog(@"window frame %@", NSStringFromRect([[mapView window] frame]));
        //      NSLog(@"contentView frame %@", NSStringFromRect([[[mapView window] contentView] frame]));
        //      NSLog(@"frame %@", NSStringFromRect([mapView frame]));
        //      NSLog(@"bounds %@", NSStringFromRect([mapView bounds]));
        NSBitmapImageRep *rep = [[NSBitmapImageRep alloc] initWithFocusedViewRect:[mapView bounds]];
        NSLog(@"rep %@", rep);
        data = [[[rep representationUsingType:NSPNGFileType properties:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:1] forKey:@"NSImageInterlaced"]] retain] autorelease];
/*           {
           NSString *path = @"/home/ahoesch/A.tiff";
           NSData *data = [[[rep representationUsingType:NSTIFFFileType properties:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:1] forKey:@"NSImageInterlaced"]] retain] autorelease];
           [data writeToFile:path atomically:YES];
          }
 */
        if ([data length] == 0) // try TIFF instead
          {
           NSLog(@"Getting PNG data failed! We try TIFF instead ...");
           //      NSData *data = [[[rep TIFFRepresentation] retain] autorelease];
           data = [[[rep representationUsingType:NSTIFFFileType properties:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:1] forKey:@"NSImageInterlaced"]] retain] autorelease];
           if ([data length] == 0) NSLog(@"Damn! TIFF failed as well!");
          }
        [mapView unlockFocus];
        NSLog(@"%@ unocked Focus!", mapView);
        [rep release];
        NS_HANDLER
        NSLog(@"Something went terribly wrong: %@", [localException description]);
        //      NSView *clipView = [mapView superview];
        //      NSLog(@"clipView %@ bounds %@", NSStringFromRect([clipView frame]), NSStringFromRect([clipView bounds]));
        NS_ENDHANDLER
       }

     NSLog(@"data %d", [data length]);
     [window release];
     [mapView release];
     return [NSDictionary dictionaryWithObjectsAndKeys:
     [NSNumber numberWithFloat:_visibleMapSection.origin.x], @"visibleMapSection.origin.x",
     [NSNumber numberWithFloat:_visibleMapSection.origin.y], @"visibleMapSection.origin.y",
     [NSNumber numberWithFloat:_visibleMapSection.size.width], @"visibleMapSection.size.width",
     [NSNumber numberWithFloat:_visibleMapSection.size.height], @"visibleMapSection.size.height",
     data, @"imageData",
     nil];
    }
  else return nil;
}



Reply | Threaded
Open this post in threaded view
|

Re: cairo drawing problem

ivucica
On Wed, Jun 17, 2020 at 10:09 AM Andreas Höschler via Discussion list
for the GNUstep programming environment <[hidden email]>
wrote:
> > Then I saw the rest of the code you attached. My thought goes in the direction of ‘_sharedMapView’-related code. Even though you’re allocating a whole new window only when the map view is not shared, you seem to be releasing window unconditionally.
>
> The ivar window is either nil (in case of _sharedMapView != nil) or initialised with window = [[NSWindow alloc] init...] (in case of _sharedMapView == nil), so the [window release] should be fine!?

This is very nonobvious, and if I were doing code review for this, I'd
recommend code cleanup.

> This stack trace does not look very helpful (at least to me). :-(

Ah, I should have expected this. X's async nature means errors can get
detected 'late'.

Sadly, I have no better thoughts on how to triage which X resource is
getting destroyed.