Restructure shaping code in preparation for optimizations.

This commit is contained in:
Hermann Kraus 2013-04-02 07:02:01 +02:00
parent 57a6111e39
commit 55ce673a8c
4 changed files with 23 additions and 152 deletions

View file

@ -1,61 +0,0 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2012 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
*
*****************************************************************************/
#ifndef MAPNIK_TEXT_SHAPING_HPP
#define MAPNIK_TEXT_SHAPING_HPP
//ICU
#include <unicode/unistr.h>
#include <unicode/uscript.h>
#include <harfbuzz/hb.h>
// freetype2
extern "C"
{
#include <ft2build.h>
#include FT_FREETYPE_H
}
namespace mapnik
{
/** This class is a thin wrapper around HarfBuzz. */
class text_shaping
{
public:
text_shaping(FT_Face face);
~text_shaping();
uint32_t process_text(UnicodeString const& text, unsigned start, unsigned end, bool rtl, UScriptCode script);
hb_buffer_t *get_buffer() { return buffer_; }
protected:
static void free_data(void *data);
void load_font();
hb_font_t *font_;
hb_buffer_t *buffer_;
FT_Face face_;
};
} //ns mapnik
#endif // TEXT_SHAPING_HPP

View file

@ -195,7 +195,6 @@ source = Split(
text/placements/dummy.cpp
text/placements/list.cpp
text/placements/simple.cpp
text/shaping.cpp
text/layout.cpp
text/layout_shape_hb.cpp
text/itemizer.cpp

View file

@ -21,7 +21,6 @@
*****************************************************************************/
// mapnik
#include <mapnik/text/layout.hpp>
#include <mapnik/text/shaping.hpp>
#include <mapnik/text/text_properties.hpp>
#include <mapnik/text/face.hpp>
@ -30,6 +29,8 @@
// harfbuzz
#include <harfbuzz/hb.h>
#include <harfbuzz/hb-ft.h>
#include <harfbuzz/hb-icu.h>
namespace mapnik
{
@ -42,24 +43,38 @@ void text_layout::shape_text(text_line_ptr line)
UnicodeString const& text = itemizer_.get_text();
size_t length = end - start;
if (!length) return;
hb_buffer_t *buffer(hb_buffer_create());
hb_buffer_set_unicode_funcs(buffer, hb_icu_get_unicode_funcs());
line->reserve(length); //Preallocate memory
hb_buffer_pre_allocate(buffer, length);
std::list<text_item> const& list = itemizer_.itemize(start, end);
std::list<text_item>::const_iterator itr = list.begin(), list_end = list.end();
for (; itr != list_end; itr++)
{
face_set_ptr face_set = font_manager_.get_face_set(itr->format->face_name, itr->format->fontset);
face_set->set_character_sizes(itr->format->text_size * scale_factor_);
double size = itr->format->text_size * scale_factor_;
face_set->set_character_sizes(size);
font_face_set::iterator face_itr = face_set->begin(), face_end = face_set->end();
for (; face_itr != face_end; face_itr++)
{
hb_buffer_clear_contents(buffer);
hb_buffer_add_utf16(buffer, text.getBuffer(), text.length(), itr->start, itr->end - itr->start);
hb_buffer_set_direction(buffer, (itr->rtl == UBIDI_RTL)?HB_DIRECTION_RTL:HB_DIRECTION_LTR);
hb_buffer_set_script(buffer, hb_icu_script_to_script(itr->script));
#if 0
hb_buffer_set_language(buffer, hb_language_from_string (language, -1));
#endif
face_ptr face = *face_itr;
text_shaping shaper(face->get_face()); //TODO: Make this more efficient by caching this object in font_face
shaper.process_text(text, itr->start, itr->end, itr->rtl == UBIDI_RTL, itr->script);
hb_buffer_t *buffer = shaper.get_buffer();
hb_font_t *font(hb_ft_font_create(face->get_face(), NULL));
hb_shape(font, buffer, 0 /*features*/, 0 /*num_features*/);
hb_font_destroy(font);
unsigned num_glyphs = hb_buffer_get_length(buffer);
hb_glyph_info_t *glyphs = hb_buffer_get_glyph_infos(buffer, NULL);
@ -100,6 +115,8 @@ void text_layout::shape_text(text_line_ptr line)
break; //When we reach this point the current font had all glyphs.
}
}
hb_buffer_destroy(buffer);
}
} //ns mapnik

View file

@ -1,84 +0,0 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2012 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
*
*****************************************************************************/
// mapnik
#include <mapnik/text/shaping.hpp>
// stl
#include <iostream>
#include <fstream>
// harf-buzz
#define HAVE_FREETYPE
#include <harfbuzz/hb.h>
#include <harfbuzz/hb-ft.h>
#include <harfbuzz/hb-icu.h>
namespace mapnik
{
text_shaping::text_shaping(FT_Face face)
: font_(0),
buffer_ (hb_buffer_create()),
face_(face)
{
load_font();
}
text_shaping::~text_shaping()
{
hb_buffer_destroy(buffer_);
hb_font_destroy(font_);
}
uint32_t text_shaping::process_text(UnicodeString const& text, unsigned start, unsigned end, bool rtl, UScriptCode script)
{
if (!font_) return 0;
hb_buffer_reset(buffer_);
hb_buffer_set_unicode_funcs(buffer_, hb_icu_get_unicode_funcs());
uint32_t length = text.length();
hb_buffer_add_utf16(buffer_, text.getBuffer(), length, start, end-start);
hb_buffer_set_direction(buffer_, rtl?HB_DIRECTION_RTL:HB_DIRECTION_LTR);
hb_buffer_set_script(buffer_, hb_icu_script_to_script(script));
#if 0
hb_buffer_set_language(buffer, hb_language_from_string (language, -1));
#endif
hb_shape(font_, buffer_, 0 /*features*/, 0 /*num_features*/);
return length;
}
void text_shaping::free_data(void *data)
{
char *tmp = (char *)data;
delete [] tmp;
}
void text_shaping::load_font()
{
if (font_) return;
font_ = hb_ft_font_create(face_, NULL);
}
}