Skip to content

Commit

Permalink
Test images to docs (#153)
Browse files Browse the repository at this point in the history
* I guess the simplest way to add a context manager

without breaking existing scripts

#140

* adding save and restore tests

this should actually test more: everything a graphic state holds and
resets on restore

* move class to global level

* added some comments

* rename to savedState

* update test referenced image for saved state

* update example with a transformation

* support to add multiple modules or classes

there are examples in the FormattedString and BezierPath classes

* add support for different ui elements while mocking Variable

* renaming example file name

this name was already used in course ware

* update expected png data

* making the rect example bigger

* making the oval example bigger

* making the blendMode example bigger

* dont use mov in examples

prefer mp4 or gif

* making the fill example bigger

* making the lineGradient example bigger

* prefer mp4 or gif above mov

* adding images to docs

* do not mock an ImageObject

* update fill example

* making the stroke example bigger

* making the shadow example bigger

* making the radialGradient example bigger

* set size of example and update png test data

* move code examples to docs

+ adding test png data

* making the clipPath and drawPath example bigger

* making the line lineCap lineDash lineJoin miterLimit polygon strokeWith example bigger

* updating examples

* making examples bigger

* renaming test to savedState and add a nested one

* adding the same nested save restore test without savedState

* renaming to savedState.<ext>

* fixing conficts

* this one works and does not fail

* make at least the sizing work correctly on Retina + Py3

* all image rep must be build with _makeBitmapImageRep

when the imageObject reads a path, when the imageObjects applies a
filter

* implement 'fuzzy' image comparison, so we can allow some tolerance between generated and expected image data; use that in the example tester

* adding PIL/PILLOW to the the require packages

* only do fuzzy image comparison in specific cases

* convert list to set
  • Loading branch information
typemytype committed Dec 22, 2017
1 parent 8763595 commit 137a75e
Show file tree
Hide file tree
Showing 60 changed files with 387 additions and 242 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ __Required packages:__
* [ufo2svg](https://github.com/typesupply/ufo2svg)
* [fontTools](https://github.com/fonttools/fonttools)
* [PyObjC](https://pythonhosted.org/pyobjc/) (Only if you're not building with the system Python 2.7)
* [PIL](https://github.com/python-pillow/Pillow) (only for running tests)

__Compile:__

Expand Down
6 changes: 6 additions & 0 deletions docs/_themes/drawBotTheme/static/drawBot.css_t
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,12 @@ div.downloadlink a.drawbotlink {
font-size: 1.2em
}

div.example-image {
margin-bottom: 20px;
border: 2px solid {{ theme_headercolor1 }};
display: inline-block;
}

h1, h2, h3, h4, h5, h6 {
font-family: {{ theme_headerfont }};
font-weight: bold;
Expand Down
44 changes: 32 additions & 12 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -315,16 +315,28 @@ def __getattr__(cls, name):
from sphinx.ext import autodoc
from sphinx.writers.html import HTMLTranslator

downloadCodeRoot = os.path.join(os.path.dirname(__file__), "downloads")
if os.path.exists(downloadCodeRoot):
shutil.rmtree(downloadCodeRoot)

os.mkdir(downloadCodeRoot)

imageSourceRoot = os.path.join(os.path.dirname(__file__), "..", "tests", "data")


def visit_download_reference(self, node):
if node.hasattr('filename'):
data = dict(
urlPath=posixpath.join(self.builder.dlpath, node['filename']),
fileName=node['filename']
if not node.get("dontShowThisNode"):
data = dict(
urlPath=posixpath.join(self.builder.dlpath, node['filename']),
fileName=node['filename']
)
self.body.append('<div class="downloadlink"><a class="reference internal drawbotlink" href="%(urlPath)s">Open in DrawBot: %(fileName)s</a>' % data)
self.body.append('<a class="reference internal" href="%(urlPath)s">Download: %(fileName)s</a></div>' % data)
self.body.append('<div class="downloadlink"><a class="reference internal drawbotlink" href="%(urlPath)s">Open in DrawBot: %(fileName)s</a>' % data)
self.body.append('<a class="reference internal" href="%(urlPath)s">Download: %(fileName)s</a></div>' % data)

if node.get('imageFileName'):
imageUrl = posixpath.join(self.builder.dlpath, node['imageFileName'])
self.body.append('<div class="example-image"><image src="%s"/></div>' % imageUrl)
node.clear()


Expand All @@ -350,13 +362,6 @@ def run(self):
return nodes


downloadCodeRoot = os.path.join(os.path.dirname(__file__), "downloads")
if os.path.exists(downloadCodeRoot):
shutil.rmtree(downloadCodeRoot)

os.mkdir(downloadCodeRoot)


class DownloadCode(CodeBlock):

def run(self):
Expand All @@ -383,10 +388,25 @@ def run(self):
f = open(path, "w")
f.write(code.encode("utf-8"))
f.close()
# add example image if present
imageBaseName, _ = os.path.splitext(fileName)
imageFileName = "example_%s.png" % imageBaseName
imagePath = os.path.join(imageSourceRoot, imageFileName)
if os.path.exists(imagePath):
imageDestPath = os.path.join(downloadCodeRoot, imageFileName)
shutil.copy(imagePath, imageDestPath)
else:
imageFileName = ""
# add download links
node = addnodes.download_reference()
node['reftarget'] = "/downloads/" + fileName
node['imageFileName'] = imageFileName
nodes.append(node)
if imageFileName:
node = addnodes.download_reference()
node['reftarget'] = "/downloads/" + imageFileName
node['dontShowThisNode'] = True
nodes.append(node)
return nodes

def checkPath(self, path, sourcePath=None, add=1):
Expand Down
2 changes: 1 addition & 1 deletion docs/content/quickReference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,6 @@ Quick Reference
saveImage(u"~/Desktop/drawBotTest.pdf")
saveImage(u"~/Desktop/drawBotTest.png")
saveImage(u"~/Desktop/drawBotTest.svg")
saveImage(u"~/Desktop/drawBotTest.mov")
saveImage(u"~/Desktop/drawBotTest.mp4")

print "Done"
38 changes: 1 addition & 37 deletions docs/content/shapes/drawingPath.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,40 +11,4 @@ Using bezier paths.
.. autofunction:: drawBot.arcTo
.. autofunction:: drawBot.closePath
.. autofunction:: drawBot.drawPath

.. downloadcode:: path.py

# create a new empty path
newPath()
# set the first oncurve point
moveTo((100, 100))
# line to from the previous point to a new point
lineTo((100, 200))
lineTo((200, 200))

# curve to a point with two given handles
curveTo((200, 100), (150, 100), (100, 100))

# close the path
closePath()
# draw the path
drawPath()

.. autofunction:: drawBot.clipPath

.. downloadcode:: clipPath.py

# create a bezier path
path = BezierPath()

# move to a point
path.moveTo((100, 100))
# line to a point
path.lineTo((100, 200))
path.lineTo((200, 200))
# close the path
path.closePath()
# set the path as a clipping path
clipPath(path)
# the oval will be clipped inside the path
oval(100, 100, 100, 100)
.. autofunction:: drawBot.clipPath
27 changes: 15 additions & 12 deletions drawBot/context/baseContext.py
Original file line number Diff line number Diff line change
Expand Up @@ -1232,6 +1232,7 @@ def openTypeFeatures(self, *args, **features):
.. downloadcode:: openTypeFeaturesFormattedString.py
size(1000, 200)
# create an empty formatted string object
t = FormattedString()
# set a font
Expand All @@ -1245,7 +1246,7 @@ def openTypeFeatures(self, *args, **features):
# add some text
t += " 0123456789 Hello"
# draw the formatted string
text(t, (10, 100))
text(t, (10, 80))
"""
if args and args[0] is None:
self._openTypeFeatures.clear()
Expand Down Expand Up @@ -1314,11 +1315,12 @@ def indent(self, indent):
.. downloadcode:: indent.py
# setting up some variables
x, y, w, h = 10, 10, 200, 300
x, y, w, h = 10, 10, 500, 600
txtIndent = 50
txtFirstLineIndent = 70
txtTailIndent = -50
txtIndent = 100
txtFirstLineIndent = 200
txtTailIndent = -100
txtFontSize = 22
paragraphTop = 3
paragraphBottom = 10
Expand Down Expand Up @@ -1347,15 +1349,15 @@ def indent(self, indent):
rect(x, y, w, h)
# create a formatted string
t = FormattedString()
t = FormattedString(fontSize=txtFontSize)
# set alignment
t.align("justified")
# add text
t += txt
# add hard return
t += "\\n"
# set style for indented text
t.fontSize(6)
t.fontSize(txtFontSize*.6)
t.paragraphTopSpacing(paragraphTop)
t.paragraphBottomSpacing(paragraphBottom)
t.firstLineIndent(txtFirstLineIndent)
Expand All @@ -1366,7 +1368,7 @@ def indent(self, indent):
# add hard return
t += "\\n"
# reset style
t.fontSize(10)
t.fontSize(txtFontSize)
t.indent(None)
t.tailIndent(None)
t.firstLineIndent(None)
Expand Down Expand Up @@ -1555,16 +1557,17 @@ def appendGlyph(self, *glyphNames):
.. downloadcode:: appendGlyphFormattedString.py
size(1000, 400)
# create an empty formatted string object
t = FormattedString()
# set a font
t.font("Menlo-Regular")
# set a font size
t.fontSize(60)
# add some glyphs
t.appendGlyph("Eng", "Eng.alt")
t.fontSize(300)
# add some glyphs by glyph name
t.appendGlyph("A", "ampersand", "Eng", "Eng.alt")
# draw the formatted string
text(t, (10, 100))
text(t, (100, 100))
"""
# use a non breaking space as replacement character
baseString = unichr(0x00A0)
Expand Down
10 changes: 7 additions & 3 deletions drawBot/context/tools/imageObject.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

from drawBot.misc import DrawBotError, optimizePath
from fontTools.misc.py23 import basestring
from drawBot.context.imageContext import _makeBitmapImageRep


class ImageObject(object):
Expand Down Expand Up @@ -69,7 +70,8 @@ def open(self, path):
im = AppKit.NSImage.alloc().initByReferencingURL_(url)
else:
raise DrawBotError("Cannot read image path '%s'." % path)
ciImage = AppKit.CIImage.imageWithData_(im.TIFFRepresentation())
rep = _makeBitmapImageRep(im)
ciImage = AppKit.CIImage.imageWithData_(rep.TIFFRepresentation())
self._merge(ciImage, doCrop=True)

def copy(self):
Expand Down Expand Up @@ -121,7 +123,8 @@ def unlockFocus(self):
# create an image
im = AppKit.NSImage.alloc().initWithData_(page.dataRepresentation())
# create an CIImage object
ciImage = AppKit.CIImage.imageWithData_(im.TIFFRepresentation())
rep = _makeBitmapImageRep(im)
ciImage = AppKit.CIImage.imageWithData_(rep.TIFFRepresentation())
# merge it with the already set data, if there already an image
self._merge(ciImage)

Expand Down Expand Up @@ -198,7 +201,8 @@ def _applyFilters(self):
ctx.setImageInterpolation_(AppKit.NSImageInterpolationNone)
generator.drawAtPoint_fromRect_operation_fraction_((0, 0), ((0, 0), (w, h)), AppKit.NSCompositeCopy, 1)
dummy.unlockFocus()
self._cachedImage = AppKit.CIImage.imageWithData_(dummy.TIFFRepresentation())
rep = _makeBitmapImageRep(dummy)
self._cachedImage = AppKit.CIImage.imageWithData_(rep.TIFFRepresentation())
del dummy
elif hasattr(self, "_cachedImage"):
ciFilter.setValue_forKey_(self._cachedImage, "inputImage")
Expand Down
Loading

0 comments on commit 137a75e

Please sign in to comment.