Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit b5bda9b

Browse files
committed
ft2font: Add internal API for accessing font variations
1 parent 2e0fee1 commit b5bda9b

5 files changed

Lines changed: 418 additions & 0 deletions

File tree

lib/matplotlib/ft2font.pyi

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,34 @@ class _SfntPcltDict(TypedDict):
215215
widthType: int
216216
serifStyle: int
217217

218+
class VarAxisFlags(Flag):
219+
DEFAULT = cast(int, ...)
220+
HIDDEN = cast(int, ...)
221+
222+
@final
223+
class VariationAxis:
224+
@property
225+
def name(self) -> str: ...
226+
@property
227+
def minimum(self) -> float: ...
228+
@property
229+
def default(self) -> float: ...
230+
@property
231+
def maximum(self) -> float: ...
232+
@property
233+
def tag(self) -> int: ...
234+
@property
235+
def names(self) -> dict[tuple[int, int, int], str | bytes]: ...
236+
@property
237+
def flags(self) -> VarAxisFlags: ...
238+
239+
@final
240+
class VariationNamedStyle:
241+
@property
242+
def names(self) -> dict[tuple[int, int, int], str | bytes]: ...
243+
@property
244+
def psnames(self) -> dict[tuple[int, int, int], str | bytes] | None: ...
245+
218246
@final
219247
class LayoutItem:
220248
@property
@@ -299,6 +327,10 @@ class FT2Font(Buffer):
299327
features: tuple[str] | None = ...,
300328
language: str | list[tuple[str, int, int]] | None = ...,
301329
) -> NDArray[np.float64]: ...
330+
def get_variation_descriptor(self) -> tuple[list[VariationAxis], list[VariationNamedStyle]]: ...
331+
def get_default_variation_style(self) -> int: ...
332+
def get_variations(self) -> tuple[float, ...]: ...
333+
def set_variations(self, variations: tuple[float, ...] | int) -> None: ...
302334
@property
303335
def ascender(self) -> int: ...
304336
@property

lib/matplotlib/tests/test_ft2font.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -905,6 +905,20 @@ def test_ft2font_loading():
905905
assert font.get_bitmap_offset() == (0, 0)
906906

907907

908+
def test_ft2font_variations_invalid():
909+
# Smoke test as we don't have a font that has variations built in.
910+
file = fm.findfont('DejaVu Sans')
911+
font = ft2font.FT2Font(file)
912+
with pytest.raises(RuntimeError):
913+
font.get_variation_descriptor()
914+
with pytest.raises(RuntimeError):
915+
font.get_variations()
916+
with pytest.raises(RuntimeError):
917+
font.get_default_variation_style()
918+
with pytest.raises(RuntimeError):
919+
font.set_variations([0.0])
920+
921+
908922
def test_ft2font_drawing():
909923
expected_str = (
910924
' ',

src/ft2font.cpp

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -780,3 +780,73 @@ long FT2Font::get_name_index(char *name)
780780
{
781781
return FT_Get_Name_Index(face, (FT_String *)name);
782782
}
783+
784+
FT2Font::VariationInfo FT2Font::get_variation_descriptor()
785+
{
786+
FT_MM_Var *master;
787+
FT_CHECK(FT_Get_MM_Var, face, &master);
788+
789+
std::vector<VariationAxis> axes;
790+
axes.reserve(master->num_axis);
791+
for (FT_UInt axis_index = 0; axis_index < master->num_axis; axis_index++) {
792+
FT_UInt flags = 0;
793+
FT_CHECK(FT_Get_Var_Axis_Flags, master, axis_index, &flags);
794+
const auto &axis = master->axis[axis_index];
795+
axes.emplace_back(axis.name,
796+
float(axis.minimum) / (1<<16),
797+
float(axis.def) / (1<<16),
798+
float(axis.maximum) / (1<<16),
799+
axis.tag,
800+
axis.strid,
801+
flags);
802+
}
803+
804+
std::vector<VariationNamedStyle> styles;
805+
styles.reserve(master->num_namedstyles);
806+
for (FT_UInt instance = 0; instance < master->num_namedstyles; instance++) {
807+
const auto &style = master->namedstyle[instance];
808+
styles.emplace_back(style.strid, style.psid);
809+
}
810+
811+
FT_CHECK(FT_Done_MM_Var, _ft2Library, master);
812+
813+
return {axes, styles};
814+
}
815+
816+
FT_UInt FT2Font::get_default_variation_style() {
817+
FT_UInt result;
818+
FT_CHECK(FT_Get_Default_Named_Instance, face, &result);
819+
return result;
820+
}
821+
822+
std::vector<double> FT2Font::get_variations() {
823+
FT_MM_Var *master;
824+
FT_CHECK(FT_Get_MM_Var, face, &master);
825+
std::vector<FT_Fixed> fixed_coords(master->num_axis);
826+
FT_CHECK(FT_Done_MM_Var, _ft2Library, master);
827+
828+
FT_CHECK(FT_Get_Var_Design_Coordinates, face, fixed_coords.size(),
829+
fixed_coords.data());
830+
831+
std::vector<double> coords;
832+
coords.reserve(fixed_coords.size());
833+
for (auto const &c : fixed_coords) {
834+
coords.emplace_back(static_cast<double>(c) / (1 << 16));
835+
}
836+
837+
return coords;
838+
}
839+
840+
void FT2Font::set_variations(std::vector<double> coords) {
841+
std::vector<FT_Fixed> fixed_coords;
842+
fixed_coords.reserve(coords.size());
843+
for (auto const &c : coords) {
844+
fixed_coords.emplace_back(static_cast<FT_Fixed>(c * (1 << 16)));
845+
}
846+
FT_CHECK(FT_Set_Var_Design_Coordinates, face, fixed_coords.size(),
847+
fixed_coords.data());
848+
}
849+
850+
void FT2Font::set_variations(FT_UInt instance_index) {
851+
FT_CHECK(FT_Set_Named_Instance, face, instance_index);
852+
}

src/ft2font.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,11 @@ extern "C" {
2222
#include FT_BITMAP_H
2323
#include FT_FREETYPE_H
2424
#include FT_GLYPH_H
25+
#include FT_MULTIPLE_MASTERS_H
2526
#include FT_OUTLINE_H
2627
#include FT_SFNT_NAMES_H
2728
#include FT_TYPE1_TABLES_H
29+
#include FT_TRUETYPE_IDS_H
2830
#include FT_TRUETYPE_TABLES_H
2931
}
3032

@@ -183,6 +185,23 @@ class FT2Font
183185
return FT_HAS_KERNING(face);
184186
}
185187

188+
using VariationAxis = std::tuple<
189+
std::string, // name
190+
FT_Fixed, // minimum
191+
FT_Fixed, // default
192+
FT_Fixed, // maximum
193+
FT_ULong, // tag
194+
FT_UInt, // name ID
195+
FT_UInt>; // flags
196+
using VariationNamedStyle = std::tuple<FT_UInt, FT_UInt>; // name ID, postscript ID
197+
using VariationInfo = std::tuple<std::vector<VariationAxis>,
198+
std::vector<VariationNamedStyle>>;
199+
VariationInfo get_variation_descriptor();
200+
FT_UInt get_default_variation_style();
201+
std::vector<double> get_variations();
202+
void set_variations(std::vector<double> coords);
203+
void set_variations(FT_UInt instance_index);
204+
186205
protected:
187206
virtual void ft_glyph_warn(FT_ULong charcode, std::set<FT_String*> family_names) = 0;
188207
private:

0 commit comments

Comments
 (0)