picrate 2.0.1-java → 2.3.0-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. checksums.yaml +4 -4
  2. data/.mvn/extensions.xml +1 -1
  3. data/.mvn/wrapper/MavenWrapperDownloader.java +1 -1
  4. data/.mvn/wrapper/maven-wrapper.properties +2 -2
  5. data/CHANGELOG.md +10 -0
  6. data/README.md +6 -3
  7. data/Rakefile +2 -1
  8. data/docs/_includes/footer.html +1 -1
  9. data/docs/_layouts/post.html +1 -1
  10. data/docs/_methods/alternative_methods.md +2 -1
  11. data/docs/_methods/noise_mode.md +88 -0
  12. data/docs/_posts/2018-05-06-install_jruby.md +3 -3
  13. data/docs/_posts/2018-11-18-building-gem.md +3 -1
  14. data/docs/_posts/2020-03-09-auto_install_picrate.md +2 -3
  15. data/docs/_posts/2020-05-11-getting_started_manjaro.md +20 -8
  16. data/docs/classes.md +2 -2
  17. data/docs/editors.md +2 -2
  18. data/docs/gems.md +3 -3
  19. data/docs/index.html +1 -1
  20. data/docs/libraries.md +2 -2
  21. data/docs/live.md +2 -2
  22. data/docs/magic.md +2 -2
  23. data/docs/methods.md +2 -2
  24. data/docs/modules.md +3 -3
  25. data/docs/objects.md +2 -2
  26. data/lib/picrate.rb +2 -1
  27. data/lib/picrate/app.rb +7 -2
  28. data/lib/picrate/helper_methods.rb +1 -1
  29. data/lib/picrate/native_folder.rb +1 -3
  30. data/lib/picrate/runner.rb +4 -4
  31. data/lib/picrate/version.rb +1 -1
  32. data/library/jcomplex/jcomplex.rb +1 -0
  33. data/library/pdf/pdf.rb +6 -0
  34. data/mvnw +2 -2
  35. data/mvnw.cmd +2 -2
  36. data/picrate.gemspec +3 -2
  37. data/pom.rb +22 -8
  38. data/pom.xml +27 -5
  39. data/src/main/java/monkstone/PicrateLibrary.java +1 -1
  40. data/src/main/java/monkstone/complex/JComplex.java +252 -0
  41. data/src/main/java/monkstone/fastmath/DegLutTables.java +111 -0
  42. data/src/main/java/monkstone/fastmath/Deglut.java +41 -93
  43. data/src/main/java/monkstone/noise/FastTerrain.java +874 -0
  44. data/src/main/java/monkstone/noise/Noise.java +90 -0
  45. data/src/main/java/monkstone/noise/NoiseGenerator.java +75 -0
  46. data/src/main/java/monkstone/noise/NoiseMode.java +28 -0
  47. data/src/main/java/monkstone/noise/OpenSimplex2F.java +881 -0
  48. data/src/main/java/monkstone/noise/OpenSimplex2S.java +1106 -0
  49. data/src/main/java/monkstone/noise/SmoothTerrain.java +1099 -0
  50. data/src/main/java/monkstone/vecmath/package-info.java +1 -1
  51. data/src/main/java/monkstone/vecmath/vec3/Vec3.java +1 -1
  52. data/src/main/java/monkstone/videoevent/package-info.java +1 -1
  53. data/src/main/java/processing/awt/PGraphicsJava2D.java +22 -23
  54. data/src/main/java/processing/awt/PImageAWT.java +377 -0
  55. data/src/main/java/processing/awt/ShimAWT.java +711 -0
  56. data/src/main/java/processing/core/PApplet.java +14880 -14101
  57. data/src/main/java/processing/core/PConstants.java +5 -5
  58. data/src/main/java/processing/core/PFont.java +1 -1
  59. data/src/main/java/processing/core/PGraphics.java +284 -271
  60. data/src/main/java/processing/core/PImage.java +1620 -1815
  61. data/src/main/java/processing/core/PShape.java +18 -18
  62. data/src/main/java/processing/core/PSurface.java +105 -139
  63. data/src/main/java/processing/core/PSurfaceNone.java +29 -0
  64. data/src/main/java/processing/core/PVector.java +23 -23
  65. data/src/main/java/processing/data/Table.java +4 -4
  66. data/src/main/java/processing/net/Client.java +13 -13
  67. data/src/main/java/processing/net/Server.java +5 -5
  68. data/src/main/java/processing/opengl/PGL.java +649 -3699
  69. data/src/main/java/processing/opengl/PGraphicsOpenGL.java +2503 -2278
  70. data/src/main/java/processing/opengl/PJOGL.java +374 -1526
  71. data/src/main/java/processing/opengl/PSurfaceJOGL.java +220 -86
  72. data/src/main/java/processing/pdf/PGraphicsPDF.java +607 -0
  73. data/test/deglut_spec_test.rb +2 -2
  74. data/test/respond_to_test.rb +0 -1
  75. data/vendors/Rakefile +33 -21
  76. data/vendors/{picrate_sketches.geany → geany.rb} +32 -7
  77. metadata +24 -9
  78. data/src/main/java/monkstone/noise/SimplexNoise.java +0 -465
@@ -63,6 +63,10 @@ import com.jogamp.newt.awt.NewtCanvasAWT;
63
63
  import com.jogamp.newt.event.InputEvent;
64
64
  import com.jogamp.newt.opengl.GLWindow;
65
65
  import com.jogamp.opengl.util.FPSAnimator;
66
+ import java.awt.EventQueue;
67
+ import java.awt.FileDialog;
68
+ import processing.awt.PImageAWT;
69
+ import processing.awt.ShimAWT;
66
70
 
67
71
  import processing.core.PApplet;
68
72
  import processing.core.PConstants;
@@ -891,6 +895,148 @@ public class PSurfaceJOGL implements PSurface {
891
895
  });
892
896
  }
893
897
 
898
+ // TODO rewrite before 4.0 release
899
+ @Override
900
+ public PImage loadImage(String path, Object... args) {
901
+ return ShimAWT.loadImage(sketch, path, args);
902
+ }
903
+
904
+
905
+ @Override
906
+ public void selectInput(String prompt, String callbackMethod,
907
+ File file, Object callbackObject) {
908
+ EventQueue.invokeLater(() -> {
909
+ // https://github.com/processing/processing/issues/3831
910
+ boolean hide = (sketch != null) &&
911
+ (PApplet.platform == PConstants.WINDOWS);
912
+ if (hide) setVisible(false);
913
+
914
+ ShimAWT.selectImpl(prompt, callbackMethod, file,
915
+ callbackObject, null, FileDialog.LOAD);
916
+
917
+ if (hide) setVisible(true);
918
+ });
919
+ }
920
+
921
+
922
+ @Override
923
+ public void selectOutput(String prompt, String callbackMethod,
924
+ File file, Object callbackObject) {
925
+ EventQueue.invokeLater(() -> {
926
+ // https://github.com/processing/processing/issues/3831
927
+ boolean hide = (sketch != null) &&
928
+ (PApplet.platform == PConstants.WINDOWS);
929
+ if (hide) setVisible(false);
930
+
931
+ ShimAWT.selectImpl(prompt, callbackMethod, file,
932
+ callbackObject, null, FileDialog.SAVE);
933
+
934
+ if (hide) setVisible(true);
935
+ });
936
+ }
937
+
938
+
939
+ @Override
940
+ public void selectFolder(String prompt, String callbackMethod,
941
+ File file, Object callbackObject) {
942
+ EventQueue.invokeLater(() -> {
943
+ // https://github.com/processing/processing/issues/3831
944
+ boolean hide = (sketch != null) &&
945
+ (PApplet.platform == PConstants.WINDOWS);
946
+ if (hide) setVisible(false);
947
+
948
+ ShimAWT.selectFolderImpl(prompt, callbackMethod, file,
949
+ callbackObject, null);
950
+
951
+ if (hide) setVisible(true);
952
+ });
953
+ }
954
+
955
+ @Override
956
+ public void setCursor(int kind) {
957
+ if (!cursorNames.containsKey(kind)) {
958
+ PGraphics.showWarning("Unknown cursor type: " + kind);
959
+ return;
960
+ }
961
+ CursorInfo cursor = cursors.get(kind);
962
+ if (cursor == null) {
963
+ String name = cursorNames.get(kind);
964
+ if (name != null) {
965
+ ImageIcon icon =
966
+ new ImageIcon(getClass().getResource("cursors/" + name + ".png"));
967
+ PImage img = new PImageAWT(icon.getImage());
968
+ // Most cursors just use the center as the hotspot...
969
+ int x = img.width / 2;
970
+ int y = img.height / 2;
971
+ // ...others are more specific
972
+ switch (kind) {
973
+ case PConstants.ARROW:
974
+ x = 10;
975
+ y = 7;
976
+ break;
977
+ case PConstants.HAND:
978
+ x = 12;
979
+ y = 8;
980
+ break;
981
+ case PConstants.TEXT:
982
+ x = 16;
983
+ y = 22;
984
+ break;
985
+ default:
986
+ break;
987
+ }
988
+ cursor = new CursorInfo(img, x, y);
989
+ cursors.put(kind, cursor);
990
+ }
991
+ }
992
+ if (cursor != null) {
993
+ cursor.set();
994
+ } else {
995
+ PGraphics.showWarning("Cannot load cursor type: " + kind);
996
+ }
997
+ }
998
+
999
+
1000
+ @Override
1001
+ public void setCursor(PImage image, int hotspotX, int hotspotY) {
1002
+ Display disp = window.getScreen().getDisplay();
1003
+ BufferedImage bimg = (BufferedImage)image.getNative();
1004
+ DataBufferInt dbuf = (DataBufferInt)bimg.getData().getDataBuffer();
1005
+ int[] ipix = dbuf.getData();
1006
+ ByteBuffer pixels = ByteBuffer.allocate(ipix.length * 4);
1007
+ pixels.asIntBuffer().put(ipix);
1008
+ PixelFormat format = PixelFormat.ARGB8888;
1009
+ final Dimension size = new Dimension(bimg.getWidth(), bimg.getHeight());
1010
+ PixelRectangle pixelrect = new PixelRectangle.GenericPixelRect(format, size, 0, false, pixels);
1011
+ final PointerIcon pi = disp.createPointerIcon(pixelrect, hotspotX, hotspotY);
1012
+ display.getEDTUtil().invoke(false, () -> {
1013
+ window.setPointerVisible(true);
1014
+ window.setPointerIcon(pi);
1015
+ });
1016
+ }
1017
+
1018
+
1019
+ @Override
1020
+ public void showCursor() {
1021
+ display.getEDTUtil().invoke(false, () -> {
1022
+ window.setPointerVisible(true);
1023
+ });
1024
+ }
1025
+
1026
+
1027
+ @Override
1028
+ public void hideCursor() {
1029
+ display.getEDTUtil().invoke(false, () -> {
1030
+ window.setPointerVisible(false);
1031
+ });
1032
+ }
1033
+
1034
+
1035
+ @Override
1036
+ public boolean openLink(String url) {
1037
+ return ShimAWT.openLink(url);
1038
+ }
1039
+
894
1040
  class DrawListener implements GLEventListener {
895
1041
 
896
1042
  @Override
@@ -1353,24 +1499,24 @@ public class PSurfaceJOGL implements PSurface {
1353
1499
  return def;
1354
1500
  }
1355
1501
 
1356
- // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1357
- class CursorInfo {
1358
1502
 
1359
- PImage image;
1360
- int x, y;
1361
1503
 
1362
- CursorInfo(PImage image, int x, int y) {
1363
- this.image = image;
1364
- this.x = x;
1365
- this.y = y;
1366
- }
1504
+ class CursorInfo {
1505
+ PImage image;
1506
+ int x, y;
1367
1507
 
1368
- void set() {
1369
- setCursor(image, x, y);
1370
- }
1508
+ CursorInfo(PImage image, int x, int y) {
1509
+ this.image = image;
1510
+ this.x = x;
1511
+ this.y = y;
1371
1512
  }
1372
1513
 
1373
- static Map<Integer, CursorInfo> cursors = new HashMap<>();
1514
+ void set() {
1515
+ setCursor(image, x, y);
1516
+ }
1517
+ }
1518
+
1519
+ static Map<Integer, CursorInfo> cursors = new HashMap<>();
1374
1520
  static Map<Integer, String> cursorNames = Map.of(
1375
1521
  PConstants.ARROW, "arrow",
1376
1522
  PConstants.CROSS, "cross",
@@ -1381,79 +1527,67 @@ public class PSurfaceJOGL implements PSurface {
1381
1527
  );
1382
1528
 
1383
1529
 
1384
- @Override
1385
- public void setCursor(int kind) {
1386
- if (!cursorNames.containsKey(kind)) {
1387
- PGraphics.showWarning("Unknown cursor type: " + kind);
1388
- return;
1389
- }
1390
- CursorInfo cursor = cursors.get(kind);
1391
- if (cursor == null) {
1392
- String name = cursorNames.get(kind);
1393
- if (name != null) {
1394
- ImageIcon icon
1395
- = new ImageIcon(getClass().getResource("cursors/" + name + ".png"));
1396
- PImage img = new PImage(icon.getImage());
1397
- // Most cursors just use the center as the hotspot...
1398
- int x = img.width / 2;
1399
- int y = img.height / 2;
1400
- // ...others are more specific
1401
- switch (kind) {
1402
- case PConstants.ARROW:
1403
- x = 10;
1404
- y = 7;
1405
- break;
1406
- case PConstants.HAND:
1407
- x = 12;
1408
- y = 8;
1409
- break;
1410
- case PConstants.TEXT:
1411
- x = 16;
1412
- y = 22;
1413
- break;
1414
- default:
1415
- break;
1416
- }
1417
- cursor = new CursorInfo(img, x, y);
1418
- cursors.put(kind, cursor);
1419
- }
1420
- }
1421
- if (cursor != null) {
1422
- cursor.set();
1423
- } else {
1424
- PGraphics.showWarning("Cannot load cursor type: " + kind);
1425
- }
1426
- }
1427
-
1428
- @Override
1429
- public void setCursor(PImage image, int hotspotX, int hotspotY) {
1430
- Display disp = window.getScreen().getDisplay();
1431
- BufferedImage bimg = (BufferedImage) image.getNative();
1432
- DataBufferInt dbuf = (DataBufferInt) bimg.getData().getDataBuffer();
1433
- int[] ipix = dbuf.getData();
1434
- ByteBuffer pixels = ByteBuffer.allocate(ipix.length * 4);
1435
- pixels.asIntBuffer().put(ipix);
1436
- PixelFormat format = PixelFormat.ARGB8888;
1437
- final Dimension size = new Dimension(bimg.getWidth(), bimg.getHeight());
1438
- PixelRectangle pixelrect = new PixelRectangle.GenericPixelRect(format, size, 0, false, pixels);
1439
- final PointerIcon pi = disp.createPointerIcon(pixelrect, hotspotX, hotspotY);
1440
- display.getEDTUtil().invoke(false, () -> {
1441
- window.setPointerVisible(true);
1442
- window.setPointerIcon(pi);
1443
- });
1444
- }
1530
+ // @Override
1531
+ // public void setCursor(int kind) {
1532
+ // if (!cursorNames.containsKey(kind)) {
1533
+ // PGraphics.showWarning("Unknown cursor type: " + kind);
1534
+ // return;
1535
+ // }
1536
+ // CursorInfo cursor = cursors.get(kind);
1537
+ // if (cursor == null) {
1538
+ // String name = cursorNames.get(kind);
1539
+ // if (name != null) {
1540
+ // ImageIcon icon
1541
+ // = new ImageIcon(getClass().getResource("cursors/" + name + ".png"));
1542
+ // PImage img = new PImage(icon.getImage());
1543
+ // // Most cursors just use the center as the hotspot...
1544
+ // int x = img.width / 2;
1545
+ // int y = img.height / 2;
1546
+ // // ...others are more specific
1547
+ // switch (kind) {
1548
+ // case PConstants.ARROW:
1549
+ // x = 10;
1550
+ // y = 7;
1551
+ // break;
1552
+ // case PConstants.HAND:
1553
+ // x = 12;
1554
+ // y = 8;
1555
+ // break;
1556
+ // case PConstants.TEXT:
1557
+ // x = 16;
1558
+ // y = 22;
1559
+ // break;
1560
+ // default:
1561
+ // break;
1562
+ // }
1563
+ // cursor = new CursorInfo(img, x, y);
1564
+ // cursors.put(kind, cursor);
1565
+ // }
1566
+ // }
1567
+ // if (cursor != null) {
1568
+ // cursor.set();
1569
+ // } else {
1570
+ // PGraphics.showWarning("Cannot load cursor type: " + kind);
1571
+ // }
1572
+ // }
1573
+ //
1574
+ // @Override
1575
+ // public void setCursor(PImage image, int hotspotX, int hotspotY) {
1576
+ // Display disp = window.getScreen().getDisplay();
1577
+ // BufferedImage bimg = (BufferedImage) image.getNative();
1578
+ // DataBufferInt dbuf = (DataBufferInt) bimg.getData().getDataBuffer();
1579
+ // int[] ipix = dbuf.getData();
1580
+ // ByteBuffer pixels = ByteBuffer.allocate(ipix.length * 4);
1581
+ // pixels.asIntBuffer().put(ipix);
1582
+ // PixelFormat format = PixelFormat.ARGB8888;
1583
+ // final Dimension size = new Dimension(bimg.getWidth(), bimg.getHeight());
1584
+ // PixelRectangle pixelrect = new PixelRectangle.GenericPixelRect(format, size, 0, false, pixels);
1585
+ // final PointerIcon pi = disp.createPointerIcon(pixelrect, hotspotX, hotspotY);
1586
+ // display.getEDTUtil().invoke(false, () -> {
1587
+ // window.setPointerVisible(true);
1588
+ // window.setPointerIcon(pi);
1589
+ // });
1590
+ // }
1445
1591
 
1446
- @Override
1447
- public void showCursor() {
1448
- display.getEDTUtil().invoke(false, () -> {
1449
- window.setPointerVisible(true);
1450
- });
1451
- }
1452
1592
 
1453
- @Override
1454
- public void hideCursor() {
1455
- display.getEDTUtil().invoke(false, () -> {
1456
- window.setPointerVisible(false);
1457
- });
1458
- }
1459
1593
  }
@@ -0,0 +1,607 @@
1
+ /*
2
+ Part of the Processing project - http://processing.org
3
+
4
+ Copyright (c) 2005-12 Ben Fry and Casey Reas
5
+ Copyright (c) 2012-18 The Processing Foundation
6
+
7
+ This library is free software; you can redistribute it and/or
8
+ modify it under the terms of the GNU Lesser General Public
9
+ License version 2.1 as published by the Free Software Foundation.
10
+
11
+ This library is distributed in the hope that it will be useful,
12
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
+ Lesser General Public License for more details.
15
+
16
+ You should have received a copy of the GNU Lesser General
17
+ Public License along with this library; if not, write to the
18
+ Free Software Foundation, Inc., 59 Temple Place, Suite 330,
19
+ Boston, MA 02111-1307 USA
20
+ */
21
+ package processing.pdf;
22
+
23
+ import com.itextpdf.awt.DefaultFontMapper;
24
+ import com.itextpdf.text.Rectangle;
25
+ import com.itextpdf.text.Document;
26
+ import com.itextpdf.text.DocumentException;
27
+ import com.itextpdf.text.pdf.ByteBuffer;
28
+ import com.itextpdf.text.pdf.PdfContentByte;
29
+ import com.itextpdf.text.pdf.PdfWriter;
30
+ import java.awt.Font;
31
+ import java.awt.Graphics2D;
32
+ import java.awt.Image;
33
+ import java.io.*;
34
+ import java.util.*;
35
+ import java.util.logging.Level;
36
+ import java.util.logging.Logger;
37
+
38
+ //import com.lowagie.text.*;
39
+ //import com.lowagie.text.pdf.*;
40
+ //import com.lowagie.text.pdf.ByteBuffer;
41
+
42
+ import processing.awt.PGraphicsJava2D;
43
+ import processing.core.*;
44
+
45
+ /**
46
+ * Thin wrapper for the iText PDF library that handles writing PDF files. The
47
+ * majority of the work in this library is done by
48
+ * <a href="http://www.lowagie.com/iText/">iText</a>.
49
+ * This is currently using iText 2.1.7.
50
+ * The issue is that versions from the 5.x series were slow to handle lots of
51
+ * fonts with the DefaultFontMapper. 2.x seemed a little slower than 1.x, but
52
+ * 5.x took up to 10 times the time to load, meaning a lag of several seconds
53
+ * when starting sketches on a machine that had a good handful of fonts
54
+ * installed. (Like, say, anyone in our target audience. Or me.)
55
+ */
56
+ public class PGraphicsPDF extends PGraphicsJava2D {
57
+
58
+ /**
59
+ * File being written, if it's a file.
60
+ */
61
+ protected File file;
62
+ /**
63
+ * OutputStream being written to, if using an OutputStream.
64
+ */
65
+ protected OutputStream output;
66
+
67
+ protected Document document;
68
+ protected PdfWriter writer;
69
+ protected PdfContentByte content;
70
+
71
+ /**
72
+ * Shared across instances because it's incredibly time-consuming to create.
73
+ */
74
+ static protected DefaultFontMapper mapper;
75
+ static protected String[] fontList;
76
+
77
+
78
+ /*
79
+ public PGraphicsPDF() {
80
+ // PDF always likes native fonts. Always.
81
+ hint(ENABLE_NATIVE_FONTS);
82
+ }
83
+ */
84
+ @Override
85
+ public void setPath(String path) {
86
+ this.path = path;
87
+ if (path != null) {
88
+ file = new File(path);
89
+ if (!file.isAbsolute()) {
90
+ file = null;
91
+ }
92
+ }
93
+ if (file == null) {
94
+ throw new RuntimeException("PGraphicsPDF requires an absolute path "
95
+ + "for the location of the output file.");
96
+ }
97
+ }
98
+
99
+ /**
100
+ * Set the library to write to an output stream instead of a file.
101
+ * @param output
102
+ */
103
+ public void setOutput(OutputStream output) {
104
+ this.output = output;
105
+ }
106
+
107
+ // /**
108
+ // * all the init stuff happens in here, in case someone calls size()
109
+ // * along the way and wants to hork things up.
110
+ // */
111
+ // protected void allocate() {
112
+ // // can't do anything here, because this will be called by the
113
+ // // superclass PGraphics, and the file/path object won't be set yet
114
+ // // (since super() called right at the beginning of the constructor)
115
+ // }
116
+ @Override
117
+ public PSurface createSurface() {
118
+ return surface = new PSurfaceNone(this);
119
+ }
120
+
121
+ @Override
122
+ protected void defaultSettings() { // ignore
123
+ super.defaultSettings();
124
+ textMode = SHAPE;
125
+ }
126
+
127
+ @Override
128
+ public void beginDraw() {
129
+ // long t0 = System.currentTimeMillis();
130
+
131
+ if (document == null) {
132
+ // https://github.com/processing/processing/issues/5801#issuecomment-466632459
133
+ ByteBuffer.HIGH_PRECISION = true;
134
+
135
+ document = new Document(new Rectangle(width, height));
136
+ boolean missingPath = false;
137
+ try {
138
+ if (file != null) {
139
+ //BufferedOutputStream output = new BufferedOutputStream(stream, 16384);
140
+ output = new BufferedOutputStream(new FileOutputStream(file), 16384);
141
+
142
+ } else if (output == null) {
143
+ missingPath = true;
144
+ throw new RuntimeException("PGraphicsPDF requires a path "
145
+ + "for the location of the output file.");
146
+ }
147
+ try {
148
+ writer = PdfWriter.getInstance(document, output);
149
+ } catch (DocumentException ex) {
150
+ Logger.getLogger(PGraphicsPDF.class.getName()).log(Level.SEVERE, null, ex);
151
+ }
152
+ document.open();
153
+ content = writer.getDirectContent();
154
+ // template = content.createTemplate(width, height);
155
+
156
+ } catch (RuntimeException re) {
157
+ if (missingPath) {
158
+ throw re; // don't re-package our own error
159
+ } else {
160
+ throw new RuntimeException("Problem saving the PDF file.", re);
161
+ }
162
+
163
+ } catch (FileNotFoundException fnfe) {
164
+ throw new RuntimeException("Can't save the PDF file to " + path, fnfe);
165
+
166
+ }
167
+
168
+ g2 = content.createGraphicsShapes(width, height);
169
+ }
170
+
171
+ // super in Java2D now creates an image buffer, don't do that
172
+ //super.beginDraw();
173
+ checkSettings();
174
+ resetMatrix(); // reset model matrix
175
+ vertexCount = 0;
176
+
177
+ // Also need to push the matrix since the matrix doesn't reset on each run
178
+ // http://dev.processing.org/bugs/show_bug.cgi?id=1227
179
+ pushMatrix();
180
+ }
181
+
182
+ static protected DefaultFontMapper getMapper() {
183
+ if (mapper == null) {
184
+ // long t = System.currentTimeMillis();
185
+ mapper = new DefaultFontMapper();
186
+
187
+ if (PApplet.platform == PConstants.LINUX) {
188
+ checkDir("/usr/share/fonts/", mapper);
189
+ checkDir("/usr/local/share/fonts/", mapper);
190
+ checkDir(System.getProperty("user.home") + "/.fonts", mapper);
191
+ }
192
+ // System.out.println("mapping " + (System.currentTimeMillis() - t));
193
+ }
194
+ return mapper;
195
+ }
196
+
197
+ static protected void checkDir(String path, DefaultFontMapper mapper) {
198
+ File folder = new File(path);
199
+ if (folder.exists()) {
200
+ mapper.insertDirectory(path);
201
+ traverseDir(folder, mapper);
202
+ }
203
+ }
204
+
205
+ /**
206
+ * Recursive walk to get all subdirectories for font fun.Patch submitted by
207
+ Matthias Breuer.(<a href="http://dev.processing.org/bugs/show_bug.cgi?id=1566">Bug
208
+ 1566</a>)
209
+ * @param folder
210
+ * @param mapper
211
+ */
212
+ static protected void traverseDir(File folder, DefaultFontMapper mapper) {
213
+ File[] files = folder.listFiles();
214
+ for (File file1 : files) {
215
+ if (file1.isDirectory()) {
216
+ mapper.insertDirectory(file1.getPath());
217
+ traverseDir(new File(file1.getPath()), mapper);
218
+ }
219
+ }
220
+ }
221
+
222
+ // endDraw() needs to be overridden so that the endDraw() from
223
+ // PGraphicsJava2D is not inherited (it calls loadPixels).
224
+ // http://dev.processing.org/bugs/show_bug.cgi?id=1169
225
+ @Override
226
+ public void endDraw() {
227
+ // Also need to pop the matrix since the matrix doesn't reset on each run
228
+ // http://dev.processing.org/bugs/show_bug.cgi?id=1227
229
+ popMatrix();
230
+ }
231
+
232
+ /**
233
+ * Call to explicitly go to the next page from within a single draw().
234
+ */
235
+ public void nextPage() {
236
+ PStyle savedStyle = getStyle();
237
+ endDraw();
238
+ g2.dispose();
239
+
240
+ try {
241
+ // writer.setPageEmpty(false); // maybe useful later
242
+ document.newPage(); // is this bad if no addl pages are made?
243
+ } catch (Exception e) {
244
+ }
245
+ g2 = createGraphics();
246
+ beginDraw();
247
+ style(savedStyle);
248
+ }
249
+
250
+ protected Graphics2D createGraphics() {
251
+ if (textMode == SHAPE) {
252
+ return content.createGraphics(width, height);
253
+ } else if (textMode == MODEL) {
254
+ return content.createGraphics(width, height, getMapper());
255
+ }
256
+ // Should not be reachable...
257
+ throw new RuntimeException("Invalid textMode() selected for PDF.");
258
+ }
259
+
260
+ @Override
261
+ public void dispose() {
262
+ if (document != null) {
263
+ g2.dispose();
264
+ document.close(); // can't be done in finalize, not always called
265
+ document = null;
266
+ }
267
+ //new Exception().printStackTrace(System.out);
268
+ }
269
+
270
+ /**
271
+ * Don't open a window for this renderer, it won't be used.
272
+ * @return
273
+ */
274
+ @Override
275
+ public boolean displayable() {
276
+ return false;
277
+ }
278
+
279
+ /*
280
+ protected void finalize() throws Throwable {
281
+ System.out.println("calling finalize");
282
+ //document.close(); // do this in dispose instead?
283
+ }
284
+ */
285
+ //////////////////////////////////////////////////////////////
286
+ /*
287
+ public void endRecord() {
288
+ super.endRecord();
289
+ dispose();
290
+ }
291
+
292
+
293
+ public void endRaw() {
294
+ System.out.println("ending raw");
295
+ super.endRaw();
296
+ System.out.println("disposing");
297
+ dispose();
298
+ System.out.println("done");
299
+ }
300
+ */
301
+ //////////////////////////////////////////////////////////////
302
+ /*
303
+ protected void rectImpl(float x1, float y1, float x2, float y2) {
304
+ //rect.setFrame(x1, y1, x2-x1, y2-y1);
305
+ //draw_shape(rect);
306
+ System.out.println("rect implements");
307
+ g2.fillRect((int)x1, (int)y1, (int) (x2-x1), (int) (y2-y1));
308
+ }
309
+ *
310
+
311
+ /*
312
+ public void clear() {
313
+ g2.setColor(Color.red);
314
+ g2.fillRect(0, 0, width, height);
315
+ }
316
+ */
317
+ //////////////////////////////////////////////////////////////
318
+ @Override
319
+ protected void imageImpl(PImage image,
320
+ float x1, float y1, float x2, float y2,
321
+ int u1, int v1, int u2, int v2) {
322
+ pushMatrix();
323
+ translate(x1, y1);
324
+ int imageWidth = image.width;
325
+ int imageHeight = image.height;
326
+ scale((x2 - x1) / imageWidth,
327
+ (y2 - y1) / imageHeight);
328
+ if (u2 - u1 == imageWidth && v2 - v1 == imageHeight) {
329
+ g2.drawImage((Image) image.getNative(), 0, 0, null);
330
+ } else {
331
+ PImage tmp = image.get(u1, v1, u2 - u1, v2 - v1);
332
+ g2.drawImage((Image) tmp.getNative(), 0, 0, null);
333
+ }
334
+ popMatrix();
335
+ }
336
+
337
+ //////////////////////////////////////////////////////////////
338
+ @Override
339
+ public void textFont(PFont which) {
340
+ super.textFont(which);
341
+ checkFont();
342
+ // Make sure a native version of the font is available.
343
+ // if (textFont.getFont() == null) {
344
+ // throw new RuntimeException("Use createFont() instead of loadFont() " +
345
+ // "when drawing text using the PDF library.");
346
+ // }
347
+ // Make sure that this is a font that the PDF library can deal with.
348
+ // if ((textMode != SHAPE) && !checkFont(which.getName())) {
349
+ // System.err.println("Use PGraphicsPDF.listFonts() to get a list of available fonts.");
350
+ // throw new RuntimeException("The font “" + which.getName() + "” cannot be used with PDF Export.");
351
+ // }
352
+ }
353
+
354
+ /**
355
+ * Change the textMode() to either SHAPE or MODEL.
356
+ * This resets all renderer settings, and therefore must be called
357
+ * <EM>before</EM> any other commands that set the fill() or the textFont()
358
+ * or anything. Unlike other renderers, use textMode() directly after the
359
+ * size() command.
360
+ */
361
+ @Override
362
+ public void textMode(int mode) {
363
+ if (textMode != mode) {
364
+ switch (mode) {
365
+ case SHAPE:
366
+ textMode = SHAPE;
367
+ g2.dispose();
368
+ // g2 = content.createGraphicsShapes(width, height);
369
+ g2 = createGraphics();
370
+ break;
371
+ case MODEL:
372
+ textMode = MODEL;
373
+ g2.dispose();
374
+ // g2 = content.createGraphics(width, height, mapper);
375
+ g2 = createGraphics();
376
+ // g2 = template.createGraphics(width, height, mapper);
377
+ break;
378
+ case SCREEN:
379
+ throw new RuntimeException("textMode(SCREEN) not supported with PDF");
380
+ default:
381
+ throw new RuntimeException("That textMode() does not exist");
382
+ }
383
+ }
384
+ }
385
+
386
+ @Override
387
+ protected void textLineImpl(char buffer[], int start, int stop,
388
+ float x, float y) {
389
+ checkFont();
390
+ super.textLineImpl(buffer, start, stop, x, y);
391
+ }
392
+
393
+ //////////////////////////////////////////////////////////////
394
+ @Override
395
+ public void loadPixels() {
396
+ nope("loadPixels");
397
+ }
398
+
399
+ @Override
400
+ public void updatePixels() {
401
+ nope("updatePixels");
402
+ }
403
+
404
+ @Override
405
+ public void updatePixels(int x, int y, int c, int d) {
406
+ nope("updatePixels");
407
+ }
408
+
409
+ //
410
+ @Override
411
+ public int get(int x, int y) {
412
+ nope("get");
413
+ return 0; // not reached
414
+ }
415
+
416
+ @Override
417
+ public PImage get(int x, int y, int c, int d) {
418
+ nope("get");
419
+ return null; // not reached
420
+ }
421
+
422
+ @Override
423
+ public PImage get() {
424
+ nope("get");
425
+ return null; // not reached
426
+ }
427
+
428
+ @Override
429
+ public void set(int x, int y, int argb) {
430
+ nope("set");
431
+ }
432
+
433
+ @Override
434
+ public void set(int x, int y, PImage image) {
435
+ nope("set");
436
+ }
437
+
438
+ //
439
+
440
+ /**
441
+ *
442
+ * @param alpha
443
+ */
444
+ @Override
445
+ public void mask(int alpha[]) {
446
+ nope("mask");
447
+ }
448
+
449
+ @Override
450
+ public void mask(PImage alpha) {
451
+ nope("mask");
452
+ }
453
+
454
+ /**
455
+ *
456
+ * @param kind
457
+ */
458
+ @Override
459
+ public void filter(int kind) {
460
+ nope("filter");
461
+ }
462
+
463
+ @Override
464
+ public void filter(int kind, float param) {
465
+ nope("filter");
466
+ }
467
+
468
+ //
469
+ @Override
470
+ protected void blendModeImpl() {
471
+ if (blendMode != REPLACE && blendMode != BLEND) {
472
+ showMissingWarning("blendMode");
473
+ }
474
+ }
475
+
476
+ //
477
+ @Override
478
+ public void copy(int sx1, int sy1, int sx2, int sy2,
479
+ int dx1, int dy1, int dx2, int dy2) {
480
+ nope("copy");
481
+ }
482
+
483
+ /**
484
+ *
485
+ * @param src
486
+ * @param sx1
487
+ * @param sy1
488
+ * @param sx2
489
+ * @param sy2
490
+ * @param dx1
491
+ * @param dy1
492
+ * @param dx2
493
+ * @param dy2
494
+ */
495
+ @Override
496
+ public void copy(PImage src,
497
+ int sx1, int sy1, int sx2, int sy2,
498
+ int dx1, int dy1, int dx2, int dy2) {
499
+ nope("copy");
500
+ }
501
+
502
+ //
503
+ public void blend(int sx, int sy, int dx, int dy, int mode) {
504
+ nope("blend");
505
+ }
506
+
507
+ public void blend(PImage src,
508
+ int sx, int sy, int dx, int dy, int mode) {
509
+ nope("blend");
510
+ }
511
+
512
+ @Override
513
+ public void blend(int sx1, int sy1, int sx2, int sy2,
514
+ int dx1, int dy1, int dx2, int dy2, int mode) {
515
+ nope("blend");
516
+ }
517
+
518
+ @Override
519
+ public void blend(PImage src,
520
+ int sx1, int sy1, int sx2, int sy2,
521
+ int dx1, int dy1, int dx2, int dy2, int mode) {
522
+ nope("blend");
523
+ }
524
+
525
+ //
526
+ @Override
527
+ public boolean save(String filename) {
528
+ nope("save");
529
+ return false;
530
+ }
531
+
532
+ //////////////////////////////////////////////////////////////
533
+ /**
534
+ * On Linux or any other platform, you'll need to add the directories by
535
+ * hand. (If there are actual standards here that we can use as a starting
536
+ * point, please file a bug to make a note of it)
537
+ * @param directory
538
+ */
539
+ public void addFonts(String directory) {
540
+ mapper.insertDirectory(directory);
541
+ }
542
+
543
+ /**
544
+ * Check whether the specified font can be used with the PDF library.
545
+ *
546
+ */
547
+ protected void checkFont() {
548
+ Font awtFont = (Font) textFont.getNative();
549
+ if (awtFont == null) { // always need a native font or reference to it
550
+ throw new RuntimeException("Use createFont() instead of loadFont() "
551
+ + "when drawing text using the PDF library.");
552
+ } else if (textMode != SHAPE) {
553
+ if (textFont.isStream()) {
554
+ throw new RuntimeException("Use textMode(SHAPE) with PDF when loading "
555
+ + ".ttf and .otf files with createFont().");
556
+ } else if (mapper.getAliases().get(textFont.getName()) == null) {
557
+ //System.out.println("alias for " + name + " = " + mapper.getAliases().get(name));
558
+ // System.err.println("Use PGraphicsPDF.listFonts() to get a list of " +
559
+ // "fonts that can be used with PDF.");
560
+ // throw new RuntimeException("The font “" + textFont.getName() + "” " +
561
+ // "cannot be used with PDF Export.");
562
+ if (textFont.getName().equals("Lucida Sans")) {
563
+ throw new RuntimeException("Use textMode(SHAPE) with the default "
564
+ + "font when exporting to PDF.");
565
+ } else {
566
+ throw new RuntimeException("Use textMode(SHAPE) with "
567
+ + "“" + textFont.getName() + "” "
568
+ + "when exporting to PDF.");
569
+ }
570
+ }
571
+ }
572
+ }
573
+
574
+ /**
575
+ * List the fonts known to the PDF renderer.This is like PFont.list(),
576
+ however not all those fonts are available by default.
577
+ * @return
578
+ */
579
+ static public String[] listFonts() {
580
+ if (fontList == null) {
581
+ HashMap<?, ?> map = getMapper().getAliases();
582
+ // Set entries = map.entrySet();
583
+ // fontList = new String[entries.size()];
584
+ fontList = new String[map.size()];
585
+ int count = 0;
586
+ for (Object key : map.keySet()) {
587
+ // for (Object entry : map.entrySet()) {
588
+ // fontList[count++] = (String) ((Map.Entry) entry).getKey();
589
+ fontList[count++] = (String) key;
590
+ }
591
+ // Iterator it = entries.iterator();
592
+ // int count = 0;
593
+ // while (it.hasNext()) {
594
+ // Map.Entry entry = (Map.Entry) it.next();
595
+ // //System.out.println(entry.getKey() + "-->" + entry.getValue());
596
+ // fontList[count++] = (String) entry.getKey();
597
+ // }
598
+ fontList = PApplet.sort(fontList);
599
+ }
600
+ return fontList;
601
+ }
602
+
603
+ //////////////////////////////////////////////////////////////
604
+ protected void nope(String function) {
605
+ throw new RuntimeException("No " + function + "() for " + getClass().getSimpleName());
606
+ }
607
+ }