void agg_renderer<T>::process(shield_symbolizer const& sym, mapnik::feature_impl & feature, proj_transform const& prj_trans) { for (std::list<feature_ptr>::iterator f = featureList_->begin(); f != featureList_->end(); f++) { feature_ptr featurePtr = *f; shield_symbolizer_helper<face_manager<freetype_engine>, label_collision_detector4> helper( sym, *featurePtr, prj_trans, width_, height_, scale_factor_, t_, font_manager_, *detector_, query_extent_); text_renderer<T> ren(*current_buffer_, font_manager_, *(font_manager_.get_stroker()), sym.comp_op(), scale_factor_); while (helper.next()) { placements_type const& placements = helper.placements(); for (unsigned int ii = 0; ii < placements.size(); ++ii) { // get_marker_position returns (minx,miny) corner position, // while (currently only) agg_renderer::render_marker newly // expects center position; // until all renderers and shield_symbolizer_helper are // modified accordingly, we must adjust the position here pixel_position pos = helper.get_marker_position(placements[ii]); // pos.x += 0.5 * helper.get_marker_width(); // pos.y += 0.5 * helper.get_marker_height(); // render_marker(pos, // helper.get_marker(), // helper.get_image_transform(), // sym.get_opacity(), // sym.comp_op()); marker const& marker_ = helper.get_marker(); image_data_32 const& src = **marker_.get_bitmap_data(); double width = src.width(); double height = src.height(); const double shifted = 0; double markerX = pos.x + shifted, markerY = height_ - pos.y - shifted - height; glMatrixLoadIdentityEXT(GL_PROJECTION); glMatrixOrthoEXT(GL_PROJECTION, 0, width_, height_, 0, -1, 1); glMatrixLoadIdentityEXT(GL_MODELVIEW); GLubyte cmd[5]; GLfloat coord[8]; int m = 0, n = 0; cmd[m++] = GL_MOVE_TO_NV; coord[n++] = markerX; coord[n++] = markerY; cmd[m++] = GL_LINE_TO_NV; coord[n++] = markerX + width; coord[n++] = markerY; cmd[m++] = GL_LINE_TO_NV; coord[n++] = markerX + width; coord[n++] = markerY + height; cmd[m++] = GL_LINE_TO_NV; coord[n++] = markerX; coord[n++] = markerY + height; cmd[m++] = GL_CLOSE_PATH_NV; glPathCommandsNV(pathObject_, m, cmd, n, GL_FLOAT, coord); // glStencilFunc(GL_NOTEQUAL, 0, 0x1F); // glStencilOp(GL_KEEP, GL_KEEP, GL_ZERO); //makeFaceTexture(TEXTURE_FACE); static GLuint texName; glGenTextures(1, &texName); glBindTexture(GL_TEXTURE_2D, texName); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (unsigned char *)src.getBytes()); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); GLfloat data[2][3] = { { 1,0,0 }, /* s = 1*x + 0*y + 0 */ { 0,1,0 } }; /* t = 0*x + 1*y + 0 */ //glEnable(GL_STENCIL_TEST); //glColor3f(1,1,1); glEnable(GL_TEXTURE_2D); glPathTexGenNV(GL_TEXTURE0, GL_PATH_OBJECT_BOUNDING_BOX_NV, 2, &data[0][0]); glStencilFillPathNV(pathObject_, GL_COUNT_UP_NV, 0x1F); glCoverFillPathNV(pathObject_, GL_BOUNDING_BOX_NV); glDisable(GL_TEXTURE_2D); pathObject_++; //Text rendering //ren.prepare_glyphs(placements[ii]); //ren.render(placements[ii].center); const int size = placements[ii].num_nodes(); int strokeEnable = 0; char word[size]; unsigned red,green,blue,alpha; double textWidth = 0; double textHeight = 0; color textColor,strokeColor; double opacity = 0.0; for (int i = 0; i < placements[ii].num_nodes(); i++) { char_info_ptr c; double x, y, angle; placements[ii].vertex(&c, &x, &y, &angle); word[i] = (char)c->c; textWidth += c->width; textHeight = c->height(); double halo_radius = c->format->halo_radius; if (halo_radius > 0.0 && halo_radius < 1024.0){ strokeEnable = 1; // red = c->format->halo_fill.red(); // green = c->format->halo_fill.green(); // blue = c->format->halo_fill.blue(); // alpha = c->format->halo_fill.alpha(); strokeColor = c->format->halo_fill; } textColor = c->format->fill; opacity = c->format->text_opacity; } double posX = placements[ii].center.x, posY = placements[ii].center.y; int centerText = textWidth / 2; double posTextY = height_ - markerY - (height)/2; double posTextX = posX - centerText; if(posTextY <= height_ / 2) posTextY -= 5; if(posTextX >= width_ / 2) posTextX += 5; if(!strokeEnable){ render_text(size, word, posTextX, posTextY,textColor, opacity); } if(strokeEnable){ render_text(size, word, posTextX, posTextY,textColor,strokeColor,opacity); } } } } }
void NVprPathRendererState::coverFill() { glCoverFillPathNV(path, fill_cover_mode); }
static void nvpr_render_shape(void *render, LVGShapeCollection *shapecol, LVGColorTransform *cxform, float ratio, int blend_mode) { //render_ctx *ctx = render; for (int j = 0; j < shapecol->num_shapes; j++) { NSVGshape *shape = shapecol->shapes + j; NSVGshape *shape2 = shapecol->morph ? shapecol->morph->shapes + j : 0; GLuint pathObj = shape->cache; if (shape2) pathObj = morph_shape(shape, shape2, ratio); /*GLfloat object_bbox[4], fill_bbox[4], stroke_bbox[4]; glGetPathParameterfvNV(pathObj, GL_PATH_OBJECT_BOUNDING_BOX_NV, object_bbox); glGetPathParameterfvNV(pathObj, GL_PATH_FILL_BOUNDING_BOX_NV, fill_bbox); glGetPathParameterfvNV(pathObj, GL_PATH_STROKE_BOUNDING_BOX_NV, stroke_bbox);*/ glEnable(GL_BLEND); glBlendEquation(GL_FUNC_ADD); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); switch(blend_mode) { case BLEND_LAYER: assert(0); break; case BLEND_MULTIPLY: glBlendFunc(GL_DST_COLOR, GL_ONE_MINUS_SRC_ALPHA); break; case BLEND_SCREEN: glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR); break; case BLEND_LIGHTEN: glBlendFunc(GL_ONE, GL_ONE); glBlendEquation(GL_MAX); break; case BLEND_DARKEN: glBlendFunc(GL_ONE, GL_ONE); glBlendEquation(GL_MIN); break; case BLEND_DIFFERENCE: assert(0); break; case BLEND_ADD: glBlendFunc(GL_ONE, GL_ONE); break; case BLEND_SUBTRACT: glBlendFunc(GL_ONE, GL_ONE); glBlendEquation(GL_FUNC_REVERSE_SUBTRACT); break; case BLEND_INVERT: assert(0); break; case BLEND_ALPHA: assert(0); break; case BLEND_ERASE: assert(0); break; case BLEND_OVERLAY: assert(0); glBlendFunc(GL_DST_COLOR, GL_ONE_MINUS_SRC_ALPHA); break; case BLEND_HARDLIGHT: assert(0); break; } glStencilFunc(GL_NOTEQUAL, 0, 0x1F); glStencilOp(GL_KEEP, GL_KEEP, GL_ZERO); glEnable(GL_STENCIL_TEST); if (NSVG_PAINT_NONE != shape->fill.type) { if (NSVG_PAINT_COLOR == shape->fill.type) { NVGcolor c = transformColor(nvgColorU32(shape->fill.color), cxform); glColor4f(c.r, c.g, c.b, c.a); } else if (NSVG_PAINT_LINEAR_GRADIENT == shape->fill.type) LinearGrad(shape, cxform, 1); else if (NSVG_PAINT_RADIAL_GRADIENT == shape->fill.type) RadialGrad(shape, cxform, 1); else if (NSVG_PAINT_IMAGE == shape->fill.type) ImagePaint(shape, cxform, 1); glStencilFillPathNV(pathObj, (NSVG_FILLRULE_EVENODD == shape->fillRule) ? GL_INVERT : GL_COUNT_UP_NV, 0x1F); glCoverFillPathNV(pathObj, GL_BOUNDING_BOX_NV); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glPathTexGenNV(GL_TEXTURE0, GL_NONE, 0, NULL); glPathColorGenNV(GL_PRIMARY_COLOR, GL_NONE, 0, NULL); glDisable(GL_TEXTURE_2D); } if (/*NSVG_PAINT_NONE != shape->stroke.type*/NSVG_PAINT_COLOR == shape->stroke.type) { if (NSVG_PAINT_COLOR == shape->stroke.type) { NVGcolor c = transformColor(nvgColorU32(shape->stroke.color), cxform); glColor4f(c.r, c.g, c.b, c.a); }/* else if (NSVG_PAINT_LINEAR_GRADIENT == shape->stroke.type) LinearGrad(shape, cxform, 0); else if (NSVG_PAINT_RADIAL_GRADIENT == shape->stroke.type) RadialGrad(shape, cxform, 0); else if (NSVG_PAINT_IMAGE == shape->stroke.type) ImagePaint(shape, cxform, 0);*/ glPathParameterfNV(pathObj, GL_PATH_STROKE_WIDTH_NV, shape->strokeWidth); if (NSVG_JOIN_ROUND == shape->strokeLineJoin) glPathParameteriNV(pathObj, GL_PATH_JOIN_STYLE_NV, GL_ROUND_NV); else if (NSVG_JOIN_BEVEL == shape->strokeLineJoin) glPathParameteriNV(pathObj, GL_PATH_JOIN_STYLE_NV, GL_BEVEL_NV); else if (NSVG_JOIN_MITER == shape->strokeLineJoin) glPathParameteriNV(pathObj, GL_PATH_JOIN_STYLE_NV, GL_MITER_TRUNCATE_NV); glPathParameterfNV(pathObj, GL_PATH_MITER_LIMIT_NV, shape->miterLimit); if (NSVG_CAP_ROUND == shape->strokeLineCap) glPathParameteriNV(pathObj, GL_PATH_END_CAPS_NV, GL_ROUND_NV); else if (NSVG_CAP_BUTT == shape->strokeLineCap) glPathParameteriNV(pathObj, GL_PATH_END_CAPS_NV, GL_FLAT); else if (NSVG_CAP_SQUARE == shape->strokeLineCap) glPathParameteriNV(pathObj, GL_PATH_END_CAPS_NV, GL_SQUARE_NV); GLint reference = 0x1; glStencilStrokePathNV(pathObj, reference, 0x1F); glCoverStrokePathNV(pathObj, GL_BOUNDING_BOX_NV); glPathColorGenNV(GL_PRIMARY_COLOR, GL_NONE, 0, NULL); } glDisable(GL_STENCIL_TEST); glDisable(GL_BLEND); if (shape2) glDeletePathsNV(pathObj, 1); } }
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_NVPathRendering_nglCoverFillPathNV(JNIEnv *env, jclass clazz, jint path, jint coverMode, jlong function_pointer) { glCoverFillPathNVPROC glCoverFillPathNV = (glCoverFillPathNVPROC)((intptr_t)function_pointer); glCoverFillPathNV(path, coverMode); }