From 568054b986d2130cfc7404a698bf2f936412ab26 Mon Sep 17 00:00:00 2001 From: Marco van Dijk Date: Tue, 27 Jul 2021 14:48:57 +0200 Subject: [PATCH] Variable margins based on page number --- lib/config.py | 8 ++++---- lib/dataStructures.py | 23 ++++++++++++----------- main.py | 8 ++++++-- output2img.py | 27 +++++++++++++++++++-------- 4 files changed, 41 insertions(+), 25 deletions(-) diff --git a/lib/config.py b/lib/config.py index cc01a77..4df11f7 100644 --- a/lib/config.py +++ b/lib/config.py @@ -30,7 +30,7 @@ def initConfig(): # Else load defaults else: config['input'] = {'inputFolders': os.getcwd(), - 'maxDepth': 2, + 'maxDepth': 1, 'readtxt': 1, 'readraw': 1 } @@ -46,9 +46,9 @@ def initConfig(): 'backgroundColour': '255,255,255', 'fontColour': '0,0,0', 'metadataColour': '128,128,128', - 'topMargin': 50, - 'leftMargin': 100, - 'rightMargin': 50, + 'verticalMargin': 50, + 'horizontalMargin': 100, + 'extraHorizontalMargin': 100, 'tryToShrinkRatio' : 0.4, 'lowestwhitespaceonwidthratioallowed': 0.90, 'highestwhitespaceonwidthratioallowed': 0.40, diff --git a/lib/dataStructures.py b/lib/dataStructures.py index e6bd971..1845d9a 100644 --- a/lib/dataStructures.py +++ b/lib/dataStructures.py @@ -203,7 +203,9 @@ class Song: # Flag for succesfully parsed self.isParsed = False configObj = lib.config.config['output'] - self.topMargin = int(configObj['topMargin']) + self.verticalMargin = int(configObj['verticalMargin']) + self.horizontalMargin = int(configObj['horizontalMargin']) + self.extraHorizontalMargin = int(configObj['extraHorizontalMargin']) self.fontColour = tuple(int(var) for var in configObj['fontColour'].split(',')) self.backgroundColour = tuple(int(var) for var in configObj['backgroundColour'].split(',')) self.metadataColour = tuple(int(var) for var in configObj['metadataColour'].split(',')) @@ -215,8 +217,6 @@ class Song: # Since font size is then shrunk and grown to fit whitespace we do not need to be as accurate # PPI of 144 -> fontSize of 32 self.fontSize = int(self.ppi / 4.5) - self.leftMargin = int(configObj['leftMargin']) - self.rightMargin = int(configObj['rightMargin']) self.fontLyrics = ImageFont.truetype(configObj['lyricfontfamily'], self.fontSize) self.fontTablature = ImageFont.truetype(configObj['tablaturefontfamliy'], self.fontSize) self.fontFamilyLyrics = configObj['lyricfontfamily'] @@ -248,7 +248,7 @@ class Song: """ def calculateMetadataDimensions(self): # metadata starts topMargin removed from top - currentHeight = self.topMargin + currentHeight = self.verticalMargin maxWidth = 0 for line in self.metadata.split('\n'): line = line.rstrip() @@ -308,8 +308,8 @@ class Song: """ def checkOverflowX(self): for section in self.sections: - if section.expectedWidth > self.imageWidth - self.leftMargin - self.rightMargin: - print("There is an overflow on width: this section has a width of {}, but we have {} ({}-{}-{}) amount of space".format(section.expectedWidth, self.imageWidth - self.leftMargin - self.rightMargin, self.imageWidth, self.leftMargin, self.rightMargin)) + if section.expectedWidth > self.imageWidth - self.extraHorizontalMargin - self.horizontalMargin - self.horizontalMargin: + print("There is an overflow on width: this section has a width of {}, but we have {} ({}-{}-{}*2) amount of space".format(section.expectedWidth, self.imageWidth - self.extraHorizontalMargin - self.horizontalMargin - self.horizontalMargin, self.imageWidth, self.extraHorizontalMargin, self.horizontalMargin)) return False return True @@ -317,7 +317,7 @@ class Song: @return True if everything OK, False if overflowing """ def checkOverflowMetadata(self): - if self.metadataWidth > self.imageWidth - self.leftMargin - self.rightMargin: + if self.metadataWidth > self.imageWidth - self.extraHorizontalMargin - self.horizontalMargin - self.horizontalMargin: return False return True @@ -331,7 +331,7 @@ class Song: self.resizeAllSections(+1) self.sectionsToPages() currentPageAmount = len(self.pages) - # Increase fontSize as long as we do not add a page + # Increase fontSize as long as we stay under the target max pages while ((currentPageAmount <= targetPageAmount) and self.checkOverflowX()): self.resizeAllSections(+1) self.sectionsToPages() @@ -362,7 +362,8 @@ class Song: biggestWhitespace = -1 for page in self.pages: for section in page.sections: - whitespaceOnWidth = self.imageWidth - self.leftMargin - self.rightMargin - section.expectedWidth + # We have 2* horizontal whitespace + whitespaceOnWidth = self.imageWidth - self.extraHorizontalMargin - self.horizontalMargin - self.horizontalMargin - section.expectedWidth if whitespaceOnWidth < smallestWhitespace: smallestWhitespace = whitespaceOnWidth if whitespaceOnWidth > biggestWhitespace: @@ -398,13 +399,13 @@ class Song: """ def sectionsToPages(self): # If we are keeping whitespace, don't count the whitespace in between sections - sectionWhitespace = self.topMargin + sectionWhitespace = self.verticalMargin if self.keepEmptyLines: sectionWhitespace = 0 self.prerenderSections() self.pages = [] # First page contains metadata - currentHeight = self.topMargin + currentHeight = self.verticalMargin currentHeight += self.metadataHeight currentHeight += sectionWhitespace curPage = Page() diff --git a/main.py b/main.py index bf98bb0..50e5fa6 100644 --- a/main.py +++ b/main.py @@ -75,8 +75,12 @@ def main(): # Prerender: calculate Pages, and move sections into Pages song.sectionsToPages() # Optimalisation: try to fill whitespace - while song.canFillWhitespace() or len(song.pages) > song.maxPages: - print("Resizing down to fit whitespace more efficiently") + while len(song.pages) > song.maxPages: + print("Resizing down since we have {} pages and want {} pages".format(len(song.pages), song.maxPages)) + song.resizeAllSections(-1) + song.sectionsToPages() + while song.canFillWhitespace(): + print("Resizing down to fill remaining vertical whitespace") song.resizeAllSections(-1) song.sectionsToPages() # Optimalisation: increase font size to fit target page amount diff --git a/output2img.py b/output2img.py index cd6e068..0a863c5 100644 --- a/output2img.py +++ b/output2img.py @@ -36,11 +36,17 @@ def outputToImage(folderLocation, songObj): # Init image info imageNumber = 1 - currentHeight = songObj.topMargin + currentHeight = songObj.verticalMargin # New Image a4image = Image.new('RGB',(songObj.imageWidth, songObj.imageHeight),(songObj.backgroundColour)) draw = ImageDraw.Draw(a4image) + + # Add extra whitespace on the left if this is an even page + # The whitespace on the right for uneven pages is handled elsewhere, by limiting the maximum horizontal size + horizontalMargin = songObj.horizontalMargin + if (imageNumber % 2) == 0: + horizontalMargin += songObj.extraHorizontalMargin # Write metadata for line in songObj.metadata.split('\n'): @@ -50,12 +56,12 @@ def outputToImage(folderLocation, songObj): continue #print("meta line '{}'".format(line)) metadataTextWidth, metadataTextHeight = songObj.fontMetadata.getsize(line) - draw.text((songObj.leftMargin,currentHeight), line, fill=songObj.metadataColour, font=songObj.fontMetadata) + draw.text((horizontalMargin, currentHeight), line, fill=songObj.metadataColour, font=songObj.fontMetadata) currentHeight += metadataTextHeight # Draw all pages for page in songObj.pages: # Margin between metadata and the first section / section and top of page - currentHeight += songObj.topMargin + currentHeight += songObj.verticalMargin for section in page.sections: # Reset section specific variables lineIterator = 0 @@ -68,7 +74,7 @@ def outputToImage(folderLocation, songObj): return # write section title headerWidth, headerHeight = songObj.fontTablature.getsize(section.header) - draw.text((songObj.leftMargin,currentHeight), section.header, fill=songObj.fontColour, font=songObj.fontTablature) + draw.text((horizontalMargin ,currentHeight), section.header, fill=songObj.fontColour, font=songObj.fontTablature) currentHeight += headerHeight # Write each line tablature&lyric data while lineIterator < amountOfLines: @@ -77,22 +83,27 @@ def outputToImage(folderLocation, songObj): lyricTextWidth, lyricTextHeight = songObj.fontLyrics.getsize(section.lyrics[lineIterator]) tablatureTextWidth, tablatureTextHeight = songObj.fontTablature.getsize(section.tablatures[lineIterator]) # add to image file - draw.text((songObj.leftMargin,currentHeight), section.tablatures[lineIterator], fill=songObj.fontColour, font=songObj.fontTablature) + draw.text((horizontalMargin ,currentHeight), section.tablatures[lineIterator], fill=songObj.fontColour, font=songObj.fontTablature) currentHeight += tablatureTextHeight - draw.text((songObj.leftMargin,currentHeight), section.lyrics[lineIterator], fill=songObj.fontColour, font=songObj.fontLyrics) + draw.text((horizontalMargin ,currentHeight), section.lyrics[lineIterator], fill=songObj.fontColour, font=songObj.fontLyrics) currentHeight += lyricTextHeight lineIterator += 1 #print("currentheight={}".format(currentHeight)) # If we stripped al whitespace, we need to add whitespace between sections if not songObj.keepEmptyLines: - currentHeight += songObj.topMargin + currentHeight += songObj.verticalMargin # Got all sections in the page, so write it outputLocation = folderLocation + "/" + songObj.title + '-' + str(imageNumber) + ".png" a4image.save(outputLocation) a4image = Image.new('RGB',(songObj.imageWidth, songObj.imageHeight),(songObj.backgroundColour)) draw = ImageDraw.Draw(a4image) - currentHeight = songObj.topMargin + currentHeight = songObj.verticalMargin imageNumber += 1 + # Add extra whitespace on the left if this is an even page + # The whitespace on the right for uneven pages is handled elsewhere, by limiting the maximum horizontal size + horizontalMargin = songObj.horizontalMargin + if (imageNumber % 2) == 0: + horizontalMargin += songObj.extraHorizontalMargin