Package org.pdfclown.samples.cli

Source Code of org.pdfclown.samples.cli.GraphicsSample

package org.pdfclown.samples.cli;

import org.pdfclown.documents.Document;
import org.pdfclown.documents.Page;
import org.pdfclown.documents.contents.LineCapEnum;
import org.pdfclown.documents.contents.LineJoinEnum;
import org.pdfclown.documents.contents.colorSpaces.DeviceRGBColor;
import org.pdfclown.documents.contents.composition.AlignmentXEnum;
import org.pdfclown.documents.contents.composition.AlignmentYEnum;
import org.pdfclown.documents.contents.composition.BlockComposer;
import org.pdfclown.documents.contents.composition.PrimitiveComposer;
import org.pdfclown.documents.contents.composition.Length.UnitModeEnum;
import org.pdfclown.documents.contents.entities.Image;
import org.pdfclown.documents.contents.fonts.StandardType1Font;
import org.pdfclown.files.File;

import java.awt.Dimension;
import java.awt.geom.Dimension2D;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.EnumSet;

/**
  This sample demonstrates some of the <b>graphics operations</b> available through the PrimitiveComposer
  and BlockComposer classes to compose a PDF document.

  @author Stefano Chizzolini (http://www.stefanochizzolini.it)
  @since 0.0.7
  @version 0.1.0
*/
public class GraphicsSample
  extends Sample
{
  private static final DeviceRGBColor SampleColor = new DeviceRGBColor(1,0,0);
  private static final DeviceRGBColor BackColor = new DeviceRGBColor(210/256,232/256,245/256);

  @Override
  public boolean run(
    )
  {
    // 1. Instantiate a new PDF file!
    File file = new File();
    Document document = file.getDocument();

    // 2. Insert the contents into the document!
    buildCurvesPage(document);
    buildMiscellaneousPage(document);
    buildSimpleTextPage(document);
    buildTextBlockPage(document);
    buildTextBlockPage2(document);

    // (boilerplate metadata insertion -- ignore it)
    buildAccessories(document,"Composition elements","applying the composition elements");

    // 3. Serialize the PDF file!
    serialize(file,false);
   
    return true;
  }

  private void buildCurvesPage(
    Document document
    )
  {
    // 1. Add the page to the document!
    Page page = new Page(document); // Instantiates the page inside the document context.
    document.getPages().add(page); // Puts the page in the pages collection.

    Dimension2D pageSize = page.getSize();

    // 2. Create a content composer for the page!
    PrimitiveComposer composer = new PrimitiveComposer(page);

    // 3. Drawing the page contents...
    try
    {
      composer.setFont(
        new StandardType1Font(
          document,
          StandardType1Font.FamilyEnum.Courier,
          true,
          false
          ),
        32
        );
    }
    catch(Exception e)
    {throw new RuntimeException(e);}

    {
      BlockComposer blockComposer = new BlockComposer(composer);
      blockComposer.begin(new Rectangle2D.Double(30,0,pageSize.getWidth()-60,50),AlignmentXEnum.Center,AlignmentYEnum.Middle);
      blockComposer.showText("Curves");
      blockComposer.end();
    }

    // 3.1. Arcs.
    {
      float y = 100;
      for(
        int rowIndex = 0;
        rowIndex < 4;
        rowIndex++
        )
      {
        int angleStep = 45;
        int startAngle = 0;
        int endAngle = angleStep;
        float x = 100;
        float diameterX;
        float diameterY;
        switch(rowIndex)
        {
          case 0: default:
            diameterX = 40;
            diameterY = 40;
            break;
          case 1:
            diameterX = 40;
            diameterY = 20;
            break;
          case 2:
            diameterX = 20;
            diameterY = 40;
            break;
          case 3:
            diameterX = 40;
            diameterY = 40;
            break;
        }
        for(
          int index = 0,
            length = 360/angleStep;
          index < length;
          index++
          )
        {
          Rectangle2D arcFrame = new Rectangle2D.Double(x,y,diameterX,diameterY);

          // Drawing the arc frame...
          composer.beginLocalState();
          composer.setLineWidth(.25f);
          composer.setLineDash(3,5,5);
          composer.drawRectangle(arcFrame);
          composer.stroke();
          composer.end();

          // Draw the arc!
          composer.drawArc(arcFrame,startAngle,endAngle);
          composer.stroke();

          endAngle += angleStep;
          switch(rowIndex)
          {
            case 3:
              startAngle += angleStep;
              break;
          }

          x += 50;
        }

        y += diameterY + 10;
      }
    }

    // 3.2. Circle.
    {
      Rectangle2D arcFrame = new Rectangle2D.Double(
        100,
        300,
        100,
        100
        );

      // Drawing the circle frame...
      composer.beginLocalState();
      composer.setLineWidth(.25f);
      composer.setLineDash(3,5,5);
      composer.drawRectangle(arcFrame);
      composer.stroke();
      composer.end();

      // Drawing the circle...
      composer.setFillColor(new DeviceRGBColor(1,0,0));
      composer.drawEllipse(arcFrame);
      composer.fillStroke();
    }

    // 3.3. Horizontal ellipse.
    {
      Rectangle2D arcFrame = new Rectangle2D.Double(
        210,
        300,
        100,
        50
        );

      // Drawing the ellipse frame...
      composer.beginLocalState();
      composer.setLineWidth(.25f);
      composer.setLineDash(3,5,5);
      composer.drawRectangle(arcFrame);
      composer.stroke();
      composer.end();

      // Drawing the ellipse...
      composer.setFillColor(new DeviceRGBColor(0,1,0));
      composer.drawEllipse(arcFrame);
      composer.fillStroke();
    }

    // 3.4. Vertical ellipse.
    {
      Rectangle2D arcFrame = new Rectangle2D.Double(
        320,
        300,
        50,
        100
        );

      // Drawing the ellipse frame...
      composer.beginLocalState();
      composer.setLineWidth(.25f);
      composer.setLineDash(3,5,5);
      composer.drawRectangle(arcFrame);
      composer.stroke();
      composer.end();

      // Drawing the ellipse...
      composer.setFillColor(new DeviceRGBColor(0,0,1));
      composer.drawEllipse(arcFrame);
      composer.fillStroke();
    }

    // 3.5. Spirals.
    {
      float y = 500;
      float spiralWidth = 100;
      composer.setLineWidth(.5f);
      for(
        int rowIndex = 0;
        rowIndex < 3;
        rowIndex++
        )
      {
        float x = 150;
        float branchWidth = .5f;
        float branchRatio = 1;
        for(
          int spiralIndex = 0;
          spiralIndex < 4;
          spiralIndex++
          )
        {
          float spiralTurnsCount;
          switch(rowIndex)
          {
            case 0: default:
              spiralTurnsCount = spiralWidth/(branchWidth*8);
              break;
            case 1:
              spiralTurnsCount = spiralWidth/(branchWidth*8*(spiralIndex*1.15f+1));
              break;
          }
          switch(rowIndex)
          {
            case 2:
              composer.setLineDash(0,10,5);
              composer.setLineCap(LineCapEnum.Round);
              break;
            default:
              break;
          }

          composer.drawSpiral(
            new Point2D.Double(x,y),
            0,
            360*spiralTurnsCount,
            branchWidth,
            branchRatio
            );
          composer.stroke();

          x += spiralWidth + 10;

          switch(rowIndex)
          {
            case 0: default:
              branchWidth += 1;
              break;
            case 1:
              branchRatio += .035;
              break;
          }
          switch(rowIndex)
          {
            case 2:
              composer.setLineWidth(composer.getState().getLineWidth() + .5f);
              break;
          }
        }

        y += spiralWidth + 10;
      }
    }

    // 4. Flush the contents into the page!
    composer.flush();
  }

  private void buildMiscellaneousPage(
    Document document
    )
  {
    // 1. Add the page to the document!
    Page page = new Page(document); // Instantiates the page inside the document context.
    document.getPages().add(page); // Puts the page in the pages collection.

    Dimension2D pageSize = page.getSize();

    // 2. Create a content composer for the page!
    PrimitiveComposer composer = new PrimitiveComposer(page);

    // 3. Drawing the page contents...
    try
    {
      composer.setFont(
        new StandardType1Font(
          document,
          StandardType1Font.FamilyEnum.Courier,
          true,
          false
          ),
        32
        );
    }
    catch(Exception e)
    {throw new RuntimeException(e);}

    {
      BlockComposer blockComposer = new BlockComposer(composer);
      blockComposer.begin(new Rectangle2D.Double(30,0,pageSize.getWidth()-60,50),AlignmentXEnum.Center,AlignmentYEnum.Middle);
      blockComposer.showText("Miscellaneous");
      blockComposer.end();
    }

    composer.beginLocalState();
    composer.setLineJoin(LineJoinEnum.Round);
    composer.setLineCap(LineCapEnum.Round);

    // 3.1. Polygon.
    composer.drawPolygon(
      new Point2D[]
      {
        new Point2D.Double(100,200),
        new Point2D.Double(150,150),
        new Point2D.Double(200,150),
        new Point2D.Double(250,200)
      }
      );

    // 3.2. Polyline.
    composer.drawPolyline(
      new Point2D[]
      {
        new Point2D.Double(300,200),
        new Point2D.Double(350,150),
        new Point2D.Double(400,150),
        new Point2D.Double(450,200)
      }
      );

    composer.stroke();

    // 3.3. Rectangle (both squared and rounded).
    int x = 50;
    int radius = 0;
    while(x < 500)
    {
      if(x > 300)
      {
        composer.setLineDash(3,5,5);
      }

      composer.setFillColor(new DeviceRGBColor(1,x/500,x/500));
      composer.drawRectangle(
          new Rectangle2D.Double(x,250,150,100),
          radius // NOTE: radius parameter determines the rounded angle size.
          );
      composer.fillStroke();

      x += 175;
      radius += 10;
    }
    composer.end(); // End local state.

    composer.beginLocalState();
    composer.setFont(
      composer.getState().getFont(),
      12
      );

    // 3.4. Line cap parameter.
    int y = 400;
    for(LineCapEnum lineCap
      : EnumSet.allOf(LineCapEnum.class))
    {
      composer.showText(
        lineCap + ":",
        new Point2D.Double(50,y),
        AlignmentXEnum.Left,
        AlignmentYEnum.Middle,
        0
        );
      composer.setLineWidth(12);
      composer.setLineCap(lineCap);
      composer.drawLine(
        new Point2D.Double(120,y),
        new Point2D.Double(220,y)
        );
      composer.stroke();

      composer.beginLocalState();
      composer.setLineWidth(1);
      composer.setStrokeColor(DeviceRGBColor.White);
      composer.setLineCap(LineCapEnum.Butt);
      composer.drawLine(
        new Point2D.Double(120,y),
        new Point2D.Double(220,y)
        );
      composer.stroke();
      composer.end(); // End local state.

      y += 30;
    }

    // 3.5. Line join parameter.
    y += 50;
    for(LineJoinEnum lineJoin
      : EnumSet.allOf(LineJoinEnum.class))
    {
      composer.showText(
        lineJoin + ":",
        new Point2D.Double(50,y),
        AlignmentXEnum.Left,
        AlignmentYEnum.Middle,
        0
        );
      composer.setLineWidth(12);
      composer.setLineJoin(lineJoin);
      Point2D.Double[] points = new Point2D.Double[]
        {
          new Point2D.Double(120,y+25),
          new Point2D.Double(150,y-25),
          new Point2D.Double(180,y+25)
        };
      composer.drawPolyline(points);
      composer.stroke();

      composer.beginLocalState();
      composer.setLineWidth(1);
      composer.setStrokeColor(DeviceRGBColor.White);
      composer.setLineCap(LineCapEnum.Butt);
      composer.drawPolyline(points);
      composer.stroke();
      composer.end(); // End local state.

      y += 50;
    }
    composer.end(); // End local state.

    // 3.6. Clipping.
    /*
      NOTE: Clipping should be conveniently enclosed within a local state
      in order to easily resume the unaltered drawing area after the operation completes.
    */
    composer.beginLocalState();
    composer.drawPolygon(
      new Point2D[]
      {
        new Point2D.Double(220,410),
        new Point2D.Double(300,490),
        new Point2D.Double(450,360),
        new Point2D.Double(430,520),
        new Point2D.Double(590,565),
        new Point2D.Double(420,595),
        new Point2D.Double(460,730),
        new Point2D.Double(380,650),
        new Point2D.Double(330,765),
        new Point2D.Double(310,640),
        new Point2D.Double(220,710),
        new Point2D.Double(275,570),
        new Point2D.Double(170,500),
        new Point2D.Double(275,510)
      }
      );
    composer.clip();
    // Showing a clown image...
    // Instantiate a jpeg image object!
    Image image = Image.get(getInputPath() + java.io.File.separator + "images" + java.io.File.separator + "Clown.jpg"); // Abstract image (entity).
    // Show the image!
    composer.showXObject(
      image.toXObject(document),
      new Point2D.Double(
        170,
        320
        ),
      new Dimension(450,0)
      );
    composer.end(); // End local state.

    // 4. Flush the contents into the page!
    composer.flush();
  }

  private void buildSimpleTextPage(
    Document document
    )
  {
    // 1. Add the page to the document!
    Page page = new Page(document); // Instantiates the page inside the document context.
    document.getPages().add(page); // Puts the page in the pages collection.

    Dimension2D pageSize = page.getSize();

    // 2. Create a content composer for the page!
    PrimitiveComposer composer = new PrimitiveComposer(page);
    // 3. Inserting contents...
    // Set the font to use!
    try
    {
      composer.setFont(
        new StandardType1Font(
          document,
          StandardType1Font.FamilyEnum.Courier,
          true,
          false
          ),
        32
        );
    }
    catch(Exception e)
    {}

    EnumSet<AlignmentXEnum> xAlignments = EnumSet.allOf(AlignmentXEnum.class);
    EnumSet<AlignmentYEnum> yAlignments = EnumSet.allOf(AlignmentYEnum.class);
    int step = (int)(pageSize.getHeight()) / ((xAlignments.size()-1) * yAlignments.size()+1);

    BlockComposer blockComposer = new BlockComposer(composer);
    Rectangle2D frame = new Rectangle2D.Double(
      30,
      0,
      pageSize.getWidth()-60,
      step/2
      );
    blockComposer.begin(frame,AlignmentXEnum.Center,AlignmentYEnum.Middle);
    blockComposer.showText(
      "Simple text alignment"
      );
    blockComposer.end();

    frame = new Rectangle2D.Double(
      30,
      pageSize.getHeight()-step/2,
      pageSize.getWidth()-60,
      step/2 -10
      );
    blockComposer.begin(frame,AlignmentXEnum.Left,AlignmentYEnum.Bottom);
    composer.setFont(composer.getState().getFont(),10);
    blockComposer.showText(
      "NOTE: showText(...) methods return the actual bounding box of the text shown.\n"
        + "NOTE: The rotation parameter can be freely defined as a floating point value."
      );
    blockComposer.end();

    composer.setFont(composer.getState().getFont(),12);
    int x = 30;
    int y = step;
    int alignmentIndex = 0;
    for(AlignmentXEnum alignmentX
      : EnumSet.allOf(AlignmentXEnum.class))
    {
      /*
        NOTE: As text shown through PrimitiveComposer has no bounding box constraining its extension,
        applying the justified alignment has no effect (it degrades to center alignment);
        in order to get such an effect, use BlockComposer instead.
      */
      if(alignmentX.equals(AlignmentXEnum.Justify))
        continue;

      for(AlignmentYEnum alignmentY
        : EnumSet.allOf(AlignmentYEnum.class))
      {
        if(alignmentIndex % 2 == 0)
        {
          composer.beginLocalState();
          composer.setFillColor(BackColor);
          composer.drawRectangle(
            new Rectangle2D.Double(
              0,
              y-step/2,
              pageSize.getWidth(),
              step
              )
            );
          composer.fill();
          composer.end();
        }

        composer.showText(
          alignmentX + " " + alignmentY + ":",
          new Point2D.Double(x,y),
          AlignmentXEnum.Left,
          AlignmentYEnum.Middle,
          0
          );

        y+=step;
        alignmentIndex++;
      }
    }

    float rotationStep = 0;
    float rotation = 0;
    for(
      int columnIndex = 0;
      columnIndex < 2;
      columnIndex++
      )
    {
      switch(columnIndex)
      {
        case 0:
          x = 200;
          rotationStep = 0;
          break;
        case 1:
          x = (int)pageSize.getWidth() / 2 + 100;
          rotationStep = 360 / ((xAlignments.size()-1) * yAlignments.size()-1);
          break;
      }
      y = step;
      rotation = 0;
      for(AlignmentXEnum alignmentX
        : EnumSet.allOf(AlignmentXEnum.class))
      {
        /*
          NOTE: As text shown through PrimitiveComposer has no bounding box constraining its extension,
          applying the justified alignment has no effect (it degrades to center alignment);
          in order to get such an effect, use BlockComposer instead.
        */
        if(alignmentX.equals(AlignmentXEnum.Justify))
          continue;

        for(AlignmentYEnum alignmentY
          : EnumSet.allOf(AlignmentYEnum.class))
        {
          float startArcAngle = 0;
          switch(alignmentX)
          {
            case Left:
              // OK -- NOOP.
              break;
            case Right:
            case Center:
              startArcAngle = 180;
              break;
          }

          composer.drawArc(
            new Rectangle2D.Double(
              x-10,
              y-10,
              20,
              20
              ),
            startArcAngle,
            startArcAngle+rotation
            );

          drawText(
            composer,
            "PDF Clown",
            new Point2D.Double(x,y),
            alignmentX,
            alignmentY,
            rotation
            );
          y+=step;
          rotation+=rotationStep;
        }
      }
    }

    // 4. Flush the contents into the page!
    composer.flush();
  }

  private void buildTextBlockPage(
    Document document
    )
  {
    // 1. Add the page to the document!
    Page page = new Page(document); // Instantiates the page inside the document context.
    document.getPages().add(page); // Puts the page in the pages collection.

    Dimension2D pageSize = page.getSize();

    // 2. Create a content composer for the page!
    PrimitiveComposer composer = new PrimitiveComposer(page);

    // 3. Drawing the page contents...
    try
    {
      composer.setFont(
        new StandardType1Font(
          document,
          StandardType1Font.FamilyEnum.Courier,
          true,
          false
          ),
        32
        );
    }
    catch(Exception e)
    {throw new RuntimeException(e);}

    EnumSet<AlignmentXEnum> xAlignments = EnumSet.allOf(AlignmentXEnum.class);
    EnumSet<AlignmentYEnum> yAlignments = EnumSet.allOf(AlignmentYEnum.class);
    int step = (int)(pageSize.getHeight()) / (xAlignments.size() * yAlignments.size()+1);

    BlockComposer blockComposer = new BlockComposer(composer);
    {
      blockComposer.begin(
        new Rectangle2D.Double(
          30,
          0,
          pageSize.getWidth()-60,
          step*.8
          ),
        AlignmentXEnum.Center,
        AlignmentYEnum.Middle
        );
      blockComposer.showText(
        "Text block alignment"
        );
      blockComposer.end();
    }

    // Drawing the text blocks...
    int x = 30;
    int y = (int)(step*1.2);
    for(AlignmentXEnum alignmentX
      : EnumSet.allOf(AlignmentXEnum.class))
    {
      for(AlignmentYEnum alignmentY
        : EnumSet.allOf(AlignmentYEnum.class))
      {
        composer.setFont(
          composer.getState().getFont(),
          12
          );
        composer.showText(
          alignmentX + " " + alignmentY + ":",
          new Point2D.Double(x,y),
          AlignmentXEnum.Left,
          AlignmentYEnum.Middle,
          0
          );

        composer.setFont(
          composer.getState().getFont(),
          8
          );
        for(
          int index = 0;
          index < 2;
          index++
          )
        {
          int frameX;
          switch(index)
          {
            case 0:
              frameX = 150;
              blockComposer.setHyphenation(false);
              break;
            case 1:
              frameX = 360;
              blockComposer.setHyphenation(true);
              break;
            default:
              throw new RuntimeException();
          }

          Rectangle2D frame = new Rectangle2D.Double(
            frameX,
            y-step*.4,
            200,
            step*.8
            );
          blockComposer.begin(frame,alignmentX,alignmentY);
          blockComposer.showText(
            "Demonstrating how to constrain text inside a page area using PDF Clown. See the other available code samples (such as TypesettingSample) to discover more functionality details."
            );
          blockComposer.end();

          composer.beginLocalState();
          composer.setLineWidth(.2f);
          composer.setLineDash(5,5,5);
          composer.drawRectangle(frame);
          composer.stroke();
          composer.end();
        }

        y+=step;
      }
    }

    // 4. Flush the contents into the page!
    composer.flush();
  }

  private void buildTextBlockPage2(
    Document document
    )
  {
    // 1. Add the page to the document!
    Page page = new Page(document); // Instantiates the page inside the document context.
    document.getPages().add(page); // Puts the page in the pages collection.

    Dimension2D pageSize = page.getSize();

    // 2. Create a content composer for the page!
    PrimitiveComposer composer = new PrimitiveComposer(page);

    // 3. Drawing the page contents...
    try
    {
      composer.setFont(
        new StandardType1Font(
          document,
          StandardType1Font.FamilyEnum.Courier,
          true,
          false
          ),
        32
        );
    }
    catch(Exception e)
    {throw new RuntimeException(e);}
   
    int stepCount = 5;
    int step = (int)(pageSize.getHeight()) / (stepCount + 1);
    BlockComposer blockComposer = new BlockComposer(composer);
    {
      blockComposer.begin(
        new Rectangle2D.Double(
          30,
          0,
          pageSize.getWidth()-60,
          step*.8
          ),
        AlignmentXEnum.Center,
        AlignmentYEnum.Middle
        );
      blockComposer.showText(
        "Text block line space"
        );
      blockComposer.end();
    }

    // Drawing the text blocks...
    int x = 30;
    int y = (int)(step*1.1);
    blockComposer.getLineSpace().setUnitMode(UnitModeEnum.Relative);
    for(int index = 0; index < stepCount; index++)
    {
      float relativeLineSpace = 0.5f * index;
      blockComposer.getLineSpace().setValue(relativeLineSpace);
     
      composer.setFont(
        composer.getState().getFont(),
        10
        );
      composer.showText(
        relativeLineSpace + ":",
        new Point2D.Double(x,y),
        AlignmentXEnum.Left,
        AlignmentYEnum.Middle,
        0
        );

      composer.setFont(
        composer.getState().getFont(),
        9
        );
      Rectangle2D frame = new Rectangle2D.Double(
        150,
        y-step*.4,
        350,
        step*.9
        );
      blockComposer.begin(frame,AlignmentXEnum.Left,AlignmentYEnum.Top);
      blockComposer.showText(
        "Demonstrating how to set the block line space. Line space can be expressed either as an absolute value (in user-space units) or as a relative one (as a floating-point ratio); in the latter case the base value is represented by the current font's line height (so that, for example, 2 means \"a line space that's double the line height\")."
        );
      blockComposer.end();
     
      composer.beginLocalState();
      composer.setLineWidth(0.2f);
      composer.setLineDash(5,5,5);
      composer.drawRectangle(frame);
      composer.stroke();
      composer.end();

      y+=step;
    }

    // 4. Flush the contents into the page!
    composer.flush();
  }

  private void drawCross(
    PrimitiveComposer composer,
    Point2D center
    )
  {
    composer.drawLine(
      new Point2D.Double(center.getX()-10,center.getY()),
      new Point2D.Double(center.getX()+10,center.getY())
      );
    composer.drawLine(
      new Point2D.Double(center.getX(),center.getY()-10),
      new Point2D.Double(center.getX(),center.getY()+10)
      );
    composer.stroke();
  }

  private void drawFrame(
    PrimitiveComposer composer,
    Point2D[] frameVertices
    )
  {
    composer.beginLocalState();
    composer.setLineWidth(.2f);
    composer.setLineDash(5,5,5);
    composer.drawPolygon(frameVertices);
    composer.stroke();
    composer.end();
  }

  private void drawText(
    PrimitiveComposer composer,
    String value,
    Point2D location,
    AlignmentXEnum alignmentX,
    AlignmentYEnum alignmentY,
    float rotation
    )
  {
    // Show the anchor point!
    drawCross(composer,location);

    composer.beginLocalState();
    composer.setFillColor(SampleColor);
    // Show the text onto the page!
    Point2D[] textFrame = composer.showText(
      value,
      location,
      alignmentX,
      alignmentY,
      rotation
      );
    composer.end();

    // Draw the frame binding the shown text!
    drawFrame(
      composer,
      textFrame
      );

    composer.beginLocalState();
    composer.setFont(composer.getState().getFont(),8);
    // Draw the rotation degrees!
    composer.showText(
      "(" + ((int)rotation) + " degrees)",
      new Point2D.Double(
        location.getX()+70,
        location.getY()
        ),
      AlignmentXEnum.Left,
      AlignmentYEnum.Middle,
      0
      );
    composer.end();
  }
}
TOP

Related Classes of org.pdfclown.samples.cli.GraphicsSample

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.