aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/python/matplotlib/py2/src/ft2font.cpp
diff options
context:
space:
mode:
authormaxim-yurchuk <maxim-yurchuk@yandex-team.com>2025-02-11 13:26:52 +0300
committermaxim-yurchuk <maxim-yurchuk@yandex-team.com>2025-02-11 13:57:59 +0300
commitf895bba65827952ed934b2b46f9a45e30a191fd2 (patch)
tree03260c906d9ec41cdc03e2a496b15d407459cec0 /contrib/python/matplotlib/py2/src/ft2font.cpp
parent5f7060466f7b9707818c2091e1a25c14f33c3474 (diff)
downloadydb-f895bba65827952ed934b2b46f9a45e30a191fd2.tar.gz
Remove deps on pandas
<https://github.com/ydb-platform/ydb/pull/14418> <https://github.com/ydb-platform/ydb/pull/14419> \-- аналогичные правки в gh Хочу залить в обход синка, чтобы посмотреть удалится ли pandas в нашей gh репе через piglet commit_hash:abca127aa37d4dbb94b07e1e18cdb8eb5b711860
Diffstat (limited to 'contrib/python/matplotlib/py2/src/ft2font.cpp')
-rw-r--r--contrib/python/matplotlib/py2/src/ft2font.cpp808
1 files changed, 0 insertions, 808 deletions
diff --git a/contrib/python/matplotlib/py2/src/ft2font.cpp b/contrib/python/matplotlib/py2/src/ft2font.cpp
deleted file mode 100644
index 7245ca332ab..00000000000
--- a/contrib/python/matplotlib/py2/src/ft2font.cpp
+++ /dev/null
@@ -1,808 +0,0 @@
-/* -*- mode: c++; c-basic-offset: 4 -*- */
-
-#define NO_IMPORT_ARRAY
-
-#include <algorithm>
-#include <stdexcept>
-#include <string>
-
-#include "ft2font.h"
-#include "mplutils.h"
-
-#ifndef M_PI
-#define M_PI 3.14159265358979323846264338328
-#endif
-
-/**
- To improve the hinting of the fonts, this code uses a hack
- presented here:
-
- http://antigrain.com/research/font_rasterization/index.html
-
- The idea is to limit the effect of hinting in the x-direction, while
- preserving hinting in the y-direction. Since freetype does not
- support this directly, the dpi in the x-direction is set higher than
- in the y-direction, which affects the hinting grid. Then, a global
- transform is placed on the font to shrink it back to the desired
- size. While it is a bit surprising that the dpi setting affects
- hinting, whereas the global transform does not, this is documented
- behavior of FreeType, and therefore hopefully unlikely to change.
- The FreeType 2 tutorial says:
-
- NOTE: The transformation is applied to every glyph that is
- loaded through FT_Load_Glyph and is completely independent of
- any hinting process. This means that you won't get the same
- results if you load a glyph at the size of 24 pixels, or a glyph
- at the size at 12 pixels scaled by 2 through a transform,
- because the hints will have been computed differently (except
- you have disabled hints).
- */
-
-FT_Library _ft2Library;
-
-FT2Image::FT2Image() : m_dirty(true), m_buffer(NULL), m_width(0), m_height(0)
-{
-}
-
-FT2Image::FT2Image(unsigned long width, unsigned long height)
- : m_dirty(true), m_buffer(NULL), m_width(0), m_height(0)
-{
- resize(width, height);
-}
-
-FT2Image::~FT2Image()
-{
- delete[] m_buffer;
-}
-
-void FT2Image::resize(long width, long height)
-{
- if (width <= 0) {
- width = 1;
- }
- if (height <= 0) {
- height = 1;
- }
- size_t numBytes = width * height;
-
- if ((unsigned long)width != m_width || (unsigned long)height != m_height) {
- if (numBytes > m_width * m_height) {
- delete[] m_buffer;
- m_buffer = NULL;
- m_buffer = new unsigned char[numBytes];
- }
-
- m_width = (unsigned long)width;
- m_height = (unsigned long)height;
- }
-
- if (numBytes && m_buffer) {
- memset(m_buffer, 0, numBytes);
- }
-
- m_dirty = true;
-}
-
-void FT2Image::draw_bitmap(FT_Bitmap *bitmap, FT_Int x, FT_Int y)
-{
- FT_Int image_width = (FT_Int)m_width;
- FT_Int image_height = (FT_Int)m_height;
- FT_Int char_width = bitmap->width;
- FT_Int char_height = bitmap->rows;
-
- FT_Int x1 = CLAMP(x, 0, image_width);
- FT_Int y1 = CLAMP(y, 0, image_height);
- FT_Int x2 = CLAMP(x + char_width, 0, image_width);
- FT_Int y2 = CLAMP(y + char_height, 0, image_height);
-
- FT_Int x_start = MAX(0, -x);
- FT_Int y_offset = y1 - MAX(0, -y);
-
- if (bitmap->pixel_mode == FT_PIXEL_MODE_GRAY) {
- for (FT_Int i = y1; i < y2; ++i) {
- unsigned char *dst = m_buffer + (i * image_width + x1);
- unsigned char *src = bitmap->buffer + (((i - y_offset) * bitmap->pitch) + x_start);
- for (FT_Int j = x1; j < x2; ++j, ++dst, ++src)
- *dst |= *src;
- }
- } else if (bitmap->pixel_mode == FT_PIXEL_MODE_MONO) {
- for (FT_Int i = y1; i < y2; ++i) {
- unsigned char *dst = m_buffer + (i * image_width + x1);
- unsigned char *src = bitmap->buffer + ((i - y_offset) * bitmap->pitch);
- for (FT_Int j = x1; j < x2; ++j, ++dst) {
- int x = (j - x1 + x_start);
- int val = *(src + (x >> 3)) & (1 << (7 - (x & 0x7)));
- *dst = val ? 255 : *dst;
- }
- }
- } else {
- throw std::runtime_error("Unknown pixel mode");
- }
-
- m_dirty = true;
-}
-
-void FT2Image::draw_rect(unsigned long x0, unsigned long y0, unsigned long x1, unsigned long y1)
-{
- if (x0 > m_width || x1 > m_width || y0 > m_height || y1 > m_height) {
- throw std::runtime_error("Rect coords outside image bounds");
- }
-
- size_t top = y0 * m_width;
- size_t bottom = y1 * m_width;
- for (size_t i = x0; i < x1 + 1; ++i) {
- m_buffer[i + top] = 255;
- m_buffer[i + bottom] = 255;
- }
-
- for (size_t j = y0 + 1; j < y1; ++j) {
- m_buffer[x0 + j * m_width] = 255;
- m_buffer[x1 + j * m_width] = 255;
- }
-
- m_dirty = true;
-}
-
-void
-FT2Image::draw_rect_filled(unsigned long x0, unsigned long y0, unsigned long x1, unsigned long y1)
-{
- x0 = std::min(x0, m_width);
- y0 = std::min(y0, m_height);
- x1 = std::min(x1 + 1, m_width);
- y1 = std::min(y1 + 1, m_height);
-
- for (size_t j = y0; j < y1; j++) {
- for (size_t i = x0; i < x1; i++) {
- m_buffer[i + j * m_width] = 255;
- }
- }
-
- m_dirty = true;
-}
-
-inline double conv(long v)
-{
- return double(v) / 64.0;
-}
-
-int FT2Font::get_path_count()
-{
- // get the glyph as a path, a list of (COMMAND, *args) as described in matplotlib.path
- // this code is from agg's decompose_ft_outline with minor modifications
-
- if (!face->glyph) {
- throw std::runtime_error("No glyph loaded");
- }
-
- FT_Outline &outline = face->glyph->outline;
-
- FT_Vector v_last;
- FT_Vector v_control;
- FT_Vector v_start;
-
- FT_Vector *point;
- FT_Vector *limit;
- unsigned char *tags;
-
- int n; // index of contour in outline
- int first; // index of first point in contour
- char tag; // current point's state
- int count;
-
- count = 0;
- first = 0;
- for (n = 0; n < outline.n_contours; n++) {
- int last; // index of last point in contour
- bool starts_with_last;
-
- last = outline.contours[n];
- limit = outline.points + last;
-
- v_start = outline.points[first];
- v_last = outline.points[last];
-
- v_control = v_start;
-
- point = outline.points + first;
- tags = outline.tags + first;
- tag = FT_CURVE_TAG(tags[0]);
-
- // A contour cannot start with a cubic control point!
- if (tag == FT_CURVE_TAG_CUBIC) {
- throw std::runtime_error("A contour cannot start with a cubic control point");
- } else if (tag == FT_CURVE_TAG_CONIC) {
- starts_with_last = true;
- } else {
- starts_with_last = false;
- }
-
- count++;
-
- while (point < limit) {
- if (!starts_with_last) {
- point++;
- tags++;
- }
- starts_with_last = false;
-
- tag = FT_CURVE_TAG(tags[0]);
- switch (tag) {
- case FT_CURVE_TAG_ON: // emit a single line_to
- {
- count++;
- continue;
- }
-
- case FT_CURVE_TAG_CONIC: // consume conic arcs
- {
- Count_Do_Conic:
- if (point < limit) {
- point++;
- tags++;
- tag = FT_CURVE_TAG(tags[0]);
-
- if (tag == FT_CURVE_TAG_ON) {
- count += 2;
- continue;
- }
-
- if (tag != FT_CURVE_TAG_CONIC) {
- throw std::runtime_error("Invalid font");
- }
-
- count += 2;
-
- goto Count_Do_Conic;
- }
-
- count += 2;
-
- goto Count_Close;
- }
-
- default: // FT_CURVE_TAG_CUBIC
- {
- if (point + 1 > limit || FT_CURVE_TAG(tags[1]) != FT_CURVE_TAG_CUBIC) {
- throw std::runtime_error("Invalid font");
- }
-
- point += 2;
- tags += 2;
-
- if (point <= limit) {
- count += 3;
- continue;
- }
-
- count += 3;
-
- goto Count_Close;
- }
- }
- }
-
- Count_Close:
- count++;
- first = last + 1;
- }
-
- return count;
-}
-
-void FT2Font::get_path(double *outpoints, unsigned char *outcodes)
-{
- FT_Outline &outline = face->glyph->outline;
- bool flip_y = false; // todo, pass me as kwarg
-
- FT_Vector v_last;
- FT_Vector v_control;
- FT_Vector v_start;
-
- FT_Vector *point;
- FT_Vector *limit;
- unsigned char *tags;
-
- int n; // index of contour in outline
- int first; // index of first point in contour
- char tag; // current point's state
-
- first = 0;
- for (n = 0; n < outline.n_contours; n++) {
- int last; // index of last point in contour
- bool starts_with_last;
-
- last = outline.contours[n];
- limit = outline.points + last;
-
- v_start = outline.points[first];
- v_last = outline.points[last];
-
- v_control = v_start;
-
- point = outline.points + first;
- tags = outline.tags + first;
- tag = FT_CURVE_TAG(tags[0]);
-
- double x, y;
- if (tag != FT_CURVE_TAG_ON) {
- x = conv(v_last.x);
- y = flip_y ? -conv(v_last.y) : conv(v_last.y);
- starts_with_last = true;
- } else {
- x = conv(v_start.x);
- y = flip_y ? -conv(v_start.y) : conv(v_start.y);
- starts_with_last = false;
- }
-
- *(outpoints++) = x;
- *(outpoints++) = y;
- *(outcodes++) = MOVETO;
-
- while (point < limit) {
- if (!starts_with_last) {
- point++;
- tags++;
- }
- starts_with_last = false;
-
- tag = FT_CURVE_TAG(tags[0]);
- switch (tag) {
- case FT_CURVE_TAG_ON: // emit a single line_to
- {
- double x = conv(point->x);
- double y = flip_y ? -conv(point->y) : conv(point->y);
- *(outpoints++) = x;
- *(outpoints++) = y;
- *(outcodes++) = LINETO;
- continue;
- }
-
- case FT_CURVE_TAG_CONIC: // consume conic arcs
- {
- v_control.x = point->x;
- v_control.y = point->y;
-
- Do_Conic:
- if (point < limit) {
- FT_Vector vec;
- FT_Vector v_middle;
-
- point++;
- tags++;
- tag = FT_CURVE_TAG(tags[0]);
-
- vec.x = point->x;
- vec.y = point->y;
-
- if (tag == FT_CURVE_TAG_ON) {
- double xctl = conv(v_control.x);
- double yctl = flip_y ? -conv(v_control.y) : conv(v_control.y);
- double xto = conv(vec.x);
- double yto = flip_y ? -conv(vec.y) : conv(vec.y);
- *(outpoints++) = xctl;
- *(outpoints++) = yctl;
- *(outpoints++) = xto;
- *(outpoints++) = yto;
- *(outcodes++) = CURVE3;
- *(outcodes++) = CURVE3;
- continue;
- }
-
- v_middle.x = (v_control.x + vec.x) / 2;
- v_middle.y = (v_control.y + vec.y) / 2;
-
- double xctl = conv(v_control.x);
- double yctl = flip_y ? -conv(v_control.y) : conv(v_control.y);
- double xto = conv(v_middle.x);
- double yto = flip_y ? -conv(v_middle.y) : conv(v_middle.y);
- *(outpoints++) = xctl;
- *(outpoints++) = yctl;
- *(outpoints++) = xto;
- *(outpoints++) = yto;
- *(outcodes++) = CURVE3;
- *(outcodes++) = CURVE3;
-
- v_control = vec;
- goto Do_Conic;
- }
- double xctl = conv(v_control.x);
- double yctl = flip_y ? -conv(v_control.y) : conv(v_control.y);
- double xto = conv(v_start.x);
- double yto = flip_y ? -conv(v_start.y) : conv(v_start.y);
-
- *(outpoints++) = xctl;
- *(outpoints++) = yctl;
- *(outpoints++) = xto;
- *(outpoints++) = yto;
- *(outcodes++) = CURVE3;
- *(outcodes++) = CURVE3;
-
- goto Close;
- }
-
- default: // FT_CURVE_TAG_CUBIC
- {
- FT_Vector vec1, vec2;
-
- vec1.x = point[0].x;
- vec1.y = point[0].y;
- vec2.x = point[1].x;
- vec2.y = point[1].y;
-
- point += 2;
- tags += 2;
-
- if (point <= limit) {
- FT_Vector vec;
-
- vec.x = point->x;
- vec.y = point->y;
-
- double xctl1 = conv(vec1.x);
- double yctl1 = flip_y ? -conv(vec1.y) : conv(vec1.y);
- double xctl2 = conv(vec2.x);
- double yctl2 = flip_y ? -conv(vec2.y) : conv(vec2.y);
- double xto = conv(vec.x);
- double yto = flip_y ? -conv(vec.y) : conv(vec.y);
-
- (*outpoints++) = xctl1;
- (*outpoints++) = yctl1;
- (*outpoints++) = xctl2;
- (*outpoints++) = yctl2;
- (*outpoints++) = xto;
- (*outpoints++) = yto;
- (*outcodes++) = CURVE4;
- (*outcodes++) = CURVE4;
- (*outcodes++) = CURVE4;
- continue;
- }
-
- double xctl1 = conv(vec1.x);
- double yctl1 = flip_y ? -conv(vec1.y) : conv(vec1.y);
- double xctl2 = conv(vec2.x);
- double yctl2 = flip_y ? -conv(vec2.y) : conv(vec2.y);
- double xto = conv(v_start.x);
- double yto = flip_y ? -conv(v_start.y) : conv(v_start.y);
- (*outpoints++) = xctl1;
- (*outpoints++) = yctl1;
- (*outpoints++) = xctl2;
- (*outpoints++) = yctl2;
- (*outpoints++) = xto;
- (*outpoints++) = yto;
- (*outcodes++) = CURVE4;
- (*outcodes++) = CURVE4;
- (*outcodes++) = CURVE4;
-
- goto Close;
- }
- }
- }
-
- Close:
- (*outpoints++) = 0.0;
- (*outpoints++) = 0.0;
- (*outcodes++) = ENDPOLY;
- first = last + 1;
- }
-}
-
-FT2Font::FT2Font(FT_Open_Args &open_args, long hinting_factor_) : image(), face(NULL)
-{
- clear();
-
- int error = FT_Open_Face(_ft2Library, &open_args, 0, &face);
-
- if (error == FT_Err_Unknown_File_Format) {
- throw std::runtime_error("Can not load face. Unknown file format.");
- } else if (error == FT_Err_Cannot_Open_Resource) {
- throw std::runtime_error("Can not load face. Can not open resource.");
- } else if (error == FT_Err_Invalid_File_Format) {
- throw std::runtime_error("Can not load face. Invalid file format.");
- } else if (error) {
- throw std::runtime_error("Can not load face.");
- }
-
- // set a default fontsize 12 pt at 72dpi
- hinting_factor = hinting_factor_;
-
- error = FT_Set_Char_Size(face, 12 * 64, 0, 72 * (unsigned int)hinting_factor, 72);
- if (error) {
- FT_Done_Face(face);
- throw std::runtime_error("Could not set the fontsize");
- }
-
- if (open_args.stream != NULL) {
- face->face_flags |= FT_FACE_FLAG_EXTERNAL_STREAM;
- }
-
- FT_Matrix transform = { 65536 / hinting_factor, 0, 0, 65536 };
- FT_Set_Transform(face, &transform, 0);
-}
-
-FT2Font::~FT2Font()
-{
- for (size_t i = 0; i < glyphs.size(); i++) {
- FT_Done_Glyph(glyphs[i]);
- }
-
- if (face) {
- FT_Done_Face(face);
- }
-}
-
-void FT2Font::clear()
-{
- angle = 0.0;
-
- pen.x = 0;
- pen.y = 0;
-
- for (size_t i = 0; i < glyphs.size(); i++) {
- FT_Done_Glyph(glyphs[i]);
- }
-
- glyphs.clear();
-}
-
-void FT2Font::set_size(double ptsize, double dpi)
-{
- int error = FT_Set_Char_Size(
- face, (long)(ptsize * 64), 0, (unsigned int)(dpi * hinting_factor), (unsigned int)dpi);
- FT_Matrix transform = { 65536 / hinting_factor, 0, 0, 65536 };
- FT_Set_Transform(face, &transform, 0);
-
- if (error) {
- throw std::runtime_error("Could not set the fontsize");
- }
-}
-
-void FT2Font::set_charmap(int i)
-{
- if (i >= face->num_charmaps) {
- throw std::runtime_error("i exceeds the available number of char maps");
- }
- FT_CharMap charmap = face->charmaps[i];
- if (FT_Set_Charmap(face, charmap)) {
- throw std::runtime_error("Could not set the charmap");
- }
-}
-
-void FT2Font::select_charmap(unsigned long i)
-{
- if (FT_Select_Charmap(face, (FT_Encoding)i)) {
- throw std::runtime_error("Could not set the charmap");
- }
-}
-
-int FT2Font::get_kerning(FT_UInt left, FT_UInt right, FT_UInt mode)
-{
- if (!FT_HAS_KERNING(face)) {
- return 0;
- }
- FT_Vector delta;
-
- if (!FT_Get_Kerning(face, left, right, mode, &delta)) {
- return (int)(delta.x) / (hinting_factor << 6);
- } else {
- return 0;
- }
-}
-
-void FT2Font::set_text(
- size_t N, uint32_t *codepoints, double angle, FT_Int32 flags, std::vector<double> &xys)
-{
- angle = angle / 360.0 * 2 * M_PI;
-
- // this computes width and height in subpixels so we have to divide by 64
- 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_Bool use_kerning = FT_HAS_KERNING(face);
- FT_UInt previous = 0;
-
- clear();
-
- bbox.xMin = bbox.yMin = 32000;
- bbox.xMax = bbox.yMax = -32000;
-
- for (unsigned int n = 0; n < N; n++) {
- std::string thischar("?");
- FT_UInt glyph_index;
- FT_BBox glyph_bbox;
- FT_Pos last_advance;
-
- glyph_index = FT_Get_Char_Index(face, codepoints[n]);
-
- // retrieve kerning distance and move pen position
- if (use_kerning && previous && glyph_index) {
- FT_Vector delta;
- FT_Get_Kerning(face, previous, glyph_index, FT_KERNING_DEFAULT, &delta);
- pen.x += (delta.x << 10) / (hinting_factor << 16);
- }
- error = FT_Load_Glyph(face, glyph_index, flags);
- if (error) {
- throw std::runtime_error("could not load glyph");
- }
- // ignore errors, jump to next glyph
-
- // extract glyph image and store it in our table
-
- FT_Glyph thisGlyph;
- error = FT_Get_Glyph(face->glyph, &thisGlyph);
-
- if (error) {
- throw std::runtime_error("could not get glyph");
- }
- // ignore errors, jump to next glyph
-
- last_advance = face->glyph->advance.x;
- FT_Glyph_Transform(thisGlyph, 0, &pen);
- FT_Glyph_Transform(thisGlyph, &matrix, 0);
- xys.push_back(pen.x);
- xys.push_back(pen.y);
-
- FT_Glyph_Get_CBox(thisGlyph, ft_glyph_bbox_subpixels, &glyph_bbox);
-
- bbox.xMin = std::min(bbox.xMin, glyph_bbox.xMin);
- bbox.xMax = std::max(bbox.xMax, glyph_bbox.xMax);
- bbox.yMin = std::min(bbox.yMin, glyph_bbox.yMin);
- bbox.yMax = std::max(bbox.yMax, glyph_bbox.yMax);
-
- pen.x += last_advance;
-
- previous = glyph_index;
- glyphs.push_back(thisGlyph);
- }
-
- FT_Vector_Transform(&pen, &matrix);
- advance = pen.x;
-
- if (bbox.xMin > bbox.xMax) {
- bbox.xMin = bbox.yMin = bbox.xMax = bbox.yMax = 0;
- }
-}
-
-void FT2Font::load_char(long charcode, FT_Int32 flags)
-{
- int error = FT_Load_Char(face, (unsigned long)charcode, flags);
-
- if (error) {
- throw std::runtime_error("Could not load charcode");
- }
-
- FT_Glyph thisGlyph;
- error = FT_Get_Glyph(face->glyph, &thisGlyph);
-
- if (error) {
- throw std::runtime_error("Could not get glyph");
- }
-
- glyphs.push_back(thisGlyph);
-}
-
-void FT2Font::load_glyph(FT_UInt glyph_index, FT_Int32 flags)
-{
- int error = FT_Load_Glyph(face, glyph_index, flags);
-
- if (error) {
- throw std::runtime_error("Could not load glyph");
- }
-
- FT_Glyph thisGlyph;
- error = FT_Get_Glyph(face->glyph, &thisGlyph);
-
- if (error) {
- throw std::runtime_error("Could not load glyph");
- }
-
- glyphs.push_back(thisGlyph);
-}
-
-void FT2Font::get_width_height(long *width, long *height)
-{
- *width = advance;
- *height = bbox.yMax - bbox.yMin;
-}
-
-long FT2Font::get_descent()
-{
- return -bbox.yMin;
-}
-
-void FT2Font::get_bitmap_offset(long *x, long *y)
-{
- *x = bbox.xMin;
- *y = 0;
-}
-
-void FT2Font::draw_glyphs_to_bitmap(bool antialiased)
-{
- size_t width = (bbox.xMax - bbox.xMin) / 64 + 2;
- size_t height = (bbox.yMax - bbox.yMin) / 64 + 2;
-
- image.resize(width, height);
-
- for (size_t n = 0; n < glyphs.size(); n++) {
- error = FT_Glyph_To_Bitmap(
- &glyphs[n], antialiased ? FT_RENDER_MODE_NORMAL : FT_RENDER_MODE_MONO, 0, 1);
- if (error) {
- throw std::runtime_error("Could not convert glyph to bitmap");
- }
-
- FT_BitmapGlyph bitmap = (FT_BitmapGlyph)glyphs[n];
- // now, draw to our target surface (convert position)
-
- // bitmap left and top in pixel, string bbox in subpixel
- FT_Int x = (FT_Int)(bitmap->left - (bbox.xMin / 64.));
- FT_Int y = (FT_Int)((bbox.yMax / 64.) - bitmap->top + 1);
-
- image.draw_bitmap(&bitmap->bitmap, x, y);
- }
-}
-
-void FT2Font::get_xys(bool antialiased, std::vector<double> &xys)
-{
- for (size_t n = 0; n < glyphs.size(); n++) {
-
- error = FT_Glyph_To_Bitmap(
- &glyphs[n], antialiased ? FT_RENDER_MODE_NORMAL : FT_RENDER_MODE_MONO, 0, 1);
- if (error) {
- throw std::runtime_error("Could not convert glyph to bitmap");
- }
-
- FT_BitmapGlyph bitmap = (FT_BitmapGlyph)glyphs[n];
-
- // bitmap left and top in pixel, string bbox in subpixel
- FT_Int x = (FT_Int)(bitmap->left - bbox.xMin / 64.);
- FT_Int y = (FT_Int)(bbox.yMax / 64. - bitmap->top + 1);
- // make sure the index is non-neg
- x = x < 0 ? 0 : x;
- y = y < 0 ? 0 : y;
- xys.push_back(x);
- xys.push_back(y);
- }
-}
-
-void FT2Font::draw_glyph_to_bitmap(FT2Image &im, int x, int y, size_t glyphInd, bool antialiased)
-{
- FT_Vector sub_offset;
- sub_offset.x = 0; // int((xd - (double)x) * 64.0);
- sub_offset.y = 0; // int((yd - (double)y) * 64.0);
-
- if (glyphInd >= glyphs.size()) {
- throw std::runtime_error("glyph num is out of range");
- }
-
- error = FT_Glyph_To_Bitmap(&glyphs[glyphInd],
- antialiased ? FT_RENDER_MODE_NORMAL : FT_RENDER_MODE_MONO,
- &sub_offset, // additional translation
- 1 // destroy image
- );
- if (error) {
- throw std::runtime_error("Could not convert glyph to bitmap");
- }
-
- FT_BitmapGlyph bitmap = (FT_BitmapGlyph)glyphs[glyphInd];
-
- im.draw_bitmap(&bitmap->bitmap, x + bitmap->left, y);
-}
-
-void FT2Font::get_glyph_name(unsigned int glyph_number, char *buffer)
-{
- if (!FT_HAS_GLYPH_NAMES(face)) {
- /* Note that this generated name must match the name that
- is generated by ttconv in ttfont_CharStrings_getname. */
- PyOS_snprintf(buffer, 128, "uni%08x", glyph_number);
- } else {
- if (FT_Get_Glyph_Name(face, glyph_number, buffer, 128)) {
- throw std::runtime_error("Could not get glyph names.");
- }
- }
-}
-
-long FT2Font::get_name_index(char *name)
-{
- return FT_Get_Name_Index(face, (FT_String *)name);
-}