예제 #1
0
int preloadSymbol(symbolSetObj *symbolset, symbolObj *symbol, rendererVTableObj *renderer) {
  switch(symbol->type) {
  case MS_SYMBOL_VECTOR:
  case MS_SYMBOL_ELLIPSE:
  case MS_SYMBOL_SIMPLE:
  case (MS_SYMBOL_TRUETYPE):
    break;
  case (MS_SYMBOL_SVG):
#if defined(USE_SVG_CAIRO) || defined(USE_RSVG)
    return msPreloadSVGSymbol(symbol);
#else
    msSetError(MS_SYMERR, "SVG symbol support is not enabled.", "preloadSymbol()");
    return MS_FAILURE;
#endif
    break;
  case (MS_SYMBOL_PIXMAP): {
    if(!symbol->pixmap_buffer) {
      if(MS_SUCCESS != msPreloadImageSymbol(renderer,symbol))
        return MS_FAILURE;
    }
  }
  break;
  default:
    msSetError(MS_MISCERR,"unsupported symbol type %d", "preloadSymbol()", symbol->type);
    return MS_FAILURE;
  }
  return MS_SUCCESS;
}
예제 #2
0
imageObj *getTile(imageObj *img, symbolObj *symbol,  symbolStyleObj *s, int width, int height,
                  int seamlessmode)
{
  tileCacheObj *tile;
  int status = MS_SUCCESS;
  rendererVTableObj *renderer = img->format->vtable;
  if(width==-1 || height == -1) {
    width=height=MS_MAX(symbol->sizex,symbol->sizey);
  }
  tile = searchTileCache(img,symbol,s,width,height);

  if(tile==NULL) {
    imageObj *tileimg;
    double p_x,p_y;
    tileimg = msImageCreate(width,height,img->format,NULL,NULL,img->resolution, img->resolution, NULL);
    if(UNLIKELY(!tileimg)) {
      return NULL;
    }
    if(!seamlessmode) {
      p_x = width/2.0;
      p_y = height/2.0;
      switch(symbol->type) {
        case (MS_SYMBOL_TRUETYPE):
        {
          unsigned int unicode;
          glyph_element *glyphc;
          face_element *face = msGetFontFace(symbol->font, &img->map->fontset);
          if(UNLIKELY(!face)) { status = MS_FAILURE; break; }
          msUTF8ToUniChar(symbol->character, &unicode);
          unicode = msGetGlyphIndex(face,unicode);
          glyphc = msGetGlyphByIndex(face, s->scale, unicode);
          if(UNLIKELY(!face)) { status = MS_FAILURE; break; }
          status = drawGlyphMarker(tileimg, face, glyphc, p_x, p_y, s->scale, s->rotation,
                s->color, s->outlinecolor, s->outlinewidth);
        }
          break;
        case (MS_SYMBOL_PIXMAP):
          status = msPreloadImageSymbol(renderer,symbol);
          if(UNLIKELY(status == MS_FAILURE)) { break; }
          status = renderer->renderPixmapSymbol(tileimg, p_x, p_y, symbol, s);
          break;
        case (MS_SYMBOL_ELLIPSE):
          status = renderer->renderEllipseSymbol(tileimg, p_x, p_y,symbol, s);
          break;
        case (MS_SYMBOL_VECTOR):
          status = renderer->renderVectorSymbol(tileimg, p_x, p_y, symbol, s);
          break;

        case (MS_SYMBOL_SVG):
#if defined(USE_SVG_CAIRO) || defined(USE_RSVG)
          status = msPreloadSVGSymbol(symbol);
          if(LIKELY(status == MS_SUCCESS)) {
            if (renderer->supports_svg) {
              status = renderer->renderSVGSymbol(tileimg, p_x, p_y, symbol, s);
            } else {
              status = msRenderRasterizedSVGSymbol(tileimg,p_x,p_y,symbol, s);
            }
          }
#else
          msSetError(MS_SYMERR, "SVG symbol support is not enabled.", "getTile()");
          status = MS_FAILURE;
#endif
          break;
        default:
          msSetError(MS_SYMERR, "Unknown symbol type %d", "getTile()", symbol->type);
          status = MS_FAILURE;
          break;
      }
      if(UNLIKELY(status == MS_FAILURE)) {
        msFreeImage(tileimg);
        return NULL;
      }
    } else {
      /*
       * in seamless mode, we render the the symbol 9 times on a 3x3 grid to account for
       * antialiasing blending from one tile to the next. We finally keep the center tile
       */
      imageObj *tile3img = msImageCreate(width*3,height*3,img->format,NULL,NULL,
                                         img->resolution, img->resolution, NULL);
      int i,j;
      rasterBufferObj tmpraster;
      for(i=1; i<=3; i++) {
        p_x = (i+0.5)*width;
        for(j=1; j<=3; j++) {
          p_y = (j+0.5) * height;
          switch(symbol->type) {
            case (MS_SYMBOL_TRUETYPE):
            {
              unsigned int unicode;
              glyph_element *glyphc;
              face_element *face = msGetFontFace(symbol->font, &img->map->fontset);
              if(UNLIKELY(!face)) { status = MS_FAILURE; break; }
              msUTF8ToUniChar(symbol->character, &unicode);
              unicode = msGetGlyphIndex(face,unicode);
              glyphc = msGetGlyphByIndex(face, s->scale, unicode);
              if(UNLIKELY(!glyphc)) { status = MS_FAILURE; break; }
              status = drawGlyphMarker(tileimg, face, glyphc, p_x, p_y, s->scale, s->rotation,
                    s->color, s->outlinecolor, s->outlinewidth);
            }
              break;
            case (MS_SYMBOL_PIXMAP):
              status = msPreloadImageSymbol(renderer,symbol);
              if(UNLIKELY(status == MS_FAILURE)) { break; }
              status = renderer->renderPixmapSymbol(tile3img, p_x, p_y, symbol, s);
              break;
            case (MS_SYMBOL_ELLIPSE):
              status = renderer->renderEllipseSymbol(tile3img, p_x, p_y,symbol, s);
              break;
            case (MS_SYMBOL_VECTOR):
              status = renderer->renderVectorSymbol(tile3img, p_x, p_y, symbol, s);
              break;
            default:
              msSetError(MS_SYMERR, "BUG: Seamless mode is only for vector symbols", "getTile()");
              return NULL;
          }
          if(UNLIKELY(status == MS_FAILURE)) {
            msFreeImage(tile3img);
            return NULL;
          }
        }
      }
      if(UNLIKELY(status == MS_FAILURE)) {
        msFreeImage(tile3img);
        return NULL;
      }

      status = MS_IMAGE_RENDERER(tile3img)->getRasterBufferHandle(tile3img,&tmpraster);
      if(UNLIKELY(status == MS_FAILURE)) {
        msFreeImage(tile3img);
        return NULL;
      }
      status = renderer->mergeRasterBuffer(tileimg,
                                  &tmpraster,
                                  1.0,width,height,0,0,width,height
                                 );
      msFreeImage(tile3img);
    }
    if(UNLIKELY(status == MS_FAILURE)) {
      msFreeImage(tileimg);
      return NULL;
    }
    tile = addTileCache(img,tileimg,symbol,s,width,height);
  }
  return tile->image;
}
예제 #3
0
/*
** Returns the size, in pixels, of a marker symbol defined by a specific style and scalefactor. Used for annotation
** layer collision avoidance. A marker is made up of a number of styles so the calling code must either do the looping
** itself or call this function for the bottom style which should be the largest.
*/
int msGetMarkerSize(symbolSetObj *symbolset, styleObj *style, double *width, double *height, double scalefactor)
{
  rectObj rect;
  int size;
  symbolObj *symbol;
  *width = *height = 0; /* set a starting value */

  if(style->symbol > symbolset->numsymbols || style->symbol < 0) return(MS_FAILURE); /* no such symbol, 0 is OK */

  if(style->symbol == 0) { /* single point */
    *width = 1;
    *height = 1;
    return(MS_SUCCESS);
  }

  symbol = symbolset->symbol[style->symbol];
  if (symbol->type == MS_SYMBOL_PIXMAP && !symbol->pixmap_buffer) {
    if (MS_SUCCESS != msPreloadImageSymbol(MS_MAP_RENDERER(symbolset->map), symbol))
      return MS_FAILURE;
  }
  if(symbol->type == MS_SYMBOL_SVG && !symbol->renderer_cache) {
#ifdef USE_SVG_CAIRO
    if(MS_SUCCESS != msPreloadSVGSymbol(symbol))
      return MS_FAILURE;
#else
    msSetError(MS_SYMERR, "SVG symbol support is not enabled.", "msGetMarkerSize()");
    return MS_FAILURE;
#endif
  }
  if(style->size == -1) {
    size = ( msSymbolGetDefaultSize(symbol) * scalefactor );
  } else
    size = (style->size*scalefactor);
  size = MS_MAX(size, style->minsize);
  size = MS_MIN(size, style->maxsize);

  switch(symbol->type) {

    case(MS_SYMBOL_TRUETYPE):
      if(msGetTruetypeTextBBox(MS_MAP_RENDERER(symbolset->map),symbol->font,symbolset->fontset,size,symbol->character,&rect,NULL,0) != MS_SUCCESS)
        return(MS_FAILURE);

      *width = MS_MAX(*width, rect.maxx - rect.minx);
      *height = MS_MAX(*height, rect.maxy - rect.miny);

      break;

    case(MS_SYMBOL_PIXMAP):
      if(size == 1) {
        *width = MS_MAX(*width, symbol->pixmap_buffer->width);
        *height = MS_MAX(*height, symbol->pixmap_buffer->height);
      } else {
        *width = MS_MAX(*width, (((double)size/(double)symbol->pixmap_buffer->height) * symbol->pixmap_buffer->width));
        *height = MS_MAX(*height, size);
      }
      break;
    default: /* vector and ellipses, scalable */
      if(style->size > 0) {
        *width = MS_MAX(*width, ((size/symbol->sizey) * symbol->sizex));
        *height = MS_MAX(*height, size);
      } else { /* use symbol defaults */
        *width = MS_MAX(*width, symbol->sizex);
        *height = MS_MAX(*height, symbol->sizey);
      }
      break;
  }

  return(MS_SUCCESS);
}