Layout-TNG-Input.cpp revision 5d4090d6a0856c3cbae9e26f7e61f2c2839ef6ee
/*
* Inkscape::Text::Layout - text layout engine input functions
*
* Authors:
* Richard Hughes <cyreve@users.sf.net>
*
* Copyright (C) 2005 Richard Hughes
*
* Released under GNU GPL, read the file 'COPYING' for more information
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#ifndef PANGO_ENABLE_ENGINE
#define PANGO_ENABLE_ENGINE
#endif
#include "Layout-TNG.h"
#include "style.h"
#include "svg/svg-length.h"
#include "sp-object.h"
#include "sp-string.h"
#include "FontFactory.h"
namespace Inkscape {
namespace Text {
void Layout::_clearInputObjects()
{
for(std::vector<InputStreamItem*>::iterator it = _input_stream.begin() ; it != _input_stream.end() ; ++it) {
delete *it;
}
}
// this function does nothing more than store all its parameters for future reference
void Layout::appendText(Glib::ustring const &text, SPStyle *style, void *source_cookie, OptionalTextTagAttrs const *optional_attributes, unsigned optional_attributes_offset, Glib::ustring::const_iterator text_begin, Glib::ustring::const_iterator text_end)
{
new_source->text_length = 0;
new_source->text_length++; // save this because calculating the length of a UTF-8 string is expensive
if (optional_attributes) {
// we need to fill in x and y even if the text is empty so that empty paragraphs can be positioned correctly
_copyInputVector(optional_attributes->x, optional_attributes_offset, &new_source->x, std::max(1, new_source->text_length));
_copyInputVector(optional_attributes->y, optional_attributes_offset, &new_source->y, std::max(1, new_source->text_length));
_copyInputVector(optional_attributes->dx, optional_attributes_offset, &new_source->dx, new_source->text_length);
_copyInputVector(optional_attributes->dy, optional_attributes_offset, &new_source->dy, new_source->text_length);
_copyInputVector(optional_attributes->rotate, optional_attributes_offset, &new_source->rotate, new_source->text_length);
if (!optional_attributes->rotate.empty() && optional_attributes_offset >= optional_attributes->rotate.size()) {
last_rotate = 0.f;
for (std::vector<SVGLength>::const_iterator it = optional_attributes->rotate.begin() ; it != optional_attributes->rotate.end() ; ++it)
last_rotate = *it;
}
}
}
void Layout::_copyInputVector(std::vector<SVGLength> const &input_vector, unsigned input_offset, std::vector<SVGLength> *output_vector, size_t max_length)
{
output_vector->clear();
break;
input_offset++;
max_length--;
}
}
// just save what we've been given, really
void Layout::appendControlCode(TextControlCode code, void *source_cookie, double width, double ascent, double descent)
{
}
// more saving of the parameters
{
}
int Layout::_enum_converter(int input, EnumConversionItem const *conversion_table, unsigned conversion_table_size)
{
for (unsigned i = 0 ; i < conversion_table_size ; i++)
return conversion_table[i].output;
return conversion_table[0].output;
}
// ***** the style format interface
// this doesn't include all accesses to SPStyle, only the ones that are non-trivial
static const float medium_font_size = 12.0; // more of a default if all else fails than anything else
{
// in case the computed value's not good enough, here's some manual code held in reserve:
float inherit_multiplier = 1.0;
for ( ; ; ) {
case SP_FONT_SIZE_LITERAL: {
default:
}
break;
}
case SP_FONT_SIZE_PERCENTAGE: { // 'em' units should be in here, but aren't. Fix in style.cpp.
break;
}
case SP_FONT_SIZE_LENGTH: {
}
}
}
if (this_style == NULL) break;
}
return medium_font_size * inherit_multiplier;
}
{
return TOP_TO_BOTTOM;
return RIGHT_TO_LEFT;
return LEFT_TO_RIGHT;
default:
std::cerr << "Layout::InputTextStream::styleGetBlockProgression: invalid writing mode." << std::endl;
}
return TOP_TO_BOTTOM;
}
static Layout::Alignment text_anchor_to_alignment(unsigned anchor, Layout::Direction para_direction)
{
switch (anchor) {
default:
case SP_CSS_TEXT_ANCHOR_START: return para_direction == Layout::LEFT_TO_RIGHT ? Layout::LEFT : Layout::RIGHT;
case SP_CSS_TEXT_ANCHOR_END: return para_direction == Layout::LEFT_TO_RIGHT ? Layout::RIGHT : Layout::LEFT;
}
}
Layout::Alignment Layout::InputStreamTextSource::styleGetAlignment(Layout::Direction para_direction, bool try_text_align) const
{
if (!try_text_align)
// there's no way to tell the difference between text-anchor set higher up the cascade to the default and
// text-anchor never set anywhere in the cascade, so in order to detect which of text-anchor or text-align
// to use we'll have to run up the style tree ourselves.
for ( ; ; ) {
// If both text-align and text-anchor are set at the same level, text-align takes
// precedence because it is the most expressive.
default:
case SP_CSS_TEXT_ALIGN_LEFT: return LEFT;
case SP_CSS_TEXT_ALIGN_RIGHT: return RIGHT;
case SP_CSS_TEXT_ALIGN_CENTER: return CENTER;
case SP_CSS_TEXT_ALIGN_JUSTIFY: return FULL;
}
}
if (this_style == NULL) break;
}
}
// NB: The Pango web page calls 500 "the normal font" but both CSS2 and the Pango
// enumeration define 400 as normal.
{
return res;
}
{
// Pango can't cope with spaces before or after the commas - let's remove them.
// this code is not exactly unicode-safe, but it's similar to what's done in
// pango, so it's not the limiting factor
family = "sans-serif";
} else {
if (families) {
g_strstrip(*f);
family += *f;
}
}
}
pango_font_description_set_weight(descr,(PangoWeight)_enum_converter(style->font_weight.computed, enum_convert_spstyle_weight_to_pango_weight, sizeof(enum_convert_spstyle_weight_to_pango_weight)/sizeof(enum_convert_spstyle_weight_to_pango_weight[0])));
pango_font_description_set_style(descr,(PangoStyle)_enum_converter(style->font_style.computed, enum_convert_spstyle_style_to_pango_style, sizeof(enum_convert_spstyle_style_to_pango_style)/sizeof(enum_convert_spstyle_style_to_pango_style[0])));
pango_font_description_set_variant(descr,(PangoVariant)_enum_converter(style->font_variant.computed, enum_convert_spstyle_variant_to_pango_variant, sizeof(enum_convert_spstyle_variant_to_pango_variant)/sizeof(enum_convert_spstyle_variant_to_pango_variant[0])));
#ifdef USE_PANGO_WIN32
// damn Pango fudges the size, so we need to unfudge. See source of pango_win32_font_map_init()
pango_font_description_set_size(descr, (int) ((font_factory::Default())->fontSize*PANGO_SCALE*72/GetDeviceCaps(pango_win32_get_dc(),LOGPIXELSY))); // mandatory huge size (hinting workaround)
// we don't set stretch on Win32, because pango-win32 has no concept of it
// (Windows doesn't really provide any useful field it could use).
// If we did set stretch, then any text with a font-stretch attribute would
// end up falling back to Arial.
#else
pango_font_description_set_size(descr, (int) ((font_factory::Default())->fontSize*PANGO_SCALE)); // mandatory huge size (hinting workaround)
pango_font_description_set_stretch(descr,(PangoStretch)_enum_converter(style->font_stretch.computed, enum_convert_spstyle_stretch_to_pango_stretch, sizeof(enum_convert_spstyle_stretch_to_pango_stretch)/sizeof(enum_convert_spstyle_stretch_to_pango_stretch[0])));
#endif
return descr;
}
{
}
}//namespace Text
}//namespace Inkscape