How to Fill the inside of a path region by hatched lines



Any idea how to fill a region inside a polygon with hatched lines.



You could set the path as a clip and then use a tiled image with your hatch pattern.


HI vinn,
I could not get what do you want to suggest.Can you just explain it briefly with some example


I can do better than that. Here is a full sample program that compiles and runs and does exactly what I described:

#include "juce.h"

namespace binaries
    extern const char*  crosshatch_png;
    const int           crosshatch_pngSize = 174;

static const unsigned char temp8[] = {137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,63,0,0,0,63,8,0,0,0,0,114,52,79,3,0,0,0,1,115,82,71,
const char* binaries::crosshatch_png = (const char*) temp8;

Image loadImageAsAlphaChannel (const void* rawData,
                               const int numBytesOfData)
  Image orig = ImageFileFormat::loadFrom(rawData, numBytesOfData);
  Image dup  = Image (Image::ARGB, orig.getWidth(), orig.getHeight(), false);
  if (orig.isRGB())
    // bug in Juce brings grayscale PNG in as RGB so deal with it
    // convert the Red channel to the alpha of the destination
    Image::BitmapData src (orig, false);
    Image::BitmapData dst (dup, true);
    for (int y=0; y<orig.getHeight(); y++ )
      PixelRGB* psrc = reinterpret_cast<PixelRGB*> (src.getLinePointer (y));
      PixelARGB* pdst = reinterpret_cast<PixelARGB*> (dst.getLinePointer (y));
      for( int x=orig.getWidth(); x; x-- )
        (pdst++)->setAlpha (psrc++->getRed());

  return dup;

void tintImageTiled (Graphics& g,
                     Image image,
                     const Rectangle<int>& bounds,
                     int xOffset,
                     int yOffset)
  int w = image.getWidth();
  int h = image.getHeight();

  xOffset %= w;
  yOffset %= h;

  for (int y = bounds.getY()-yOffset; y<bounds.getBottom(); y+=h )
    for (int x = bounds.getX()-xOffset; x<bounds.getRight(); x+=w )
      int sourceX=0;
      int sourceY=0;
      int destWidth = w;
      int destHeight = h;
      int destX = x;
      int destY = y;

      if (destX < bounds.getX())
        sourceX += (bounds.getX() - destX);
        destWidth -= bounds.getX() - destX;
        destX = bounds.getX();

      if (destX + destWidth > bounds.getRight())
        destWidth -= (destX + destWidth) - bounds.getRight();

      if (destY < bounds.getY())
        sourceY += (bounds.getY() - destY);
        destHeight -= bounds.getY() - destY;
        destY = bounds.getY();

      if (destY + destHeight > bounds.getBottom())
        destHeight -= (destY + destHeight) - bounds.getBottom();

      g.drawImage (image, destX, destY, destWidth, destHeight,
                   sourceX, sourceY, destWidth, destHeight, true);

struct ContentComponent : Component
  Image m_image;

    setSize(512, 384);

    m_image = loadImageAsAlphaChannel (binaries::crosshatch_png, binaries::crosshatch_pngSize);
  void paint (Graphics& g)
    int w = getLocalBounds().getWidth();
    int h = getLocalBounds().getHeight();
    g.setColour (Colours::white);

    Path p;
    p.startNewSubPath (10, 10);
    p.lineTo (w-100, 50);
    p.lineTo (w-300, h-100);
    p.lineTo (w-350, h-60);
    p.lineTo (75, 100);
    p.closeSubPath ();

    g.setColour (Colours::blue);
    g.reduceClipRegion (p);
    tintImageTiled (g, m_image, p.getBounds().getSmallestIntegerContainer(), 0, 0);

    // frame
    g.setColour (Colours::black);
    g.strokePath (p, 4);

struct MainWindow : DocumentWindow
  : DocumentWindow (JUCE_T("Test")
  , Colours::black
  , DocumentWindow::allButtons
  , true )
    ContentComponent* p = new ContentComponent;
    setResizable (true, false);
    setContentComponent (p, true, true);
    centreWithSize (getWidth(), getHeight());
    setVisible( true );
  ~MainWindow() {}

  void closeButtonPressed() { JUCEApplication::quit(); }

struct MainApp : JUCEApplication
  MainApp() : mainWindow(0) { s_app=this; }
  ~MainApp() { s_app=0; }
  static MainApp& GetInstance() { return *s_app; }
  const String getApplicationName() { return JUCE_T("JuceTest"); }
  const String getApplicationVersion() { return JUCE_T("0.1.0"); }
  bool moreThanOneInstanceAllowed() { return true; }
  void anotherInstanceStarted (const String& commandLine) {}

  void initialise (const String& commandLine)
    mainWindow = new MainWindow;

  void shutdown()
    delete mainWindow;

  static MainApp* s_app;
  MainWindow* mainWindow;

MainApp* MainApp::s_app = 0;


Here is the PNG image that I used to produce the hatch pattern. You can substitute your own image and then run the BinaryBuilder to embed it in your application:


Note that there is still a bug in the Juce PNG loader, it brings grayscale images in as RGB. There is also another thing I consider a bug / usability issue which is that Juce won’t treat a single channel Image as an Alpha channel, so some hacking is required to use a Grayscale image in a tinting operation (thats why I have to swizzle bits in loadImageAsAlphaChannel).


Hey Vinn,

Thanks a lot…that was really helpful.



Another option would be to draw a series of lines. To make the calculations easier you can just draw vertical lines at a given spacing after setting an appropriate rotation transform.


Thanks Vinn.