picrate 2.0.1-java → 2.3.0-java

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 (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
+ }