rays 0.1.47 → 0.1.49

Sign up to get free protection for your applications and to get access to all the features.
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