Navigation

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

    Posts made by robstenson

    • Animation pipeline, from DrawBot to AfterEffects

      Hello! I recently put together a tutorial based on how I make animations with a combination of DrawBot, After Effects, and a small library I wrote called furniture.

      Link to tutorial: https://adaktypo.com/articles/animating-with-drawbot.html

      This is not really a general-purpose tutorial on animating in DrawBot, since I’m usually working with some specific constraints (like viewing the animation in time to audio playback), but I thought someone on the DrawBot forum might find it useful, particularly the concept of the storyboard that I use when writing animations in the DrawBot app itself, and the concept of an animation callback (both discussed in the tutorial).

      I’d also love feedback on the tutorial, particularly if some if it seems confusing, misleading, or misinformed.

      And a big thank you to the DrawBot authors for such an awesome piece of software!

      posted in Tutorials
      robstenson
      robstenson
    • RE: Color fonts: “Create Outlines”, changing palettes

      Hello! I'm no expert on DrawBot but I found your question to be very interesting, so I looked into figuring out a way to do a "color separation" of sorts — basically, I wanted to know if it was possible, as you suggested, to get a different BezierPath for each layer of color in a given string.

      And it looks like it is (at least for Pappardelle Party)! Here's some rough & ready code (a lot of it is a copy/paste from the DrawBot BezierPath.textBox method, just to convert a string into its glyphNames — probably this method could be simplified but I don't know my way around the CoreText calls all that well), but the code seems to be working well on my computer running in the latest DrawBot app.

      The bit at the end is where the customization happens, and you can access all the alternative CPAL palettes, just with the index of the palette in the CPAL table. (The one pictured is 1 I think).

      0_1541179864083_Screen Shot 2018-11-02 at 10.30.28 AM.png

      import CoreText
      import AppKit
      
      def glyphIdentifiers(txt, font, fontSize):
          from drawBot.context.baseContext import BaseContext
          context = BaseContext()
          context.font(font, fontSize)
          path, (x, y) = context._getPathForFrameSetter((0, 0, 1200, 1200))
          attributedString = context.attributedString(txt, "left")
          setter = CoreText.CTFramesetterCreateWithAttributedString(attributedString)
          frame = CoreText.CTFramesetterCreateFrame(setter, (0, 0), path, None)
          ctLines = CoreText.CTFrameGetLines(frame)
          origins = CoreText.CTFrameGetLineOrigins(frame, (0, len(ctLines)), None)
      
          glyphIDs = []
          for i, (originX, originY) in enumerate(origins):
              ctLine = ctLines[i]
              ctRuns = CoreText.CTLineGetGlyphRuns(ctLine)
              for ctRun in ctRuns:
                  attributes = CoreText.CTRunGetAttributes(ctRun)
                  font = attributes.get(AppKit.NSFontAttributeName)
                  baselineShift = attributes.get(AppKit.NSBaselineOffsetAttributeName, 0)
                  glyphCount = CoreText.CTRunGetGlyphCount(ctRun)
                  for i in range(glyphCount):
                      glyph = CoreText.CTRunGetGlyphs(ctRun, (i, 1), None)[0]
                      ax, ay = CoreText.CTRunGetPositions(ctRun, (i, 1), None)[0]
                      if glyph:
                          glyphIDs.append(glyph)
          return glyphIDs
      
      def getFontToolsFont(font_path):
          from fontTools.ttLib import TTFont, TTLibError
          from fontTools.misc.macRes import ResourceReader, ResourceError
          return TTFont(font_path, lazy=True, fontNumber=None, res_name_or_index=None)
          
      def glyphIdentifierToGlyphName(ft_font, glyph_id):
          return ft_font.getGlyphOrder()[glyph_id]
      
      from fontTools.ttLib.tables.C_O_L_R_ import table_C_O_L_R_
      from fontTools.ttLib.tables.C_P_A_L_ import table_C_P_A_L_
      
      def hex_to_tuple(palette):
          return tuple([c/255 for c in (palette.red, palette.green, palette.blue, palette.alpha)])
      
      def getPathAndColorForColorID(f, font_size, txt, _rect, color_id=0, palette_id=0):
          fs2 = FormattedString()
          fs2.font(f)
          fs2.fontSize(font_size)
          
          ft_font = getFontToolsFont(fs2.fontFilePath())
          colr = table_C_O_L_R_()
          cpal = table_C_P_A_L_()
          colr.decompile(ft_font.getTableData("COLR"), ft_font)
          cpal.decompile(ft_font.getTableData("CPAL"), ft_font)
          
          ids = glyphIdentifiers(txt, f, 500)
          glyphNames = [glyphIdentifierToGlyphName(ft_font, _id) for _id in ids]
          
          for glyphName in glyphNames:
              for layer in colr[glyphName]:
                  if layer.colorID == color_id:
                      fs2.fill(*hex_to_tuple(cpal.palettes[palette_id][layer.colorID]))
                      fs2.appendGlyph(layer.name)
          
          bp = BezierPath()
          bp.textBox(fs2, _rect)
          return bp, hex_to_tuple(cpal.palettes[palette_id][color_id])
      
      #############################
      ##### CUSTOMIZABLE CODE #####
      #############################
      
      font_name = "Pappardelle Party Regular"
      font_size = 300
      txt = "HELLO WORLD"
      r = (100, 100, 800, 800)
      palette_id = 1
      
      for c in range(0, 4): # <----- which layers of color to actually print
          path, color = getPathAndColorForColorID(font_name, font_size, txt, r, color_id=c, palette_id=palette_id)
          fill(*color)
          drawPath(path)
      
      
      posted in Feature Requests
      robstenson
      robstenson