Skip to content

Commit 4813ce3

Browse files
committed
Encapsulate Fc unsafe a bit - use a Pattern type for most situations.
1 parent 591d799 commit 4813ce3

File tree

12 files changed

+365
-187
lines changed

12 files changed

+365
-187
lines changed

crates/xetex_layout/cbindgen.toml

+10-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,16 @@ language = "C"
22
cpp_compat = true
33
style = "type"
44
include_guard = "XETEX_LAYOUT_BINDINGS_H"
5-
includes = ["harfbuzz/hb.h", "harfbuzz/hb-ft.h", "fontconfig/fontconfig.h"]
6-
after_includes = "typedef struct XeTeXFont_rec* XeTeXFont;\ntypedef struct XeTeXLayoutEngine_rec* XeTeXLayoutEngine;"
5+
includes = ["harfbuzz/hb.h", "harfbuzz/hb-ft.h"]
6+
after_includes = """
7+
#ifdef XETEX_MAC
8+
#include <ApplicationServices/ApplicationServices.h>
9+
#else
10+
#include <fontconfig/fontconfig.h>
11+
#endif
12+
13+
typedef struct XeTeXFont_rec* XeTeXFont;
14+
typedef struct XeTeXLayoutEngine_rec* XeTeXLayoutEngine;"""
715

816
[export.rename]
917

crates/xetex_layout/layout/layout_bindings.h

+28-1
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,42 @@
77
#include <stdlib.h>
88
#include "harfbuzz/hb.h"
99
#include "harfbuzz/hb-ft.h"
10-
#include "fontconfig/fontconfig.h"
10+
#ifdef XETEX_MAC
11+
#include <ApplicationServices/ApplicationServices.h>
12+
#else
13+
#include <fontconfig/fontconfig.h>
14+
#endif
15+
1116
typedef struct XeTeXFont_rec* XeTeXFont;
1217
typedef struct XeTeXLayoutEngine_rec* XeTeXLayoutEngine;
1318

1419
#define LEFT_SIDE 0
1520

1621
#define RIGHT_SIDE 1
1722

23+
#if !defined(XETEX_MAC)
24+
#define FONT_FAMILY_NAME 1
25+
#endif
26+
27+
#if !defined(XETEX_MAC)
28+
#define FONT_STYLE_NAME 2
29+
#endif
30+
31+
#if !defined(XETEX_MAC)
32+
#define FONT_FULL_NAME 4
33+
#endif
34+
35+
#if !defined(XETEX_MAC)
36+
#define PREFERRED_FAMILY_NAME 16
37+
#endif
38+
39+
#if !defined(XETEX_MAC)
40+
#define PREFERRED_SUBFAMILY_NAME 17
41+
#endif
42+
43+
#if !defined(XETEX_MAC)
1844
typedef int32_t Fixed;
45+
#endif
1946

2047
typedef struct {
2148
float xMin;

crates/xetex_layout/layout/tectonic_xetex_layout.h

+12-41
Original file line numberDiff line numberDiff line change
@@ -39,50 +39,21 @@ authorization from the copyright holders.
3939
#include "tectonic_bridge_core.h"
4040
#include "layout_bindings.h"
4141

42-
/* harfbuzz: hb_tag_t and hb_font_t used below */
43-
#include <harfbuzz/hb.h>
44-
45-
4642
/* Set up our types */
4743

48-
#ifdef XETEX_MAC
49-
50-
#include <ApplicationServices/ApplicationServices.h>
51-
typedef CTFontDescriptorRef PlatformFontRef;
52-
53-
#else /* XETEX_MAC */
54-
55-
#include <fontconfig/fontconfig.h>
56-
typedef FcPattern* PlatformFontRef;
57-
typedef int32_t Fixed; /* macOS defines Fixed in system headers */
58-
59-
#endif /* XETEX_MAC */
44+
//#ifdef XETEX_MAC
45+
//
46+
//#include <ApplicationServices/ApplicationServices.h>
47+
//typedef CTFontDescriptorRef PlatformFontRef;
48+
//
49+
//#else /* XETEX_MAC */
50+
//
51+
//#include <fontconfig/fontconfig.h>
52+
//typedef FcPattern* PlatformFontRef;
53+
//typedef int32_t Fixed; /* macOS defines Fixed in system headers */
54+
//
55+
//#endif /* XETEX_MAC */
6056

6157
typedef uint16_t GlyphID;
6258

63-
typedef struct XeTeXFont_rec* XeTeXFont;
64-
typedef struct XeTeXLayoutEngine_rec* XeTeXLayoutEngine;
65-
66-
/* Now we can defined our C APIs */
67-
68-
BEGIN_EXTERN_C
69-
70-
extern Fixed loaded_font_design_size;
71-
72-
void terminate_font_manager(void);
73-
void destroy_font_manager(void);
74-
75-
PlatformFontRef findFontByName(const char* name, char* var, double size);
76-
77-
char getReqEngine(void);
78-
void setReqEngine(char reqEngine);
79-
const char* getFullName(PlatformFontRef fontRef);
80-
81-
double getDesignSize(XeTeXFont font);
82-
83-
/* Extra APIs needed to encapsulate across the crate boundaries */
84-
const char *ttxl_platfont_get_desc(PlatformFontRef fontRef);
85-
86-
END_EXTERN_C
87-
8859
#endif /* XETEX_LAYOUT_INTERFACE_H */

crates/xetex_layout/layout/xetex-XeTeXFontMgr.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ class XeTeXFontMgr
161161
std::list<std::string> m_styleNames;
162162
std::list<std::string> m_fullNames;
163163
std::string m_psName;
164-
std::string m_subFamily;
164+
// std::string m_subFamily;
165165
};
166166

167167
std::map<std::string,Font*> m_nameToFont; // maps full name (as used in TeX source) to font record

crates/xetex_layout/src/c_api/engine.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ impl XeTeXLayoutEngineBase {
112112

113113
#[no_mangle]
114114
pub unsafe extern "C" fn getFontRef(engine: XeTeXLayoutEngine) -> PlatformFontRef {
115-
(*engine).font_ref
115+
(*engine).font_ref.clone()
116116
}
117117

118118
#[no_mangle]

crates/xetex_layout/src/c_api/fc.rs

+19-59
Original file line numberDiff line numberDiff line change
@@ -1,69 +1,29 @@
1-
#![allow(nonstandard_style, unused)]
1+
use std::convert::TryFrom;
22

3-
pub const FC_FAMILY: *const libc::c_char = c!("family");
4-
pub const FC_STYLE: *const libc::c_char = c!("style");
5-
pub const FC_SLANT: *const libc::c_char = c!("slant");
6-
pub const FC_WEIGHT: *const libc::c_char = c!("weight");
7-
pub const FC_WIDTH: *const libc::c_char = c!("width");
8-
pub const FC_FILE: *const libc::c_char = c!("file");
9-
pub const FC_INDEX: *const libc::c_char = c!("index");
10-
pub const FC_FULLNAME: *const libc::c_char = c!("fullname");
11-
pub const FC_FONTFORMAT: *const libc::c_char = c!("fontformat");
3+
pub mod pat;
4+
pub mod sys;
125

13-
pub type FcBool = libc::c_int;
6+
pub use pat::Pattern;
147

15-
pub const FcTrue: FcBool = 1;
16-
pub const FcFalse: FcBool = 0;
17-
18-
#[repr(C)]
19-
pub struct FcPattern(());
20-
21-
#[repr(C)]
22-
pub struct FcFontSet {
23-
pub nfont: libc::c_int,
24-
sfont: libc::c_int,
25-
pub fonts: *const *const FcPattern,
26-
}
27-
28-
#[repr(C)]
29-
pub struct FcObjectSet(());
30-
31-
#[repr(C)]
32-
pub struct FcConfig(());
33-
34-
#[derive(PartialEq)]
35-
#[repr(C)]
36-
pub enum FcResult {
37-
Match,
8+
#[derive(Debug, PartialEq)]
9+
pub enum FcErr {
3810
NoMatch,
3911
TypeMismatch,
4012
ResultNoId,
4113
OutOfMemory,
4214
}
4315

44-
extern "C" {
45-
pub fn FcPatternGetString(
46-
p: *mut FcPattern,
47-
object: *const libc::c_char,
48-
n: libc::c_int,
49-
s: *mut *const libc::c_char,
50-
) -> FcResult;
51-
pub fn FcPatternGetInteger(
52-
p: *mut FcPattern,
53-
object: *const libc::c_char,
54-
n: libc::c_int,
55-
i: *mut libc::c_int,
56-
) -> FcResult;
57-
pub fn FcInit() -> FcBool;
58-
pub fn FcNameParse(name: *const u8) -> *mut FcPattern;
59-
pub fn FcObjectSetBuild(first: *const libc::c_char, ...) -> *mut FcObjectSet;
60-
pub fn FcFontList(
61-
config: *mut FcConfig,
62-
p: *mut FcPattern,
63-
os: *mut FcObjectSet,
64-
) -> *mut FcFontSet;
65-
pub fn FcConfigGetCurrent() -> *mut FcConfig;
66-
pub fn FcObjectSetDestroy(os: *mut FcObjectSet);
67-
pub fn FcPatternDestroy(pat: *mut FcPattern);
68-
pub fn FcFontSetDestroy(fs: *mut FcFontSet);
16+
impl TryFrom<sys::FcResult> for FcErr {
17+
type Error = ();
18+
19+
fn try_from(value: sys::FcResult) -> Result<Self, Self::Error> {
20+
use sys::FcResult;
21+
Ok(match value {
22+
FcResult::Match => return Err(()),
23+
FcResult::NoMatch => FcErr::NoMatch,
24+
FcResult::TypeMismatch => FcErr::TypeMismatch,
25+
FcResult::ResultNoId => FcErr::ResultNoId,
26+
FcResult::OutOfMemory => FcErr::OutOfMemory,
27+
})
28+
}
6929
}
+107
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
use super::{sys, FcErr};
2+
use std::convert::TryInto;
3+
use std::ffi::CStr;
4+
use std::ptr;
5+
use std::ptr::NonNull;
6+
7+
unsafe fn get_string<'a>(
8+
pat: *mut sys::FcPattern,
9+
ty: *const libc::c_char,
10+
idx: libc::c_int,
11+
) -> Result<&'a CStr, FcErr> {
12+
let mut str = ptr::null();
13+
match unsafe { sys::FcPatternGetString(pat, ty, idx, &mut str) }.try_into() {
14+
Ok(err) => Err(err),
15+
Err(_) => Ok(CStr::from_ptr(str)),
16+
}
17+
}
18+
19+
unsafe fn get_int(
20+
pat: *mut sys::FcPattern,
21+
ty: *const libc::c_char,
22+
idx: libc::c_int,
23+
) -> Result<i32, FcErr> {
24+
let mut int = 0;
25+
match unsafe { sys::FcPatternGetInteger(pat, ty, idx, &mut int) }.try_into() {
26+
Ok(err) => Err(err),
27+
Err(_) => Ok(int as i32),
28+
}
29+
}
30+
31+
pub trait PatParam {
32+
type Output<'a>;
33+
fn get(pat: &Pattern, idx: usize) -> Result<Self::Output<'_>, FcErr>;
34+
}
35+
36+
pub struct File(());
37+
38+
impl PatParam for File {
39+
type Output<'a> = &'a CStr;
40+
41+
fn get(pat: &Pattern, idx: usize) -> Result<Self::Output<'_>, FcErr> {
42+
unsafe { get_string(pat.0.as_ptr(), sys::FC_FILE, idx as libc::c_int) }
43+
}
44+
}
45+
46+
pub struct Family(());
47+
48+
impl PatParam for Family {
49+
type Output<'a> = &'a CStr;
50+
51+
fn get(pat: &Pattern, idx: usize) -> Result<Self::Output<'_>, FcErr> {
52+
unsafe { get_string(pat.0.as_ptr(), sys::FC_FAMILY, idx as libc::c_int) }
53+
}
54+
}
55+
56+
pub struct FullName(());
57+
58+
impl PatParam for FullName {
59+
type Output<'a> = &'a CStr;
60+
61+
fn get(pat: &Pattern, idx: usize) -> Result<Self::Output<'_>, FcErr> {
62+
unsafe { get_string(pat.0.as_ptr(), sys::FC_FULLNAME, idx as libc::c_int) }
63+
}
64+
}
65+
66+
pub struct Style(());
67+
68+
impl PatParam for Style {
69+
type Output<'a> = &'a CStr;
70+
71+
fn get(pat: &Pattern, idx: usize) -> Result<Self::Output<'_>, FcErr> {
72+
unsafe { get_string(pat.0.as_ptr(), sys::FC_STYLE, idx as libc::c_int) }
73+
}
74+
}
75+
76+
pub struct Index(());
77+
78+
impl PatParam for Index {
79+
type Output<'a> = i32;
80+
81+
fn get(pat: &Pattern, idx: usize) -> Result<Self::Output<'_>, FcErr> {
82+
unsafe { get_int(pat.0.as_ptr(), sys::FC_INDEX, idx as libc::c_int) }
83+
}
84+
}
85+
86+
#[derive(Clone, PartialEq, Eq, Hash)]
87+
#[repr(transparent)]
88+
pub struct Pattern(NonNull<sys::FcPattern>);
89+
90+
impl Pattern {
91+
pub unsafe fn from_raw(ptr: *mut sys::FcPattern) -> Option<Pattern> {
92+
NonNull::new(ptr).map(Pattern)
93+
}
94+
95+
pub fn into_raw(self) -> *mut sys::FcPattern {
96+
self.0.as_ptr()
97+
}
98+
99+
pub fn from_name(name: &CStr) -> Option<Pattern> {
100+
let raw = unsafe { sys::FcNameParse(name.as_ptr()) };
101+
NonNull::new(raw).map(Pattern)
102+
}
103+
104+
pub fn get<T: PatParam>(&self, idx: usize) -> Result<T::Output<'_>, FcErr> {
105+
T::get(self, idx)
106+
}
107+
}

0 commit comments

Comments
 (0)