void endPath(PathPtr p) { if (!path) { path = glGenPathsNV(1); } glPathCommandsNV(path, GLsizei(cmds.size()), &cmds[0], GLsizei(coords.size()), GL_FLOAT, &coords[0]); }
void flush(GLuint path) { glPathCommandsNV ( path, GLsizei(commands.size()), commands.data(), GLsizei(points.size() << 1), GL_FLOAT, points.data() ); commands.clear(); points.clear(); }
static int morph_shape(NSVGshape *shape, NSVGshape *shape2, float ratio) { //render_ctx *ctx = render; int cmds = 0, coords = 0; float om_ratio = 1.0f - ratio; NSVGpath *path, *path2; for (path = shape->paths; path != NULL; path = path->next) { if (path->npts > 2) { int ncubic = (path->npts - 1)/3; cmds += 1 + ncubic; coords += 2 + ncubic*6; if (path->closed) cmds++; } } GLubyte *cmd = (GLubyte *)alloca(cmds*sizeof(GLubyte)); GLfloat *coord = alloca(coords*sizeof(GLfloat)); cmds = 0, coords = 0; path2 = shape2->paths; for (path = shape->paths; path != NULL; path = path->next, path2 = path2->next) { if (path->npts > 2) { cmd[cmds] = GL_MOVE_TO_NV; int ncubic = (path->npts - 1)/3; memset(cmd + cmds + 1, GL_CUBIC_CURVE_TO_NV, ncubic); cmds += 1 + ncubic; for (int i = 0; i < (2 + ncubic*6); i++) coord[coords + i] = path->pts[i]*om_ratio + path2->pts[i]*ratio; coords += 2 + ncubic*6; if (path->closed) cmd[cmds++] = GL_CLOSE_PATH_NV; } } GLuint pathObj = glGenPathsNV(1); glPathCommandsNV(pathObj, cmds, cmd, coords, GL_FLOAT, coord); return pathObj; }
static int nvpr_cache_shape(void *render, NSVGshape *shape) { //render_ctx *ctx = render; int cmds = 0, coords = 0; GLuint pathObj = glGenPathsNV(1); NSVGpath *path; for (path = shape->paths; path != NULL; path = path->next) { if (path->npts > 2) { int ncubic = (path->npts - 1)/3; cmds += 1 + ncubic; coords += 2 + ncubic*6; if (path->closed) cmds++; } } GLubyte *cmd = (GLubyte *)alloca(cmds*sizeof(GLubyte)); GLfloat *coord = alloca(coords*sizeof(GLfloat)); cmds = 0, coords = 0; for (path = shape->paths; path != NULL; path = path->next) { if (path->npts > 2) { cmd[cmds] = GL_MOVE_TO_NV; int ncubic = (path->npts - 1)/3; memset(cmd + cmds + 1, GL_CUBIC_CURVE_TO_NV, ncubic); cmds += 1 + ncubic; memcpy(coord + coords, path->pts, (2 + ncubic*6)*sizeof(float)); coords += 2 + ncubic*6; if (path->closed) cmd[cmds++] = GL_CLOSE_PATH_NV; } } glPathCommandsNV(pathObj, cmds, cmd, coords, GL_FLOAT, coord); shape->cache = pathObj; return pathObj; }
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); } } } } }
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_NVPathRendering_nglPathCommandsNV(JNIEnv *env, jclass clazz, jint path, jint numCommands, jlong commands, jint numCoords, jint coordType, jlong coords, jlong function_pointer) { const GLubyte *commands_address = (const GLubyte *)(intptr_t)commands; const GLvoid *coords_address = (const GLvoid *)(intptr_t)coords; glPathCommandsNVPROC glPathCommandsNV = (glPathCommandsNVPROC)((intptr_t)function_pointer); glPathCommandsNV(path, numCommands, commands_address, numCoords, coordType, coords_address); }
void NVPFont::createGlyphs() { if ( mGlyphBase != 0 ) { glDeletePathsNV ( mGlyphBase, 1+numChars ); } mGlyphBase = 0; mPathTemplate = 0; /* Create a range of path objects corresponding to Latin-1 character codes. */ mGlyphBase = glGenPathsNV ( 1+numChars ); /* Use the path object at the end of the range as a template. */ mPathTemplate = mGlyphBase; //set stroke width of path as percentage of emscale glPathCommandsNV ( mPathTemplate, 0, NULL, 0, GL_FLOAT, NULL ); glPathParameteriNV ( mPathTemplate, GL_PATH_STROKE_WIDTH_NV, GLint ( mStrokeWidth * mEmScale ) ); glPathParameteriNV ( mPathTemplate, GL_PATH_JOIN_STYLE_NV, GL_ROUND_NV ); //attempt to load glyphs from mFontname system font. If mFontName can't be found then load Arial. if Arial can't be found //then load the default sans system font glPathGlyphRangeNV ( mGlyphBase, mSystemFont ? GL_SYSTEM_FONT_NAME_NV : GL_FILE_NAME_NV, mFontName.c_str(), GL_NONE, 0, numChars, GL_SKIP_MISSING_GLYPH_NV, mPathTemplate, GLfloat ( mEmScale ) ); glPathGlyphRangeNV ( mGlyphBase, GL_SYSTEM_FONT_NAME_NV, "Arial", GL_NONE, 0, numChars, GL_SKIP_MISSING_GLYPH_NV, mPathTemplate, GLfloat ( mEmScale ) ); glPathGlyphRangeNV ( mGlyphBase, GL_STANDARD_FONT_NAME_NV, "Sans", GL_NONE, 0, numChars, GL_USE_MISSING_GLYPH_NV, mPathTemplate, GLfloat ( mEmScale ) ); float font_data[4]; glGetPathMetricRangeNV ( GL_FONT_Y_MIN_BOUNDS_BIT_NV | GL_FONT_Y_MAX_BOUNDS_BIT_NV | GL_FONT_UNDERLINE_POSITION_BIT_NV | GL_FONT_UNDERLINE_THICKNESS_BIT_NV, mGlyphBase + ' ', /*count*/1, 4 * sizeof ( GLfloat ), font_data ); mFontMetrics.mYMin = font_data[0]; mFontMetrics.mYMax = font_data[1]; mFontMetrics.mUnderlinePosition = font_data[2]; mFontMetrics.mUnderlineThickness = font_data[3]; glGetPathMetricRangeNV ( GL_FONT_X_MIN_BOUNDS_BIT_NV | GL_FONT_X_MAX_BOUNDS_BIT_NV | GL_FONT_UNITS_PER_EM_BIT_NV | GL_FONT_ASCENDER_BIT_NV, mGlyphBase + ' ', /*count*/1, 4 * sizeof ( GLfloat ), font_data ); mFontMetrics.mXMin = font_data[0]; mFontMetrics.mXMax = font_data[1]; mFontMetrics.mEmUnits = font_data[2]; mFontMetrics.mAscender = font_data[3]; glGetPathMetricRangeNV ( GL_FONT_DESCENDER_BIT_NV | GL_FONT_HEIGHT_BIT_NV | GL_FONT_MAX_ADVANCE_WIDTH_BIT_NV | GL_FONT_MAX_ADVANCE_HEIGHT_BIT_NV, mGlyphBase + ' ', /*count*/1, 4 * sizeof ( GLfloat ), font_data ); mFontMetrics.mDescender = font_data[0]; mFontMetrics.mFontHeight = font_data[1]; mFontMetrics.mMaxAdvanceWidth = font_data[2]; mFontMetrics.mMaxAdvanceHeight = font_data[3]; GLfloat glyphMetrics[256]; mGlyphMetrics = GlyphMetrics::create(); //collect glyph metrics glGetPathMetricRangeNV ( GL_GLYPH_HORIZONTAL_BEARING_ADVANCE_BIT_NV, mGlyphBase, numChars, 0, /* stride of zero means sizeof(GLfloat) since 1 bit in mask */ glyphMetrics ); mGlyphMetrics->mHorizontalAdvance = std::vector<float> ( glyphMetrics, glyphMetrics + sizeof glyphMetrics / sizeof glyphMetrics[0] ); glGetPathMetricRangeNV ( GL_GLYPH_VERTICAL_BEARING_ADVANCE_BIT_NV, mGlyphBase, numChars, 0, /* stride of zero means sizeof(GLfloat) since 1 bit in mask */ glyphMetrics ); mGlyphMetrics->mVerticalAdvance = std::vector<float> ( glyphMetrics, glyphMetrics + sizeof glyphMetrics / sizeof glyphMetrics[0] ); glGetPathMetricRangeNV ( GL_GLYPH_WIDTH_BIT_NV, mGlyphBase, numChars, 0, /* stride of zero means sizeof(GLfloat) since 1 bit in mask */ glyphMetrics ); mGlyphMetrics->mGlyphWidth = std::vector<float> ( glyphMetrics, glyphMetrics + sizeof glyphMetrics / sizeof glyphMetrics[0] ); glGetPathMetricRangeNV ( GL_GLYPH_HEIGHT_BIT_NV, mGlyphBase, numChars, 0, /* stride of zero means sizeof(GLfloat) since 1 bit in mask */ glyphMetrics ); mGlyphMetrics->mGlyphHeight = std::vector<float> ( glyphMetrics, glyphMetrics + sizeof glyphMetrics / sizeof glyphMetrics[0] ); glGetPathMetricRangeNV ( GL_GLYPH_HORIZONTAL_BEARING_X_BIT_NV, mGlyphBase, numChars, 0, /* stride of zero means sizeof(GLfloat) since 1 bit in mask */ glyphMetrics ); mGlyphMetrics->mHorizontalBearingX = std::vector<float> ( glyphMetrics, glyphMetrics + sizeof glyphMetrics / sizeof glyphMetrics[0] ); glGetPathMetricRangeNV ( GL_GLYPH_HORIZONTAL_BEARING_Y_BIT_NV, mGlyphBase, numChars, 0, /* stride of zero means sizeof(GLfloat) since 1 bit in mask */ glyphMetrics ); mGlyphMetrics->mHorizontalBearingY = std::vector<float> ( glyphMetrics, glyphMetrics + sizeof glyphMetrics / sizeof glyphMetrics[0] ); glGetPathMetricRangeNV ( GL_GLYPH_VERTICAL_BEARING_X_BIT_NV, mGlyphBase, numChars, 0, /* stride of zero means sizeof(GLfloat) since 1 bit in mask */ glyphMetrics ); mGlyphMetrics->mVerticalBearingX = std::vector<float> ( glyphMetrics, glyphMetrics + sizeof glyphMetrics / sizeof glyphMetrics[0] ); glGetPathMetricRangeNV ( GL_GLYPH_VERTICAL_BEARING_Y_BIT_NV, mGlyphBase, numChars, 0, /* stride of zero means sizeof(GLfloat) since 1 bit in mask */ glyphMetrics ); mGlyphMetrics->mVerticalBearingY = std::vector<float> ( glyphMetrics, glyphMetrics + sizeof glyphMetrics / sizeof glyphMetrics[0] ); }