Ejemplo n.º 1
0
DrawableTextureDataP texture_utils::getTextureData(
	const TXshSimpleLevel *sl, const TFrameId &fid, int subsampling)
{
	const std::string &texId = sl->getImageId(fid);

	// Now, we must associate a texture
	DrawableTextureDataP data(TTexturesStorage::instance()->getTextureData(texId));
	if (data)
		return data;

	// There was no associated texture. We must bind the texture and repeat

	// First, retrieve the image to be used as texture
	TRasterImageP ri(::getTexture(sl, fid, subsampling));
	if (!ri)
		return DrawableTextureDataP();

	TRaster32P ras(ri->getRaster());
	assert(ras);

	TRectD geom(0, 0, ras->getLx(), ras->getLy());
	geom = TScale(ri->getSubsampling()) *
		   TTranslation(convert(ri->getOffset()) - ras->getCenterD()) *
		   geom;

	return TTexturesStorage::instance()->loadTexture(texId, ras, geom);
}
Ejemplo n.º 2
0
std::pair<TRasterP, TCacheResource::CellData *> TCacheResource::touch(const PointLess &cellIndex)
{
	std::string cellId(getCellCacheId(cellIndex.x, cellIndex.y));

	std::map<PointLess, CellData>::iterator it = m_cellDatas.find(cellIndex);
	if (it != m_cellDatas.end()) {
		//Retrieve the raster from image cache
		TImageP img(TImageCache::instance()->get(cellId, true));
		if (img)
			return std::make_pair(getRaster(img), &it->second);
	}

	it = m_cellDatas.insert(std::make_pair(cellIndex, CellData())).first;

	//Then, attempt retrieval from back resource
	TRasterP ras(load(cellIndex));
	if (ras) {
		TImageCache::instance()->add(cellId, TRasterImageP(ras));
		return std::make_pair(ras, &it->second);
	}

	//Else, create it
	return std::make_pair(
		createCellRaster(m_tileType, cellId), //increases m_cellsCount too
		&it->second);
}
Ejemplo n.º 3
0
void TLevelWriterMov::save(const TImageP &img, int frameIndex) {
  TRasterImageP ri(img);
  if (!img) throw TImageException(getFilePath(), "Unsupported image type");

  TRasterP ras(ri->getRaster());

  int lx = ras->getLx(), ly = ras->getLy(), pixSize = ras->getPixelSize();
  if (pixSize != 4)
    throw TImageException(getFilePath(), "Unsupported pixel type");

  int size = lx * ly * pixSize;

  // Send messages
  QLocalSocket socket;
  tipc::startSlaveConnection(&socket, t32bitsrv::srvName(), -1,
                             t32bitsrv::srvCmdline());

  tipc::Stream stream(&socket);
  tipc::Message msg;

  // Send the write message.
  stream << (msg << QString("$LWMovImageWrite") << m_id << frameIndex << lx
                 << ly);

  // Send the data through a shared memory segment
  {
    t32bitsrv::RasterExchanger<TPixel32> exch(ras);
    tipc::writeShMemBuffer(stream, msg << tipc::clr, size, &exch);
  }

  if (tipc::readMessage(stream, msg) != "ok")
    throw TImageException(getFilePath(), "Couln't save image");
}
Ejemplo n.º 4
0
    //------------------------------------------------------------------------
    void draw_dashes_draft()
    {
        pixfmt pixf(rbuf_window());
        base_renderer rb(pixf);
        primitives_renderer prim(rb);
        outline_rasterizer ras(prim);

        int i;
        for(i = 0; i < m_graph.get_num_edges(); i++)
        {
            graph::edge e  = m_graph.get_edge(i);
            graph::node n1 = m_graph.get_node(e.node1, width(), height());
            graph::node n2 = m_graph.get_node(e.node2, width(), height());
            curve c(n1.x, n1.y, n2.x, n2.y);
            dash_stroke_draft<curve> s(c, 6.0, 3.0, m_width.value());

            int r = rand() & 0x7F;
            int g = rand() & 0x7F;
            int b = rand() & 0x7F;
            int a = 255;
            if(m_translucent.status()) a = 80;
            prim.line_color(agg::srgba8(r, g, b, a));
            ras.add_path(s);
        }
    }
Ejemplo n.º 5
0
TEST( Raster, MoveRaster )	{
	raster_t ras(100,100);
	raster_t copy( std::move(ras) );

	check_empty_raster( ras );

	ASSERT_EQ( copy.height(), 100 );
	ASSERT_EQ( copy.width(), 100); 
}
void  agg_renderer<T>::process(line_pattern_symbolizer const& sym,
                               mapnik::feature_ptr const& feature,
                               proj_transform const& prj_trans)
{
    typedef agg::conv_clip_polyline<geometry_type> clipped_geometry_type;
    typedef coord_transform2<CoordTransform,clipped_geometry_type> path_type;
    typedef agg::line_image_pattern<agg::pattern_filter_bilinear_rgba8> pattern_type;
    typedef agg::renderer_base<agg::pixfmt_rgba32_plain> renderer_base;
    typedef agg::renderer_outline_image<renderer_base, pattern_type> renderer_type;
    typedef agg::rasterizer_outline_aa<renderer_type> rasterizer_type;

    agg::rendering_buffer buf(pixmap_.raw_data(),width_,height_, width_ * 4);
    agg::pixfmt_rgba32_plain pixf(buf);

    std::string filename = path_processor_type::evaluate( *sym.get_filename(), *feature);

    boost::optional<marker_ptr> mark = marker_cache::instance()->find(filename,true);
    if (!mark) return;

    if (!(*mark)->is_bitmap())
    {
        std::clog << "### Warning only images (not '" << filename << "') are supported in the line_pattern_symbolizer\n";
        return;
    }

    boost::optional<image_ptr> pat = (*mark)->get_bitmap_data();

    if (!pat) return;

    box2d<double> ext = query_extent_ * 1.1;
    renderer_base ren_base(pixf);
    agg::pattern_filter_bilinear_rgba8 filter;
    pattern_source source(*(*pat));
    pattern_type pattern (filter,source);
    renderer_type ren(ren_base, pattern);
    // TODO - should be sensitive to buffer size
    ren.clip_box(0,0,width_,height_);
    rasterizer_type ras(ren);
    //metawriter_with_properties writer = sym.get_metawriter();
    for (unsigned i=0;i<feature->num_geometries();++i)
    {
        geometry_type & geom = feature->get_geometry(i);
        if (geom.num_points() > 1)
        {
            clipped_geometry_type clipped(geom);
            clipped.clip_box(ext.minx(),ext.miny(),ext.maxx(),ext.maxy());
            path_type path(t_,clipped,prj_trans);
            ras.add_path(path);
            //if (writer.first) writer.first->add_line(path, *feature, t_, writer.second);
        }
    }
}
Ejemplo n.º 7
0
bool THRawBitmap::_checkScaled(THRenderTarget* pCanvas, SDL_Rect& rcDest)
{
    float fFactor;
    if(!pCanvas->shouldScaleBitmaps(&fFactor))
        return false;
    int iScaledWidth = (int)((float)m_pBitmap->w * fFactor);
    if(!m_pCachedScaledBitmap || m_pCachedScaledBitmap->w != iScaledWidth)
    {
        SDL_FreeSurface(m_pCachedScaledBitmap);
        Uint32 iRMask, iGMask, iBMask;
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
        iRMask = 0xff000000;
        iGMask = 0x00ff0000;
        iBMask = 0x0000ff00;
#else
        iRMask = 0x000000ff;
        iGMask = 0x0000ff00;
        iBMask = 0x00ff0000;
#endif

        m_pCachedScaledBitmap = SDL_CreateRGBSurface(SDL_SWSURFACE, iScaledWidth, (int)((float)m_pBitmap->h * fFactor), 24, iRMask, iGMask, iBMask, 0);
        SDL_LockSurface(m_pCachedScaledBitmap);
        SDL_LockSurface(m_pBitmap);

        typedef agg::pixfmt_rgb24_pre pixfmt_pre_t;
        typedef agg::renderer_base<pixfmt_pre_t> renbase_pre_t;
        typedef image_accessor_clip_rgb24_pal8<pixfmt_pre_t> imgsrc_t;
        typedef agg::span_interpolator_linear<> interpolator_t;
        typedef agg::span_image_filter_rgb_2x2<imgsrc_t, interpolator_t> span_gen_type;
        agg::scanline_p8 sl;
        agg::span_allocator<pixfmt_pre_t::color_type> sa;
        agg::image_filter<agg::image_filter_bilinear> filter;
        agg::trans_affine_scaling img_mtx(1.0 / fFactor);
        agg::rendering_buffer rbuf_src(m_pData, m_pBitmap->w, m_pBitmap->h, m_pBitmap->pitch);
        imgsrc_t img_src(rbuf_src, *m_pPalette, agg::rgba(0.0, 0.0, 0.0));
        interpolator_t interpolator(img_mtx);
        span_gen_type sg(img_src, interpolator, filter);
        agg::rendering_buffer rbuf(reinterpret_cast<unsigned char*>(m_pCachedScaledBitmap->pixels), m_pCachedScaledBitmap->w, m_pCachedScaledBitmap->h, m_pCachedScaledBitmap->pitch);
        pixfmt_pre_t pixf_pre(rbuf);
        renbase_pre_t rbase_pre(pixf_pre);
        rasterizer_scanline_rect ras(0, 0, rbuf.width(), rbuf.height());
        rbase_pre.clear(agg::rgba(1.0,0,0,0));
        agg::render_scanlines_aa(ras, sl, rbase_pre, sa, sg);

        SDL_UnlockSurface(m_pBitmap);
        SDL_UnlockSurface(m_pCachedScaledBitmap);
    }
    rcDest.x = (Sint16)((float)rcDest.x * fFactor);
    rcDest.y = (Sint16)((float)rcDest.y * fFactor);
    return true;
}
Ejemplo n.º 8
0
TEST( Raster, CopyRaster )	{
	raster_t ras(100,100);
	raster_t copy(ras);

	ASSERT_EQ( ras.height(), copy.height() );
	ASSERT_EQ( ras.width(), copy.width() );

	const unsigned char* pix_ras = ras.data();
	const unsigned char* pix_copy = copy.data();

	for( int i = 0; i < (ras.height() * ras.width()); ++i)	{
		ASSERT_EQ( pix_ras[i], pix_copy[i] );
	}
}
Ejemplo n.º 9
0
    virtual void on_draw()
    {
        int width = rbuf_window().width();
        int height = rbuf_window().height();

        typedef agg::renderer_base<pixfmt> renderer_base;
        typedef agg::renderer_scanline_aa_solid<renderer_base> renderer_solid;

        pixfmt pixf(rbuf_window());
        renderer_base rb(pixf);
        renderer_solid r(rb);
        rb.clear(agg::rgba(1,1,1));

        agg::trans_affine mtx;
        mtx *= agg::trans_affine_translation(-g_base_dx, -g_base_dy);
        mtx *= agg::trans_affine_scaling(g_scale, g_scale);
        mtx *= agg::trans_affine_rotation(g_angle + agg::pi);
        mtx *= agg::trans_affine_skewing(g_skew_x/1000.0, g_skew_y/1000.0);
        mtx *= agg::trans_affine_translation(width/2, height/2);

        if(m_scanline.status())
        {
            agg::conv_stroke<agg::path_storage> stroke(g_path);
            stroke.width(m_width_slider.value());
            stroke.line_join(agg::round_join);
            agg::conv_transform<agg::conv_stroke<agg::path_storage> > trans(stroke, mtx);
            agg::render_all_paths(g_rasterizer, g_scanline, r, trans, g_colors, g_path_idx, g_npaths);
        }
        else
        {
            typedef agg::renderer_outline_aa<renderer_base> renderer_type;
            typedef agg::rasterizer_outline_aa<renderer_type> rasterizer_type;

            double w = m_width_slider.value() * mtx.scale();

            agg::line_profile_aa profile(w, agg::gamma_none());
            renderer_type ren(rb, profile);
            rasterizer_type ras(ren);

            agg::conv_transform<agg::path_storage> trans(g_path, mtx);

            ras.render_all_paths(trans, g_colors, g_path_idx, g_npaths);
        }


        agg::render_ctrl(g_rasterizer, g_scanline, rb, m_width_slider);
        agg::render_ctrl(g_rasterizer, g_scanline, rb, m_scanline);
    }
QScriptValue ImageBuilder::fill(const QString &colorName) {
  QColor color;
  QScriptValue err = checkColor(context(), colorName, color);
  if (err.isError()) return err;
  TPixel32 pix(color.red(), color.green(), color.blue(), color.alpha());
  if (m_img) {
    if (m_img->getType() != TImage::RASTER)
      context()->throwError("Can't fill a non-'Raster' image");
    TRaster32P ras = m_img->raster();
    if (ras) ras->fill(pix);
  } else if (m_width > 0 && m_height > 0) {
    TRaster32P ras(m_width, m_height);
    ras->fill(pix);
    m_img = TRasterImageP(ras);
  }
  return context()->thisObject();
}
Ejemplo n.º 11
0
TImageP ImageFiller::build(int imFlags, void *extData)
{
	assert(imFlags == ImageManager::none);

	// Fetch image
	assert(extData);

	ImageLoader::BuildExtData *data = (ImageLoader::BuildExtData *)extData;
	assert(data->m_subs == 0);

	const std::string &srcImgId = data->m_sl->getImageId(data->m_fid);

	TImageP img = ImageManager::instance()->getImage(srcImgId, imFlags, extData);
	if (img) {
		TRasterImageP ri = img;
		if (ri) {
			TRaster32P ras = ri->getRaster();
			if (ras) {
				TRaster32P newRas = ras->clone();
				FullColorAreaFiller filler(newRas);

				TPaletteP palette = new TPalette();
				int styleId = palette->getPage(0)->addStyle(TPixel32::White);

				FillParameters params;
				params.m_palette = palette.getPointer();
				params.m_styleId = styleId;
				params.m_minFillDepth = 0;
				params.m_maxFillDepth = 15;
				filler.rectFill(newRas->getBounds(), params, false);

				TRasterImageP ri = TRasterImageP(newRas);
				return ri;
			}
		}
	}

	// Error case: return a dummy image (is it really required?)

	TRaster32P ras(10, 10);
	ras->fill(TPixel32(127, 0, 127, 127));

	return TRasterImageP(ras);
}
void  agg_renderer<T>::process(line_pattern_symbolizer const& sym,
                               Feature const& feature,
                               proj_transform const& prj_trans)
{
    typedef  coord_transform2<CoordTransform,geometry_type> path_type;
    typedef agg::line_image_pattern<agg::pattern_filter_bilinear_rgba8> pattern_type;
    typedef agg::renderer_base<agg::pixfmt_rgba32_plain> renderer_base;
    typedef agg::renderer_outline_image<renderer_base, pattern_type> renderer_type;
    typedef agg::rasterizer_outline_aa<renderer_type> rasterizer_type;

    agg::rendering_buffer buf(pixmap_.raw_data(),width_,height_, width_ * 4);
    agg::pixfmt_rgba32_plain pixf(buf);
    
    std::string filename = path_processor_type::evaluate( *sym.get_filename(), feature);

    boost::optional<marker_ptr> mark = marker_cache::instance()->find(filename,true);
    if (!mark || !(*mark)->is_bitmap()) return;

    boost::optional<image_ptr> pat = (*mark)->get_bitmap_data();

    if (!pat) return;
      
    renderer_base ren_base(pixf);
    agg::pattern_filter_bilinear_rgba8 filter;
    pattern_source source(*(*pat));
    pattern_type pattern (filter,source);
    renderer_type ren(ren_base, pattern);
    ren.clip_box(0,0,width_,height_);
    rasterizer_type ras(ren);
    metawriter_with_properties writer = sym.get_metawriter();
    for (unsigned i=0;i<feature.num_geometries();++i)
    {
        geometry_type const& geom = feature.get_geometry(i);
        if (geom.num_points() > 1)
        {
            path_type path(t_,geom,prj_trans);
            ras.add_path(path);
            if (writer.first) writer.first->add_line(path, feature, t_, writer.second);
        }
    }
}
Ejemplo n.º 13
0
TImageP TImageReaderMovProxy::load() {
  TRaster32P ras(m_lr->getSize());
  m_lr->load(ras, m_frameIndex, TPointI(), 1, 1);
  return TRasterImageP(ras);
}
Ejemplo n.º 14
0
TToonzImageP Naa2TlvConverter::makeTlv(bool transparentSyntheticInks) {
  if (!m_valid || m_colors.empty() || m_regions.empty() || !m_regionRas)
    return TToonzImageP();
  int lx                = m_regionRas->getLx();
  int ly                = m_regionRas->getLy();
  TPalette *palette     = m_palette;
  if (!palette) palette = new TPalette();

  TRasterCM32P ras(lx, ly);

  QList<int> styleIds;

  for (int i = 0; i < m_colors.count() - 1; i++) {
    TPixel32 color  = m_colors.at(i);
    int styleId     = palette->getClosestStyle(color);
    TColorStyle *cs = styleId < 0 ? 0 : palette->getStyle(styleId);
    if (cs) {
      if (cs->getMainColor() != color) cs = 0;
    }
    if (cs == 0) {
      styleId = palette->getPage(0)->addStyle(color);
      cs      = palette->getStyle(styleId);
    }
    styleIds.append(styleId);
  }
  styleIds.append(0);  // syntetic ink

  // int synteticInkStyleId = palette->getPage(0)->addStyle(TPixel32(0,0,0,0));
  // styleIds.append(synteticInkStyleId);

  for (int y = 0; y < ly; y++) {
    unsigned short *workScanLine = m_regionRas->pixels(y);
    TPixelCM32 *outScanLine      = ras->pixels(y);
    for (int x = 0; x < lx; x++) {
      int c = workScanLine[x];
      Q_ASSERT(0 <= c && c < m_regions.count());

      int color = m_regions[c].colorIndex;
      Q_ASSERT(0 <= color && color < styleIds.count());

      int styleId = styleIds.at(color);

      RegionInfo::Type type = m_regions.at(c).type;
      if (type == RegionInfo::Background)
        outScanLine[x] = TPixelCM32();
      else if (type & RegionInfo::Ink)
        outScanLine[x] = TPixelCM32(styleId, 0, 0);
      else if (m_syntheticInkRas->pixels(y)[x] == 1)
        outScanLine[x] =
            TPixelCM32(transparentSyntheticInks ? 0 : styleId, styleId, 0);
      else
        outScanLine[x] = TPixelCM32(0, styleId, 255);
    }
  }

  TToonzImageP ti = new TToonzImage(ras, ras->getBounds());
  ti->setPalette(palette);
  ti->setDpi(72, 72);

  return ti;
}
Ejemplo n.º 15
0
void agg_renderer<T0,T1>::process(line_symbolizer const& sym,
                              mapnik::feature_impl & feature,
                              proj_transform const& prj_trans)

{
    color const& col = get<color, keys::stroke>(sym, feature, common_.vars_);
    unsigned r=col.red();
    unsigned g=col.green();
    unsigned b=col.blue();
    unsigned a=col.alpha();

    double gamma = get<value_double, keys::stroke_gamma>(sym, feature, common_.vars_);
    gamma_method_enum gamma_method = get<gamma_method_enum, keys::stroke_gamma_method>(sym, feature, common_.vars_);
    ras_ptr->reset();

    if (gamma != gamma_ || gamma_method != gamma_method_)
    {
        set_gamma_method(ras_ptr, gamma, gamma_method);
        gamma_method_ = gamma_method;
        gamma_ = gamma;
    }

    agg::rendering_buffer buf(current_buffer_->getBytes(),current_buffer_->width(),current_buffer_->height(), current_buffer_->getRowSize());

    using color_type = agg::rgba8;
    using order_type = agg::order_rgba;
    using blender_type = agg::comp_op_adaptor_rgba_pre<color_type, order_type>; // comp blender
    using pixfmt_comp_type = agg::pixfmt_custom_blend_rgba<blender_type, agg::rendering_buffer>;
    using renderer_base = agg::renderer_base<pixfmt_comp_type>;

    pixfmt_comp_type pixf(buf);
    pixf.comp_op(static_cast<agg::comp_op_e>(get<composite_mode_e, keys::comp_op>(sym, feature, common_.vars_)));
    renderer_base renb(pixf);

    agg::trans_affine tr;
    auto transform = get_optional<transform_type>(sym, keys::geometry_transform);
    if (transform) evaluate_transform(tr, feature, common_.vars_, *transform, common_.scale_factor_);

    box2d<double> clip_box = clipping_extent(common_);

    value_bool clip = get<value_bool, keys::clip>(sym, feature, common_.vars_);
    value_double width = get<value_double, keys::stroke_width>(sym, feature, common_.vars_);
    value_double opacity = get<value_double,keys::stroke_opacity>(sym,feature, common_.vars_);
    value_double offset = get<value_double, keys::offset>(sym, feature, common_.vars_);
    value_double simplify_tolerance = get<value_double, keys::simplify_tolerance>(sym, feature, common_.vars_);
    value_double smooth = get<value_double, keys::smooth>(sym, feature, common_.vars_);
    line_rasterizer_enum rasterizer_e = get<line_rasterizer_enum, keys::line_rasterizer>(sym, feature, common_.vars_);
    if (clip)
    {
        double padding = static_cast<double>(common_.query_extent_.width()/pixmap_.width());
        double half_stroke = 0.5 * width;
        if (half_stroke > 1)
        {
            padding *= half_stroke;
        }
        if (std::fabs(offset) > 0)
        {
            padding *= std::fabs(offset) * 1.2;
        }

        padding *= common_.scale_factor_;
        clip_box.pad(padding);
        // debugging
        //box2d<double> inverse = query_extent_;
        //inverse.pad(-padding);
        //draw_geo_extent(inverse,mapnik::color("red"));
    }

    if (rasterizer_e == RASTERIZER_FAST)
    {
        using renderer_type = agg::renderer_outline_aa<renderer_base>;
        using rasterizer_type = agg::rasterizer_outline_aa<renderer_type>;
        agg::line_profile_aa profile(width * common_.scale_factor_, agg::gamma_power(gamma));
        renderer_type ren(renb, profile);
        ren.color(agg::rgba8_pre(r, g, b, int(a * opacity)));
        rasterizer_type ras(ren);
        set_join_caps_aa(sym, ras, feature, common_.vars_);

        vertex_converter<rasterizer_type,clip_line_tag, transform_tag,
                         affine_transform_tag,
                         simplify_tag, smooth_tag,
                         offset_transform_tag,
                         dash_tag, stroke_tag>
            converter(clip_box,ras,sym,common_.t_,prj_trans,tr,feature,common_.vars_,common_.scale_factor_);
        if (clip) converter.set<clip_line_tag>(); // optional clip (default: true)
        converter.set<transform_tag>(); // always transform
        if (std::fabs(offset) > 0.0) converter.set<offset_transform_tag>(); // parallel offset
        converter.set<affine_transform_tag>(); // optional affine transform
        if (simplify_tolerance > 0.0) converter.set<simplify_tag>(); // optional simplify converter
        if (smooth > 0.0) converter.set<smooth_tag>(); // optional smooth converter

        for (geometry_type const& geom : feature.paths())
        {
            if (geom.size() > 1)
            {
                vertex_adapter va(geom);
                converter.apply(va);
            }
        }
    }
    else
    {
        vertex_converter<rasterizer,clip_line_tag, transform_tag,
                         affine_transform_tag,
                         simplify_tag, smooth_tag,
                         offset_transform_tag,
                         dash_tag, stroke_tag>
            converter(clip_box,*ras_ptr,sym,common_.t_,prj_trans,tr,feature,common_.vars_,common_.scale_factor_);

        if (clip) converter.set<clip_line_tag>(); // optional clip (default: true)
        converter.set<transform_tag>(); // always transform
        if (std::fabs(offset) > 0.0) converter.set<offset_transform_tag>(); // parallel offset
        converter.set<affine_transform_tag>(); // optional affine transform
        if (simplify_tolerance > 0.0) converter.set<simplify_tag>(); // optional simplify converter
        if (smooth > 0.0) converter.set<smooth_tag>(); // optional smooth converter
        if (has_key(sym, keys::stroke_dasharray))
            converter.set<dash_tag>();
        converter.set<stroke_tag>(); //always stroke

        for (geometry_type const& geom : feature.paths())
        {
            if (geom.size() > 1)
            {
                vertex_adapter va(geom);
                converter.apply(va);
            }
        }

        using renderer_type = agg::renderer_scanline_aa_solid<renderer_base>;
        renderer_type ren(renb);
        ren.color(agg::rgba8_pre(r, g, b, int(a * opacity)));
        agg::scanline_u8 sl;
        ras_ptr->filling_rule(agg::fill_non_zero);
        agg::render_scanlines(*ras_ptr, sl, ren);
    }
}
Ejemplo n.º 16
0
void agg_renderer<T>::process(line_symbolizer const& sym,
                              mapnik::feature_impl & feature,
                              proj_transform const& prj_trans)

{
    stroke const& stroke_ = sym.get_stroke();
    color const& col = stroke_.get_color();
    unsigned r=col.red();
    unsigned g=col.green();
    unsigned b=col.blue();
    unsigned a=col.alpha();

    ras_ptr->reset();
    if (stroke_.get_gamma() != gamma_ || stroke_.get_gamma_method() != gamma_method_)
    {
        set_gamma_method(stroke_, ras_ptr);
        gamma_method_ = stroke_.get_gamma_method();
        gamma_ = stroke_.get_gamma();
    }

    agg::rendering_buffer buf(current_buffer_->raw_data(),current_buffer_->width(),current_buffer_->height(), current_buffer_->width() * 4);

    typedef agg::rgba8 color_type;
    typedef agg::order_rgba order_type;
    typedef agg::comp_op_adaptor_rgba_pre<color_type, order_type> blender_type; // comp blender
    typedef agg::pixfmt_custom_blend_rgba<blender_type, agg::rendering_buffer> pixfmt_comp_type;
    typedef agg::renderer_base<pixfmt_comp_type> renderer_base;
    typedef boost::mpl::vector<clip_line_tag, transform_tag,
            offset_transform_tag, affine_transform_tag,
            simplify_tag, smooth_tag, dash_tag, stroke_tag> conv_types;

    pixfmt_comp_type pixf(buf);
    pixf.comp_op(static_cast<agg::comp_op_e>(sym.comp_op()));
    renderer_base renb(pixf);

    agg::trans_affine tr;
    evaluate_transform(tr, feature, sym.get_transform(), scale_factor_);

    box2d<double> clip_box = clipping_extent();
    if (sym.clip())
    {
        double padding = (double)(query_extent_.width()/pixmap_.width());
        double half_stroke = stroke_.get_width()/2.0;
        if (half_stroke > 1)
            padding *= half_stroke;
        if (std::fabs(sym.offset()) > 0)
            padding *= std::fabs(sym.offset()) * 1.2;
        padding *= scale_factor_;
        clip_box.pad(padding);
        // debugging
        //box2d<double> inverse = query_extent_;
        //inverse.pad(-padding);
        //draw_geo_extent(inverse,mapnik::color("red"));
    }

    if (sym.get_rasterizer() == RASTERIZER_FAST)
    {
        typedef agg::renderer_outline_aa<renderer_base> renderer_type;
        typedef agg::rasterizer_outline_aa<renderer_type> rasterizer_type;
        agg::line_profile_aa profile(stroke_.get_width() * scale_factor_, agg::gamma_power(stroke_.get_gamma()));
        renderer_type ren(renb, profile);
        ren.color(agg::rgba8_pre(r, g, b, int(a*stroke_.get_opacity())));
        rasterizer_type ras(ren);
        set_join_caps_aa(stroke_,ras);

        vertex_converter<box2d<double>, rasterizer_type, line_symbolizer,
                         CoordTransform, proj_transform, agg::trans_affine, conv_types>
                         converter(clip_box,ras,sym,t_,prj_trans,tr,scale_factor_);
        if (sym.clip()) converter.set<clip_line_tag>(); // optional clip (default: true)
        converter.set<transform_tag>(); // always transform
        if (std::fabs(sym.offset()) > 0.0) converter.set<offset_transform_tag>(); // parallel offset
        converter.set<affine_transform_tag>(); // optional affine transform
        if (sym.simplify_tolerance() > 0.0) converter.set<simplify_tag>(); // optional simplify converter
        if (sym.smooth() > 0.0) converter.set<smooth_tag>(); // optional smooth converter

        for (geometry_type & geom : feature.paths())
        {
            if (geom.size() > 1)
            {
                converter.apply(geom);
            }
        }
    }
    else
    {
        vertex_converter<box2d<double>, rasterizer, line_symbolizer,
                         CoordTransform, proj_transform, agg::trans_affine, conv_types>
                         converter(clip_box,*ras_ptr,sym,t_,prj_trans,tr,scale_factor_);

        if (sym.clip()) converter.set<clip_line_tag>(); // optional clip (default: true)
        converter.set<transform_tag>(); // always transform
        if (std::fabs(sym.offset()) > 0.0) converter.set<offset_transform_tag>(); // parallel offset
        converter.set<affine_transform_tag>(); // optional affine transform
        if (sym.simplify_tolerance() > 0.0) converter.set<simplify_tag>(); // optional simplify converter
        if (sym.smooth() > 0.0) converter.set<smooth_tag>(); // optional smooth converter
        if (stroke_.has_dash()) converter.set<dash_tag>();
        converter.set<stroke_tag>(); //always stroke

        for (geometry_type & geom : feature.paths())
        {
            if (geom.size() > 1)
            {
                converter.apply(geom);
            }
        }

        typedef agg::renderer_scanline_aa_solid<renderer_base> renderer_type;
        renderer_type ren(renb);
        ren.color(agg::rgba8_pre(r, g, b, int(a * stroke_.get_opacity())));
        agg::scanline_u8 sl;
        ras_ptr->filling_rule(agg::fill_non_zero);
        agg::render_scanlines(*ras_ptr, sl, ren);
    }
}
void  agg_renderer<T0,T1>::process(line_pattern_symbolizer const& sym,
                                   mapnik::feature_impl & feature,
                                   proj_transform const& prj_trans)
{

    using color = agg::rgba8;
    using order = agg::order_rgba;
    using blender_type = agg::comp_op_adaptor_rgba_pre<color, order>;
    using pattern_filter_type = agg::pattern_filter_bilinear_rgba8;
    using pattern_type = agg::line_image_pattern<pattern_filter_type>;
    using pixfmt_type = agg::pixfmt_custom_blend_rgba<blender_type, agg::rendering_buffer>;
    using renderer_base = agg::renderer_base<pixfmt_type>;
    using renderer_type = agg::renderer_outline_image<renderer_base, pattern_type>;
    using rasterizer_type = agg::rasterizer_outline_aa<renderer_type>;

    std::string filename = get<std::string>(sym, keys::file, feature, common_.vars_);
    if (filename.empty()) return;
    boost::optional<mapnik::marker_ptr> marker_ptr = marker_cache::instance().find(filename, true);
    if (!marker_ptr || !(*marker_ptr)) return;
    boost::optional<image_ptr> pat;
    // TODO - re-implement at renderer level like polygon_pattern symbolizer
    double opacity = get<value_double>(sym, keys::opacity, feature, common_.vars_,1.0);
    if ((*marker_ptr)->is_bitmap())
    {
        pat = (*marker_ptr)->get_bitmap_data();
    }
    else
    {
        agg::trans_affine image_tr = agg::trans_affine_scaling(common_.scale_factor_);
        auto image_transform = get_optional<transform_type>(sym, keys::image_transform);
        if (image_transform) evaluate_transform(image_tr, feature, common_.vars_, *image_transform);
        pat = render_pattern(*ras_ptr, **marker_ptr, image_tr, 1.0);
    }

    if (!pat) return;

    bool clip = get<value_bool>(sym, keys::clip, feature, common_.vars_, false);
    double offset = get<value_double>(sym, keys::offset, feature, common_.vars_, 0.0);
    double simplify_tolerance = get<value_double>(sym, keys::simplify_tolerance, feature, common_.vars_, 0.0);
    double smooth = get<value_double>(sym, keys::smooth, feature, common_.vars_, false);

    agg::rendering_buffer buf(current_buffer_->raw_data(),current_buffer_->width(),current_buffer_->height(), current_buffer_->width() * 4);
    pixfmt_type pixf(buf);
    pixf.comp_op(static_cast<agg::comp_op_e>(get<composite_mode_e>(sym, keys::comp_op, feature, common_.vars_, src_over)));
    renderer_base ren_base(pixf);
    agg::pattern_filter_bilinear_rgba8 filter;

    pattern_source source(*(*pat), opacity);
    pattern_type pattern (filter,source);
    renderer_type ren(ren_base, pattern);
    rasterizer_type ras(ren);

    agg::trans_affine tr;
    auto transform = get_optional<transform_type>(sym, keys::geometry_transform);
    if (transform) evaluate_transform(tr, feature, common_.vars_, *transform, common_.scale_factor_);

    box2d<double> clip_box = clipping_extent(common_);
    if (clip)
    {
        double padding = (double)(common_.query_extent_.width()/pixmap_.width());
        double half_stroke = (*marker_ptr)->width()/2.0;
        if (half_stroke > 1)
            padding *= half_stroke;
        if (std::fabs(offset) > 0)
            padding *= std::fabs(offset) * 1.2;
        padding *= common_.scale_factor_;
        clip_box.pad(padding);
    }

    using conv_types = boost::mpl::vector<clip_line_tag, transform_tag,
          affine_transform_tag,
          simplify_tag,smooth_tag,
          offset_transform_tag>;
    vertex_converter<box2d<double>, rasterizer_type, line_pattern_symbolizer,
                     view_transform, proj_transform, agg::trans_affine, conv_types, feature_impl>
                     converter(clip_box,ras,sym,common_.t_,prj_trans,tr,feature,common_.vars_,common_.scale_factor_);

    if (clip) converter.set<clip_line_tag>(); //optional clip (default: true)
    converter.set<transform_tag>(); //always transform
    if (simplify_tolerance > 0.0) converter.set<simplify_tag>(); // optional simplify converter
    if (std::fabs(offset) > 0.0) converter.set<offset_transform_tag>(); // parallel offset
    converter.set<affine_transform_tag>(); // optional affine transform
    if (smooth > 0.0) converter.set<smooth_tag>(); // optional smooth converter

    for (geometry_type & geom : feature.paths())
    {
        if (geom.size() > 1)
        {
            converter.apply(geom);
        }
    }
}
void cairo_renderer<T>::process(line_pattern_symbolizer const& sym,
                                  mapnik::feature_impl & feature,
                                  proj_transform const& prj_trans)
{
    std::string filename = get<std::string, keys::file>(sym, feature, common_.vars_);
    composite_mode_e comp_op = get<composite_mode_e, keys::comp_op>(sym, feature, common_.vars_);
    value_bool clip = get<value_bool, keys::clip>(sym, feature, common_.vars_);
    value_double offset = get<value_double, keys::offset>(sym, feature, common_.vars_);
    value_double simplify_tolerance = get<value_double, keys::simplify_tolerance>(sym, feature, common_.vars_);
    value_double smooth = get<value_double, keys::smooth>(sym, feature, common_.vars_);

    if (filename.empty())
    {
        return;
    }

    std::shared_ptr<mapnik::marker const> marker = marker_cache::instance().find(filename, true);

    if (marker->is<mapnik::marker_null>()) return;

    unsigned width = marker->width();
    unsigned height = marker->height();

    cairo_save_restore guard(context_);
    context_.set_operator(comp_op);
    // TODO - re-implement at renderer level like polygon_pattern symbolizer
    cairo_renderer_process_visitor_l visit(common_,
                                           sym,
                                           feature,
                                           width,
                                           height);
    std::shared_ptr<cairo_pattern> pattern = util::apply_visitor(visit, *marker);

    context_.set_line_width(height);

    pattern->set_extend(CAIRO_EXTEND_REPEAT);
    pattern->set_filter(CAIRO_FILTER_BILINEAR);

    agg::trans_affine tr;
    auto geom_transform = get_optional<transform_type>(sym, keys::geometry_transform);
    if (geom_transform) { evaluate_transform(tr, feature, common_.vars_, *geom_transform, common_.scale_factor_); }

    box2d<double> clipping_extent = common_.query_extent_;
    if (clip)
    {
        double padding = (double)(common_.query_extent_.width()/common_.width_);
        double half_stroke = width/2.0;
        if (half_stroke > 1)
            padding *= half_stroke;
        if (std::fabs(offset) > 0)
            padding *= std::fabs(offset) * 1.2;
        padding *= common_.scale_factor_;
        clipping_extent.pad(padding);
    }

    using rasterizer_type = line_pattern_rasterizer<cairo_context>;
    rasterizer_type ras(context_, *pattern, width, height);
    using vertex_converter_type = vertex_converter<clip_line_tag, transform_tag,
                                                   affine_transform_tag,
                                                   simplify_tag, smooth_tag,
                                                   offset_transform_tag>;

    vertex_converter_type converter(clipping_extent,sym, common_.t_, prj_trans, tr, feature, common_.vars_, common_.scale_factor_);

    if (clip) converter.set<clip_line_tag>(); // optional clip (default: true)
    converter.set<transform_tag>(); // always transform
    if (std::fabs(offset) > 0.0) converter.set<offset_transform_tag>(); // parallel offset
    converter.set<affine_transform_tag>(); // optional affine transform
    if (simplify_tolerance > 0.0) converter.set<simplify_tag>(); // optional simplify converter
    if (smooth > 0.0) converter.set<smooth_tag>(); // optional smooth converter

    using apply_vertex_converter_type = detail::apply_vertex_converter<vertex_converter_type, rasterizer_type>;
    using vertex_processor_type = geometry::vertex_processor<apply_vertex_converter_type>;
    apply_vertex_converter_type apply(converter, ras);
    mapnik::util::apply_visitor(vertex_processor_type(apply), feature.get_geometry());
}
Ejemplo n.º 19
0
TImageP TImageReader::load0()
{
	if (!m_reader && !m_vectorReader)
		open();

	if (m_reader) {
		TImageInfo info = m_reader->getImageInfo();
		if (info.m_lx <= 0 || info.m_ly <= 0)
			return TImageP();

		// Initialize raster info
		assert(m_shrink > 0);

		// Build loading rect
		int x0 = 0;
		int x1 = info.m_lx - 1;
		int y0 = 0;
		int y1 = info.m_ly - 1;

		if (!m_region.isEmpty()) {
			// Intersect with the externally specified loading region

			x0 = tmax(x0, m_region.x0);
			y0 = tmax(y0, m_region.y0);
			x1 = tmin(x1, m_region.x1);
			y1 = tmin(y1, m_region.y1);

			if (x0 >= x1 || y0 >= y1)
				return TImageP();
		}

		if (m_shrink > 1) {
			// Crop to shrink multiples
			x1 -= (x1 - x0) % m_shrink;
			y1 -= (y1 - y0) % m_shrink;
		}

		assert(x0 <= x1 && y0 <= y1);

		TDimension imageDimension = TDimension((x1 - x0) / m_shrink + 1, (y1 - y0) / m_shrink + 1);

		if (m_path.getType() == "tzp" || m_path.getType() == "tzu") {
			// Colormap case

			TRasterCM32P ras(imageDimension);
			readRaster(ras, m_reader, x0, y0, x1, y1, info.m_lx, info.m_ly, m_shrink);

			// Build the savebox
			TRect saveBox(info.m_x0, info.m_y0, info.m_x1, info.m_y1);
			if (!m_region.isEmpty()) {
				// Intersect with the loading rect
				if (m_region.overlaps(saveBox)) {
					saveBox *= m_region;

					int sbx0 = saveBox.x0 - m_region.x0;
					int sby0 = saveBox.y0 - m_region.y0;
					int sbx1 = sbx0 + saveBox.getLx() - 1;
					int sby1 = sby0 + saveBox.getLy() - 1;
					assert(sbx0 >= 0);
					assert(sby0 >= 0);
					assert(sbx1 >= 0);
					assert(sby1 >= 0);

					saveBox = TRect(sbx0, sby0, sbx1, sby1);
				} else
					saveBox = TRect(0, 0, 1, 1);
			}

			if (m_shrink > 1) {
				saveBox.x0 = saveBox.x0 / m_shrink;
				saveBox.y0 = saveBox.y0 / m_shrink;
				saveBox.x1 = saveBox.x1 / m_shrink;
				saveBox.y1 = saveBox.y1 / m_shrink;
			}

			TToonzImageP ti(ras, ras->getBounds() * saveBox);
			ti->setDpi(info.m_dpix, info.m_dpiy);

			return ti;
		} else if (info.m_bitsPerSample >= 8) {
			// Common byte-based rasters (see below, we have black-and-white bit-based images too)

			if (info.m_samplePerPixel == 1 && m_readGreytones) {
				//  Greymap case
				// NOTE: Uses a full 32-bit raster first, and then copies down to the GR8

				// Observe that GR16 file images get immediately down-cast to GR8...
				// Should we implement that too?

				TRasterGR8P ras(imageDimension);
				readRaster_copyLines(ras, m_reader, x0, y0, x1, y1, info.m_lx, info.m_ly, m_shrink);

				TRasterImageP ri(ras);
				ri->setDpi(info.m_dpix, info.m_dpiy);

				return ri;
			}

			// assert(info.m_samplePerPixel == 3 || info.m_samplePerPixel == 4);

			TRasterP _ras;
			if (info.m_bitsPerSample == 16) {
				if (m_is64BitEnabled || m_path.getType() != "tif") {
					//  Standard 64-bit case.

					// Also covers down-casting to 32-bit from a 64-bit image file whenever
					// not a tif file (see below).

					TRaster64P ras(imageDimension);
					readRaster(ras, m_reader, x0, y0, x1, y1, info.m_lx, info.m_ly, m_shrink);

					_ras = ras;
				} else {
					// The Tif reader has got an automatically down-casting readLine(char*, ...)
					// in case the input file is 64-bit. The advantage is that no intermediate
					// 64-bit raster is required in this case.

					TRaster32P ras(imageDimension);
					readRaster(ras, m_reader, x0, y0, x1, y1, info.m_lx, info.m_ly, m_shrink);

					_ras = ras;
				}
			} else if (info.m_bitsPerSample == 8) {
				//  Standard 32-bit case
				TRaster32P ras(imageDimension);
				readRaster(ras, m_reader, x0, y0, x1, y1, info.m_lx, info.m_ly, m_shrink);

				_ras = ras;
			} else
				throw TImageException(m_path, "Image format not supported");

			// 64-bit to 32-bit conversions if necessary  (64 bit images not allowed)
			if (!m_is64BitEnabled && (TRaster64P)_ras) {
				TRaster32P raux(_ras->getLx(), _ras->getLy());
				TRop::convert(raux, _ras);
				_ras = raux;
			}

			// Return the image
			TRasterImageP ri(_ras);
			ri->setDpi(info.m_dpix, info.m_dpiy);

			return ri;
		} else if (info.m_samplePerPixel == 1 && info.m_valid == true) {
			//  Previously dubbed as 'Palette cases'. No clue about what is this... :|

			TRaster32P ras(imageDimension);
			readRaster(ras, m_reader, x0, y0, x1, y1, info.m_lx, info.m_ly, m_shrink);

			TRasterImageP ri(ras);
			ri->setDpi(info.m_dpix, info.m_dpiy);

			return ri;
		} else if (info.m_samplePerPixel == 1 && m_readGreytones) {
			//  Black-and-White case, I guess. Standard greymaps were considered above...

			TRasterGR8P ras(imageDimension);
			readRaster_copyLines(ras, m_reader, x0, y0, x1, y1, info.m_lx, info.m_ly, m_shrink);

			TRasterImageP ri(ras);
			ri->setDpi(info.m_dpix, info.m_dpiy);

			if (info.m_bitsPerSample == 1) // I suspect this always evaluates true...
				ri->setScanBWFlag(true);

			return ri;
		} else
			return TImageP();
	} else if (m_vectorReader) {
		TVectorImage *vi = m_vectorReader->read();
		return TVectorImageP(vi);
	} else
		return TImageP();
}
Ejemplo n.º 20
0
TImageP ImageRasterizer::build(int imFlags, void *extData)
{
	assert(!(imFlags & ~(ImageManager::dontPutInCache | ImageManager::forceRebuild)));

	TDimension d(10, 10);
	TPoint off(0, 0);

	// Fetch image
	assert(extData);
	ImageLoader::BuildExtData *data = (ImageLoader::BuildExtData *)extData;

	const std::string &srcImgId = data->m_sl->getImageId(data->m_fid);

	TImageP img = ImageManager::instance()->getImage(srcImgId, imFlags, extData);
	if (img) {
		TVectorImageP vi = img;
		if (vi) {
			TRectD bbox = vi->getBBox();

			d = TDimension(tceil(bbox.getLx()) + 1, tceil(bbox.getLy()) + 1);
			off = TPoint((int)bbox.x0, (int)bbox.y0);

			TPalette *vpalette = vi->getPalette();
			TVectorRenderData rd(TTranslation(-off.x, -off.y), TRect(TPoint(0, 0), d), vpalette, 0, true, true);

			TGlContext oldContext = tglGetCurrentContext();

			// this is too slow.
			{
				QSurfaceFormat format;
				format.setProfile(QSurfaceFormat::CompatibilityProfile);

				TRaster32P ras(d);

				glPushAttrib(GL_ALL_ATTRIB_BITS);
				glMatrixMode(GL_MODELVIEW), glPushMatrix();
				glMatrixMode(GL_PROJECTION), glPushMatrix();
				{
					std::unique_ptr<QOpenGLFramebufferObject> fb(new QOpenGLFramebufferObject(d.lx, d.ly));

					fb->bind();
					assert(glGetError() == 0);

					glViewport(0, 0, d.lx, d.ly);
					glClearColor(0, 0, 0, 0);
					glClear(GL_COLOR_BUFFER_BIT);

					glMatrixMode(GL_PROJECTION);
					glLoadIdentity();
					gluOrtho2D(0, d.lx, 0, d.ly);

					glMatrixMode(GL_MODELVIEW);
					glLoadIdentity();
					glTranslatef(0.375, 0.375, 0.0);

					assert(glGetError() == 0);
					tglDraw(rd, vi.getPointer());
					assert(glGetError() == 0);

					assert(glGetError() == 0);
					glFlush();
					assert(glGetError() == 0);

					QImage img = fb->toImage().scaled(QSize(d.lx, d.ly), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);

					int wrap = ras->getLx() * sizeof(TPixel32);
					uchar *srcPix = img.bits();
					uchar *dstPix = ras->getRawData() + wrap * (d.ly - 1);
					for (int y = 0; y < d.ly; y++) {
						memcpy(dstPix, srcPix, wrap);
						dstPix -= wrap;
						srcPix += wrap;
					}
					fb->release();
				}
				glMatrixMode(GL_MODELVIEW), glPopMatrix();
				glMatrixMode(GL_PROJECTION), glPopMatrix();

				glPopAttrib();

				tglMakeCurrent(oldContext);

				TRasterImageP ri = TRasterImageP(ras);
				ri->setOffset(off + ras->getCenter());

				return ri;
			}
		}
	}

	// Error case: return a dummy image (is it really required?)

	TRaster32P ras(d);
	ras->fill(TPixel32(127, 0, 127, 127));

	return TRasterImageP(ras);
}
Ejemplo n.º 21
0
void agg_renderer<T>::process(line_symbolizer const& sym,
                              Feature const& feature,
                              proj_transform const& prj_trans)
{
    typedef agg::renderer_base<agg::pixfmt_rgba32_plain> ren_base;
    typedef coord_transform2<CoordTransform,geometry_type> path_type;

    stroke const& stroke_ = sym.get_stroke();
    color const& col = stroke_.get_color();
    unsigned r=col.red();
    unsigned g=col.green();
    unsigned b=col.blue();
    unsigned a=col.alpha();
    
    agg::rendering_buffer buf(pixmap_.raw_data(),width_,height_, width_ * 4);
    agg::pixfmt_rgba32_plain pixf(buf);
    
    if (sym.get_rasterizer() == RASTERIZER_FAST)
    {
        typedef agg::renderer_outline_aa<ren_base> renderer_type;
        typedef agg::rasterizer_outline_aa<renderer_type> rasterizer_type;

        agg::line_profile_aa profile;
        //agg::line_profile_aa profile(stroke_.get_width() * scale_factor_, agg::gamma_none());
        profile.width(stroke_.get_width() * scale_factor_);
        ren_base base_ren(pixf);
        renderer_type ren(base_ren, profile);
        ren.color(agg::rgba8(r, g, b, int(a*stroke_.get_opacity())));
        //ren.clip_box(0,0,width_,height_);
        rasterizer_type ras(ren);
        ras.line_join(agg::outline_miter_accurate_join);
        ras.round_cap(true);
   
        for (unsigned i=0;i<feature.num_geometries();++i)
        {
            geometry_type const& geom = feature.get_geometry(i);
            if (geom.num_points() > 1)
            {
                path_type path(t_,geom,prj_trans);
                ras.add_path(path);
            }
        }
    }
    else
    {
        typedef agg::renderer_scanline_aa_solid<ren_base> renderer;

        agg::scanline_p8 sl;
    
        ren_base renb(pixf);
        renderer ren(renb);
        ras_ptr->reset();
        switch (stroke_.get_gamma_method())
        {
            case GAMMA_POWER:
                ras_ptr->gamma(agg::gamma_power(stroke_.get_gamma()));
                break;
            case GAMMA_LINEAR:
                ras_ptr->gamma(agg::gamma_linear(0.0, stroke_.get_gamma()));
                break;
            case GAMMA_NONE:
                ras_ptr->gamma(agg::gamma_none());
                break;
            case GAMMA_THRESHOLD:
                ras_ptr->gamma(agg::gamma_threshold(stroke_.get_gamma()));
                break;
            case GAMMA_MULTIPLY:
                ras_ptr->gamma(agg::gamma_multiply(stroke_.get_gamma()));
                break;
            default:
                ras_ptr->gamma(agg::gamma_power(stroke_.get_gamma()));
        }
        
        metawriter_with_properties writer = sym.get_metawriter();
        for (unsigned i=0;i<feature.num_geometries();++i)
        {
            geometry_type const& geom = feature.get_geometry(i);
            if (geom.num_points() > 1)
            {
                path_type path(t_,geom,prj_trans);
    
                if (stroke_.has_dash())
                {
                    agg::conv_dash<path_type> dash(path);
                    dash_array const& d = stroke_.get_dash_array();
                    dash_array::const_iterator itr = d.begin();
                    dash_array::const_iterator end = d.end();
                    for (;itr != end;++itr)
                    {
                        dash.add_dash(itr->first * scale_factor_, 
                                      itr->second * scale_factor_);
                    }
    
                    agg::conv_stroke<agg::conv_dash<path_type > > stroke(dash);
    
                    line_join_e join=stroke_.get_line_join();
                    if ( join == MITER_JOIN)
                        stroke.generator().line_join(agg::miter_join);
                    else if( join == MITER_REVERT_JOIN)
                        stroke.generator().line_join(agg::miter_join);
                    else if( join == ROUND_JOIN)
                        stroke.generator().line_join(agg::round_join);
                    else
                        stroke.generator().line_join(agg::bevel_join);
    
                    line_cap_e cap=stroke_.get_line_cap();
                    if (cap == BUTT_CAP)
                        stroke.generator().line_cap(agg::butt_cap);
                    else if (cap == SQUARE_CAP)
                        stroke.generator().line_cap(agg::square_cap);
                    else
                        stroke.generator().line_cap(agg::round_cap);
    
                    stroke.generator().miter_limit(4.0);
                    stroke.generator().width(stroke_.get_width() * scale_factor_);
                    ras_ptr->add_path(stroke);
    
                }
                else
                {
                    agg::conv_stroke<path_type>  stroke(path);
                    line_join_e join=stroke_.get_line_join();
                    if ( join == MITER_JOIN)
                        stroke.generator().line_join(agg::miter_join);
                    else if( join == MITER_REVERT_JOIN)
                        stroke.generator().line_join(agg::miter_join);
                    else if( join == ROUND_JOIN)
                        stroke.generator().line_join(agg::round_join);
                    else
                        stroke.generator().line_join(agg::bevel_join);
    
                    line_cap_e cap=stroke_.get_line_cap();
                    if (cap == BUTT_CAP)
                        stroke.generator().line_cap(agg::butt_cap);
                    else if (cap == SQUARE_CAP)
                        stroke.generator().line_cap(agg::square_cap);
                    else
                        stroke.generator().line_cap(agg::round_cap);
    
                    stroke.generator().miter_limit(4.0);
                    stroke.generator().width(stroke_.get_width() * scale_factor_);
                    ras_ptr->add_path(stroke);
                    if (writer.first) writer.first->add_line(path, feature, t_, writer.second);
                }
            }
        }
        ren.color(agg::rgba8(r, g, b, int(a*stroke_.get_opacity())));
        agg::render_scanlines(*ras_ptr, sl, ren);    
    }
}
    void operator() (marker_rgba8 const& marker)
    {
        using color = agg::rgba8;
        using order = agg::order_rgba;
        using blender_type = agg::comp_op_adaptor_rgba_pre<color, order>;
        using pattern_filter_type = agg::pattern_filter_bilinear_rgba8;
        using pattern_type = agg::line_image_pattern<pattern_filter_type>;
        using pixfmt_type = agg::pixfmt_custom_blend_rgba<blender_type, agg::rendering_buffer>;
        using renderer_base = agg::renderer_base<pixfmt_type>;
        using renderer_type = agg::renderer_outline_image<renderer_base, pattern_type>;
        using rasterizer_type = agg::rasterizer_outline_aa<renderer_type>;
        
        value_double opacity = get<value_double, keys::opacity>(sym_, feature_, common_.vars_);
        mapnik::image_rgba8 const& image = marker.get_data();
        
        value_bool clip = get<value_bool, keys::clip>(sym_, feature_, common_.vars_);
        value_double offset = get<value_double, keys::offset>(sym_, feature_, common_.vars_);
        value_double simplify_tolerance = get<value_double, keys::simplify_tolerance>(sym_, feature_, common_.vars_);
        value_double smooth = get<value_double, keys::smooth>(sym_, feature_, common_.vars_);

        agg::rendering_buffer buf(current_buffer_->getBytes(),current_buffer_->width(),current_buffer_->height(), current_buffer_->getRowSize());
        pixfmt_type pixf(buf);
        pixf.comp_op(static_cast<agg::comp_op_e>(get<composite_mode_e, keys::comp_op>(sym_, feature_, common_.vars_)));
        renderer_base ren_base(pixf);
        agg::pattern_filter_bilinear_rgba8 filter;

        pattern_source source(image, opacity);
        pattern_type pattern (filter,source);
        renderer_type ren(ren_base, pattern);
        ren.clip_box(0,0,common_.width_,common_.height_);
        rasterizer_type ras(ren);

        agg::trans_affine tr;
        auto transform = get_optional<transform_type>(sym_, keys::geometry_transform);
        if (transform) evaluate_transform(tr, feature_, common_.vars_, *transform, common_.scale_factor_);

        box2d<double> clip_box = clipping_extent(common_);
        if (clip)
        {
            double padding = (double)(common_.query_extent_.width()/pixmap_.width());
            double half_stroke = marker.width()/2.0;
            if (half_stroke > 1)
                padding *= half_stroke;
            if (std::fabs(offset) > 0)
                padding *= std::fabs(offset) * 1.2;
            padding *= common_.scale_factor_;
            clip_box.pad(padding);
        }

        vertex_converter<rasterizer_type, clip_line_tag, transform_tag,
                         affine_transform_tag,
                         simplify_tag,smooth_tag,
                         offset_transform_tag>
            converter(clip_box,ras,sym_,common_.t_,prj_trans_,tr,feature_,common_.vars_,common_.scale_factor_);

        if (clip) converter.set<clip_line_tag>(); //optional clip (default: true)
        converter.set<transform_tag>(); //always transform
        if (simplify_tolerance > 0.0) converter.set<simplify_tag>(); // optional simplify converter
        if (std::fabs(offset) > 0.0) converter.set<offset_transform_tag>(); // parallel offset
        converter.set<affine_transform_tag>(); // optional affine transform
        if (smooth > 0.0) converter.set<smooth_tag>(); // optional smooth converter

        for (geometry_type const& geom : feature_.paths())
        {
            if (geom.size() > 1)
            {
                vertex_adapter va(geom);
                converter.apply(va);
            }
        }
    }
Ejemplo n.º 23
0
    virtual void on_draw()
    {
        typedef agg::pixfmt_bgr24 pixfmt;
        typedef agg::renderer_base<pixfmt> renderer_base;
        typedef agg::renderer_scanline_aa_solid<renderer_base> renderer_solid;
        
        pixfmt pixf(rbuf_window());
        renderer_base rb(pixf);
        renderer_solid rs(rb);
        
        rb.clear(agg::rgba(1, 1, 1));

        agg::trans_affine mtx;
        agg::conv_transform<agg::path_storage, agg::trans_affine> trans(g_path, mtx);

        mtx *= agg::trans_affine_translation(-g_base_dx, -g_base_dy);
        mtx *= agg::trans_affine_scaling(g_scale, g_scale);
        mtx *= agg::trans_affine_rotation(g_angle + agg::pi);
        mtx *= agg::trans_affine_skewing(g_skew_x/1000.0, g_skew_y/1000.0);
        mtx *= agg::trans_affine_translation(initial_width()/4, initial_height()/2);
        mtx *= trans_affine_resizing();

        agg::rasterizer_scanline_aa<> ras2;
        agg::scanline_p8 sl;
        agg::scanline_u8 sl2;

        agg::render_all_paths(ras2, sl, rs, trans, g_colors, g_path_idx, g_npaths);

        mtx *= ~trans_affine_resizing();
        mtx *= agg::trans_affine_translation(initial_width()/2, 0);
        mtx *= trans_affine_resizing();

        agg::line_profile_aa profile;
        profile.width(1.0);
        agg::renderer_outline_aa<renderer_base> rp(rb, profile);
        agg::rasterizer_outline_aa<agg::renderer_outline_aa<renderer_base> > ras(rp);
        ras.round_cap(true);

        ras.render_all_paths(trans, g_colors, g_path_idx, g_npaths);

        agg::ellipse ell(m_cx, m_cy, 100.0, 100.0, 100);
        agg::conv_stroke<agg::ellipse> ell_stroke1(ell);
        ell_stroke1.width(6.0);
        agg::conv_stroke<agg::conv_stroke<agg::ellipse> > ell_stroke2(ell_stroke1);

        ell_stroke2.width(2.0);
        rs.color(agg::rgba(0,0.2,0));
        ras2.add_path(ell_stroke2);
        agg::render_scanlines(ras2, sl, rs);

        typedef agg::span_simple_blur_rgb24<agg::order_bgr> span_blur_gen;
        typedef agg::span_allocator<span_blur_gen::color_type> span_blur_alloc;

        span_blur_alloc sa;
        span_blur_gen sg;

        sg.source_image(rbuf_img(0));
        ras2.add_path(ell);

        copy_window_to_img(0);
        agg::render_scanlines_aa(ras2, sl2, rb, sa, sg);

        // More blur if desired :-)
        //copy_window_to_img(0);
        //agg::render_scanlines(ras2, sl2, rblur);
        //copy_window_to_img(0);
        //agg::render_scanlines(ras2, sl2, rblur);
        //copy_window_to_img(0);
        //agg::render_scanlines(ras2, sl2, rblur);
    }
    void operator() (marker_svg const& marker) const
    {
        using color = agg::rgba8;
        using order = agg::order_rgba;
        using blender_type = agg::comp_op_adaptor_rgba_pre<color, order>;
        using pattern_filter_type = agg::pattern_filter_bilinear_rgba8;
        using pattern_type = agg::line_image_pattern<pattern_filter_type>;
        using pixfmt_type = agg::pixfmt_custom_blend_rgba<blender_type, agg::rendering_buffer>;
        using renderer_base = agg::renderer_base<pixfmt_type>;
        using renderer_type = agg::renderer_outline_image<renderer_base, pattern_type>;
        using rasterizer_type = agg::rasterizer_outline_aa<renderer_type>;

        value_double opacity = get<value_double, keys::opacity>(sym_, feature_, common_.vars_);
        agg::trans_affine image_tr = agg::trans_affine_scaling(common_.scale_factor_);
        auto image_transform = get_optional<transform_type>(sym_, keys::image_transform);
        if (image_transform) evaluate_transform(image_tr, feature_, common_.vars_, *image_transform, common_.scale_factor_);
        mapnik::box2d<double> const& bbox_image = marker.get_data()->bounding_box() * image_tr;
        image_rgba8 image(bbox_image.width(), bbox_image.height());
        render_pattern<buffer_type>(*ras_ptr_, marker, image_tr, 1.0, image);

        value_bool clip = get<value_bool, keys::clip>(sym_, feature_, common_.vars_);
        value_double offset = get<value_double, keys::offset>(sym_, feature_, common_.vars_);
        value_double simplify_tolerance = get<value_double, keys::simplify_tolerance>(sym_, feature_, common_.vars_);
        value_double smooth = get<value_double, keys::smooth>(sym_, feature_, common_.vars_);

        agg::rendering_buffer buf(current_buffer_->bytes(),current_buffer_->width(),current_buffer_->height(), current_buffer_->row_size());
        pixfmt_type pixf(buf);
        pixf.comp_op(static_cast<agg::comp_op_e>(get<composite_mode_e, keys::comp_op>(sym_, feature_, common_.vars_)));
        renderer_base ren_base(pixf);
        agg::pattern_filter_bilinear_rgba8 filter;

        pattern_source source(image, opacity);
        pattern_type pattern (filter,source);
        renderer_type ren(ren_base, pattern);
        double half_stroke = std::max(marker.width()/2.0,marker.height()/2.0);
        int rast_clip_padding = static_cast<int>(std::round(half_stroke));
        ren.clip_box(-rast_clip_padding,-rast_clip_padding,common_.width_+rast_clip_padding,common_.height_+rast_clip_padding);
        rasterizer_type ras(ren);

        agg::trans_affine tr;
        auto transform = get_optional<transform_type>(sym_, keys::geometry_transform);
        if (transform) evaluate_transform(tr, feature_, common_.vars_, *transform, common_.scale_factor_);

        box2d<double> clip_box = clipping_extent(common_);
        if (clip)
        {
            double padding = (double)(common_.query_extent_.width()/pixmap_.width());
            if (half_stroke > 1)
                padding *= half_stroke;
            if (std::fabs(offset) > 0)
                padding *= std::fabs(offset) * 1.2;
            padding *= common_.scale_factor_;
            clip_box.pad(padding);
        }
        using vertex_converter_type = vertex_converter<clip_line_tag, transform_tag,
                                                       affine_transform_tag,
                                                       simplify_tag,smooth_tag,
                                                       offset_transform_tag>;

        vertex_converter_type converter(clip_box,sym_,common_.t_,prj_trans_,tr,feature_,common_.vars_,common_.scale_factor_);

        if (clip) converter.set<clip_line_tag>();
        converter.set<transform_tag>(); //always transform
        if (simplify_tolerance > 0.0) converter.set<simplify_tag>(); // optional simplify converter
        if (std::fabs(offset) > 0.0) converter.set<offset_transform_tag>(); // parallel offset
        converter.set<affine_transform_tag>(); // optional affine transform
        if (smooth > 0.0) converter.set<smooth_tag>(); // optional smooth converter

        using apply_vertex_converter_type = detail::apply_vertex_converter<vertex_converter_type, rasterizer_type>;
        using vertex_processor_type = geometry::vertex_processor<apply_vertex_converter_type>;
        apply_vertex_converter_type apply(converter, ras);
        mapnik::util::apply_visitor(vertex_processor_type(apply),feature_.get_geometry());
    }