-
Notifications
You must be signed in to change notification settings - Fork 20
Expand file tree
/
Copy pathfont_face.cpp
More file actions
149 lines (120 loc) · 3.41 KB
/
Copy pathfont_face.cpp
File metadata and controls
149 lines (120 loc) · 3.41 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
/*
* Copyright (C) 2026 Shitty team
* MIT licensed
* See the file LICENSE.MIT for the full license.
*/
#include "font_face.h"
#include <std/lib/buffer.h>
#include <std/ptr/arc.h>
#include <std/str/builder.h>
#include <std/str/view.h>
#include <std/sys/throw.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>
using namespace stl;
namespace {
struct CountedFontFace: public FontFace {
u32 id() const noexcept override;
void ref() noexcept override;
i32 unref() noexcept override;
i32 refCount() const noexcept override;
const u32 id_ = nextFontFaceId();
ARC arc_;
};
struct MemoryFontFace final: public CountedFontFace {
MemoryFontFace(const void* data, size_t size, i32 faceIndex);
const void* data() const override;
size_t size() const override;
i32 faceIndex() const override;
const void* data_;
size_t size_;
i32 faceIndex_;
};
struct MmapFontFace final: public CountedFontFace {
MmapFontFace(void* data, size_t size, i32 faceIndex);
~MmapFontFace() noexcept override;
const void* data() const override;
size_t size() const override;
i32 faceIndex() const override;
void* data_;
size_t size_;
i32 faceIndex_;
};
}
u32 nextFontFaceId() noexcept {
static u32 counter = 0;
return counter++;
}
FontFace::~FontFace() noexcept {
}
u32 CountedFontFace::id() const noexcept {
return id_;
}
void CountedFontFace::ref() noexcept {
arc_.ref();
}
i32 CountedFontFace::unref() noexcept {
return arc_.unref();
}
i32 CountedFontFace::refCount() const noexcept {
return arc_.refCount();
}
MemoryFontFace::MemoryFontFace(const void* data, size_t size, i32 faceIndex)
: data_(data)
, size_(size)
, faceIndex_(faceIndex)
{
}
const void* MemoryFontFace::data() const {
return data_;
}
size_t MemoryFontFace::size() const {
return size_;
}
i32 MemoryFontFace::faceIndex() const {
return faceIndex_;
}
MmapFontFace::MmapFontFace(void* data, size_t size, i32 faceIndex)
: data_(data)
, size_(size)
, faceIndex_(faceIndex)
{
}
MmapFontFace::~MmapFontFace() noexcept {
munmap(data_, size_);
}
const void* MmapFontFace::data() const {
return data_;
}
size_t MmapFontFace::size() const {
return size_;
}
i32 MmapFontFace::faceIndex() const {
return faceIndex_;
}
FontFace* createMemoryFontFace(const void* data, size_t size, i32 faceIndex) {
return new MemoryFontFace(data, size, faceIndex);
}
FontFace* openFontFile(StringView path, i32 faceIndex) {
Buffer filename(path);
const int fd = open(filename.cStr(), O_RDONLY | O_CLOEXEC);
if (fd < 0) {
Errno().raise(StringBuilder() << StringView(u8"failed to open font ") << path);
}
struct stat status {};
if (fstat(fd, &status) != 0 || status.st_size <= 0) {
const int error = errno;
close(fd);
Errno(error == 0 ? EINVAL : error).raise(StringBuilder() << StringView(u8"failed to measure font ") << path);
}
void* const data = mmap(nullptr, (size_t)(status.st_size), PROT_READ, MAP_PRIVATE, fd, 0);
const int error = errno;
close(fd);
if (data == MAP_FAILED) {
Errno(error).raise(StringBuilder() << StringView(u8"failed to map font ") << path);
}
return new MmapFontFace(data, (size_t)(status.st_size), faceIndex);
}