rays 0.1.47 → 0.1.49
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.doc/ext/rays/bitmap.cpp +287 -46
- data/.doc/ext/rays/camera.cpp +2 -2
- data/.doc/ext/rays/color.cpp +11 -0
- data/.doc/ext/rays/defs.cpp +32 -8
- data/.doc/ext/rays/font.cpp +50 -2
- data/.doc/ext/rays/image.cpp +3 -3
- data/.doc/ext/rays/matrix.cpp +65 -7
- data/.doc/ext/rays/native.cpp +2 -4
- data/.doc/ext/rays/painter.cpp +117 -9
- data/.doc/ext/rays/point.cpp +1 -11
- data/.doc/ext/rays/polygon.cpp +133 -97
- data/.doc/ext/rays/polyline.cpp +89 -10
- data/.doc/ext/rays/rays.cpp +80 -0
- data/.doc/ext/rays/{noise.cpp → util.cpp} +2 -2
- data/ChangeLog.md +46 -0
- data/VERSION +1 -1
- data/ext/rays/bitmap.cpp +288 -46
- data/ext/rays/camera.cpp +2 -2
- data/ext/rays/color.cpp +13 -1
- data/ext/rays/defs.cpp +32 -8
- data/ext/rays/defs.h +56 -3
- data/ext/rays/font.cpp +56 -4
- data/ext/rays/image.cpp +3 -3
- data/ext/rays/matrix.cpp +69 -7
- data/ext/rays/native.cpp +2 -4
- data/ext/rays/painter.cpp +132 -13
- data/ext/rays/point.cpp +1 -12
- data/ext/rays/polygon.cpp +136 -99
- data/ext/rays/polyline.cpp +95 -9
- data/ext/rays/rays.cpp +80 -0
- data/ext/rays/{noise.cpp → util.cpp} +2 -2
- data/include/rays/color.h +3 -1
- data/include/rays/defs.h +24 -26
- data/include/rays/font.h +17 -3
- data/include/rays/image.h +1 -1
- data/include/rays/matrix.h +24 -0
- data/include/rays/painter.h +24 -0
- data/include/rays/polygon.h +68 -43
- data/include/rays/polyline.h +17 -2
- data/include/rays/ruby/polygon.h +0 -11
- data/include/rays/ruby/rays.h +4 -0
- data/include/rays/{noise.h → util.h} +2 -2
- data/lib/rays/color.rb +7 -1
- data/lib/rays/font.rb +1 -1
- data/lib/rays/image.rb +11 -1
- data/lib/rays/matrix.rb +16 -0
- data/lib/rays/painter.rb +18 -7
- data/lib/rays/point.rb +5 -1
- data/lib/rays/polygon.rb +44 -35
- data/lib/rays/polyline.rb +54 -8
- data/lib/rays.rb +0 -1
- data/rays.gemspec +2 -2
- data/src/color.cpp +11 -2
- data/src/font.cpp +37 -18
- data/src/font.h +6 -5
- data/src/image.cpp +58 -14
- data/src/ios/font.mm +89 -32
- data/src/ios/helper.h +2 -2
- data/src/ios/helper.mm +2 -2
- data/src/matrix.cpp +45 -0
- data/src/osx/font.mm +93 -33
- data/src/osx/helper.h +2 -2
- data/src/osx/helper.mm +2 -2
- data/src/painter.cpp +246 -114
- data/src/painter.h +11 -3
- data/src/polygon.cpp +431 -332
- data/src/polyline.cpp +138 -27
- data/src/polyline.h +3 -5
- data/src/shader.cpp +36 -4
- data/src/shader.h +1 -1
- data/src/texture.cpp +23 -4
- data/src/texture.h +2 -0
- data/src/{noise.cpp → util.cpp} +1 -1
- data/src/win32/font.cpp +1 -1
- data/test/test_bitmap.rb +12 -5
- data/test/test_color.rb +25 -4
- data/test/test_font.rb +23 -2
- data/test/test_image.rb +44 -18
- data/test/test_matrix.rb +22 -0
- data/test/test_painter.rb +27 -0
- data/test/test_point.rb +1 -1
- data/test/test_polygon.rb +52 -45
- data/test/test_polyline.rb +191 -72
- metadata +12 -18
- data/.doc/ext/rays/polygon_line.cpp +0 -97
- data/ext/rays/polygon_line.cpp +0 -100
- data/lib/rays/polygon_line.rb +0 -33
- data/test/test_polygon_line.rb +0 -164
data/lib/rays/polygon.rb
CHANGED
@@ -8,74 +8,83 @@ module Rays
|
|
8
8
|
class Polygon
|
9
9
|
|
10
10
|
include Enumerable
|
11
|
+
include Comparable
|
11
12
|
|
12
|
-
def initialize(*args, loop: true)
|
13
|
-
setup args, loop
|
13
|
+
def initialize(*args, loop: true, colors: nil, texcoords: nil)
|
14
|
+
setup args, loop, colors, texcoords
|
14
15
|
end
|
15
16
|
|
16
|
-
def transform(
|
17
|
-
|
18
|
-
|
19
|
-
lines = block.call lines if block
|
20
|
-
self.class.new(*lines)
|
17
|
+
def transform(&block)
|
18
|
+
polylines = block.call to_a
|
19
|
+
self.class.new(*polylines)
|
21
20
|
end
|
22
21
|
|
23
22
|
def intersects(obj)
|
24
23
|
!(self & obj).empty?
|
25
24
|
end
|
26
25
|
|
27
|
-
def
|
28
|
-
|
26
|
+
def <=>(o)
|
27
|
+
(size <=> o.size).then {|cmp| return cmp if cmp != 0}
|
28
|
+
to_a.zip(o.to_a).each {|a, b| cmp = a <=> b; return cmp if cmp != 0}
|
29
|
+
0
|
29
30
|
end
|
30
31
|
|
31
|
-
def
|
32
|
-
|
32
|
+
def inspect()
|
33
|
+
"#<Rays::Polygon [#{map {|polyline| polyline.inspect}.join ', '}]>"
|
33
34
|
end
|
34
35
|
|
35
|
-
def self.
|
36
|
-
|
36
|
+
def self.points(*points)
|
37
|
+
points! points
|
37
38
|
end
|
38
39
|
|
39
|
-
def self.
|
40
|
-
|
41
|
-
|
40
|
+
def self.line(*points, loop: false)
|
41
|
+
line! points, loop
|
42
|
+
end
|
42
43
|
|
43
|
-
|
44
|
+
def self.lines(*points)
|
45
|
+
lines! points
|
44
46
|
end
|
45
47
|
|
46
|
-
def self.
|
47
|
-
|
48
|
-
|
48
|
+
def self.triangles(*points, loop: true, colors: nil, texcoords: nil)
|
49
|
+
triangles! points, loop, colors, texcoords
|
50
|
+
end
|
49
51
|
|
50
|
-
|
52
|
+
def self.triangle_strip(*points, colors: nil, texcoords: nil)
|
53
|
+
triangle_strip! points, colors, texcoords
|
51
54
|
end
|
52
55
|
|
53
|
-
def self.
|
54
|
-
|
56
|
+
def self.triangle_fan(*points, colors: nil, texcoords: nil)
|
57
|
+
triangle_fan! points, colors, texcoords
|
55
58
|
end
|
56
59
|
|
57
|
-
def self.
|
58
|
-
|
60
|
+
def self.rect(
|
61
|
+
*args, round: nil, lt: nil, rt: nil, lb: nil, rb: nil,
|
62
|
+
nsegment: nil)
|
63
|
+
|
64
|
+
rect! args, round, lt, rt, lb, rb, nsegment
|
59
65
|
end
|
60
66
|
|
61
|
-
def self.
|
62
|
-
|
67
|
+
def self.quads(*points, loop: true, colors: nil, texcoords: nil)
|
68
|
+
quads! points, loop, colors, texcoords
|
63
69
|
end
|
64
70
|
|
65
|
-
def self.
|
66
|
-
|
71
|
+
def self.quad_strip(*points, colors: nil, texcoords: nil)
|
72
|
+
quad_strip! points, colors, texcoords
|
67
73
|
end
|
68
74
|
|
69
|
-
def self.
|
70
|
-
|
75
|
+
def self.ellipse(
|
76
|
+
*args, center: nil, radius: nil, hole: nil, from: nil, to: nil,
|
77
|
+
nsegment: nil)
|
78
|
+
|
79
|
+
ellipse! args, center, radius, hole, from, to, nsegment
|
71
80
|
end
|
72
81
|
|
73
|
-
def self.curve(*
|
74
|
-
curve!
|
82
|
+
def self.curve(*points, loop: false, nsegment: nil)
|
83
|
+
curve! points, loop, nsegment
|
75
84
|
end
|
76
85
|
|
77
|
-
def self.bezier(*
|
78
|
-
bezier!
|
86
|
+
def self.bezier(*points, loop: false, nsegment: nil)
|
87
|
+
bezier! points, loop, nsegment
|
79
88
|
end
|
80
89
|
|
81
90
|
end# Polygon
|
data/lib/rays/polyline.rb
CHANGED
@@ -7,20 +7,66 @@ module Rays
|
|
7
7
|
class Polyline
|
8
8
|
|
9
9
|
include Enumerable
|
10
|
+
include Comparable
|
10
11
|
|
11
|
-
def initialize(
|
12
|
-
|
12
|
+
def initialize(
|
13
|
+
*points, loop: false, fill: nil, colors: nil, texcoords: nil, hole: false)
|
14
|
+
|
15
|
+
setup points, loop, (fill != nil ? fill : loop), colors, texcoords, hole
|
16
|
+
end
|
17
|
+
|
18
|
+
def with(**kwargs)
|
19
|
+
points_, loop_, fill_, colors_, texcoords_, hole_ =
|
20
|
+
kwargs.values_at :points, :loop, :fill, :colors, :texcoords, :hole
|
21
|
+
self.class.new(
|
22
|
+
*(points_ || (points? ? points : [])),
|
23
|
+
loop: loop_ != nil ? loop_ : loop?,
|
24
|
+
fill: fill_ != nil ? fill_ : fill?,
|
25
|
+
colors: colors_ || (colors? ? colors : nil),
|
26
|
+
texcoords: texcoords_ || (texcoords? ? texcoords : nil),
|
27
|
+
hole: hole_ != nil ? hole_ : hole?)
|
28
|
+
end
|
29
|
+
|
30
|
+
def points()
|
31
|
+
each_point.to_a
|
32
|
+
end
|
33
|
+
|
34
|
+
def colors()
|
35
|
+
each_color.to_a
|
36
|
+
end
|
37
|
+
|
38
|
+
def texcoords()
|
39
|
+
each_texcoord.to_a
|
40
|
+
end
|
41
|
+
|
42
|
+
def each_point(&block)
|
43
|
+
block ? each_point!(&block) : enum_for(:each_point!)
|
44
|
+
end
|
45
|
+
|
46
|
+
def each_color(&block)
|
47
|
+
block ? each_color!(&block) : enum_for(:each_color!)
|
48
|
+
end
|
49
|
+
|
50
|
+
def each_texcoord(&block)
|
51
|
+
block ? each_texcoord!(&block) : enum_for(:each_texcoord!)
|
13
52
|
end
|
14
53
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
54
|
+
alias each each_point
|
55
|
+
|
56
|
+
def <=>(o)
|
57
|
+
(size <=> o.size) .then {|cmp| return cmp if cmp != 0}
|
58
|
+
(loop? <=> o.loop?).then {|cmp| return cmp if cmp != 0}
|
59
|
+
(fill? <=> o.fill?).then {|cmp| return cmp if cmp != 0}
|
60
|
+
points .zip(o.points) .each {|a, b| cmp = a <=> b; return cmp if cmp != 0}
|
61
|
+
colors .zip(o.colors) .each {|a, b| cmp = a <=> b; return cmp if cmp != 0}
|
62
|
+
texcoords.zip(o.texcoords).each {|a, b| cmp = a <=> b; return cmp if cmp != 0}
|
63
|
+
0
|
20
64
|
end
|
21
65
|
|
22
66
|
def inspect()
|
23
|
-
|
67
|
+
p = points.map {|o| o.to_a.join ','}.join ', '
|
68
|
+
c, t = colors.size, texcoords.size
|
69
|
+
"#<Rays::Polyline [#{p}] loop:#{loop?} fill:#{fill?} hole:#{hole?} colors:#{c} texcoords:#{t}>"
|
24
70
|
end
|
25
71
|
|
26
72
|
end# Polyline
|
data/lib/rays.rb
CHANGED
data/rays.gemspec
CHANGED
@@ -25,8 +25,8 @@ Gem::Specification.new do |s|
|
|
25
25
|
s.platform = Gem::Platform::RUBY
|
26
26
|
s.required_ruby_version = '>= 3.0.0'
|
27
27
|
|
28
|
-
s.add_runtime_dependency 'xot', '~> 0.1.
|
29
|
-
s.add_runtime_dependency 'rucy', '~> 0.1.
|
28
|
+
s.add_runtime_dependency 'xot', '~> 0.1.42'
|
29
|
+
s.add_runtime_dependency 'rucy', '~> 0.1.44'
|
30
30
|
|
31
31
|
s.files = `git ls-files`.split $/
|
32
32
|
s.executables = s.files.grep(%r{^bin/}) {|f| File.basename f}
|
data/src/color.cpp
CHANGED
@@ -47,8 +47,17 @@ namespace Rays
|
|
47
47
|
hue = fmod(hue, 1.f);
|
48
48
|
if (hue < 0) hue += 1.f;
|
49
49
|
|
50
|
-
auto
|
51
|
-
return Color(
|
50
|
+
auto rgb = glm::rgbColor(Vec3(hue * 360.f, saturation, value));
|
51
|
+
return Color(rgb[0], rgb[1], rgb[2], alpha);
|
52
|
+
}
|
53
|
+
|
54
|
+
void
|
55
|
+
get_hsv (float* hue, float* saturation, float* value, const Color& color)
|
56
|
+
{
|
57
|
+
auto hsv = glm::hsvColor(Vec3(color.r, color.g, color.b));
|
58
|
+
if (hue) *hue = hsv[0] / 360.f;
|
59
|
+
if (saturation) *saturation = hsv[1];
|
60
|
+
if (value) *value = hsv[2];
|
52
61
|
}
|
53
62
|
|
54
63
|
|
data/src/font.cpp
CHANGED
@@ -27,7 +27,7 @@ namespace Rays
|
|
27
27
|
if (pixel_density != for_pixel_density)
|
28
28
|
{
|
29
29
|
rawfont_for_pixel_density =
|
30
|
-
RawFont(rawfont
|
30
|
+
RawFont(rawfont, rawfont.size() * pixel_density);
|
31
31
|
for_pixel_density = pixel_density;
|
32
32
|
}
|
33
33
|
|
@@ -37,8 +37,16 @@ namespace Rays
|
|
37
37
|
};// Font::Data
|
38
38
|
|
39
39
|
|
40
|
+
Font
|
41
|
+
load_font (const char* path, coord size)
|
42
|
+
{
|
43
|
+
Font font;
|
44
|
+
font.self->rawfont = RawFont_load(path, size);
|
45
|
+
return font;
|
46
|
+
}
|
47
|
+
|
40
48
|
const Font&
|
41
|
-
|
49
|
+
get_default_font ()
|
42
50
|
{
|
43
51
|
static const Font FONT(NULL);
|
44
52
|
return FONT;
|
@@ -50,21 +58,6 @@ namespace Rays
|
|
50
58
|
return font.self->get_raw(pixel_density);
|
51
59
|
}
|
52
60
|
|
53
|
-
coord
|
54
|
-
Font_get_width (const Font& font, float pixel_density, const char* str)
|
55
|
-
{
|
56
|
-
return Font_get_raw(font, pixel_density).get_width(str);
|
57
|
-
}
|
58
|
-
|
59
|
-
coord
|
60
|
-
Font_get_height (
|
61
|
-
const Font& font, float pixel_density,
|
62
|
-
coord* ascent, coord* descent, coord* leading)
|
63
|
-
{
|
64
|
-
return Font_get_raw(font, pixel_density)
|
65
|
-
.get_height(ascent, descent, leading);
|
66
|
-
}
|
67
|
-
|
68
61
|
|
69
62
|
Font::Font ()
|
70
63
|
{
|
@@ -79,12 +72,26 @@ namespace Rays
|
|
79
72
|
{
|
80
73
|
}
|
81
74
|
|
75
|
+
Font
|
76
|
+
Font::dup () const
|
77
|
+
{
|
78
|
+
Font f;
|
79
|
+
f.self->rawfont = RawFont(self->rawfont, self->rawfont.size());
|
80
|
+
return f;
|
81
|
+
}
|
82
|
+
|
82
83
|
String
|
83
84
|
Font::name () const
|
84
85
|
{
|
85
86
|
return self->rawfont.name();
|
86
87
|
}
|
87
88
|
|
89
|
+
void
|
90
|
+
Font::set_size (coord size)
|
91
|
+
{
|
92
|
+
self->rawfont = RawFont(self->rawfont, size);
|
93
|
+
}
|
94
|
+
|
88
95
|
coord
|
89
96
|
Font::size () const
|
90
97
|
{
|
@@ -94,7 +101,19 @@ namespace Rays
|
|
94
101
|
coord
|
95
102
|
Font::get_width (const char* str) const
|
96
103
|
{
|
97
|
-
|
104
|
+
if (!strchr(str, '\n'))
|
105
|
+
return self->rawfont.get_width(str);
|
106
|
+
|
107
|
+
Xot::StringList lines;
|
108
|
+
split(&lines, str);
|
109
|
+
|
110
|
+
coord width = 0;
|
111
|
+
for (const auto& line : lines)
|
112
|
+
{
|
113
|
+
coord w = self->rawfont.get_width(line.c_str());
|
114
|
+
if (w > width) width = w;
|
115
|
+
}
|
116
|
+
return width;
|
98
117
|
}
|
99
118
|
|
100
119
|
coord
|
data/src/font.h
CHANGED
@@ -15,11 +15,15 @@ namespace Rays
|
|
15
15
|
class RawFont
|
16
16
|
{
|
17
17
|
|
18
|
+
typedef RawFont This;
|
19
|
+
|
18
20
|
public:
|
19
21
|
|
20
22
|
RawFont ();
|
21
23
|
|
22
|
-
RawFont (const char* name, coord size
|
24
|
+
RawFont (const char* name, coord size);
|
25
|
+
|
26
|
+
RawFont (const This& obj, coord size);
|
23
27
|
|
24
28
|
~RawFont ();
|
25
29
|
|
@@ -51,11 +55,8 @@ namespace Rays
|
|
51
55
|
|
52
56
|
const RawFont& Font_get_raw (const Font& font, float pixel_density);
|
53
57
|
|
54
|
-
coord Font_get_width (const Font& font, float pixel_density, const char* str);
|
55
58
|
|
56
|
-
|
57
|
-
const Font& font, float pixel_density,
|
58
|
-
coord* ascent = NULL, coord* descent = NULL, coord* leading = NULL);
|
59
|
+
RawFont RawFont_load (const char* path, coord size);
|
59
60
|
|
60
61
|
|
61
62
|
}// Rays
|
data/src/image.cpp
CHANGED
@@ -10,6 +10,13 @@
|
|
10
10
|
#include "texture.h"
|
11
11
|
|
12
12
|
|
13
|
+
#if 0
|
14
|
+
#define PRINT_MODIFIED_FLAGS(message) self->print_modified_flags(message)
|
15
|
+
#else
|
16
|
+
#define PRINT_MODIFIED_FLAGS(message)
|
17
|
+
#endif
|
18
|
+
|
19
|
+
|
13
20
|
namespace Rays
|
14
21
|
{
|
15
22
|
|
@@ -27,6 +34,16 @@ namespace Rays
|
|
27
34
|
|
28
35
|
mutable Texture texture;
|
29
36
|
|
37
|
+
void print_modified_flags (const char* message)
|
38
|
+
{
|
39
|
+
printf("%s: %d %d %d %d \n",
|
40
|
+
message,
|
41
|
+
bitmap ? 1 : 0,
|
42
|
+
Bitmap_get_modified(bitmap) ? 1 : 0,
|
43
|
+
texture ? 1 : 0,
|
44
|
+
texture.modified() ? 1 : 0);
|
45
|
+
}
|
46
|
+
|
30
47
|
};// Image::Data
|
31
48
|
|
32
49
|
|
@@ -82,18 +99,30 @@ namespace Rays
|
|
82
99
|
if (!self->bitmap)
|
83
100
|
{
|
84
101
|
if (self->texture)
|
102
|
+
{
|
103
|
+
PRINT_MODIFIED_FLAGS("new bitmap from texture");
|
85
104
|
self->bitmap = Bitmap_from(self->texture);
|
105
|
+
}
|
86
106
|
else
|
107
|
+
{
|
108
|
+
PRINT_MODIFIED_FLAGS("new bitmap");
|
87
109
|
self->bitmap = Bitmap(self->width, self->height, self->color_space);
|
110
|
+
}
|
88
111
|
clear_modified_flags(image);
|
89
112
|
}
|
90
|
-
else if (
|
91
|
-
self->texture &&
|
92
|
-
self->texture.modified() &&
|
93
|
-
!Bitmap_get_modified(self->bitmap))
|
113
|
+
else if (self->texture && self->texture.modified())
|
94
114
|
{
|
95
|
-
|
96
|
-
|
115
|
+
if (Bitmap_get_modified(self->bitmap))
|
116
|
+
{
|
117
|
+
invalid_state_error(
|
118
|
+
__FILE__, __LINE__, "bitmap and texture modifications conflicted");
|
119
|
+
}
|
120
|
+
else
|
121
|
+
{
|
122
|
+
PRINT_MODIFIED_FLAGS("bitmap from texture");
|
123
|
+
self->bitmap = Bitmap_from(self->texture);
|
124
|
+
clear_modified_flags(image);
|
125
|
+
}
|
97
126
|
}
|
98
127
|
|
99
128
|
return self->bitmap;
|
@@ -115,9 +144,13 @@ namespace Rays
|
|
115
144
|
if (!self->texture)
|
116
145
|
{
|
117
146
|
if (self->bitmap)
|
147
|
+
{
|
148
|
+
PRINT_MODIFIED_FLAGS("new texture from bitmap");
|
118
149
|
self->texture = Texture(self->bitmap);
|
150
|
+
}
|
119
151
|
else
|
120
152
|
{
|
153
|
+
PRINT_MODIFIED_FLAGS("new texture");
|
121
154
|
self->texture = Texture(self->width, self->height, self->color_space);
|
122
155
|
|
123
156
|
Painter p = image.painter();
|
@@ -127,13 +160,19 @@ namespace Rays
|
|
127
160
|
}
|
128
161
|
clear_modified_flags(&image);
|
129
162
|
}
|
130
|
-
else if (
|
131
|
-
self->bitmap &&
|
132
|
-
Bitmap_get_modified(self->bitmap) &&
|
133
|
-
!self->texture.modified())
|
163
|
+
else if (self->bitmap && Bitmap_get_modified(self->bitmap))
|
134
164
|
{
|
135
|
-
self->texture
|
136
|
-
|
165
|
+
if (self->texture.modified())
|
166
|
+
{
|
167
|
+
invalid_state_error(
|
168
|
+
__FILE__, __LINE__, "texture and bitmap modifications conflicted");
|
169
|
+
}
|
170
|
+
else
|
171
|
+
{
|
172
|
+
PRINT_MODIFIED_FLAGS("texture from bitmap");
|
173
|
+
self->texture = self->bitmap;
|
174
|
+
clear_modified_flags(&image);
|
175
|
+
}
|
137
176
|
}
|
138
177
|
|
139
178
|
return self->texture;
|
@@ -232,15 +271,20 @@ namespace Rays
|
|
232
271
|
}
|
233
272
|
|
234
273
|
Bitmap&
|
235
|
-
Image::bitmap ()
|
274
|
+
Image::bitmap (bool modify)
|
236
275
|
{
|
276
|
+
if (modify)
|
277
|
+
{
|
278
|
+
if (!self->bitmap) get_bitmap(this);
|
279
|
+
Bitmap_set_modified(&self->bitmap);
|
280
|
+
}
|
237
281
|
return get_bitmap(this);
|
238
282
|
}
|
239
283
|
|
240
284
|
const Bitmap&
|
241
285
|
Image::bitmap () const
|
242
286
|
{
|
243
|
-
return
|
287
|
+
return const_cast<Image*>(this)->bitmap();
|
244
288
|
}
|
245
289
|
|
246
290
|
Image::operator bool () const
|
data/src/ios/font.mm
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
#include "../font.h"
|
3
3
|
|
4
4
|
|
5
|
+
#include <memory>
|
5
6
|
#import <CoreGraphics/CGContext.h>
|
6
7
|
#import <CoreText/CoreText.h>
|
7
8
|
#include "rays/exception.h"
|
@@ -12,15 +13,23 @@ namespace Rays
|
|
12
13
|
{
|
13
14
|
|
14
15
|
|
16
|
+
typedef std::shared_ptr<const __CFDictionary> CFDictionaryPtr;
|
17
|
+
|
18
|
+
typedef std::shared_ptr<const __CFAttributedString> CFAttributedStringPtr;
|
19
|
+
|
20
|
+
typedef std::shared_ptr<CGDataProvider> CGDataProviderPtr;
|
21
|
+
|
22
|
+
typedef std::shared_ptr<CGFont> CGFontPtr;
|
23
|
+
|
24
|
+
typedef std::shared_ptr<const __CTLine> CTLinePtr;
|
25
|
+
|
26
|
+
|
15
27
|
struct RawFont::Data
|
16
28
|
{
|
17
29
|
|
18
|
-
CTFontRef font;
|
30
|
+
CTFontRef font = NULL;
|
19
31
|
|
20
|
-
|
21
|
-
: font(NULL)
|
22
|
-
{
|
23
|
-
}
|
32
|
+
String path;
|
24
33
|
|
25
34
|
~Data ()
|
26
35
|
{
|
@@ -34,7 +43,7 @@ namespace Rays
|
|
34
43
|
};// RawFont::Data
|
35
44
|
|
36
45
|
|
37
|
-
static
|
46
|
+
static CTLinePtr
|
38
47
|
make_line (CTFontRef font, const char* str)
|
39
48
|
{
|
40
49
|
if (!font || !str || *str == '\0')
|
@@ -50,18 +59,65 @@ namespace Rays
|
|
50
59
|
};
|
51
60
|
size_t nkeys = sizeof(keys) / sizeof(keys[0]);
|
52
61
|
|
53
|
-
|
54
|
-
|
55
|
-
|
62
|
+
CFDictionaryPtr attr(
|
63
|
+
CFDictionaryCreate(
|
64
|
+
NULL, (const void**) &keys, (const void**) &values, nkeys,
|
65
|
+
&kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks),
|
66
|
+
CFRelease);
|
56
67
|
|
57
|
-
|
58
|
-
NULL, cfstring(str).get(), attr)
|
59
|
-
|
68
|
+
CFAttributedStringPtr attrstr(
|
69
|
+
CFAttributedStringCreate(NULL, cfstring(str).get(), attr.get()),
|
70
|
+
CFRelease);
|
60
71
|
|
61
|
-
|
62
|
-
|
72
|
+
return CTLinePtr(
|
73
|
+
CTLineCreateWithAttributedString(attrstr.get()),
|
74
|
+
CFRelease);
|
75
|
+
}
|
63
76
|
|
64
|
-
|
77
|
+
const FontFamilyMap&
|
78
|
+
get_font_families ()
|
79
|
+
{
|
80
|
+
static const FontFamilyMap MAP = []() {
|
81
|
+
FontFamilyMap map;
|
82
|
+
for (NSString* family in UIFont.familyNames)
|
83
|
+
{
|
84
|
+
FontFamilyMap::mapped_type array;
|
85
|
+
for (NSString* name in [UIFont fontNamesForFamilyName: family])
|
86
|
+
array.emplace_back(name.UTF8String);
|
87
|
+
map[family.UTF8String] = array;
|
88
|
+
}
|
89
|
+
return map;
|
90
|
+
}();
|
91
|
+
return MAP;
|
92
|
+
}
|
93
|
+
|
94
|
+
RawFont
|
95
|
+
RawFont_load (const char* path, coord size)
|
96
|
+
{
|
97
|
+
if (!path)
|
98
|
+
argument_error(__FILE__, __LINE__);
|
99
|
+
|
100
|
+
CGDataProviderPtr data_provider(
|
101
|
+
CGDataProviderCreateWithFilename(path),
|
102
|
+
CGDataProviderRelease);
|
103
|
+
if (!data_provider)
|
104
|
+
rays_error(__FILE__, __LINE__, "failed to create CGDataProvider");
|
105
|
+
|
106
|
+
CGFontPtr cgfont(
|
107
|
+
CGFontCreateWithDataProvider(data_provider.get()),
|
108
|
+
CGFontRelease);
|
109
|
+
if (!cgfont)
|
110
|
+
rays_error(__FILE__, __LINE__, "failed to create CGFont");
|
111
|
+
|
112
|
+
CTFontRef ctfont = CTFontCreateWithGraphicsFont(
|
113
|
+
cgfont.get(), size, NULL, NULL);
|
114
|
+
if (!ctfont)
|
115
|
+
rays_error(__FILE__, __LINE__, "failed to create CTFont");
|
116
|
+
|
117
|
+
RawFont rawfont;
|
118
|
+
rawfont.self->font = ctfont;
|
119
|
+
rawfont.self->path = path;
|
120
|
+
return rawfont;
|
65
121
|
}
|
66
122
|
|
67
123
|
|
@@ -76,6 +132,15 @@ namespace Rays
|
|
76
132
|
: CTFontCreateUIFontForLanguage(kCTFontSystemFontType, size, NULL);
|
77
133
|
}
|
78
134
|
|
135
|
+
RawFont::RawFont (const This& obj, coord size)
|
136
|
+
{
|
137
|
+
const char* path = obj.self->path.empty() ? NULL : obj.self->path.c_str();
|
138
|
+
if (path)
|
139
|
+
*this = RawFont_load(path, size);
|
140
|
+
else
|
141
|
+
self->font = CTFontCreateWithName(cfstring(obj.name()).get(), size, NULL);
|
142
|
+
}
|
143
|
+
|
79
144
|
RawFont::~RawFont ()
|
80
145
|
{
|
81
146
|
}
|
@@ -92,15 +157,13 @@ namespace Rays
|
|
92
157
|
|
93
158
|
if (*str == '\0') return;
|
94
159
|
|
95
|
-
|
160
|
+
CTLinePtr line = make_line(self->font, str);
|
96
161
|
if (!line)
|
97
162
|
rays_error(__FILE__, __LINE__, "creating CTLineRef failed.");
|
98
163
|
|
99
|
-
coord width
|
100
|
-
width = get_width(str);
|
101
|
-
height = get_height(&ascent);
|
102
|
-
|
103
|
-
height = ceil(height);
|
164
|
+
coord width, height, ascent = 0;
|
165
|
+
width = ceil(get_width(str));
|
166
|
+
height = ceil(get_height(&ascent));
|
104
167
|
ascent = floor(ascent);
|
105
168
|
|
106
169
|
CGRect rect = CGRectMake(x, context_height - height - y, width, height);
|
@@ -112,10 +175,8 @@ namespace Rays
|
|
112
175
|
CGContextSaveGState(context);
|
113
176
|
CGContextSetTextMatrix(context, CGAffineTransformIdentity);
|
114
177
|
CGContextSetTextPosition(context, x, context_height - ascent - y);
|
115
|
-
CTLineDraw(line, context);
|
178
|
+
CTLineDraw(line.get(), context);
|
116
179
|
CGContextRestoreGState(context);
|
117
|
-
|
118
|
-
CFRelease(line);
|
119
180
|
}
|
120
181
|
|
121
182
|
String
|
@@ -123,14 +184,13 @@ namespace Rays
|
|
123
184
|
{
|
124
185
|
if (!*this) return "";
|
125
186
|
|
126
|
-
|
187
|
+
CFStringPtr str(CTFontCopyFullName(self->font), CFRelease);
|
127
188
|
|
128
189
|
enum {BUFSIZE = 2048};
|
129
190
|
char buf[BUFSIZE + 1];
|
130
|
-
if (!CFStringGetCString(str, buf, BUFSIZE, kCFStringEncodingUTF8))
|
191
|
+
if (!CFStringGetCString(str.get(), buf, BUFSIZE, kCFStringEncodingUTF8))
|
131
192
|
buf[0] = '\0';
|
132
193
|
|
133
|
-
CFRelease(str);
|
134
194
|
return buf;
|
135
195
|
}
|
136
196
|
|
@@ -152,14 +212,11 @@ namespace Rays
|
|
152
212
|
|
153
213
|
if (*str == '\0') return 0;
|
154
214
|
|
155
|
-
|
215
|
+
CTLinePtr line = make_line(self->font, str);
|
156
216
|
if (!line)
|
157
217
|
rays_error(__FILE__, __LINE__, "creating CTLineRef failed.");
|
158
218
|
|
159
|
-
|
160
|
-
CFRelease(line);
|
161
|
-
|
162
|
-
return w;
|
219
|
+
return CTLineGetTypographicBounds(line.get(), NULL, NULL, NULL);
|
163
220
|
}
|
164
221
|
|
165
222
|
coord
|