mirror of https://github.com/vitalif/openscad
152 lines
5.5 KiB
C++
152 lines
5.5 KiB
C++
/*
|
|
* OpenSCAD (www.openscad.org)
|
|
* Copyright (C) 2009-2011 Clifford Wolf <clifford@clifford.at> and
|
|
* Marius Kintel <marius@kintel.net>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* As a special exception, you have permission to link this program
|
|
* with the CGAL library and distribute executables, as long as you
|
|
* follow the requirements of the GNU GPL in regard to all of the
|
|
* software in the executable aside from CGAL.
|
|
*
|
|
* This program 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 General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*
|
|
*/
|
|
#pragma once
|
|
|
|
#include <string>
|
|
#include <vector>
|
|
#include <ostream>
|
|
|
|
#include <hb.h>
|
|
#include <ft2build.h>
|
|
#include FT_FREETYPE_H
|
|
#include FT_GLYPH_H
|
|
|
|
class FreetypeRenderer {
|
|
public:
|
|
class Params {
|
|
public:
|
|
void set_size(double size) {
|
|
this->size = size;
|
|
}
|
|
void set_spacing(double spacing) {
|
|
this->spacing = spacing;
|
|
}
|
|
void set_fn(double fn) {
|
|
this->fn = fn;
|
|
}
|
|
void set_fa(double fa) {
|
|
this->fa = fa;
|
|
}
|
|
void set_fs(double fs) {
|
|
this->fs = fs;
|
|
}
|
|
void set_segments(double segments) {
|
|
this->segments = segments;
|
|
}
|
|
void set_text(std::string text) {
|
|
this->text = text;
|
|
}
|
|
void set_font(std::string font) {
|
|
this->font = font;
|
|
}
|
|
void set_direction(std::string direction) {
|
|
this->direction = direction;
|
|
}
|
|
void set_language(std::string language) {
|
|
this->language = language;
|
|
}
|
|
void set_script(std::string script) {
|
|
this->script = script;
|
|
}
|
|
void set_halign(std::string halign) {
|
|
this->halign = halign;
|
|
}
|
|
void set_valign(std::string valign) {
|
|
this->valign = valign;
|
|
}
|
|
friend std::ostream & operator << (std::ostream &stream, const FreetypeRenderer::Params ¶ms) {
|
|
return stream
|
|
<< "text = \"" << params.text
|
|
<< "\", size = " << params.size
|
|
<< ", spacing = " << params.spacing
|
|
<< ", font = \"" << params.font
|
|
<< "\", direction = \"" << params.direction
|
|
<< "\", language = \"" << params.language
|
|
<< (params.script.empty() ? "" : "\", script = \"") << params.script
|
|
<< "\", halign = \"" << params.halign
|
|
<< "\", valign = \"" << params.valign
|
|
<< "\", $fn = " << params.fn
|
|
<< ", $fa = " << params.fa
|
|
<< ", $fs = " << params.fs;
|
|
}
|
|
private:
|
|
double size, spacing, fn, fa, fs, segments;
|
|
std::string text, font, direction, language, script, halign, valign;
|
|
|
|
friend class FreetypeRenderer;
|
|
};
|
|
|
|
FreetypeRenderer();
|
|
virtual ~FreetypeRenderer();
|
|
|
|
void detect_properties(FreetypeRenderer::Params ¶ms) const;
|
|
std::vector<const class Geometry *> render(const FreetypeRenderer::Params ¶ms) const;
|
|
private:
|
|
const static double scale;
|
|
FT_Outline_Funcs funcs;
|
|
|
|
class GlyphData {
|
|
public:
|
|
GlyphData(FT_Glyph glyph, unsigned int idx, hb_glyph_position_t *glyph_pos) : glyph(glyph), idx(idx), glyph_pos(glyph_pos) {}
|
|
unsigned int get_idx() const { return idx; };
|
|
FT_Glyph get_glyph() const { return glyph; };
|
|
double get_x_offset() const { return glyph_pos->x_offset / 64.0 / 16.0; };
|
|
double get_y_offset() const { return glyph_pos->y_offset / 64.0 / 16.0; };
|
|
double get_x_advance() const { return glyph_pos->x_advance / 64.0 / 16.0; };
|
|
double get_y_advance() const { return glyph_pos->y_advance / 64.0 / 16.0; };
|
|
private:
|
|
FT_Glyph glyph;
|
|
unsigned int idx;
|
|
hb_glyph_position_t *glyph_pos;
|
|
};
|
|
|
|
struct done_glyph : public std::unary_function<const GlyphData *, void> {
|
|
void operator() (const GlyphData *glyph_data) {
|
|
FT_Done_Glyph(glyph_data->get_glyph());
|
|
delete glyph_data;
|
|
}
|
|
};
|
|
|
|
class GlyphArray : public std::vector<const GlyphData *> {
|
|
public:
|
|
virtual ~GlyphArray() {
|
|
std::for_each(begin(), end(), done_glyph());
|
|
}
|
|
};
|
|
|
|
bool is_ignored_script(const hb_script_t script) const;
|
|
hb_script_t get_script(const FreetypeRenderer::Params ¶ms, hb_glyph_info_t *glyph_info, unsigned int glyph_count) const;
|
|
hb_direction_t get_direction(const FreetypeRenderer::Params ¶ms, const hb_script_t script) const;
|
|
|
|
double calc_x_offset(std::string halign, double width) const;
|
|
double calc_y_offset(std::string valign, double ascend, double descend) const;
|
|
|
|
static int outline_move_to_func(const FT_Vector *to, void *user);
|
|
static int outline_line_to_func(const FT_Vector *to, void *user);
|
|
static int outline_conic_to_func(const FT_Vector *c1, const FT_Vector *to, void *user);
|
|
static int outline_cubic_to_func(const FT_Vector *c1, const FT_Vector *c2, const FT_Vector *to, void *user);
|
|
};
|