Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add face_index support to celiagg and kiva.agg backends. #605

Merged
merged 8 commits into from
Mar 10, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 22 additions & 8 deletions kiva/agg/agg-24/font_freetype/agg_font_freetype.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,7 @@ namespace agg24
delete [] m_face_names;
delete [] m_faces;
delete [] m_signature;
delete [] m_face_lookup_scratch;
if(m_library_initialized) FT_Done_FreeType(m_library);
}

Expand All @@ -517,9 +518,10 @@ namespace agg24
m_last_error(0),
m_name(0),
m_name_len(256-16-1),
m_face_index(0),
m_char_map(FT_ENCODING_NONE),
m_signature(new char [256+256-16]),
m_face_lookup_scratch_len(512),
m_face_lookup_scratch(new char [m_face_lookup_scratch_len]),
m_height(0),
m_width(0),
m_hinting(true),
Expand Down Expand Up @@ -567,12 +569,24 @@ namespace agg24


//------------------------------------------------------------------------
int font_engine_freetype_base::find_face(const char* face_name) const
int font_engine_freetype_base::find_face(const char* face_name, unsigned face_name_len, unsigned face_index)
{
unsigned i;

if ((face_name_len + 4 + 1) > m_face_lookup_scratch_len)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i'm not entirely sure what the magical 4 and 1 here are.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

4 for the face index (this is the %04u in the format string) and 1 for the NULL.

{
delete [] m_face_lookup_scratch;
m_face_lookup_scratch_len = face_name_len + 4 + 1;
m_face_lookup_scratch = new char [m_face_lookup_scratch_len];
}

// Build the lookup string by combining the face_index and face_name
snprintf(m_face_lookup_scratch, m_face_lookup_scratch_len,
"%04u%s", face_index, face_name);

for(i = 0; i < m_num_faces; ++i)
{
if(strcmp(face_name, m_face_names[i]) == 0) return i;
if(strcmp(m_face_lookup_scratch, m_face_names[i]) == 0) return i;
}
return -1;
}
Expand Down Expand Up @@ -612,7 +626,8 @@ namespace agg24
{
m_last_error = 0;

int idx = find_face(font_name);
unsigned font_name_len = strlen(font_name);
int idx = find_face(font_name, font_name_len, face_index);
if(idx >= 0)
{
m_cur_face = m_faces[idx];
Expand Down Expand Up @@ -651,8 +666,8 @@ namespace agg24

if(m_last_error == 0)
{
m_face_names[m_num_faces] = new char [strlen(font_name) + 1];
strcpy(m_face_names[m_num_faces], font_name);
m_face_names[m_num_faces] = new char [font_name_len + 4 + 1];
sprintf(m_face_names[m_num_faces], "%04u%s", face_index, font_name);
m_cur_face = m_faces[m_num_faces];
m_name = m_face_names[m_num_faces];
++m_num_faces;
Expand Down Expand Up @@ -838,10 +853,9 @@ namespace agg24
}

sprintf(m_signature,
"%s,%u,%d,%d,%d:%dx%d,%d,%d,%08X",
"%s,%u,%d,%d:%dx%d,%d,%d,%08X",
m_name,
m_char_map,
m_face_index,
int(m_glyph_rendering),
m_resolution,
m_height,
Expand Down
5 changes: 3 additions & 2 deletions kiva/agg/agg-24/font_freetype/agg_font_freetype.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,16 +109,17 @@ namespace agg24

void update_char_size();
void update_signature();
int find_face(const char* face_name) const;
int find_face(const char* face_name, unsigned face_name_len, unsigned face_index);

bool m_flag32;
int m_change_stamp;
int m_last_error;
char* m_name;
unsigned m_name_len;
unsigned m_face_index;
FT_Encoding m_char_map;
char* m_signature;
unsigned m_face_lookup_scratch_len;
char* m_face_lookup_scratch;
unsigned m_height;
unsigned m_width;
bool m_hinting;
Expand Down
18 changes: 10 additions & 8 deletions kiva/agg/src/font_type.i
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ namespace kiva
std::string name;
int family;
int style;
int encoding;
int encoding;
int face_index;
std::string filename;

// constructor
Expand All @@ -35,6 +36,7 @@ namespace kiva
int _family=0,
int _style=0,
int _encoding=0,
int _face_index=0,
bool validate=true);

int change_filename(std::string _filename);
Expand All @@ -47,12 +49,11 @@ namespace kiva
char *__repr__()
{
static char tmp[1024];
// Write out elements of trans_affine in a,b,c,d,tx,ty order
// !! We should work to make output formatting conform to
// !! whatever it Numeric does (which needs to be cleaned up also).
sprintf(tmp,"Font(%s,%d,%d,%d,%d)", self->name.c_str(), self->family,
self->size, self->style,
self->encoding);
sprintf(tmp,"Font(%s,%d,%d,%d,%d,%d)",
self->name.c_str(), self->family, self->size, self->style,
self->encoding, self->face_index);
return tmp;
}
int __eq__(kiva::font_type& other)
Expand All @@ -61,14 +62,15 @@ namespace kiva
self->family == other.family &&
self->size == other.size &&
self->style == other.style &&
self->encoding == other.encoding);
self->encoding == other.encoding &&
self->face_index == other.face_index);
}
}

%pythoncode
%{
def unicode_safe_init(self, _name="Arial", _size=12, _family=0, _style=0,
_encoding=0, validate=True):
_encoding=0, _face_index=0, validate=True):
### HACK: C++ stuff expects a string (not unicode) for the face_name, so fix
### if needed.
### Only for python < 3
Expand All @@ -79,7 +81,7 @@ def unicode_safe_init(self, _name="Arial", _size=12, _family=0, _style=0,
if isinstance(_name, bytes):
_name = _name.decode()
obj = _agg.new_AggFontType(_name, _size, _family, _style,
_encoding, validate)
_encoding, _face_index, validate)
_swig_setattr(self, AggFontType, "this", obj)
_swig_setattr(self, AggFontType, "thisown", 1)

Expand Down
7 changes: 4 additions & 3 deletions kiva/agg/src/graphics_context.i
Original file line number Diff line number Diff line change
Expand Up @@ -561,11 +561,12 @@ namespace kiva {
and (font.encoding == cur_font.encoding):
return
else:
newfilename = font.findfont()
spec = font.findfont()
agg_font = AggFontType(font.face_name, font.size, font.family, font.style,
font.encoding, False)
agg_font.filename = newfilename
font.encoding, spec.face_index, False)
agg_font.filename = spec.filename
else:
# XXX: What are we expecting here?
agg_font = AggFontType(font.face_name, font.size, font.family, font.style, font.encoding)
try:
retval = _agg.GraphicsContextArray_set_font(self, agg_font)
Expand Down
11 changes: 6 additions & 5 deletions kiva/agg/src/kiva_font_type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,10 @@ const char* freetype_suffixes[] = { ".ttf", ".pfa", ".pfb" };
// Therefore this simple function is left in.

kiva::font_type::font_type(std::string _name, int _size, int _family,
int _style, int _encoding, bool validate):
int _style, int _encoding, int _face_index, bool validate):
name(_name), size(_size), family(_family), style(_style),
encoding(_encoding), _is_loaded(false)
encoding(_encoding), face_index(_face_index),
_is_loaded(false)
{
std::string full_file_name;
if (validate)
Expand Down Expand Up @@ -83,10 +84,9 @@ kiva::font_type::font_type(std::string _name, int _size, int _family,

kiva::font_type::font_type(const kiva::font_type &font) :
name(font.name), filename(font.filename), size(font.size),
_is_loaded(font.is_loaded())
family(font.family), style(font.style), encoding(font.encoding),
face_index(font.face_index), _is_loaded(font.is_loaded())
{
this->family = font.family;
this->style = font.style;
}

kiva::font_type &kiva::font_type::operator=(const kiva::font_type& font)
Expand All @@ -95,6 +95,7 @@ kiva::font_type &kiva::font_type::operator=(const kiva::font_type& font)
this->family = font.family;
this->style = font.style;
this->encoding = font.encoding;
this->face_index = font.face_index;
this->name = font.name;
this->filename = font.filename;
this->_is_loaded = font.is_loaded();
Expand Down
4 changes: 3 additions & 1 deletion kiva/agg/src/kiva_font_type.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ namespace kiva
int family;
int style;
int encoding;
int face_index;

// Constructors

Expand All @@ -39,6 +40,7 @@ namespace kiva
int _family=0,
int _style=0,
int _encoding=0,
int _face_index=0,
bool validate=true);

font_type(const font_type &font);
Expand All @@ -57,7 +59,7 @@ namespace kiva
{
return (a.size == b.size) && (a.name == b.name) &&
(a.style == b.style) && (a.encoding == b.encoding) &&
(a.family == b.family);
(a.family == b.family) && (a.face_index == b.face_index);
}


Expand Down
4 changes: 2 additions & 2 deletions kiva/agg/src/kiva_graphics_context_base.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -668,12 +668,12 @@ void graphics_context_base::_grab_font_manager()
#ifdef KIVA_USE_FREETYPE
if (font->filename != "")
{
font_engine->load_font(font->filename.c_str(), 0,
font_engine->load_font(font->filename.c_str(), font->face_index,
agg24::glyph_ren_agg_gray8);
}
else
{
font_engine->load_font(font->name.c_str(), 0,
font_engine->load_font(font->name.c_str(), font->face_index,
agg24::glyph_ren_agg_gray8);
}
#endif
Expand Down
17 changes: 12 additions & 5 deletions kiva/celiagg.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,15 @@
from collections import namedtuple
from math import fabs
import os
import sys
import warnings

import celiagg as agg
import numpy as np

from .abstract_graphics_context import AbstractGraphicsContext
from .fonttools import Font
from kiva.abstract_graphics_context import AbstractGraphicsContext
import kiva.constants as constants
from kiva.fonttools import Font

# These are the symbols that a backend has to define.
__all__ = ["CompiledPath", "Font", "font_metrics_provider", "GraphicsContext"]
Expand Down Expand Up @@ -616,16 +617,22 @@ def select_font(self, face_name, size=12, style='regular', encoding=None):
def set_font(self, font):
""" Set the font for the current graphics context.
"""
self.font = agg.Font(font.findfont(), font.size)
if sys.platform in ('win32', 'cygwin'):
# Win32 font selection is handled by the OS
self.font = agg.Font(font.findfontname(), font.size)
else:
# FreeType font selection is handled by kiva
spec = font.findfont()
self.font = agg.Font(spec.filename, font.size, spec.face_index)

def set_font_size(self, size):
""" Set the font size for the current graphics context.
"""
if self.font is None:
return

font = self.font
self.select_font(font.filepath, size)
# Just set a new height
self.font.height = size

def set_character_spacing(self, spacing):
msg = "set_character_spacing not implemented on celiagg yet."
Expand Down
8 changes: 4 additions & 4 deletions kiva/fonttools/font.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,11 +112,11 @@ def __init__(self, face_name="", size=12, family=SWISS, weight=NORMAL,
self.encoding = encoding

def findfont(self):
""" Returns the file name containing the font that most closely matches
our font properties.
""" Returns the file name and face index of the font that most closely
matches our font properties.
"""
fp = self._make_font_props()
return str(default_font_manager().findfont(fp))
return default_font_manager().findfont(fp)

def findfontname(self):
""" Returns the name of the font that most closely matches our font
Expand Down Expand Up @@ -181,7 +181,7 @@ def __ne__(self, other):
def __repr__(self):
fmt = (
"Font(size=%d,family=%d,weight=%d, style=%d, face_name='%s', "
+ "encoding=%d)"
"encoding=%d)"
)
return fmt % (
self.size,
Expand Down
Loading