Compare commits
45 commits
master
...
skia-rende
Author | SHA1 | Date | |
---|---|---|---|
|
c88db8c08a | ||
|
f2dc21bf72 | ||
|
179631560d | ||
|
a2691d57ca | ||
|
88e29148ea | ||
|
9089671ddd | ||
|
4d6cc61ec1 | ||
|
2b7340ca2c | ||
|
3d54870bea | ||
|
58833e23d4 | ||
|
8d946f78d5 | ||
|
1ff1ed9b3e | ||
|
157039c963 | ||
|
9c2704036c | ||
|
251a393d4a | ||
|
fa67d61743 | ||
|
065c3fb624 | ||
|
734634479a | ||
|
4604453f5d | ||
|
2be3d4a149 | ||
|
9522f6d6ca | ||
|
430b1d7a84 | ||
|
b1afb1d7bc | ||
|
21858be3ed | ||
|
1801a33949 | ||
|
c2a32313d9 | ||
|
de774ea941 | ||
|
95faf49fa2 | ||
|
8c25cd33b1 | ||
|
99ab053558 | ||
|
acc14b9cc0 | ||
|
55cb8188ab | ||
|
6a82e617cc | ||
|
5d91048534 | ||
|
a464092396 | ||
|
06701cfdf9 | ||
|
b7bff7106b | ||
|
ec570d8a7e | ||
|
c1a9b60b50 | ||
|
1a813f8af2 | ||
|
7c6a5f0659 | ||
|
a7e2c2ea0d | ||
|
d34fdd7fca | ||
|
d3cd1ece47 | ||
|
97039e83a1 |
31 changed files with 1461 additions and 213 deletions
20
SConstruct
20
SConstruct
|
@ -70,6 +70,7 @@ pretty_dep_names = {
|
||||||
'proj':'Proj.4 C Projections library | configure with PROJ_LIBS & PROJ_INCLUDES | more info: http://trac.osgeo.org/proj/',
|
'proj':'Proj.4 C Projections library | configure with PROJ_LIBS & PROJ_INCLUDES | more info: http://trac.osgeo.org/proj/',
|
||||||
'pg':'Postgres C Library required for PostGIS plugin | configure with pg_config program | more info: https://github.com/mapnik/mapnik/wiki/PostGIS',
|
'pg':'Postgres C Library required for PostGIS plugin | configure with pg_config program | more info: https://github.com/mapnik/mapnik/wiki/PostGIS',
|
||||||
'sqlite3':'SQLite3 C Library | configure with SQLITE_LIBS & SQLITE_INCLUDES | more info: https://github.com/mapnik/mapnik/wiki/SQLite',
|
'sqlite3':'SQLite3 C Library | configure with SQLITE_LIBS & SQLITE_INCLUDES | more info: https://github.com/mapnik/mapnik/wiki/SQLite',
|
||||||
|
'skia_core':'Skia rendering toolkit | configure with SKIA_LIBS & SKIA_INCLUDES',
|
||||||
'jpeg':'JPEG C library | configure with JPEG_LIBS & JPEG_INCLUDES',
|
'jpeg':'JPEG C library | configure with JPEG_LIBS & JPEG_INCLUDES',
|
||||||
'tiff':'TIFF C library | configure with TIFF_LIBS & TIFF_INCLUDES',
|
'tiff':'TIFF C library | configure with TIFF_LIBS & TIFF_INCLUDES',
|
||||||
'png':'PNG C library | configure with PNG_LIBS & PNG_INCLUDES',
|
'png':'PNG C library | configure with PNG_LIBS & PNG_INCLUDES',
|
||||||
|
@ -347,6 +348,12 @@ opts.AddVariables(
|
||||||
BoolVariable('CAIRO', 'Attempt to build with Cairo rendering support', 'True'),
|
BoolVariable('CAIRO', 'Attempt to build with Cairo rendering support', 'True'),
|
||||||
PathVariable('CAIRO_INCLUDES', 'Search path for cairo include files', '',PathVariable.PathAccept),
|
PathVariable('CAIRO_INCLUDES', 'Search path for cairo include files', '',PathVariable.PathAccept),
|
||||||
PathVariable('CAIRO_LIBS', 'Search path for cairo library files','',PathVariable.PathAccept),
|
PathVariable('CAIRO_LIBS', 'Search path for cairo library files','',PathVariable.PathAccept),
|
||||||
|
|
||||||
|
# Skia backend
|
||||||
|
BoolVariable('SKIA', 'Attempt to build with Skia rendering support', 'False'),
|
||||||
|
PathVariable('SKIA_INCLUDES', 'Search path for skia include files', '',PathVariable.PathAccept),
|
||||||
|
PathVariable('SKIA_LIBS', 'Search path for skia library files','',PathVariable.PathAccept),
|
||||||
|
|
||||||
('GDAL_CONFIG', 'The path to the gdal-config executable for finding gdal and ogr details.', 'gdal-config'),
|
('GDAL_CONFIG', 'The path to the gdal-config executable for finding gdal and ogr details.', 'gdal-config'),
|
||||||
('PG_CONFIG', 'The path to the pg_config executable.', 'pg_config'),
|
('PG_CONFIG', 'The path to the pg_config executable.', 'pg_config'),
|
||||||
PathVariable('OCCI_INCLUDES', 'Search path for OCCI include files', '/usr/lib/oracle/10.2.0.3/client/include', PathVariable.PathAccept),
|
PathVariable('OCCI_INCLUDES', 'Search path for OCCI include files', '/usr/lib/oracle/10.2.0.3/client/include', PathVariable.PathAccept),
|
||||||
|
@ -426,6 +433,7 @@ pickle_store = [# Scons internal variables
|
||||||
'HAS_CAIRO',
|
'HAS_CAIRO',
|
||||||
'HAS_PYCAIRO',
|
'HAS_PYCAIRO',
|
||||||
'HAS_LIBXML2',
|
'HAS_LIBXML2',
|
||||||
|
'SKIA_RENDERER',
|
||||||
'PYTHON_IS_64BIT',
|
'PYTHON_IS_64BIT',
|
||||||
'SAMPLE_INPUT_PLUGINS',
|
'SAMPLE_INPUT_PLUGINS',
|
||||||
'PKG_CONFIG_PATH',
|
'PKG_CONFIG_PATH',
|
||||||
|
@ -1050,6 +1058,7 @@ if not preconfigured:
|
||||||
env['CAIRO_LIBPATHS'] = []
|
env['CAIRO_LIBPATHS'] = []
|
||||||
env['CAIRO_ALL_LIBS'] = []
|
env['CAIRO_ALL_LIBS'] = []
|
||||||
env['CAIRO_CPPPATHS'] = []
|
env['CAIRO_CPPPATHS'] = []
|
||||||
|
env['SKIA_RENDERER'] = False
|
||||||
env['HAS_PYCAIRO'] = False
|
env['HAS_PYCAIRO'] = False
|
||||||
env['HAS_LIBXML2'] = False
|
env['HAS_LIBXML2'] = False
|
||||||
env['LIBMAPNIK_LIBS'] = []
|
env['LIBMAPNIK_LIBS'] = []
|
||||||
|
@ -1189,6 +1198,17 @@ if not preconfigured:
|
||||||
|
|
||||||
OPTIONAL_LIBSHEADERS = []
|
OPTIONAL_LIBSHEADERS = []
|
||||||
|
|
||||||
|
if env['SKIA']:
|
||||||
|
OPTIONAL_LIBSHEADERS.append(['skia_core', ['SkCanvas.h'], False,'C++','-DSKIA_RENDERER'])
|
||||||
|
if env['SKIA_LIBS'] or env['SKIA_INCLUDES']:
|
||||||
|
env.AppendUnique(CPPPATH = os.path.realpath(env['SKIA_INCLUDES'] + '/config'))
|
||||||
|
env.AppendUnique(CPPPATH = os.path.realpath(env['SKIA_INCLUDES'] + '/utils'))
|
||||||
|
env.AppendUnique(CPPPATH = os.path.realpath(env['SKIA_INCLUDES'] + '/core'))
|
||||||
|
env.AppendUnique(CPPPATH = os.path.realpath(env['SKIA_INCLUDES'] + '/effects'))
|
||||||
|
env.AppendUnique(LIBPATH = os.path.realpath(env['SKIA_LIBS']))
|
||||||
|
else:
|
||||||
|
env['SKIPPED_DEPS'].extend(['skia'])
|
||||||
|
|
||||||
if env['JPEG']:
|
if env['JPEG']:
|
||||||
OPTIONAL_LIBSHEADERS.append(['jpeg', ['stdio.h', 'jpeglib.h'], False,'C','-DHAVE_JPEG'])
|
OPTIONAL_LIBSHEADERS.append(['jpeg', ['stdio.h', 'jpeglib.h'], False,'C','-DHAVE_JPEG'])
|
||||||
inc_path = env['%s_INCLUDES' % 'JPEG']
|
inc_path = env['%s_INCLUDES' % 'JPEG']
|
||||||
|
|
|
@ -397,6 +397,15 @@ bool has_grid_renderer()
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool has_skia_renderer()
|
||||||
|
{
|
||||||
|
#if defined(SKIA_RENDERER)
|
||||||
|
return true;
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
bool has_jpeg()
|
bool has_jpeg()
|
||||||
{
|
{
|
||||||
#if defined(HAVE_JPEG)
|
#if defined(HAVE_JPEG)
|
||||||
|
|
|
@ -19,11 +19,14 @@
|
||||||
|
|
||||||
|
|
||||||
// qt
|
// qt
|
||||||
#include <QtWidgets/QApplication>
|
#include <QApplication>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
#include <mapnik/datasource_cache.hpp>
|
#include <mapnik/datasource_cache.hpp>
|
||||||
#include <mapnik/font_engine_freetype.hpp>
|
#include <mapnik/font_engine_freetype.hpp>
|
||||||
|
#if defined(SKIA_RENDERER)
|
||||||
|
#include <mapnik/skia/skia_typeface_cache.hpp>
|
||||||
|
#endif
|
||||||
#include "mainwindow.hpp"
|
#include "mainwindow.hpp"
|
||||||
|
|
||||||
// boost
|
// boost
|
||||||
|
@ -54,6 +57,15 @@ int main( int argc, char **argv )
|
||||||
QString font_dir = settings.value("dir").toString();
|
QString font_dir = settings.value("dir").toString();
|
||||||
freetype_engine::register_fonts(font_dir.toStdString());
|
freetype_engine::register_fonts(font_dir.toStdString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(SKIA_RENDERER)
|
||||||
|
for (int index=0; index < count; ++index)
|
||||||
|
{
|
||||||
|
settings.setArrayIndex(index);
|
||||||
|
QString font_dir = settings.value("dir").toString();
|
||||||
|
mapnik::skia_typeface_cache::register_fonts(font_dir.toStdString());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
settings.endArray();
|
settings.endArray();
|
||||||
|
|
||||||
QApplication app( argc, argv );
|
QApplication app( argc, argv );
|
||||||
|
|
|
@ -263,6 +263,71 @@ void MainWindow::export_as()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef SKIA_RENDERER
|
||||||
|
void MainWindow::export_as_skia_pdf()
|
||||||
|
{
|
||||||
|
QAction *action = qobject_cast<QAction *>(sender());
|
||||||
|
QByteArray fileFormat = action->data().toByteArray();
|
||||||
|
QString initialPath = QDir::currentPath() + "/map-skia." + fileFormat;
|
||||||
|
|
||||||
|
QString fileName = QFileDialog::getSaveFileName(this, tr("Export As Skia PDF"),
|
||||||
|
initialPath,
|
||||||
|
tr("%1 Files (*.%2);;All Files (*)")
|
||||||
|
.arg(QString(fileFormat.toUpper()))
|
||||||
|
.arg(QString(fileFormat)));
|
||||||
|
if (!fileName.isEmpty())
|
||||||
|
{
|
||||||
|
std::cerr << "Skia PDF" << std::endl;
|
||||||
|
mapWidget_->export_skia_pdf(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_CAIRO
|
||||||
|
void MainWindow::export_as_cairo_pdf()
|
||||||
|
{
|
||||||
|
QAction *action = qobject_cast<QAction *>(sender());
|
||||||
|
QByteArray fileFormat = action->data().toByteArray();
|
||||||
|
QString initialPath = QDir::currentPath() + "/map-cairo." + fileFormat;
|
||||||
|
|
||||||
|
QString fileName = QFileDialog::getSaveFileName(this, tr("Export As Cairo PDF"),
|
||||||
|
initialPath,
|
||||||
|
tr("%1 Files (*.%2);;All Files (*)")
|
||||||
|
.arg(QString(fileFormat.toUpper()))
|
||||||
|
.arg(QString(fileFormat)));
|
||||||
|
if (!fileName.isEmpty())
|
||||||
|
{
|
||||||
|
std::cerr << "Cairo PDF" << std::endl;
|
||||||
|
mapWidget_->export_cairo_pdf(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef SVG_RENDERER
|
||||||
|
|
||||||
|
void MainWindow::export_as_mapnik_svg()
|
||||||
|
{
|
||||||
|
QAction *action = qobject_cast<QAction *>(sender());
|
||||||
|
QByteArray fileFormat = action->data().toByteArray();
|
||||||
|
QString initialPath = QDir::currentPath() + "/map-mapnik." + fileFormat;
|
||||||
|
|
||||||
|
QString fileName = QFileDialog::getSaveFileName(this, tr("Export As Mapnik SVG"),
|
||||||
|
initialPath,
|
||||||
|
tr("%1 Files (*.%2);;All Files (*)")
|
||||||
|
.arg(QString(fileFormat.toUpper()))
|
||||||
|
.arg(QString(fileFormat)));
|
||||||
|
if (!fileName.isEmpty())
|
||||||
|
{
|
||||||
|
std::cerr << "Mapnik SVG" << std::endl;
|
||||||
|
mapWidget_->export_mapnik_svg(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
void MainWindow::print()
|
void MainWindow::print()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -334,6 +399,23 @@ void MainWindow::createActions()
|
||||||
connect(action, SIGNAL(triggered()), this, SLOT(export_as()));
|
connect(action, SIGNAL(triggered()), this, SLOT(export_as()));
|
||||||
exportAsActs.append(action);
|
exportAsActs.append(action);
|
||||||
}
|
}
|
||||||
|
#ifdef SKIA_RENDERER
|
||||||
|
exportSkiaPDF = new QAction("Skia",this);
|
||||||
|
exportSkiaPDF->setData(QByteArray("pdf"));
|
||||||
|
connect(exportSkiaPDF, SIGNAL(triggered()), this, SLOT(export_as_skia_pdf()));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_CAIRO
|
||||||
|
exportCairoPDF = new QAction("Cairo",this);
|
||||||
|
exportCairoPDF->setData(QByteArray("pdf"));
|
||||||
|
connect(exportCairoPDF, SIGNAL(triggered()), this, SLOT(export_as_cairo_pdf()));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef SVG_RENDERER
|
||||||
|
exportMapnikSVG = new QAction("Mapnik",this);
|
||||||
|
exportMapnikSVG->setData(QByteArray("svg"));
|
||||||
|
connect(exportMapnikSVG, SIGNAL(triggered()), this, SLOT(export_as_mapnik_svg()));
|
||||||
|
#endif
|
||||||
|
|
||||||
printAct = new QAction(QIcon(":/images/print.png"),tr("&Print ..."),this);
|
printAct = new QAction(QIcon(":/images/print.png"),tr("&Print ..."),this);
|
||||||
printAct->setShortcut(tr("Ctrl+E"));
|
printAct->setShortcut(tr("Ctrl+E"));
|
||||||
|
@ -353,10 +435,19 @@ void MainWindow::createMenus()
|
||||||
foreach (QAction *action, exportAsActs)
|
foreach (QAction *action, exportAsActs)
|
||||||
exportMenu->addAction(action);
|
exportMenu->addAction(action);
|
||||||
|
|
||||||
|
exportPDFMenu = new QMenu(tr("&Export As PDF"), this);
|
||||||
|
exportPDFMenu->addAction(exportSkiaPDF);
|
||||||
|
exportPDFMenu->addAction(exportCairoPDF);
|
||||||
|
|
||||||
|
exportSVGMenu = new QMenu(tr("&Export As SVG"), this);
|
||||||
|
exportSVGMenu->addAction(exportMapnikSVG);
|
||||||
|
|
||||||
fileMenu = new QMenu(tr("&File"),this);
|
fileMenu = new QMenu(tr("&File"),this);
|
||||||
fileMenu->addAction(openAct);
|
fileMenu->addAction(openAct);
|
||||||
fileMenu->addAction(saveAct);
|
fileMenu->addAction(saveAct);
|
||||||
fileMenu->addMenu(exportMenu);
|
fileMenu->addMenu(exportMenu);
|
||||||
|
fileMenu->addMenu(exportPDFMenu);
|
||||||
|
fileMenu->addMenu(exportSVGMenu);
|
||||||
fileMenu->addAction(printAct);
|
fileMenu->addAction(printAct);
|
||||||
fileMenu->addSeparator();
|
fileMenu->addSeparator();
|
||||||
fileMenu->addAction(exitAct);
|
fileMenu->addAction(exitAct);
|
||||||
|
@ -386,6 +477,10 @@ void MainWindow::createToolBars()
|
||||||
renderer_selector_->addItem("AGG");
|
renderer_selector_->addItem("AGG");
|
||||||
#ifdef HAVE_CAIRO
|
#ifdef HAVE_CAIRO
|
||||||
renderer_selector_->addItem("Cairo");
|
renderer_selector_->addItem("Cairo");
|
||||||
|
#endif
|
||||||
|
#ifdef SKIA_RENDERER
|
||||||
|
renderer_selector_->addItem("Skia");
|
||||||
|
renderer_selector_->addItem("Skia-Gpu");
|
||||||
#endif
|
#endif
|
||||||
renderer_selector_->addItem("Grid");
|
renderer_selector_->addItem("Grid");
|
||||||
fileToolBar->addWidget(renderer_selector_);
|
fileToolBar->addWidget(renderer_selector_);
|
||||||
|
|
|
@ -41,7 +41,7 @@ class QDoubleSpinBox;
|
||||||
class MainWindow : public QMainWindow
|
class MainWindow : public QMainWindow
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
MainWindow();
|
MainWindow();
|
||||||
virtual ~MainWindow();
|
virtual ~MainWindow();
|
||||||
void set_default_extent(double x0,double y0,double x1, double y1);
|
void set_default_extent(double x0,double y0,double x1, double y1);
|
||||||
|
@ -54,6 +54,9 @@ public slots:
|
||||||
void pan();
|
void pan();
|
||||||
void info();
|
void info();
|
||||||
void export_as();
|
void export_as();
|
||||||
|
void export_as_skia_pdf();
|
||||||
|
void export_as_cairo_pdf();
|
||||||
|
void export_as_mapnik_svg();
|
||||||
void open(QString const& path = QString());
|
void open(QString const& path = QString());
|
||||||
void reload();
|
void reload();
|
||||||
void save();
|
void save();
|
||||||
|
@ -96,11 +99,16 @@ private:
|
||||||
QAction *panDownAct;
|
QAction *panDownAct;
|
||||||
QAction *reloadAct;
|
QAction *reloadAct;
|
||||||
QAction *layerInfo;
|
QAction *layerInfo;
|
||||||
|
QAction *exportSkiaPDF;
|
||||||
|
QAction *exportCairoPDF;
|
||||||
|
QAction *exportMapnikSVG;
|
||||||
//toolbars
|
//toolbars
|
||||||
QToolBar *fileToolBar;
|
QToolBar *fileToolBar;
|
||||||
QToolBar *editToolBar;
|
QToolBar *editToolBar;
|
||||||
//menus
|
//menus
|
||||||
QMenu *exportMenu;
|
QMenu *exportMenu;
|
||||||
|
QMenu *exportPDFMenu;
|
||||||
|
QMenu *exportSVGMenu;
|
||||||
QMenu *fileMenu;
|
QMenu *fileMenu;
|
||||||
QMenu *helpMenu;
|
QMenu *helpMenu;
|
||||||
//status bar
|
//status bar
|
||||||
|
|
|
@ -35,14 +35,50 @@
|
||||||
#include <mapnik/config_error.hpp>
|
#include <mapnik/config_error.hpp>
|
||||||
#include <mapnik/image_util.hpp>
|
#include <mapnik/image_util.hpp>
|
||||||
|
|
||||||
|
#ifdef SVG_RENDERER
|
||||||
|
#include <mapnik/svg/output/svg_renderer.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_CAIRO
|
#ifdef HAVE_CAIRO
|
||||||
// cairo
|
// cairo
|
||||||
#include <mapnik/cairo_renderer.hpp>
|
#include <mapnik/cairo_renderer.hpp>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef SKIA_RENDERER
|
||||||
|
// skia
|
||||||
|
#include <mapnik/skia/skia_renderer.hpp>
|
||||||
|
#include <SkCanvas.h>
|
||||||
|
#include <SkBitmap.h>
|
||||||
|
#include <SkStream.h>
|
||||||
|
#include <SkPDFDevice.h>
|
||||||
|
#include <SkPDFDocument.h>
|
||||||
|
#include <SkGpuDevice.h>
|
||||||
|
#include <gl/GrGLInterface.h>
|
||||||
|
#if SK_SUPPORT_GPU
|
||||||
|
#include <gl/GrGLFunctions.h>
|
||||||
|
#include <GrContextFactory.h>
|
||||||
|
#include <gl/GrGLDefines.h>
|
||||||
|
#include <gl/GrGLUtil.h>
|
||||||
|
#include <gl/GrGLExtensions.h>
|
||||||
|
GrContextFactory gGrContextFactory;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
GrContextFactory* GetGrContextFactory() {
|
||||||
|
#if SK_SUPPORT_GPU
|
||||||
|
return &gGrContextFactory;
|
||||||
|
#else
|
||||||
|
return NULL;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include "mapwidget.hpp"
|
#include "mapwidget.hpp"
|
||||||
#include "info_dialog.hpp"
|
#include "info_dialog.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
using mapnik::image_32;
|
using mapnik::image_32;
|
||||||
using mapnik::Map;
|
using mapnik::Map;
|
||||||
using mapnik::layer;
|
using mapnik::layer;
|
||||||
|
@ -77,7 +113,7 @@ double scales [] = {279541132.014,
|
||||||
533.182395962};
|
533.182395962};
|
||||||
|
|
||||||
MapWidget::MapWidget(QWidget *parent)
|
MapWidget::MapWidget(QWidget *parent)
|
||||||
: QWidget(parent),
|
: QGLWidget(parent),
|
||||||
map_(),
|
map_(),
|
||||||
selected_(1),
|
selected_(1),
|
||||||
extent_(),
|
extent_(),
|
||||||
|
@ -98,6 +134,7 @@ MapWidget::MapWidget(QWidget *parent)
|
||||||
pen_.setJoinStyle(Qt::RoundJoin);
|
pen_.setJoinStyle(Qt::RoundJoin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void MapWidget::setTool(eTool tool)
|
void MapWidget::setTool(eTool tool)
|
||||||
{
|
{
|
||||||
cur_tool_=tool;
|
cur_tool_=tool;
|
||||||
|
@ -495,18 +532,15 @@ void MapWidget::set_scaling_factor(double scaling_factor)
|
||||||
|
|
||||||
void render_agg(mapnik::Map const& map, double scaling_factor, QPixmap & pix)
|
void render_agg(mapnik::Map const& map, double scaling_factor, QPixmap & pix)
|
||||||
{
|
{
|
||||||
|
boost::timer::auto_cpu_timer t;
|
||||||
unsigned width=map.width();
|
unsigned width=map.width();
|
||||||
unsigned height=map.height();
|
unsigned height=map.height();
|
||||||
|
|
||||||
image_32 buf(width,height);
|
image_32 buf(width,height);
|
||||||
mapnik::agg_renderer<image_32> ren(map,buf,scaling_factor);
|
mapnik::agg_renderer<image_32> ren(map,buf,scaling_factor);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
{
|
ren.apply();
|
||||||
boost::timer::auto_cpu_timer t;
|
|
||||||
ren.apply();
|
|
||||||
}
|
|
||||||
QImage image((uchar*)buf.raw_data(),width,height,QImage::Format_ARGB32);
|
QImage image((uchar*)buf.raw_data(),width,height,QImage::Format_ARGB32);
|
||||||
pix = QPixmap::fromImage(image.rgbSwapped());
|
pix = QPixmap::fromImage(image.rgbSwapped());
|
||||||
}
|
}
|
||||||
|
@ -524,17 +558,130 @@ void render_agg(mapnik::Map const& map, double scaling_factor, QPixmap & pix)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef SKIA_RENDERER
|
||||||
|
void render_skia(mapnik::Map const& map, double scaling_factor, QPixmap & pix)
|
||||||
|
{
|
||||||
|
boost::timer::auto_cpu_timer t;
|
||||||
|
|
||||||
|
unsigned width=map.width();
|
||||||
|
unsigned height=map.height();
|
||||||
|
|
||||||
|
mapnik::image_32 buf(width,height);
|
||||||
|
|
||||||
|
SkBitmap bitmap;
|
||||||
|
bitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height);
|
||||||
|
bitmap.setPixels(buf.raw_data());
|
||||||
|
SkCanvas canvas(bitmap);
|
||||||
|
|
||||||
|
mapnik::skia_renderer ren(map,canvas,scaling_factor);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ren.apply();
|
||||||
|
QImage image((uchar*)buf.raw_data(),width,height,QImage::Format_ARGB32);
|
||||||
|
pix = QPixmap::fromImage(image.rgbSwapped());
|
||||||
|
}
|
||||||
|
catch (mapnik::config_error & ex)
|
||||||
|
{
|
||||||
|
std::cerr << "Skia:" << ex.what() << std::endl;
|
||||||
|
}
|
||||||
|
catch (const std::exception & ex)
|
||||||
|
{
|
||||||
|
std::cerr << "Skia:exception: " << ex.what() << std::endl;
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
std::cerr << "Skia:Unknown exception caught!\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void render_skia_gpu(GrGLInterface const * cur_interface, mapnik::Map const& map, double scaling_factor)
|
||||||
|
{
|
||||||
|
std::cerr << "SKIA GPU start " << cur_interface << std::endl ;
|
||||||
|
boost::timer::auto_cpu_timer t;
|
||||||
|
unsigned width=map.width();
|
||||||
|
unsigned height=map.height();
|
||||||
|
|
||||||
|
GrContext* context = GrContext::Create(kOpenGL_GrBackend, (GrBackendContext) cur_interface);
|
||||||
|
GrBackendRenderTargetDesc desc;
|
||||||
|
desc.fConfig = kSkia8888_GrPixelConfig;
|
||||||
|
desc.fWidth = width;
|
||||||
|
desc.fHeight = height;
|
||||||
|
//GrGLExtensions extensions;
|
||||||
|
//GrGLBinding binding;
|
||||||
|
//GrGLInterface interface;
|
||||||
|
//interface.validate(binding);
|
||||||
|
//extensions.init(binding, cur_interface);
|
||||||
|
GR_GL_GetIntegerv(cur_interface, GR_GL_SAMPLES, &desc.fSampleCnt);
|
||||||
|
GR_GL_GetIntegerv(cur_interface, GR_GL_STENCIL_BITS, &desc.fStencilBits);
|
||||||
|
GrGLint buffer;
|
||||||
|
GR_GL_GetIntegerv(cur_interface, GR_GL_FRAMEBUFFER_BINDING, &buffer);
|
||||||
|
desc.fRenderTargetHandle = buffer;
|
||||||
|
desc.fOrigin = kBottomLeft_GrSurfaceOrigin;
|
||||||
|
|
||||||
|
GrRenderTarget* curRenderTarget = context->wrapBackendRenderTarget(desc);
|
||||||
|
SkGpuDevice device(context, curRenderTarget);
|
||||||
|
SkCanvas canvas(&device);
|
||||||
|
|
||||||
|
mapnik::skia_renderer ren(map,canvas,scaling_factor);
|
||||||
|
ren.apply();
|
||||||
|
context->resetContext();
|
||||||
|
context->flush();
|
||||||
|
std::cerr << "SKIA GPU Done" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MapWidget::export_skia_pdf(QString const& filename)
|
||||||
|
{
|
||||||
|
unsigned width = map_->width();
|
||||||
|
unsigned height = map_->height();
|
||||||
|
SkISize pageSize = SkISize::Make(width,height);
|
||||||
|
|
||||||
|
|
||||||
|
SkPDFDevice dev(pageSize, pageSize, SkMatrix::I());
|
||||||
|
SkCanvas canvas(&dev);
|
||||||
|
mapnik::skia_renderer ren(*map_,canvas,scaling_factor_);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ren.apply();
|
||||||
|
}
|
||||||
|
catch (mapnik::config_error & ex)
|
||||||
|
{
|
||||||
|
std::cerr << "Skia:" << ex.what() << std::endl;
|
||||||
|
}
|
||||||
|
catch (const std::exception & ex)
|
||||||
|
{
|
||||||
|
std::cerr << "Skia:exception: " << ex.what() << std::endl;
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
std::cerr << "Skia:Unknown exception caught!\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
SkPDFDocument doc;
|
||||||
|
doc.appendPage(&dev);
|
||||||
|
std::cerr << filename.toStdString() << std::endl;
|
||||||
|
SkFILEWStream stream(filename.toStdString().c_str());
|
||||||
|
if (stream.isValid())
|
||||||
|
{
|
||||||
|
doc.emitPDF(&stream);
|
||||||
|
}
|
||||||
|
std::cerr << "Done" << std::endl;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void render_grid(mapnik::Map const& map, double scaling_factor, QPixmap & pix)
|
void render_grid(mapnik::Map const& map, double scaling_factor, QPixmap & pix)
|
||||||
{
|
{
|
||||||
std::cerr << "Not supported" << std::endl;
|
std::cerr << "Not supported" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_CAIRO
|
||||||
|
void MapWidget::export_cairo_pdf(QString const& filename)
|
||||||
|
{
|
||||||
|
save_to_cairo_file(*map_,filename.toStdString(),scaling_factor_);
|
||||||
|
std::cerr << "Done" << std::endl;
|
||||||
|
}
|
||||||
void render_cairo(mapnik::Map const& map, double scaling_factor, QPixmap & pix)
|
void render_cairo(mapnik::Map const& map, double scaling_factor, QPixmap & pix)
|
||||||
{
|
{
|
||||||
|
boost::timer::auto_cpu_timer t;
|
||||||
#ifdef HAVE_CAIRO
|
|
||||||
mapnik::cairo_surface_ptr image_surface(cairo_image_surface_create(CAIRO_FORMAT_ARGB32,map.width(),map.height()),
|
mapnik::cairo_surface_ptr image_surface(cairo_image_surface_create(CAIRO_FORMAT_ARGB32,map.width(),map.height()),
|
||||||
mapnik::cairo_surface_closer());
|
mapnik::cairo_surface_closer());
|
||||||
mapnik::cairo_renderer<mapnik::cairo_surface_ptr> renderer(map, image_surface, scaling_factor);
|
mapnik::cairo_renderer<mapnik::cairo_surface_ptr> renderer(map, image_surface, scaling_factor);
|
||||||
|
@ -542,15 +689,49 @@ void render_cairo(mapnik::Map const& map, double scaling_factor, QPixmap & pix)
|
||||||
image_32 buf(image_surface);
|
image_32 buf(image_surface);
|
||||||
QImage image((uchar*)buf.raw_data(),buf.width(),buf.height(),QImage::Format_ARGB32);
|
QImage image((uchar*)buf.raw_data(),buf.width(),buf.height(),QImage::Format_ARGB32);
|
||||||
pix = QPixmap::fromImage(image.rgbSwapped());
|
pix = QPixmap::fromImage(image.rgbSwapped());
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef SVG_RENDERER
|
||||||
|
void MapWidget::export_mapnik_svg(QString const& filename)
|
||||||
|
{
|
||||||
|
boost::timer::auto_cpu_timer t;
|
||||||
|
std::ofstream output_stream(filename.toStdString().c_str());
|
||||||
|
if (output_stream)
|
||||||
|
{
|
||||||
|
std::ostream_iterator<char> output_itr(output_stream);
|
||||||
|
mapnik::svg_renderer<std::ostream_iterator<char> > ren(*map_, output_itr, scaling_factor_);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ren.apply();
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
std::cerr << "Exception caught." << std::endl;
|
||||||
|
}
|
||||||
|
output_stream.close();
|
||||||
|
}
|
||||||
|
std::cerr << "Done" << std::endl;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void MapWidget::updateRenderer(QString const& txt)
|
void MapWidget::updateRenderer(QString const& txt)
|
||||||
{
|
{
|
||||||
|
bool auto_swap = true;
|
||||||
|
|
||||||
if (txt == "AGG") cur_renderer_ = AGG;
|
if (txt == "AGG") cur_renderer_ = AGG;
|
||||||
else if (txt == "Cairo") cur_renderer_ = Cairo;
|
else if (txt == "Cairo") cur_renderer_ = Cairo;
|
||||||
else if (txt == "Grid") cur_renderer_ = Grid;
|
else if (txt == "Grid") cur_renderer_ = Grid;
|
||||||
|
else if (txt == "Skia") cur_renderer_ = Skia;
|
||||||
|
else if (txt == "Skia-Gpu")
|
||||||
|
{
|
||||||
|
cur_renderer_ = Skia_Gpu;
|
||||||
|
auto_swap = false;
|
||||||
|
}
|
||||||
std::cerr << "Update renderer called" << std::endl;
|
std::cerr << "Update renderer called" << std::endl;
|
||||||
|
setAutoBufferSwap(auto_swap);
|
||||||
updateMap();
|
updateMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -568,14 +749,28 @@ void MapWidget::updateMap()
|
||||||
{
|
{
|
||||||
render_agg(*map_, scaling_factor_, pix_);
|
render_agg(*map_, scaling_factor_, pix_);
|
||||||
}
|
}
|
||||||
|
#ifdef HAVE_CAIRO
|
||||||
else if (cur_renderer_ == Cairo)
|
else if (cur_renderer_ == Cairo)
|
||||||
{
|
{
|
||||||
render_cairo(*map_, scaling_factor_, pix_);
|
render_cairo(*map_, scaling_factor_, pix_);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
else if (cur_renderer_ == Grid)
|
else if (cur_renderer_ == Grid)
|
||||||
{
|
{
|
||||||
render_grid(*map_, scaling_factor_, pix_);
|
render_grid(*map_, scaling_factor_, pix_);
|
||||||
}
|
}
|
||||||
|
#ifdef SKIA_RENDERER
|
||||||
|
else if (cur_renderer_ == Skia)
|
||||||
|
{
|
||||||
|
render_skia(*map_, scaling_factor_, pix_);
|
||||||
|
}
|
||||||
|
else if (cur_renderer_ == Skia_Gpu)
|
||||||
|
{
|
||||||
|
GrGLInterface const* cur_interface = GrGLCreateNativeInterface();
|
||||||
|
render_skia_gpu(cur_interface, *map_, scaling_factor_);
|
||||||
|
swapBuffers();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::cerr << "Unknown renderer..." << std::endl;
|
std::cerr << "Unknown renderer..." << std::endl;
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#define MAP_WIDGET_HPP
|
#define MAP_WIDGET_HPP
|
||||||
|
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
#include <QGLWidget>
|
||||||
#include <QImage>
|
#include <QImage>
|
||||||
#include <QPixmap>
|
#include <QPixmap>
|
||||||
#include <QPen>
|
#include <QPen>
|
||||||
|
@ -35,7 +36,9 @@
|
||||||
#include <mapnik/map.hpp>
|
#include <mapnik/map.hpp>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class MapWidget : public QWidget
|
struct GrGLInterface;
|
||||||
|
|
||||||
|
class MapWidget : public QGLWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
@ -49,8 +52,10 @@ public:
|
||||||
|
|
||||||
enum eRenderer
|
enum eRenderer
|
||||||
{
|
{
|
||||||
AGG,
|
AGG = 1,
|
||||||
Cairo,
|
Cairo,
|
||||||
|
Skia,
|
||||||
|
Skia_Gpu,
|
||||||
Grid
|
Grid
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -85,6 +90,18 @@ public:
|
||||||
void panUp();
|
void panUp();
|
||||||
void panDown();
|
void panDown();
|
||||||
void set_scaling_factor(double);
|
void set_scaling_factor(double);
|
||||||
|
#ifdef SKIA_RENDERER
|
||||||
|
void export_skia_pdf(QString const& filename);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_CAIRO
|
||||||
|
void export_cairo_pdf(QString const& filename);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef SVG_RENDERER
|
||||||
|
void export_mapnik_svg(QString const& filename);
|
||||||
|
#endif
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void zoomToLevel(int level);
|
void zoomToLevel(int level);
|
||||||
void updateMap();
|
void updateMap();
|
||||||
|
@ -105,6 +122,7 @@ protected:
|
||||||
unsigned height,
|
unsigned height,
|
||||||
std::string const& filename,
|
std::string const& filename,
|
||||||
std::string const& type);
|
std::string const& type);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // MAP_WIDGET_HPP
|
#endif // MAP_WIDGET_HPP
|
||||||
|
|
|
@ -3,12 +3,24 @@
|
||||||
######################################################################
|
######################################################################
|
||||||
TEMPLATE = app
|
TEMPLATE = app
|
||||||
QT += core gui widgets
|
QT += core gui widgets
|
||||||
QMAKE_CXX = clang++
|
QT += opengl
|
||||||
QMAKE_CXXFLAGS += $$system(mapnik-config --cxxflags)
|
|
||||||
|
QMAKE_CXX = $$system(mapnik-config --cxx)
|
||||||
|
QMAKE_LINK = $$system(mapnik-config --cxx)
|
||||||
|
QMAKE_CXXFLAGS += $$system(mapnik-config --cxxflags --defines)
|
||||||
QMAKE_CXXFLAGS += $$system(mapnik-config --includes --dep-includes)
|
QMAKE_CXXFLAGS += $$system(mapnik-config --includes --dep-includes)
|
||||||
|
QMAKE_CXXFLAGS += "-I/Users/artem/Projects/skia/trunk/include/gpu"
|
||||||
|
QMAKE_CXXFLAGS += "-I/Users/artem/Projects/skia/trunk/include/pdf"
|
||||||
|
QMAKE_CXXFLAGS += "-I/Users/artem/Projects/skia/trunk/src/gpu"
|
||||||
|
|
||||||
QMAKE_LFLAGS += $$system(mapnik-config --libs)
|
QMAKE_LFLAGS += $$system(mapnik-config --libs)
|
||||||
QMAKE_LFLAGS += $$system(mapnik-config --ldflags --dep-libs)
|
QMAKE_LFLAGS += $$system(mapnik-config --ldflags --dep-libs)
|
||||||
QMAKE_LFLAGS += -lboost_timer
|
QMAKE_LFLAGS += -lboost_timer
|
||||||
|
QMAKE_LFLAGS += -lskia_pdf
|
||||||
|
QMAKE_LFLAGS += -lskia_skgpu
|
||||||
|
QMAKE_LFLAGS += -lzlib
|
||||||
|
QMAKE_LFLAGS += "-framework Cocoa"
|
||||||
|
|
||||||
# Input
|
# Input
|
||||||
|
|
||||||
CONFIG += qt debug_and_release
|
CONFIG += qt debug_and_release
|
||||||
|
|
|
@ -4,7 +4,7 @@ from glob import glob
|
||||||
Import('env')
|
Import('env')
|
||||||
|
|
||||||
base = './mapnik/'
|
base = './mapnik/'
|
||||||
subdirs = ['','svg','wkt','grid','json','util','text_placements','formatting']
|
subdirs = ['','svg','wkt','grid','json','util','text_placements','formatting','skia']
|
||||||
|
|
||||||
if env['SVG_RENDERER']:
|
if env['SVG_RENDERER']:
|
||||||
subdirs.append('svg/output')
|
subdirs.append('svg/output')
|
||||||
|
|
|
@ -78,19 +78,17 @@ void check_object_status_and_throw_exception(T const& object)
|
||||||
class cairo_face : private mapnik::noncopyable
|
class cairo_face : private mapnik::noncopyable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
cairo_face(boost::shared_ptr<freetype_engine> const& engine, face_ptr const& face);
|
cairo_face(boost::shared_ptr<freetype_engine> const& engine, FT_Face face);
|
||||||
~cairo_face();
|
~cairo_face();
|
||||||
cairo_font_face_t * face() const;
|
cairo_font_face_t * face() const;
|
||||||
private:
|
private:
|
||||||
class handle
|
class handle
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
handle(boost::shared_ptr<freetype_engine> const& engine, face_ptr const& face)
|
handle(boost::shared_ptr<freetype_engine> const& engine)
|
||||||
: engine_(engine), face_(face) {}
|
: engine_(engine) {}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
boost::shared_ptr<freetype_engine> engine_;
|
boost::shared_ptr<freetype_engine> engine_;
|
||||||
face_ptr face_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void destroy(void *data)
|
static void destroy(void *data)
|
||||||
|
@ -100,20 +98,21 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
face_ptr face_;
|
|
||||||
cairo_font_face_t *c_face_;
|
cairo_font_face_t *c_face_;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef boost::shared_ptr<cairo_face> cairo_face_ptr;
|
typedef boost::shared_ptr<cairo_face> cairo_face_ptr;
|
||||||
|
|
||||||
|
struct FT_FaceRec_;
|
||||||
|
|
||||||
class cairo_face_manager : private mapnik::noncopyable
|
class cairo_face_manager : private mapnik::noncopyable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
cairo_face_manager(boost::shared_ptr<freetype_engine> engine);
|
cairo_face_manager(boost::shared_ptr<freetype_engine> engine);
|
||||||
cairo_face_ptr get_face(face_ptr face);
|
cairo_face_ptr get_face(font_face const& face);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef std::map<face_ptr,cairo_face_ptr> cairo_face_cache;
|
typedef std::map<FT_FaceRec_*,cairo_face_ptr> cairo_face_cache;
|
||||||
boost::shared_ptr<freetype_engine> font_engine_;
|
boost::shared_ptr<freetype_engine> font_engine_;
|
||||||
cairo_face_cache cache_;
|
cairo_face_cache cache_;
|
||||||
};
|
};
|
||||||
|
@ -310,7 +309,7 @@ public:
|
||||||
void set_gradient(cairo_gradient const& pattern, box2d<double> const& bbox);
|
void set_gradient(cairo_gradient const& pattern, box2d<double> const& bbox);
|
||||||
void add_image(double x, double y, image_data_32 & data, double opacity = 1.0);
|
void add_image(double x, double y, image_data_32 & data, double opacity = 1.0);
|
||||||
void add_image(agg::trans_affine const& tr, image_data_32 & data, double opacity = 1.0);
|
void add_image(agg::trans_affine const& tr, image_data_32 & data, double opacity = 1.0);
|
||||||
void set_font_face(cairo_face_manager & manager, face_ptr face);
|
void set_font_face(cairo_face_manager & manager, font_face const& face);
|
||||||
void set_font_matrix(cairo_matrix_t const& matrix);
|
void set_font_matrix(cairo_matrix_t const& matrix);
|
||||||
void set_matrix(cairo_matrix_t const& matrix);
|
void set_matrix(cairo_matrix_t const& matrix);
|
||||||
void transform(cairo_matrix_t const& matrix);
|
void transform(cairo_matrix_t const& matrix);
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
*
|
*
|
||||||
* This file is part of Mapnik (c++ mapping toolkit)
|
* This file is part of Mapnik (c++ mapping toolkit)
|
||||||
*
|
*
|
||||||
* Copyright (C) 2011 Artem Pavlenko
|
* Copyright (C) 2013 Artem Pavlenko
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
@ -37,7 +37,7 @@
|
||||||
#include <mapnik/noncopyable.hpp>
|
#include <mapnik/noncopyable.hpp>
|
||||||
#include <mapnik/value_types.hpp>
|
#include <mapnik/value_types.hpp>
|
||||||
#include <mapnik/pixel_position.hpp>
|
#include <mapnik/pixel_position.hpp>
|
||||||
|
#include <mapnik/font_util.hpp>
|
||||||
// boost
|
// boost
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
#include <boost/make_shared.hpp>
|
#include <boost/make_shared.hpp>
|
||||||
|
@ -68,13 +68,13 @@ struct glyph_t;
|
||||||
|
|
||||||
typedef boost::shared_ptr<font_face> face_ptr;
|
typedef boost::shared_ptr<font_face> face_ptr;
|
||||||
|
|
||||||
class MAPNIK_DECL font_glyph : private mapnik::noncopyable
|
class MAPNIK_DECL font_glyph //: private mapnik::noncopyable FIXME
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
font_glyph(face_ptr face, unsigned index)
|
font_glyph(font_face const& face, unsigned index)
|
||||||
: face_(face), index_(index) {}
|
: face_(face), index_(index) {}
|
||||||
|
|
||||||
face_ptr get_face() const
|
font_face const& get_face() const
|
||||||
{
|
{
|
||||||
return face_;
|
return face_;
|
||||||
}
|
}
|
||||||
|
@ -84,13 +84,10 @@ public:
|
||||||
return index_;
|
return index_;
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
face_ptr face_;
|
font_face const& face_;
|
||||||
unsigned index_;
|
unsigned index_;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef boost::shared_ptr<font_glyph> glyph_ptr;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class MAPNIK_DECL font_face_set : private mapnik::noncopyable
|
class MAPNIK_DECL font_face_set : private mapnik::noncopyable
|
||||||
{
|
{
|
||||||
|
@ -98,13 +95,13 @@ public:
|
||||||
typedef std::vector<face_ptr> container_type;
|
typedef std::vector<face_ptr> container_type;
|
||||||
typedef container_type::size_type size_type;
|
typedef container_type::size_type size_type;
|
||||||
|
|
||||||
font_face_set(void)
|
font_face_set()
|
||||||
: faces_(),
|
: faces_(),
|
||||||
dimension_cache_() {}
|
dimension_cache_() {}
|
||||||
|
|
||||||
void add(face_ptr face);
|
void add(face_ptr face);
|
||||||
size_type size() const;
|
size_type size() const;
|
||||||
glyph_ptr get_glyph(unsigned c) const;
|
font_glyph get_glyph(unsigned c) const;
|
||||||
char_info character_dimensions(unsigned c);
|
char_info character_dimensions(unsigned c);
|
||||||
void get_string_info(string_info & info, UnicodeString const& ustr, char_properties *format);
|
void get_string_info(string_info & info, UnicodeString const& ustr, char_properties *format);
|
||||||
void set_pixel_sizes(unsigned size);
|
void set_pixel_sizes(unsigned size);
|
||||||
|
@ -163,8 +160,7 @@ public:
|
||||||
|
|
||||||
face_ptr get_face(std::string const& name)
|
face_ptr get_face(std::string const& name)
|
||||||
{
|
{
|
||||||
face_ptr_cache_type::iterator itr;
|
face_ptr_cache_type::iterator itr = face_ptr_cache_.find(name);
|
||||||
itr = face_ptr_cache_.find(name);
|
|
||||||
if (itr != face_ptr_cache_.end())
|
if (itr != face_ptr_cache_.end())
|
||||||
{
|
{
|
||||||
return itr->second;
|
return itr->second;
|
||||||
|
@ -213,7 +209,7 @@ public:
|
||||||
return face_set;
|
return face_set;
|
||||||
}
|
}
|
||||||
|
|
||||||
face_set_ptr get_face_set(std::string const& name, boost::optional<font_set> fset)
|
face_set_ptr get_face_set(std::string const& name, boost::optional<font_set> fset) // FIXME : bad style !!
|
||||||
{
|
{
|
||||||
if (fset && fset->size() > 0)
|
if (fset && fset->size() > 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -37,7 +37,7 @@ class MAPNIK_DECL font_set
|
||||||
public:
|
public:
|
||||||
font_set(std::string const& name);
|
font_set(std::string const& name);
|
||||||
font_set(font_set const& rhs);
|
font_set(font_set const& rhs);
|
||||||
font_set& operator=(font_set const& rhs);
|
font_set& operator=(font_set rhs);
|
||||||
unsigned size() const;
|
unsigned size() const;
|
||||||
void set_name(std::string const& name);
|
void set_name(std::string const& name);
|
||||||
std::string const& get_name() const;
|
std::string const& get_name() const;
|
||||||
|
|
|
@ -30,10 +30,13 @@
|
||||||
|
|
||||||
namespace mapnik {
|
namespace mapnik {
|
||||||
namespace formatting {
|
namespace formatting {
|
||||||
class MAPNIK_DECL text_node: public node {
|
class MAPNIK_DECL text_node: public node
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
text_node(expression_ptr text): node(), text_(text) {}
|
text_node(expression_ptr text)
|
||||||
text_node(std::string text): node(), text_(parse_expression(text)) {}
|
: node(), text_(text) {}
|
||||||
|
text_node(std::string const& text)
|
||||||
|
: node(), text_(parse_expression(text)) {}
|
||||||
void to_xml(boost::property_tree::ptree &xml) const;
|
void to_xml(boost::property_tree::ptree &xml) const;
|
||||||
static node_ptr from_xml(xml_node const& xml);
|
static node_ptr from_xml(xml_node const& xml);
|
||||||
virtual void apply(char_properties const& p, feature_impl const& feature, processed_text &output) const;
|
virtual void apply(char_properties const& p, feature_impl const& feature, processed_text &output) const;
|
||||||
|
|
|
@ -122,7 +122,10 @@
|
||||||
|
|
||||||
namespace mapnik { namespace filter { namespace detail {
|
namespace mapnik { namespace filter { namespace detail {
|
||||||
|
|
||||||
static const float blur_matrix[] = {0.1111f,0.1111f,0.1111f,0.1111f,0.1111f,0.1111f,0.1111f,0.1111f,0.1111f};
|
static const float blur_matrix[] = {1/16.0f,2/16.0f,1/16.0f,
|
||||||
|
2/16.0f,4/16.0f,2/16.0f,
|
||||||
|
1/16.0f,2/16.0f,1/16.0f};
|
||||||
|
|
||||||
static const float emboss_matrix[] = {-2,-1,0,-1,1,1,0,1,2};
|
static const float emboss_matrix[] = {-2,-1,0,-1,1,1,0,1,2};
|
||||||
static const float sharpen_matrix[] = {0,-1,0,-1,5,-1,0,-1,0 };
|
static const float sharpen_matrix[] = {0,-1,0,-1,5,-1,0,-1,0 };
|
||||||
static const float edge_detect_matrix[] = {0,1,0,1,-4,1,0,1,0 };
|
static const float edge_detect_matrix[] = {0,1,0,1,-4,1,0,1,0 };
|
||||||
|
|
|
@ -26,16 +26,18 @@
|
||||||
#include <mapnik/text_properties.hpp>
|
#include <mapnik/text_properties.hpp>
|
||||||
#include <mapnik/text_path.hpp>
|
#include <mapnik/text_path.hpp>
|
||||||
#include <mapnik/noncopyable.hpp>
|
#include <mapnik/noncopyable.hpp>
|
||||||
|
#include <mapnik/font_engine_freetype.hpp> //!!
|
||||||
|
#include <mapnik/skia/skia_font_manager.hpp>
|
||||||
// stl
|
// stl
|
||||||
#include <list>
|
#include <list>
|
||||||
|
// icu (temp)
|
||||||
|
#include <unicode/schriter.h>
|
||||||
|
|
||||||
namespace mapnik
|
namespace mapnik {
|
||||||
{
|
|
||||||
|
|
||||||
// fwd declares
|
// fwd declares
|
||||||
class freetype_engine;
|
//class freetype_engine;
|
||||||
template <typename T> class face_manager;
|
//template <typename T> class face_manager;
|
||||||
|
|
||||||
class MAPNIK_DECL processed_text : mapnik::noncopyable
|
class MAPNIK_DECL processed_text : mapnik::noncopyable
|
||||||
{
|
{
|
||||||
|
@ -48,7 +50,7 @@ public:
|
||||||
UnicodeString str;
|
UnicodeString str;
|
||||||
};
|
};
|
||||||
public:
|
public:
|
||||||
processed_text(face_manager<freetype_engine> & font_manager, double scale_factor);
|
processed_text(double scale_factor);
|
||||||
void push_back(char_properties const& properties, UnicodeString const& text);
|
void push_back(char_properties const& properties, UnicodeString const& text);
|
||||||
unsigned size() const { return expr_list_.size(); }
|
unsigned size() const { return expr_list_.size(); }
|
||||||
unsigned empty() const { return expr_list_.empty(); }
|
unsigned empty() const { return expr_list_.empty(); }
|
||||||
|
@ -56,10 +58,69 @@ public:
|
||||||
typedef std::list<processed_expression> expression_list;
|
typedef std::list<processed_expression> expression_list;
|
||||||
expression_list::const_iterator begin() const;
|
expression_list::const_iterator begin() const;
|
||||||
expression_list::const_iterator end() const;
|
expression_list::const_iterator end() const;
|
||||||
string_info const& get_string_info();
|
|
||||||
|
template <typename T>
|
||||||
|
string_info const& get_string_info(T & font_manager)
|
||||||
|
{
|
||||||
|
info_.clear(); //if this function is called twice invalid results are returned, so clear string_info first
|
||||||
|
expression_list::iterator itr = expr_list_.begin();
|
||||||
|
expression_list::iterator end = expr_list_.end();
|
||||||
|
for (; itr != end; ++itr)
|
||||||
|
{
|
||||||
|
char_properties const& p = itr->p;
|
||||||
|
face_set_ptr faces = font_manager.get_face_set(p.face_name, p.fontset);
|
||||||
|
if (faces->size() > 0)
|
||||||
|
{
|
||||||
|
faces->set_character_sizes(p.text_size * scale_factor_); // ???
|
||||||
|
faces->get_string_info(info_, itr->str, &(itr->p));
|
||||||
|
info_.add_text(itr->str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return info_;
|
||||||
|
}
|
||||||
|
#if defined(SKIA_RENDERER)
|
||||||
|
string_info const& get_string_info(skia_font_manager & manager)
|
||||||
|
{
|
||||||
|
info_.clear(); //if this function is called twice invalid results are returned, so clear string_info first
|
||||||
|
expression_list::iterator itr = expr_list_.begin();
|
||||||
|
expression_list::iterator end = expr_list_.end();
|
||||||
|
for (; itr != end; ++itr)
|
||||||
|
{
|
||||||
|
char_properties const& p = itr->p;
|
||||||
|
if (p.fontset)
|
||||||
|
{
|
||||||
|
for (auto face_name : p.fontset->get_face_names())
|
||||||
|
{
|
||||||
|
face_name.erase(remove_if(face_name.begin(), face_name.end(), ::isspace), face_name.end());
|
||||||
|
size_t pos = face_name.rfind("-");
|
||||||
|
if (pos != std::string::npos)
|
||||||
|
{
|
||||||
|
face_name = face_name.substr(0,pos);
|
||||||
|
}
|
||||||
|
std::cerr << face_name << std::endl;
|
||||||
|
manager.test(face_name, itr->str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
StringCharacterIterator iter(itr->str);
|
||||||
|
for (iter.setToStart(); iter.hasNext();)
|
||||||
|
{
|
||||||
|
UChar ch = iter.nextPostInc();
|
||||||
|
char_info char_dim(ch, p.text_size * scale_factor_, p.text_size * scale_factor_, 0, p.text_size * scale_factor_);
|
||||||
|
char_dim.format = &(itr->p);
|
||||||
|
char_dim.avg_height = p.text_size * scale_factor_;
|
||||||
|
info_.add_info(char_dim);
|
||||||
|
}
|
||||||
|
// char sizes ---> p.text_size * scale_factor_
|
||||||
|
info_.add_text(itr->str);
|
||||||
|
}
|
||||||
|
|
||||||
|
return info_;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
expression_list expr_list_;
|
expression_list expr_list_;
|
||||||
face_manager<freetype_engine> &font_manager_;
|
|
||||||
double scale_factor_;
|
double scale_factor_;
|
||||||
string_info info_;
|
string_info info_;
|
||||||
};
|
};
|
||||||
|
|
52
include/mapnik/skia/skia_font_manager.hpp
Normal file
52
include/mapnik/skia/skia_font_manager.hpp
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* This file is part of Mapnik (c++ mapping toolkit)
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 Artem Pavlenko
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(SKIA_RENDERER)
|
||||||
|
|
||||||
|
#ifndef MAPNIK_SKIA_FONT_MANAGER_HPP
|
||||||
|
#define MAPNIK_SKIA_FONT_MANAGER_HPP
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <mapnik/unicode.hpp>
|
||||||
|
|
||||||
|
namespace mapnik
|
||||||
|
{
|
||||||
|
|
||||||
|
class skia_typeface_cache;
|
||||||
|
|
||||||
|
class skia_font_manager
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
skia_font_manager(skia_typeface_cache & cache)
|
||||||
|
: cache_(cache) {}
|
||||||
|
|
||||||
|
void test(std::string const&, UnicodeString & ustr);
|
||||||
|
private:
|
||||||
|
skia_typeface_cache & cache_;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // MAPNIK_SKIA_FONT_MANAGER_HPP
|
||||||
|
#endif // #if defined(SKIA_RENDERER)
|
114
include/mapnik/skia/skia_renderer.hpp
Normal file
114
include/mapnik/skia/skia_renderer.hpp
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* This file is part of Mapnik (c++ mapping toolkit)
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 Artem Pavlenko
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#if defined(SKIA_RENDERER)
|
||||||
|
|
||||||
|
#ifndef MAPNIK_SKIA_RENDERER_HPP
|
||||||
|
#define MAPNIK_SKIA_RENDERER_HPP
|
||||||
|
|
||||||
|
// mapnik
|
||||||
|
#include <mapnik/config.hpp>
|
||||||
|
#include <mapnik/debug.hpp>
|
||||||
|
#include <mapnik/layer.hpp>
|
||||||
|
#include <mapnik/map.hpp>
|
||||||
|
#include <mapnik/ctrans.hpp>
|
||||||
|
#include <mapnik/rule.hpp>
|
||||||
|
#include <mapnik/feature_style_processor.hpp>
|
||||||
|
#include <mapnik/skia/skia_font_manager.hpp>
|
||||||
|
#include <mapnik/skia/skia_typeface_cache.hpp>
|
||||||
|
#include <mapnik/label_collision_detector.hpp>
|
||||||
|
|
||||||
|
//
|
||||||
|
#include <mapnik/font_engine_freetype.hpp>
|
||||||
|
|
||||||
|
// skia fwd decl
|
||||||
|
class SkCanvas;
|
||||||
|
|
||||||
|
namespace mapnik
|
||||||
|
{
|
||||||
|
|
||||||
|
class MAPNIK_DECL skia_renderer : public feature_style_processor<skia_renderer>,
|
||||||
|
private mapnik::noncopyable
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef skia_renderer processor_impl_type;
|
||||||
|
|
||||||
|
skia_renderer(Map const& map, SkCanvas & canvas, double scale_factor = 1.0);
|
||||||
|
~skia_renderer();
|
||||||
|
|
||||||
|
void start_map_processing(Map const& map);
|
||||||
|
void end_map_processing(Map const& map);
|
||||||
|
void start_layer_processing(layer const& lay, box2d<double> const& query_extent);
|
||||||
|
void end_layer_processing(layer const& lay);
|
||||||
|
void start_style_processing(feature_type_style const& st);
|
||||||
|
void end_style_processing(feature_type_style const& st);
|
||||||
|
void process(line_symbolizer const& sym,
|
||||||
|
mapnik::feature_impl & feature,
|
||||||
|
proj_transform const& prj_trans);
|
||||||
|
|
||||||
|
void process(polygon_symbolizer const& sym,
|
||||||
|
mapnik::feature_impl & feature,
|
||||||
|
proj_transform const& prj_trans);
|
||||||
|
|
||||||
|
void process(text_symbolizer const& sym,
|
||||||
|
mapnik::feature_impl & feature,
|
||||||
|
proj_transform const& prj_trans);
|
||||||
|
|
||||||
|
void painted(bool painted) {};
|
||||||
|
|
||||||
|
inline double scale_factor() const
|
||||||
|
{
|
||||||
|
return scale_factor_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool process(rule::symbolizers const& ,
|
||||||
|
mapnik::feature_impl & ,
|
||||||
|
proj_transform const& )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline eAttributeCollectionPolicy attribute_collection_policy() const
|
||||||
|
{
|
||||||
|
return DEFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
SkCanvas & canvas_;
|
||||||
|
unsigned width_;
|
||||||
|
unsigned height_;
|
||||||
|
CoordTransform t_;
|
||||||
|
double scale_factor_;
|
||||||
|
box2d<double> query_extent_;
|
||||||
|
//skia_font_manager font_manager_;
|
||||||
|
skia_typeface_cache typeface_cache_;
|
||||||
|
freetype_engine font_engine_;
|
||||||
|
face_manager<freetype_engine> font_manager_;
|
||||||
|
boost::shared_ptr<label_collision_detector4> detector_;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif //MAPNIK_SKIA_RENDERER_HPP
|
||||||
|
#endif // SKIA_RENDERER
|
59
include/mapnik/skia/skia_typeface_cache.hpp
Normal file
59
include/mapnik/skia/skia_typeface_cache.hpp
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* This file is part of Mapnik (c++ mapping toolkit)
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 Artem Pavlenko
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(SKIA_RENDERER)
|
||||||
|
|
||||||
|
#ifndef MAPNIK_SKIA_TYPEFACE_CACHE_HPP
|
||||||
|
#define MAPNIK_SKIA_TYPEFACE_CACHE_HPP
|
||||||
|
|
||||||
|
#ifdef MAPNIK_THREADSAFE
|
||||||
|
#include <boost/thread/mutex.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
class SkTypeface;
|
||||||
|
|
||||||
|
namespace mapnik
|
||||||
|
{
|
||||||
|
|
||||||
|
class skia_typeface_cache
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef std::map<std::string, SkTypeface*> cache_type;
|
||||||
|
skia_typeface_cache();
|
||||||
|
~skia_typeface_cache();
|
||||||
|
static bool register_font(std::string const& file_name);
|
||||||
|
static bool register_fonts(std::string const& dir, bool recurse = false);
|
||||||
|
SkTypeface * create(std::string const& family_name);
|
||||||
|
private:
|
||||||
|
#ifdef MAPNIK_THREADSAFE
|
||||||
|
static boost::mutex mutex_;
|
||||||
|
#endif
|
||||||
|
static cache_type typefaces_;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // MAPNIK_SKIA_TYPEFACE_CACHE_HPP
|
||||||
|
#endif // #if defined(SKIA_RENDERER)
|
|
@ -19,6 +19,7 @@
|
||||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
#ifndef TEXT_PROPERTIES_HPP
|
#ifndef TEXT_PROPERTIES_HPP
|
||||||
#define TEXT_PROPERTIES_HPP
|
#define TEXT_PROPERTIES_HPP
|
||||||
|
|
||||||
|
@ -57,9 +58,9 @@ typedef std::map<std::string, font_set> fontset_map;
|
||||||
struct MAPNIK_DECL char_properties
|
struct MAPNIK_DECL char_properties
|
||||||
{
|
{
|
||||||
char_properties();
|
char_properties();
|
||||||
/** Construct object from XML. */
|
// Construct object from XML.
|
||||||
void from_xml(xml_node const &sym, fontset_map const & fontsets);
|
void from_xml(xml_node const &sym, fontset_map const & fontsets);
|
||||||
/** Write object to XML ptree. */
|
// Write object to XML ptree.
|
||||||
void to_xml(boost::property_tree::ptree &node, bool explicit_defaults, char_properties const& dfl=char_properties()) const;
|
void to_xml(boost::property_tree::ptree &node, bool explicit_defaults, char_properties const& dfl=char_properties()) const;
|
||||||
std::string face_name;
|
std::string face_name;
|
||||||
boost::optional<font_set> fontset;
|
boost::optional<font_set> fontset;
|
||||||
|
@ -124,27 +125,27 @@ typedef std::pair<double, double> position;
|
||||||
class processed_text;
|
class processed_text;
|
||||||
|
|
||||||
|
|
||||||
/** Contains all text symbolizer properties which are not directly related to text formatting. */
|
// Contains all text symbolizer properties which are not directly related to text formatting.
|
||||||
struct MAPNIK_DECL text_symbolizer_properties
|
struct MAPNIK_DECL text_symbolizer_properties
|
||||||
{
|
{
|
||||||
text_symbolizer_properties();
|
text_symbolizer_properties();
|
||||||
/** Load all values from XML ptree. */
|
// Load all values from XML ptree.
|
||||||
void from_xml(xml_node const &sym, fontset_map const & fontsets);
|
void from_xml(xml_node const &sym, fontset_map const & fontsets);
|
||||||
/** Save all values to XML ptree (but does not create a new parent node!). */
|
// Save all values to XML ptree (but does not create a new parent node!).
|
||||||
void to_xml(boost::property_tree::ptree &node, bool explicit_defaults, text_symbolizer_properties const &dfl=text_symbolizer_properties()) const;
|
void to_xml(boost::property_tree::ptree &node, bool explicit_defaults,
|
||||||
|
text_symbolizer_properties const &dfl=text_symbolizer_properties()) const;
|
||||||
|
|
||||||
/** Takes a feature and produces formated text as output.
|
// Takes a feature and produces formated text as output.
|
||||||
* The output object has to be created by the caller and passed in for thread safety.
|
// The output object has to be created by the caller and passed in for thread safety.
|
||||||
*/
|
|
||||||
void process(processed_text &output, feature_impl const& feature) const;
|
void process(processed_text &output, feature_impl const& feature) const;
|
||||||
/** Automatically create processing instructions for a single expression. */
|
// Automatically create processing instructions for a single expression.
|
||||||
void set_old_style_expression(expression_ptr expr);
|
void set_old_style_expression(expression_ptr expr);
|
||||||
/** Sets new format tree. */
|
// Sets new format tree.
|
||||||
void set_format_tree(formatting::node_ptr tree);
|
void set_format_tree(formatting::node_ptr tree);
|
||||||
/** Get format tree. */
|
// Get format tree.
|
||||||
formatting::node_ptr format_tree() const;
|
formatting::node_ptr format_tree() const;
|
||||||
/** Get a list of all expressions used in any placement.
|
// Get a list of all expressions used in any placement.
|
||||||
* This function is used to collect attributes. */
|
// This function is used to collect attributes.
|
||||||
void add_expressions(expression_set &output) const;
|
void add_expressions(expression_set &output) const;
|
||||||
|
|
||||||
//Per symbolizer options
|
//Per symbolizer options
|
||||||
|
@ -154,26 +155,26 @@ struct MAPNIK_DECL text_symbolizer_properties
|
||||||
horizontal_alignment_e halign;
|
horizontal_alignment_e halign;
|
||||||
justify_alignment_e jalign;
|
justify_alignment_e jalign;
|
||||||
vertical_alignment_e valign;
|
vertical_alignment_e valign;
|
||||||
/** distance between repeated labels on a single geometry */
|
// distance between repeated labels on a single geometry
|
||||||
double label_spacing;
|
double label_spacing;
|
||||||
/** distance the label can be moved on the line to fit, if 0 the default is used */
|
// distance the label can be moved on the line to fit, if 0 the default is used
|
||||||
unsigned label_position_tolerance;
|
unsigned label_position_tolerance;
|
||||||
bool avoid_edges;
|
bool avoid_edges;
|
||||||
double minimum_distance;
|
double minimum_distance;
|
||||||
double minimum_padding;
|
double minimum_padding;
|
||||||
double minimum_path_length;
|
double minimum_path_length;
|
||||||
double max_char_angle_delta;
|
double max_char_angle_delta;
|
||||||
/** Always try render an odd amount of labels */
|
// Always try render an odd amount of labels
|
||||||
bool force_odd_labels;
|
bool force_odd_labels;
|
||||||
bool allow_overlap;
|
bool allow_overlap;
|
||||||
/** Only consider geometry with largest bbox (polygons) */
|
// Only consider geometry with largest bbox (polygons)
|
||||||
bool largest_bbox_only;
|
bool largest_bbox_only;
|
||||||
double text_ratio;
|
double text_ratio;
|
||||||
double wrap_width;
|
double wrap_width;
|
||||||
/** Default values for char_properties. */
|
// Default values for char_properties.
|
||||||
char_properties format;
|
char_properties format;
|
||||||
private:
|
private:
|
||||||
/** A tree of formatting::nodes which contain text and formatting information. */
|
// A tree of formatting::nodes which contain text and formatting information.
|
||||||
formatting::node_ptr tree_;
|
formatting::node_ptr tree_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
12
src/build.py
12
src/build.py
|
@ -261,6 +261,18 @@ if env['HAS_CAIRO']:
|
||||||
source.insert(0,'cairo_renderer.cpp')
|
source.insert(0,'cairo_renderer.cpp')
|
||||||
source.insert(0,'cairo_context.cpp')
|
source.insert(0,'cairo_context.cpp')
|
||||||
|
|
||||||
|
if '-DSKIA_RENDERER' in env['CPPDEFINES']:
|
||||||
|
lib_env.AppendUnique(LIBPATH=env['SKIA_LIBS'])
|
||||||
|
lib_env.Append(LIBS=['skia_core','skia_ports','skia_utils','skia_images',
|
||||||
|
'skia_effects','skia_sfnt','skia_opts','skia_opts_ssse3','skia_skgpu'])
|
||||||
|
lib_env.Append(FRAMEWORKS = ['Cocoa'])
|
||||||
|
lib_env.Append(CPPDEFINES = '-DSKIA_RENDERER')
|
||||||
|
libmapnik_defines.append('-DSKIA_RENDERER')
|
||||||
|
source.insert(0,'skia/skia_renderer.cpp')
|
||||||
|
source.insert(0,'skia/skia_typeface_cache.cpp')
|
||||||
|
source.insert(0,'skia/skia_font_manager.cpp')
|
||||||
|
|
||||||
|
|
||||||
for cpp in enabled_imaging_libraries:
|
for cpp in enabled_imaging_libraries:
|
||||||
source.append(cpp)
|
source.append(cpp)
|
||||||
|
|
||||||
|
|
|
@ -29,14 +29,34 @@
|
||||||
#include <cairo-ft.h>
|
#include <cairo-ft.h>
|
||||||
|
|
||||||
#include <valarray>
|
#include <valarray>
|
||||||
|
|
||||||
namespace mapnik {
|
namespace mapnik {
|
||||||
|
|
||||||
cairo_face::cairo_face(boost::shared_ptr<freetype_engine> const& engine, face_ptr const& face)
|
cairo_face_manager::cairo_face_manager(boost::shared_ptr<freetype_engine> engine)
|
||||||
: face_(face)
|
: font_engine_(engine) {}
|
||||||
|
|
||||||
|
cairo_face_ptr cairo_face_manager::get_face(font_face const& face)
|
||||||
|
{
|
||||||
|
cairo_face_cache::iterator itr = cache_.find((FT_FaceRec_ *const)face.get_face());
|
||||||
|
cairo_face_ptr entry;
|
||||||
|
|
||||||
|
if (itr != cache_.end())
|
||||||
|
{
|
||||||
|
entry = itr->second;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
entry = boost::make_shared<cairo_face>(font_engine_, face.get_face());
|
||||||
|
cache_.insert(std::make_pair((FT_FaceRec_ *const)face.get_face(), entry));
|
||||||
|
}
|
||||||
|
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
cairo_face::cairo_face(boost::shared_ptr<freetype_engine> const& engine, FT_Face face)
|
||||||
{
|
{
|
||||||
static cairo_user_data_key_t key;
|
static cairo_user_data_key_t key;
|
||||||
c_face_ = cairo_ft_font_face_create_for_ft_face(face->get_face(), FT_LOAD_NO_HINTING);
|
c_face_ = cairo_ft_font_face_create_for_ft_face(face, FT_LOAD_NO_HINTING);
|
||||||
cairo_font_face_set_user_data(c_face_, &key, new handle(engine, face), destroy);
|
cairo_font_face_set_user_data(c_face_, &key, new handle(engine), destroy);
|
||||||
}
|
}
|
||||||
|
|
||||||
cairo_face::~cairo_face()
|
cairo_face::~cairo_face()
|
||||||
|
@ -363,7 +383,7 @@ void cairo_context::add_image(agg::trans_affine const& tr, image_data_32 & data,
|
||||||
check_object_status_and_throw_exception(*this);
|
check_object_status_and_throw_exception(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cairo_context::set_font_face(cairo_face_manager & manager, face_ptr face)
|
void cairo_context::set_font_face(cairo_face_manager & manager, font_face const& face)
|
||||||
{
|
{
|
||||||
cairo_set_font_face(cairo_.get(), manager.get_face(face)->face());
|
cairo_set_font_face(cairo_.get(), manager.get_face(face)->face());
|
||||||
}
|
}
|
||||||
|
@ -447,25 +467,21 @@ void cairo_context::add_text(text_path const& path,
|
||||||
double text_size = c->format->text_size * scale_factor;
|
double text_size = c->format->text_size * scale_factor;
|
||||||
faces->set_character_sizes(text_size);
|
faces->set_character_sizes(text_size);
|
||||||
|
|
||||||
glyph_ptr glyph = faces->get_glyph(c->c);
|
font_glyph glyph = faces->get_glyph(c->c);
|
||||||
|
cairo_matrix_t matrix;
|
||||||
if (glyph)
|
matrix.xx = text_size * std::cos(angle);
|
||||||
{
|
matrix.xy = text_size * std::sin(angle);
|
||||||
cairo_matrix_t matrix;
|
matrix.yx = text_size * -std::sin(angle);
|
||||||
matrix.xx = text_size * std::cos(angle);
|
matrix.yy = text_size * std::cos(angle);
|
||||||
matrix.xy = text_size * std::sin(angle);
|
matrix.x0 = 0;
|
||||||
matrix.yx = text_size * -std::sin(angle);
|
matrix.y0 = 0;
|
||||||
matrix.yy = text_size * std::cos(angle);
|
set_font_matrix(matrix);
|
||||||
matrix.x0 = 0;
|
set_font_face(manager, glyph.get_face());
|
||||||
matrix.y0 = 0;
|
glyph_path(glyph.get_index(), sx + x, sy - y);
|
||||||
set_font_matrix(matrix);
|
set_line_width(2.0 * c->format->halo_radius * scale_factor);
|
||||||
set_font_face(manager, glyph->get_face());
|
set_line_join(ROUND_JOIN);
|
||||||
glyph_path(glyph->get_index(), sx + x, sy - y);
|
set_color(c->format->halo_fill);
|
||||||
set_line_width(2.0 * c->format->halo_radius * scale_factor);
|
stroke();
|
||||||
set_line_join(ROUND_JOIN);
|
|
||||||
set_color(c->format->halo_fill);
|
|
||||||
stroke();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
path.rewind();
|
path.rewind();
|
||||||
|
@ -481,22 +497,19 @@ void cairo_context::add_text(text_path const& path,
|
||||||
double text_size = c->format->text_size * scale_factor;
|
double text_size = c->format->text_size * scale_factor;
|
||||||
faces->set_character_sizes(text_size);
|
faces->set_character_sizes(text_size);
|
||||||
|
|
||||||
glyph_ptr glyph = faces->get_glyph(c->c);
|
font_glyph glyph = faces->get_glyph(c->c);
|
||||||
|
|
||||||
if (glyph)
|
cairo_matrix_t matrix;
|
||||||
{
|
matrix.xx = text_size * std::cos(angle);
|
||||||
cairo_matrix_t matrix;
|
matrix.xy = text_size * std::sin(angle);
|
||||||
matrix.xx = text_size * std::cos(angle);
|
matrix.yx = text_size * -std::sin(angle);
|
||||||
matrix.xy = text_size * std::sin(angle);
|
matrix.yy = text_size * std::cos(angle);
|
||||||
matrix.yx = text_size * -std::sin(angle);
|
matrix.x0 = 0;
|
||||||
matrix.yy = text_size * std::cos(angle);
|
matrix.y0 = 0;
|
||||||
matrix.x0 = 0;
|
set_font_matrix(matrix);
|
||||||
matrix.y0 = 0;
|
set_font_face(manager, glyph.get_face());
|
||||||
set_font_matrix(matrix);
|
set_color(c->format->fill);
|
||||||
set_font_face(manager, glyph->get_face());
|
show_glyph(glyph.get_index(), sx + x, sy - y);
|
||||||
set_color(c->format->fill);
|
|
||||||
show_glyph(glyph->get_index(), sx + x, sy - y);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,31 +95,6 @@ struct cairo_save_restore
|
||||||
cairo_context & context_;
|
cairo_context & context_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
cairo_face_manager::cairo_face_manager(boost::shared_ptr<freetype_engine> engine)
|
|
||||||
: font_engine_(engine)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
cairo_face_ptr cairo_face_manager::get_face(face_ptr face)
|
|
||||||
{
|
|
||||||
cairo_face_cache::iterator itr = cache_.find(face);
|
|
||||||
cairo_face_ptr entry;
|
|
||||||
|
|
||||||
if (itr != cache_.end())
|
|
||||||
{
|
|
||||||
entry = itr->second;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
entry = boost::make_shared<cairo_face>(font_engine_, face);
|
|
||||||
cache_.insert(std::make_pair(face, entry));
|
|
||||||
}
|
|
||||||
|
|
||||||
return entry;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
cairo_renderer_base::cairo_renderer_base(Map const& m,
|
cairo_renderer_base::cairo_renderer_base(Map const& m,
|
||||||
cairo_ptr const& cairo,
|
cairo_ptr const& cairo,
|
||||||
double scale_factor,
|
double scale_factor,
|
||||||
|
|
|
@ -39,6 +39,10 @@
|
||||||
#include <mapnik/svg/output/svg_renderer.hpp>
|
#include <mapnik/svg/output/svg_renderer.hpp>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(SKIA_RENDERER)
|
||||||
|
#include <mapnik/skia/skia_renderer.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace mapnik
|
namespace mapnik
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -47,6 +51,10 @@ template class feature_style_processor<cairo_renderer<cairo_ptr> >;
|
||||||
template class feature_style_processor<cairo_renderer<cairo_surface_ptr> >;
|
template class feature_style_processor<cairo_renderer<cairo_surface_ptr> >;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(SKIA_RENDERER)
|
||||||
|
template class feature_style_processor<skia_renderer>;
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(SVG_RENDERER)
|
#if defined(SVG_RENDERER)
|
||||||
template class feature_style_processor<svg_renderer<std::ostream_iterator<char> > >;
|
template class feature_style_processor<svg_renderer<std::ostream_iterator<char> > >;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -104,7 +104,8 @@ bool freetype_engine::register_font(std::string const& file_name)
|
||||||
// some font files have multiple fonts in a file
|
// some font files have multiple fonts in a file
|
||||||
// the count is in the 'root' face library[0]
|
// the count is in the 'root' face library[0]
|
||||||
// see the FT_FaceRec in freetype.h
|
// see the FT_FaceRec in freetype.h
|
||||||
for ( int i = 0; face == 0 || i < num_faces; i++ ) {
|
for ( int i = 0; face == 0 || i < num_faces; i++ )
|
||||||
|
{
|
||||||
// if face is null then this is the first face
|
// if face is null then this is the first face
|
||||||
error = FT_New_Face (library,file_name.c_str(),i,&face);
|
error = FT_New_Face (library,file_name.c_str(),i,&face);
|
||||||
if (error)
|
if (error)
|
||||||
|
@ -221,8 +222,7 @@ std::map<std::string,std::pair<int,std::string> > const& freetype_engine::get_ma
|
||||||
|
|
||||||
face_ptr freetype_engine::create_face(std::string const& family_name)
|
face_ptr freetype_engine::create_face(std::string const& family_name)
|
||||||
{
|
{
|
||||||
std::map<std::string, std::pair<int,std::string> >::const_iterator itr;
|
std::map<std::string, std::pair<int,std::string> >::const_iterator itr = name2file_.find(family_name);
|
||||||
itr = name2file_.find(family_name);
|
|
||||||
if (itr != name2file_.end())
|
if (itr != name2file_.end())
|
||||||
{
|
{
|
||||||
FT_Face face;
|
FT_Face face;
|
||||||
|
@ -289,16 +289,21 @@ font_face_set::size_type font_face_set::size() const
|
||||||
return faces_.size();
|
return faces_.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
glyph_ptr font_face_set::get_glyph(unsigned c) const
|
font_glyph font_face_set::get_glyph(unsigned c) const
|
||||||
{
|
{
|
||||||
|
FT_UInt g = 0;
|
||||||
|
font_face * cur_face = 0;
|
||||||
BOOST_FOREACH ( face_ptr const& face, faces_)
|
BOOST_FOREACH ( face_ptr const& face, faces_)
|
||||||
{
|
{
|
||||||
FT_UInt g = face->get_char(c);
|
if (g = face->get_char(c))
|
||||||
if (g) return boost::make_shared<font_glyph>(face, g);
|
{
|
||||||
|
cur_face = face.get();
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Final fallback to empty square if nothing better in any font
|
// Final fallback to empty square if nothing better in any font
|
||||||
return boost::make_shared<font_glyph>(*faces_.begin(), 0);
|
return font_glyph(g > 0 ? *cur_face: *(*faces_.begin()), g);
|
||||||
}
|
}
|
||||||
|
|
||||||
char_info font_face_set::character_dimensions(unsigned int c)
|
char_info font_face_set::character_dimensions(unsigned int c)
|
||||||
|
@ -321,8 +326,8 @@ char_info font_face_set::character_dimensions(unsigned int c)
|
||||||
FT_BBox glyph_bbox;
|
FT_BBox glyph_bbox;
|
||||||
FT_Glyph image;
|
FT_Glyph image;
|
||||||
|
|
||||||
glyph_ptr glyph = get_glyph(c);
|
font_glyph glyph = get_glyph(c);
|
||||||
FT_Face face = glyph->get_face()->get_face();
|
FT_Face face = glyph.get_face().get_face();
|
||||||
|
|
||||||
matrix.xx = (FT_Fixed)( 1 * 0x10000L );
|
matrix.xx = (FT_Fixed)( 1 * 0x10000L );
|
||||||
matrix.xy = (FT_Fixed)( 0 * 0x10000L );
|
matrix.xy = (FT_Fixed)( 0 * 0x10000L );
|
||||||
|
@ -331,7 +336,7 @@ char_info font_face_set::character_dimensions(unsigned int c)
|
||||||
|
|
||||||
FT_Set_Transform(face, &matrix, &pen);
|
FT_Set_Transform(face, &matrix, &pen);
|
||||||
|
|
||||||
error = FT_Load_Glyph (face, glyph->get_index(), FT_LOAD_NO_HINTING);
|
error = FT_Load_Glyph (face, glyph.get_index(), FT_LOAD_NO_HINTING);
|
||||||
if ( error )
|
if ( error )
|
||||||
return char_info();
|
return char_info();
|
||||||
|
|
||||||
|
@ -374,9 +379,11 @@ void font_face_set::get_string_info(string_info & info, UnicodeString const& ust
|
||||||
|
|
||||||
shaped.releaseBuffer(length);
|
shaped.releaseBuffer(length);
|
||||||
|
|
||||||
if (U_SUCCESS(err)) {
|
if (U_SUCCESS(err))
|
||||||
|
{
|
||||||
StringCharacterIterator iter(shaped);
|
StringCharacterIterator iter(shaped);
|
||||||
for (iter.setToStart(); iter.hasNext();) {
|
for (iter.setToStart(); iter.hasNext();)
|
||||||
|
{
|
||||||
UChar ch = iter.nextPostInc();
|
UChar ch = iter.nextPostInc();
|
||||||
char_info char_dim = character_dimensions(ch);
|
char_info char_dim = character_dimensions(ch);
|
||||||
char_dim.format = format;
|
char_dim.format = format;
|
||||||
|
@ -564,8 +571,8 @@ box2d<double> text_renderer<T>::prepare_glyphs(text_path const& path)
|
||||||
face_set_ptr faces = font_manager_.get_face_set(c->format->face_name, c->format->fontset);
|
face_set_ptr faces = font_manager_.get_face_set(c->format->face_name, c->format->fontset);
|
||||||
faces->set_character_sizes(c->format->text_size*scale_factor_);
|
faces->set_character_sizes(c->format->text_size*scale_factor_);
|
||||||
|
|
||||||
glyph_ptr glyph = faces->get_glyph(unsigned(c->c));
|
font_glyph glyph = faces->get_glyph(unsigned(c->c));
|
||||||
FT_Face face = glyph->get_face()->get_face();
|
FT_Face face = glyph.get_face().get_face();
|
||||||
|
|
||||||
matrix.xx = (FT_Fixed)( std::cos( angle ) * 0x10000L );
|
matrix.xx = (FT_Fixed)( std::cos( angle ) * 0x10000L );
|
||||||
matrix.xy = (FT_Fixed)(-std::sin( angle ) * 0x10000L );
|
matrix.xy = (FT_Fixed)(-std::sin( angle ) * 0x10000L );
|
||||||
|
@ -574,7 +581,7 @@ box2d<double> text_renderer<T>::prepare_glyphs(text_path const& path)
|
||||||
|
|
||||||
FT_Set_Transform(face, &matrix, &pen);
|
FT_Set_Transform(face, &matrix, &pen);
|
||||||
|
|
||||||
error = FT_Load_Glyph(face, glyph->get_index(), FT_LOAD_NO_HINTING);
|
error = FT_Load_Glyph(face, glyph.get_index(), FT_LOAD_NO_HINTING);
|
||||||
if ( error )
|
if ( error )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
|
@ -36,13 +36,10 @@ font_set::font_set(font_set const& rhs)
|
||||||
: name_(rhs.name_),
|
: name_(rhs.name_),
|
||||||
face_names_(rhs.face_names_) {}
|
face_names_(rhs.face_names_) {}
|
||||||
|
|
||||||
font_set& font_set::operator=(font_set const& other)
|
font_set& font_set::operator=(font_set other)
|
||||||
{
|
{
|
||||||
if (this == &other)
|
std::swap(name_,other.name_);
|
||||||
return *this;
|
std::swap(face_names_,other.face_names_);
|
||||||
name_ = other.name_;
|
|
||||||
face_names_ = other.face_names_;
|
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1714,7 +1714,7 @@ void map_parser::find_unused_nodes_recursive(xml_node const& node, std::string &
|
||||||
xml_node::attribute_map const& attr = node.get_attributes();
|
xml_node::attribute_map const& attr = node.get_attributes();
|
||||||
xml_node::attribute_map::const_iterator aitr = attr.begin();
|
xml_node::attribute_map::const_iterator aitr = attr.begin();
|
||||||
xml_node::attribute_map::const_iterator aend = attr.end();
|
xml_node::attribute_map::const_iterator aend = attr.end();
|
||||||
for (;aitr!=aend; aitr++)
|
for (;aitr!=aend; ++aitr)
|
||||||
{
|
{
|
||||||
if (!aitr->second.processed)
|
if (!aitr->second.processed)
|
||||||
{
|
{
|
||||||
|
@ -1725,7 +1725,7 @@ void map_parser::find_unused_nodes_recursive(xml_node const& node, std::string &
|
||||||
}
|
}
|
||||||
xml_node::const_iterator itr = node.begin();
|
xml_node::const_iterator itr = node.begin();
|
||||||
xml_node::const_iterator end = node.end();
|
xml_node::const_iterator end = node.end();
|
||||||
for (; itr!=end; itr++)
|
for (; itr!=end; ++itr)
|
||||||
{
|
{
|
||||||
find_unused_nodes_recursive(*itr, error_message);
|
find_unused_nodes_recursive(*itr, error_message);
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,11 +42,8 @@ processed_text::expression_list::const_iterator processed_text::end() const
|
||||||
return expr_list_.end();
|
return expr_list_.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
processed_text::processed_text(face_manager<freetype_engine> & font_manager, double scale_factor)
|
processed_text::processed_text( double scale_factor)
|
||||||
: font_manager_(font_manager), scale_factor_(scale_factor)
|
: scale_factor_(scale_factor) {}
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void processed_text::clear()
|
void processed_text::clear()
|
||||||
{
|
{
|
||||||
|
@ -54,50 +51,4 @@ void processed_text::clear()
|
||||||
expr_list_.clear();
|
expr_list_.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
string_info const& processed_text::get_string_info()
|
|
||||||
{
|
|
||||||
info_.clear(); //if this function is called twice invalid results are returned, so clear string_info first
|
|
||||||
expression_list::iterator itr = expr_list_.begin();
|
|
||||||
expression_list::iterator end = expr_list_.end();
|
|
||||||
for (; itr != end; ++itr)
|
|
||||||
{
|
|
||||||
char_properties const &p = itr->p;
|
|
||||||
face_set_ptr faces = font_manager_.get_face_set(p.face_name, p.fontset);
|
|
||||||
if (faces->size() == 0)
|
|
||||||
{
|
|
||||||
if (p.fontset && !p.fontset->get_name().empty())
|
|
||||||
{
|
|
||||||
if (p.fontset->size())
|
|
||||||
{
|
|
||||||
if (!p.face_name.empty())
|
|
||||||
{
|
|
||||||
throw config_error("Unable to find specified font face '" + p.face_name + "' in font set: '" + p.fontset->get_name() + "'");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw config_error("No valid font face could be loaded for font set: '" + p.fontset->get_name() + "'");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw config_error("Font set '" + p.fontset->get_name() + "' does not contain any Font face-name entries");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (!p.face_name.empty())
|
|
||||||
{
|
|
||||||
throw config_error("Unable to find specified font face '" + p.face_name + "'");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw config_error("Both font set and face name are empty!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
faces->set_character_sizes(p.text_size * scale_factor_);
|
|
||||||
faces->get_string_info(info_, itr->str, &(itr->p));
|
|
||||||
info_.add_text(itr->str);
|
|
||||||
}
|
|
||||||
return info_;
|
|
||||||
}
|
|
||||||
|
|
||||||
} //ns mapnik
|
} //ns mapnik
|
||||||
|
|
78
src/skia/skia_font_manager.cpp
Normal file
78
src/skia/skia_font_manager.cpp
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* This file is part of Mapnik (c++ mapping toolkit)
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 Artem Pavlenko
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <mapnik/skia/skia_font_manager.hpp>
|
||||||
|
#include <mapnik/skia/skia_typeface_cache.hpp>
|
||||||
|
#include <mapnik/unicode.hpp>
|
||||||
|
|
||||||
|
#include <SkTypeface.h>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace mapnik {
|
||||||
|
|
||||||
|
void skia_font_manager::test(std::string const& family_name, UnicodeString & ustr)
|
||||||
|
{
|
||||||
|
SkTypeface * typeface = cache_.create(family_name);
|
||||||
|
//SkTypeface * typeface = SkTypeface::CreateFromName(family_name.c_str(),SkTypeface::kNormal);
|
||||||
|
if (typeface)
|
||||||
|
{
|
||||||
|
std::cerr << "ustr.length()=" << ustr.length() << std::endl;
|
||||||
|
std::vector<uint16_t> glyph_ids;
|
||||||
|
glyph_ids.resize(ustr.length());
|
||||||
|
std::cerr << (char*)ustr.getTerminatedBuffer() << std::endl;
|
||||||
|
int num_ids = typeface->charsToGlyphs((void*)ustr.getTerminatedBuffer(), SkTypeface::kUTF16_Encoding,
|
||||||
|
&glyph_ids[0], glyph_ids.size());
|
||||||
|
|
||||||
|
std::cerr << "num_ids = " << num_ids << std::endl;
|
||||||
|
std::vector<uint32_t> glyph_32_ids;
|
||||||
|
for (std::size_t i = 0; i < glyph_ids.size() ;++i)
|
||||||
|
{
|
||||||
|
glyph_32_ids.push_back(glyph_ids[i]);
|
||||||
|
}
|
||||||
|
//const uint32_t glyph_id = 0;
|
||||||
|
// SkAdvancedTypefaceMetrics * metrics =
|
||||||
|
// typeface->getAdvancedTypefaceMetrics(SkAdvancedTypefaceMetrics::kHAdvance_PerGlyphInfo, &glyph_32_ids[0], glyph_32_ids.size());
|
||||||
|
|
||||||
|
|
||||||
|
//auto const& advances = metrics->fGlyphWidths->fAdvance;
|
||||||
|
//std::cerr << "count = " << advances.count();
|
||||||
|
//for ( unsigned j=0; j< num_ids; ++j)
|
||||||
|
//{
|
||||||
|
// std::cerr << advances[j] << ",";
|
||||||
|
//}
|
||||||
|
//std::cerr << std::endl;
|
||||||
|
//for (size_t i = 0; i<metrics.fGlyphWidths.
|
||||||
|
//std::cerr << "SkAdvancedTypefaceMetrics: fFontName=" << metrics->fFontName.c_str() << std::endl;
|
||||||
|
//std::cerr << "SkAdvancedTypefaceMetrics: fAscent=" << metrics->fAscent << std::endl;
|
||||||
|
//std::cerr << "SkAdvancedTypefaceMetrics: fCapHeight=" << metrics->fCapHeight << std::endl;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cerr << "FAIL" << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
410
src/skia/skia_renderer.cpp
Normal file
410
src/skia/skia_renderer.cpp
Normal file
|
@ -0,0 +1,410 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* This file is part of Mapnik (c++ mapping toolkit)
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 Artem Pavlenko
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#if defined(SKIA_RENDERER)
|
||||||
|
|
||||||
|
#include <mapnik/skia/skia_renderer.hpp>
|
||||||
|
#include <mapnik/vertex_converters.hpp>
|
||||||
|
#include <mapnik/symbolizer_helpers.hpp>
|
||||||
|
// skia
|
||||||
|
#include <SkCanvas.h>
|
||||||
|
#include <SkPath.h>
|
||||||
|
#include <SkPaint.h>
|
||||||
|
#include <SkDashPathEffect.h>
|
||||||
|
#include "agg_trans_affine.h"
|
||||||
|
|
||||||
|
namespace mapnik {
|
||||||
|
|
||||||
|
|
||||||
|
void set_comp_op(SkPaint & paint, composite_mode_e comp_op)
|
||||||
|
{
|
||||||
|
SkXfermode::Mode mode = SkXfermode::kSrcOver_Mode;
|
||||||
|
switch (comp_op)
|
||||||
|
{
|
||||||
|
case clear:
|
||||||
|
mode = SkXfermode::kClear_Mode;
|
||||||
|
break;
|
||||||
|
case src:
|
||||||
|
mode = SkXfermode::kSrc_Mode;
|
||||||
|
break;
|
||||||
|
case dst:
|
||||||
|
mode = SkXfermode::kDst_Mode;
|
||||||
|
break;
|
||||||
|
case src_over:
|
||||||
|
mode = SkXfermode::kSrcOver_Mode;
|
||||||
|
break;
|
||||||
|
case dst_over:
|
||||||
|
mode = SkXfermode::kDstOver_Mode;
|
||||||
|
break;
|
||||||
|
case src_in:
|
||||||
|
mode = SkXfermode::kSrcIn_Mode;
|
||||||
|
break;
|
||||||
|
case dst_in:
|
||||||
|
mode = SkXfermode::kDstIn_Mode;
|
||||||
|
break;
|
||||||
|
case src_out:
|
||||||
|
mode = SkXfermode::kSrcOut_Mode;
|
||||||
|
break;
|
||||||
|
case dst_out:
|
||||||
|
mode = SkXfermode::kDstOut_Mode;
|
||||||
|
break;
|
||||||
|
case src_atop:
|
||||||
|
mode = SkXfermode::kSrcATop_Mode;
|
||||||
|
break;
|
||||||
|
case dst_atop:
|
||||||
|
mode = SkXfermode::kDstATop_Mode;
|
||||||
|
break;
|
||||||
|
case _xor:
|
||||||
|
mode = SkXfermode::kXor_Mode;
|
||||||
|
break;
|
||||||
|
case plus:
|
||||||
|
mode = SkXfermode::kPlus_Mode;
|
||||||
|
break;
|
||||||
|
case multiply:
|
||||||
|
mode = SkXfermode::kMultiply_Mode;
|
||||||
|
break;
|
||||||
|
case screen:
|
||||||
|
mode = SkXfermode::kScreen_Mode;
|
||||||
|
break;
|
||||||
|
case overlay:
|
||||||
|
mode = SkXfermode::kOverlay_Mode;
|
||||||
|
break;
|
||||||
|
case darken:
|
||||||
|
mode = SkXfermode::kDarken_Mode;
|
||||||
|
break;
|
||||||
|
case lighten:
|
||||||
|
mode = SkXfermode::kLighten_Mode;
|
||||||
|
break;
|
||||||
|
case color_dodge:
|
||||||
|
mode = SkXfermode::kColorDodge_Mode;
|
||||||
|
break;
|
||||||
|
case color_burn:
|
||||||
|
mode = SkXfermode::kColorBurn_Mode;
|
||||||
|
break;
|
||||||
|
case hard_light:
|
||||||
|
mode = SkXfermode::kHardLight_Mode;
|
||||||
|
break;
|
||||||
|
case soft_light:
|
||||||
|
mode = SkXfermode::kSoftLight_Mode;
|
||||||
|
break;
|
||||||
|
case difference:
|
||||||
|
mode = SkXfermode::kDifference_Mode;
|
||||||
|
break;
|
||||||
|
case exclusion:
|
||||||
|
mode = SkXfermode::kExclusion_Mode;
|
||||||
|
break;
|
||||||
|
case hue:
|
||||||
|
mode = SkXfermode::kHue_Mode;
|
||||||
|
break;
|
||||||
|
case saturation:
|
||||||
|
mode = SkXfermode::kSaturation_Mode;
|
||||||
|
break;
|
||||||
|
case _color:
|
||||||
|
mode = SkXfermode::kColor_Mode;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
paint.setXfermodeMode(mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct skia_path_adapter : private mapnik::noncopyable
|
||||||
|
{
|
||||||
|
skia_path_adapter(SkPath & path)
|
||||||
|
: sk_path_(path) {}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void add_path(T & path)
|
||||||
|
{
|
||||||
|
vertex2d vtx(vertex2d::no_init);
|
||||||
|
path.rewind(0);
|
||||||
|
while ((vtx.cmd = path.vertex(&vtx.x, &vtx.y)) != SEG_END)
|
||||||
|
{
|
||||||
|
switch (vtx.cmd)
|
||||||
|
{
|
||||||
|
case SEG_MOVETO:
|
||||||
|
sk_path_.moveTo(vtx.x, vtx.y);
|
||||||
|
case SEG_LINETO:
|
||||||
|
sk_path_.lineTo(vtx.x, vtx.y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SkPath & sk_path_;
|
||||||
|
};
|
||||||
|
|
||||||
|
skia_renderer::skia_renderer(Map const& map, SkCanvas & canvas, double scale_factor)
|
||||||
|
: feature_style_processor<skia_renderer>(map,scale_factor),
|
||||||
|
canvas_(canvas),
|
||||||
|
width_(map.width()),
|
||||||
|
height_(map.height()),
|
||||||
|
t_(map.width(), map.height(), map.get_current_extent()),
|
||||||
|
scale_factor_(scale_factor),
|
||||||
|
typeface_cache_(),
|
||||||
|
//font_manager_(typeface_cache_),
|
||||||
|
font_engine_(),
|
||||||
|
font_manager_(font_engine_),
|
||||||
|
detector_(boost::make_shared<label_collision_detector4>(
|
||||||
|
box2d<double>(-map.buffer_size(), -map.buffer_size(),
|
||||||
|
map.width() + map.buffer_size(), map.height() + map.buffer_size()))) {}
|
||||||
|
|
||||||
|
skia_renderer::~skia_renderer() {}
|
||||||
|
|
||||||
|
void skia_renderer::start_map_processing(Map const& map)
|
||||||
|
{
|
||||||
|
MAPNIK_LOG_DEBUG(skia_renderer) << "skia_renderer_base: Start map processing bbox=" << map.get_current_extent();
|
||||||
|
boost::optional<color> bg = map.background();
|
||||||
|
if (bg)
|
||||||
|
{
|
||||||
|
canvas_.drawARGB((*bg).alpha(), (*bg).red(), (*bg).green(), (*bg).blue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void skia_renderer::end_map_processing(Map const& map)
|
||||||
|
{
|
||||||
|
MAPNIK_LOG_DEBUG(skia_renderer) << "skia_renderer_base: End map processing";
|
||||||
|
}
|
||||||
|
|
||||||
|
void skia_renderer::start_layer_processing(layer const& lay, box2d<double> const& query_extent)
|
||||||
|
{
|
||||||
|
MAPNIK_LOG_DEBUG(skia_renderer) << "skia_renderer_base: Start processing layer=" << lay.name() ;
|
||||||
|
MAPNIK_LOG_DEBUG(skia_renderer) << "skia_renderer_base: -- datasource=" << lay.datasource().get();
|
||||||
|
MAPNIK_LOG_DEBUG(skia_renderer) << "skia_renderer_base: -- query_extent=" << query_extent;
|
||||||
|
query_extent_ = query_extent;
|
||||||
|
}
|
||||||
|
void skia_renderer::end_layer_processing(layer const& lay)
|
||||||
|
{
|
||||||
|
MAPNIK_LOG_DEBUG(skia_renderer) << "skia_renderer_base: End layer processing";
|
||||||
|
}
|
||||||
|
void skia_renderer::start_style_processing(feature_type_style const& st)
|
||||||
|
{
|
||||||
|
MAPNIK_LOG_DEBUG(skia_renderer) << "skia_renderer:start style processing";
|
||||||
|
}
|
||||||
|
void skia_renderer::end_style_processing(feature_type_style const& st)
|
||||||
|
{
|
||||||
|
MAPNIK_LOG_DEBUG(skia_renderer) << "skia_renderer:end style processing";
|
||||||
|
}
|
||||||
|
|
||||||
|
void skia_renderer::process(line_symbolizer const& sym,
|
||||||
|
mapnik::feature_impl & feature,
|
||||||
|
proj_transform const& prj_trans)
|
||||||
|
{
|
||||||
|
agg::trans_affine tr;
|
||||||
|
evaluate_transform(tr, feature, sym.get_transform());
|
||||||
|
|
||||||
|
box2d<double> clipping_extent = query_extent_;
|
||||||
|
SkPath path;
|
||||||
|
skia_path_adapter adapter(path);
|
||||||
|
|
||||||
|
typedef boost::mpl::vector<clip_line_tag,transform_tag,affine_transform_tag,simplify_tag,smooth_tag> conv_types;
|
||||||
|
vertex_converter<box2d<double>, skia_path_adapter, line_symbolizer,
|
||||||
|
CoordTransform, proj_transform, agg::trans_affine, conv_types>
|
||||||
|
converter(clipping_extent,adapter,sym,t_,prj_trans,tr,scale_factor_);
|
||||||
|
|
||||||
|
if (prj_trans.equal() && sym.clip()) converter.template set<clip_line_tag>(); //optional clip (default: true)
|
||||||
|
converter.template set<transform_tag>(); //always transform
|
||||||
|
converter.template set<affine_transform_tag>();
|
||||||
|
if (sym.simplify_tolerance() > 0.0) converter.template set<simplify_tag>(); // optional simplify converter
|
||||||
|
if (sym.smooth() > 0.0) converter.template set<smooth_tag>(); // optional smooth converter
|
||||||
|
|
||||||
|
BOOST_FOREACH( geometry_type & geom, feature.paths())
|
||||||
|
{
|
||||||
|
if (geom.size() > 1)
|
||||||
|
{
|
||||||
|
converter.apply(geom);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stroke const& strk = sym.get_stroke();
|
||||||
|
color const& col = strk.get_color();
|
||||||
|
SkPaint paint;
|
||||||
|
paint.setStyle(SkPaint::kStroke_Style);
|
||||||
|
paint.setAntiAlias(true);
|
||||||
|
set_comp_op(paint, sym.comp_op());
|
||||||
|
paint.setARGB(int(col.alpha() * strk.get_opacity()), col.red(), col.green(), col.blue());
|
||||||
|
paint.setStrokeWidth(strk.get_width() * scale_factor_);
|
||||||
|
|
||||||
|
switch (strk.get_line_join())
|
||||||
|
{
|
||||||
|
case MITER_JOIN:
|
||||||
|
paint.setStrokeJoin(SkPaint::kMiter_Join);
|
||||||
|
break;
|
||||||
|
case MITER_REVERT_JOIN:
|
||||||
|
break;
|
||||||
|
case ROUND_JOIN:
|
||||||
|
paint.setStrokeJoin(SkPaint::kRound_Join);
|
||||||
|
break;
|
||||||
|
case BEVEL_JOIN:
|
||||||
|
paint.setStrokeJoin(SkPaint::kBevel_Join);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (strk.get_line_cap())
|
||||||
|
{
|
||||||
|
case BUTT_CAP:
|
||||||
|
paint.setStrokeCap(SkPaint::kButt_Cap);
|
||||||
|
break;
|
||||||
|
case SQUARE_CAP:
|
||||||
|
paint.setStrokeCap(SkPaint::kSquare_Cap);
|
||||||
|
break;
|
||||||
|
case ROUND_CAP:
|
||||||
|
paint.setStrokeCap(SkPaint::kRound_Cap);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strk.has_dash())
|
||||||
|
{
|
||||||
|
std::vector<SkScalar> dash;
|
||||||
|
for (auto p : strk.get_dash_array())
|
||||||
|
{
|
||||||
|
dash.push_back(p.first * scale_factor_);
|
||||||
|
dash.push_back(p.second * scale_factor_);
|
||||||
|
}
|
||||||
|
paint.setPathEffect(new SkDashPathEffect(&dash[0], dash.size(), strk.dash_offset(), false));
|
||||||
|
|
||||||
|
}
|
||||||
|
canvas_.drawPath(path, paint);
|
||||||
|
}
|
||||||
|
|
||||||
|
void skia_renderer::process(polygon_symbolizer const& sym,
|
||||||
|
mapnik::feature_impl & feature,
|
||||||
|
proj_transform const& prj_trans)
|
||||||
|
{
|
||||||
|
|
||||||
|
agg::trans_affine tr;
|
||||||
|
evaluate_transform(tr, feature, sym.get_transform());
|
||||||
|
|
||||||
|
SkPath path;
|
||||||
|
skia_path_adapter adapter(path);
|
||||||
|
|
||||||
|
typedef boost::mpl::vector<clip_poly_tag,transform_tag,affine_transform_tag,simplify_tag,smooth_tag> conv_types;
|
||||||
|
vertex_converter<box2d<double>, skia_path_adapter, polygon_symbolizer,
|
||||||
|
CoordTransform, proj_transform, agg::trans_affine, conv_types>
|
||||||
|
converter(query_extent_, adapter ,sym,t_,prj_trans,tr,scale_factor_);
|
||||||
|
|
||||||
|
if (prj_trans.equal() && sym.clip()) converter.template set<clip_poly_tag>(); //optional clip (default: true)
|
||||||
|
converter.template set<transform_tag>(); //always transform
|
||||||
|
converter.template set<affine_transform_tag>();
|
||||||
|
if (sym.simplify_tolerance() > 0.0) converter.template set<simplify_tag>(); // optional simplify converter
|
||||||
|
if (sym.smooth() > 0.0) converter.template set<smooth_tag>(); // optional smooth converter
|
||||||
|
BOOST_FOREACH( geometry_type & geom, feature.paths())
|
||||||
|
{
|
||||||
|
if (geom.size() > 2)
|
||||||
|
{
|
||||||
|
converter.apply(geom);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
color const& fill = sym.get_fill();
|
||||||
|
SkPaint paint;
|
||||||
|
paint.setStyle(SkPaint::kFill_Style);
|
||||||
|
paint.setAntiAlias(true);
|
||||||
|
set_comp_op(paint, sym.comp_op());
|
||||||
|
paint.setARGB(int(fill.alpha() * sym.get_opacity()), fill.red(), fill.green(), fill.blue());
|
||||||
|
canvas_.drawPath(path, paint);
|
||||||
|
}
|
||||||
|
|
||||||
|
void skia_renderer::process(text_symbolizer const& sym,
|
||||||
|
mapnik::feature_impl & feature,
|
||||||
|
proj_transform const& prj_trans)
|
||||||
|
{
|
||||||
|
text_symbolizer_helper<face_manager<freetype_engine>,label_collision_detector4>
|
||||||
|
//text_symbolizer_helper<skia_font_manager,label_collision_detector4>
|
||||||
|
helper(sym, feature, prj_trans,
|
||||||
|
width_, height_,
|
||||||
|
scale_factor_,
|
||||||
|
t_, font_manager_, *detector_, query_extent_);
|
||||||
|
|
||||||
|
while (helper.next())
|
||||||
|
{
|
||||||
|
placements_type const& placements = helper.placements();
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < placements.size(); ++i)
|
||||||
|
{
|
||||||
|
double sx = placements[i].center.x;
|
||||||
|
double sy = placements[i].center.y;
|
||||||
|
|
||||||
|
placements[i].rewind();
|
||||||
|
SkPaint paint;
|
||||||
|
paint.setAntiAlias(true);
|
||||||
|
set_comp_op(paint, sym.comp_op());
|
||||||
|
SkTypeface * typeface = typeface_cache_.create("DejaVuSans"); // FIXME
|
||||||
|
if (typeface) paint.setTypeface(typeface);
|
||||||
|
paint.setTextEncoding(SkPaint::kUTF32_TextEncoding);
|
||||||
|
|
||||||
|
// halo
|
||||||
|
for (int j = 0; j < placements[i].num_nodes(); ++j)
|
||||||
|
{
|
||||||
|
char_info_ptr c;
|
||||||
|
double x, y, angle;
|
||||||
|
placements[i].vertex(c, x, y, angle);
|
||||||
|
if (c->format->halo_radius > 0)
|
||||||
|
{
|
||||||
|
paint.setStyle(SkPaint::kStroke_Style);
|
||||||
|
double text_size = c->format->text_size * scale_factor_;
|
||||||
|
paint.setTextSize((SkScalar)text_size);
|
||||||
|
paint.setStrokeWidth(2.0 * c->format->halo_radius * scale_factor_);
|
||||||
|
paint.setStrokeJoin(SkPaint::kRound_Join);
|
||||||
|
color const& halo_fill = c->format->halo_fill;
|
||||||
|
paint.setARGB(int(halo_fill.alpha() * c->format->text_opacity),
|
||||||
|
halo_fill.red(), halo_fill.green(), halo_fill.blue());
|
||||||
|
SkPoint pt = SkPoint::Make(0,0);
|
||||||
|
canvas_.save();
|
||||||
|
canvas_.translate((SkScalar)(sx + x), (SkScalar)(sy - y));
|
||||||
|
canvas_.rotate(-(SkScalar)180 * (angle/M_PI));
|
||||||
|
canvas_.drawPosText(&(c->c),4, &pt, paint);
|
||||||
|
canvas_.restore();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// text
|
||||||
|
placements[i].rewind();
|
||||||
|
for (int j = 0; j < placements[i].num_nodes(); ++j)
|
||||||
|
{
|
||||||
|
char_info_ptr c;
|
||||||
|
double x, y, angle;
|
||||||
|
placements[i].vertex(c, x, y, angle);
|
||||||
|
paint.setStyle(SkPaint::kFill_Style);
|
||||||
|
double text_size = c->format->text_size * scale_factor_;
|
||||||
|
paint.setTextSize((SkScalar)text_size);
|
||||||
|
color const& fill = c->format->fill;
|
||||||
|
paint.setARGB(int(fill.alpha() * c->format->text_opacity),
|
||||||
|
fill.red(), fill.green(), fill.blue());
|
||||||
|
SkPoint pt = SkPoint::Make(0,0);
|
||||||
|
canvas_.save();
|
||||||
|
canvas_.translate((SkScalar)(sx + x), (SkScalar)(sy - y));
|
||||||
|
canvas_.rotate(-(SkScalar)180 * (angle/M_PI));
|
||||||
|
canvas_.drawPosText(&(c->c),4, &pt, paint);
|
||||||
|
canvas_.restore();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // SKIA_RENDERER
|
133
src/skia/skia_typeface_cache.cpp
Normal file
133
src/skia/skia_typeface_cache.cpp
Normal file
|
@ -0,0 +1,133 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* This file is part of Mapnik (c++ mapping toolkit)
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 Artem Pavlenko
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <mapnik/debug.hpp>
|
||||||
|
#include <boost/filesystem.hpp>
|
||||||
|
#include <boost/algorithm/string.hpp>
|
||||||
|
#ifdef MAPNIK_THREADSAFE
|
||||||
|
#include <boost/thread/mutex.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <SkTypeface.h>
|
||||||
|
//#include <SkFontHost.h>
|
||||||
|
#include <SkAdvancedTypefaceMetrics.h>
|
||||||
|
|
||||||
|
#include <mapnik/skia/skia_typeface_cache.hpp>
|
||||||
|
#include <mapnik/util/fs.hpp>
|
||||||
|
|
||||||
|
namespace mapnik
|
||||||
|
{
|
||||||
|
|
||||||
|
skia_typeface_cache::skia_typeface_cache()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
skia_typeface_cache::~skia_typeface_cache()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SkTypeface * skia_typeface_cache::create(std::string const& family_name)
|
||||||
|
{
|
||||||
|
cache_type::const_iterator itr = typefaces_.find(family_name);
|
||||||
|
if (itr != typefaces_.end())
|
||||||
|
{
|
||||||
|
return itr->second;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool skia_typeface_cache::register_font(std::string const& file_name)
|
||||||
|
{
|
||||||
|
#ifdef MAPNIK_THREADSAFE
|
||||||
|
boost::mutex::scoped_lock lock(mutex_);
|
||||||
|
#endif
|
||||||
|
SkTypeface * typeface = SkTypeface::CreateFromFile(file_name.c_str());
|
||||||
|
if (typeface)
|
||||||
|
{
|
||||||
|
SkAdvancedTypefaceMetrics * metrics = typeface->getAdvancedTypefaceMetrics(SkAdvancedTypefaceMetrics::kNo_PerGlyphInfo);
|
||||||
|
std::cerr << metrics->fFontName.c_str() << std::endl;
|
||||||
|
typefaces_.insert(std::make_pair(std::string(metrics->fFontName.c_str()),typeface));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool skia_typeface_cache::register_fonts(std::string const& dir, bool recurse)
|
||||||
|
{
|
||||||
|
if (!mapnik::util::exists(dir))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!mapnik::util::is_directory(dir))
|
||||||
|
{
|
||||||
|
return register_font(dir);
|
||||||
|
}
|
||||||
|
bool success = false;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
boost::filesystem::directory_iterator end_itr;
|
||||||
|
for (boost::filesystem::directory_iterator itr(dir); itr != end_itr; ++itr)
|
||||||
|
{
|
||||||
|
#if (BOOST_FILESYSTEM_VERSION == 3)
|
||||||
|
std::string file_name = itr->path().string();
|
||||||
|
#else // v2
|
||||||
|
std::string file_name = itr->string();
|
||||||
|
#endif
|
||||||
|
if (boost::filesystem::is_directory(*itr) && recurse)
|
||||||
|
{
|
||||||
|
if (register_fonts(file_name, true))
|
||||||
|
{
|
||||||
|
success = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#if (BOOST_FILESYSTEM_VERSION == 3)
|
||||||
|
std::string base_name = itr->path().filename().string();
|
||||||
|
#else // v2
|
||||||
|
std::string base_name = itr->filename();
|
||||||
|
#endif
|
||||||
|
if (!boost::algorithm::starts_with(base_name,".") &&
|
||||||
|
boost::filesystem::is_regular_file(file_name))
|
||||||
|
{
|
||||||
|
if (register_font(file_name))
|
||||||
|
{
|
||||||
|
success = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (std::exception const& ex)
|
||||||
|
{
|
||||||
|
MAPNIK_LOG_ERROR(skia_typeface_cache) << "register_fonts: " << ex.what();
|
||||||
|
}
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef MAPNIK_THREADSAFE
|
||||||
|
boost::mutex skia_typeface_cache::mutex_;
|
||||||
|
#endif
|
||||||
|
skia_typeface_cache::cache_type skia_typeface_cache::typefaces_;
|
||||||
|
|
||||||
|
}
|
|
@ -34,6 +34,10 @@
|
||||||
#include <mapnik/expression_evaluator.hpp>
|
#include <mapnik/expression_evaluator.hpp>
|
||||||
#include <mapnik/pixel_position.hpp>
|
#include <mapnik/pixel_position.hpp>
|
||||||
|
|
||||||
|
#if defined(SKIA_RENDERER)
|
||||||
|
#include <mapnik/skia/skia_font_manager.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
// agg
|
// agg
|
||||||
#include "agg_conv_clip_polyline.h"
|
#include "agg_conv_clip_polyline.h"
|
||||||
|
|
||||||
|
@ -58,7 +62,7 @@ text_symbolizer_helper<FaceManagerT, DetectorT>::text_symbolizer_helper(text_sym
|
||||||
detector_(detector),
|
detector_(detector),
|
||||||
dims_(0, 0, width, height),
|
dims_(0, 0, width, height),
|
||||||
query_extent_(query_extent),
|
query_extent_(query_extent),
|
||||||
text_(font_manager, scale_factor),
|
text_(scale_factor),
|
||||||
angle_(0.0),
|
angle_(0.0),
|
||||||
placement_valid_(false),
|
placement_valid_(false),
|
||||||
points_on_line_(false),
|
points_on_line_(false),
|
||||||
|
@ -331,7 +335,7 @@ bool text_symbolizer_helper<FaceManagerT, DetectorT>::next_placement()
|
||||||
}
|
}
|
||||||
|
|
||||||
finder_.reset(new placement_finder<DetectorT>(*placement_,
|
finder_.reset(new placement_finder<DetectorT>(*placement_,
|
||||||
text_.get_string_info(),
|
text_.get_string_info(font_manager_),
|
||||||
detector_, dims_));
|
detector_, dims_));
|
||||||
placement_valid_ = true;
|
placement_valid_ = true;
|
||||||
return true;
|
return true;
|
||||||
|
@ -503,6 +507,9 @@ agg::trans_affine const& shield_symbolizer_helper<FaceManagerT, DetectorT>::get_
|
||||||
}
|
}
|
||||||
|
|
||||||
template class text_symbolizer_helper<face_manager<freetype_engine>, label_collision_detector4>;
|
template class text_symbolizer_helper<face_manager<freetype_engine>, label_collision_detector4>;
|
||||||
|
#if defined(SKIA_RENDERER)
|
||||||
|
template class text_symbolizer_helper<skia_font_manager, label_collision_detector4>;
|
||||||
|
#endif
|
||||||
template class shield_symbolizer_helper<face_manager<freetype_engine>, label_collision_detector4>;
|
template class shield_symbolizer_helper<face_manager<freetype_engine>, label_collision_detector4>;
|
||||||
template class mapnik::placement_finder<mapnik::label_collision_detector4>;
|
template class mapnik::placement_finder<mapnik::label_collision_detector4>;
|
||||||
} //namespace
|
} //namespace
|
||||||
|
|
Loading…
Add table
Reference in a new issue