int renderPolygonTiledGD(imageObj *img, shapeObj *p, imageObj *tile) { gdImagePtr ip, tp; if(!img || !p || !tile) return MS_FAILURE; if(!(ip = MS_IMAGE_GET_GDIMAGEPTR(img))) return MS_FAILURE; if(!(tp = MS_IMAGE_GET_GDIMAGEPTR(tile))) return MS_FAILURE; gdImageColorTransparent(tp,0); gdImageSetTile(ip, tp); imageFilledPolygon(ip, p, gdTiled); return MS_SUCCESS; }
int mergeRasterBufferGD(imageObj *dest, rasterBufferObj *overlay, double opacity, int srcX, int srcY, int dstX, int dstY, int width, int height) { assert(dest && overlay); assert(overlay->type == MS_BUFFER_GD); gdImageCopyMerge(MS_IMAGE_GET_GDIMAGEPTR(dest),overlay->data.gd_img,dstX,dstY,srcX,srcY,width,height,opacity*100); return MS_SUCCESS; }
int renderPixmapSymbolGD(imageObj *img, double x, double y, symbolObj *symbol, symbolStyleObj *style) { gdImagePtr ip,pp; if(!(ip = MS_IMAGE_GET_GDIMAGEPTR(img))) return MS_FAILURE; assert(symbol->pixmap_buffer && symbol->pixmap_buffer->type == MS_BUFFER_GD); pp = symbol->pixmap_buffer->data.gd_img; /* gdImageAlphaBlending(ip,1); */ /* gdImageAlphaBlending(pp,1); */ if(symbol->transparent) gdImageColorTransparent(pp,symbol->transparentcolor); if(style->scale == 1.0 && style->rotation == 0.0) { /* don't scale */ x -= .5*symbol->pixmap_buffer->width; y -= .5*symbol->pixmap_buffer->height; gdImageCopy(ip, pp, x, y, 0, 0, symbol->pixmap_buffer->width,symbol->pixmap_buffer->height); } else { int bRotated = MS_FALSE; if(style->rotation) { bRotated = MS_TRUE; pp = rotatePixmapGD(pp,style->rotation); } x -= .5*gdImageSX(pp)*style->scale; y -= .5*gdImageSY(pp)*style->scale; gdImageCopyResampled(ip, pp, x, y, 0, 0, (int)(gdImageSX(pp) * style->scale), (int)(gdImageSY(pp) * style->scale), gdImageSX(pp),gdImageSY(pp)); if(bRotated) { gdImageDestroy(pp); } } /* gdImageAlphaBlending(ip,0); */ return MS_SUCCESS; }
/* ** GD driver-specific raster buffer functions. */ int getRasterBufferHandleGD(imageObj *img, rasterBufferObj *rb) { gdImagePtr gdImg = MS_IMAGE_GET_GDIMAGEPTR(img); rb->type = MS_BUFFER_GD; rb->data.gd_img = gdImg; rb->width = gdImg->sx; rb->height = gdImg->sy; return MS_SUCCESS; }
int renderPolygonGD(imageObj *img, shapeObj *p, colorObj *color) { gdImagePtr ip; if(!img || !p || !color) return MS_FAILURE; if(!(ip = MS_IMAGE_GET_GDIMAGEPTR(img))) return MS_FAILURE; SETPEN(ip, color); imageFilledPolygon(ip, p, color->pen); return MS_SUCCESS; }
int saveImageGD(imageObj *img, mapObj *map, FILE *fp, outputFormatObj *format) { gdImagePtr ip; if(!img || !fp) return MS_FAILURE; if(!(ip = MS_IMAGE_GET_GDIMAGEPTR(img))) return MS_FAILURE; return saveGdImage(ip,fp,format); }
int freeImageGD(imageObj *img) { gdImagePtr ip; if(img) { ip = MS_IMAGE_GET_GDIMAGEPTR(img); if(ip) gdImageDestroy(ip); } return MS_SUCCESS; }
int getRasterBufferCopyGD(imageObj *img, rasterBufferObj *rb) { gdImagePtr gdImg = MS_IMAGE_GET_GDIMAGEPTR(img); int row; rb->type = MS_BUFFER_GD; rb->width = gdImg->sx; rb->height = gdImg->sy; rb->data.gd_img = gdImageCreate(gdImg->sx,gdImg->sy); rb->data.gd_img->transparent = gdImg->transparent; gdImagePaletteCopy(rb->data.gd_img,gdImg); for(row=0;row<gdImg->sy;row++) memcpy(rb->data.gd_img->pixels[row],gdImg->pixels[row],gdImg->sx); return MS_SUCCESS; }
int renderGlyphsGD(imageObj *img, double x, double y, labelStyleObj *style, char *text) { #ifdef USE_GD_FREETYPE gdImagePtr ip; char *error=NULL; int bbox[8]; int c = 0,oc = 0; x = MS_NINT(x); y = MS_NINT(y); if(!(ip = MS_IMAGE_GET_GDIMAGEPTR(img))) return MS_FAILURE; if(!text || !strlen(text)) return(MS_SUCCESS); /* not errors, just don't want to do anything */ SETPEN(ip, style->color); SETPEN(ip, style->outlinecolor); if(style->antialias) { if(style->color) c = style->color->pen; if(style->outlinewidth > 0) oc = style->outlinecolor->pen; } else { if(style->color) c = -style->color->pen; if(style->outlinewidth > 0) oc = -style->outlinecolor->pen; } if(style->outlinewidth > 0) { /* handle the outline color */ error = gdImageStringFT(ip, bbox, oc, style->fonts[0], style->size, style->rotation, x, y-1, text); if(error) { msSetError(MS_TTFERR, "%s", "msDrawTextGD()", error); return(MS_FAILURE); } gdImageStringFT(ip, bbox, oc, style->fonts[0], style->size, style->rotation, x, y+1, text); gdImageStringFT(ip, bbox, oc, style->fonts[0], style->size, style->rotation, x+1, y, text); gdImageStringFT(ip, bbox, oc, style->fonts[0], style->size, style->rotation, x-1, y, text); gdImageStringFT(ip, bbox, oc, style->fonts[0], style->size, style->rotation, x-1, y-1, text); gdImageStringFT(ip, bbox, oc, style->fonts[0], style->size, style->rotation, x-1, y+1, text); gdImageStringFT(ip, bbox, oc, style->fonts[0], style->size, style->rotation, x+1, y-1, text); gdImageStringFT(ip, bbox, oc, style->fonts[0], style->size, style->rotation, x+1, y+1, text); } if(style->color) gdImageStringFT(ip, bbox, c, style->fonts[0], style->size, style->rotation, x, y, text); return MS_SUCCESS; #else msSetError(MS_TTFERR, "Freetype support not enabled in this GD build", "renderGlyphsGD()"); return MS_FAILURE; #endif }
int renderEllipseSymbolGD(imageObj *img, double x, double y, symbolObj *symbol, symbolStyleObj *style) { /* check for trivial cases - 1x1 and 2x2, GD does not do these well */ gdImagePtr ip; int w,h,fc,oc; if(!(ip = MS_IMAGE_GET_GDIMAGEPTR(img))) return MS_FAILURE; SETPEN(ip, style->color); SETPEN(ip, style->outlinecolor); fc = style->color ? style->color->pen : -1; oc = style->outlinecolor ? style->outlinecolor->pen : -1; if(oc==-1 && fc ==-1) { return MS_SUCCESS; } w = symbol->sizex * style->scale; h = symbol->sizey * style->scale; if(w==1 && h==1) { if(fc >= 0) gdImageSetPixel(ip, x, y, fc); else gdImageSetPixel(ip, x, y, oc); return MS_SUCCESS; } if(w==2 && h==2) { if(oc >= 0) { gdImageSetPixel(ip, x, y, oc); gdImageSetPixel(ip, x, y+1, oc); gdImageSetPixel(ip, x+1, y, oc); gdImageSetPixel(ip, x+1, y+1, oc); } else { gdImageSetPixel(ip, x, y, fc); gdImageSetPixel(ip, x, y+1, fc); gdImageSetPixel(ip, x+1, y, fc); gdImageSetPixel(ip, x+1, y+1, fc); } return MS_SUCCESS; } if(symbol->filled) { if(fc >= 0) gdImageFilledEllipse(ip, x, y, w, h, fc); if(oc >= 0) gdImageArc(ip, x, y, w, h, 0, 360, oc); } else { if(fc < 0) fc = oc; /* try the outline color */ gdImageArc(ip, x, y, w, h, 0, 360, fc); } return MS_SUCCESS; }
int renderBitmapGlyphsGD(imageObj *img, double x, double y, labelStyleObj *style, char *text) { int size = MS_NINT(style->size); gdFontPtr fontPtr; gdImagePtr ip; int numlines=0,t; char **lines; if(!(ip = MS_IMAGE_GET_GDIMAGEPTR(img))) return MS_FAILURE; if(size<0 || size>4 || (fontPtr = msGetBitmapFont(size))==NULL) { msSetError(MS_RENDERERERR,"invalid bitmap font size", "renderBitmapGlyphsGD()"); return MS_FAILURE; } SETPEN(ip, style->color); SETPEN(ip, style->outlinecolor); if(msCountChars(text,'\n')) { if((lines = msStringSplit((const char*)text, '\n', &(numlines))) == NULL) return(-1); } else { lines = &text; numlines = 1; } y -= fontPtr->h; for(t=0; t<numlines; t++) { if(style->outlinewidth > 0) { gdImageString(ip, fontPtr, x, y-1, (unsigned char *) lines[t], style->outlinecolor->pen); gdImageString(ip, fontPtr, x, y+1, (unsigned char *) lines[t], style->outlinecolor->pen); gdImageString(ip, fontPtr, x+1, y, (unsigned char *) lines[t], style->outlinecolor->pen); gdImageString(ip, fontPtr, x-1, y, (unsigned char *) lines[t], style->outlinecolor->pen); gdImageString(ip, fontPtr, x+1, y-1, (unsigned char *) lines[t], style->outlinecolor->pen); gdImageString(ip, fontPtr, x+1, y+1, (unsigned char *) lines[t], style->outlinecolor->pen); gdImageString(ip, fontPtr, x-1, y-1, (unsigned char *) lines[t], style->outlinecolor->pen); gdImageString(ip, fontPtr, x-1, y+1, (unsigned char *) lines[t], style->outlinecolor->pen); } if(style->color->pen != -1) { gdImageString(ip, fontPtr, x, y, (unsigned char *) lines[t], style->color->pen); } y += fontPtr->h; /* shift down */ } if(lines != &text) msFreeCharArray(lines, numlines); return MS_SUCCESS; }
int renderTruetypeSymbolGD(imageObj *img, double x, double y, symbolObj *symbol, symbolStyleObj *s) { #ifdef USE_GD_FREETYPE int bbox[8]; char *error; int c,oc = 0; gdImagePtr ip; if(!(ip = MS_IMAGE_GET_GDIMAGEPTR(img))) return MS_FAILURE; SETPEN(ip, s->color); SETPEN(ip, s->outlinecolor); if(s->style->antialias) { c = s->color->pen; if(s->outlinecolor) oc = s->outlinecolor->pen; } else { c = -s->color->pen; if(s->outlinecolor) oc = -s->outlinecolor->pen; } gdImageStringFT(NULL, bbox, c, symbol->full_font_path, s->scale, s->rotation, 0,0, symbol->character); x -= (bbox[2] - bbox[0])/2 + bbox[0]; y += (bbox[1] - bbox[5])/2 - bbox[1]; if( s->outlinecolor ) { error = gdImageStringFT(ip, bbox, oc, symbol->full_font_path, s->scale, s->rotation, x, y-1, symbol->character); if(error) { msSetError(MS_TTFERR, "%s", "renderTruetypeSymbolGD()", error); return MS_FAILURE; } gdImageStringFT(ip, bbox, oc, symbol->full_font_path, s->scale, s->rotation, x, y+1, symbol->character); gdImageStringFT(ip, bbox, oc, symbol->full_font_path, s->scale, s->rotation, x+1, y, symbol->character); gdImageStringFT(ip, bbox, oc, symbol->full_font_path, s->scale, s->rotation, x-1, y, symbol->character); gdImageStringFT(ip, bbox, oc, symbol->full_font_path, s->scale, s->rotation, x+1, y+1, symbol->character); gdImageStringFT(ip, bbox, oc, symbol->full_font_path, s->scale, s->rotation, x+1, y-1, symbol->character); gdImageStringFT(ip, bbox, oc, symbol->full_font_path, s->scale, s->rotation, x-1, y+1, symbol->character); gdImageStringFT(ip, bbox, oc, symbol->full_font_path, s->scale, s->rotation, x-1, y-1, symbol->character); } if(s->color) gdImageStringFT(ip, bbox, c, symbol->full_font_path, s->scale, s->rotation, x, y, symbol->character); return MS_SUCCESS; #else msSetError(MS_TTFERR, "Freetype support not enabled in this GD build", "renderTruetypeSymbolGD()"); return MS_FAILURE; #endif }
int renderVectorSymbolGD(imageObj *img, double x, double y, symbolObj *symbol, symbolStyleObj *style) { int bRotated = MS_FALSE; int j,k; gdImagePtr ip; gdPoint mPoints[MS_MAXVECTORPOINTS]; gdPoint oldpnt,newpnt; int fc,oc; if(!(ip = MS_IMAGE_GET_GDIMAGEPTR(img))) return MS_FAILURE; SETPEN(ip, style->color); SETPEN(ip, style->outlinecolor); fc = style->color ? style->color->pen : -1; oc = style->outlinecolor ? style->outlinecolor->pen : -1; if(oc==-1 && fc ==-1) { return MS_SUCCESS; } if (style->rotation != 0.0) { bRotated = MS_TRUE; symbol = rotateVectorSymbolPoints(symbol, style->rotation); if(!symbol) { return MS_FAILURE; } } /* We avoid MS_NINT in this context because the potentially variable handling of 0.5 rounding is often a problem for symbols which are often an odd size (ie. 7pixels) and so if "p" is integral the value is always on a 0.5 boundary - bug 1716 */ x -= style->scale*.5*symbol->sizex; y -= style->scale*.5*symbol->sizey; if(symbol->filled) { /* if filled */ k = 0; /* point counter */ for(j=0; j < symbol->numpoints; j++) { if((symbol->points[j].x == -99) && (symbol->points[j].y == -99)) { /* new polygon (PENUP) */ if(k>2) { if(fc >= 0) gdImageFilledPolygon(ip, mPoints, k, fc); if(oc >= 0) gdImagePolygon(ip, mPoints, k, oc); } k = 0; /* reset point counter */ } else { mPoints[k].x = MS_NINT(style->scale*symbol->points[j].x + x); mPoints[k].y = MS_NINT(style->scale*symbol->points[j].y + y); k++; } } if(fc >= 0) gdImageFilledPolygon(ip, mPoints, k, fc); if(oc >= 0) gdImagePolygon(ip, mPoints, k, oc); } else { /* NOT filled */ if(oc >= 0) fc = oc; /* try the outline color (reference maps sometimes do this when combining a box and a custom vector marker */ oldpnt.x = MS_NINT(style->scale*symbol->points[0].x + x); /* convert first point in marker */ oldpnt.y = MS_NINT(style->scale*symbol->points[0].y + y); gdImageSetThickness(ip, style->outlinewidth); for(j=1; j < symbol->numpoints; j++) { /* step through the marker */ if((symbol->points[j].x != -99) || (symbol->points[j].y != -99)) { if((symbol->points[j-1].x == -99) && (symbol->points[j-1].y == -99)) { /* Last point was PENUP, now a new beginning */ oldpnt.x = MS_NINT(style->scale*symbol->points[j].x + x); oldpnt.y = MS_NINT(style->scale*symbol->points[j].y + y); } else { newpnt.x = MS_NINT(style->scale*symbol->points[j].x + x); newpnt.y = MS_NINT(style->scale*symbol->points[j].y + y); gdImageLine(ip, oldpnt.x, oldpnt.y, newpnt.x, newpnt.y, fc); oldpnt = newpnt; } } } /* end for loop */ gdImageSetThickness(ip, 1); /* restore thinkness */ } /* end if-then-else */ if(bRotated) { msFreeSymbol(symbol); /* clean up */ msFree(symbol); } return MS_SUCCESS; }
int renderLineGD(imageObj *img, shapeObj *p, strokeStyleObj *stroke) { gdImagePtr ip; int c; gdImagePtr brush=NULL; if(!img || !p || !stroke) return MS_FAILURE; if(!(ip = MS_IMAGE_GET_GDIMAGEPTR(img))) return MS_FAILURE; SETPEN(ip, stroke->color); c = stroke->color->pen; if(stroke->patternlength > 0) { int *style; int i, j, k=0; int sc; for(i=0; i<stroke->patternlength; i++) k += MS_NINT(stroke->pattern[i]); style = (int *) malloc (k * sizeof(int)); MS_CHECK_ALLOC(style, k * sizeof(int), MS_FAILURE); sc = c; /* start with the color */ k=0; for(i=0; i<stroke->patternlength; i++) { for(j=0; j<MS_NINT(stroke->pattern[i]); j++, k++) { style[k] = sc; } sc = ((sc==c)?gdTransparent:c); } gdImageSetStyle(ip, style, k); free(style); c = gdStyled; } if(stroke->width > 1) { int brush_fc; brush = gdImageCreate(ceil(stroke->width), ceil(stroke->width)); gdImageColorAllocate(brush, gdImageRed(ip,0), gdImageGreen(ip, 0), gdImageBlue(ip, 0)); gdImageColorTransparent(brush,0); brush_fc = gdImageColorAllocate(brush, gdImageRed(ip,stroke->color->pen), gdImageGreen(ip,stroke->color->pen), gdImageBlue(ip,stroke->color->pen)); gdImageFilledEllipse(brush,MS_NINT(brush->sx/2),MS_NINT(brush->sy/2), MS_NINT(stroke->width),MS_NINT(stroke->width), brush_fc); gdImageSetBrush(ip, brush); if(stroke->patternlength > 0) { c = gdStyledBrushed; } else { c = gdBrushed; } } /* finally draw something */ imagePolyline(ip, p, c); /* clean up */ if(stroke->width>1) { gdImageDestroy(brush); } return MS_SUCCESS; }