/src/serenity/Userland/Libraries/LibGfx/Font/BitmapFont.h
Line | Count | Source |
1 | | /* |
2 | | * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> |
3 | | * |
4 | | * SPDX-License-Identifier: BSD-2-Clause |
5 | | */ |
6 | | |
7 | | #pragma once |
8 | | |
9 | | #include <AK/ByteString.h> |
10 | | #include <AK/CharacterTypes.h> |
11 | | #include <AK/RefCounted.h> |
12 | | #include <AK/RefPtr.h> |
13 | | #include <AK/Types.h> |
14 | | #include <AK/Vector.h> |
15 | | #include <LibCore/MappedFile.h> |
16 | | #include <LibCore/Resource.h> |
17 | | #include <LibGfx/Font/Font.h> |
18 | | #include <LibGfx/Size.h> |
19 | | |
20 | | namespace Gfx { |
21 | | |
22 | | class BitmapFont final : public Font { |
23 | | public: |
24 | | virtual NonnullRefPtr<Font> clone() const override; |
25 | | virtual ErrorOr<NonnullRefPtr<Font>> try_clone() const override; |
26 | | static ErrorOr<NonnullRefPtr<BitmapFont>> create(u8 glyph_height, u8 glyph_width, bool fixed, size_t glyph_count); |
27 | | |
28 | | virtual FontPixelMetrics pixel_metrics() const override; |
29 | | |
30 | | ErrorOr<NonnullRefPtr<BitmapFont>> masked_character_set() const; |
31 | | ErrorOr<NonnullRefPtr<BitmapFont>> unmasked_character_set() const; |
32 | | |
33 | | static NonnullRefPtr<BitmapFont> load_from_uri(StringView); |
34 | | static ErrorOr<NonnullRefPtr<BitmapFont>> try_load_from_uri(StringView); |
35 | | static ErrorOr<NonnullRefPtr<BitmapFont>> try_load_from_resource(NonnullRefPtr<Core::Resource>); |
36 | | static ErrorOr<NonnullRefPtr<BitmapFont>> try_load_from_mapped_file(NonnullOwnPtr<Core::MappedFile>); |
37 | | static ErrorOr<NonnullRefPtr<BitmapFont>> try_load_from_stream(FixedMemoryStream&); |
38 | | |
39 | | ErrorOr<void> write_to_file(ByteString const& path); |
40 | | ErrorOr<void> write_to_file(NonnullOwnPtr<Core::File> file); |
41 | | |
42 | | ~BitmapFont(); |
43 | | |
44 | 0 | Bytes rows() { return m_rows; } |
45 | 0 | Span<u8> widths() { return m_glyph_widths; } |
46 | | |
47 | 0 | virtual float point_size() const override { return m_presentation_size; } |
48 | | |
49 | 0 | u8 presentation_size() const override { return m_presentation_size; } |
50 | 0 | void set_presentation_size(u8 size) { m_presentation_size = size; } |
51 | | |
52 | 0 | virtual float pixel_size() const override { return m_glyph_height; } |
53 | 0 | virtual int pixel_size_rounded_up() const override { return m_glyph_height; } |
54 | | |
55 | 0 | u16 width() const override { return FontWidth::Normal; } |
56 | | |
57 | 0 | u16 weight() const override { return m_weight; } |
58 | 0 | void set_weight(u16 weight) { m_weight = weight; } |
59 | | |
60 | 0 | virtual u8 slope() const override { return m_slope; } |
61 | 0 | void set_slope(u8 slope) { m_slope = slope; } |
62 | | |
63 | | Optional<Glyph> glyph(u32 code_point) const override; |
64 | 0 | Optional<Glyph> glyph(u32 code_point, GlyphSubpixelOffset) const override { return glyph(code_point); } |
65 | 0 | Optional<Glyph> glyph_for_postscript_name(StringView, GlyphSubpixelOffset) const override { return {}; } |
66 | | |
67 | 0 | float glyph_left_bearing(u32) const override { return 0; } |
68 | 0 | Optional<float> glyph_left_bearing_for_postscript_name(StringView) const override { return {}; } |
69 | | |
70 | | Glyph raw_glyph(u32 code_point) const; |
71 | | bool contains_glyph(u32 code_point) const override; |
72 | 0 | bool contains_glyph_for_postscript_name(StringView) const override { return false; } |
73 | 0 | bool contains_raw_glyph(u32 code_point) const { return m_glyph_widths[code_point] > 0; } |
74 | | |
75 | | virtual float glyph_or_emoji_width(Utf8CodePointIterator&) const override; |
76 | | virtual float glyph_or_emoji_width(Utf32CodePointIterator&) const override; |
77 | | |
78 | 0 | float glyphs_horizontal_kerning(u32, u32) const override { return 0.f; } |
79 | 0 | u8 glyph_height() const { return m_glyph_height; } |
80 | 0 | int x_height() const override { return m_x_height; } |
81 | 0 | virtual float preferred_line_height() const override { return glyph_height() + m_line_gap; } |
82 | | |
83 | | virtual float glyph_width(u32 code_point) const override; |
84 | 0 | virtual Optional<float> glyph_width_for_postscript_name(StringView) const override { return {}; } |
85 | 0 | u8 raw_glyph_width(u32 code_point) const { return m_glyph_widths[code_point]; } |
86 | | |
87 | 0 | u8 min_glyph_width() const override { return m_min_glyph_width; } |
88 | 0 | u8 max_glyph_width() const override { return m_max_glyph_width; } |
89 | 0 | u8 glyph_fixed_width() const override { return m_glyph_width; } |
90 | | |
91 | 0 | u8 baseline() const override { return m_baseline; } |
92 | | void set_baseline(u8 baseline) |
93 | 0 | { |
94 | 0 | m_baseline = baseline; |
95 | 0 | update_x_height(); |
96 | 0 | } |
97 | | |
98 | 0 | u8 mean_line() const override { return m_mean_line; } |
99 | | void set_mean_line(u8 mean_line) |
100 | 0 | { |
101 | 0 | m_mean_line = mean_line; |
102 | 0 | update_x_height(); |
103 | 0 | } |
104 | | |
105 | | virtual float width(StringView) const override; |
106 | | virtual float width(Utf8View const&) const override; |
107 | | virtual float width(Utf32View const&) const override; |
108 | | |
109 | | virtual int width_rounded_up(StringView) const override; |
110 | | |
111 | 0 | virtual String name() const override { return m_name; } |
112 | 0 | void set_name(String name) { m_name = move(name); } |
113 | | |
114 | 0 | bool is_fixed_width() const override { return m_fixed_width; } |
115 | 0 | void set_fixed_width(bool b) { m_fixed_width = b; } |
116 | | |
117 | 0 | u8 glyph_spacing() const override { return m_glyph_spacing; } |
118 | 0 | void set_glyph_spacing(u8 spacing) { m_glyph_spacing = spacing; } |
119 | | |
120 | | void set_glyph_width(u32 code_point, u8 width) |
121 | 0 | { |
122 | 0 | m_glyph_widths[code_point] = width; |
123 | 0 | } |
124 | | |
125 | 0 | size_t glyph_count() const override { return m_glyph_count; } |
126 | | Optional<size_t> glyph_index(u32 code_point) const; |
127 | | |
128 | 0 | bool is_range_empty(u32 code_point) const { return !(m_range_mask[code_point / 256 / 8] & 1 << (code_point / 256 % 8)); } |
129 | | |
130 | 0 | virtual String family() const override { return m_family; } |
131 | 0 | void set_family(String family) { m_family = move(family); } |
132 | | virtual String variant() const override; |
133 | | |
134 | | virtual String qualified_name() const override; |
135 | 0 | virtual String human_readable_name() const override { return MUST(String::formatted("{} {} {}", family(), variant(), presentation_size())); } |
136 | | |
137 | | virtual NonnullRefPtr<Font> with_size(float point_size) const override; |
138 | | |
139 | | private: |
140 | | BitmapFont(String name, String family, Bytes rows, Span<u8> widths, bool is_fixed_width, |
141 | | u8 glyph_width, u8 glyph_height, u8 glyph_spacing, Bytes range_mask, |
142 | | u8 baseline, u8 mean_line, u8 presentation_size, u16 weight, u8 slope, bool owns_arrays = false); |
143 | | |
144 | | template<typename T> |
145 | | int unicode_view_width(T const& view) const; |
146 | | |
147 | 0 | void update_x_height() { m_x_height = m_baseline - m_mean_line; } |
148 | | |
149 | 0 | virtual bool has_color_bitmaps() const override { return false; } |
150 | | |
151 | | String m_name; |
152 | | String m_family; |
153 | | size_t m_glyph_count { 0 }; |
154 | | |
155 | | Bytes m_range_mask; |
156 | | Vector<Optional<size_t>> m_range_indices; |
157 | | |
158 | | Bytes m_rows; |
159 | | Span<u8> m_glyph_widths; |
160 | | Variant<Empty, NonnullOwnPtr<Core::MappedFile>, NonnullRefPtr<Core::Resource>> m_owned_data = Empty {}; |
161 | | |
162 | | u8 m_glyph_width { 0 }; |
163 | | u8 m_glyph_height { 0 }; |
164 | | u8 m_x_height { 0 }; |
165 | | u8 m_min_glyph_width { 0 }; |
166 | | u8 m_max_glyph_width { 0 }; |
167 | | u8 m_glyph_spacing { 0 }; |
168 | | u8 m_baseline { 0 }; |
169 | | u8 m_mean_line { 0 }; |
170 | | u8 m_presentation_size { 0 }; |
171 | | u16 m_weight { 0 }; |
172 | | u8 m_slope { 0 }; |
173 | | u8 m_line_gap { 4 }; |
174 | | |
175 | | bool m_fixed_width { false }; |
176 | | bool m_owns_arrays { false }; |
177 | | }; |
178 | | |
179 | | } |