00001 package edu.stanford.hci.r3.pattern.output;
00002
00003 import java.awt.Color;
00004 import java.awt.geom.AffineTransform;
00005 import java.io.IOException;
00006
00007 import com.lowagie.text.DocumentException;
00008 import com.lowagie.text.pdf.BaseFont;
00009 import com.lowagie.text.pdf.PdfContentByte;
00010 import com.lowagie.text.pdf.PdfTemplate;
00011
00012 import edu.stanford.hci.r3.pattern.PatternJitter;
00013 import edu.stanford.hci.r3.pattern.TiledPattern;
00014 import edu.stanford.hci.r3.units.Units;
00015 import edu.stanford.hci.r3.util.DebugUtils;
00016 import edu.stanford.hci.r3.util.MathUtils;
00017
00045 public class PDFPatternGenerator {
00046
00050 private static final BaseFont BFONT_TAHOMA = createBaseFontTahoma();
00051
00055 private static final BaseFont BFONT_ZAPF = createBaseFontZapfDingbats();
00056
00061 private static final double convertHundredthsOfMMToPoints = 72 / 2540.0;
00062
00066 private static final double convertPointsToHundredthsOfMM = 2540.0 / 72;
00067
00071 private static final boolean DEBUG_PATTERN = false;
00072
00076 private static final int DEFAULT_JITTER = 5;
00077
00081 private static final int DEFAULT_PADDING = 30;
00082
00086 private static final int X_FONT_OFFSET = -2;
00087
00091 private static final int Y_FONT_OFFSET = 9;
00092
00096 private static BaseFont createBaseFontTahoma() {
00097 try {
00098 return BaseFont.createFont("/fonts/tahoma.ttf", BaseFont.CP1252, BaseFont.EMBEDDED);
00099 } catch (DocumentException e) {
00100 e.printStackTrace();
00101 } catch (IOException e) {
00102 e.printStackTrace();
00103 }
00104 return null;
00105 }
00106
00110 private static BaseFont createBaseFontZapfDingbats() {
00111 try {
00112 return BaseFont.createFont(BaseFont.ZAPFDINGBATS, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
00113 } catch (DocumentException e) {
00114 e.printStackTrace();
00115 } catch (IOException e) {
00116 e.printStackTrace();
00117 }
00118 return null;
00119 }
00120
00124 private PdfContentByte content;
00125
00129 private BaseFont debugFont;
00130
00134 private String dotSymbol;
00135
00139 private PdfTemplate dotTemplate;
00140
00141 private int fontSize;
00142
00146 private Units height;
00147
00151 private Color patternColor = Color.BLACK;
00152
00156 private BaseFont patternFont;
00157
00161 private boolean useTemplateInsteadOfFont = true;
00162
00166 private Units width;
00167
00178 public PDFPatternGenerator(PdfContentByte cb, Units w, Units h) {
00179 content = cb;
00180 width = w;
00181 height = h;
00182
00183
00184
00185
00186
00187
00188 content.transform(AffineTransform.getScaleInstance(convertHundredthsOfMMToPoints,
00189 convertHundredthsOfMMToPoints));
00190
00191 if (useTemplateInsteadOfFont) {
00192 createDotTemplate(0 );
00193 }
00194
00195
00196
00197 initializePatternFont_Zapf();
00198 }
00199
00205 public void adjustPatternSize(int patternDotSizeAdjustment) {
00206 if (useTemplateInsteadOfFont) {
00207
00208 createDotTemplate(patternDotSizeAdjustment);
00209 } else {
00210
00211 fontSize += patternDotSizeAdjustment;
00212 }
00213 }
00214
00221 private void createDotTemplate(float adjustment) {
00222 float radiusAdjustment = 0.5f * adjustment;
00223 final float defaultRadius = 2.8f;
00224 float xCenter = defaultRadius;
00225 float yCenter = defaultRadius;
00226
00227
00228 dotTemplate = content.createTemplate(2 * xCenter + 1, 2 * yCenter + 1);
00229 dotTemplate.circle(xCenter, yCenter, defaultRadius + radiusAdjustment);
00230 dotTemplate.fill();
00231 }
00232
00236 @SuppressWarnings("unused")
00237 private void initializePatternFont_Tahoma() {
00238 setPatternFontSize(21);
00239 debugFont = BFONT_TAHOMA;
00240 patternFont = BFONT_TAHOMA;
00241 dotSymbol = "•";
00242 }
00243
00248 private void initializePatternFont_Zapf() {
00249 setPatternFontSize(7);
00250 debugFont = BFONT_TAHOMA;
00251 patternFont = BFONT_ZAPF;
00252 dotSymbol = "l";
00253 }
00254
00263 public void renderPattern(TiledPattern pattern, Units xOrigin, Units yOrigin) {
00264
00265
00266 float heightOfPDF = (float) height.getValueInPoints();
00267
00268
00269 final double xOrigInPoints = xOrigin.getValueInPoints();
00270 final double yOrigInPoints = yOrigin.getValueInPoints();
00271
00272 final int numRows = pattern.getNumTotalRows();
00273 final int numCols = pattern.getNumTotalColumns();
00274
00275
00276
00277
00278
00279
00280
00281 final float heightInHundredths = (float) (heightOfPDF * convertPointsToHundredthsOfMM);
00282
00283
00284 if (!useTemplateInsteadOfFont) {
00285 content.beginText();
00286
00287 content.setFontAndSize(patternFont, fontSize);
00288 }
00289
00290 content.setColorFill(patternColor);
00291
00292
00293
00294 final int initX = MathUtils.rint(xOrigInPoints * convertPointsToHundredthsOfMM);
00295
00296 int gridXPosition = initX;
00297 int gridYPosition = MathUtils.rint(yOrigInPoints * convertPointsToHundredthsOfMM);
00298
00299 DebugUtils.println("PDFPatternGenerator: Dot Position is " + gridXPosition + " " + gridYPosition);
00300
00301 int xJitter = 0;
00302 int yJitter = 0;
00303 char currentJitterDirection;
00304
00305 for (int row = 0; row < numRows; row++) {
00306
00307 final String patternRow = pattern.getPatternOnRow(row);
00308 final int rowLength = patternRow.length();
00309
00310 for (int i = 0; i < rowLength; i++) {
00311
00312
00313 currentJitterDirection = patternRow.charAt(i);
00314
00315
00316 xJitter = 0;
00317 yJitter = 0;
00318
00319 switch (currentJitterDirection) {
00320 case PatternJitter.DOWN:
00321
00322 yJitter = DEFAULT_JITTER;
00323 break;
00324 case PatternJitter.UP:
00325
00326 yJitter = -DEFAULT_JITTER;
00327 break;
00328 case PatternJitter.LEFT:
00329
00330 xJitter = -DEFAULT_JITTER;
00331 break;
00332 case PatternJitter.RIGHT:
00333
00334 xJitter = DEFAULT_JITTER;
00335 break;
00336 }
00337
00338 if (useTemplateInsteadOfFont) {
00339 content.addTemplate(dotTemplate, gridXPosition + xJitter,
00340 heightInHundredths - (gridYPosition + yJitter));
00341 } else {
00342 content.showTextAligned(PdfContentByte.ALIGN_CENTER, dotSymbol,
00343 gridXPosition + xJitter + X_FONT_OFFSET,
00344 heightInHundredths - (gridYPosition + yJitter + Y_FONT_OFFSET), 0);
00345 }
00346
00347 gridXPosition += DEFAULT_PADDING;
00348
00349 }
00350 gridXPosition = initX;
00351 gridYPosition += DEFAULT_PADDING;
00352
00353 }
00354
00355 if (!useTemplateInsteadOfFont) {
00356 content.endText();
00357 }
00358 }
00359
00363 public void setPatternColor(Color c) {
00364 patternColor = c;
00365 }
00366
00373 private void setPatternFontSize(int s) {
00374 fontSize = s;
00375 }
00376 }