Skip to content

Commit

Permalink
Divide Font descriptions into FreeType and Win32. (#85)
Browse files Browse the repository at this point in the history
The Font class is still available and won't break existing code,
but now the code is more explicit about what a Font object describes.
  • Loading branch information
jwiggins authored Mar 5, 2021
1 parent d39fe45 commit 5b789dc
Show file tree
Hide file tree
Showing 14 changed files with 276 additions and 77 deletions.
32 changes: 23 additions & 9 deletions celiagg/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,15 @@
#
# Authors: Erik Hvatum <[email protected]>
# John Wiggins
import sys

from . import _celiagg
from ._celiagg import (
AggError, BSpline, BlendMode, DrawingMode, Font, FontCache,
GradientSpread, GradientUnits, GraphicsState, Image, InnerJoin,
LineCap, LineJoin, LinearGradientPaint, Path, PatternPaint, PatternStyle,
PixelFormat, RadialGradientPaint, Rect, ShapeAtPoints, SolidPaint,
TextDrawingMode, Transform,
AggError, BSpline, BlendMode, DrawingMode, FontCache, FontWeight,
FreeTypeFont, GradientSpread, GradientUnits, GraphicsState, Image,
InnerJoin, LineCap, LineJoin, LinearGradientPaint, Path, PatternPaint,
PatternStyle, PixelFormat, RadialGradientPaint, Rect, ShapeAtPoints,
SolidPaint, TextDrawingMode, Transform, Win32Font,
)

# Query the library
Expand All @@ -43,6 +44,12 @@ def example_font():
"""
import pkg_resources

# Windows GDI font selection uses names and not file paths.
# Our included font could be added to the system fonts using
# `AddFontResourceEx`, but that's beyond the scope of this function.
if sys.platform in ('win32', 'cygwin'):
return 'Segoe UI'

return pkg_resources.resource_filename(
'celiagg', 'data/Montserrat-Regular.ttf'
)
Expand All @@ -53,15 +60,22 @@ def example_font():
'HAS_TEXT', 'example_font',

'AggError', 'BlendMode', 'BSpline', 'DrawingMode', 'Font', 'FontCache',
'GradientSpread', 'GradientUnits', 'GraphicsState', 'Image', 'InnerJoin',
'LinearGradientPaint', 'LineCap', 'LineJoin', 'RadialGradientPaint',
'Path', 'PatternPaint', 'PatternStyle', 'PixelFormat', 'Rect',
'ShapeAtPoints', 'SolidPaint', 'TextDrawingMode', 'Transform',
'FontWeight', 'FreeTypeFont', 'GradientSpread', 'GradientUnits',
'GraphicsState', 'Image', 'InnerJoin', 'LinearGradientPaint', 'LineCap',
'LineJoin', 'RadialGradientPaint', 'Path', 'PatternPaint', 'PatternStyle',
'PixelFormat', 'Rect', 'ShapeAtPoints', 'SolidPaint', 'TextDrawingMode',
'Transform', 'Win32Font',

'CanvasG8', 'CanvasGA16', 'CanvasRGB24', 'CanvasRGBA32', 'CanvasBGRA32',
'CanvasRGBA128',
]

# Select the correct font class for the platform
if sys.platform in ('win32', 'cygwin'):
Font = Win32Font
else:
Font = FreeTypeFont

# Keep a font cache for callers that don't want to mess with it
__global_font_cache = None

Expand Down
18 changes: 16 additions & 2 deletions celiagg/_enums.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,24 @@
#
# Authors: John Wiggins

cdef extern from "font.h" namespace "Font":
cdef enum FontWeight:
k_FontWeightAny
k_FontWeightThin
k_FontWeightExtraLight
k_FontWeightLight
k_FontWeightRegular
k_FontWeightMedium
k_FontWeightSemiBold
k_FontWeightBold
k_FontWeightExtraBold
k_FontWeightHeavy


cdef extern from "font_cache.h" namespace "FontCache":
cdef enum GlyphType:
RasterGlyph
VectorGlyph
k_GlyphTypeRaster
k_GlyphTypeVector


cdef extern from "image.h":
Expand Down
9 changes: 7 additions & 2 deletions celiagg/_font.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,22 @@
# Authors: John Wiggins

from libcpp cimport bool
cimport _enums


cdef extern from "font.h":
cdef cppclass Font:
Font(char* fileName, double height, unsigned face_index)
Font(char* fileName, double height, unsigned face_index, _enums.FontWeight weight, bool italic)

unsigned face_index() const
const char* filepath() const
const char* face_or_path() const
bool flip() const
void flip(bool flip)
double height() const
void height(double height)
bool hinting() const
void hinting(bool hint)
bool italic() const
void italic(bool italic)
_enums.FontWeight weight() const
void weight(_enums.FontWeight weight)
12 changes: 12 additions & 0 deletions celiagg/enums.pxi
Original file line number Diff line number Diff line change
Expand Up @@ -106,3 +106,15 @@ cpdef enum BlendMode:
BlendSoftLight = _enums.BlendSoftLight
BlendDifference = _enums.BlendDifference
BlendExclusion = _enums.BlendExclusion

cpdef enum FontWeight:
Any = _enums.k_FontWeightAny
Thin = _enums.k_FontWeightThin
ExtraLight = _enums.k_FontWeightExtraLight
Light = _enums.k_FontWeightLight
Regular = _enums.k_FontWeightRegular
Medium = _enums.k_FontWeightMedium
SemiBold = _enums.k_FontWeightSemiBold
Bold = _enums.k_FontWeightBold
ExtraBold = _enums.k_FontWeightExtraBold
Heavy = _enums.k_FontWeightHeavy
38 changes: 33 additions & 5 deletions celiagg/font.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,16 @@

#include "font.h"

Font::Font(char const* fontName, double const height, unsigned const face_index)
: m_height(height)
, m_font_name(fontName)
Font::Font(char const* face_or_path, double const height,
unsigned const face_index, Font::FontWeight const weight,
bool const italic)
: m_face_or_path(face_or_path)
, m_height(height)
, m_weight(weight)
, m_face_index(face_index)
, m_flip(false)
, m_hinting(true)
, m_italic(italic)
{}

unsigned
Expand All @@ -40,9 +44,9 @@ Font::face_index() const
}

const char*
Font::filepath() const
Font::face_or_path() const
{
return m_font_name.c_str();
return m_face_or_path.c_str();
}

bool
Expand Down Expand Up @@ -80,3 +84,27 @@ Font::hinting(bool const hint)
{
m_hinting = hint;
}

bool
Font::italic() const
{
return m_italic;
}

void
Font::italic(bool const italic)
{
m_italic = italic;
}

Font::FontWeight
Font::weight() const
{
return m_weight;
}

void
Font::weight(Font::FontWeight const weight)
{
m_weight = weight;
}
55 changes: 40 additions & 15 deletions celiagg/font.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,29 +31,54 @@
class Font
{
public:
// These map directly to the weights used by the WinGDI CreateFont function
enum FontWeight {
k_FontWeightAny = 0,
k_FontWeightThin = 100,
k_FontWeightExtraLight = 200,
k_FontWeightLight = 300,
k_FontWeightRegular = 400,
k_FontWeightMedium = 500,
k_FontWeightSemiBold = 600,
k_FontWeightBold = 700,
k_FontWeightExtraBold = 800,
k_FontWeightHeavy = 900,
};

Font(char const* fileName, double const height,
unsigned const face_index = 0);
public:

Font(char const* face_or_path, double const height,
unsigned const face_index = 0,
FontWeight const weight = k_FontWeightRegular,
bool const italic = false);

unsigned face_index() const;
const char* face_or_path() const;

bool flip() const;
void flip(bool const flip);

unsigned face_index() const;
const char* filepath() const;
double height() const;
void height(double const height);

bool flip() const;
void flip(bool const flip);
bool hinting() const;
void hinting(bool const hint);

double height() const;
void height(double const height);
bool italic() const;
void italic(bool const italic);

bool hinting() const;
void hinting(bool const hint);
FontWeight weight() const;
void weight(FontWeight const weight);

private:

double m_height;
std::string m_font_name;
unsigned m_face_index;
bool m_flip;
bool m_hinting;
std::string m_face_or_path;
double m_height;
FontWeight m_weight;
unsigned m_face_index;
bool m_flip;
bool m_hinting;
bool m_italic;
};

#endif // CELIAGG_FONT_H
92 changes: 67 additions & 25 deletions celiagg/font.pxi
Original file line number Diff line number Diff line change
Expand Up @@ -23,37 +23,15 @@
#
# Authors: John Wiggins


cdef class Font:
"""Font(path, size, face_index=0)
:param path: A Unicode string containing the path of a ``Font`` file
:param size: The size of the font
:param face_index: For .ttc fonts, the index of the desired font within
the collection.
@cython.internal
cdef class FontBase:
""" Base class for fonts
"""
cdef _font.Font* _this

def __cinit__(self, fontName, double size, unsigned face_index=0):
fontName = _get_utf8_text(fontName,
"Font path must be a unicode string")
self._this = new _font.Font(fontName, size, face_index)

def __dealloc__(self):
del self._this

def copy(self):
return Font(self._this.filepath(), self._this.height(),
self._this.face_index())

property face_index:
def __get__(self):
return self._this.face_index()

property filepath:
def __get__(self):
return self._this.filepath()

property flip:
def __get__(self):
return self._this.flip()
Expand All @@ -71,3 +49,67 @@ cdef class Font:
return self._this.hinting()
def __set__(self, bool value):
self._this.hinting(value)


cdef class FreeTypeFont(FontBase):
"""FreeTypeFont(path, size, face_index=0)
:param path: A Unicode string containing the path of a font file.
:param size: The size of the font
:param face_index: For .ttc fonts, the index of the desired font within
the collection.
"""

def __cinit__(self, path, double size, unsigned face_index=0):
path = _get_utf8_text(path, "Font path must be a unicode string")
self._this = new _font.Font(path, size, face_index,
# Ignored argument values
_enums.FontWeight.k_FontWeightAny, False)

def copy(self):
return FreeTypeFont(self._this.face_or_path(), self._this.height(),
self._this.face_index())

property face_index:
def __get__(self):
return self._this.face_index()

property filepath:
def __get__(self):
return self._this.face_or_path().decode('utf8')



cdef class Win32Font(FontBase):
"""Win32Font(face_name, size, weight=FontWeight.Regular, italic=False)
:param face_name: A Unicode string containing the the face name of a font
known to the system.
:param size: The size of the font.
:param weight: A FontWeight value.
:param italic: If True, pick an italic font.
"""
def __cinit__(self, face, double size,
FontWeight weight=FontWeight.Regular, bool italic=False):
face = _get_utf8_text(face, "Font face must be a unicode string")
self._this = new _font.Font(face, size, 0, weight, italic)

def copy(self):
return Win32Font(self._this.face_or_path(), self._this.height(),
self._this.weight(), self._this.italic())

property face_name:
def __get__(self):
return self._this.face_or_path().decode('utf8')

property italic:
def __get__(self):
return self._this.italic()
def __set__(self, bool value):
self._this.italic(value)

property weight:
def __get__(self):
return self._this.weight()
def __set__(self, FontWeight value):
self._this.weight(value)
Loading

0 comments on commit 5b789dc

Please sign in to comment.