Navigation

    • Register
    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Users
    • Groups
    • Solved
    • Unsolved
    • Search
    1. Home
    2. monomonnik
    3. Posts
    • Profile
    • Following
    • Followers
    • Topics
    • Posts
    • Best
    • Groups

    Posts made by monomonnik

    • RE: Even-Odd Fill Rule

      You are correct, I should have looked better.

      I don’t know if there exist these kind of filters for DrawBot (I assume you mean something like Illustrator’s Pathfinder tool).

      I did some reading on the underlying NSBezierPath, which has an even-odd winding rule, but I'm not smart enough to figure out if that's useable, let alone how.

      posted in General Discussion
      monomonnik
      monomonnik
    • RE: Even-Odd Fill Rule

      Maybe this post can help you on your way?

      posted in General Discussion
      monomonnik
      monomonnik
    • RE: extracting anchor and control points in a variable font

      Nice! Thanks for sharing the result.

      posted in General Discussion
      monomonnik
      monomonnik
    • RE: extracting anchor and control points in a variable font

      I think you ask for something from DrawBot that is not there.

      formattedString = FormattedString('HO', font='Helvetica', fontSize=700)
      # Get the Bézier path of the text using FormattedString
      path = BezierPath()
      path.text(formattedString, (50, 50))
      # Draw the bezier path with the formatted string
      newPage()
      with savedState():
          fill(.8)
          drawPath(path)
      # A segment of a DrawBot contour doesn’t have an attribute ‘points’ or ‘type’
      for contour in path.contours:
          for segment in contour:
              print(segment) # returns list with point(s)
              print(type(segment)) # returns ‘<class 'list'>’
              # print(segment.points) # returns AttributeError: 'list' object has no attribute 'points'
              # print(segment.type) # returns AttributeError: 'list' object has no attribute 'type'
              if hasattr(segment, 'points'):
                  # Will never be true
                  print(segment.points)
      
      
      
      posted in General Discussion
      monomonnik
      monomonnik
    • RE: extracting anchor and control points in a variable font

      Not sure if this is completely correct and robust enough for what you need, but it works. At least for H and O.

      H_with_anchor_points.png

      # Set up canvas
      canvas_width = 500
      canvas_height = 500
      txt = "HO"
      variable_font_path = "RobotoFlex-VariableFont_GRAD,XOPQ,XTRA,YOPQ,YTAS,YTDE,YTFI,YTLC,YTUC,opsz,slnt,wdth,wght.ttf"
      font_size = 400
      point_size = 2
      
      # Neue Seite erstellen und Hintergrund setzen
      newPage(canvas_width, canvas_height)
      fill(1)  # Weißer Hintergrund
      rect(0, 0, canvas_width, canvas_height)
      fill(0)  # Schwarzer Text
      
      # Schriftart setzen und prüfen, ob sie korrekt geladen wird
      font(variable_font_path)
      fontSize(font_size)
      
      # Alle Achsen der aktuellen Schriftart auflisten
      variations = listFontVariations()
      # for axis, data in variations.items():
      #     print(f"Axis: {axis}, Data: {data}")
      
      # Eine Variation der aktuellen Schriftart auswählen
      if 'wght' in variations:
          fontVariations(wght=500)
      
      # Create a FormattedString with the text and variable font
      formattedString = FormattedString(txt, font=variable_font_path, fontSize=font_size)
      
      # Get the Bézier path of the text using FormattedString
      path = BezierPath()
      path.text(formattedString, (50, 50))
      with savedState():
          fill(.8)
          drawPath(path)
      
      # Initialize lists to hold on-curve and off-curve points
      on_curve_points = []
      off_curve_points = []
      
      # Iterate through contours and segments to extract points
      output = ""
      for contour in path.contours:
          # moveTo
          x, y = contour[0][0]
          on_curve_points.append((x, y))
          for segment in contour[1:]:
              if len(segment) == 1:
                  # lineTo
                  pt = segment[0]
                  on_curve_points.append((pt[0], pt[1]))
              if len(segment) == 3:
                  # curveTo
                  cp1 = segment[0]
                  cp2 = segment[1]
                  pt = segment[2]
                  off_curve_points.append((cp1[0], cp1[1]))
                  off_curve_points.append((cp2[0], cp2[1]))
                  on_curve_points.append((pt[0], pt[1]))
      
      # Draw on-curve points
      fill(1, 0, 0)  # Rot für on-curve Punkte
      stroke(None)
      for (x, y) in on_curve_points:
          print("Drawing on-curve point at:", x, y)
          oval(x - point_size / 2, y - point_size / 2, point_size, point_size)
      
      # Draw off-curve points
      fill(0, 1, 0)  # Grün für off-curve Punkte
      stroke(None)
      for (x, y) in off_curve_points:
          print("Drawing off-curve point at:", x, y)
          oval(x - point_size / 2, y - point_size / 2, point_size, point_size)
      
      # Save the image
      saveImage("H_with_anchor_points.png")
      
      # Ausgabe der Koordinaten
      print(output)
      
      
      posted in General Discussion
      monomonnik
      monomonnik
    • RE: Defining lineHeight and first baseline: status?

      I’m trying to understand the problem. Does this simplification work with your font?

      What I'd like to do is keep fontSize constant and vary the lineHeight from line to line […]

      source = 'lestextessociologiques' 
      fSize = 90
      array = FormattedString()
      ft = 'Helvetica'
      lh_min = 100
      lh_max = 200
      lh_step = 10
      
      temp = FormattedString()
      for lh in range(lh_min, lh_max, lh_step):
          temp.append(source, font=ft, fontSize=fSize, lineHeight=lh, align='center')
          temp.append('\n')
      array.append(temp)
      
      newPage()
      with savedState():
          fill(1)
          rect(0, 0, width(), height())
      
      textBox(array, (0, 0, width(), height()))
      
      fill(None); stroke(1, 0, 0)
      y = height()
      for lh in range(lh_min, lh_max, lh_step):
          y -= lh
          line((0, y), (width(), y))
      
      saveImage('~/Desktop/baseline_test.png')
      

      baseline_test.png

      posted in Bugs
      monomonnik
      monomonnik
    • RE: Copy Page Data

      You could create an imageObject of the background, but I believe you get pixels instead of outlines.

      Maybe you can create the whole background in one BezierPath? I’m not sure, but it seems possible to append multiple paths to one BezierPath.

      posted in General Discussion
      monomonnik
      monomonnik
    • RE: conditional control UI

      I don’t believe it’s possible with DrawBot’s Variables.

      It might be possible to use DrawBot with Vanilla and create your own interface, but I have no first hand experience with that.

      Also, the example script on that page does only work for me if I add this at the top:

      from PyObjCTools import AppHelper
      

      and this at the bottom:

      AppHelper.runEventLoop()
      
      posted in General Discussion
      monomonnik
      monomonnik
    • RE: Can I use use areaAverage() to analyze an actual image?

      The thing that tripped me up initially was ‘Returns a single-pixel image…’. I was (mis)reading that and assumed that ‘returns’ meant ‘returns a new image’ instead of altering the imageObject.

      I’m not sure if the documentation is a little confusing, or that the behaviour of areaAverage is unexpected.

      posted in General Discussion
      monomonnik
      monomonnik
    • RE: How to draw a line connecting all off curve points to on curve points

      @micahmicah Maybe, if the last segment is a line, the last point is not updated?

      Maybe change:

      # IF IT'S A LINE DRAW A LINE
              if len(segment) == 1:
                  x,y = segment[0].x, segment[0].y
                  P.lineTo((x,y))
                  
                  #SHOW POINTS
                  rect(x-diameter/2,y-diameter/2,diameter,diameter)
      

      to:

      # IF IT'S A LINE DRAW A LINE
              if len(segment) == 1:
                  x3,y3 = segment[0].x, segment[0].y
                  P.lineTo((x3,y3))
                  
                  #SHOW POINTS
                  rect(x3-diameter/2,y3-diameter/2,diameter,diameter)
      

      (I’m coding blind, I have not tested this)

      posted in Tutorials
      monomonnik
      monomonnik
    • RE: How to draw a line connecting all off curve points to on curve points

      @micahmicah I have no experience with RoboFont, but I assume this wil work. The trick is to remember the last point and use that as the first point.

      g = BezierPath()
      g.oval(0,0,500,500)
      
      newPage(1000,1000)
      
      P = BezierPath()
      
      diameter = 10
      translate(240,100)
      
      # DRAW CONTOURS
      for contour in g.contours:
          # DEFINE STARTING POINT
          x3,y3 = (contour[0][0][0],contour[0][0][1])
          P.moveTo((x3,y3))
      
          for segment in contour:
              # LAST POINT BECOMES THE FIRST POINT
              x0,y0 = x3,y3
              
              # IF IT'S A CURVE DRAW A CURVE
              if len(segment) == 3:
                  x1,y1 = segment[0][0], segment[0][1]
                  x2,y2 = segment[1][0], segment[1][1]
                  x3,y3 = segment[2][0], segment[2][1]
      
                  P.curveTo((x1,y1),(x2,y2),(x3,y3))
                  
                  # SHOW THE OFF CURVE POINTS
                  oval(x1-diameter/2,y1-diameter/2,diameter,diameter)
                  oval(x2-diameter/2,y2-diameter/2,diameter,diameter)
                  
                  # SHOW THE ON CURVE POINTS
                  rect(x3-diameter/2,y3-diameter/2,diameter,diameter)
                  
                  # DRAW A LINE
                  stroke(0)
                  line((x2,y2),(x3,y3))
                  line((x0,y0),(x1,y1))
                              
              # IF IT'S A LINE DRAW A LINE
              if len(segment) == 1:
                  x,y = segment[0][0], segment[0][1]
                  P.lineTo((x,y))
                  
                  #SHOW POINTS
                  rect(x-diameter/2,y-diameter/2,diameter,diameter)
          P.closePath()
      
      
      fill(None)
      stroke(0)
      
      drawPath(P)
      
      posted in Tutorials
      monomonnik
      monomonnik
    • RE: Can I use use areaAverage() to analyze an actual image?

      areaAverage() does not return anything, but changes the imageObject.

      p = 'schrofer_head.jpg'
      
      im = ImageObject(p)
      print(im.size()) # (1365.0, 1365.0)
      
      im.areaAverage()
      print(im.size()) # (1.0, 1.0)
      
      print(imagePixelColor(im, (0, 0))) # (0.6, 0.6039215686274509, 0.6, 1.0)
      
      
      posted in General Discussion
      monomonnik
      monomonnik
    • RE: QRCodeGenerator(size, message)

      Thanks @frederik

      posted in General Discussion
      monomonnik
      monomonnik
    • RE: QRCodeGenerator(size, message)

      Using almost the exact same script of @gferreira (only added the generated image on top of the shapes) I get a QR code that is not very crisp.

      Am I doing something wrong? Or has something changed since 2020?

      blurry-qr-code.png

      path = bytes('http://www.drawbot.com/', 'utf-8')
      
      w, h = 31, 31
      s = 10
      
      img = ImageObject()
      img.QRCodeGenerator((w, h), path, 'Q')
      
      size(w*s, h*s)
      for x in range(w):
          for y in range(h):
              c = imagePixelColor(img, (x, y))
              fill(*c)
              rect(x*s, y*s, s, s)
      
      image(img, (0, 0))
      
      
      posted in General Discussion
      monomonnik
      monomonnik
    • RE: trim box in pdfs

      Hi @jo,

      I don’t have an answer or solution, but maybe there is a way to circumvent the error message.

      When I place a Drawbot pdf in InDesign I don’t get an error. If I place a pdf with ‘Show Import Options’ checked, the Crop to: options is pre-selected to ‘Media’.

      Maybe your selection is set to ‘Trim’, and the error message will disappear when you change that?

      Screenshot 2023-04-01 at 13.36.05.png

      posted in Feature Requests
      monomonnik
      monomonnik
    • RE: UI questions

      @crackheroine I have little experience with creating UI for DrawBot, and no experience with Vanilla or tkinter. So, I would love to see your results here, if you are willing to share.

      posted in General Discussion
      monomonnik
      monomonnik
    • RE: UI questions

      If a very basic UI is sufficient, maybe you can use the Variable() funtion?

      posted in General Discussion
      monomonnik
      monomonnik
    • RE: UI questions

      In this post @frederik talks about Vanilla. That might be useful to you?

      posted in General Discussion
      monomonnik
      monomonnik
    • RE: Running Drawbot as a module in environments that aren't Mac OS X

      Yes, macOS only.

      From the GitHub page: ‘This module only works on Mac OS as it requires PyObjC, AppKit, CoreText Quartz and more.’

      posted in Bugs
      monomonnik
      monomonnik
    • RE: BezierPath offset problem.

      I found a way.

      newPage(2000,2000)
      
      # Red Rectangle
      path2 = BezierPath()
      path2.text("2", fontSize=200, offset=(200,300))
      with savedState():
          fill(1,0,0)
          x = path2.getNSBezierPath().bounds().origin.x
          y = path2.getNSBezierPath().bounds().origin.y
          w = path2.getNSBezierPath().bounds().size.width
          h = path2.getNSBezierPath().bounds().size.height
          rect(x,y,w,h)
      drawPath(path2)
      

      I’m not sure if this is even allowed, maybe @frederik will take some reputation points away from me ;-). Also, I’m not sure if the way offset works is correct, or if it’s a bug.

      Personally, I would just wrap your fourth solution in a savedState() and accept all the translations of the canvas. I think that would be the DrawBot way.

      # Magenta Rectangle
      with savedState():
          translate(900,800)
          path4 = BezierPath()
          path4.text("4", fontSize=200)
          with savedState():
              fill(1,0,1)
              rect(*path4.bounds())
          drawPath(path4)
      
      posted in General Discussion
      monomonnik
      monomonnik