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.
Files changed (89) hide show
  1. checksums.yaml +4 -4
  2. data/.doc/ext/rays/bitmap.cpp +287 -46
  3. data/.doc/ext/rays/camera.cpp +2 -2
  4. data/.doc/ext/rays/color.cpp +11 -0
  5. data/.doc/ext/rays/defs.cpp +32 -8
  6. data/.doc/ext/rays/font.cpp +50 -2
  7. data/.doc/ext/rays/image.cpp +3 -3
  8. data/.doc/ext/rays/matrix.cpp +65 -7
  9. data/.doc/ext/rays/native.cpp +2 -4
  10. data/.doc/ext/rays/painter.cpp +117 -9
  11. data/.doc/ext/rays/point.cpp +1 -11
  12. data/.doc/ext/rays/polygon.cpp +133 -97
  13. data/.doc/ext/rays/polyline.cpp +89 -10
  14. data/.doc/ext/rays/rays.cpp +80 -0
  15. data/.doc/ext/rays/{noise.cpp → util.cpp} +2 -2
  16. data/ChangeLog.md +46 -0
  17. data/VERSION +1 -1
  18. data/ext/rays/bitmap.cpp +288 -46
  19. data/ext/rays/camera.cpp +2 -2
  20. data/ext/rays/color.cpp +13 -1
  21. data/ext/rays/defs.cpp +32 -8
  22. data/ext/rays/defs.h +56 -3
  23. data/ext/rays/font.cpp +56 -4
  24. data/ext/rays/image.cpp +3 -3
  25. data/ext/rays/matrix.cpp +69 -7
  26. data/ext/rays/native.cpp +2 -4
  27. data/ext/rays/painter.cpp +132 -13
  28. data/ext/rays/point.cpp +1 -12
  29. data/ext/rays/polygon.cpp +136 -99
  30. data/ext/rays/polyline.cpp +95 -9
  31. data/ext/rays/rays.cpp +80 -0
  32. data/ext/rays/{noise.cpp → util.cpp} +2 -2
  33. data/include/rays/color.h +3 -1
  34. data/include/rays/defs.h +24 -26
  35. data/include/rays/font.h +17 -3
  36. data/include/rays/image.h +1 -1
  37. data/include/rays/matrix.h +24 -0
  38. data/include/rays/painter.h +24 -0
  39. data/include/rays/polygon.h +68 -43
  40. data/include/rays/polyline.h +17 -2
  41. data/include/rays/ruby/polygon.h +0 -11
  42. data/include/rays/ruby/rays.h +4 -0
  43. data/include/rays/{noise.h → util.h} +2 -2
  44. data/lib/rays/color.rb +7 -1
  45. data/lib/rays/font.rb +1 -1
  46. data/lib/rays/image.rb +11 -1
  47. data/lib/rays/matrix.rb +16 -0
  48. data/lib/rays/painter.rb +18 -7
  49. data/lib/rays/point.rb +5 -1
  50. data/lib/rays/polygon.rb +44 -35
  51. data/lib/rays/polyline.rb +54 -8
  52. data/lib/rays.rb +0 -1
  53. data/rays.gemspec +2 -2
  54. data/src/color.cpp +11 -2
  55. data/src/font.cpp +37 -18
  56. data/src/font.h +6 -5
  57. data/src/image.cpp +58 -14
  58. data/src/ios/font.mm +89 -32
  59. data/src/ios/helper.h +2 -2
  60. data/src/ios/helper.mm +2 -2
  61. data/src/matrix.cpp +45 -0
  62. data/src/osx/font.mm +93 -33
  63. data/src/osx/helper.h +2 -2
  64. data/src/osx/helper.mm +2 -2
  65. data/src/painter.cpp +246 -114
  66. data/src/painter.h +11 -3
  67. data/src/polygon.cpp +431 -332
  68. data/src/polyline.cpp +138 -27
  69. data/src/polyline.h +3 -5
  70. data/src/shader.cpp +36 -4
  71. data/src/shader.h +1 -1
  72. data/src/texture.cpp +23 -4
  73. data/src/texture.h +2 -0
  74. data/src/{noise.cpp → util.cpp} +1 -1
  75. data/src/win32/font.cpp +1 -1
  76. data/test/test_bitmap.rb +12 -5
  77. data/test/test_color.rb +25 -4
  78. data/test/test_font.rb +23 -2
  79. data/test/test_image.rb +44 -18
  80. data/test/test_matrix.rb +22 -0
  81. data/test/test_painter.rb +27 -0
  82. data/test/test_point.rb +1 -1
  83. data/test/test_polygon.rb +52 -45
  84. data/test/test_polyline.rb +191 -72
  85. metadata +12 -18
  86. data/.doc/ext/rays/polygon_line.cpp +0 -97
  87. data/ext/rays/polygon_line.cpp +0 -100
  88. data/lib/rays/polygon_line.rb +0 -33
  89. data/test/test_polygon_line.rb +0 -164
data/src/painter.cpp CHANGED
@@ -59,12 +59,20 @@ namespace Rays
59
59
 
60
60
  uint nsegment;
61
61
 
62
+ coord line_height;
63
+
62
64
  BlendMode blend_mode;
63
65
 
64
66
  Bounds clip;
65
67
 
66
68
  Font font;
67
69
 
70
+ Image texture;
71
+
72
+ TexCoordMode texcoord_mode;
73
+
74
+ TexCoordWrap texcoord_wrap;
75
+
68
76
  Shader shader;
69
77
 
70
78
  void init ()
@@ -78,9 +86,13 @@ namespace Rays
78
86
  stroke_join = JOIN_DEFAULT;
79
87
  miter_limit = JOIN_DEFAULT_MITER_LIMIT;
80
88
  nsegment = 0;
89
+ line_height = -1;
81
90
  blend_mode = BLEND_NORMAL;
82
91
  clip .reset(-1);
83
- font = default_font();
92
+ font = get_default_font();
93
+ texture = Image();
94
+ texcoord_mode = TEXCOORD_IMAGE;
95
+ texcoord_wrap = TEXCOORD_CLAMP;
84
96
  shader = Shader();
85
97
  }
86
98
 
@@ -97,7 +109,7 @@ namespace Rays
97
109
 
98
110
  const Texture& texture;
99
111
 
100
- Point texcoord_min, texcoord_max;
112
+ Point min, max;
101
113
 
102
114
  TextureInfo (
103
115
  const Texture& texture,
@@ -105,16 +117,16 @@ namespace Rays
105
117
  coord x_max, coord y_max)
106
118
  : texture(texture)
107
119
  {
108
- texcoord_min.reset(x_min, y_min);
109
- texcoord_max.reset(x_max, y_max);
120
+ min.reset(x_min, y_min);
121
+ max.reset(x_max, y_max);
110
122
  }
111
123
 
112
124
  operator bool () const
113
125
  {
114
126
  return
115
127
  texture &&
116
- texcoord_min.x < texcoord_max.x &&
117
- texcoord_min.y < texcoord_max.y;
128
+ min.x < max.x &&
129
+ min.y < max.y;
118
130
  }
119
131
 
120
132
  bool operator ! () const
@@ -310,13 +322,14 @@ namespace Rays
310
322
  return true;
311
323
  }
312
324
 
313
- void draw_polygon (
314
- GLenum mode, const Color& color,
325
+ void draw (
326
+ GLenum mode, const Color* color,
315
327
  const Coord3* points, size_t npoints,
316
328
  const uint* indices = NULL, size_t nindices = 0,
329
+ const Color* colors = NULL,
317
330
  const Coord3* texcoords = NULL,
318
- const Shader& default_shader = Shader_get_default_shader_for_shape(),
319
- const TextureInfo* texinfo = NULL)
331
+ const TextureInfo* texinfo = NULL,
332
+ const Shader* shader = NULL)
320
333
  {
321
334
  if (!points || npoints <= 0)
322
335
  argument_error(__FILE__, __LINE__);
@@ -324,15 +337,18 @@ namespace Rays
324
337
  if (!painting)
325
338
  invalid_state_error(__FILE__, __LINE__, "'painting' should be true.");
326
339
 
327
- const Shader& shader = state.shader ? state.shader : default_shader;
328
- const ShaderProgram* program = Shader_get_program(shader);
340
+ std::unique_ptr<TextureInfo> ptexinfo;
341
+ texinfo = setup_texinfo(texinfo, ptexinfo);
342
+ shader = setup_shader(shader, texinfo);
343
+
344
+ const ShaderProgram* program = Shader_get_program(*shader);
329
345
  if (!program || !*program) return;
330
346
 
331
347
  ShaderProgram_activate(*program);
332
348
 
333
- const auto& names = Shader_get_builtin_variable_names(shader);
349
+ const auto& names = Shader_get_builtin_variable_names(*shader);
334
350
  apply_builtin_uniforms(*program, names, texinfo);
335
- apply_attributes(*program, names, points, npoints, texcoords, color);
351
+ apply_attributes(*program, names, points, npoints, texcoords, color, colors);
336
352
  draw_indices(mode, indices, nindices, npoints);
337
353
  cleanup();
338
354
 
@@ -345,6 +361,27 @@ namespace Rays
345
361
 
346
362
  std::vector<GLuint> buffers;
347
363
 
364
+ const TextureInfo* setup_texinfo (const TextureInfo* texinfo, auto& ptr)
365
+ {
366
+ if (texinfo) return texinfo;
367
+
368
+ const Texture* tex =
369
+ state.texture ? &Image_get_texture(state.texture) : NULL;
370
+ if (!tex) return NULL;
371
+
372
+ ptr.reset(new TextureInfo(*tex, 0, 0, tex->width(), tex->height()));
373
+ return ptr.get();
374
+ }
375
+
376
+ const Shader* setup_shader (const Shader* shader, bool for_texture)
377
+ {
378
+ if (state.shader) return &state.shader;
379
+ if (shader) return shader;
380
+ return for_texture
381
+ ? &Shader_get_default_shader_for_texture(state.texcoord_wrap)
382
+ : &Shader_get_default_shader_for_shape();
383
+ }
384
+
348
385
  void apply_builtin_uniforms (
349
386
  const ShaderProgram& program, const ShaderBuiltinVariableNames& names,
350
387
  const TextureInfo* texinfo)
@@ -354,9 +391,10 @@ namespace Rays
354
391
  Matrix texcoord_matrix(1);
355
392
  if (texture && *texture)
356
393
  {
394
+ bool normal = state.texcoord_mode == TEXCOORD_NORMAL;
357
395
  texcoord_matrix.scale(
358
- 1.0 / texture->reserved_width(),
359
- 1.0 / texture->reserved_height());
396
+ (normal ? texture->width() : 1.0) / texture->reserved_width(),
397
+ (normal ? texture->height() : 1.0) / texture->reserved_height());
360
398
  }
361
399
 
362
400
  for (const auto& name : names.uniform_position_matrix_names)
@@ -374,24 +412,27 @@ namespace Rays
374
412
 
375
413
  if (!texinfo || !texture || !*texture) return;
376
414
 
415
+ coord tw = texture->reserved_width();
416
+ coord th = texture->reserved_height();
417
+ Point min(texinfo->min.x / tw, texinfo->min.y / th);
418
+ Point max(texinfo->max.x / tw, texinfo->max.y / th);
419
+ Point offset( 1 / tw, 1 / th);
420
+
377
421
  for (const auto& name : names.uniform_texcoord_min_names)
378
422
  {
379
423
  apply_uniform(program, name, [&](GLint loc) {
380
- Point min = texcoord_matrix * texinfo->texcoord_min;
381
424
  glUniform3fv(loc, 1, min.array);
382
425
  });
383
426
  }
384
427
  for (const auto& name : names.uniform_texcoord_max_names)
385
428
  {
386
429
  apply_uniform(program, name, [&](GLint loc) {
387
- Point max = texcoord_matrix * texinfo->texcoord_max;
388
430
  glUniform3fv(loc, 1, max.array);
389
431
  });
390
432
  }
391
433
  for (const auto& name : names.uniform_texcoord_offset_names)
392
434
  {
393
435
  apply_uniform(program, name, [&](GLint loc) {
394
- Point offset(1.0 / texture->width(), 1.0 / texture->height());
395
436
  glUniform3fv(loc, 1, offset.array);
396
437
  });
397
438
  }
@@ -412,9 +453,10 @@ namespace Rays
412
453
  void apply_attributes (
413
454
  const ShaderProgram& program, const ShaderBuiltinVariableNames& names,
414
455
  const Coord3* points, size_t npoints, const Coord3* texcoords,
415
- const Color& color)
456
+ const Color* color, const Color* colors)
416
457
  {
417
- assert(points && npoints > 0);
458
+ assert(npoints > 0);
459
+ assert(!!color != !!colors);
418
460
 
419
461
  apply_attribute(
420
462
  program, names.attribute_position_names,
@@ -424,21 +466,30 @@ namespace Rays
424
466
  program, names.attribute_texcoord_names,
425
467
  texcoords ? texcoords : points, npoints);
426
468
 
427
- #if defined(GL_VERSION_2_1) && !defined(GL_VERSION_3_0)
428
- // to fix that GL 2.1 with glVertexAttrib4fv() draws nothing
429
- // with specific glsl 'attribute' name.
430
- std::vector<Color> colors(npoints, color);
431
- apply_attribute(
432
- program, names.attribute_color_names,
433
- (const Coord4*) &colors[0], npoints);
434
- #else
435
- for (const auto& name : names.attribute_color_names)
469
+ if (colors)
436
470
  {
437
- apply_attribute(program, name, [&](GLint loc) {
438
- glVertexAttrib4fv(loc, color.array);
439
- });
471
+ apply_attribute(
472
+ program, names.attribute_color_names,
473
+ colors, npoints);
440
474
  }
475
+ else if (color)
476
+ {
477
+ #if defined(GL_VERSION_2_1) && !defined(GL_VERSION_3_0)
478
+ // to fix that GL 2.1 with glVertexAttrib4fv() draws nothing
479
+ // with specific glsl 'attribute' name.
480
+ std::vector<Color> colors_(npoints, *color);
481
+ apply_attribute(
482
+ program, names.attribute_color_names,
483
+ (const Coord4*) &colors_[0], npoints);
484
+ #else
485
+ for (const auto& name : names.attribute_color_names)
486
+ {
487
+ apply_attribute(program, name, [&](GLint loc) {
488
+ glVertexAttrib4fv(loc, color->array);
489
+ });
490
+ }
441
491
  #endif
492
+ }
442
493
  }
443
494
 
444
495
  template <typename CoordN>
@@ -557,52 +608,27 @@ namespace Rays
557
608
  };// Painter::Data
558
609
 
559
610
 
560
- static void
561
- draw_polygon (
562
- Painter* painter,
563
- const GLenum* modes,
564
- coord offset_x, coord offset_y,
565
- bool nofill, bool nostroke,
566
- const Coord3* points, size_t npoints,
567
- const uint* indices = NULL, size_t nindices = 0,
568
- const Coord3* texcoords = NULL,
569
- const Shader& default_shader = Shader_get_default_shader_for_shape(),
570
- const TextureInfo* texinfo = NULL)
611
+ void
612
+ Painter_draw (
613
+ Painter* painter, GLenum mode, const Color& color,
614
+ const Coord3* points, size_t npoints,
615
+ const uint* indices, size_t nindices,
616
+ const Coord3* texcoords)
571
617
  {
572
- assert(painter);
573
-
574
- bool offset = offset_x != 0 || offset_y != 0;
575
- if (offset)
576
- {
577
- painter->push_matrix();
578
- painter->translate(offset_x, offset_y);
579
- }
580
-
581
- Color color;
582
- for (int type = COLOR_TYPE_BEGIN; type < COLOR_TYPE_END; ++type)
583
- {
584
- if ((nofill && type == FILL) || (nostroke && type == STROKE))
585
- continue;
586
-
587
- if (!painter->self->get_color(&color, (ColorType) type))
588
- continue;
589
-
590
- painter->self->draw_polygon(
591
- modes[type], color, points, npoints, indices, nindices, texcoords,
592
- default_shader, texinfo);
593
- }
594
-
595
- if (offset)
596
- painter->pop_matrix();
618
+ painter->self->draw(
619
+ mode, &color, points, npoints, indices, nindices, NULL, texcoords);
597
620
  }
598
621
 
599
622
  void
600
- Painter_draw_polygon (
601
- Painter* painter, GLenum mode, const Color& color,
623
+ Painter_draw (
624
+ Painter* painter, GLenum mode,
602
625
  const Coord3* points, size_t npoints,
603
- const uint* indices, size_t nindices)
626
+ const uint* indices, size_t nindices,
627
+ const Color* colors,
628
+ const Coord3* texcoords)
604
629
  {
605
- painter->self->draw_polygon(mode, color, points, npoints, indices, nindices);
630
+ painter->self->draw(
631
+ mode, NULL, points, npoints, indices, nindices, colors, texcoords);
606
632
  }
607
633
 
608
634
 
@@ -700,7 +726,13 @@ namespace Rays
700
726
  set_blend_mode(self->state.blend_mode);
701
727
 
702
728
  FrameBuffer& fb = self->frame_buffer;
703
- if (fb) FrameBuffer_bind(fb.id());
729
+ if (fb)
730
+ {
731
+ FrameBuffer_bind(fb.id());
732
+
733
+ Texture& tex = fb.texture();
734
+ if (tex) tex.set_modified();
735
+ }
704
736
 
705
737
  const Bounds& vp = self->viewport;
706
738
  float density = self->pixel_density;
@@ -750,12 +782,7 @@ namespace Rays
750
782
  glFinish();
751
783
 
752
784
  if (self->frame_buffer)
753
- {
754
785
  FrameBuffer_unbind();
755
-
756
- Texture& tex = self->frame_buffer.texture();
757
- if (tex) tex.set_modified();
758
- }
759
786
  }
760
787
 
761
788
  bool
@@ -792,10 +819,7 @@ namespace Rays
792
819
  if (Polygon_triangulate(&triangles, polygon))
793
820
  {
794
821
  for (size_t i = 0; i < triangles.size(); i += 3)
795
- {
796
- painter->self->draw_polygon(
797
- GL_LINE_LOOP, invert_color, &triangles[i], 3);
798
- }
822
+ painter->self->draw(GL_LINE_LOOP, &invert_color, &triangles[i], 3);
799
823
  }
800
824
  #endif
801
825
  }
@@ -873,6 +897,24 @@ namespace Rays
873
897
  this, polygon, bounds.x, bounds.y, bounds.width, bounds.height, true);
874
898
  }
875
899
 
900
+ void
901
+ Painter::point (coord x, coord y)
902
+ {
903
+ polygon(create_point(x, y));
904
+ }
905
+
906
+ void
907
+ Painter::point (const Point& point)
908
+ {
909
+ polygon(create_point(point));
910
+ }
911
+
912
+ void
913
+ Painter::points (const Point* points, size_t size)
914
+ {
915
+ polygon(create_points(points, size));
916
+ }
917
+
876
918
  void
877
919
  Painter::line (coord x1, coord y1, coord x2, coord y2)
878
920
  {
@@ -970,7 +1012,7 @@ namespace Rays
970
1012
  coord x3, coord y3, coord x4, coord y4,
971
1013
  bool loop)
972
1014
  {
973
- polygon(create_curve(x1, y1, x2, y2, x3, y3, x4, y4, loop));
1015
+ polygon(create_curve(x1, y1, x2, y2, x3, y3, x4, y4, loop, nsegment()));
974
1016
  }
975
1017
 
976
1018
  void
@@ -978,13 +1020,13 @@ namespace Rays
978
1020
  const Point& p1, const Point& p2, const Point& p3, const Point& p4,
979
1021
  bool loop)
980
1022
  {
981
- polygon(create_curve(p1, p2, p3, p4, loop));
1023
+ polygon(create_curve(p1, p2, p3, p4, loop, nsegment()));
982
1024
  }
983
1025
 
984
1026
  void
985
1027
  Painter::curve (const Point* points, size_t size, bool loop)
986
1028
  {
987
- polygon(create_curve(points, size, loop));
1029
+ polygon(create_curve(points, size, loop, nsegment()));
988
1030
  }
989
1031
 
990
1032
  void
@@ -993,7 +1035,7 @@ namespace Rays
993
1035
  coord x3, coord y3, coord x4, coord y4,
994
1036
  bool loop)
995
1037
  {
996
- polygon(create_bezier(x1, y1, x2, y2, x3, y3, x4, y4, loop));
1038
+ polygon(create_bezier(x1, y1, x2, y2, x3, y3, x4, y4, loop, nsegment()));
997
1039
  }
998
1040
 
999
1041
  void
@@ -1001,13 +1043,13 @@ namespace Rays
1001
1043
  const Point& p1, const Point& p2, const Point& p3, const Point& p4,
1002
1044
  bool loop)
1003
1045
  {
1004
- polygon(create_bezier(p1, p2, p3, p4, loop));
1046
+ polygon(create_bezier(p1, p2, p3, p4, loop, nsegment()));
1005
1047
  }
1006
1048
 
1007
1049
  void
1008
1050
  Painter::bezier (const Point* points, size_t size, bool loop)
1009
1051
  {
1010
- polygon(create_bezier(points, size, loop));
1052
+ polygon(create_bezier(points, size, loop, nsegment()));
1011
1053
  }
1012
1054
 
1013
1055
  static void
@@ -1015,7 +1057,8 @@ namespace Rays
1015
1057
  Painter* painter, const Image& image,
1016
1058
  coord src_x, coord src_y, coord src_w, coord src_h,
1017
1059
  coord dst_x, coord dst_y, coord dst_w, coord dst_h,
1018
- bool nostroke = false, const Shader* shader = NULL)
1060
+ bool nofill = false, bool nostroke = false,
1061
+ const Shader* shader = NULL)
1019
1062
  {
1020
1063
  static const GLenum MODES[] = {GL_TRIANGLE_FAN, GL_LINE_LOOP};
1021
1064
 
@@ -1051,12 +1094,19 @@ namespace Rays
1051
1094
 
1052
1095
  TextureInfo texinfo(texture, src_x, src_y, src_x + src_w, src_y + src_h);
1053
1096
 
1054
- if (!shader)
1055
- shader = &Shader_get_default_shader_for_texture();
1097
+ Color color;
1098
+ for (int type = COLOR_TYPE_BEGIN; type < COLOR_TYPE_END; ++type)
1099
+ {
1100
+ if ((nofill && type == FILL) || (nostroke && type == STROKE))
1101
+ continue;
1102
+
1103
+ if (!painter->self->get_color(&color, (ColorType) type))
1104
+ continue;
1056
1105
 
1057
- draw_polygon(
1058
- painter, MODES, 0, 0, false, nostroke, points, 4, NULL, 0, texcoords,
1059
- *shader, &texinfo);
1106
+ painter->self->draw(
1107
+ MODES[type], &color, points, 4, NULL, 0, NULL, texcoords,
1108
+ &texinfo, shader);
1109
+ }
1060
1110
  }
1061
1111
 
1062
1112
  void
@@ -1148,7 +1198,7 @@ namespace Rays
1148
1198
  }
1149
1199
 
1150
1200
  static inline void
1151
- debug_draw_text (
1201
+ debug_draw_line (
1152
1202
  Painter* painter, const Font& font,
1153
1203
  coord x, coord y, coord str_width, coord str_height)
1154
1204
  {
@@ -1182,25 +1232,20 @@ namespace Rays
1182
1232
  }
1183
1233
 
1184
1234
  static void
1185
- draw_text (
1235
+ draw_line (
1186
1236
  Painter* painter, const Font& font,
1187
- const char* str, coord x, coord y, coord width = 0, coord height = 0)
1237
+ const char* line, coord x, coord y, coord width = 0, coord height = 0)
1188
1238
  {
1189
1239
  assert(painter && font && str && *str != '\0');
1190
1240
 
1191
1241
  Painter::Data* self = painter->self.get();
1192
1242
 
1193
- if (!self->painting)
1194
- invalid_state_error(__FILE__, __LINE__, "painting flag should be true.");
1195
-
1196
- if (!self->state.has_color())
1197
- return;
1198
-
1199
- float density = self->pixel_density;
1200
- coord str_w = Font_get_width(font, density, str);
1201
- coord str_h = Font_get_height(font, density);
1202
- int tex_w = ceil(str_w);
1203
- int tex_h = ceil(str_h);
1243
+ float density = self->pixel_density;
1244
+ const RawFont& rawfont = Font_get_raw(font, density);
1245
+ coord str_w = rawfont.get_width(line);
1246
+ coord str_h = rawfont.get_height();
1247
+ int tex_w = ceil(str_w);
1248
+ int tex_h = ceil(str_h);
1204
1249
  const Texture& texture = Image_get_texture(self->text_image);
1205
1250
  if (
1206
1251
  texture.width() < tex_w ||
@@ -1217,8 +1262,7 @@ namespace Rays
1217
1262
 
1218
1263
  assert(self->text_image.pixel_density() == density);
1219
1264
 
1220
- Bitmap_draw_string(
1221
- &self->text_image.bitmap(), Font_get_raw(font, density), str, 0, 0);
1265
+ Bitmap_draw_string(&self->text_image.bitmap(), rawfont, line, 0, 0);
1222
1266
 
1223
1267
  str_w /= density;
1224
1268
  str_h /= density;
@@ -1229,9 +1273,40 @@ namespace Rays
1229
1273
  painter, self->text_image,
1230
1274
  0, 0, str_w, str_h,
1231
1275
  x, y, str_w, str_h,
1232
- true, &Shader_get_shader_for_text());
1276
+ false, true, &Shader_get_shader_for_text());
1277
+
1278
+ debug_draw_line(painter, font, x, y, str_w / density, str_h / density);
1279
+ }
1233
1280
 
1234
- debug_draw_text(painter, font, x, y, str_w / density, str_h / density);
1281
+ static void
1282
+ draw_text (
1283
+ Painter* painter, const Font& font,
1284
+ const char* str, coord x, coord y, coord width = 0, coord height = 0)
1285
+ {
1286
+ assert(painter && font && str && *str != '\0');
1287
+
1288
+ Painter::Data* self = painter->self.get();
1289
+
1290
+ if (!self->painting)
1291
+ invalid_state_error(__FILE__, __LINE__, "painting flag should be true.");
1292
+
1293
+ if (!self->state.has_color())
1294
+ return;
1295
+
1296
+ if (!strchr(str, '\n'))
1297
+ draw_line(painter, font, str, x, y, width, height);
1298
+ else
1299
+ {
1300
+ coord line_height = painter->line_height();
1301
+
1302
+ Xot::StringList lines;
1303
+ split(&lines, str, '\n');
1304
+ for (const auto& line : lines)
1305
+ {
1306
+ draw_line(painter, font, line.c_str(), x, y, width, height);
1307
+ y += line_height;
1308
+ }
1309
+ }
1235
1310
  }
1236
1311
 
1237
1312
  void
@@ -1426,6 +1501,21 @@ namespace Rays
1426
1501
  return self->state.nsegment;
1427
1502
  }
1428
1503
 
1504
+ void
1505
+ Painter::set_line_height (coord height)
1506
+ {
1507
+ if (height < 0) height = -1;
1508
+ self->state.line_height = height;
1509
+ }
1510
+
1511
+ coord
1512
+ Painter::line_height (bool raw) const
1513
+ {
1514
+ coord height = self->state.line_height;
1515
+ if (!raw && height < 0) height = self->state.font.get_height();
1516
+ return height;
1517
+ }
1518
+
1429
1519
  void
1430
1520
  Painter::set_blend_mode (BlendMode mode)
1431
1521
  {
@@ -1522,7 +1612,7 @@ namespace Rays
1522
1612
  {
1523
1613
  return
1524
1614
  font.size() == size &&
1525
- font.name() == (name ? name : default_font().name().c_str());
1615
+ font.name() == (name ? name : get_default_font().name().c_str());
1526
1616
  }
1527
1617
 
1528
1618
  void
@@ -1545,6 +1635,48 @@ namespace Rays
1545
1635
  return self->state.font;
1546
1636
  }
1547
1637
 
1638
+ void
1639
+ Painter::set_texture (const Image& image)
1640
+ {
1641
+ self->state.texture = image;
1642
+ }
1643
+
1644
+ void
1645
+ Painter::no_texture ()
1646
+ {
1647
+ self->state.texture = Image();
1648
+ }
1649
+
1650
+ const Image&
1651
+ Painter::texture () const
1652
+ {
1653
+ return self->state.texture;
1654
+ }
1655
+
1656
+ void
1657
+ Painter::set_texcoord_mode (TexCoordMode mode)
1658
+ {
1659
+ self->state.texcoord_mode = mode;
1660
+ }
1661
+
1662
+ TexCoordMode
1663
+ Painter::texcoord_mode () const
1664
+ {
1665
+ return self->state.texcoord_mode;
1666
+ }
1667
+
1668
+ void
1669
+ Painter::set_texcoord_wrap (TexCoordWrap wrap)
1670
+ {
1671
+ self->state.texcoord_wrap = wrap;
1672
+ }
1673
+
1674
+ TexCoordWrap
1675
+ Painter::texcoord_wrap () const
1676
+ {
1677
+ return self->state.texcoord_wrap;
1678
+ }
1679
+
1548
1680
  void
1549
1681
  Painter::set_shader (const Shader& shader)
1550
1682
  {
data/src/painter.h CHANGED
@@ -12,10 +12,18 @@ namespace Rays
12
12
  {
13
13
 
14
14
 
15
- void Painter_draw_polygon (
15
+ void Painter_draw (
16
16
  Painter* painter, GLenum mode, const Color& color,
17
- const Coord3* points, size_t npoints,
18
- const uint* indices = NULL, size_t nindices = 0);
17
+ const Coord3* points, size_t npoints,
18
+ const uint* indices = NULL, size_t nindices = 0,
19
+ const Coord3* texcoords = NULL);
20
+
21
+ void Painter_draw (
22
+ Painter* painter, GLenum mode,
23
+ const Coord3* points, size_t npoints,
24
+ const uint* indices = NULL, size_t nindices = 0,
25
+ const Color* colors = NULL,
26
+ const Coord3* texcoords = NULL);
19
27
 
20
28
 
21
29
  }// Rays