diff options
Diffstat (limited to 'ksvg/impl/libs/libtext2path/src')
25 files changed, 3668 insertions, 0 deletions
diff --git a/ksvg/impl/libs/libtext2path/src/Affine.cpp b/ksvg/impl/libs/libtext2path/src/Affine.cpp new file mode 100644 index 00000000..d06b53bc --- /dev/null +++ b/ksvg/impl/libs/libtext2path/src/Affine.cpp @@ -0,0 +1,174 @@ +/* + Copyright (C) 2003 Nikolas Zimmermann <wildfox@kde.org> + This file is part of the KDE project + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + aint with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include <math.h> + +#include "Point.h" +#include "Affine.h" + +using namespace T2P; + +Affine::Affine() +{ + m_affine[0] = 1.0; + m_affine[1] = 0.0; + m_affine[2] = 0.0; + m_affine[3] = 1.0; + m_affine[4] = 0.0; + m_affine[5] = 0.0; +} + +Affine::Affine(double affine[6]) +{ + for(int i = 0; i < 6; i++) + m_affine[i] = affine[i]; +} + +Affine::Affine(const Affine &other) +{ + (*this) = other; +} + +Affine::Affine(double m11, double m12, double m21, double m22, double dx, double dy) +{ + m_affine[0] = m11; m_affine[1] = m12; m_affine[2] = m21; + m_affine[3] = m22; m_affine[4] = dx; m_affine[5] = dy; +} + +Affine::~Affine() +{ +} + +Affine &Affine::operator*=(Affine &other) +{ + double d0 = m11() * other.m11() + m12() * other.m21(); + double d1 = m11() * other.m12() + m12() * other.m22(); + double d2 = m21() * other.m11() + m22() * other.m21(); + double d3 = m21() * other.m12() + m22() * other.m22(); + double d4 = dx() * other.m11() + dy() * other.m21() + other.dx(); + double d5 = dx() * other.m12() + dy() * other.m22() + other.dy(); + + m_affine[0] = d0; m_affine[1] = d1; m_affine[2] = d2; + m_affine[3] = d3; m_affine[4] = d4; m_affine[5] = d5; + + return *this; +} + +Affine &Affine::operator=(const Affine &other) +{ + for(int i = 0; i < 6; i++) + m_affine[i] = other.m_affine[i]; + + return *this; +} + +double &Affine::m11() +{ + return m_affine[0]; +} + +double &Affine::m12() +{ + return m_affine[1]; +} + +double &Affine::m21() +{ + return m_affine[2]; +} + +double &Affine::m22() +{ + return m_affine[3]; +} + +double &Affine::dx() +{ + return m_affine[4]; +} + +double &Affine::dy() +{ + return m_affine[5]; +} + +void Affine::scale(double s) +{ + scale(s, s); +} + +void Affine::scale(double sx, double sy) +{ + m_affine[0] = sx; + m_affine[3] = sy; +} + +void Affine::translate(const Point &point) +{ + m_affine[4] += point.x(); + m_affine[5] += point.y(); +} + +void Affine::translate(double tx, double ty) +{ + m_affine[4] += tx * m_affine[0] + ty * m_affine[2]; + m_affine[5] += tx * m_affine[1] + ty * m_affine[3]; +} + +void Affine::rotate(double angle) +{ + double sina = sin(angle); + double cosa = cos(angle); + + double tm11 = cosa * m_affine[0] + sina * m_affine[2]; + double tm12 = cosa * m_affine[1] + sina * m_affine[3]; + double tm21 = -sina * m_affine[0] + cosa * m_affine[2]; + double tm22 = -sina * m_affine[1] + cosa * m_affine[3]; + + m_affine[0] = tm11; m_affine[1] = tm12; + m_affine[2] = tm21; m_affine[3] = tm22; +} + +void Affine::rotateAround(double angle, const Point &point) +{ + translate(point); + rotate(angle); + translate(point.invert()); +} + +void Affine::rotateAround(double angle, double cx, double cy) +{ + translate(-cx, -cy); + rotate(angle); + translate(cx, cy); +} + +Point Affine::mapPoint(const Point &p) const +{ + return Point(p.x() * m_affine[0] + p.y() * m_affine[2] + m_affine[4], + p.x() * m_affine[1] + p.y() * m_affine[3] + m_affine[5]); +} + +double *Affine::data() +{ + return m_affine; +} + +// vim:ts=4:noet diff --git a/ksvg/impl/libs/libtext2path/src/Affine.h b/ksvg/impl/libs/libtext2path/src/Affine.h new file mode 100644 index 00000000..c0f11e9b --- /dev/null +++ b/ksvg/impl/libs/libtext2path/src/Affine.h @@ -0,0 +1,67 @@ +/* + Copyright (C) 2003 Nikolas Zimmermann <wildfox@kde.org> + This file is part of the KDE project + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + aint with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef T2P_AFFINE_H +#define T2P_AFFINE_H + +namespace T2P +{ + class Point; + class Affine + { + public: + Affine(); + Affine(double affine[6]); + Affine(const Affine &other); + Affine(double m11, double m12, double m21, double m22, double dx, double dy); + ~Affine(); + + Affine &operator*=(Affine &other); + Affine &operator=(const Affine &other); + + double &m11(); + double &m12(); + double &m21(); + double &m22(); + double &dx(); + double &dy(); + + void scale(double s); + void scale(double sx, double sy); + void translate(const Point &point); // Assumes point is already transformed + void translate(double tx, double ty); + + void rotate(double angle); + void rotateAround(double angle, const Point &point); // Assumes point is already transformed + void rotateAround(double angle, double cx, double cy); + + Point mapPoint(const Point &p) const; + + // Internal + double *data(); + + private: + double m_affine[6]; + }; +} + +#endif + +// vim:ts=4:noet diff --git a/ksvg/impl/libs/libtext2path/src/BezierPath.h b/ksvg/impl/libs/libtext2path/src/BezierPath.h new file mode 100644 index 00000000..1c357abd --- /dev/null +++ b/ksvg/impl/libs/libtext2path/src/BezierPath.h @@ -0,0 +1,56 @@ +/* + Copyright (C) 2003 Nikolas Zimmermann <wildfox@kde.org> + This file is part of the KDE project + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + aint with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef T2P_BEZIERPATH_H +#define T2P_BEZIERPATH_H + +#include <list> + +namespace T2P +{ + class Point; + class BezierPath + { + public: + BezierPath() { } + virtual ~BezierPath() { } + + /** + * Calculates the arclength from p0 to the point parametrized by 0 <= t <= 1. + */ + virtual double length(double t = 1.0) = 0; + + /** + * Calculates the point, the tangent vector and the normal vector for + * 0 <= t <= 1. The tangent vector and the normal vector are + * normalized (length=1). + */ + virtual void pointTangentNormalAt(double t, Point *p = 0, Point *tn = 0, Point *n = 0) = 0; + + /** + * Calculates the axis-aligned bounding box. + */ + virtual void boundingBox(Point *topLeft, Point *bottomRight) = 0; + }; +} + +#endif + +// vim:ts=4:noet diff --git a/ksvg/impl/libs/libtext2path/src/Cache.h b/ksvg/impl/libs/libtext2path/src/Cache.h new file mode 100644 index 00000000..a85fdf92 --- /dev/null +++ b/ksvg/impl/libs/libtext2path/src/Cache.h @@ -0,0 +1,156 @@ +/* + Copyright (C) 2003 Nikolas Zimmermann <wildfox@kde.org> + This file is part of the KDE project + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + aint with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef T2P_CACHE_H +#define T2P_CACHE_H + +#include <map> +#include <string> +#include <vector> +#include <iostream> + +#include "myboost/shared_ptr.hpp" + +namespace T2P +{ + class CacheElement + { + public: + CacheElement(std::string key) : m_key(key), m_usage(0) { } + ~CacheElement() { } + + std::string key() const { return m_key; } + int usage() const { return m_usage; } + + void incUsage() { m_usage++; } + + private: + std::string m_key; + int m_usage; + }; + + template<typename T> + class Cache + { + public: + typedef myboost::shared_ptr<T> SharedT; + + Cache(int maxSize = 10) : m_size(0), m_maxSize(maxSize) { } + ~Cache() { clear(); } + + // Number of elements in cache + int size() const { return m_size; } + + // Maximum number of elements in cache + int maxSize() const { return m_maxSize; } + + // Add new entry + void insert(const std::string &key, SharedT &value) + { + // TODO: Add real LRU logic, now i will just delete the less + // used item when inserting a new item would exceed maxSize + if(m_size == m_maxSize) + { + // Find less used item + typename std::map<SharedT, CacheElement *>::const_iterator it = m_cacheMap.begin(); + int usage = (*it).second->usage(); std::string keyUsage = (*it).second->key(); + for(it++; it != m_cacheMap.end(); ++it) + { + int curUsage = (*it).second->usage(); + if(curUsage < usage) + { + usage = curUsage; + keyUsage = (*it).second->key(); + } + } + +// std::cout << "[CACHE] Removing less used element with key: " << keyUsage << " (Used " << usage << " times!)" << std::endl; + remove(keyUsage); + } + + m_size++; + m_entries.push_back(value); + m_cacheMap[value] = new CacheElement(key); + } + + // Remove single entry + void remove(const std::string &key) + { + for(typename std::vector<SharedT>::iterator it = m_entries.begin(); it != m_entries.end(); ++it) + { + SharedT cur = *it; + if(m_cacheMap[cur]->key() == key) + { + m_size--; + + typename std::map<SharedT, CacheElement *>::iterator cacheElement = m_cacheMap.find(cur); + m_cacheMap.erase(cacheElement); + delete cacheElement->second; + m_entries.erase(it); // Only valid to write because we don't go on here! + break; // Otherwhise the iterators _may_ be invalid! + } + } + } + + // Remove all entries + void clear() + { + m_size = 0; + m_entries.clear(); + m_cacheMap.clear(); + } + + // Lookup entry + SharedT find(const std::string &key) + { + for(typename std::vector<SharedT>::const_iterator it = m_entries.begin(); it != m_entries.end(); ++it) + { + SharedT cur = *it; + if(m_cacheMap[cur]->key() == key) + { + m_cacheMap[cur]->incUsage(); + return cur; + } + } + + return SharedT(); + } + + void dump() + { + std::cout << "[CACHE] " << size() << " of " << maxSize() << " Objects in the cache." << std::endl; + + for(typename std::vector<SharedT>::iterator it = m_entries.begin(); it != m_entries.end(); ++it) + { + SharedT cur = *it; + std::cout << "[CACHE] - " << m_cacheMap[cur]->key() << " -> " << cur << " (Usage: " << m_cacheMap[cur]->usage() << ")" << std::endl; + } + } + + private: + std::vector<SharedT> m_entries; + std::map<SharedT, CacheElement *> m_cacheMap; + int m_size, m_maxSize; + }; +} + +#endif + +// vim:ts=4:noet diff --git a/ksvg/impl/libs/libtext2path/src/Converter.cpp b/ksvg/impl/libs/libtext2path/src/Converter.cpp new file mode 100644 index 00000000..7810b417 --- /dev/null +++ b/ksvg/impl/libs/libtext2path/src/Converter.cpp @@ -0,0 +1,505 @@ +/* + Copyright (C) 2003 Nikolas Zimmermann <wildfox@kde.org> + This file is part of the KDE project + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + aint with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include <math.h> + +#include "myboost/shared_ptr.hpp" +#include <fontconfig/fontconfig.h> +#include <fribidi/fribidi.h> +#include <fribidi/fribidi_types.h> + +#include "Font.h" +#include "Glyph.h" +#include "Tools.h" +#include "Rectangle.h" +#include "Converter.h" +#include "QtUnicode.h" +#include "GlyphTracer.h" + +// Macros +#define FT_TRUNC(x) ((x) >> 6) +#define FT_TOFLOAT(x) ((x) * (1.0 / 64.0)) +#define FT_FROMFLOAT(x) ((int) floor ((x) * 64.0 + 0.5)) + +const double deg2rad = 0.017453292519943295769; // pi/180 + +using namespace T2P; + +// Font engine. The core component. +Converter::Converter(GlyphTracer *tracer) : m_glyphTracer(tracer) +{ + m_init = false; + m_kerning = true; + m_library = 0; +} + +Converter::~Converter() +{ + if(m_glyphTracer) + delete m_glyphTracer; + + m_fontCache.clear(); + m_glyphCache.clear(); + + // Close FreeType2 library + if(m_library) + FT_Done_FreeType(m_library); +} + +void Converter::init() +{ + // Initialize FreeType2 + m_init = (FT_Init_FreeType(&m_library) == 0); +} + +bool Converter::ready() +{ + return m_init; +} + +void Converter::setKerning(bool mode) +{ + m_kerning = mode; +} + +// Lookup font in cache or create new font +SharedFont Converter::requestFont(const FontVisualParams *params) +{ + std::string cacheKey = cacheFontKey(params); + SharedFont cached = m_fontCache.find(cacheKey); + + // If not available in cache, create new one and cache it :) + if(cached) + { + delete params; + return cached; + } + else + { + // Create a new Font + SharedFont newFont(new Font(this)); + + // Load the font + if(!newFont->load(params)) + { + delete params; + return SharedFont(); + } + + // Append to cache + m_fontCache.insert(cacheKey, newFont); + return newFont; + } +} + +GlyphAffinePair *Converter::requestGlyph(GlyphRenderParams *params, Rectangle &bbox, Affine &affine, bool onlyLatin) +{ + // 1. Select glyph to have glyphIndex information, + // needed to generate the cache lookup key + selectGlyph(params); + + SharedGlyph cached = m_glyphCache.find(cacheGlyphKey(params)); + + // If not available in cache, render new one and cache it :) + // If we're mixing ie. japanese and latin characters (TTB layout), + // then we also have to re-calculate the glyph again with the appropriate rotation matrix (Niko) + if(!cached || !onlyLatin) + cached = calcGlyph(params, affine, onlyLatin); + + // Correct bezier path by setting up the correct scaling matrix + // and multiplying with the current glyph affine + double fontSize = params->font()->fontParams()->size(); + + T2P::Affine correctAffine; + correctAffine.scale(0.001 * fontSize, -0.001 * fontSize); + correctAffine *= affine; + + // Get bbox information + Point p1(FT_TRUNC(cached->ftBbox()->xMin), FT_TRUNC(cached->ftBbox()->yMin)); + Point p2(FT_TRUNC(cached->ftBbox()->xMax), FT_TRUNC(cached->ftBbox()->yMax)); + + bbox.setA(affine.mapPoint(p1)); + bbox.setB(affine.mapPoint(p2)); + + return new GlyphAffinePair(cached.get(), correctAffine); +} + +void Converter::selectGlyph(GlyphRenderParams *params) +{ + // 1. Select glyph + test if it exists + // | + // |-> if it doesn't exist, replace by a '?' and check if exists + // |-> if it does exist, use it! + params->setGlyphIndex(FT_Get_Char_Index(params->font()->fontFace(), (FT_ULong) params->character())); + + if(params->glyphIndex() == 0) + params->setGlyphIndex(FT_Get_Char_Index(params->font()->fontFace(), '?')); + + // 2. Load glyph into font's glyphSlot, according to the GlyphLayoutParams + int flags = FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP; + + // 3. Don't pass FT_LOAD_VERTICAL_LAYOUT on TTB layouts when rendering + // a latin glyph because it needs to be rotated... + if(params->layout()->tb()) + { + Script script; + SCRIPT_FOR_CHAR(script, params->character()) + if(script != Latin || params->layout()->glyphOrientationVertical() == 0) + flags |= FT_LOAD_VERTICAL_LAYOUT; + } + + FT_Error error = FT_Load_Glyph(params->font()->fontFace(), params->glyphIndex(), flags); + if(error) + params->setGlyphIndex(0); +} + +SharedGlyph Converter::calcGlyph(const GlyphRenderParams *params, Affine &affine, bool onlyLatin) +{ + // 2. Apply kerning if needed + if(m_kerning && params->lastGlyph() != 0 && params->glyphIndex() != 0) + { + FT_Vector kerningVector; + double kx, ky; + + FT_Get_Kerning(params->font()->fontFace(), params->lastGlyph(), params->glyphIndex(), ft_kerning_default, &kerningVector); + + kx = FT_TRUNC(kerningVector.x); + ky = FT_TRUNC(kerningVector.y); + + affine.dx() += kx + affine.m21() * ky; + + // Only apply y kerning in TB mode + if(params->layout()->tb()) + affine.dy() += kx + affine.m22() * ky; + } + + // 3. Prepare path tracing + FT_OutlineGlyph ftGlyph; + FT_Get_Glyph(params->font()->fontFace()->glyph, reinterpret_cast<FT_Glyph *>(&ftGlyph)); + + // 3a. Prepare tracing matrix + Affine traceAffine; + traceAffine.scale(1000.0 / params->font()->fontFace()->units_per_EM); + + // 3b. Enable character rotation, if needed + if(params->layout()->tb()) + { + Script script; + SCRIPT_FOR_CHAR(script, params->character()) + if(!onlyLatin && script == Latin) + { + FT_Matrix matrix; + + double angle = deg2rad * params->layout()->glyphOrientationVertical(); + matrix.xx = (FT_Fixed)( cos(angle) * 0x10000L); + matrix.xy = (FT_Fixed)(-sin(angle) * 0x10000L); + matrix.yx = (FT_Fixed)( sin(angle) * 0x10000L); + matrix.yy = (FT_Fixed)( cos(angle) * 0x10000L); + + FT_Glyph_Transform(reinterpret_cast<FT_Glyph>(ftGlyph), &matrix, 0); + } + } + + // 4. Begin path tracing + // - Setup glyphOutlineing glyph + // - Start tracing + // - Close path + FT_Outline *ftOut = &ftGlyph->outline; + + SharedGlyph glyphOutline(new Glyph()); + glyphOutline->setBezierPath(m_glyphTracer->allocBezierPath(ftOut->n_points * 2 + ftOut->n_contours + 1)); + glyphOutline->setAffine(traceAffine); + + FT_Outline_Decompose(ftOut, m_glyphTracer->outlineFuncs(), glyphOutline.get()); + + m_glyphTracer->closePath(glyphOutline.get()); + + // 5. Determine bounding box (aka "cbox") + FT_Glyph_Get_CBox(reinterpret_cast<FT_Glyph>(ftGlyph), ft_glyph_bbox_unscaled, glyphOutline->ftBbox()); + + // 6. Cache glyph! + m_glyphCache.insert(cacheGlyphKey(params), glyphOutline); + + FT_Done_Glyph(reinterpret_cast<FT_Glyph>(ftGlyph)); + + return glyphOutline; +} + +GlyphSet *Converter::calcString(Font *font, const unsigned short *text, unsigned int length, Affine &affine, const GlyphLayoutParams *params, BezierPath *bpath) +{ + unsigned short *bidi = 0; + + // 0. Apply BiDi Rules + if(params->useBidi()) + { + FriBidiCharType baseDir = FRIBIDI_TYPE_N; + FriBidiChar *unicodeIn = new FriBidiChar[length + 1]; + FriBidiChar *unicodeOut = new FriBidiChar[length + 1]; + bidi = new unsigned short[length + 1]; + + for(unsigned int i = 0; i < length; i++) + unicodeIn[i] = text[i]; + + fribidi_log2vis(unicodeIn, length, &baseDir, unicodeOut, 0, 0, 0); + + for(unsigned int i = 0; i < length; i++) + bidi[i] = unicodeOut[i]; + + bidi[length] = 0; + delete []unicodeIn; + delete []unicodeOut; + } + else + bidi = const_cast<unsigned short *>(text); + + // Detect character rotation if needed, + // probably working in 0.1% of the cases :/ + Script script; + bool onlyLatin = true; + for(unsigned int i = 0; i < length; i++) + { + SCRIPT_FOR_CHAR(script, bidi[i]) + if(script != Latin) + { + onlyLatin = false; + break; + } + } + + // 1. Set initial font size + double fontSize = font->fontParams()->size(); + FT_Set_Char_Size(font->fontFace(), FT_FROMFLOAT(fontSize), FT_FROMFLOAT(fontSize), 0, 0); + + // 2. Compute positioning metrics + // - See http://www.freetype.org/freetype2/docs/tutorial/stepX.html (X = 1 or 2) + int pixelHeight = (int) (FT_TOFLOAT(font->fontFace()->size->metrics.ascender - font->fontFace()->size->metrics.descender) * affine.m22()); + int pixelBaseline = (int) (FT_TOFLOAT(font->fontFace()->size->metrics.ascender) * affine.m22()); + int pixelUnderlinePosition = (int) (((font->fontFace()->ascender - font->fontFace()->underline_position - font->fontFace()->underline_thickness / 2) * fontSize / font->fontFace()->units_per_EM) * affine.m22()); + int pixelUnderlineThickness = T2PMAX(1, (int) ((font->fontFace()->underline_thickness * fontSize / font->fontFace()->units_per_EM) * affine.m22())); + + // 3. Prepare needed variables for the rendering loop + // - rendering params (layout, font...) + // - bounding box (per glyph, overall) + // - glyph matrix (overall) + // - resulting glyph sets + GlyphRenderParams *renderParams = new GlyphRenderParams(); + renderParams->setFont(font); + renderParams->setLayout(params); + renderParams->setLastGlyph(0); + renderParams->setGlyphIndex(0); + + Affine glyphAffine(affine); + Rectangle bbox, currentBbox; + GlyphSet *result = new GlyphSet(); + + // Align to path start, if bpath != 0 + Point pathPoint, pathTangent, pathNormal; + double pathLength = 0, pathAdvance = 0; + double startOffset = params->textPathStartOffset(); + + if(bpath) + { + pathLength = bpath->length(); + bpath->pointTangentNormalAt(startOffset, &pathPoint, &pathTangent); + + glyphAffine.dx() = pathPoint.x(); + glyphAffine.dy() = pathPoint.y(); + glyphAffine.rotate(atan2(pathTangent.y(), pathTangent.x())); + + std::cout << "[T2P] Starting textPath at: " << pathPoint.x() << ", " << pathPoint.y() << std::endl; + } + + // <tspan> elements can have different baseline-shift's + // baseline-shift support (Niko) + double baseline = 0; + if(!params->baselineShift().empty()) + { + if(params->baselineShift() == "sub") + baseline += fontSize / 5 + 1; + else if(params->baselineShift() == "super") + baseline -= fontSize / 3 + 1; + else + { + std::string temp = params->baselineShift(); + if(temp.find("%") > 0) + baseline -= (atof(temp.c_str()) / 100.0) * fontSize; + else + baseline -= atoi(temp.c_str()); + } + + if(!params->tb()) + glyphAffine.translate(0, baseline); + else + glyphAffine.translate(-baseline, 0); + } + + // 4. Enter main rendering loop + for(unsigned int i = 0; i < length; i++) + { + // 4a. Modify character to render + renderParams->setCharacter(bidi[i]); + + // 4c. Get glyph outline + GlyphAffinePair *glyphOutline = requestGlyph(renderParams, currentBbox, glyphAffine, onlyLatin); + m_glyphTracer->correctGlyph(glyphOutline); + + // 4d. Save advance values + result->m_glyphXAdvance.push_back((font->fontFace()->glyph->advance.x * fontSize / font->fontFace()->units_per_EM) * affine.m11()); + result->m_glyphYAdvance.push_back((font->fontFace()->glyph->advance.y * fontSize / font->fontFace()->units_per_EM) * affine.m22()); + + // 4e. Misc + // - union current + overall bounding box + // - add glyph to list of glyphs + // - apply letter & word spacing + if(renderParams->glyphIndex() != 0) + { + // Remember last glyph for kerning + renderParams->setLastGlyph(renderParams->glyphIndex()); + + // Union current + overall bounding box + bbox.bboxUnion(bbox, currentBbox); + + // Move glyph locations for the next glyph to be + // rendered apply letter & word spacing + bool addGlyph = true; + if(!params->tb()) + { + if(bpath) + { + double advance = startOffset + (pathAdvance / pathLength); + if(advance < 0.0 || advance > 1.0) // dont render off-path glyphs + addGlyph = false; + + pathAdvance += (result->m_glyphXAdvance.back() + params->letterSpacing() * affine.m11()) + ((bidi[(i + 1)] == ' ') ? params->wordSpacing() * affine.m11() : 0); + + std::cout << "[T2P] Adjusting textPath advance: " << pathAdvance << " Path Length: " << pathLength << " StartOffset: " << startOffset << " Position in Path (relative 0-1): " << pathAdvance/pathLength << " Adjusted by offset: " << startOffset + (pathAdvance / pathLength) << std::endl; + + bpath->pointTangentNormalAt(startOffset + (pathAdvance / pathLength), &pathPoint, &pathTangent, &pathNormal); + + glyphAffine.m11() = affine.m11(); + glyphAffine.m12() = affine.m12(); + glyphAffine.m21() = affine.m21(); + glyphAffine.m22() = affine.m22(); + glyphAffine.dx() = pathPoint.x(); + glyphAffine.dy() = pathPoint.y(); + + glyphAffine.rotateAround(atan2(pathTangent.y(), pathTangent.x()), Point(result->m_glyphXAdvance.back() / 2, result->m_glyphYAdvance.back() / 2)); + + std::cout << "[T2P] Aligning textPath to: " << pathPoint.x() << ", " << pathPoint.y() << std::endl; + if(!params->tb()) + glyphAffine.translate(0, baseline); + else + glyphAffine.translate(-baseline, 0); + } + else + glyphAffine.dx() += (result->m_glyphXAdvance.back() + params->letterSpacing() * affine.m11()) + ((bidi[(i + 1)] == ' ') ? params->wordSpacing() * affine.m11() : 0); + } + else + { + double advy = result->m_glyphYAdvance.back(); + + Script script; + SCRIPT_FOR_CHAR(script, bidi[i]) + if(!onlyLatin && script == Latin && params->glyphOrientationVertical() != 0) + advy = result->m_glyphXAdvance.back(); + + glyphAffine.dy() += (advy + params->letterSpacing() * affine.m22()) + ((bidi[(i + 1)] == ' ') ? params->wordSpacing() * affine.m22() : 0); + } + + // Copy bezier path/affine pair + if(addGlyph) + { + result->m_set.push_back(glyphOutline); + result->m_glyphCount++; + } + else + delete glyphOutline; + } + } + + // 5. Fill out resulting data structures + result->m_underlinePosition = pixelUnderlinePosition; + result->m_overlinePosition = pixelHeight - pixelUnderlinePosition; + result->m_strikeThroughPosition = (result->m_underlinePosition + result->m_overlinePosition) / 2; + result->m_pixelBaseline = pixelBaseline; + result->m_underlineThickness = pixelUnderlineThickness; + + result->m_xpen = glyphAffine.dx() - affine.dx(); + result->m_ypen = glyphAffine.dy() - affine.dy(); + + result->m_bboxX = T2PMAX(1, int(bbox.a().x())); + result->m_bboxY = T2PMAX(1, int(bbox.a().y() - int(pixelHeight / 2))); + result->m_height = T2PMAX(1, int(bbox.b().y() - bbox.a().y())); + + // Correct bounding box information also on + // vertical layouts! (Niko) + if(!params->tb()) + { + if(bpath) + result->m_width = int(pathAdvance); + else + result->m_width = T2PMAX(1, int(bbox.b().x() - bbox.a().x())); + } + else + result->m_width = T2PMAX(1, pixelHeight); + + // 6. Cleanup memory + if(text != bidi) + delete []bidi; + + delete renderParams; + + // 7. Eventually, dump cache statistics + // m_glyphCache.dump(); + // m_fontCache.dump(); + + return result; +} + +std::string Converter::cacheFontKey(const FontVisualParams *params) const +{ + // TODO: Tune the key + std::string key; + + key += Tools::joinList('|', const_cast<FontVisualParams *>(params)->fontList()); + key += Tools::a2str(params->weight()); + key += Tools::a2str(params->slant()); + key += Tools::a2str(params->size()); + + // std::cout << "Font cache key: " << key << std::endl; + return key; +} + +std::string Converter::cacheGlyphKey(const GlyphRenderParams *params) const +{ + // TODO: Tune the key + std::string key; + + key += params->font()->fontFile(); + key += Tools::a2str(params->character()); + key += Tools::a2str(params->glyphIndex()); + key += Tools::a2str(params->font()->fontParams()->size()); + key += Tools::a2str(params->font()->fontParams()->weight()); + key += Tools::a2str(params->font()->fontParams()->slant()); + + // std::cout << "Glyph cache key: " << key << std::endl; + return key; +} +// vim:ts=4:noet diff --git a/ksvg/impl/libs/libtext2path/src/Converter.h b/ksvg/impl/libs/libtext2path/src/Converter.h new file mode 100644 index 00000000..d6e19521 --- /dev/null +++ b/ksvg/impl/libs/libtext2path/src/Converter.h @@ -0,0 +1,94 @@ +/* + Copyright (C) 2003 Nikolas Zimmermann <wildfox@kde.org> + This file is part of the KDE project + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + aint with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef T2P_CONVERTER_H +#define T2P_CONVERTER_H + +#include "Cache.h" + +// FreeType 2 includes +#include <ft2build.h> +#include FT_FREETYPE_H +#include FT_OUTLINE_H +#include FT_GLYPH_H + +namespace T2P +{ + class BezierPath; + + class Font; + class Glyph; + class Affine; + class GlyphSet; + class Rectangle; + class GlyphTracer; + class GlyphAffinePair; + class FontVisualParams; + class GlyphLayoutParams; + class GlyphRenderParams; + + typedef myboost::shared_ptr<Font> SharedFont; + typedef myboost::shared_ptr<Glyph> SharedGlyph; + + class Converter + { + public: + Converter(GlyphTracer *tracer); + ~Converter(); + + // Is initialized? + void init(); + bool ready(); + + // Kerning control + void setKerning(bool mode); + + SharedFont requestFont(const FontVisualParams *params); + GlyphAffinePair *requestGlyph(GlyphRenderParams *params, Rectangle &bbox, Affine &affine, bool onlyLatin); + + GlyphSet *calcString(Font *font, const unsigned short *text, unsigned int length, Affine &affine, const GlyphLayoutParams *params, BezierPath *bpath = 0); + SharedGlyph calcGlyph(const GlyphRenderParams *params, Affine &affine, bool onlyLatin); + + void selectGlyph(GlyphRenderParams *params); + + protected: + friend class Font; + + // Internal + FT_Library library() { return m_library; } + + private: + std::string cacheFontKey(const FontVisualParams *params) const; + std::string cacheGlyphKey(const GlyphRenderParams *params) const; + + FT_Library m_library; + + GlyphTracer *m_glyphTracer; + + Cache<Glyph> m_glyphCache; + Cache<Font> m_fontCache; + + bool m_init, m_kerning; + }; +} + +#endif + +// vim:ts=4:noet diff --git a/ksvg/impl/libs/libtext2path/src/Font.cpp b/ksvg/impl/libs/libtext2path/src/Font.cpp new file mode 100644 index 00000000..1d6f7005 --- /dev/null +++ b/ksvg/impl/libs/libtext2path/src/Font.cpp @@ -0,0 +1,252 @@ +/* + Copyright (C) 2003 Nikolas Zimmermann <wildfox@kde.org> + This file is part of the KDE project + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + aint with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include <math.h> +#include <iostream> +#include <fontconfig/fontconfig.h> + +#include "Font.h" +#include "Tools.h" +#include "Converter.h" + +// Macros +#define FT_TRUNC(x) ((x) >> 6) +#define FT_TOFLOAT(x) ((x) * (1.0 / 64.0)) +#define FT_FROMFLOAT(x) ((int) floor ((x) * 64.0 + 0.5)) + +using namespace T2P; + +FontVisualParams::FontVisualParams() +{ + m_size = 0.0; + m_slant = 0; + m_weight = 0; +} + +FontVisualParams::FontVisualParams(const FontVisualParams &other) +{ + (*this) = other; +} + +FontVisualParams::~FontVisualParams() +{ +} + +FontVisualParams &FontVisualParams::operator=(const FontVisualParams &other) +{ + m_size = other.m_size; + m_slant = other.m_slant; + m_weight = other.m_weight; + m_fontList = other.m_fontList; + + return *this; +} + +void FontVisualParams::setWeight(int weight) +{ + m_weight = weight; +} + +int FontVisualParams::weight() const +{ + return m_weight; +} + +void FontVisualParams::setSlant(int slant) +{ + m_slant = slant; +} + +int FontVisualParams::slant() const +{ + return m_slant; +} + +void FontVisualParams::setSize(double size) +{ + m_size = size; +} + +double FontVisualParams::size() const +{ + return m_size; +} + +std::list<std::string> &FontVisualParams::fontList() +{ + return m_fontList; +} + +// ##### + +Font::Font(Converter *context) : m_context(context) +{ + m_ready = false; + + m_fontFace = 0; + m_fontParams = 0; +} + +Font::~Font() +{ + // Release font face + if(m_ready && m_fontFace) + { + // FIXME: Debug that! + //std::cout << "CALLING DONE FACE " << m_fontFace << std::endl; + FT_Done_Face(m_fontFace); + } + + delete m_fontParams; +} + +std::string Font::buildRequest(const FontVisualParams *fontParams, int &id) +{ + // Use FontConfig to locate & select fonts and use + // FreeType2 to open them + FcPattern *pattern; + std::string fileName; + + pattern = FcPatternBuild(0, + FC_WEIGHT, FcTypeInteger, fontParams->weight(), + FC_SLANT, FcTypeInteger, fontParams->slant(), + FC_SIZE, FcTypeDouble, fontParams->size(), + NULL); + + // Add multiple font names + std::list<std::string> &fontList = const_cast<FontVisualParams *>(fontParams)->fontList(); + + for(std::list<std::string>::const_iterator it = fontList.begin(); it != fontList.end(); ++it) + { + std::string string = *it; + + if(!string.empty()) + FcPatternAddString(pattern, FC_FAMILY, reinterpret_cast<const FcChar8 *>(string.c_str())); + } + + // Always load vertical layout + FcPatternAddBool(pattern, FC_VERTICAL_LAYOUT, true); + + // Disable hinting + FcPatternAddBool(pattern, FC_HINTING, false); + + // Perform the default font pattern modification operations. + FcDefaultSubstitute(pattern); + FcConfigSubstitute(FcConfigGetCurrent(), pattern, FcMatchPattern); + + // Match the pattern! + FcResult result; + FcPattern *match = FcFontMatch(0, pattern, &result); + + // Destroy pattern + FcPatternDestroy(pattern); + + // Get index & filename + FcChar8 *temp; + + if(match) + { + FcPattern *pattern = FcPatternDuplicate(match); + + // Get index & filename + if(FcPatternGetString(pattern, FC_FILE, 0, &temp) != FcResultMatch || + FcPatternGetInteger(pattern, FC_INDEX, 0, &id) != FcResultMatch) + { + std::cout << "Font::buildRequest(), could not load font file for requested font \"" << Tools::joinList('|', fontList) << "\"" << std::endl; + return fileName; + } + + fileName = reinterpret_cast<const char *>(temp); + + // Kill pattern + FcPatternDestroy(pattern); + } + + // Kill pattern + FcPatternDestroy(match); + + return fileName; +} + +bool Font::load(const FontVisualParams *fontParams) +{ + // Build FontConfig request pattern + int id = -1; + std::string filename = Font::buildRequest(fontParams, id); + + // Load font directly using FreeType2 + std::cout << "Font::load(), loading " << filename << " for requested font \"" << Tools::joinList('|', const_cast<FontVisualParams *>(fontParams)->fontList()) << "\"" << std::endl; + + FT_Error error = FT_New_Face(m_context->library(), filename.c_str(), id, &m_fontFace); + if(error) + { + std::cout << "Font::load(), could not load font. Aborting!" << std::endl; + return false; + } + if(!FT_IS_SCALABLE(m_fontFace)) + { + std::cout << "Font::load(), font does not contain outlines. Aborting!" << std::endl; + FT_Done_Face(m_fontFace); + m_fontFace = 0; + return false; + } + + // Choose unicode charmap + for(int charmap = 0; charmap < m_fontFace->num_charmaps; charmap++) + { + if(m_fontFace->charmaps[charmap]->encoding == ft_encoding_unicode) + { + FT_Error error = FT_Set_Charmap(m_fontFace, m_fontFace->charmaps[charmap]); + + if(error) + { + std::cout << "Font::load(), unable to select unicode charmap. Aborting!" << std::endl; + + FT_Done_Face(m_fontFace); + m_fontFace = 0; + + return false; + } + } + } + + m_fontParams = fontParams; + m_fontFile = filename; + m_ready = true; + + return true; +} + +FT_Face &Font::fontFace() +{ + return m_fontFace; +} + +std::string Font::fontFile() const +{ + return m_fontFile; +} + +const FontVisualParams *Font::fontParams() const +{ + return m_fontParams; +} + +// vim:ts=4:noet diff --git a/ksvg/impl/libs/libtext2path/src/Font.h b/ksvg/impl/libs/libtext2path/src/Font.h new file mode 100644 index 00000000..72844285 --- /dev/null +++ b/ksvg/impl/libs/libtext2path/src/Font.h @@ -0,0 +1,91 @@ +/* + Copyright (C) 2003 Nikolas Zimmermann <wildfox@kde.org> + This file is part of the KDE project + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + aint with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef T2P_FONT_H +#define T2P_FONT_H + +#include <list> +#include <string> + +// FreeType 2 includes +#include <ft2build.h> +#include FT_FREETYPE_H + +namespace T2P +{ + class Converter; + + class FontVisualParams + { + public: + FontVisualParams(); + FontVisualParams(const FontVisualParams &other); + ~FontVisualParams(); + + FontVisualParams &operator=(const FontVisualParams &other); + + void setWeight(int weight); + int weight() const; + + void setSlant(int slant); + int slant() const; + + void setSize(double size); + double size() const; + + std::list<std::string> &fontList(); + + private: + int m_weight, m_slant; + double m_size; + + std::list<std::string> m_fontList; + }; + + class Font + { + public: + Font(Converter *context); + ~Font(); + + // Build font loading request for FontConfig + static std::string buildRequest(const FontVisualParams *fontParams, int &id); + + // Load it! :) + bool load(const FontVisualParams *fontParams); + + FT_Face &fontFace(); + std::string fontFile() const; + const FontVisualParams *fontParams() const; + + private: + FT_Face m_fontFace; + std::string m_fontFile; + + Converter *m_context; + const FontVisualParams *m_fontParams; + + bool m_ready; + }; +} + +#endif + +// vim:ts=4:noet diff --git a/ksvg/impl/libs/libtext2path/src/Glyph.cpp b/ksvg/impl/libs/libtext2path/src/Glyph.cpp new file mode 100644 index 00000000..5d172018 --- /dev/null +++ b/ksvg/impl/libs/libtext2path/src/Glyph.cpp @@ -0,0 +1,353 @@ +/* + Copyright (C) 2003 Nikolas Zimmermann <wildfox@kde.org> + This file is part of the KDE project + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + aint with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include <iostream> +#include "Glyph.h" + +using namespace T2P; + +Glyph::Glyph() +{ + m_bezierPath = 0; +} + +Glyph::~Glyph() +{ + delete m_bezierPath; + m_bezierPath = 0; +} + +Affine &Glyph::affine() +{ + return m_affine; +} + +void Glyph::setAffine(const Affine &affine) +{ + m_affine = affine; +} + +const BezierPath *Glyph::bezierPath() const +{ + return const_cast<const BezierPath *>(m_bezierPath); +} + +BezierPath *Glyph::modifiableBezierPath() +{ + return m_bezierPath; +} + +void Glyph::setBezierPath(const BezierPath *bpath) +{ + m_bezierPath = const_cast<BezierPath *>(bpath); +} + +FT_BBox *Glyph::ftBbox() +{ + return m_ftBbox; +} + +// ##### + +GlyphAffinePair::GlyphAffinePair(const Glyph *glyph, const Affine &affine) +{ + m_glyph = glyph; + m_affine = affine; + m_transformatedPath = 0; +} + +GlyphAffinePair::~GlyphAffinePair() +{ + // The glyphs are shared and thus not deleted (Niko) + delete m_transformatedPath; +} + +void GlyphAffinePair::setTransformatedPath(const BezierPath *path) +{ + m_transformatedPath = path; +} + +const BezierPath *GlyphAffinePair::transformatedPath() const +{ + return m_transformatedPath; +} + +const Glyph *GlyphAffinePair::glyph() const +{ + return m_glyph; +} + +Affine &GlyphAffinePair::affine() +{ + return m_affine; +} + +// ##### + +GlyphSet::GlyphSet() +{ + m_glyphCount = 0; + + m_bboxX = 0; + m_bboxY = 0; + m_width = 0; + m_height = 0; + + m_xpen = 0; + m_ypen = 0; + + m_underlinePosition = 0; + m_underlineThickness = 0; + m_overlinePosition = 0; + m_strikeThroughPosition = 0; + m_pixelBaseline = 0; +} + +GlyphSet::~GlyphSet() +{ + m_set.clear(); +} + +std::vector<GlyphAffinePair *> &GlyphSet::set() +{ + return m_set; +} + +std::list<float> GlyphSet::glyphXAdvance() +{ + return m_glyphXAdvance; +} + +std::list<float> GlyphSet::glyphYAdvance() +{ + return m_glyphYAdvance; +} + +unsigned int GlyphSet::glyphCount() const +{ + return m_glyphCount; +} + +int GlyphSet::width() const +{ + return m_width; +} + +int GlyphSet::height() const +{ + return m_height; +} + +int GlyphSet::bboxX() const +{ + return m_bboxX; +} + +int GlyphSet::bboxY() const +{ + return m_bboxY; +} + +double GlyphSet::xpen() const +{ + return m_xpen; +} + +double GlyphSet::ypen() const +{ + return m_ypen; +} + +int GlyphSet::underlinePosition() const +{ + return m_underlinePosition; +} + +int GlyphSet::underlineThickness() const +{ + return m_underlineThickness; +} + +int GlyphSet::overlinePosition() const +{ + return m_overlinePosition; +} + +int GlyphSet::strikeThroughPosition() const +{ + return m_strikeThroughPosition; +} + +int GlyphSet::pixelBaseline() const +{ + return m_pixelBaseline; +} + +// ##### + +GlyphLayoutParams::GlyphLayoutParams() +{ +} + +GlyphLayoutParams::~GlyphLayoutParams() +{ +} + +bool GlyphLayoutParams::tb() const +{ + return m_tb; +} + +void GlyphLayoutParams::setTb(bool tb) +{ + m_tb = tb; +} + +bool GlyphLayoutParams::useBidi() const +{ + return m_useBidi; +} + +void GlyphLayoutParams::setUseBidi(bool bidi) +{ + m_useBidi = bidi; +} + +double GlyphLayoutParams::wordSpacing() const +{ + return m_wordSpacing; +} + +void GlyphLayoutParams::setWordSpacing(double wordSpacing) +{ + m_wordSpacing = wordSpacing; +} + +double GlyphLayoutParams::letterSpacing() const +{ + return m_letterSpacing; +} + +void GlyphLayoutParams::setLetterSpacing(double letterSpacing) +{ + m_letterSpacing = letterSpacing; +} + +std::string GlyphLayoutParams::baselineShift() const +{ + return m_baseline; +} + +void GlyphLayoutParams::setBaselineShift(const std::string &baseline) +{ + m_baseline = baseline; +} + +int GlyphLayoutParams::glyphOrientationVertical() const +{ + return m_glyphOrientationVertical; +} + +void GlyphLayoutParams::setGlyphOrientationVertical(int orient) +{ + m_glyphOrientationVertical = orient; +} + +int GlyphLayoutParams::glyphOrientationHorizontal() const +{ + return m_glyphOrientationHorizontal; +} + +void GlyphLayoutParams::setGlyphOrientationHorizontal(int orient) +{ + m_glyphOrientationHorizontal = orient; +} + +double GlyphLayoutParams::textPathStartOffset() const +{ + return m_textPathStartOffset; +} + +void GlyphLayoutParams::setTextPathStartOffset(double offset) +{ + m_textPathStartOffset = offset; +} + +// ##### + +GlyphRenderParams::GlyphRenderParams() +{ +} + +GlyphRenderParams::~GlyphRenderParams() +{ +} + +Font *GlyphRenderParams::font() const +{ + return m_font; +} + +void GlyphRenderParams::setFont(Font *font) +{ + m_font = font; +} + +const GlyphLayoutParams *GlyphRenderParams::layout() const +{ + return m_layout; +} + +void GlyphRenderParams::setLayout(const GlyphLayoutParams *layout) +{ + m_layout = layout; +} + +unsigned int GlyphRenderParams::glyphIndex() const +{ + return m_glyphIndex; +} + +void GlyphRenderParams::setGlyphIndex(unsigned int glyphIndex) +{ + m_glyphIndex = glyphIndex; +} + +unsigned int GlyphRenderParams::lastGlyph() const +{ + return m_lastGlyph; +} + +void GlyphRenderParams::setLastGlyph(unsigned int lastGlyph) +{ + m_lastGlyph = lastGlyph; +} + +unsigned short GlyphRenderParams::character() const +{ + return m_character; +} + +void GlyphRenderParams::setCharacter(unsigned short character) +{ + m_character = character; +} + +// vim:ts=4:noet diff --git a/ksvg/impl/libs/libtext2path/src/Glyph.h b/ksvg/impl/libs/libtext2path/src/Glyph.h new file mode 100644 index 00000000..b3bd3fb5 --- /dev/null +++ b/ksvg/impl/libs/libtext2path/src/Glyph.h @@ -0,0 +1,198 @@ +/* + Copyright (C) 2003 Nikolas Zimmermann <wildfox@kde.org> + This file is part of the KDE project + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + aint with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef T2P_GLYPH_H +#define T2P_GLYPH_H + +#include <list> +#include <vector> +#include <string> + +#include "Affine.h" +#include "BezierPath.h" + +// FreeType 2 includes +#include <ft2build.h> +#include FT_FREETYPE_H + +namespace T2P +{ + class Font; + + // Represent one single glyph in cache + class Glyph + { + public: + Glyph(); + ~Glyph(); + + Affine &affine(); // Initial tracing affine + void setAffine(const Affine &affine); + + const BezierPath *bezierPath() const; // Non-modifyable bezierPath belonging to this glyph + BezierPath *modifiableBezierPath(); // ONLY USED BY GLYPHTRACER, DO NOT USE SOMEWHERE ELSE! + void setBezierPath(const BezierPath *bpath); + + FT_BBox *ftBbox(); + + private: + Affine m_affine; + FT_BBox m_ftBbox[4]; + BezierPath *m_bezierPath; + }; + + // Is created for every character which needs to + // be rendered and has to be deleted by the "client" + class GlyphAffinePair + { + public: + GlyphAffinePair(const Glyph *glyph, const Affine &affine); + ~GlyphAffinePair(); + + void setTransformatedPath(const BezierPath *path); + const BezierPath *transformatedPath() const; + + const Glyph *glyph() const; + Affine &affine(); + + private: + const Glyph *m_glyph; + const BezierPath *m_transformatedPath; + Affine m_affine; + }; + + class GlyphSet + { + public: + GlyphSet(); + ~GlyphSet(); + + std::vector<GlyphAffinePair *> &set(); + std::list<float> glyphXAdvance(); + std::list<float> glyphYAdvance(); + + unsigned int glyphCount() const; + + int width() const; + int height() const; + + int bboxX() const; + int bboxY() const; + + double xpen() const; + double ypen() const; + + int underlinePosition() const; + int underlineThickness() const; + int overlinePosition() const; + int strikeThroughPosition() const; + int pixelBaseline() const; + + private: + friend class Converter; + unsigned int m_glyphCount; // Number of glyphs in the set + + int m_bboxX, m_bboxY; // Bounding box locations (x,y) + (x + width, y + width) + int m_width, m_height; + + double m_xpen, m_ypen; // relative pen locations + + int m_underlinePosition, m_underlineThickness, m_overlinePosition, m_strikeThroughPosition, m_pixelBaseline; + + std::vector<GlyphAffinePair *> m_set; // Bezier paths in the set + + std::list<float> m_glyphXAdvance; // List of advance values needed ie. for text paths + std::list<float> m_glyphYAdvance; + }; + + class GlyphLayoutParams + { + public: + GlyphLayoutParams(); + ~GlyphLayoutParams(); + + bool tb() const; + void setTb(bool tb); + + bool useBidi() const; + void setUseBidi(bool bidi); + + double wordSpacing() const; + void setWordSpacing(double wordSpacing); + + double letterSpacing() const; + void setLetterSpacing(double letterSpacing); + + std::string baselineShift() const; + void setBaselineShift(const std::string &baseline); + + int glyphOrientationVertical() const; + void setGlyphOrientationVertical(int orient); + + int glyphOrientationHorizontal() const; + void setGlyphOrientationHorizontal(int orient); + + // textOnPath specific stuff + double textPathStartOffset() const; + void setTextPathStartOffset(double offset); + + private: + bool m_tb; // Top-To-Bottom or Bottom-To-Top ? + bool m_useBidi; // Use Bidi ? + double m_wordSpacing, m_letterSpacing; // word/character spacing + double m_textPathStartOffset; // range: 0.0 - 1.0; start offset in the path + int m_glyphOrientationVertical, m_glyphOrientationHorizontal; // Degrees... + std::string m_baseline; // baseline description, using same system as svg + }; + + class GlyphRenderParams + { + public: + GlyphRenderParams(); + ~GlyphRenderParams(); + + Font *font() const; + void setFont(Font *font); + + const GlyphLayoutParams *layout() const; + void setLayout(const GlyphLayoutParams *layout); + + unsigned int glyphIndex() const; + void setGlyphIndex(unsigned int glyphIndex); + + unsigned int lastGlyph() const; + void setLastGlyph(unsigned int lastGlyph); + + unsigned short character() const; + void setCharacter(unsigned short character); + + private: + Font *m_font; + const GlyphLayoutParams *m_layout; // Glyph layouting params + + unsigned int m_glyphIndex; // 'character' index in font + unsigned int m_lastGlyph; // Kerning + unsigned short m_character; // Unicode glyph to process + }; +} + +#endif + +// vim:ts=4:noet diff --git a/ksvg/impl/libs/libtext2path/src/GlyphTracer.cpp b/ksvg/impl/libs/libtext2path/src/GlyphTracer.cpp new file mode 100644 index 00000000..42457553 --- /dev/null +++ b/ksvg/impl/libs/libtext2path/src/GlyphTracer.cpp @@ -0,0 +1,76 @@ +/* + Copyright (C) 2003 Nikolas Zimmermann <wildfox@kde.org> + This file is part of the KDE project + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + aint with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "GlyphTracer.h" + +using namespace T2P; + +GlyphTracer::GlyphTracer() +{ + m_moveTo = 0; + m_lineTo = 0; + m_conicBezier = 0; + m_cubicBezier = 0; + m_outlineMethods = 0; +} + +GlyphTracer::~GlyphTracer() +{ + delete m_outlineMethods; +} + +void GlyphTracer::setMoveto(FT_Outline_MoveToFunc funcPtr) +{ + m_moveTo = funcPtr; +} + +void GlyphTracer::setLineto(FT_Outline_LineToFunc funcPtr) +{ + m_lineTo = funcPtr; +} + +void GlyphTracer::setConicBezier(FT_Outline_ConicToFunc funcPtr) +{ + m_conicBezier = funcPtr; +} + +void GlyphTracer::setCubicBezier(FT_Outline_CubicToFunc funcPtr) +{ + m_cubicBezier = funcPtr; +} + +FT_Outline_Funcs *GlyphTracer::outlineFuncs() +{ + if(m_outlineMethods) + return m_outlineMethods; + + FT_Outline_Funcs *ret = new FT_Outline_Funcs(); + ret->move_to = m_moveTo; + ret->line_to = m_lineTo; + ret->conic_to = m_conicBezier; + ret->cubic_to = m_cubicBezier; + ret->shift = 0; + ret->delta = 0; + + m_outlineMethods = ret; + return m_outlineMethods; +} + +// vim:ts=4:noet diff --git a/ksvg/impl/libs/libtext2path/src/GlyphTracer.h b/ksvg/impl/libs/libtext2path/src/GlyphTracer.h new file mode 100644 index 00000000..7607ecad --- /dev/null +++ b/ksvg/impl/libs/libtext2path/src/GlyphTracer.h @@ -0,0 +1,65 @@ +/* + Copyright (C) 2003 Nikolas Zimmermann <wildfox@kde.org> + This file is part of the KDE project + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + aint with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef T2P_GLYPHTRACER_H +#define T2P_GLYPHTRACER_H + +// FreeType 2 includes +#include <ft2build.h> +#include FT_FREETYPE_H + +namespace T2P +{ + class Glyph; + class BezierPath; + class GlyphAffinePair; + + class GlyphTracer + { + public: + GlyphTracer(); + virtual ~GlyphTracer(); + + // Needs to be implemented + virtual void correctGlyph(GlyphAffinePair *glyphAffine) = 0; + virtual BezierPath *allocBezierPath(int size) = 0; + virtual void closePath(Glyph *glyph) = 0; + + // FreeType glyph tracing functions + void setMoveto(FT_Outline_MoveToFunc funcPtr); + void setLineto(FT_Outline_LineToFunc funcPtr); + void setConicBezier(FT_Outline_ConicToFunc funcPtr); + void setCubicBezier(FT_Outline_CubicToFunc funcPtr); + + FT_Outline_Funcs *outlineFuncs(); + + private: + FT_Outline_Funcs *m_outlineMethods; + + FT_Outline_MoveToFunc m_moveTo; + FT_Outline_LineToFunc m_lineTo; + FT_Outline_ConicToFunc m_conicBezier; + FT_Outline_CubicToFunc m_cubicBezier; + }; +} + +#endif + +// vim:ts=4:noet diff --git a/ksvg/impl/libs/libtext2path/src/Makefile.am b/ksvg/impl/libs/libtext2path/src/Makefile.am new file mode 100644 index 00000000..175e1a91 --- /dev/null +++ b/ksvg/impl/libs/libtext2path/src/Makefile.am @@ -0,0 +1,10 @@ +lib_LTLIBRARIES = libtext2path.la + +KDE_CXXFLAGS = $(USE_EXCEPTIONS) +INCLUDES = $(FRIBIDI_CFLAGS) $(FREETYPE_CFLAGS) $(FONTCONFIG_CFLAGS) $(all_includes) + +libtext2path_includedir=$(includedir)/libtext2path-0.1 +libtext2path_include_HEADERS = BezierPath.h Glyph.h GlyphTracer.h + +libtext2path_la_SOURCES = Affine.cpp Rectangle.cpp Font.cpp Glyph.cpp GlyphTracer.cpp Converter.cpp QtUnicode.cpp +libtext2path_la_LDFLAGS = $(FRIBIDI_LIBS) $(FONTCONFIG_LIBS) diff --git a/ksvg/impl/libs/libtext2path/src/Point.h b/ksvg/impl/libs/libtext2path/src/Point.h new file mode 100644 index 00000000..d95742a2 --- /dev/null +++ b/ksvg/impl/libs/libtext2path/src/Point.h @@ -0,0 +1,65 @@ +/* + Copyright (C) 2003 Nikolas Zimmermann <wildfox@kde.org> + This file is part of the KDE project + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + aint with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef T2P_POINT_H +#define T2P_POINT_H + +namespace T2P +{ + class Point + { + public: + Point() { m_x = 0.0; m_y = 0.0; } + Point(double x, double y) { m_x = x; m_y = y; } + Point &operator=(const Point &other) { m_x = other.x(); m_y = other.y(); return *this; } + + friend inline Point operator+(const Point &, const Point &); + friend inline Point operator-(const Point &, const Point &); + friend inline Point operator*(const double &, const Point &); + friend inline Point operator*(const Point &, const double &); + + double x() const { return m_x; } + double y() const { return m_y; } + + void setX(double x) { m_x = x; } + void setY(double y) { m_y = y; } + + const Point invert() const + { + Point temp; + temp.setX(-x()); + temp.setY(-y()); + return temp; + } + + private: + double m_x; + double m_y; + }; + + inline Point operator+(const Point &p1, const Point &p2) { return Point(p1.m_x + p2.m_x, p1.m_y + p2.m_y); } + inline Point operator-(const Point &p1, const Point &p2) { return Point(p1.m_x - p2.m_x, p1.m_y - p2.m_y); } + inline Point operator*(const double &c, const Point &p) { return Point(p.m_x * c, p.m_y * c); } + inline Point operator*(const Point &p, const double &c) { return Point(p.m_x * c, p.m_y * c); } +} + +#endif + +// vim:ts=4:noet diff --git a/ksvg/impl/libs/libtext2path/src/QtUnicode.cpp b/ksvg/impl/libs/libtext2path/src/QtUnicode.cpp new file mode 100644 index 00000000..694ed5c7 --- /dev/null +++ b/ksvg/impl/libs/libtext2path/src/QtUnicode.cpp @@ -0,0 +1,164 @@ +/**************************************************************************** +** +** +** ??? +** +** Copyright (C) 2002-2003 Trolltech AS. All rights reserved. +** +** This file is part of the kernel module of the Qt GUI Toolkit. +** +** This file may be distributed under the terms of the Q Public License +** as defined by Trolltech AS of Norway and appearing in the file +** LICENSE.QPL included in the packaging of this file. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition +** licenses may use this file in accordance with the Qt Commercial License +** Agreement provided with the Software. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for +** information about Qt Commercial License Agreements. +** See http://www.trolltech.com/qpl/ for QPL licensing information. +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#include "QtUnicode.h" + +using namespace T2P; +// START OF GENERATED DATA + +// copied form qfont.h, as we can't include it in tools. Do not modify without +// changing the script enum in qfont.h aswell. +const unsigned char QtUnicode::otherScripts [120] = { +#define SCRIPTS_02 0 + 0xaf, Latin, 0xff, SpacingModifiers, // row 0x02, index 0 +#define SCRIPTS_03 4 + 0x6f, CombiningMarks, 0xff, Greek, // row 0x03, index 4 +#define SCRIPTS_05 8 + 0x2f, Cyrillic, 0x8f, Armenian, 0xff, Hebrew, // row 0x05, index 8 +#define SCRIPTS_07 14 + 0x4f, Syriac, 0x7f, Unicode, 0xbf, Thaana, + 0xff, Unicode, // row 0x07, index 14 +#define SCRIPTS_10 22 + 0x9f, Myanmar, 0xff, Georgian, // row 0x10, index 20 +#define SCRIPTS_13 26 + 0x7f, Ethiopic, 0x9f, Unicode, 0xff, Cherokee, // row 0x13, index 24 +#define SCRIPTS_16 32 + 0x7f, CanadianAboriginal, 0x9f, Ogham, + 0xff, Runic, // row 0x16 index 30 +#define SCRIPTS_17 38 + 0x1f, Tagalog, 0x3f, Hanunoo, 0x5f, Buhid, + 0x7f, Tagbanwa, 0xff, Khmer, // row 0x17, index 36 +#define SCRIPTS_18 48 + 0xaf, Mongolian, 0xff, Unicode, // row 0x18, index 46 +#define SCRIPTS_20 52 + 0x0b, Unicode, 0x0d, UnknownScript, 0x6f, Unicode, 0x9f, NumberForms, + 0xab, CurrencySymbols, 0xac, Latin, + 0xcf, CurrencySymbols, 0xff, CombiningMarks, // row 0x20, index 50 +#define SCRIPTS_21 68 + 0x4f, LetterlikeSymbols, 0x8f, NumberForms, + 0xff, MathematicalOperators, // row 0x21, index 62 +#define SCRIPTS_24 74 + 0x5f, TechnicalSymbols, 0xff, EnclosedAndSquare, // row 0x24, index 68 +#define SCRIPTS_2e 78 + 0x7f, Unicode, 0xff, Han, // row 0x2e, index 72 +#define SCRIPTS_30 82 + 0x3f, Han, 0x9f, Hiragana, 0xff, Katakana, // row 0x30, index 76 +#define SCRIPTS_31 88 + 0x2f, Bopomofo, 0x8f, Hangul, 0x9f, Han, + 0xff, Unicode, // row 0x31, index 82 +#define SCRIPTS_fb 96 + 0x06, Latin, 0x1c, Unicode, 0x4f, Hebrew, + 0xff, Arabic, // row 0xfb, index 90 +#define SCRIPTS_fe 104 + 0x1f, Unicode, 0x2f, CombiningMarks, 0x6f, Unicode, + 0xff, Arabic, // row 0xfe, index 98 +#define SCRIPTS_ff 112 + 0x5e, Katakana, 0x60, Unicode, // row 0xff, index 106 + 0x9f, KatakanaHalfWidth, 0xff, Unicode +}; + +// (uc-0x0900)>>7 +const unsigned char QtUnicode::indicScripts [] = +{ + Devanagari, Bengali, + Gurmukhi, Gujarati, + Oriya, Tamil, + Telugu, Kannada, + Malayalam, Sinhala, + Thai, Lao +}; + + +// 0x80 + x: x is the offset into the otherScripts table +const unsigned char QtUnicode::scriptTable[256] = +{ + Latin, Latin, 0x80+SCRIPTS_02, 0x80+SCRIPTS_03, + Cyrillic, 0x80+SCRIPTS_05, Arabic, 0x80+SCRIPTS_07, + Unicode, SCRIPTS_INDIC, SCRIPTS_INDIC, SCRIPTS_INDIC, + SCRIPTS_INDIC, SCRIPTS_INDIC, SCRIPTS_INDIC, Tibetan, + + 0x80+SCRIPTS_10, Hangul, Ethiopic, 0x80+SCRIPTS_13, + CanadianAboriginal, CanadianAboriginal, 0x80+SCRIPTS_16, 0x80+SCRIPTS_17, + 0x80+SCRIPTS_18, Unicode, Unicode, Unicode, + Unicode, Unicode, Latin, Greek, + + 0x80+SCRIPTS_20, 0x80+SCRIPTS_21, MathematicalOperators, TechnicalSymbols, + 0x80+SCRIPTS_24, GeometricSymbols, MiscellaneousSymbols, MiscellaneousSymbols, + Braille, Unicode, Unicode, Unicode, + Unicode, Unicode, 0x80+SCRIPTS_2e, Han, + + 0x80+SCRIPTS_30, 0x80+SCRIPTS_31, EnclosedAndSquare, EnclosedAndSquare, + Han, Han, Han, Han, + Han, Han, Han, Han, + Han, Han, Han, Han, + + Han, Han, Han, Han, Han, Han, Han, Han, + Han, Han, Han, Han, Han, Han, Han, Han, + + Han, Han, Han, Han, Han, Han, Han, Han, + Han, Han, Han, Han, Han, Han, Han, Han, + + Han, Han, Han, Han, Han, Han, Han, Han, + Han, Han, Han, Han, Han, Han, Han, Han, + + Han, Han, Han, Han, Han, Han, Han, Han, + Han, Han, Han, Han, Han, Han, Han, Han, + + + Han, Han, Han, Han, Han, Han, Han, Han, + Han, Han, Han, Han, Han, Han, Han, Han, + + Han, Han, Han, Han, Han, Han, Han, Han, + Han, Han, Han, Han, Han, Han, Han, Han, + + Yi, Yi, Yi, Yi, Yi, Unicode, Unicode, Unicode, + Unicode, Unicode, Unicode, Unicode, Hangul, Hangul, Hangul, Hangul, + + Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, + Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, + + Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, + Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, + + Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, + Unicode, Unicode, Unicode, Unicode, Unicode, Unicode, Unicode, Unicode, + + Unicode, Unicode, Unicode, Unicode, Unicode, Unicode, Unicode, Unicode, + Unicode, Unicode, Unicode, Unicode, Unicode, Unicode, Unicode, Unicode, + + Unicode, Unicode, Unicode, Unicode, Unicode, Unicode, Unicode, Unicode, + Unicode, Han, Han, 0x80+SCRIPTS_fb, Arabic, Arabic, 0x80+SCRIPTS_fe, 0x80+SCRIPTS_ff +}; + diff --git a/ksvg/impl/libs/libtext2path/src/QtUnicode.h b/ksvg/impl/libs/libtext2path/src/QtUnicode.h new file mode 100644 index 00000000..41008500 --- /dev/null +++ b/ksvg/impl/libs/libtext2path/src/QtUnicode.h @@ -0,0 +1,149 @@ +/* + Copyright (C) 2003 Nikolas Zimmermann <wildfox@kde.org> + This file is part of the KDE project + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + aint with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef T2P_QT_UNICODE_H +#define T2P_QT_UNICODE_H + +namespace T2P +{ + enum Script + { + // European Alphabetic Scripts + Latin, + Greek, + Cyrillic, + Armenian, + Georgian, + Runic, + Ogham, + SpacingModifiers, + CombiningMarks, + + // Middle Eastern Scripts + Hebrew, + Arabic, + Syriac, + Thaana, + + // South and Southeast Asian Scripts + Devanagari, + Bengali, + Gurmukhi, + Gujarati, + Oriya, + Tamil, + Telugu, + Kannada, + Malayalam, + Sinhala, + Thai, + Lao, + Tibetan, + Myanmar, + Khmer, + + // East Asian Scripts + Han, + Hiragana, + Katakana, + Hangul, + Bopomofo, + Yi, + + // Additional Scripts + Ethiopic, + Cherokee, + CanadianAboriginal, + Mongolian, + + // Symbols + CurrencySymbols, + LetterlikeSymbols, + NumberForms, + MathematicalOperators, + TechnicalSymbols, + GeometricSymbols, + MiscellaneousSymbols, + EnclosedAndSquare, + Braille, + + Unicode, + + // some scripts added in Unicode 3.2 + Tagalog, + Hanunoo, + Buhid, + Tagbanwa, + + KatakanaHalfWidth, + + // End + NScripts, + UnknownScript = NScripts + }; + + class QtUnicode + { + public: + QtUnicode() { } + ~QtUnicode() { } + + static int scriptForChar(unsigned short uc) + { + unsigned char script = QtUnicode::scriptTable[(uc >> 8)]; + if(script >= QtUnicode::SCRIPTS_INDIC) + { + if(script == QtUnicode::SCRIPTS_INDIC) + script = QtUnicode::indicScripts[(uc - 0x0900) >> 7]; + else + { + // 0x80 + SCRIPTS_xx + unsigned char index = script - 0x80; + unsigned char cell = uc & 0xff; + while(QtUnicode::otherScripts[index++] < cell) + index++; + script = QtUnicode::otherScripts[index]; + } + } + + return script; + } + + private: + enum + { + SCRIPTS_INDIC = 0x7e + }; + + static const unsigned char otherScripts[]; + static const unsigned char indicScripts[]; + static const unsigned char scriptTable[]; + }; +} + +#define SCRIPT_FOR_CHAR(script, c) \ +if(c < 0x100) \ + script = T2P::Latin; \ +else \ + script = (T2P::Script) QtUnicode::scriptForChar(c); + +#endif + +// vim:ts=4:noet diff --git a/ksvg/impl/libs/libtext2path/src/Rectangle.cpp b/ksvg/impl/libs/libtext2path/src/Rectangle.cpp new file mode 100644 index 00000000..ef59d6be --- /dev/null +++ b/ksvg/impl/libs/libtext2path/src/Rectangle.cpp @@ -0,0 +1,102 @@ +/* + Copyright (C) 2003 Nikolas Zimmermann <wildfox@kde.org> + This file is part of the KDE project + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + aint with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "Tools.h" +#include "Rectangle.h" + +using namespace T2P; + +Rectangle::Rectangle() +{ +} + +Rectangle::Rectangle(const Rectangle &other) +{ + (*this) = other; +} + +Rectangle::Rectangle(const Point &a, const Point &b) : m_a(a), m_b(b) +{ +} + +Rectangle::Rectangle(double x, double y, double width, double height) +{ + m_a = Point(x, y); + m_b = Point(x + width, y + height); +} + +Rectangle::~Rectangle() +{ +} + +Rectangle &Rectangle::operator=(const Rectangle &other) +{ + m_a = other.m_a; + m_b = other.m_b; + + return *this; +} + +Point Rectangle::a() const +{ + return m_a; +} + +void Rectangle::setA(const Point &a) +{ + m_a = a; +} + +Point Rectangle::b() const +{ + return m_b; +} + +void Rectangle::setB(const Point &b) +{ + m_b = b; +} + +void Rectangle::bboxUnion(const Rectangle &src1, const Rectangle &src2) +{ + double src1x0 = src1.a().x(), src1x1 = src1.b().x(); + double src1y0 = src1.a().y(), src1y1 = src1.b().y(); + + double src2x0 = src2.a().x(), src2x1 = src2.b().x(); + double src2y0 = src2.a().y(), src2y1 = src2.b().y(); + + if(src1x1 <= src1x0 || src1y1 <= src1y0) // Is src1 empty? + { // Copy src2 to dst + setA(Point(src2x0, src2y0)); + setB(Point(src2x1, src2y1)); + } + else if(src2x1 <= src2x0 || src2y1 <= src2y0) // Is src2 empty? + { // Copy src1 to dest + setA(Point(src1x0, src1y0)); + setB(Point(src1x1, src1y1)); + } + else + { + setA(Point(T2PMIN(src1x0, src2x0), T2PMIN(src1y0, src2y0))); + setB(Point(T2PMAX(src1x1, src2x1), T2PMAX(src1y1, src2y1))); + } +} + +// vim:ts=4:noet diff --git a/ksvg/impl/libs/libtext2path/src/Rectangle.h b/ksvg/impl/libs/libtext2path/src/Rectangle.h new file mode 100644 index 00000000..1a5eeeb1 --- /dev/null +++ b/ksvg/impl/libs/libtext2path/src/Rectangle.h @@ -0,0 +1,55 @@ +/* + Copyright (C) 2003 Nikolas Zimmermann <wildfox@kde.org> + This file is part of the KDE project + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + aint with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef T2P_RECTANGLE_H +#define T2P_RECTANGLE_H + +#include "Point.h" + +namespace T2P +{ + class Rectangle + { + public: + Rectangle(); + Rectangle(const Rectangle &other); + Rectangle(const Point &a, const Point &b); + Rectangle(double x, double y, double width, double height); + ~Rectangle(); + + Rectangle &operator=(const Rectangle &other); + + Point a() const; + void setA(const Point &a); + + Point b() const; + void setB(const Point &b); + + // Finds the smallest rectangle that includes src1 and src2. + void bboxUnion(const Rectangle &src1, const Rectangle &src2); + + private: + Point m_a, m_b; + }; +} + +#endif + +// vim:ts=4:noet diff --git a/ksvg/impl/libs/libtext2path/src/Tools.h b/ksvg/impl/libs/libtext2path/src/Tools.h new file mode 100644 index 00000000..c7753365 --- /dev/null +++ b/ksvg/impl/libs/libtext2path/src/Tools.h @@ -0,0 +1,85 @@ +/* + Copyright (C) 2003 Nikolas Zimmermann <wildfox@kde.org> + This file is part of the KDE project + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + aint with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef T2P_TOOLS_H +#define T2P_TOOLS_H + +#include <list> +#include <string> +#include <config.h> +#ifdef HAVE_SSTREAM +# include <sstream> +#else +# include <strstream> +# define ostringstream ostrstream +#endif + +#define T2PMAX(a, b) ((b) < (a) ? (a) : (b)) +#define T2PMIN(a, b) ((a) < (b) ? (a) : (b)) + +namespace T2P +{ + class Tools + { + public: + static std::string joinList(char seperator, std::list<std::string> &list) + { + std::string result; + + if(list.empty()) + return result; + + bool first = true; + for(std::list<std::string>::const_iterator it = list.begin(); it != list.end(); ++it) + { + std::string string = *it; + + if(!string.empty()) + { + if(!first) + result += seperator + string; + else + { + result += string; + first = false; + } + } + } + + return result; + } + + template<typename T> + static std::string a2str(T arg) + { + std::ostringstream buffer; + buffer << arg; + return buffer.str(); + } + }; +} + +#ifdef ostringstream +# undef ostringstream +#endif + +#endif + +// vim:ts=4:noet diff --git a/ksvg/impl/libs/libtext2path/src/myboost/assert.hpp b/ksvg/impl/libs/libtext2path/src/myboost/assert.hpp new file mode 100644 index 00000000..3f3c61c2 --- /dev/null +++ b/ksvg/impl/libs/libtext2path/src/myboost/assert.hpp @@ -0,0 +1,24 @@ +// +// boost/assert.hpp - BOOST_ASSERT(expr) +// +// Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd. +// +// Permission to copy, use, modify, sell and distribute this software +// is granted provided this copyright notice appears in all copies. +// This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. +// +// Note: There are no include guards. This is intentional. +// +// See http://www.boost.org/libs/utility/assert.html for documentation. +// + +#ifndef ASSERT_HPP +#define ASSERT_HPP + +#undef BOOST_ASSERT + +# include <assert.h> +# define BOOST_ASSERT(expr) assert(expr) + +#endif diff --git a/ksvg/impl/libs/libtext2path/src/myboost/checked_delete.hpp b/ksvg/impl/libs/libtext2path/src/myboost/checked_delete.hpp new file mode 100644 index 00000000..73afd5f5 --- /dev/null +++ b/ksvg/impl/libs/libtext2path/src/myboost/checked_delete.hpp @@ -0,0 +1,61 @@ +#ifndef BOOST_CHECKED_DELETE_HPP_INCLUDED +#define BOOST_CHECKED_DELETE_HPP_INCLUDED + +// +// boost/checked_delete.hpp +// +// Copyright (c) 1999, 2000, 2001, 2002 boost.org +// Copyright (c) 2002, 2003 Peter Dimov +// +// Permission to copy, use, modify, sell and distribute this software +// is granted provided this copyright notice appears in all copies. +// This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. +// +// See http://www.boost.org/libs/utility/checked_delete.html for documentation. +// + +namespace myboost +{ + +// verify that types are complete for increased safety + +template<class T> inline void checked_delete(T * x) +{ + // Intel 7 accepts sizeof(incomplete) as 0 in system headers + typedef char type_must_be_complete[ sizeof(T)? 1: -1 ]; + delete x; +} + +template<class T> inline void checked_array_delete(T * x) +{ + typedef char type_must_be_complete[ sizeof(T)? 1: -1 ]; + delete [] x; +} + +template<class T> struct checked_deleter +{ + typedef void result_type; + typedef T * argument_type; + + void operator()(T * x) const + { + // boost:: disables ADL + myboost::checked_delete(x); + } +}; + +template<class T> struct checked_array_deleter +{ + typedef void result_type; + typedef T * argument_type; + + void operator()(T * x) const + { + myboost::checked_array_delete(x); + } +}; + +} // namespace myboost + +#endif // #ifndef BOOST_CHECKED_DELETE_HPP_INCLUDED diff --git a/ksvg/impl/libs/libtext2path/src/myboost/lightweight_mutex.hpp b/ksvg/impl/libs/libtext2path/src/myboost/lightweight_mutex.hpp new file mode 100644 index 00000000..10db127c --- /dev/null +++ b/ksvg/impl/libs/libtext2path/src/myboost/lightweight_mutex.hpp @@ -0,0 +1,74 @@ +#ifndef BOOST_DETAIL_LWM_PTHREADS_HPP_INCLUDED +#define BOOST_DETAIL_LWM_PTHREADS_HPP_INCLUDED + +// +// boost/detail/lwm_pthreads.hpp +// +// Copyright (c) 2002 Peter Dimov and Multi Media Ltd. +// +// Permission to copy, use, modify, sell and distribute this software +// is granted provided this copyright notice appears in all copies. +// This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. +// + +#include <pthread.h> + +namespace myboost +{ + +namespace detail +{ + +class lightweight_mutex +{ +private: + + pthread_mutex_t m_; + + lightweight_mutex(lightweight_mutex const &); + lightweight_mutex & operator=(lightweight_mutex const &); + +public: + + lightweight_mutex() + { + pthread_mutex_init(&m_, 0); + } + + ~lightweight_mutex() + { + pthread_mutex_destroy(&m_); + } + + class scoped_lock; + friend class scoped_lock; + + class scoped_lock + { + private: + + pthread_mutex_t & m_; + + scoped_lock(scoped_lock const &); + scoped_lock & operator=(scoped_lock const &); + + public: + + scoped_lock(lightweight_mutex & m): m_(m.m_) + { + pthread_mutex_lock(&m_); + } + + ~scoped_lock() + { + pthread_mutex_unlock(&m_); + } + }; +}; + +} // namespace detail + +} // namespace myboost + +#endif // #ifndef BOOST_DETAIL_LWM_PTHREADS_HPP_INCLUDED diff --git a/ksvg/impl/libs/libtext2path/src/myboost/shared_count.hpp b/ksvg/impl/libs/libtext2path/src/myboost/shared_count.hpp new file mode 100644 index 00000000..e8ec19a8 --- /dev/null +++ b/ksvg/impl/libs/libtext2path/src/myboost/shared_count.hpp @@ -0,0 +1,367 @@ +#ifndef BOOST_DETAIL_SHARED_COUNT_HPP_INCLUDED +#define BOOST_DETAIL_SHARED_COUNT_HPP_INCLUDED + +// +// detail/shared_count.hpp +// +// Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd. +// +// Permission to copy, use, modify, sell and distribute this software +// is granted provided this copyright notice appears in all copies. +// This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. +// + +#include "myboost/checked_delete.hpp" +#include "myboost/throw_exception.hpp" +#include "myboost/lightweight_mutex.hpp" + +#include <memory> // std::auto_ptr, std::allocator +#include <functional> // std::less +#include <exception> // std::exception +#include <new> // std::bad_alloc +#include <typeinfo> // std::type_info in get_deleter +#include <cstddef> // std::size_t + +namespace myboost +{ + +class bad_weak_ptr: public std::exception +{ +public: + + virtual char const * what() const throw() + { + return "myboost::bad_weak_ptr"; + } +}; + +namespace detail +{ + +class sp_counted_base +{ +private: + + typedef detail::lightweight_mutex mutex_type; + +public: + + sp_counted_base(): use_count_(1), weak_count_(1) + { + } + + virtual ~sp_counted_base() // nothrow + { + } + + // dispose() is called when use_count_ drops to zero, to release + // the resources managed by *this. + + virtual void dispose() = 0; // nothrow + + // destruct() is called when weak_count_ drops to zero. + + virtual void destruct() // nothrow + { + delete this; + } + + virtual void * get_deleter(std::type_info const & ti) = 0; + + void add_ref_copy() + { + mutex_type::scoped_lock lock(mtx_); + ++use_count_; + } + + void add_ref_lock() + { + mutex_type::scoped_lock lock(mtx_); + if(use_count_ == 0) myboost::throw_exception(myboost::bad_weak_ptr()); + ++use_count_; + } + + void release() // nothrow + { + { + mutex_type::scoped_lock lock(mtx_); + long new_use_count = --use_count_; + + if(new_use_count != 0) return; + } + + dispose(); + weak_release(); + } + + void weak_add_ref() // nothrow + { + mutex_type::scoped_lock lock(mtx_); + ++weak_count_; + } + + void weak_release() // nothrow + { + long new_weak_count; + + { + mutex_type::scoped_lock lock(mtx_); + new_weak_count = --weak_count_; + } + + if(new_weak_count == 0) + { + destruct(); + } + } + + long use_count() const // nothrow + { + mutex_type::scoped_lock lock(mtx_); + return use_count_; + } + +private: + + sp_counted_base(sp_counted_base const &); + sp_counted_base & operator= (sp_counted_base const &); + + long use_count_; // #shared + long weak_count_; // #weak + (#shared != 0) + + mutable mutex_type mtx_; +}; + +template<class P, class D> class sp_counted_base_impl: public sp_counted_base +{ +private: + + P ptr; // copy constructor must not throw + D del; // copy constructor must not throw + + sp_counted_base_impl(sp_counted_base_impl const &); + sp_counted_base_impl & operator= (sp_counted_base_impl const &); + + typedef sp_counted_base_impl<P, D> this_type; + +public: + + // pre: initial_use_count <= initial_weak_count, d(p) must not throw + + sp_counted_base_impl(P p, D d): ptr(p), del(d) + { + } + + virtual void dispose() // nothrow + { + del(ptr); + } + + virtual void * get_deleter(std::type_info const & ti) + { + return ti == typeid(D)? &del: 0; + } + + void * operator new(std::size_t) + { + return std::allocator<this_type>().allocate(1, static_cast<this_type *>(0)); + } + + void operator delete(void * p) + { + std::allocator<this_type>().deallocate(static_cast<this_type *>(p), 1); + } +}; + +class weak_count; + +class shared_count +{ +private: + + sp_counted_base * pi_; + + friend class weak_count; + +public: + + shared_count(): pi_(0) // nothrow + { + } + + template<class P, class D> shared_count(P p, D d): pi_(0) + { + + try + { + pi_ = new sp_counted_base_impl<P, D>(p, d); + } + catch(...) + { + d(p); // delete p + throw; + } + + + pi_ = new sp_counted_base_impl<P, D>(p, d); + + if(pi_ == 0) + { + d(p); // delete p + myboost::throw_exception(std::bad_alloc()); + } + } + + // auto_ptr<Y> is special cased to provide the strong guarantee + + template<class Y> + explicit shared_count(std::auto_ptr<Y> & r): pi_(new sp_counted_base_impl< Y *, checked_deleter<Y> >(r.get(), checked_deleter<Y>())) + { + r.release(); + } + + ~shared_count() // nothrow + { + if(pi_ != 0) pi_->release(); + } + + shared_count(shared_count const & r): pi_(r.pi_) // nothrow + { + if(pi_ != 0) pi_->add_ref_copy(); + } + + explicit shared_count(weak_count const & r); // throws bad_weak_ptr when r.use_count() == 0 + + shared_count & operator= (shared_count const & r) // nothrow + { + sp_counted_base * tmp = r.pi_; + if(tmp != 0) tmp->add_ref_copy(); + if(pi_ != 0) pi_->release(); + pi_ = tmp; + + return *this; + } + + void swap(shared_count & r) // nothrow + { + sp_counted_base * tmp = r.pi_; + r.pi_ = pi_; + pi_ = tmp; + } + + long use_count() const // nothrow + { + return pi_ != 0? pi_->use_count(): 0; + } + + bool unique() const // nothrow + { + return use_count() == 1; + } + + friend inline bool operator==(shared_count const & a, shared_count const & b) + { + return a.pi_ == b.pi_; + } + + friend inline bool operator<(shared_count const & a, shared_count const & b) + { + return std::less<sp_counted_base *>()(a.pi_, b.pi_); + } + + void * get_deleter(std::type_info const & ti) const + { + return pi_? pi_->get_deleter(ti): 0; + } +}; + +class weak_count +{ +private: + + sp_counted_base * pi_; + + friend class shared_count; + +public: + + weak_count(): pi_(0) // nothrow + { + } + + weak_count(shared_count const & r): pi_(r.pi_) // nothrow + { + if(pi_ != 0) pi_->weak_add_ref(); + } + + weak_count(weak_count const & r): pi_(r.pi_) // nothrow + { + if(pi_ != 0) pi_->weak_add_ref(); + } + + ~weak_count() // nothrow + { + if(pi_ != 0) pi_->weak_release(); + } + + weak_count & operator= (shared_count const & r) // nothrow + { + sp_counted_base * tmp = r.pi_; + if(tmp != 0) tmp->weak_add_ref(); + if(pi_ != 0) pi_->weak_release(); + pi_ = tmp; + + return *this; + } + + weak_count & operator= (weak_count const & r) // nothrow + { + sp_counted_base * tmp = r.pi_; + if(tmp != 0) tmp->weak_add_ref(); + if(pi_ != 0) pi_->weak_release(); + pi_ = tmp; + + return *this; + } + + void swap(weak_count & r) // nothrow + { + sp_counted_base * tmp = r.pi_; + r.pi_ = pi_; + pi_ = tmp; + } + + long use_count() const // nothrow + { + return pi_ != 0? pi_->use_count(): 0; + } + + friend inline bool operator==(weak_count const & a, weak_count const & b) + { + return a.pi_ == b.pi_; + } + + friend inline bool operator<(weak_count const & a, weak_count const & b) + { + return std::less<sp_counted_base *>()(a.pi_, b.pi_); + } +}; + +inline shared_count::shared_count(weak_count const & r): pi_(r.pi_) +{ + if(pi_ != 0) + { + pi_->add_ref_lock(); + } + else + { + myboost::throw_exception(myboost::bad_weak_ptr()); + } +} + +} // namespace detail + +} // namespace myboost + +#endif // #ifndef BOOST_DETAIL_SHARED_COUNT_HPP_INCLUDED diff --git a/ksvg/impl/libs/libtext2path/src/myboost/shared_ptr.hpp b/ksvg/impl/libs/libtext2path/src/myboost/shared_ptr.hpp new file mode 100644 index 00000000..3f2fe30d --- /dev/null +++ b/ksvg/impl/libs/libtext2path/src/myboost/shared_ptr.hpp @@ -0,0 +1,395 @@ +#ifndef BOOST_SHARED_PTR_HPP_INCLUDED +#define BOOST_SHARED_PTR_HPP_INCLUDED + +// shared_ptr.hpp +// +// (C) Copyright Greg Colvin and Beman Dawes 1998, 1999. +// Copyright (c) 2001, 2002, 2003 Peter Dimov +// +// Permission to copy, use, modify, sell and distribute this software +// is granted provided this copyright notice appears in all copies. +// This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. +// +// See http://www.boost.org/libs/smart_ptr/shared_ptr.htm for documentation. +// + +#include "myboost/assert.hpp" +#include "myboost/checked_delete.hpp" +#include "myboost/throw_exception.hpp" +#include "myboost/shared_count.hpp" + +#include <memory> // for std::auto_ptr +#include <algorithm> // for std::swap +#include <functional> // for std::less +#include <typeinfo> // for std::bad_cast +#include <iosfwd> // for std::basic_ostream + +namespace myboost +{ + +template<class T> class weak_ptr; +template<class T> class enable_shared_from_this; + +namespace detail +{ + +struct static_cast_tag {}; +struct const_cast_tag {}; +struct dynamic_cast_tag {}; +struct polymorphic_cast_tag {}; + +template<class T> struct shared_ptr_traits +{ + typedef T & reference; +}; + +template<> struct shared_ptr_traits<void> +{ + typedef void reference; +}; + +template<> struct shared_ptr_traits<void const> +{ + typedef void reference; +}; + +template<> struct shared_ptr_traits<void volatile> +{ + typedef void reference; +}; + +template<> struct shared_ptr_traits<void const volatile> +{ + typedef void reference; +}; + +// enable_shared_from_this support + +template<class T, class Y> void sp_enable_shared_from_this(myboost::enable_shared_from_this<T> * pe, Y * px, shared_count const & pn) +{ + if(pe != 0) pe->_internal_weak_this._internal_assign(px, pn); +} + +inline void sp_enable_shared_from_this(void const *, void const *, shared_count const &) +{ +} + +} // namespace detail + + +// +// shared_ptr +// +// An enhanced relative of scoped_ptr with reference counted copy semantics. +// The object pointed to is deleted when the last shared_ptr pointing to it +// is destroyed or reset. +// + +template<class T> class shared_ptr +{ +private: + + // Borland 5.5.1 specific workaround + typedef shared_ptr<T> this_type; + +public: + + typedef T element_type; + typedef T value_type; + typedef T * pointer; + typedef typename detail::shared_ptr_traits<T>::reference reference; + + shared_ptr(): px(0), pn() // never throws in 1.30+ + { + } + + template<class Y> + explicit shared_ptr(Y * p): px(p), pn(p, checked_deleter<Y>()) // Y must be complete + { + detail::sp_enable_shared_from_this(p, p, pn); + } + + // + // Requirements: D's copy constructor must not throw + // + // shared_ptr will release p by calling d(p) + // + + template<class Y, class D> shared_ptr(Y * p, D d): px(p), pn(p, d) + { + detail::sp_enable_shared_from_this(p, p, pn); + } + +// generated copy constructor, assignment, destructor are fine... +// except that Borland C++ has a bug, and g++ with -Wsynth warns + shared_ptr & operator=(shared_ptr const & r) // never throws + { + px = r.px; + pn = r.pn; // shared_count::op= doesn't throw + return *this; + } + + template<class Y> + explicit shared_ptr(weak_ptr<Y> const & r): pn(r.pn) // may throw + { + // it is now safe to copy r.px, as pn(r.pn) did not throw + px = r.px; + } + + template<class Y> + shared_ptr(shared_ptr<Y> const & r): px(r.px), pn(r.pn) // never throws + { + } + + template<class Y> + shared_ptr(shared_ptr<Y> const & r, detail::static_cast_tag): px(static_cast<element_type *>(r.px)), pn(r.pn) + { + } + + template<class Y> + shared_ptr(shared_ptr<Y> const & r, detail::const_cast_tag): px(const_cast<element_type *>(r.px)), pn(r.pn) + { + } + + template<class Y> + shared_ptr(shared_ptr<Y> const & r, detail::dynamic_cast_tag): px(dynamic_cast<element_type *>(r.px)), pn(r.pn) + { + if(px == 0) // need to allocate new counter -- the cast failed + { + pn = detail::shared_count(); + } + } + + template<class Y> + shared_ptr(shared_ptr<Y> const & r, detail::polymorphic_cast_tag): px(dynamic_cast<element_type *>(r.px)), pn(r.pn) + { + if(px == 0) + { + myboost::throw_exception(std::bad_cast()); + } + } + + template<class Y> + explicit shared_ptr(std::auto_ptr<Y> & r): px(r.get()), pn() + { + Y * tmp = r.get(); + pn = detail::shared_count(r); + detail::sp_enable_shared_from_this(tmp, tmp, pn); + } + + template<class Y> + shared_ptr & operator=(shared_ptr<Y> const & r) // never throws + { + px = r.px; + pn = r.pn; // shared_count::op= doesn't throw + return *this; + } + + template<class Y> + shared_ptr & operator=(std::auto_ptr<Y> & r) + { + this_type(r).swap(*this); + return *this; + } + + void reset() // never throws in 1.30+ + { + this_type().swap(*this); + } + + template<class Y> void reset(Y * p) // Y must be complete + { + BOOST_ASSERT(p == 0 || p != px); // catch self-reset errors + this_type(p).swap(*this); + } + + template<class Y, class D> void reset(Y * p, D d) + { + this_type(p, d).swap(*this); + } + + reference operator* () const // never throws + { + BOOST_ASSERT(px != 0); + return *px; + } + + T * operator-> () const // never throws + { + BOOST_ASSERT(px != 0); + return px; + } + + T * get() const // never throws + { + return px; + } + + typedef T * (this_type::*unspecified_bool_type)() const; + + operator unspecified_bool_type() const // never throws + { + return px == 0? 0: &this_type::get; + } + + // operator! is redundant, but some compilers need it + + bool operator! () const // never throws + { + return px == 0; + } + + bool unique() const // never throws + { + return pn.unique(); + } + + long use_count() const // never throws + { + return pn.use_count(); + } + + void swap(shared_ptr<T> & other) // never throws + { + std::swap(px, other.px); + pn.swap(other.pn); + } + + template<class Y> bool _internal_less(shared_ptr<Y> const & rhs) const + { + return pn < rhs.pn; + } + + void * _internal_get_deleter(std::type_info const & ti) const + { + return pn.get_deleter(ti); + } + +// Tasteless as this may seem, making all members public allows member templates +// to work in the absence of member template friends. (Matthew Langston) + +# if __GNUC__ >= 2 && __GNUC_MINOR__ >= 97 +private: + + template<class Y> friend class shared_ptr; + template<class Y> friend class weak_ptr; +#endif + + T * px; // contained pointer + detail::shared_count pn; // reference counter + +}; // shared_ptr + +template<class T, class U> inline bool operator==(shared_ptr<T> const & a, shared_ptr<U> const & b) +{ + return a.get() == b.get(); +} + +template<class T, class U> inline bool operator!=(shared_ptr<T> const & a, shared_ptr<U> const & b) +{ + return a.get() != b.get(); +} + +#if __GNUC__ == 2 && __GNUC_MINOR__ <= 96 + +// Resolve the ambiguity between our op!= and the one in rel_ops + +template<class T> inline bool operator!=(shared_ptr<T> const & a, shared_ptr<T> const & b) +{ + return a.get() != b.get(); +} + +#endif + +template<class T, class U> inline bool operator<(shared_ptr<T> const & a, shared_ptr<U> const & b) +{ + return a._internal_less(b); +} + +template<class T> inline void swap(shared_ptr<T> & a, shared_ptr<T> & b) +{ + a.swap(b); +} + +template<class T, class U> shared_ptr<T> static_pointer_cast(shared_ptr<U> const & r) +{ + return shared_ptr<T>(r, detail::static_cast_tag()); +} + +template<class T, class U> shared_ptr<T> const_pointer_cast(shared_ptr<U> const & r) +{ + return shared_ptr<T>(r, detail::const_cast_tag()); +} + +template<class T, class U> shared_ptr<T> dynamic_pointer_cast(shared_ptr<U> const & r) +{ + return shared_ptr<T>(r, detail::dynamic_cast_tag()); +} + +// shared_*_cast names are deprecated. Use *_pointer_cast instead. + +template<class T, class U> shared_ptr<T> shared_static_cast(shared_ptr<U> const & r) +{ + return shared_ptr<T>(r, detail::static_cast_tag()); +} + +template<class T, class U> shared_ptr<T> shared_dynamic_cast(shared_ptr<U> const & r) +{ + return shared_ptr<T>(r, detail::dynamic_cast_tag()); +} + +template<class T, class U> shared_ptr<T> shared_polymorphic_cast(shared_ptr<U> const & r) +{ + return shared_ptr<T>(r, detail::polymorphic_cast_tag()); +} + +template<class T, class U> shared_ptr<T> shared_polymorphic_downcast(shared_ptr<U> const & r) +{ + BOOST_ASSERT(dynamic_cast<T *>(r.get()) == r.get()); + return shared_static_cast<T>(r); +} + +// get_pointer() enables boost::mem_fn to recognize shared_ptr + +template<class T> inline T * get_pointer(shared_ptr<T> const & p) +{ + return p.get(); +} + +// operator<< + + +template<class Y> std::ostream & operator<< (std::ostream & os, shared_ptr<Y> const & p) +{ + os << p.get(); + return os; +} + + +// get_deleter (experimental) + +#if (defined(__GNUC__) && (__GNUC__ < 3)) || (defined(__EDG_VERSION__) && (__EDG_VERSION__ <= 238)) + +// g++ 2.9x doesn't allow static_cast<X const *>(void *) +// apparently EDG 2.38 also doesn't accept it + +template<class D, class T> D * get_deleter(shared_ptr<T> const & p) +{ + void const * q = p._internal_get_deleter(typeid(D)); + return const_cast<D *>(static_cast<D const *>(q)); +} + +#else + +template<class D, class T> D * get_deleter(shared_ptr<T> const & p) +{ + return static_cast<D *>(p._internal_get_deleter(typeid(D))); +} + +#endif + +} // namespace boost + + +#endif // #ifndef BOOST_SHARED_PTR_HPP_INCLUDED diff --git a/ksvg/impl/libs/libtext2path/src/myboost/throw_exception.hpp b/ksvg/impl/libs/libtext2path/src/myboost/throw_exception.hpp new file mode 100644 index 00000000..dd32ec43 --- /dev/null +++ b/ksvg/impl/libs/libtext2path/src/myboost/throw_exception.hpp @@ -0,0 +1,30 @@ +#ifndef BOOST_THROW_EXCEPTION_HPP_INCLUDED +#define BOOST_THROW_EXCEPTION_HPP_INCLUDED + + +// +// boost/throw_exception.hpp +// +// Copyright (c) 2002 Peter Dimov and Multi Media Ltd. +// +// Permission to copy, use, modify, sell and distribute this software +// is granted provided this copyright notice appears in all copies. +// This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. +// +// http://www.boost.org/libs/utility/throw_exception.html +// + +# include <exception> + +namespace myboost +{ + +template<class E> void throw_exception(E const & e) +{ + throw e; +} + +} // namespace myboost + +#endif // #ifndef BOOST_THROW_EXCEPTION_HPP_INCLUDED |